2024-05-10 07:49 PM
Hello, I am working on a TouchGFX (4.23.2 release) project with the Nucleo-F746ZG. I was able set up my registers in cube mx and use the designer to generate for for screens and custom widgets. However, I get a when any of the Matrix3x3 methods are called.
I have some svg icons that have been generate in my SVGDatabase file. During debug, I see the svg objects being loaded in through the setSVG method, which also calls resizeToCurrentSVG. Inside resizeToCurrentSVG, the VGObject image is loaded from the svg database table. A Matrix3x3 object is then created to perform matrix operation on the svg data. Please see the code below:
SVGImage.cpp
void SVGImage::setSVG(uint16_t id)
{
if (id >= SVGDatabase::getInstanceSize())
{
svgId = SVG_INVALID;
return;
}
svgId = id;
reset();
// If the widget is empty, resize it to the size of the SVG
if (rect.isEmpty())
{
resizeToCurrentSVG();
}
}
void SVGImage::resizeToCurrentSVG()
{
if (svgId == SVG_INVALID)
{
return;
}
const VGObject* const table = SVGDatabase::getInstance();
const VGObject& image = table[svgId];
const Matrix3x3 matrix = getTransformationMatrix();
// Transform bounding box corners
const Matrix3x3::Point p1 = matrix.affineTransform(0.0f, 0.0f);
const Matrix3x3::Point p2 = matrix.affineTransform(0.0f, image.imageHeight);
const Matrix3x3::Point p3 = matrix.affineTransform(image.imageWidth, 0.0f);
const Matrix3x3::Point p4 = matrix.affineTransform(image.imageWidth, image.imageHeight);
// Find limits of transformed box
const float x_max = MAX(MAX(p1.x, p2.x), MAX(p3.x, p4.x));
const float y_max = MAX(MAX(p1.y, p2.y), MAX(p3.y, p4.y));
setWidthHeight(static_cast<int16_t>(ceilf(x_max)), static_cast<int16_t>(ceilf(y_max)));
}
touchgfx::Matrix3x3 SVGImage::getTransformationMatrix() const
{
Matrix3x3 matrix; // Implicit reset to identity matrix
if (svgId != SVG_INVALID)
{
matrix.scale(scaleX, scaleY);
matrix.translate(imagePositionX - rotationCenterX, imagePositionY - rotationCenterY);
matrix.rotate(rotation);
matrix.translate(rotationCenterX, rotationCenterY);
}
return matrix;
}
However, the code breaks (reaches a HardFault_Handler(void)) when any of the Matrix3x3 methods are called. I see the function prototypes and definitions for some of these methods inside <Middlewares/ST/touchgfx/framework/include/touchgfx/Matrix3x3.hpp>. But I cannot find the source code (Matrix3x3.cpp) file.
I have tried commenting lines 44 through 47 (since only their prototype exists inside Matrix3x3.hpp). But after exiting the getTransformationMatrix method, at line 29 it complains that the Matrix3x3.h has no source code.
At first I thought maybe I need to cache the svg images to the chip's RAM to access them quicker instead of reading from flash. But then I realized that procedure only applies to bitmaps. I soon realized the generated code form my bitmaps array is also populated with zeros:
BitmapDatabase.cpp
const touchgfx::Bitmap::BitmapData bitmap_database[] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
Assuming the hard fault is caused by the Matrix3x3 methods:
1- Is there supposed to be a Matrix3x3.cpp file? or is it hidden inside the private libtouchgfx.a library file? If inside libtouchgfx.a, how can I link these failing methods to it? I thought my c / c++ compilers and linker file would take care of this.
2- Based on the following settings, is my bitmap_database supposed to be all zeros instead of addresses?
Solved! Go to Solution.
2024-05-16 03:44 PM
The problem was that due to floating point option not being enabled, somewhere in the matrix code a double precision, was being written to a signle precision S register.
I found out the example project I was applying touch gfx to, had the FPU disabled. "Project properties/C/C++ build/Settings/Tool Settings/ MCU Settings/ Floating-point unit" was set to none. I assigned it to FPv5-SP-D16. I also assigned floating point ABI to Hardware implementation. This option needs to match the linker library being used. It determines if software takes care of floating point conversion or the hardware (or a mix).
Cube IDE was no help in debugging, so I reached out to a colleague and they thought me how to use disassembly through debugger console and pin point exactly which assembly command is causing a hard fault. This was very interesting to figure out. I basically used disaassemble command and disassemble *<memory address> to figure out what is happening inside the function. Thank you @GaetanGodart for pointing that issue out, I performed a workaround and manually added the following script to a .cpp file and got past vector rendering issues.
#include <touchgfx/widgets/canvas/CWRVectorRenderer.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>
namespace touchgfx {
VectorRenderer* VectorRenderer::getInstance() {
static CWRVectorRendererRGB565 renderer;
return &renderer;
}
}
2024-05-16 06:24 AM
Hello @bornamm and welcome to the community!
In the TouchGFX SVG article it is mentioned that "Vector Rendering" have to be enabled to allow the use of SVG.
In your picture, this is the second line under "Additional Features" and it is currently set to "Disabled".
Enabling it could resolve your problem.
If this solves your problem, I invite you to select this message as "best answer".
Regards,
2024-05-16 03:44 PM
The problem was that due to floating point option not being enabled, somewhere in the matrix code a double precision, was being written to a signle precision S register.
I found out the example project I was applying touch gfx to, had the FPU disabled. "Project properties/C/C++ build/Settings/Tool Settings/ MCU Settings/ Floating-point unit" was set to none. I assigned it to FPv5-SP-D16. I also assigned floating point ABI to Hardware implementation. This option needs to match the linker library being used. It determines if software takes care of floating point conversion or the hardware (or a mix).
Cube IDE was no help in debugging, so I reached out to a colleague and they thought me how to use disassembly through debugger console and pin point exactly which assembly command is causing a hard fault. This was very interesting to figure out. I basically used disaassemble command and disassemble *<memory address> to figure out what is happening inside the function. Thank you @GaetanGodart for pointing that issue out, I performed a workaround and manually added the following script to a .cpp file and got past vector rendering issues.
#include <touchgfx/widgets/canvas/CWRVectorRenderer.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>
namespace touchgfx {
VectorRenderer* VectorRenderer::getInstance() {
static CWRVectorRendererRGB565 renderer;
return &renderer;
}
}
2024-05-17 01:41 AM
I am glad you were able to fix your issue!
Regards,