AnsweredAssumed Answered

Restart Rx USART + DMA in STM32L1

Question asked by aguilar.genis on Jul 27, 2015
Latest reply on Jul 28, 2015 by Clive One
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.

Outcomes