Floyd-Fish / ST7789-STM32

using STM32's Hardware SPI to drive a ST7789 based IPS displayer
GNU General Public License v3.0
304 stars 60 forks source link

Fix function ST7789_Fill_Color not fill correct color #26

Open codead opened 1 year ago

codead commented 1 year ago

Hello, function ST7789_Fill_Color is not correct because memset is not working with uint16_t data, and the uint16_t buffer should be swap 2 byte high and low . So, we have to modify this function to working correct: `void MemsetBuffer(uint16_t buf, uint16_t data, uint32_t size) { while(size--) { buf++ = data; } } /**

JorikWit commented 5 months ago

I can confirm that this is a working fix. Had the same issue. To clarify, this fix is only needed if u use DMA.

jorgie0 commented 4 months ago

I could not get MemsetBuffer to compile using STMCubeIDE so I changed it to: ` void MemsetBuffer(void m, uint16_t val, size_t count) { { char buf = m; union { uint8_t d8[2]; uint16_t d16; }u16 = {.d16 = val};

    while(count--)
    {
        *buf++ = u16.d8[0];
        *buf++ = u16.d8[1];
    }
    return m;
}

} I then called it using this slightly modified code: MemsetBuffer(disp_buf, convert_color, ST7789_WIDTH * HOR_LEN); for (i = 0; i < ST7789_HEIGHT / HOR_LEN; i++) { ST7789_WriteData(&disp_buf, sizeof(disp_buf)); } ` I moved the call to 'MemsetBuffer' out of the for loop as the buffer already contains what it needs to so we are just wasting clock cycles filling it up again.

igorpie commented 1 week ago

My non-dma fill function with close to DMA speed. Driver uses DMA for only fill, so it's not too useful and no memory buffer and memset needed.

void ST7789FillColor2(uint16_t color){
    int i;
    ST7789_Select();
    ST7789_SetAddressWindow(0, 0, ST7789_WIDTH - 1, ST7789_HEIGHT - 1);

    uint8_t data[] = {color >> 8, color & 0xFF};

    ST7789_DC_Set();
    for (i = 0; i < ST7789_WIDTH * ST7789_HEIGHT; i++)
        HAL_SPI_Transmit(&ST7789_SPI_PORT, data, 2, 1);
    ST7789_UnSelect();
}

And fast draw filled rectangle

void ST7789DrawFilledRectangle2(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color){
    ST7789_Select();
    int i;
    if (x >= ST7789_WIDTH || y >= ST7789_HEIGHT) return;
    if ((x + w) >= ST7789_WIDTH) w = ST7789_WIDTH - x;
    if ((y + h) >= ST7789_HEIGHT) h = ST7789_HEIGHT - y;

    ST7789_SetAddressWindow(x, y, x + w, y + h);
    uint8_t data[] = {color >> 8, color & 0xFF};
    ST7789_DC_Set();
    for (i = 0; i < w * h; i++)
        HAL_SPI_Transmit(&ST7789_SPI_PORT, data, 2, 1);
    ST7789_UnSelect();
}