Hi.
I've 2 problems :
first is that my english is awfull. Sooooooorry.
Second is why i post ...
I use STM32F407 in bare metal code, Code::Blocks and gcc toolchain on Linux. Perfect !
My last project is to use ADC to convert 4 GPIO with DMA but without IRQ. It's the user software who enable conversion when i want ! Fréquency of µC is 8MHz ( low consomption and no clock management).
I've readen RM0090 §10 and 13 but i think i forgot one thing.
Without DMA, i can read ADC data in a scan mode ( group of channels) after InitADC1_DMA_F4() function .
ADC1 is connected to DMA2 channel 0 stream 0 ( RM0090 table 43 p.308).
Base adress of DMA2 registers is 0x4002 6400 ( RM0090 p.65) - Offset in RM0090 p.335.
But with DMA, the area of data don't have real data. Values must be 0 <= v <= 4096 ...
For information, i use DMA ( DMA2 - channel4 - stream2) with USART1 in bare metal code without problem.
start cycle n° 0
SWSTAR enable.
analog value IN1 = 23658498
analog value IN2 = 46465603
analog value IN3 = 51118835
analog value IN6 = 52298478
End cycle n° 0
It seems that data area ( BufferADC1[] ) don't contain values.
Strange : work fine in SCAN mode without DMA ...
Is, community, can help me ?
Thank you
Part of main program :
//---------------------------------- setup zone
#define SIZEBuffADC1 4 //Number of data ( 4 GPIO = 4 Data)
volatile unsigned long BufferADC1[SIZEBuffADC1]; //Area of datas ADC in RAM
InitPIOA_F4(); //Pour UART1 PA9-10 et DAC1 PA1,2,3,6
InitADC1_DMA_F4((unsigned long) SIZEBuffADC1); //ADC1 Param
InitDMA4ADC1_F4( BufferADC1, (unsigned long) SIZEBuffADC1); //DMA Param
//--------------------------------- loop zone
...
//................. Enable a software start for ADC
if( *ADC1_SR & 0x00000002) //if [EOC] != 0 ...
{
*ADC1_SR &= 0xFFFFFFFD ; //... Reset EOC - bit1 - (AND on a complete register)
*ADC1_CR2 |= ( 1<<30); //[SWSART] Enable a software start for ADC
}
//Later : Read BufferADC1[n] ( no problem in scan mode without DMA)
...
//-------------------------------- End of main
Init ADC function
void InitADC1_DMA_F4( unsigned long NbreConv)
{
//Enable ADC1 clock bus
*APB2_ENR |= (1<<8); //[ADC1EN] bit 8 = 1
//----------------- RAZ used registers before use-----------------
*ADC1_SQR1 &= 0xFF000000; //Reset all fields without reserved
*ADC1_SQR2 &= 0xC0000000; //Reset all fields without reserved
*ADC1_SQR3 &= 0xC0000000; //Reset all fields without reserved
*ADC1_CR1 &= 0xF43F0000; //Reset all fields without reserved
*ADC1_CR2 &= 0xC0000000; //Reset all fields without reserved
//------------------ Paramétrage des canaux IN ------------
//Number of channels for conversion ( [L] = n-1)
*ADC1_SQR1 |= (((NbreConv-1)&0x0000000F)<<20); //[L] bits 20 to 23
//Ordrer & numéro of channels ( IN1, 2, 3 &6)
*ADC1_SQR3 |= ( 0b00001<<0); //[SQ1] bits 0 à 4 = 00001 -> IN1
*ADC1_SQR3 |= ( 0b00010<<5); //[SQ2] bits 5 à 9 = 00010 -> IN2
*ADC1_SQR3 |= ( 0b00011<<10); //[SQ3] bits 10 à 14 = 00011 -> IN3
*ADC1_SQR3 |= ( 0b00110<<15); //[SQ4] bits 15 à 19 = 00110 -> IN6
//Duration of each channel conversion
//SMPR2 = canaux 0 à 9 - Used : ch1,2,3,6
//Duration of conversion = 13,5 cycles (+12,5 de base)
*ADC1_SMPR2 |= ( 0b010<<3); //[SMP1] bits 3,4,5 = 010
*ADC1_SMPR2 |= ( 0b010<<6); //[SMP2] bits 6,7,8 = 010
*ADC1_SMPR2 |= ( 0b010<<9); //[SMP3] bits 9,10,11 = 010
*ADC1_SMPR2 |= ( 0b010<<18); //[SMP6] bits 18,19,20 = 010
//----------------------- Modes of conversion ------------------
/*------ By fault ( after RAZ), these fields have good value ( = 0) :
ADC_CR2 [EXTSEL] unselected
ADC_CR2 [CONT] User launch conversion. No continue
------------------------------------------------------------------*/
//Mode SCAN of regulars channels §13.3.8 - Scan validate
*ADC1_CR1 |= ( 1<<8); //Bit 8 [SCAN] = 1
//EOC set after each channel converted. ( No at the end of group)
*ADC1_CR2 |= ( 1<<10); //Bit 10 [EOCS] = 1 - EOC set after each conv
*ADC1_CR2 |= ( 1<<9); //Bit 9 (DDCS) = 1 - DMA request if data available
*ADC1_CR2 |= ( 1<<8); //Bit 8 [DMA] = 1 - Use DMA
//----------------- End modes of conversion ------------------
//Start ADC
*ADC1_CR2 |= ( 1<<0); //Bit 0 (ADON) = 1
return;
}
Init DMA function
void InitDMA4ADC1_F4( volatile unsigned long *BuffADC, unsigned long BuffADC1size )
{
//Valide les horloges du bus AHB si pas déjà fait
*AHB1_ENR |= ( 1<<22); // ... pour la DMA2 - bit DMA2EN
//Memories/registers adress for data stream
*DMA2_S0PA = (unsigned long) ADC1_DR; //Data register ADC1 ( source)
*DMA2_S0M0A = (unsigned long) BuffADC; //Destination area in RAM
//Size of recept buffer = Nbre of IN to scan
*DMA2_S0NDT = (unsigned long) BuffADC1size; //buff size = transmit argument
//RAZ authorised fields
*DMA2_S0CR &= 0xF0100000; //Reset all fields without reserved
/*------ By fault ( after RAZ), these fields have good value ( = 0) :
DMA2_S0CR [DIR] Data stream direction periph->memory
DMA2_S0CR [CHSEL] Use chanel 0 ( ADC1 use DMA2-channel0-stream0)
------------------------------------------------------------------*/
*DMA2_S0CR |= (0b01<<16); //Priority - [PL] -> bits 17-16 = 01 = Medium
*DMA2_S0CR |= (0b01<<13); //Size of data mém- [MSIZE]-> 01 = 16bits
*DMA2_S0CR |= (0b01<<11); //Size of data périph- [PSIZE]-> 01 = 16bits
*DMA2_S0CR |= (1<<10); //Incrément memory pointer - [MINC]-> bit 10 = 1
*DMA2_S0CR |= (1<<8); //Buffer circulaire - [CIRC]-> bit 8 = 1
*DMA2_S0CR |= (1<<0); //Enable DMA2 - [EN] -> bit 0 = 1
}