Does somebody know how to get hardware trigger ADHWTsn and reading the correct ADC value?

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

Does somebody know how to get hardware trigger ADHWTsn and reading the correct ADC value?

7,008 Views
albert_zhou
Contributor III

I have ADC reading issues on the SE6b and SE7b on NXP MKL27Z64VFM4(QFN32). The other channel reading is fine after I connected PTE30 to Vcc. Does somebody know how to get hardware trigger and reading the correct ADC value?

Tags (1)
0 Kudos
13 Replies

6,592 Views
mjbcswitzerland
Specialist V

Albert

The 32 pin package has PTE30 as primary source of reference voltage for the ADC and that is why you needed to put 3.3V on it if you use this setting.

You can however use the Valt setting instead and then the ADC takes its reference internally from VDDA. To do this, set BIT0 in ADC0_CFG2.

Since you no longer need to apply 3.3V to PTE30 you can use it as ADC0_SE32 instead.

You just need to ensure that the precision reference module is disabled (its default state), which is however also the case when using the primary reference on PTE30.

Regards

Mark

0 Kudos

6,592 Views
albert_zhou
Contributor III

Hi Mark,

What is Valt setting?

The listed BIT0 of ADC0-CFG2 is for ADLSTS Long Sample selection. Set ADLSTS =01 =12 extra ADCK cycle…. It is strange that will set internal reference to VDDA?

Could set PTE30 to a GPIO output and the reference internal connect to VDDA?

Best regards,

Albert Zhou

Sr. Electronics Engineer

Sensorex

p:

+1 714-230-2768

a:

11751 Markon Drive, Garden Grove, CA 92841

w:

www.sensorex.com<http://www.sensorex.com/>; e: albert.zhou@sensorex.com<mailto:albert.zhou@sensorex.com>

<https://www.facebook.com/Sensorex> <https://twitter.com/SensorexInc> <https://www.linkedin.com/company-beta/1768298/>

0 Kudos

6,592 Views
mjbcswitzerland
Specialist V

Albert

Sorry, my mistake, the bit is in ADC0_SC2 !

Regards

Mark

0 Kudos

6,592 Views
albert_zhou
Contributor III

Ops, Everything works OK.

Albert

0 Kudos

6,592 Views
albert_zhou
Contributor III

Hi Mark,

Thanks a lot. Yes, I did understand that could be ADC0_SC2 this morning. Very thing now works OK.

Thanks thanks again!!

Albert Zhou

Sr. Electronics Engineer

Sensorex

p:

+1 714-230-2768

a:

11751 Markon Drive, Garden Grove, CA 92841

w:

www.sensorex.com<http://www.sensorex.com/>; e: albert.zhou@sensorex.com<mailto:albert.zhou@sensorex.com>

<https://www.facebook.com/Sensorex> <https://twitter.com/SensorexInc> <https://www.linkedin.com/company-beta/1768298/>

0 Kudos

6,592 Views
albert_zhou
Contributor III

This one does not say any thing about hardware trigger that should be very simple instead of long long code and many prototypes.....

0 Kudos

6,592 Views
mjbcswitzerland
Specialist V

For HW triggering just read the manual since it tells you all you need to know about sources and trigger selection::

pastedImage_1.png

There is an example of PIT triggering in appendix A, paragraph B and of TPM triggering in paragraph E (this allows variable A/B HW triggering).


Paragraph D explains input mixing fundamentals that are needed to be understood to correctly to use 'parallel' A/B channel triggering and a/b muxing.

If you have problems with (just) SE6b and SE7b inputs it is not a HW triggering issue but incorrect input channel muxing (again paragraph D explains this, which is why I pointed it out). These inputs don't need HW triggering - they can be read in SW mode as others that you already have working.

Notice the a/b and A/B notations used since they have DIFFERENT meanings.

Regards

Mark

0 Kudos

6,592 Views
albert_zhou
Contributor III

Hi Mark,

I have changed code as this below, that still does not work: (hang there…)

#define Convertion_in_Progress ((ADC0->SC2)&(BIT7))

uint16_t ADC16(uint8_t channel)

