Skip to main content
Graduate II
July 2, 2023
Solved

Using SPI with DMA

  • July 2, 2023
  • 4 replies
  • 12874 views

Hi All, I'm using an STM32F1 with a 240x240 LCD screen that comunicates with the micro by SPI (with DMA). The screen uses the ST7789 driver (I supose it is not important). I'm working with RGB565 color format.

The problem that I have is, for example, when I'm using the ST7789_Fill_Color(YELLOW); the SPI uses the DMA and the LCD shoul be yellow but it's not. If yellow is 0b1111 1111 1110 0000 the DMA only sends to SPI the LSB (0b0000 0000 1110 0000) witch is a wrong color.
When I do the same without DMA it work's fine!

The DMA is configures this way:

BTurc2_0-1688298032648.png

I tried every configuration possible but nothing works. My question is why the DMA only graps the first byte of a color and what I have to change in order to send the real color.

Thanks in advance!!!

 

    This topic has been closed for replies.
    Best answer by BTurc.2

    Sorry for wasting your time. I found the problem. It is not the DMA fault. The problem is with the library of the LCD.

    Thanks all for the help!!

    4 replies

    Visitor II
    July 2, 2023

    Hi.

    Is your spi peripheral configured correctly?

    Do you see any DMA error?

    Could you share code?

    BTurc.2Author
    Graduate II
    July 2, 2023

    The SPI is configured as so:

    BTurc2_0-1688302636605.png

    Maby something it is not configured propertly because I have this error:

    BTurc2_1-1688302895891.png

    This error sometimes dissapears and I don't know why!

    Thanks for the help!

     

    Super User
    July 2, 2023

    you didnt set memory increment - so dma just doing 1 transfer . not very useful...

    AScha3_0-1688306444836.png

    check "memory" !

    Visitor II
    July 2, 2023

    As i can see the spi is configured as 8 bit data size and your dma is 16bits.

    Make spi 16 bits and see if it works.

    Maybe sharing inside of the function st7768_writedata would help much better.

    BTurc.2Author
    Graduate II
    July 2, 2023

    Initially the DMA was configured at 8 bit but doing tests I changed It. The st7769_witedata():

    static void ST7789_WriteData(uint8_t *buff, size_t buff_size)
    {
    ST7789_Select();
    ST7789_DC_Set();
     
    // split data in small chunks because HAL can't send more than 64K at once
     
    while (buff_size > 0) {
    uint16_t chunk_size = buff_size > 65535 ? 65535 : buff_size;
    #ifdef USE_DMA
    if (DMA_MIN_SIZE <= buff_size)
    {
    HAL_SPI_Transmit_DMA(&ST7789_SPI_PORT, buff, chunk_size);
    while (ST7789_SPI_PORT.hdmatx->State != HAL_DMA_STATE_READY)
    {}
    }
    else
    HAL_SPI_Transmit(&ST7789_SPI_PORT, buff, chunk_size, HAL_MAX_DELAY);
    #else
    HAL_SPI_Transmit(&ST7789_SPI_PORT, buff, chunk_size, HAL_MAX_DELAY);
    #endif
    buff += chunk_size;
    buff_size -= chunk_size;
    }
     
    ST7789_UnSelect();
    }
    Graduate II
    July 2, 2023

    How is "disp_buf" declared? You may need to use "&" when calling ST7789_Write_Date ... like :

    ST7789_Write_Date(&disp_buf,...

    BTurc.2AuthorAnswer
    Graduate II
    July 2, 2023

    Sorry for wasting your time. I found the problem. It is not the DMA fault. The problem is with the library of the LCD.

    Thanks all for the help!!

    Graduate
    July 18, 2023

    Hello @BTurc.2 .
    I'm having the same problem as you. And I'm thinking it's the ST7789 library because everything else in my code is correct or as in the example. So you changed the library?

    Would it be possible for you to send me your library? Or would it be possible to send me a github link?

    Explorer
    November 12, 2025

    Hello BTurc.2, I have same problem with you. This is my fixed part, and it's work well with my stm32f401.

    Hope this helps.

     

    void ST7789_Fill_Color(uint16_t color)

    {

    uint32_t i,color_convert;

    uint16_t disp_buf_size=ST7789_WIDTH * HOR_LEN;

    ST7789_SetAddressWindow(0, 0, ST7789_WIDTH - 1, ST7789_HEIGHT - 1);

    ST7789_Select();

     

    #ifdef USE_DMA

    color_convert=(color<<11) | ((color>>11)<<6) | ((color<<5)>>10);

    for (uint32_t i=0;i<disp_buf_size;i++) {

    disp_buf[i]=color_convert;

    }

     

    for (i = 0; i < ST7789_HEIGHT / HOR_LEN; i++)

    {

    // memset(disp_buf, color, sizeof(disp_buf));

     

    ST7789_WriteData((uint8_t *)disp_buf, sizeof(disp_buf));

     

    }

    #else

    uint16_t j;

    for (i = 0; i < ST7789_WIDTH; i++)

    for (j = 0; j < ST7789_HEIGHT; j++) {

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

    ST7789_WriteData(data, sizeof(data));

    }

    #endif

    ST7789_UnSelect();

    }

     

     

    Explorer
    November 13, 2025

    Hi all, about last reply that function sometime has wrong color. Then, I used logic analyzer and find out my dma spi output data is shift 1 bit : 1 111111011100100 become 111111011100100 1. i will still research.....