2010-07-22 06:25 AM
DMA interrupt
#dma-irq #stm-32 #stm32-uart-usart #dma2011-05-17 04:59 AM
Yes, though it's now 5 months later...
I've started in on getting DMA working and ran into this problem. Let me just say that the DMA interrupts do work, just not the handler function enabled through NVIC config - I will provide code. For my application I'm just testing so picked USART2RX which is DMA1_Channel6. I have USART1 TX DMA1_Channel4 enabled and it just spits out a dma message to test transmit with DMA. So i start by setting up RCC: /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable USART1, GPIOA, GPIOB and AFIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); /* Enable USART2 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Next I setup NVIC: /* Enable the DMA1 channel 6 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //Next I config DMA: DMA_InitTypeDef DMA_InitStructure; /* DMA1 Channel4 (triggered by USART1 Tx event) Config */ DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)TxBuffer1; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = TxBufferSize1; 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_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel4, DMA_IT_TC | DMA_IT_TE, ENABLE); DMA_ClearFlag(DMA1_FLAG_TC4); /* DMA1 Channel6 (triggered by USART2 Rx event) Config */ DMA_DeInit(DMA1_Channel6); DMA_InitStructure.DMA_PeripheralBaseAddr = USART2_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RxBuffer2; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = TxBufferSize1; DMA_Init(DMA1_Channel6, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel6, DMA_IT_HT | DMA_IT_TC | DMA_IT_TE, ENABLE); DMA_ClearFlag(DMA1_FLAG_TC6); //Next I setup Usarts and enable /* Init USART struct */ USART_InitStructure.USART_BaudRate = 115200; 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; /* Configure USART1 */ USART_Init(USART1, &USART_InitStructure); /* Configure USART2 */ USART_Init(USART2, &USART_InitStructure); /* Enable USART1 DMA Rx and TX request */ USART_DMACmd(USART1, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE); /* Enable USART2 DMA Rx and TX request */ USART_DMACmd(USART2, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE); /* Enable DMA1 Channel4 */ DMA_Cmd(DMA1_Channel4, ENABLE); /* Enable DMA1 Channel6 */ DMA_Cmd(DMA1_Channel6, ENABLE); /* Enable the USART1 */ USART_Cmd(USART1, ENABLE); /* Enable the USART2 */ USART_Cmd(USART2, ENABLE); END OF CODE SAMPLE... I can then sit in a while(1) and check the interrupt flags for say half transfer if ( DMA_GetITStatus(DMA1_IT_HT6) ) { ... //clear it flag and perform a usart1 tx } this works fine, so I stick a breakpoint in the interrupt handler in stm32f10x_it.c (of course in the proper one -> void DMA1_Channel6_IRQHandler(void){} and the code never reaches it :( Could be the interrupt handlers only work in M2M mode but I'm not sure. Lets get this Solved! hope u check ur post again zivkovic it may get answered. Thanks to any future posters for your time.2011-05-17 04:59 AM
UPDATE:
Got the code to enter the IRQ handler now forgot to enable global interrupts ''__enable_interrupt();''. There is just the problem of processing an RX dma and entering the dma IRQ at the same time - suggest using USART IRQ instead. This may be peripheral specific but in your case try enabling global interrupts first... feels like a monday.2013-01-18 05:05 AM
in:
void NVIC_DMA1_Ch6_Configuration( FunctionalState NewState ) { /* Enable the DMA1 channel 6 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } try replacing DMA1_Channel6_IRQChannel with DMA1_Channel6_IRQn2013-01-18 05:13 AM
Thread from 2+ years ago (May 17 is when the forum melted down, and was recovered, initial post has correct date). The IRQ is correct for V2.0 of the FW Library.