2010-01-14 07:38 AM
ADC1 converts only 1st channel of regular group
2011-05-17 04:31 AM
Hello everyone,
using the ADC1 in combination with DMA I encountered the following problem: ADC1 is configured to convert a group of 5 different regular channels; continuous mode as well as scan modes is enabled. DMA1 is configured to transfer the results from the ADC1_DR (data register) to an array defined as u16 buffer[5]. The content of the array is sent to PC by USART2. Unfortunately all 5 values in the buffer array seem to be conversion results of the first channel of the regular group. Any guess? my code: --------------ADC1 configuration- void ADC1_Start_ConvGroup_1(u32 buffer_startaddress, u8 buffer_length_absolute) //starts continuous conversion of a group of regular channels; results are stored in buffer by DMA { ADC1_CR2 &= ~BIT1; //clear END OF CONVERSION bit DMA1_Ch1_SetTargetAddress(buffer_startaddress, (u16) buffer_length_absolute); //give start address of ADC1 conversion results buffer to DMA1 ADC1_SQR3 |= (BIT1 | BIT2 | BIT3); //select channel 14 as first one to convert in regular conversion //ADC1_SQR3 |= (BIT1 | BIT3); //set channel 10 as first one to convert in regular conversion ADC1_SQR3 |= (BIT5 | BIT6 | BIT8); //set channel 11 as second one to convert ADC1_SQR3 |= (BIT12 | BIT13); //set channel 12 as third one to convert ADC1_SQR3 |= (BIT15 | BIT17 | BIT18); //set channel 13 as fourth one to convert ADC1_SQR3 |= (BIT21 | BIT22 | BIT23); //set channel 14 as fifth one to convert ADC1_SQR1 |= (BIT20 | BIT22); //set length of group of channels to convert to 5 ADC1_CR2 |= BIT8; //enable DMA mode ADC1_CR1 |= BIT8; //enable scan mode ADC1_CR2 |= BIT1; //enable continuous mode return; } ----------------DMA configuration------- void DMA1_Init_Ch1(void) { /*Configure DMA1 channel 1 for ADC1*/ DMA1_CPAR1 = (u32)(ADC1_BASE + 0x4C); //set the ADC1 Data register as source for DMA transfers DMA1_CCR1 = 0; //set to default DMA1_CCR1 |= BIT13; //set channel priority bits to 10=''high'' DMA1_CCR1 |= BIT10; //set Memory Size to 16 bit DMA1_CCR1 |= BIT8; //set Peripheral memory size to 16 bit DMA1_CCR1 |= BIT7; //enable memory increment mode DMA1_CCR1 |= BIT5; //enable circular mode //DMA1_CCR1 |= BIT4; //data transfer direction: read from memory //DMA1_CNDTR1 = 5; //number of data to be transmitted; afterwards, DMA1_CNDTR7 is reloaded with this value if circular mode is enabled //DMA1_CCR1 |= BIT0; //enable channel return; } void DMA1_Ch1_SetTargetAddress(u32 address, u16 nod) { DMA1_CCR1 &= ~BIT0; //disable channel: reset bit 0 DMA1_CMAR1 = address; //set memory address to where the DMA will transfer data from the ADC1_DATA register DMA1_CNDTR1 = nod; //set number of data to transfer by DMA DMA1_CCR1 |= BIT0; //enable channel } best regards, Jan [ This message was edited by: j.bolting on 26-11-2009 22:53 ] [ This message was edited by: j.bolting on 26-11-2009 22:55 ]2011-05-17 04:31 AM
Hello,
I just wrote an ADC driver using DMA and it appears to work correctly in the scenario you described. The code is here: http://chibios.svn.sourceforge.net/viewvc/chibios/trunk/os/hal/platforms/STM32/ Look for adc_lld.c and adc_lld.h, I hope this can help. regards, Giovanni --- ChibiOS/RT2011-05-17 04:32 AM
Hi,
o.k., sorry, that was my fault. Obviously it was a mistake in the wiring on my testboard. Now everything works fine. best regards, jan [ This message was edited by: j.bolting on 14-01-2010 21:09 ] [ This message was edited by: j.bolting on 14-01-2010 21:10 ]