2008-02-12 04:59 AM
DMA Transfers through memory
2011-05-17 03:23 AM
I'm having trouble getting DMA transfers from the ADC to RAM to SPI2 to work properly. I've followed example 1 from App Note 2548 but can't seem to get the interrup from DMA channel 5 to fire properly. I need it to fire because my process of data transfer requires some smarts to reconfigure which external device I'm writing to every so often. Code from my DMA config function is below. Please let me know what I'm doing wrong.
My ADC DMA transfers appear to work, I just never get an interrupt (or even see flags) for the transfers on channel 5.Code:
void DMAConfig()
{ DMA_InitTypeDef DMA_InitStructure; ///////////// DMA channel1 configuration from ADC to memory buffer ///////////// DMA_DeInit(DMA_Channel1); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)0x4001244C; // ADC1 data register DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&adcDataBuffer[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 3; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA_Channel1, &DMA_InitStructure); // Enable DMA Channel1 DMA_Cmd(DMA_Channel1, ENABLE); ///////////// DMA channel 5 - Storing things to external memory ///////////// DMA_DeInit(DMA_Channel5); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; // SPI 2 data register; 0x4000380C DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&writeBuffer1[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = WRITE_BUFFER_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_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA_Channel5, &DMA_InitStructure); // Setup channel 5 interrupts DMA_ITConfig(DMA_Channel5, DMA_IT_TC, ENABLE); // Interrupt on transfer complete DMA_Cmd(DMA_Channel5, ENABLE); // Setup NVIC NVIC_InitTypeDef NVIC_InitStruct; NVIC_StructInit(&NVIC_InitStruct); NVIC_InitStruct.NVIC_IRQChannel = DMAChannel5_IRQChannel; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); } // end DMAConfigThanks in advance for any help!2011-05-17 03:23 AM
Just a quick thought, did you enable the DMA clock?
2011-05-17 03:23 AM
I did remember to enable the DMA clock, though failing to enable clocks has bitten me enough in the past.
After some more prodding around it turns out that since I didn't set the transfer to a circular mode I had to be sure to reload the buffer size register (CNDTRx) after each transfer.