cancel
Showing results for 
Search instead for 
Did you mean: 

DMA Transfers through memory

sjackson
Associate II
Posted on February 12, 2008 at 13:59

DMA Transfers through memory

3 REPLIES 3
sjackson
Associate II
Posted on May 17, 2011 at 12:23

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 DMAConfig

Thanks in advance for any help!

smart
Associate II
Posted on May 17, 2011 at 12:23

Just a quick thought, did you enable the DMA clock?

sjackson
Associate II
Posted on May 17, 2011 at 12:23

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.