Question
STM32F4xx DMA IRQ problem
Posted on June 04, 2012 at 11:15
Hi all,
I'm using the STM Discovery EVM to make some sample program. I'm using IAR as compiler and CMSIS 2.1 In this example I simple set a timer with 50ms period and start DMA transfert on USART 3 The transfer is correctly done on the serial port (I see the transmitted sting using Hyperterminal on PC), but I have a problem on the DMA IRQ Handler routine, Infact when I check the TCIF flag I found that the DMA transfert is not complete (while the transfert is already done on serial port). Furthermore I check for any DMA tranfert error and I found that there are no error. Where I wrong? Here The revelant part of the code: First the define for DMA /* Definition for DMAx resources **********************************************/ #define USARTx_DR_ADDRESS ((uint32_t)USART3 + 0x04) #define USARTx_DMA DMA1 #define USARTx_DMAx_CLK RCC_AHB1Periph_DMA1 #define USARTx_TX_DMA_CHANNEL DMA_Channel_4 #define USARTx_TX_DMA_STREAM DMA1_Stream3 #define USARTx_TX_DMA_FLAG_FEIF DMA_FLAG_FEIF3 #define USARTx_TX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF3 #define USARTx_TX_DMA_FLAG_TEIF DMA_FLAG_TEIF3 #define USARTx_TX_DMA_FLAG_HTIF DMA_FLAG_HTIF3 #define USARTx_TX_DMA_FLAG_TCIF DMA_FLAG_TCIF3 #define USARTx_RX_DMA_CHANNEL DMA_Channel_4 #define USARTx_RX_DMA_STREAM DMA1_Stream1 #define USARTx_RX_DMA_FLAG_FEIF DMA_FLAG_FEIF1 #define USARTx_RX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF1 #define USARTx_RX_DMA_FLAG_TEIF DMA_FLAG_TEIF1 #define USARTx_RX_DMA_FLAG_HTIF DMA_FLAG_HTIF1 #define USARTx_RX_DMA_FLAG_TCIF DMA_FLAG_TCIF1 #define USARTx_DMA_TX_IRQn DMA1_Stream3_IRQn #define USARTx_DMA_RX_IRQn DMA1_Stream1_IRQn #define USARTx_DMA_TX_IRQHandler DMA1_Stream3_IRQHandler #define USARTx_DMA_RX_IRQHandler DMA1_Stream1_IRQHandler here the TX Buffer String uint8_t TxBuffer[]= ''^**********************************************************************\r\n\ Prova di invio di caratteri alla seriale per vedere se ne perde qualcuno\r\n\ Cosi vediamo come si comporta il uP e il PC sperando che entrambi ce la facciano\r\n\ **********************************************************************@''; Then the Timer IRQ Handler routine: void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); /* LED4 toggling with frequency = 4.57 Hz */ STM_EVAL_LEDToggle(LED4); capture = TIM_GetCapture1(TIM3); TIM_SetCompare1(TIM3, capture + CCR1_Val); if (!DMASet) SetDMA(); STM_EVAL_LEDToggle(LED4); } } Here MY routine for DMA settings void SetDMA(void) { DMASet = 1; DMA_DeInit(USARTx_TX_DMA_STREAM); DMA_InitStructureTX.DMA_PeripheralBaseAddr = USARTx_DR_ADDRESS; DMA_InitStructureTX.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructureTX.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructureTX.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructureTX.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructureTX.DMA_Mode = DMA_Mode_Normal; DMA_InitStructureTX.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructureTX.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructureTX.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructureTX.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructureTX.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructureTX.DMA_Channel = USARTx_TX_DMA_CHANNEL; DMA_InitStructureTX.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructureTX.DMA_Memory0BaseAddr = (uint32_t)TxBuffer; // DMA_InitStructureTX.DMA_BufferSize = 300; DMA_InitStructureTX.DMA_BufferSize = 300; // DMA_InitStructureTX.DMA_BufferSize = (uint16_t)BUFFERSIZE; DMA_Init(USARTx_TX_DMA_STREAM, &DMA_InitStructureTX); /* Enable DMA1_Stream3 Transfer complete interrupt */ DMA_ITConfig(USARTx_TX_DMA_STREAM, DMA_IT_TC, ENABLE); // /* Enable DMA1_Stream3 */ // DMA_Cmd(USARTx_TX_DMA_STREAM, ENABLE); // /* Enable DMA USART Tx Stream */ DMA_Cmd(USARTx_TX_DMA_STREAM, ENABLE); } At the end the DMA IRQ Handler routine void DMA1_Stream3_IRQHandler(void) { // STM_EVAL_LEDToggle(LED6); if(DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TCIF)) { DMA_ClearITPendingBit(DMA1_Stream3, DMA_IT_TCIF3); // /* Clear all DMA Streams flags */ //// DMA_ClearFlag(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_HTIF | USARTx_TX_DMA_FLAG_TCIF); // DMA_ClearFlag(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TCIF); // // /* Disable the DMA Stream */ // DMA_Cmd(USARTx_TX_DMA_STREAM, DISABLE); // // /* Disable the USART Tx DMA request */ // USART_DMACmd(USARTx, USART_DMAReq_Tx, DISABLE); STM_EVAL_LEDToggle(LED6); } if (DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TEIF)) STM_EVAL_LEDToggle(LED6); if (DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_HTIF)) STM_EVAL_LEDToggle(LED6); if (DMA_GetITStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_FEIF)) STM_EVAL_LEDToggle(LED6); }