Skip to main content
d4ng3r09
Associate III
October 8, 2014
Question

DMA not responding stm32f3 discovery

  • October 8, 2014
  • 6 replies
  • 891 views
Posted on October 08, 2014 at 22:46

Hi,

I am trying to read a sequence of 2 values on ADC1 .I made the code without dma work then i decided to use the dma.I did some research and came out with those lines of code: When i debugg the buffer array keeps its defalut value. Any helpfull suggestions?

#include ''stm32f30x.h''
#include ''stm32f30x_adc.h''
#include ''stm32f30x_gpio.h''
#include ''stm32f30x_rcc.h''
#include ''stm32f30x_dma.h''
__IO uint32_t TimingDelay = 10;
ADC_InitTypeDef ADC_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
int ConvValue = 0;
DMA_InitTypeDef DMA_InitStruct;
int DataBuffer[]={1,2};
void AdcConfig()
{TimingDelay = 10;
int calibration_value;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinLockConfig(GPIOA, GPIO_Pin_0);
GPIO_PinLockConfig(GPIOA, GPIO_Pin_1);
ADC_InitStruct.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable;
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStruct.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
ADC_InitStruct.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_OverrunMode = DISABLE;
ADC_InitStruct.ADC_AutoInjMode = DISABLE;
ADC_InitStruct.ADC_NbrOfRegChannel = 2;
ADC_Init(ADC1,&ADC_InitStruct);
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_Circular ;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = 9;
ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_1Cycles5);
ADC_VoltageRegulatorCmd(ADC1, ENABLE);
do {
TimingDelay--;
} while (TimingDelay > 0);
ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) != RESET);
calibration_value = ADC_GetCalibrationValue(ADC1);
ADC_RegularChannelSequencerLengthConfig(ADC1, 2);
ADC_Cmd(ADC1, ENABLE);
}
void DmaConfig()
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/*-------------- Reset DMA init structure parameters values ------------------*/
DMA_InitStruct.DMA_PeripheralBaseAddr = ADC1->DR;
DMA_InitStruct.DMA_MemoryBaseAddr = DataBuffer;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_BufferSize = 2;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_Low;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1,&DMA_InitStruct);
DMA_Cmd(DMA1_Channel1,ENABLE);
}
int main(void) {
int i=0;
int j=0;
DmaConfig();
AdcConfig();
ADC_DMACmd(ADC1,ENABLE);
ADC_StartConversion(ADC1);
while (1) {
TimingDelay++;
i=DataBuffer[0];
j=DataBuffer[1];
}
return (0);
}
//j,i and Timing delay are just for debugging purpose.

    This topic has been closed for replies.

    6 replies

    Tesla DeLorean
    Guru
    October 8, 2014
    Posted on October 08, 2014 at 22:53

    DMA_InitStruct.DMA_PeripheralBaseAddr = &ADC1->DR; // IT'S AN ADDRESS, NOT THE CONTENT

    12-bit values fit in a 16-bit Half Word, not 8-bit, and not 32-bit int

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    d4ng3r09
    d4ng3r09Author
    Associate III
    October 9, 2014
    Posted on October 09, 2014 at 09:45

    Ok thank you.

    d4ng3r09
    d4ng3r09Author
    Associate III
    October 9, 2014
    Posted on October 09, 2014 at 12:20

    I changed Dma configuration to this one according to your remarks but it still doesn t give any logical values in the buffer:I don't even get 0 on both channels when i attach them to the ground.

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_InitStruct.DMA_MemoryBaseAddr =(uint32_t)DataBuffer;
    DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStruct.DMA_BufferSize = 2;
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStruct.DMA_Priority = DMA_Priority_High;
    DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1,&DMA_InitStruct);
    DMA_Cmd(DMA1_Channel1,ENABLE);

    Tesla DeLorean
    Guru
    October 9, 2014
    Posted on October 09, 2014 at 18:17

    Do they need to be volatile?

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    October 9, 2014
    Posted on October 09, 2014 at 18:37

    This works for me...

    // STM32 ADC Dual Channel STM32F3-Discovery - sourcer32@gmail.com
    /**************************************************************************************/
    // ADC1 ADC2 ADC3 ADC4
    // IN1 PA0* PA4 PB1 PE14*
    // IN2 PA1 PA5* PE9* PE15*
    // IN3 PA2 PA6* PE13* PB12
    // IN4 PA3 PA7* --- PB14
    // IN5 PF4 PC4 PB13 PB15
    //
    // *Used on STM32F3-Discovery
    // Free pins located in STM32F3-Discovery manual, UM1570
    /**************************************************************************************/
    #include ''stm32f3_discovery.h''
    #include ''stm32f30x.h''
    #include <
    stdio.h
    >
    /**************************************************************************************/
    #define BUFSIZE 1 // Small for no useful reason
    volatile uint16_t ADCConvertedValues[2 * BUFSIZE];
    uint16_t CalibrationValue;
    /**************************************************************************************/
    void ADC_GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    /* Enable GPIOA and GPIOB Periph clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    /* ADC Channels configuration */
    /* Configure as analog input */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    }
    /**************************************************************************************/
    void ADC12_DMA_Configuration(void)
    {
    DMA_InitTypeDef DMA_InitStructure;
    /* Enable DMA1 clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    /* DMA configuration */
    /* DMA1 Channel1 Init Test */
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // The register of a singular ADC
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValues[0];
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = BUFSIZE * 2;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure); // ADC1
    }
    /**************************************************************************************/
    void ADC_Configuration(void)
    {
    ADC_InitTypeDef ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    volatile int i;
    /* Configure the ADC clocks */
    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1);
    /* Enable ADC1/2 clocks */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
    /* ADC GPIO configuration */
    ADC_GPIO_Configuration();
    /* ADC DMA Channel configuration */
    ADC12_DMA_Configuration();
    /* ADC Calibration procedure */
    ADC_VoltageRegulatorCmd(ADC1, ENABLE);
    /* Insert delay equal to 10 µs */
    for(i=0; i<
    10000
    ; i++);
    ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1) != RESET);
    CalibrationValue
    = 
    ADC_GetCalibrationValue
    (ADC1);
    /* ADC configuration */
    ADC_CommonInitStructure.ADC_Mode
    = 
    ADC_Mode_Independent
    ;
    ADC_CommonInitStructure.ADC_Clock
    = 
    ADC_Clock_AsynClkMode
    ;
    ADC_CommonInitStructure.ADC_DMAAccessMode
    = 
    ADC_DMAAccessMode_Disabled
    ; // Not Multi Mode
    ADC_CommonInitStructure.ADC_DMAMode
    = 
    ADC_DMAMode_Circular
    ;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay
    = 
    10
    ;
    ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
    /* */
    ADC_InitStructure.ADC_ContinuousConvMode
    = 
    ADC_ContinuousConvMode_Enable
    ; // Freerun
    ADC_InitStructure.ADC_Resolution
    = 
    ADC_Resolution_12b
    ;
    ADC_InitStructure.ADC_ExternalTrigConvEvent
    = 
    ADC_ExternalTrigConvEvent_0
    ; // Not using
    ADC_InitStructure.ADC_ExternalTrigEventEdge
    = 
    ADC_ExternalTrigEventEdge_None
    ;
    ADC_InitStructure.ADC_DataAlign
    = 
    ADC_DataAlign_Right
    ;
    ADC_InitStructure.ADC_OverrunMode
    = 
    ADC_OverrunMode_Disable
    ;
    ADC_InitStructure.ADC_AutoInjMode
    = 
    ADC_AutoInjec_Disable
    ;
    ADC_InitStructure.ADC_NbrOfRegChannel
    = 
    2
    ;
    ADC_Init(ADC1, &ADC_InitStructure);
    /* ADC1 regular configuration */
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_61Cycles5); // PA1
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_61Cycles5); // PA2
    /* Configures the ADC DMA */
    ADC_DMAConfig(ADC1, ADC_DMAMode_Circular);
    /* Enable the ADC DMA */
    ADC_DMACmd(ADC1, ENABLE);
    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);
    /* wait for ADC1 ADRDY */
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
    /* Enable the DMA channel */
    DMA_Cmd(DMA1_Channel1, ENABLE);
    /* Start ADC1 Software Conversion */
    ADC_StartConversion(ADC1);
    }
    /**************************************************************************************/
    void DMA1_Channel1_IRQHandler(void) // X Hz
    {
    /* Test on DMA1 Channel1 Transfer Complete interrupt */
    if(DMA_GetITStatus(DMA1_IT_TC1))
    {
    /* Clear DMA1 Channel1 Half Transfer, Transfer Complete and Global interrupt pending bits */
    DMA_ClearITPendingBit(DMA1_IT_GL1);
    STM_EVAL_LEDToggle(LED3); // X/2 Hz
    }
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable the DMA1 CH1 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel
    = 
    DMA1_Channel1_IRQn
    ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
    = 
    0
    ;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority
    = 
    1
    ;
    NVIC_InitStructure.NVIC_IRQChannelCmd
    = 
    ENABLE
    ;
    NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    int main(void)
    {
    /* Initialize LEDs available on STM32F-Discovery board */
    STM_EVAL_LEDInit(LED3);
    STM_EVAL_LEDInit(LED4);
    /* Turn on LD3 */
    STM_EVAL_LEDOn(LED3);
    STM_EVAL_LEDOn(LED4);
    NVIC_Configuration();
    ADC_Configuration();
    /* Enable DMA1 Channel1 Transfer Complete interrupt */
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
    while(1) // Don't want to exit
    {
    if (ADCConvertedValues[0] != 0xFFFF)
    {
    printf(''%03X %03
    X'', ADCConvertedValues[0], ADCConvertedValues[1]);
    ADCConvertedValues[0] = 0xFFFF;
    }
    }
    }
    //******************************************************************************
    // Rough SWV support in Keil, STM32F3-Discovery, Make SB10 to connect PB3/SWO
    //******************************************************************************
    #include <rt_misc.h>
    #pragma import(__use_no_semihosting_swi)
    struct __FILE { int handle; /* Add whatever you need here */ };
    FILE __stdout;
    FILE __stdin;
    int fputc(int ch, FILE *f)
    {
    ITM_SendChar(ch);
    return(ch);
    }
    int fgetc(FILE *f)
    {
    char ch;
    ch = 1;
    return((int)ch);
    }
    int ferror(FILE *f)
    {
    /* Your implementation of ferror */
    return EOF;
    }
    void _ttywrch(int ch)
    {
    ITM_SendChar(ch);
    }
    void _sys_exit(int return_code)
    {
    label: goto label; /* endless loop */
    }
    //******************************************************************************
    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t* file, uint32_t line)
    {
    /* User can add his own implementation to report the file name and line number,
    ex: printf(''Wrong parameters value: file %s on line %d
    
    '', file, line) */
    /* Infinite loop */
    while (1)
    {
    }
    }
    #endif
    //******************************************************************************

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    d4ng3r09
    d4ng3r09Author
    Associate III
    October 12, 2014
    Posted on October 12, 2014 at 21:35

    Actually , my code worked great when i changed the buffer size to one which is weird.Any potential explanations?