STM32F7 DMA UART RX no Data seen.
I am working with the STM32F7. I am implementing a DMA communications handler, preferably using the HAL (but LL is also an option that I have tried). I have successfully implemented the TX side of the equation but, am unable to get the RX portion to put data into the buffer. Below I have detailed the HW configuration and provided the HAL based code to match. I can also provide the LL based code should anyone want to see that. Can someone help me to see the error of my ways?
I am hoping to use the idle line detection to allow variable packet size, but cannot get the RX to work even with a fixed packet size.
I have used the following references:
Example code for Idle Line with f4: https://github.com/MaJerle/STM32_USART_DMA_RX
DMA Controller Guide: https://www.st.com/content/ccc/resource/technical/document/application_note/27/46/7c/ea/2d/91/40/a9/DM00046011.pdf/files/DM00046011.pdf/jcr:content/translations/en.DM00046011.pdf
Platform: NUCLEO-F767ZI
RTOS: uC/OS-III
UART: UART4 (RX: PC11, TX: PC10)
UART Config:
#define MAIN_BOARD_UART_BAUD 115200
#define MAIN_BOARD_UART_WORDLENGTH UART_WORDLENGTH_8B
#define MAIN_BOARD_UART_STOPBITS UART_STOPBITS_1
#define MAIN_BOARD_UART_PARITY UART_PARITY_NONE
#define MAIN_BOARD_UART_HW_FLOW_CTL UART_HWCONTROL_NONE
#define MAIN_BOARD_UART_MODE UART_MODE_TX_RX
#define MAIN_BOARD_UART_OVERSAMPLING UART_OVERSAMPLING_16DMA, Channel, Stream: DMA1, Channel 4, Stream 4
DMA Config: See Code below
UART Init Code:
__HAL_RCC_UART4_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = USARTx_RX_PIN | USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
GPIO_InitStruct.Alternate = USARTx_RX_AF | USARTx_TX_AF;
//Init the UART - Configured thorugh macros in .h for portability
HAL_UART_MspInit(&CommUartHandle);
CommUartHandle.Instance = MAIN_BOARD_UART_INSTANCE;
CommUartHandle.Init.BaudRate = MAIN_BOARD_UART_BAUD;
CommUartHandle.Init.WordLength = MAIN_BOARD_UART_WORDLENGTH;
CommUartHandle.Init.StopBits = MAIN_BOARD_UART_STOPBITS;
CommUartHandle.Init.Parity = MAIN_BOARD_UART_PARITY;
CommUartHandle.Init.HwFlowCtl = MAIN_BOARD_UART_HW_FLOW_CTL;
CommUartHandle.Init.Mode = MAIN_BOARD_UART_MODE;
CommUartHandle.Init.OverSampling = MAIN_BOARD_UART_OVERSAMPLING;
if(HAL_UART_Init(&CommUartHandle) != HAL_OK)
{
BSP_LED_On(USER_LD2);
while(1) {;}
}
HAL_NVIC_SetPriority(UART4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(UART4_IRQn);
DMA Init Code:
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_DMA_CLEAR_FLAG(&dma_comm_rx, DMA_FLAG_TCIF2_6 | DMA_FLAG_HTIF2_6 | DMA_FLAG_TEIF2_6 | DMA_FLAG_DMEIF2_6 | DMA_FLAG_FEIF2_6);
dma_comm_rx.Instance = DMA1_Stream2;
dma_comm_rx.Init.Channel = DMA_CHANNEL_4;
dma_comm_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
dma_comm_rx.Init.PeriphInc = DMA_PINC_DISABLE;
dma_comm_rx.Init.MemInc = DMA_MINC_ENABLE;
dma_comm_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
dma_comm_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
dma_comm_rx.Init.Mode = DMA_CIRCULAR ;
dma_comm_rx.Init.Priority= DMA_PRIORITY_VERY_HIGH;
dma_comm_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
dma_comm_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
if(HAL_DMA_Init(&dma_comm_rx) != HAL_OK){
while(1);
}
__HAL_LINKDMA(huart,hdmarx,dma_comm_rx);
__HAL_DMA_ENABLE(&dma_comm_rx);
__HAL_DMA_ENABLE_IT(huart->hdmarx, DMA_IT_TC);
__HAL_DMA_ENABLE_IT(huart->hdmarx, DMA_IT_HT);
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);Interrupt Code:
void DMA1_Stream2_IRQHandler(void){
HAL_DMA_IRQHandler(&dma_comm_rx);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
OS_ERR os_err;
huart->gState = HAL_UART_STATE_READY;
OSSemPost(&CommRxSem,OS_OPT_POST_1,&os_err);
HAL_UART_Receive_DMA(&CommUartHandle, rxDmaBuffer, 10);
BSP_LED_Off(USER_LD3);
}
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart){
OS_ERR os_err;
huart->gState = HAL_UART_STATE_READY;
OSSemPost(&CommRxSem,OS_OPT_POST_1,&os_err);
BSP_LED_Off(USER_LD3);
}
void UART4_IRQHandler(void){
OS_ERR os_err;
if (LL_USART_IsEnabledIT_IDLE(UART4) && LL_USART_IsActiveFlag_IDLE(UART4)) {
LL_USART_ClearFlag_IDLE(UART4); // Clear IDLE line flag
//HAL_UART_Receive_DMA(&CommUartHandle, rxDmaBuffer, 100);
CommUartHandle.gState = HAL_UART_STATE_READY;
OSSemPost(&CommRxSem,OS_OPT_POST_1,&os_err);
BSP_LED_Off(USER_LD3);
}
HAL_UART_IRQHandler(&CommUartHandle);
}Receive Code:
status = HAL_UART_Receive_DMA(&CommUartHandle, rxDmaBuffer, 100);
if(status !=HAL_OK){
while(1){;}
}
while(DEF_TRUE){
BSP_LED_On(USER_LD3);
OSSemPend(&CommRxSem, 0, OS_OPT_PEND_BLOCKING, DEF_NULL, &os_err);
BSP_LED_Off(USER_LD3);
printf("end%s\n",rxDmaBuffer );
}