| Welcome to AT91SAM Community Forum http://www.at91.com/samphpbb/ |
|
| ADC + PDC - Understanding Problem http://www.at91.com/samphpbb/viewtopic.php?f=15&t=2613 |
Page 1 of 1 |
| Author: | theodor [ Tue Mar 06, 2007 3:18 pm ] |
| Post subject: | ADC + PDC - Understanding Problem |
Hi, iam new to the AT91s. I read the Datasheed of the SAM7S32 and want to make an ADC with using the DMA Controller to sample ~1000 Values at 250Khz with 8Bit Resolution. It´s not clear to me how the ADC triggers the PDC. The Datasheed says the PDC is triggert when "TXRDY and RXRDY Signals" occour. Does the ADC send out this Singals to the Bus automaticly when it finished a conversation? What are this for Singals? I read,the ADC can be triggert by one of the Countersoutputs Rising Edge.But my device (CCD-CIS Sensor) has only stable data at the falling edge of its clock. It is possible to configure one Timer with a Phasedifferent of Pi? So one Timer will clock the external Device and the other will clock the ADC. Thank you for ur help und sorry for my poor English. |
|
| Author: | JamesM [ Thu Sep 10, 2009 6:21 pm ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
I found that it is best to search for "PDC" in the ADC section of the specification to find all references to PDC related info. The answer is that the DRDY signal initiates the DMA xfer. |
|
| Author: | micha1999 [ Fri Sep 18, 2009 4:45 pm ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Theodor, read the PDC section of the datasheet to understand how DMA works. The signals you are referring to would probably be flags in the ADC's status register. You can program an interrupt to call your function when the flag is set. |
|
| Author: | mjbcswitzerland [ Fri Sep 25, 2009 5:12 pm ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi The DMA operation of the ADC is quite easy to use. The following code is about all that is needed to configure it: ADC_RPR = (unsigned long)adc_setup->int_adc_result; // transfer start location ADC_RCR = adc_setup->int_samples; // transfer count ADC_PTCR = PDC_RXTEN; // enable transfer ADC_IER = ADC_ENDRX; // enable interrupt on transfer complete This causes the PDC to store adc_setup->int_samples samples in the buffer adc_setup->int_adc_result. When all samples have completed, an end of transfer interrupt is generated. The sample triggering can be controlled by rising edges on ADTRG. If you would prefer falling edges it may be easiest to insert an inverter in the path. Regards Mark http://www.uTasker.com |
|
| Author: | samuel_zhang [ Fri Mar 12, 2010 5:04 am ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Mark, If the PDC "Receiver Counter" reaches zero, the next PDC received data will automaticcally write to the location which "Receiver Next Pointer" point to ? I can't find how the "Receiver Next pointer" works in the manual. Regards Samuel |
|
| Author: | mjbcswitzerland [ Fri Mar 12, 2010 1:27 pm ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Samuel When the counter reaches 0 the DMA operation will terminate so no more copies take place. There is an interrupt generated when this happens so that following operation can be started if desired. Regards Mark www.uTasker.com |
|
| Author: | samuel_zhang [ Mon Mar 15, 2010 7:35 am ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Mark, I find this from the manual (Page of 141 at DOC6120.pdf) "The counters are decremented after each data transfer as stated above, but when the transfer counter reaches zero, the values of the Next Counter/Pointer are loaded into the Counter/Pointer registers in order to re-enable the triggers." Everything works, my AD rate can reach 500K! It is very quick! It can reach only 100K if use TIOA pulse and interrupt. Regards Samuel |
|
| Author: | mjbcswitzerland [ Mon Mar 15, 2010 11:56 am ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Samuel This is the ping-pong buffer operation that the DMA supports. It doesn't have to be used though but enables high throughput by allowing the interrupt from the end of the first block to prepare the 'over-next' buffer while the next buffer is immediately used by the DMA. The USB controller uses the same method so that it can achieve isochronous rates - using a single buffer would mean that the process is highly dependent on the reaction time of the interrupt of a single buffer and so there would be 'dead-periods'. Also the SSC can use the same technique to maintain high throughput rates without losing synchronisation. http://www.utasker.com/docs/uTasker/uTaskerSSC.PDF Regards Mark www.uTasker.com |
|
| Author: | samuel_zhang [ Tue Oct 19, 2010 8:41 am ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Mark, The high speed A/D works. But after the AD DMA complete, then interrupt occur, but the "AT91C_ADC_ENDRX" flag can't be cleared, so the interrupt keep occuring, here are those source code. Do you have any idea? static void Configure_AD(void) { unsigned short* ADC_Ptr; unsigned short* ADC_Ptr_Next; int i; /* ADCClock = MCK/ ((AD_PRESCAL +1) *2); Startup Time = (AD_STARTUP +1) *8 /ADCClock; Sample&Hold Time = (AD_SHTIM + 1) /ADCClock; */ #define AD_PRESCAL 1 #define AD_STARTUP 1 #define AD_SHTIM 2 // Enable peripheral clock AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_ADC; //Notice: After ADC_SR = 0xc000 after Reset; AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; //Reset AD //Rxternal trigger: TIOA2 output pulse; Get data using ISP. AT91C_BASE_ADC->ADC_MR = ((AD_SHTIM << 24) | (AD_STARTUP << 16) | (AD_PRESCAL << | AT91C_ADC_TRGEN_EN | AT91C_ADC_TRGSEL_TIOA2); AT91C_BASE_ADC->ADC_CHER = AT91C_ADC_CH4; //channel 4 enable //Configure PDC; Write Counter Register reset ADC_SR. ADC_Ptr = ADC_Result; ADC_Ptr_Next = ADC_Result_Next; AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTDIS ; AT91C_BASE_ADC->ADC_RPR = (unsigned long)ADC_Ptr; // Receive Pointer Register AT91C_BASE_ADC->ADC_RCR = AD_DATA_BUFFER_SIZE; // Receive Counter Register AT91C_BASE_ADC->ADC_RNPR = (unsigned long)ADC_Ptr_Next; // Receive Next Pointer Register AT91C_BASE_ADC-> ADC_RNCR = AD_DATA_BUFFER_SIZE ; // Receive Next Counter Register AT91C_BASE_ADC->ADC_PTCR = AT91C_PDC_RXTEN ; //Enable PDC AT91C_BASE_ADC->ADC_IER = AT91C_ADC_ENDRX | AT91C_ADC_RXBUFF; //enable interrupt on transfer complete //AT91C_BASE_ADC->ADC_IER = AT91C_ADC_DRDY; // Configure and enable interrupt AIC_ConfigureIT(AT91C_ID_ADC, AT91C_AIC_PRIOR_LOWEST, ISR_adc); AIC_EnableIT(AT91C_ID_ADC); } ================================================= static void ISR_adc(void) { unsigned int AdcStatus = AT91C_BASE_ADC->ADC_SR; unsigned short* ADC_Ptr; unsigned short* ADC_Ptr_Next; if(((AdcStatus & AT91C_ADC_RXBUFF) == AT91C_ADC_RXBUFF) && ((AdcStatus & AT91C_ADC_ENDRX) == AT91C_ADC_ENDRX)) {//Both bit set when get the end of next buffer ADC_Ptr = ADC_Result; ADC_Ptr_Next = ADC_Result_Next; AT91C_BASE_ADC->ADC_RPR = (unsigned long) ADC_Ptr; // Receive Pointer Register AT91C_BASE_ADC->ADC_RCR = AD_DATA_BUFFER_SIZE; // Receive Counter Register AT91C_BASE_ADC->ADC_RNPR = (unsigned long)ADC_Ptr_Next; // Receive Next Pointer Register AT91C_BASE_ADC->ADC_RNCR = AD_DATA_BUFFER_SIZE ; // Receive Next Counter Registe TC_Stop(AT91C_BASE_TC2); // Stop the Timer to stop automatic AD conversion. } else if((AdcStatus & AT91C_ADC_ENDRX) == AT91C_ADC_ENDRX) {//ENDRX bit set when reach the end of buffer. AT91C_BASE_ADC->ADC_RNCR = AD_DATA_BUFFER_SIZE; //Write the register to Clear STATUS register ENDRX bit ==>But don't clear the flag??? } } |
|
| Author: | mjbcswitzerland [ Tue Oct 19, 2010 3:46 pm ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Samuel Have you tried? ADC_IDR = ADC_ENDRX; // no more PDC interrupt Regards Mark |
|
| Author: | samuel_zhang [ Wed Oct 20, 2010 3:14 am ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Mark, You are smart! It works as you expect. But in the AT91SAM7X512 manual, it said " The peripheral end flag is automatically cleared when the counter register is written". But it don't work as the manual said, I can't understand why, do you know why? Regards Samuel. |
|
| Author: | mjbcswitzerland [ Wed Oct 20, 2010 4:04 am ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Samuel It is almost two years since I wrote a DMA based ADC driver for the SAM7 and my memory of the details have faded somewhat since then. But, although the manuals are great, sometimes nothing beats some trial-and-error to get things working as they should; possibly I had the same problem that you had and tried a few things until it worked... Cheers Mark http://www.uTasker.com |
|
| Author: | samuel_zhang [ Wed Oct 20, 2010 4:52 am ] |
| Post subject: | Re: ADC + PDC - Understanding Problem |
Hi Mark, Many thanks for your help. There is another problem, I'm feeling it is from hardware. The data from the end of first buffer to the beginning of the next buffer are not "smooth". The data in the beginning of next buffer is always a little lower than expected. Have you get similar problem before? I'll redesign the PCB, if this problem still exists, I'll remove some data from the beginning of next buffer to make the waveform smooth. Regards Samuel |
|
| Page 1 of 1 | All times are UTC + 1 hour [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|



Forum