2021-06-17 09:02 AM
Hello,
I am trying to set the UART5 TX with the DMA. I am using Cube, and in the GUI I selected UART5 to asynchronous, and added DMA for UART5_TX. Then, in the generated code, I added this part as I didn't see initialization for the DMA (inside the MX_DMA_Init()):
/* Peripheral DMA init*/
hdma_uart5_tx.Instance = DMA1_Stream0;
//hdma_uart5_tx.Init.Channel = DMA_CHANNEL_4;
hdma_uart5_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_uart5_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart5_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart5_tx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart5_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart5_tx.Init.Mode = DMA_NORMAL;
hdma_uart5_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_uart5_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_uart5_tx);
__HAL_LINKDMA(&huart5,hdmatx,hdma_uart5_tx);
The Main function, I didn't do much except I added this code in the while(1):
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (HAL_UART_Transmit_DMA(&huart5,au8ch, 1) == HAL_OK)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
}
HAL_Delay(1000);
}
/* USER CODE END 3 */
Which is a code to transmit the first byte of an array. I connected the Nucleo-H753ZI board pins to a terminal software, and I didn't get anything. (Note that I was able to get something without using the DMA). The LED turned ON, which means the function is returning HAL_OK, but still nothing on the screen.
I tried to debug the code, I put a breakpoint in the function "void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)" and it stops there, which means it got the interrupt to send something, but then it goes into this autogenerated code:
if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
{
/* Transfer Error Interrupt management ***************************************/
if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != 0U)
{
/* Disable the transfer error interrupt */
((DMA_Stream_TypeDef *)hdma->Instance)->CR &= ~(DMA_IT_TE);
/* Clear the transfer error flag */
regs_dma->IFCR = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
/* Update error code */
hdma->ErrorCode |= HAL_DMA_ERROR_TE;
}
}
...
...
...
/* manage error case */
if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
{
if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != 0U)
{
hdma->State = HAL_DMA_STATE_ABORT;
/* Disable the stream */
__HAL_DMA_DISABLE(hdma);
do
{
if (++count > timeout)
{
break;
}
}
while((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U);
/* Process Unlocked */
__HAL_UNLOCK(hdma);
if((((DMA_Stream_TypeDef *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
{
/* Change the DMA state to error if DMA disable fails */
hdma->State = HAL_DMA_STATE_ERROR;
}
else
{
/* Change the DMA state to Ready if DMA disable success */
hdma->State = HAL_DMA_STATE_READY;
}
}
if(hdma->XferErrorCallback != NULL)
{
/* Transfer error callback */
hdma->XferErrorCallback(hdma);
}
}
}
Any idea what I may be missing?
Solved! Go to Solution.
2021-06-17 12:22 PM
Does that answer your question?
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
}
2021-06-17 12:50 PM
New update, so the previous memory map I did in the RAM.ld, I did the same in flash.ld file, and it started to transmit data now.
However, for some reason it is not transmitting what I am sending, and it is continuously transmitting. (not stopping after the 4 bytes I am sending)
2021-06-17 02:18 PM
@Community member and @TDK Thank you both for your help.
I figured it out. I had to build void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) function in which I put the values I need to send, also in the Cube GUI, I had to make it Normal not circular in order to send the data only once.
It is working to send one array now. Thanks!
Karim