{

uint16_t adcValue;

//ADC0->CFG2 &= ~BIT4;

//ADC0->SC1[0] =channel;

//while(Convertion_in_Progress!=0){};

//while(Convertion_Complete==0){};

//adcValue =ADC0->R[0];

if((channel==6)||(channel==7))

{

ADC0->CFG2 |= BIT4;

ADC0->SC1[0] =channel;

//ADC0->CFG2 |= BIT4;

while(Convertion_in_Progress!=0){}; //

while(((ADC0->SC1[0])&(BIT7))==0){};

adcValue =ADC0->R[0];

}

else

{

ADC0->CFG2 &= ~BIT4;

ADC0->SC1[0] =channel;

while(Convertion_in_Progress!=0){};

while(Convertion_Complete==0){};

adcValue =ADC0->R[0];

}

return adcValue;

}

0 Kudos

6,592 Views
mjbcswitzerland
Specialist V

Hi Albert

I just checked operation on SE6b on a KL27 with following code:

ADC_SETUP adc_setup;                                                 // interrupt configuration parameters
adc_setup.int_type = ADC_INTERRUPT;                                  // identifier when configuring
adc_setup.pga_gain = PGA_GAIN_OFF;
adc_setup.int_priority = PRIORITY_ADC;                               // ADC interrupt priority
adc_setup.int_adc_controller = 0;                                    // ADC controller 0
adc_setup.int_handler = adc_conversion_complete;
adc_setup.int_adc_int_type = (ADC_SINGLE_SHOT_TRIGGER_INT);
adc_setup.int_adc_bit = ADC_SE6_SINGLE;
adc_setup.int_adc_mode = (ADC_CALIBRATE | ADC_SELECT_INPUTS_B | ADC_CLOCK_BUS_DIV_2 | ADC_CLOCK_DIVIDE_8 | ADC_SAMPLE_ACTIVATE_LONG | ADC_CONFIGURE_ADC | ADC_REFERENCE_VREF | ADC_CONFIGURE_CHANNEL | ADC_SINGLE_ENDED_INPUT | ADC_SINGLE_SHOT_MODE | ADC_12_BIT_MODE | ADC_SW_TRIGGERED); // note that the first configuration should calibrate the ADC - single shot with interrupt on completion
adc_setup.int_adc_sample = (ADC_SAMPLE_LONG_PLUS_12 | ADC_SAMPLE_AVERAGING_32); // additional sampling clocks
fnConfigureInterrupt((void *)&adc_setup);                            // configure ADC and start first conversion
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

It uses an interrupt and when the conversion is complete I checked the value with a debug message to verify the operation was correct across the voltage range (12 bit mode)

ADC triggered: 0x0fff
ADC triggered: 0x0d54
ADC triggered: 0x0b30
ADC triggered: 0x0932
ADC triggered: 0x0724
ADC triggered: 0x0509
ADC triggered: 0x0307
ADC triggered: 0x0153
ADC triggered: 0x0000

So that you can check the ADC interaction, this is the low level code that this controls:

KINETIS_ADC_REGS *ptrADC = (KINETIS_ADC_REGS *)ADC0_BLOCK;
POWER_UP_ATOMIC(6, ADC0);                        // enable clocks to module
ptrADC->ADC_CFG1 = (ADC_CLOCK_DIVIDE_8 | ADC_SAMPLE_ACTIVATE_LONG | ADC_12_BIT_MODE | ADC_CLOCK_BUS_DIV_2); // 0x75
// Do ADC calibration sequence - not shown
ptrADC->ADC_CFG2 = (ADC_CFG2_MUXSEL_B | ADC_SAMPLE_LONG_PLUS_12); // 0x11
_CONFIG_PERIPHERAL(D, 5, PD_5_ADC0_SE6b);        // ensure that the ADC pin is configured
ptrADC->ADC_SC2 = ADC_REFERENCE_VREF; // configure the reference voltage and triggering - 0x00
ptrADC->ADC_SC3 = ADC_SAMPLE_AVERAGING_32; // 0x07 - single shot conversion
// Configure interupt handler - not shown
ptrADC->ADC_SC1A = (ADC_SC1A_AIEN | ADC_SC1A_ADCH_6); // 0x46


