ADC with PEC problem (XC2765)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hello everyone!

I have a problem when reading the ADC1 data with PEC at XC2765.
Only arbitration slot 1 of ADC1 is enabled. The ADC1 is configured to scan all available channels and write the result to RESRA0 register. PEC5 is configured to hanlde the register 0 interrupt (lev 11, group 1) and copy a word to an array of 5 words. The DEST counter is incremented after transfer. I do not use the autoscan mode. When program starts I start the convertion once. When PEC finishes the sequence (5 transfers) the ADC1 REG0 interrupt is called. In this interrupt I read the data from the PEC array, reload the PEC counter and start the convertion again. All these perfectly works for ADC0, but for some reason does not work for ADC1. With ADC1 after the start of convertion PEC performs a single sequence, then the IRQ is called, convertion is restarted, but the second sequence does not finish with the following symptoms: PEC counter stops at value 3, but the DEST counter shows that all five transfers were completed! As for me it looks like a hardware bug, but may be I do something wrong? May be there some timing issues between ADC & PEC and I can't start the convertion immediately after PEC counter change?

I've tried to enable the Autoscan mode. In this case everything works fine until I add the code to read the data from PEC buffer. After I enable this piece of code the stack overflow occurs due to multiple nested interrupts (as far as I concern). Probably in this case I does not manage to read all the data before PEC transfer takes place. But it's rather strange with 5us sampling time , CPU Speed 40MHz and ADC digital clock of 20MHz.

Here is my ADC1 IRQ handler routine (called only when PEC sequence is finished):

_interrupt(ADC1_SRN0INT) void ADC1_IRQAD0Done(void)
{

if((ADC1_EVINFR & 0x0100) == 0x0100) //Result0 event interrupt
{
ADC1_EVINCR = 0x0100; // Clear Result0 event interrupt

// USER CODE BEGIN (ADC1_viSRN0,20)

// read the PEC buffer in reverse order
for(i1=0; i1 ADC1_Mean[i1] += ( ADC1_PEC_Dest[ADC1_CHANNELS_CNT-i1-1]>>2 );

//--------------------------
//reload PEC
DSTP5 = ((uword)ADC1_PEC_Dest) & 0x00ffff; // reset the DEST address
PECC5 |= 0x0008; // load the counter

// software data reduction implementation
if ( adc1_decimation_cnt >= 255)
{
for(i1=0; i1 {
ADC1_Data[i1] = (uword)( ADC1_Mean[i1]>>8 ) ;
ADC1_Mean[i1] = 0;
}

// set software flag
ADC1_ConvDone = TRUE;

adc1_decimation_cnt = 0;
}
else
adc1_decimation_cnt++;

// Convertion restart.
// !!!!!!!!! Following two lines are disabled in ADC Autoscan mode.
ADC1_vStartParReqChNum( 1 | (1<<2) | (1<<4) | (1<<5) | (1<<6) ); // write CRCR1
ADC1_CRMR1 |= 0x200; // set load event

// USER CODE END

}

} // End of function ADC1_IRQAD0Done

The Tasking VX Lite v3.1 r1 is used.
DAVE 2.2 r2 is used to configure the peripherials.


--------------------------------------
Peripherial configuration detailes:

The ADC1 setup made by DAVE:
- only arbitration slot 1 is used (parallel), MasterMode, Permanent arbitration , Wait-for-start
- no Autoscan;
- all available analog channels enabled (0,2,4,5,6);
- all channels write data to register 0;
- register 0 generates an interrupt (lev 11, group 1), data reduction disabled.

PEC5 setup for ADC1:
- source addr is RESRA0 register of ADC1;
- destination register is an array of 5 unsigned int;
- counter is set to 5. After transfer the counter is decremented, SRC is not changed, DEST is incremented by word.
- EOP interrupt is not used


Hope for Your help.
Roman, Moscow, Russia.
0 Likes
2 Replies
Not applicable
This problem is solved. The reason was in a rather stupid code mistake.

But another one arised. Both ADC kernels work fine separetely, but when I start both ADC kernels PEC of ADC0 does not perform properly. As far as I understood only 7 of 8 requested transfers are actualy made. After that ADC0 and its PEC stop.
Can anyone share with me a code with to ADC kernels working simutaneously with PECs enabled for both kernels? This will be a great help for me because I don't know what to do...
0 Likes
Not applicable
The problem with two PECs was solved too by enabling the Wait-before-read mode of the result register. I think that the low priority PEC(PEC0) missed some ADC samples because the high priority PEC(PEC5) transfer happeden at the same time.

But still I don't understand why this problem arised. As far as I concern, PEC0 (low priority) should wait while PEC5(high priority) transfer on ADC1 finishes (I mean a single word transfer, not a sequence) and perform a transfer on ADC0. The sampling period is raser long (5 and 25 us for ADC0 and ADC1 with 40MHz CPU & ADC clock) so there shouldn't be a data loss, but it was... Can anyone explain this?
0 Likes