Skip to main content
sjackson
Associate III
February 12, 2008
Question

DMA Transfers through memory

  • February 12, 2008
  • 3 replies
  • 897 views
Posted on February 12, 2008 at 13:59

DMA Transfers through memory

    This topic has been closed for replies.

    3 replies

    sjackson
    sjacksonAuthor
    Associate III
    May 17, 2011
    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 III
    May 17, 2011
    Posted on May 17, 2011 at 12:23

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

    sjackson
    sjacksonAuthor
    Associate III
    May 17, 2011
    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.