cancel
Showing results for 
Search instead for 
Did you mean: 

DMA not responding stm32f3 discovery

d4ng3r09
Associate II
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.

6 REPLIES 6
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 Up vote any posts that you find helpful, it shows what's working..
d4ng3r09
Associate II
Posted on October 09, 2014 at 09:45

Ok thank you.

d4ng3r09
Associate II
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);

Posted on October 09, 2014 at 18:17

Do they need to be volatile?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
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 Up vote any posts that you find helpful, it shows what's working..
d4ng3r09
Associate II
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?