// When interrupt fires - read result
result = ptrADC->ADC_RA;
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I have shown the HEX values written to the registers and note the following:
1) You should preform ADC calibration before first use
2) Although the pin PTD5 default to its ADC0_SE6b function it is good practice to ensure that it is correct - and power up the PTD port.
3) Although I don't see all your ADC initialisation details setting BIT4 of ADC0_CFG2 is what selects the b input, so that looks correct.
4) As a test, I selected a input on SE6a - and the result was then always 0x0fff (presumably the unavailable SE6 a input is connected internally to VDD).

With these details you may be able to identify your issue.

Regards

Mark

You can also download the uTasker project from its open source reference on GitHub for check the coding details from above and simulate the KL27 in Visual Studio.
Short video attached of testing/verifying the ADC input.

0 Kudos

6,592 Views
albert_zhou
Contributor III

Hi Mark,

Yes, it works with the code I send to you when I flashed the target board. I had a mistake at debug display line. I put

“ADC0->SC1[0] =6;” after “ADC0->SC1[0] =6;”. So the screen display is “0…..”.

I guess I did not put a line for ensure PTD5 (SE6b) to ALT0 at earlier time. I did it then send the code to you.

Thank you…. Thanks a lot for help me out for this critical issue.

Plus. I still have the question about PTE30. Please advise.

Albert Zhou

Sr. Electronics Engineer

Sensorex

p:

+1 714-230-2768

a:

11751 Markon Drive, Garden Grove, CA 92841

w:

www.sensorex.com<http://www.sensorex.com/>; e: albert.zhou@sensorex.com<mailto:albert.zhou@sensorex.com>

<https://www.facebook.com/Sensorex> <https://twitter.com/SensorexInc> <https://www.linkedin.com/company-beta/1768298/>

0 Kudos

6,592 Views
albert_zhou
Contributor III

Hi Mark,

Thanks for your help.

I did ADC self-calibration I hare attached complete code for your check.

I read your code. It seems almost the same as I did except clock setup and 12 bit – 16 bit and interrupt. I will check it again with ADC interrupt as you did.

One more thing, about the PTE30 pin. I have to connect this pin(9 for 32QFN) to Vcc(3.3V) for accurate read, otherwise if I used as SE23 as ADC input. The ADC channel(a) could not read accurate value.

Is that right? That means I have lost another ADC channel(SE23)? Please advise.

Best regards,

Albert Zhou

Sr. Electronics Engineer

Sensorex

p:

+1 714-230-2768

a:

11751 Markon Drive, Garden Grove, CA 92841

w:

www.sensorex.com<http://www.sensorex.com/>; e: albert.zhou@sensorex.com<mailto:albert.zhou@sensorex.com>

<https://www.facebook.com/Sensorex> <https://twitter.com/SensorexInc> <https://www.linkedin.com/company-beta/1768298/>

0 Kudos

6,592 Views
albert_zhou
Contributor III

Hi Mark,

Thank you for your point out that the SE6b and SE7b inputs do not need Hardware trigger just change input mux. That will help me a lot.

I tried this code below that does not work. Please advise.

uint16_t ADC16(uint8_t channel)

{

uint16_t adcValue;

//ADC0->SC1[0] =channel;

//while(Convertion_in_Progress!=0){};

//while(Convertion_Complete==0){};

//adcValue =ADC0->R[0];

if((channel==6)||(channel==7))

{

ADC0->CFG2 |= BIT4;

ADC0->SC1[1] =channel;

while(Convertion_in_Progress!=0){};

while(((ADC0->SC1[1])&(BIT7))==0){};

adcValue =ADC0->R[1];

}

else

{

ADC0->CFG2 &= ~BIT4;

ADC0->SC1[0] =channel;

while(Convertion_in_Progress!=0){};

while(Convertion_Complete==0){};

adcValue =ADC0->R[0];

}

return adcValue;

}

Best regards,

0 Kudos