/**********************************************
Function: Draws a solid color rectangle on the LCD
Input: x1 - X-axis starting coordinate
y1 - Y-axis starting coordinate
w - Rectangle width (pixels)
h - Rectangle height (pixels)
fill - 16-bit RGB color value
Output: None
***********************************************/
void Lcd_ColorFill(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h, uint16_t fill)
{
uint8_t *line_buffer;
uint16_t row_counter;
uint16_t pixel_idx;
line_buffer = (uint8_t *)malloc(2 * w);
if (!line_buffer) return;
BlockWrite_SetRegion(x1, x1 + w - 1, y1, y1 + h - 1);
SPI_CS_Low();
LCD_SendCmdViaSPI(0x72);
for (row_counter = 0; row_counter < h; row_counter++) {
for (pixel_idx = 0; pixel_idx < w; pixel_idx++) {
line_buffer[2 * pixel_idx] = (fill >> 8) & 0xFF;
line_buffer[2 * pixel_idx + 1] = fill & 0xFF;
}
HAL_SPI_Transmit(&hspi4, line_buffer, 2 * w, 20);
}
SPI_CS_High();
free(line_buffer);
line_buffer = NULL;
}
Enitial analysis shows the HardFault appears rooted in the BlockWrite_SetRegion() call. Typical root causes for such issues include stack overflow, invalid memory acces, or unhandled hardware constraints, though dynamic allocation didn’t resolve the failure.
The failure is triggered specifically by back-to-back identical rectangle fills:
Lcd_ColorFill(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_WHITE);
Lcd_ColorFill(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_WHITE);
A practical workraound leverages the LCD’s high refresh speed to mask a two-step intermediate color swap:
Lcd_ColorFill(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_WHITE);
Lcd_ColorFill(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_BLACK);
Lcd_ColorFill(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_WHITE);