Question
Restart Rx USART + DMA in STM32L1
Posted on July 27, 2015 at 11:09
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