KL28 ADC clocking - how to use other sources than the ADCK?

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

KL28 ADC clocking - how to use other sources than the ADCK?

1,314 Views
mjbcswitzerland
Specialist V

Hi All


Has anyone worked with the KL28's ADC but not using its internal asynchronous clock source?

The NXP examples that I have seen all use the ADC's internal clock rather than a PCC selected clock source but I haven't been able to get the ADC to calibrate when connecting other sources (bus clock, fast IRC, etc.) although I believe that they should be correctly in range. When I use the internal clock source it does operate.

The KL28 is one of the first with a PCC and SCG to control clocks and peripheral clock sources, whereas I never had issues with using the bus clock in many other parts.

Anyone know the trick needed!

Regards

Mark

Labels (1)
Tags (2)
0 Kudos
Reply
7 Replies

1,087 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Mark,

I think this is the clock tree of Kl28.

ADCx_CFG1[ADICLK]=00; //bus clock

                                    =01; //bus clock/2

                                    =10; //ADC clock is from PCC

                                    =11; //Asynchronous clock

I do not test calibration, but if I select ADCx_CFG1[ADICLK]=10; PCC_ADC0=0x42000000; //select SCGIRCLK - Slow IRC Clock, the ADC can convert analog channel. The Slow IRC Clock is always enabled.

As you said that the KL28 is a new product, I am not familiar with it, but i have one FRDM-Kl28 board, I can have a test.

Hope it can help you

BR

Xiangjun Rong

0 Kudos
Reply

1,087 Views
mjbcswitzerland
Specialist V

Hi Xiangjun

Thanks - if I use the alternative clock (rather than bus) I can control the clock via the PCC.

I wonder whether you could find out details to the following because it is possibly missing from the user's manual, as is the fact that selecting the clock source for the alternative clock is the PCC module (ALTCLK is not defined anywhere in the manual)

pastedImage_7.png

This is the general ADC block diagram showing the 4 clock sources that can (normally) be selected:
- ADACK (the internal asynchronous clock that works)

- ALTCLK, which we now know is the ADC's PCC source
- Bus clock and Bus clock/2. This is the source that I haven't been able to get to work. Is it possible that it is not connected in the KL28? Note that the bus clock is DIVSLOW_CLK in the KL28 (also the flash clock).

The only reference in the user's manual is:

3.7.1.5 ADC clock source
The ADC module clock is sourced from the Peripheral Clock Control (PCC) module.

which I initially understood to mean that the ADC's bus clock input may be from there. I now believe that it means that the ALTCLK input is sourced from the PCC. Further, I have the feeling that the bus clock inputs are not connected at all based on the fact that when I use this (24MHz), divided by 16 at the ADC input to get a 1.5MHz clock for calibration, the calibration never takes place/completes although there is also no calibration error flagged.

Can this be confirmed?

Regards

Mark

0 Kudos
Reply

1,087 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Mark,

I have tested based on KSDK, I just change the ADC clock to bus clock and set the ADC clock divider as 8, the ADC clock will be 24MHz/8=3MHz.

I can pass the calibration, this is the code:

You can have a test after you download KSDK based on Kl28, I use KDS tools.

BR

Xiangjun Rong

int main(void)
{
    adc16_config_t adc16ConfigStruct;
    adc16_channel_config_t adc16ChannelConfigStruct;

    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    PRINTF("\r\nADC16 polling Example.\r\n");

    /*
     * adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
     * adc16ConfigStruct.clockSource = kADC16_ClockSourceAsynchronousClock;
     * adc16ConfigStruct.enableAsynchronousClock = true;
     * adc16ConfigStruct.clockDivider = kADC16_ClockDivider8;
     * adc16ConfigStruct.resolution = kADC16_ResolutionSE12Bit;
     * adc16ConfigStruct.longSampleMode = kADC16_LongSampleDisabled;
     * adc16ConfigStruct.enableHighSpeed = false;
     * adc16ConfigStruct.enableLowPower = false;
     * adc16ConfigStruct.enableContinuousConversion = false;
     */
    ADC16_GetDefaultConfig(&adc16ConfigStruct);
    adc16ConfigStruct.clockSource=kADC16_ClockSourceAlt0; //bus clock 24MHz, kADC16_ClockSourceAlt2;
    //PCC_ADC0=0x42000000;
#ifdef BOARD_ADC_USE_ALT_VREF
    adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceValt;
#endif    
    ADC16_Init(DEMO_ADC16_BASE, &adc16ConfigStruct);
    ADC16_EnableHardwareTrigger(DEMO_ADC16_BASE, false); /* Make sure the software trigger is used. */
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
    if (kStatus_Success == ADC16_DoAutoCalibration(DEMO_ADC16_BASE))
    {
        PRINTF("ADC16_DoAutoCalibration() Done.\r\n");
    }
    else
    {
        PRINTF("ADC16_DoAutoCalibration() Failed.\r\n");
    }
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
    PRINTF("Press any key to get user channel's ADC value ...\r\n");

    adc16ChannelConfigStruct.channelNumber = DEMO_ADC16_USER_CHANNEL;
    adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = false;
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
    adc16ChannelConfigStruct.enableDifferentialConversion = false;
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */

    while (1)
    {
        GETCHAR();
        /*
         When in software trigger mode, each conversion would be launched once calling the "ADC16_ChannelConfigure()"
         function, which works like writing a conversion command and executing it. For another channel's conversion,
         just to change the "channelNumber" field in channel's configuration structure, and call the
         "ADC16_ChannelConfigure() again.
        */
        ADC16_SetChannelConfig(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP, &adc16ChannelConfigStruct);
        while (0U == (kADC16_ChannelConversionDoneFlag &
                      ADC16_GetChannelStatusFlags(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP)))
        {
        }
        PRINTF("ADC Value: %d\r\n", ADC16_GetChannelConversionValue(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP));
    }
}

0 Kudos
Reply

1,087 Views
mjbcswitzerland
Specialist V

Hi Xiangjun

Yes, you are correct that the bus clock directly works - try however the kADC16_ClockSourceAlt1 instead (this is BUS_CLOCK / 2). With kADC16_ClockDivider4 it should be equivalent but you will see that also the KSDK code will hang in the calibration routine.

Regards

Mark

0 Kudos
Reply

1,087 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Mark,

you are right, if I use BUS_CLOCK / 2 as clock alternative, the ADC flag can not be set. I suppose that the BUS clock/2 signal is NOT connected to ADC module.

I will ask application team and hope they can give a confirmation.

BR

Xiangjun Rong

0 Kudos
Reply

1,087 Views
mjbcswitzerland
Specialist V

Hi Xiangjun

Many thanks for the confirmation!

It is strange that the BUS_CLOCK/2 source doesn't work (I tend to use that as default and have used/tested it on about 60 different K, KL, KE, KEA, KV, KM, KW derivatives and this is the first time that it hasn't worked).

Maybe be its a (new) errata? In any case it would be great to have an official technical response/explanation.

Regards

Mark

0 Kudos
Reply

1,087 Views
mjbcswitzerland
Specialist V

Hi Xiangjun

Note that the KE15's (another SCG + PCC based processor) user's manual is very clear on the ADC clocking:

pastedImage_1.png

[This has neither bus nor synchronous support].

In comparison, the KL28's description leaves one guessing!

pastedImage_2.png

Regards

Mark

0 Kudos
Reply