cancel
Showing results for 
Search instead for 
Did you mean: 

DMA transfer is completed before transmitting all the data to SRAM (or data is corrupted)

EPerr.1
Associate

I am currently working on a touch screen for one of our products.

I built an LCD intel 8080 driver with the FMC and it's not working with DMA.

The image is only partially flushed to the screen.

It seems that there is some kind of limits to the transfer size that i don't know of ?

The use of the DMA is major to our application performance as printing a full screens takes 22ms in blocking mode.

I use a Frame buffer of 307200B the size of the screen. In the below example, code structure doesn't allow differences in the buffer data used by the API DMA/NODMA.

WITHOUT DMA

-Code:

CONFIGURATION

0693W00000WKX9dQAH.png 

RUN

HAL_StatusTypeDef res = HAL_SRAM_Write_8b(&hsram1, (uint32_t *)FMC_DATA_ADDR, (uint8_t *)buffer, len);
ASSERT(res==HAL_OK);

-Display:

0693W00000WKXGyQAP.jpg 

WITH DMA

-Code:

CONFIGURATION

0693W00000WKXDkQAP.png 

INIT

This is the only configuration Added to the gpma.c

  /* USER CODE BEGIN GPDMA1_Init 2 */
  __HAL_LINKDMA(&hsram1, hdma, DMA_TFT_CHANNEL_HANDLE);
  /* USER CODE END GPDMA1_Init 2 */

CB

/* USER CODE BEGIN 0 */
#include "gpdma.h"
#include "02_Mid/LVGL/lvgl_drivers.h"
#include "01_Drv/inc/ecran/ST7796S.h"
 
/**
  * @brief  DMA transfer complete callback.
  * @param  hdma pointer to a SRAM_HandleTypeDef structure that contains
  *                the configuration information for SRAM module.
  * @retval None
  */
void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
{
	if(hdma == &DMA_TFT_CHANNEL_HANDLE){
		st7796s_txCplt_irq(true);
	}
}
 
/**
  * @brief  DMA transfer complete error callback.
  * @param  hdma pointer to a SRAM_HandleTypeDef structure that contains
  *                the configuration information for SRAM module.
  * @retval None
  */
void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma)
{
	if(hdma == &DMA_TFT_CHANNEL_HANDLE){
		st7796s_txCplt_irq(false);
	}
}
/* USER CODE END 0 */

RUN

HAL_StatusTypeDef res = HAL_SRAM_Write_DMA(&hsram1, (uint32_t *)FMC_DATA_ADDR, (uint32_t *)buffer, len);
ASSERT(res==HAL_OK);
PRINTLN("len %d",len);

-Log:

0693W00000WKXGFQA5.png 

-Display:

0693W00000WKXGoQAP.jpg 

1 ACCEPTED SOLUTION

Accepted Solutions
EPerr.1
Associate

I missed the number max of block in DMA registers p689.

0693W00000WKYfpQAH.png 

I can only send 64kB max.

Another mistakes was to not change the len in the API when i'm using words.

HAL_StatusTypeDef res = HAL_SRAM_Write_8b(&hsram1, (uint32_t *)FMC_DATA_ADDR, (uint8_t *)buffer, len);

uint32_t buffersize = len/4.

Buffersize is not the size in bytes but the size of the array...

Inside the API this code manage the number of bytes...

if (data_width == DMA_DEST_DATAWIDTH_WORD){
       size = (BufferSize * 4U);
}
else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD){
          size = (BufferSize * 2U);
 }
else {
          size = (BufferSize);
 }

View solution in original post

1 REPLY 1
EPerr.1
Associate

I missed the number max of block in DMA registers p689.

0693W00000WKYfpQAH.png 

I can only send 64kB max.

Another mistakes was to not change the len in the API when i'm using words.

HAL_StatusTypeDef res = HAL_SRAM_Write_8b(&hsram1, (uint32_t *)FMC_DATA_ADDR, (uint8_t *)buffer, len);

uint32_t buffersize = len/4.

Buffersize is not the size in bytes but the size of the array...

Inside the API this code manage the number of bytes...

if (data_width == DMA_DEST_DATAWIDTH_WORD){
       size = (BufferSize * 4U);
}
else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD){
          size = (BufferSize * 2U);
 }
else {
          size = (BufferSize);
 }