MPC5674F QADC DMA Data Swap Problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MPC5674F QADC DMA Data Swap Problem

977 Views
u_kayacik
Contributor II

Hi,

 

I have a problem with QADC and EDMA continuous conversion. My code is like below, Actually I used example "Example_MPC5674F-eQADC+eDMA-Continuous_Scan-v0_1-CW210.zip".

 

uint32_t CQueue_B_0[] =

{

    ( CHANNEL(0)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(1)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(2)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(3)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(4)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(5)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(6)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(7)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(8)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(9)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(10)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(11)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(12)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(13)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(14)  | B1 | MESSAGE_TAG(RFIFO0) | EOQ   )

};

 

I set up a QADCB init for continuous conversion like below, (I dont use interrupt)

 

void INITQADCB(void)

{

  #define SINGLE_SCAN_B_TRIGGER_Q0 EQADC_B.CFCR[0].R=0x0410

  #define SINGLE_SCAN_B_TRIGGER_Q1 EQADC_B.CFCR[1].R=0x0410

 

  #define FISR_EOQ_MASK 0x10000000

 

  #define ADC_configuration 0x8004

 

  EQADC_B.MCR.R = 0x00000000; //debug mode

 

  // write to indirectly mapped ADC configuration register

  // set prescaler and enable ADC0

  EQADC_B.CFPR[1].R = ADC_REG_ADDR(ADC0_CR)  | ADC_REG_VALUE(ADC_configuration)  | B0;

 

  // set prescaler and enable ADC1

  EQADC_B.CFPR[1].R = ADC_REG_ADDR(ADC1_CR) | ADC_REG_VALUE(ADC_configuration)  | B1  | EOQ;

 

  // Trigger CFIFO 1 using Single Scan SW mode

  SINGLE_SCAN_B_TRIGGER_Q1;

 

  // Wait for End Of Queue flag

  while (EQADC_B.FISR[1].B.EOQF !=1)

  {

  }

 

  // Clear End Of Queue flag

  EQADC_B.FISR[1].R = FISR_EOQ_MASK;

 

  EQADC_B.IDCR[0].R = //EQADC_A_IDCR_PIE0_MASK    | // Pause Interrupt Enable

  //EQADC_A_IDCR_EOQIE0_MASK  | // End of Queue Int. Enable

  EQADC_B_IDCR_CFFE0_MASK   | // CFIFO Fill Enable

  EQADC_B_IDCR_CFFS0_MASK   | // CFIFO Filled by DMA

  EQADC_B_IDCR_RFDE0_MASK   | // RFIFO Drain Enable

  EQADC_B_IDCR_RFDS0_MASK   ; // RFIFO Drained by DMA

 

 

  EQADC_B.CFCR[0].R = MODEx(SOFTWARE_TRIGGER_CONTINUOUS_SCAN);

}

 

DMA is like example but only I closed DMA ch after major loop is finished with

EDMA_B.TCD[CFIFO_0_DMA_chnl].D_REQ = 1;

 

and I have a trigger function, after all conversions finished :

 

void Trigger(void)

{

  /* Wait for End Of Queue flag */

  /* Be sure CFIFO DMA is finished the process */

  while (EQADC_B.FISR[0].B.EOQF != 1)

  {

  }

  /* Clear End Of Queue flag */

  EQADC_B.FISR[0].R = 0x10000000;

 

 

    /* Be sure RFIFO DMA is finished the process */

  while (EDMA_B.TCD[RFIFO_0_DMA_chnl].DONE == 0){}

 

  /*-- pop converted ch results to clean buf --*/

  for (i= 0; i< 15; i++)

  {

     ADCResults[i] = (RQueue_B_0[i] >> 2u ) & 0xFFFF;

  }

 

  /*-- Trigger ADC CFIFO registers to QADCA peripheral --*/

  EDMA_B.SERQR.R = CFIFO_0_DMA_chnl;

  EDMA_B.SERQR.R = RFIFO_0_DMA_chnl;

 

}

 

Problem is conversion results are shifted to other channels and I couldnt find any reasonable answer. I call this trigger func within ms interval and conversion is well at first times, after 3-16 minutes sometimes 3 sometimes, sometimes 11 minutes ADC channel results are shifted. Could you please help me to solve this problem ?

 

