K02 Clock Manager Setup

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

K02 Clock Manager Setup

1,723 Views
anbui
Contributor II

Our design is using an 16 Mhz external crystal for the K02.

 

I'm setting the clock manger for SystemCoreClock = 80000000 (80 MHz) with the following parameters:

const clock_manager_user_config_t g_defaultClockConfig =

{

    .mcgConfig =

    {

        .mcg_mode           = kMcgModeFEE,

        .irclkEnable           = true,  // MCGIRCLK enable.

        .irclkEnableInStop  = false, // MCGIRCLK disable in STOP mode.

        .ircs               = kMcgIrcSlow, // Select IRC32k.

        .fcrdiv             = 0U,    // FCRDIV is 0.

 

        .frdiv   = 4U,

        .drs     = kMcgDcoRangeSelLow,  // Low frequency range

        .dmx32   = kMcgDmx32Default,    // DCO has a default range of 25%

        .oscsel  = kMcgOscselOsc,       // Select OSC

#if FSL_FEATURE_MCG_HAS_PLL1  /* There are NO PLL on K02 */

        .pll0EnableInFllMode        = false,  // PLL0 disable

        .pll0EnableInStop           = false,  // PLL0 disalbe in STOP mode

        .prdiv0                     = 0x1U,

        .vdiv0                      = 0x6U,

#endif

    },

    .simConfig =

    {

     .pllFllSel = kClockPllFllSelFll,

     .er32kSrc  = kClockEr32kSrcOsc0,

        .outdiv1   = 0U,

        .outdiv2   = 1U,

        .outdiv3   = 3U,

        .outdiv4   = 4U,

    },

    .oscerConfig =

    {

        .enable       = true,  // OSCERCLK enable.

        .enableInStop = false, // OSCERCLK disable in STOP mode.

        .erclkDiv     = 0U,    // OSCERCLK divider setting.

    }

};

 

Our UART driver module is not reading the proper characters from our device.  This configuration is from the K02 Reference Manual.

148363_148363.pngpastedImage_6.png

Labels (1)
0 Kudos
Reply
5 Replies

1,271 Views
DavidS
NXP Employee
NXP Employee

Hi An,

From the code provide I can see (correct me if wrong) that you are using KSDK_1.3.  Correct?

If you look at the following example as reference:

C:\Freescale\KSDK_1.3.0\examples\frdmk22f\driver_examples\dspi\dspi_polling\master\kds

You will see in the main() in main.c for setting up the SPI Master there is a HAL call to set various delays:

    // Initialize the configurable delays: PCS-to-SCK, prescaler = 0, scaler = 1

    DSPI_HAL_SetDelay(dspiBaseAddr, kDspiCtar0, 0, 1, kDspiPcsToSck);

The fsl_dspi_hal.h header has following information:

/*!

* @brief Manually configures the delay prescaler and scaler for a particular CTAR.

*

* This function configures the PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK),

* after SCK delay pre-scalar (PASC) and scalar (ASC), and the delay

* after transfer pre-scalar (PDT)and scalar (DT).

*

* These delay names are available in type dspi_delay_type_t.

*

* The user passes which delay they want to configure along with the prescaler and scaler value.

* This  allows the user to directly set the prescaler/scaler values if they have

* pre-calculated them or if they simply wish to manually increment either value.

*

* @param base Module base pointer of type SPI_Type.

* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type

*                  dspi_ctar_selection_t.

* @param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3).

* @param scaler The scaler delay value (can be any integer between 0 to 15).

* @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t

*/

void DSPI_HAL_SetDelay(SPI_Type * base, dspi_ctar_selection_t whichCtar, uint32_t prescaler,

                       uint32_t scaler, dspi_delay_type_t whichDelay);

The fsl_dspi_hal.c has the following:

/*FUNCTION**********************************************************************

*

* Function Name : DSPI_HAL_SetDelay

* Description   : Manually configures the delay prescaler and scaler for a particular CTAR.

* This function configures the:

* PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK),

* After SCK delay pre-scalar (PASC) and scalar (ASC),

* Delay after transfer pre-scalar (PDT)and scalar (DT).

*

* These delay names are available in type dspi_delay_type_t.

*

* The user passes which delay they want to configure along with the prescaler and scaler value.

* This basically allows the user to directly set the prescaler/scaler values if they have

* pre-calculated them or if they simply wish to manually increment either value.

*END**************************************************************************/

void DSPI_HAL_SetDelay(SPI_Type * base, dspi_ctar_selection_t whichCtar, uint32_t prescaler,

                       uint32_t scaler, dspi_delay_type_t whichDelay)

{

    /* these settings are only relevant in master mode */

    if ((bool)SPI_RD_MCR_MSTR(base))

    {

        if (whichDelay == kDspiPcsToSck)

        {

            SPI_BWR_CTAR_PCSSCK(base, whichCtar, prescaler);

            SPI_BWR_CTAR_CSSCK(base, whichCtar, scaler);

        }

        if (whichDelay == kDspiLastSckToPcs)

        {

            SPI_BWR_CTAR_PASC(base, whichCtar, prescaler);

            SPI_BWR_CTAR_ASC(base, whichCtar, scaler);

        }

        if (whichDelay == kDspiAfterTransfer)

        {

            SPI_BWR_CTAR_PDT(base, whichCtar, prescaler);

            SPI_BWR_CTAR_DT(base, whichCtar, scaler);

        }

    }

}

