Restart Rx USART + DMA in STM32L1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-07-27 2:09 AM
I am using an STM32L1 on a Nucleo-L152RE board. I have to devices I control through serial running at rather high baudrates, so I am trying to enable DMA on the USART. With the code below I can launch one Rx DMA, but the second one, which I start from the ISR never completes:
void uart_receive_dma() { DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &USART1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = UART_PACKET_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_Init(DMA1_Channel5, &DMA_InitStructure); /* RX */ DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); DMA_Cmd(DMA1_Channel5, ENABLE); USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); } void DMA1_Channel5_IRQHandler(void){
if (DMA_GetITStatus(DMA1_IT_TC5) != RESET) {
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_ClearFlag(DMA1_FLAG_TC5);
uart_receive_dma(); } int main(void) { RCC_Configuration(); GPIO_Configuration(); NVIC_Configuration(); USART_Configuration(); /* First Rx, works and MA1_Channel5_IRQHandler gets called */ uart_receive_dma(); while(1); }
The first DMA transfer works well, so I guess I am not clearing something before starting the second one, but I can't figure out what it is.
Depending on some external conditions, the real code doesn't always restart the DMA transfer from DMA1_Channel5_IRQHandler but restarts it from somewhere else, that's why I can't use the DMA in circular mode.
EDIT: I removed the line numbers, fixed an error when calling DMA_Init and checked the source of the interrupt, as suggested. Still, the interrupt is called only once.
#usart #dma #stm32l1
- Labels:
-
DMA
-
STM32L1 Series
-
UART-USART
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-07-27 3:52 AM
Pro Tip : When your simple example runs 80 lines, don't post 40 of them, and don't enable line numbering.
Make sure you've fully filled the DMA Init structure, and qualify the source of your interrupt. Don't use a variable to select the DMA if you've hard coded a value *everywhere* else.Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-07-27 7:41 AM
Thanks for the suggestions. I 'm now checking the source of the interrupt, but still no luck. The USART seems to work well in Tx mode using DMA and interrupts.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-07-27 7:54 AM
Unfortunately there are limits to static analysis.
How are you telling that the interrupt is not occurring? If you're sitting in a debugger is it probable you might cause the USART to overrun? Are the USART or DMA indicating an error conditions? Consider toggling a GPIO/LED.Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-07-28 3:40 AM
You were right. I was using either breakpoints on the interrupt routing or calling printf from there. After I stopped doing that, the DMA seems to work well.
Thanks a lot for your support.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-07-28 9:16 AM
In another sort of things, if I configure the UART with RTS/CTS flow contol, does the DMA controller set/check the CTS and RTS pins or do I need to handle them myself?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-07-28 9:24 AM
That's all managed by you and the USART. The DMA just recognizes the TXE and RXNE from the USART and services it.
I've covered RTS/CTS on the forum several times, in my opinion it's something you have to manage at a ''system'' level. And you'll have to read the reference manual to understand what the hardware does.Up vote any posts that you find helpful, it shows what's working..
