Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: AT91C_ADC_ENDRX flag don't clear at DMA AD
PostPosted: Thu Aug 05, 2010 6:08 am 
Offline

Joined: Thu Oct 16, 2008 2:18 am
Posts: 10
I have a high speed AD conversion, a DMA is implemented. After the AD DMA complete, then interrupt occur, but the "AT91C_ADC_ENDRX" flag can't be cleared, so the interrupt keep occuring, if I put a bearkpoint in the in the interrupt routine, then the flag can be cleared.
AT91C_BASE_ADC->ADC_SR; can't clear the flag, why?

here are the source code:
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 << 8)
| 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

}
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: