2018-03-27 03:55 AM
Hello,
I have ported an exisiting code for a UART peripheral that uses DMA to copy the data from stm32F4 to an stm32L4
When I send a character through the UART bus, and wait for the IDLE line detection interrupt to accure, I got the following :
char received in the RDR (receive data register), but is not copied in the DMA Rx buffer that I defined previous
Here how I setup the UART
_t_DeviceHandle.Instance = USART3;
_t_Device
Handle.Init.BaudRate = 9600; _t_Device
Handle.Init.WordLength = UART_WORDLENGTH_8B; _t_Device
Handle.Init.StopBits = UART_STOPBITS_1; _t_Device
Handle.Init.Parity = UART_PARITY_NONE; _t_Device
Handle.Init.Mode = UART_MODE_TX_RX; _t_Device
Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;// UART_HWCONTROL_RTS_CTS; _t_Device
Handle.Init.OverSampling = UART_OVERSAMPLING_16; _t_Device
Handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; _t_Device
Handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&_t_DeviceHandle) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /* Configure USART interrupt */ HAL_NVIC_SetPriority(USART3_IRQn, 5, 0U); HAL_NVIC_EnableIRQ(USART3_IRQn); }Here is how I setup my DMA
__HAL_RCC_DMA1_CLK_ENABLE();
_t_DeviceRxDmaStreamHandle.Instance =
DMA1_Channel3
; _t_Device
RxDmaStreamHandle.Init.Direction = DMA_PERIPH_TO_MEMORY; _t_Device
RxDmaStreamHandle.Init.PeriphInc = DMA_PINC_DISABLE; _t_Device
RxDmaStreamHandle.Init.MemInc = DMA_MINC_ENABLE; _t_Device
RxDmaStreamHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; _t_Device
RxDmaStreamHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; _t_Device
RxDmaStreamHandle.Init.Mode = DMA_NORMAL; _t_Device
RxDmaStreamHandle.Init.Priority = DMA_PRIORITY_HIGH; if(HAL_DMA_Init(&_t_Device
RxDmaStreamHandle) != HAL_OK) { assert_failed((uint8_t*)__FILE__, __LINE__); }// linking DMA channel with the UART RX
__HAL_LINKDMA(&_t_
Device
Handle, hdmarx, _t_Device
RxDmaStreamHandle);// defining memory address, size...etc
HAL_UART_Receive_DMA(&_t_
Device
Handle, __au8_StorageBuffer, __u16_MaxDataLength);I checked the DMA register and they seemed correct :
CCR3->EN = 1 // channel is enabled
CCR3->TCIE = 1 // transfert complete interrupt is enabled
CCR3->TEIE = 1 // error interrupt enabled
CCR3->DIR = 0 // from peripheral to memory
CPAR3 has the UART RDR address
CMAR3 has the Rx buffer address.
I'm not sure what I missed here. Any suggesting on how I can debug this further ?
Thank you
regards
#dma #stm32l4 #hal #uartSolved! Go to Solution.
2018-03-29 03:58 AM
Looking at Cube's sources it appears you are supposed to fill the required setting of CSELR into .Request field of the init struct.
JW
2018-03-27 04:38 AM
Hello
c.malki
which channel and stream setup do you use?
Best regards,
Tilen
2018-03-27 05:02 AM
Hi Tilen,
Sorry I forget to mention that.
I use
DMA1_Channel3 for Rx and DMA1_Channel2 for Tx. and STM32L475
I added them in my post
2018-03-27 04:34 PM
And the respective field in DMA_CSELR is set properly?
JW
2018-03-29 03:38 AM
The CSELR register is set to 0 which is not good !
Based on the manual, the bits 11:8 should be set to 0010 to map the DMA to USART3_RX.
I'm trying to figure it out but the only place where the DMA_CSELR is set is in the HAL_DMA_Init()
/* Reset request selection for DMA1 Channelx */
DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << hdma->ChannelIndex);/* Configure request selection for DMA1 Channelx */
DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex));looking into this function, it seems that that both variables Init.Request and hdma->ChannelIndex are set inside the DMA init function aswell !
Any idea how to set this properly ?
Thx
2018-03-29 03:53 AM
I don't use Cube so I have no idea, sorry.
JW
2018-03-29 03:58 AM
Looking at Cube's sources it appears you are supposed to fill the required setting of CSELR into .Request field of the init struct.
JW
2018-04-04 02:47 AM
Indeed, I missed this configuration
Thank you for the help