AnsweredAssumed Answered

No interrupt from DMA

Question asked by hzcodec on Sep 29, 2016
Latest reply on Sep 29, 2016 by hzcodec
I'm trying to receive serial data using USART1 and DMA in 3 different chunks.

Between I'm setting the buffer size in the DMA (2 bytes, 1 byte, 10 bytes) using the function set_dma_buffer_size().

The first two attempts are OK. I get an interrupt from DMA after 2 bytes and 1 byte.
However when the last 10 bytes arrives, I don't get any interrupt at all.

The last 10 bytes are in concecutive order.

So can anyone see what I'm doing wrong here?


void GPIO_Usart_1_Configuaration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
 
    // enable USART clocks
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
 
    // setup port A
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9 |  // USART1_TX
                                    GPIO_Pin_10;  // USART1_RX
 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_7);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_7);
 
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    // setup USART1
    USART_InitTypeDef USART_InitStructure;
    USART_ClockInitTypeDef USART_ClockInitStructure;
 
    // setup USART1_ClockInitStruct member with its default value
    USART_ClockStructInit(&USART_ClockInitStructure);
    USART_ClockInit(USART1, &USART_ClockInitStructure);
     
    USART_InitStructure.USART_BaudRate            = BAUDRATE_57600;
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_Parity              = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
 
    USART_Init(USART1, &USART_InitStructure);
 
    // enable DMA interface for RX
    USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);  // USART_CR3, mdw 0x40013808
 
    // enable USART1 port
    USART_Cmd(USART1, ENABLE);
}
 
void GPIO_Dma_1_Configuaration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
 
    // enable DMA clocks
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
    /* DMA2 channel5 configuration */
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->RDR;          // DMA_CPAR, mdw 0x40020060
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)rx_buffer;             // DMA_CMAR, mdw 0x40020064
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize         = 10;                              // DMA_CNDTR, mdw 0x4002005C
    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_Circular;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;               // DMA_CCR, mdw 0x40020058
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
 
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
 
    // enable DMA interrupt
    NVIC_EnableIRQ(DMA1_Channel5_IRQn);
 
    // enable transfer complete interrupt
    DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); // DMA_CCR, mdw 0x4002 0058
 
    // enable DMA1 channel5
    DMA_Cmd(DMA1_Channel5, ENABLE);
}

void DMA1_Channel5_IRQHandler(void)
{
    // handle DMA IRQ
}
 
void set_dma_buffer_size(int bufferSize)
{
    DMA1_Channel5->CCR &= ~DMA_CCR_EN;                // DMA_CCR,   mdw 0x40020058
    DMA1_Channel5->CCR &= ~DMA_CCR_TCIE;
    DMA1_Channel5->CNDTR = (uint32_t)bufferSize;      // DMA_CNDTR, mdw 0x4002005C
    DMA1_Channel5->CCR |= DMA_CCR_TCIE;
    DMA1_Channel5->CCR |= DMA_CCR_EN;
}

int main()
{
    GPIO_Usart_1_Configuaration();
    GPIO_Dma_1_Configuaration();
     
    set_dma_buffer_size(2);
    set_dma_buffer_size(RX_BUFFER_SIZE_2);
    // handle DMA IRQ first time, OK
     
    set_dma_buffer_size(1);
    set_dma_buffer_size(RX_BUFFER_SIZE_1);
    // handle DMA IRQ second time, OK
     
    set_dma_buffer_size(10);
    set_dma_buffer_size(RX_BUFFER_SIZE_10);
    // handle DMA IRQ third time, not OK
}

Outcomes