Arry 0 ------------ ch0-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 1 ------------ ch1-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 2 ------------ ch2-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 3 ------------ ch3-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 4 ------------ ch4-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 5 ------------ ch5-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 6 ------------ ch6-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 7 ------------ ch7-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 8 ------------ ch8-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 9 ------------ ch9-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 10 ------------ ch10-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 11 ------------ ch11-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 12 ------------ ch12-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 13 ------------ ch13-  CFIFO0 ---- ADC0 ---- RFIFO0

Arry 14 ------------ ch14-  CFIFO0 ---- ADC0 ---- RFIFO0

 

ch0 result goes to Arry 12 instead of Arry0. Other ch results are shifted with this rate.

 

Not: Is there any CFIFO SW Trigger need after "EDMA_B.SERQR.R = RFIFO_0_DMA_chnl;", if needs is there any example usage?

 

Best Regards,

Umit.

Labels (1)
0 Kudos
4 Replies

597 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

Yesterday I have written document describing possible result swap reasons, you may find it here:

https://community.freescale.com/docs/DOC-329779

Note that in you case I see the problem, command 14 use ADC1. As the whole sequence runs cyclically in continuous scan and all samples points to RFIFO0, result swap could happen.

Additionally there is another possible reason caused by erratum e5086 that may manifest as result swap as well - in this case best solution is “Do not use the abort feature (ICEAn=0)”

0 Kudos

597 Views
u_kayacik
Contributor II

Hi David,

I think your possible solutions:

1) Use 2 command queues and 2 results queues (therefore two different return tags). (I can not use 2 different cfifos and rfifos)

2) One command queue and two results queues by using two different return tags. (I can not use 1 different cfifos and 2 rfifos)

3) If forced to use one results queue then add 3 dummy conversions with null return tags to keep ADC1 busy until ADC0 has returned the last result.(I dont use ADC1 and all convesions on ADC0)

4) To keep regular alternating of commands assigned to ADC0 and ADC1. (I dont understand actually)

I opened XBAR and I think it solved problem , but I can not believe that is not occurs again, David. :smileyhappy: Please say that your way is true and it will not happen swap again with that configuration :smileyhappy:

Best regards,

Umit.

0 Kudos

597 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

I am not sure if I understand what you did with XBAR but you have show my setting that sets higher priority for DMA than CPU what is necessary setup for eQADC used with conjunction to eDMA to prevent CFIFO underflow or RIFO overflow.

However according to your new setting it seems you are using only ADC0 thus result swap described by my bulletin cannot happen at all (actually it is the solution as well, although it negatively impacts conversion performance, understandably).

By solution no.4 (regular alternating of commands) I had on my my mind command queue like this for instance:

uint32_t CQueue_B_0[] =

{

    ( CHANNEL(0)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(1)  | B1 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(2)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(3)  | B1 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(4)  | B0 | MESSAGE_TAG(RFIFO0)         ),

    ( CHANNEL(5)  | B1 | MESSAGE_TAG(RFIFO0) | EOQ   )

};

I am glad you have solved your issue. Have a nice day.

0 Kudos

597 Views
u_kayacik
Contributor II

Hi David,

my MCR configuration like below:

EQADC_B.MCR.R = 0x00000000; that means I dont use immediate continuous scan. Is my configuration right or wrong?

Also I changed,

( CHANNEL(14)  | B1 | MESSAGE_TAG(RFIFO0) | EOQ   to  ( CHANNEL(14)  | B0 | MESSAGE_TAG(RFIFO0) | EOQ.

Suddenly when I ,

---- open XBAR like below,

XBAR.MPR0.R = 0x54300012; /* internal FLASH */
XBAR.MPR2.R = 0x54300012; /* internal SRAM */
XBAR.MPR7.R = 0x54300012; /* PBRIDGE_B */

---- Carry whole QADCB process to QADCA

---- Change B1 to B0 , problem solved. I tested 60 dk.

Is there any risk for this operation, I have to use only one CFIFO and one RFIFO for DMA configuration ?

Can only above configuration solve this problem?

Best regards,

Umit.

0 Kudos