From the "C" code it shows there are 3 delays you can tune.  The example code is only adjusting the "kDspiPcsToSck" delay but you can also add in calls to the "kDspiLastSckToPcs", and "kDspiAfterTransfer".

Now if you want the code to calculate the nears possible delay value(s) there is a function to review as well:

/*!

* @brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds.

*

* This function calculates the values for:

* PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or

* After SCK delay pre-scalar (PASC) and scalar (ASC), or

* Delay after transfer pre-scalar (PDT)and scalar (DT).

*

* These delay names are available in type dspi_delay_type_t.

*

* The user passes which delay they want to configure along with the desired delay value in

* nanoseconds.  The function calculates the values needed for the prescaler and scaler and

* returning the actual calculated delay as an exact delay match may not be possible. In this

* case, the closest match is calculated without going below the desired delay value input.

* It is possible to input a very large delay value that exceeds the capability of the part, in

* which case the maximum supported delay is returned. It is to the higher level

* peripheral driver to alert the user of an out of range delay input.

*

* @param base Module base pointer of type SPI_Type.

* @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type

*                  dspi_ctar_selection_t.

* @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t

* @param sourceClockInHz Module source input clock in Hertz

* @param delayInNanoSec The desired delay value in nanoseconds.

* @return The actual calculated delay value.

*/

uint32_t DSPI_HAL_CalculateDelay(SPI_Type * base, dspi_ctar_selection_t whichCtar,

                                 dspi_delay_type_t whichDelay, uint32_t sourceClockInHz,

                                 uint32_t delayInNanoSec);

In summary I think the dspi_blocking_example_master_frdmk22f example is setting up the Driver with default delays.  Using the polling example to see how using HAL function calls to setup delays, should allow you to tune the SPI interface for your application.

Regards,

David

0 Kudos
Reply

1,271 Views
anbui
Contributor II

Muxing the flash clock out to PTC3 gave us the following results with:

.mcgConfig.drs     = kMcgDcoRangeSelMidHigh, // 12Mhz = 60 Mhz SystemCoreClock

.mcgConfig.drs     = kMcgDcoRangeSelHigh, // 16Mhz  = 80 Mhz SystemCoreClock.

We went with kMcgDcoRangeSelHigh to get us the 80 Mhz frequency.  We continued with out testing on the UART and the data received match what was expected. 

We moved on to the SPI module to continue our hardware verification.  The SPI is configured as followed:

  userConfig.isChipSelectContinuous = false;

  userConfig.isSckContinuous  = false;

  userConfig.pcsPolarity  = kDspiPcs_ActiveLow;

  userConfig.whichCtar  = kDspiCtar0;

  userConfig.whichPcs  = kDspiPcs0

  spiDevice.dataBusConfig.bitsPerFrame = 8;

  spiDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge;

  spiDevice.dataBusConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;

  spiDevice.dataBusConfig.direction = kDspiMsbFirst;

  spiDevice.bitsPerSec = 100000;

We transfer 28 bytes / transfer with DSPI_DRV_MasterTransferBlocking();

The clock between bits( 8 & 9, 16 & 17, 24 & 25 .....) does not allow enough setup.  Exactly every 8 bits, the duty cycle for the SCLK is invalid.  However, if we changer the baudrate from 100khz to 3 Mhz, there is a much larger delay of the SCLK.

0 Kudos
Reply

1,271 Views
anbui
Contributor II

The OSC0 configuratation:

    osc_user_config_t osc0Config =

    {

        .freq                = OSC0_XTAL_FREQ,  // 16000000U

        .hgo                 = MCG_HGO0,  //kOscGainLow

        .range               = MCG_RANGE0,  //kOscRangeVeryHigh

        .erefs               = MCG_EREFS0,  // kOscSrcOsc

        .enableCapacitor2p   = OSC0_SC2P_ENABLE_CONFIG,  //false

        .enableCapacitor4p   = OSC0_SC4P_ENABLE_CONFIG,  //false

        .enableCapacitor8p   = OSC0_SC8P_ENABLE_CONFIG,  //false

        .enableCapacitor16p  = OSC0_SC16P_ENABLE_CONFIG,  //false

    };

0 Kudos
Reply

1,271 Views
xiangjunrong
Contributor IV

Hi, An,

At the time being, I think you have to know the exact clock frequency of the core/system clock. There is a pin

PTC3/CMP1_IN1/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT

you can use the code and hook the scope to PTC3 to test the flash clock.

//enable PORTC clock

SIM_SCGC5|=0x800;

PORTC_PCR3&=~(0x700);

PORTC_PCR3|=5<<8;

SIM_SOPT2|=2<<5; //CLKOUT output flash clock

//checking the SIM_CLKDIV1 register  setting, you can figure out out the core/system clock, the core/system clock drive the UART module for K0

Hope it can help you.

BR

Xiangjun Rong

0 Kudos
Reply

1,271 Views
DavidS
NXP Employee
NXP Employee

Hi An,

Xiangjun Rong has good suggestion.

What development tools are you using?  KDS_3.2 + KSDK_v2 ?

Have you downloaded the KSDK_v2 for the K02 device?

It has a example to allow playing with clock:

C:\NXP\KSDK_v2\SDK_2.0_MK02FN128xxx10\boards\frdmk22f\driver_examples\mcg\fee_blpe\kds

Regards,

David

0 Kudos
Reply