ADC Compare Function Does Not Work (S32K146)

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

ADC Compare Function Does Not Work (S32K146)

Jump to solution
1,025 Views
iit
Contributor I

Hi,
I'm using S32K146 EVB trying to obtain an interrupt request from ADC when internal compare function is enabled. In particular, I set "greater than or equal to threshold" by SC2[ACFE]=1,SC2[ACFGT]=1,SC2[ACREN]=0 and CV1=<threshold_value>.
Other info: single external channel conversion, trigger from PDB every 100us, ADCclock 40 MHz.

When I try to run the program without compare function everything works just fine, but I have to compare value inside handler (wasting time). If I enable compare function, interrupt is never requested.

I don't understand what is wrong.

Here is ADC init function (all the others bit values are left default):

void ADC0_init_HWTrigger(uint8_t ExtChannel){

  //ADC0_calibrate();
  
  /* Disable clock to change PCS */
  PCC->PCCn[PCC_ADC0_INDEX] &= ~PCC_PCCn_CGC_MASK;
  /* PCS=6: Select SPLLDIV2 */
  PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_PCS(6);   
  /* Enable bus clock in ADC */
  PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_CGC_MASK; 

  /* ADCH: Module disabled for conversions */
  ADC0->SC1[0] = ADC_SC1_ADCH_MASK;               

  /* (5000*R/0xFFF) > 2750 mV that is R > 2252.25 */
  ADC0->CV[0] = ADC_CV_CV(2253);                  

  /* MODE=1: 12-bit conversion */
  ADC0->CFG1 |= ADC_CFG1_MODE(1);                 
  
  /* SMPLTS=12(default): sample time is 13 ADC clks */
  ADC0->CFG2 = ADC_CFG2_SMPLTS( 2);               

  ADC0->SC2 = ADC_SC2_ADTRG(1) /* ADTRG=1: HW trigger */
            | ADC_SC2_ACFE(1)  /* ACFE=1: Enable compare function */
            | ADC_SC2_ACFGT(1) /* ACFGT=1,ACREN=0: Greater than or equal to threshold */
            | ADC_SC2_ACREN(0);

  ADC0->SC3 = ADC_SC3_ADCO(0); /* ADCO=0: One conversion per request */

  /* External Channels 16..31 are not mapped directly to ADCH */
  if(ExtChannel >= 16){        
      ExtChannel = (ExtChannel - 16) | (1<<5);
  }
  ADC0->SC1[0] = ADC_SC1_ADCH(ExtChannel)/* ADCH=<external ch. ExtChannel> */
              |ADC_SC1_AIEN(1);          /* AIEN=1: Enable Conversion Interrupt */

}

 Tell me if you need more source code

0 Kudos
1 Solution
1,003 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi 

I did not find where you set the value of CV1. And don't know why: ADC0->CV[0] = ADC_CV_CV(2253);

 

There is a note when using ADC automatic compare function triggered by PDB pre-trigger feature.

Once ADC is configured for automatic compare function, the "COCO" (Conversion Complete Flag) is asserted only when the compare condition is satisfied.

The PDB, however, needs the "COCO" signal assertion to unlock the pre-trigger channel. This is to avoid inappropriate pre-trigger generation while ADC is still under conversion, or result is still not read.

In case with ADC automatic compare function, the "COCO" may not be asserted even though ADC became ready for another comparison. To allow the next pre-trigger generation, the PDB channel will need to be unlocked by disabling and enabling it again. Please note ADC may still be under conversion for previous comparison, so the timing of PDB pre-trigger generation should carefully be chosen.

Best Regards,
Robin
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

0 Kudos
2 Replies
1,004 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi 

I did not find where you set the value of CV1. And don't know why: ADC0->CV[0] = ADC_CV_CV(2253);

 

There is a note when using ADC automatic compare function triggered by PDB pre-trigger feature.

Once ADC is configured for automatic compare function, the "COCO" (Conversion Complete Flag) is asserted only when the compare condition is satisfied.

The PDB, however, needs the "COCO" signal assertion to unlock the pre-trigger channel. This is to avoid inappropriate pre-trigger generation while ADC is still under conversion, or result is still not read.

In case with ADC automatic compare function, the "COCO" may not be asserted even though ADC became ready for another comparison. To allow the next pre-trigger generation, the PDB channel will need to be unlocked by disabling and enabling it again. Please note ADC may still be under conversion for previous comparison, so the timing of PDB pre-trigger generation should carefully be chosen.

Best Regards,
Robin
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
994 Views
iit
Contributor I

Thanks for fast reply Robin_Shen.

I did not find where you set the value of CV1. And don't know why: ADC0->CV[0] = ADC_CV_CV(2253);

Referring to S32K146.h ("Peripheral Access Layer for S32K146"), CV1 register is accessed by CV vector (made of two entries: CV[0] is CV1 at 0x88 offset from ADC0 base address, and CV[1] is CV2 at 0x8C offset).
ADC_CV_CV(x) mask out the upper 16 bits, so that only lower 16 bits of x are used.

The PDB, however, needs the "COCO" signal assertion to unlock the pre-trigger channel. This is to avoid inappropriate pre-trigger generation while ADC is still under conversion, or result is still not read.

In case with ADC automatic compare function, the "COCO" may not be asserted even though ADC became ready for another comparison. To allow the next pre-trigger generation, the PDB channel will need to be unlocked by disabling and enabling it again. Please note ADC may still be under conversion for previous comparison, so the timing of PDB pre-trigger generation should carefully be chosen.

We agree on this, but in my case I'm using (only)pre-trigger 0 without back-to-back function so ACK signal (coming from COCO) is not used. I set BB[0] = 0, TOS[0] = 1, EN[0] = 1, so pre-trigger0 asserts when PDBCNT reaches PDB0CH0DLY0 (in particular, I set DLY0 = 0).
In conclusion, PDB0 works as a continuos timer triggering ADC0 every 100 us. This period is sufficiently longer than ADC0 conversion time (about 1 us) so I don't think that the problem is here.

Just to be safe, I try using compare function with manual (software) triggering of ADC0 and it works correctly as expected. Unfortunately, I need hardware triggering for adc conversions.

Any idea?

0 Kudos