USB clock initialization when CPU CLock = 150MHz.

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

USB clock initialization when CPU CLock = 150MHz.

Jump to solution
1,179 Views
arnogir
Senior Contributor II

Hello,

I'm tis K70 150MHz.

By default, Bus Clk is 120MHz in MQX.

for that, in init_gpio.c, _bsp_usb_io_init, the USB clock is initialised like this:

      /* Configure USB divider to be 120MHz * 2 / 5 = 48 MHz */
       SIM_CLKDIV2_REG(SIM_BASE_PTR) &= ~(SIM_CLKDIV2_USBFSDIV_MASK | SIM_CLKDIV2_USBFSFRAC_MASK);
       SIM_CLKDIV2_REG(SIM_BASE_PTR) |= SIM_CLKDIV2_USBFSDIV(4) | SIM_CLKDIV2_USBFSFRAC_MASK;

Now, I change CLock configuration to have Bus Clock to 150MHz.

So If I keep this USB init, USB clock will be 50MHz instead of 48Mhz which is the maximum USB frequency.

But When I change SIM_CLK2 register FSDiv and FSFrac to adapt frequency to lower, USB not work!

I test many value.

Exemple:

        SIM_CLKDIV2_REG(SIM_BASE_PTR) &= ~(SIM_CLKDIV2_USBFSDIV_MASK | SIM_CLKDIV2_USBFSFRAC_MASK);
        SIM_CLKDIV2_REG(SIM_BASE_PTR) |= SIM_CLKDIV2_USBFSDIV(4) ;

To obtain 150Mhz * 1 / 5 = 30MHz, but not work!

Are they a value which work with 150MHz busClock??

Thank

0 Kudos
1 Solution
822 Views
arnogir
Senior Contributor II

Hi,

Ok After test, all work correctly now!

Like PLL0 was no more use to generate MCGOUTCLK, we must activate it.

So use PLL0 at 120MHz for USB only and PLL1 for DDR and LCGOUTCLK was the solution.

Thank for your help

View solution in original post

0 Kudos
7 Replies
823 Views
arnogir
Senior Contributor II

Hi,

Ok After test, all work correctly now!

Like PLL0 was no more use to generate MCGOUTCLK, we must activate it.

So use PLL0 at 120MHz for USB only and PLL1 for DDR and LCGOUTCLK was the solution.

Thank for your help

0 Kudos
822 Views
arnogir
Senior Contributor II

Hello

I made many test and something is strange.

In default configuration provided in MQX (v4.1.1), the used PLL for MCGOUTCLK is the PLL0 which is configured to 120MHz.

The PLL1 is configured to 150MHz and used for DDR.

Is somebody can confirm this?

The code is following in

__pe_initialize_hardware:

...

/* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=4 */
MCG_C5
= (uint8_t)0x04U;
/* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=8 */
MCG_C6
= (uint8_t)0x08U;
 

/* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=3 */
MCG_C11
= (uint8_t)0x03U;
 
/* MCG_C11: PLLCLKEN1=1 */
MCG_C11
|= (uint8_t)0x40U; /* Enable the PLL */
/* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=8 */
MCG_C12
= (uint8_t)0x08U;
while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
}
while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
}
/* Switch to PBE Mode */
/* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=8 */
MCG_C6
= (uint8_t)0x48U;
while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
}
while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until PLL locked */
}
/* Switch to PEE Mode */
/* MCG_C1: CLKS=0,FRDIV=5,IREFS=0,IRCLKEN=0,IREFSTEN=0 */
MCG_C1
= (uint8_t)0x28U;
while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */
}
/* MCG_C6: CME0=1 */
MCG_C6
|= (uint8_t)0x20U; /* Enable the clock monitor */
/*** End of PE initialization code after reset ***/



With this code, I put in a ground loop a pin toggle.  The time is about 200ns to execute it.

-1) If I change MCG_C5 from 0x4 to 0x3 this could generate PLL0 to 150MHz instead of 120MHz. => The time to toggle bit is about 175ns => Ok Cpu frequency is increased.

But with this, like USB use only PLL0 we can't reach 48MHz exactly.

-2) By previous test, we can consider PLL0 is Ok because  all run correctly, but MCG_C5.PLLCLKEN0 is set to 0 = PLL0 not enabled!!! ??? So what this RUN???

-3) Now the idea is to keep PLL0 to 120MHz and PLL1 to 150MHHz (MQX original configuration) and just switch MCGOUTCLK from PLL0 (120MHz) to PLL1 (150MHz) to increase core/bus... from 120MHz to 150MHz like my CPU is a K70F150M.

To do that, I just changed the configuration of MCG_11 from 0x03 to 0x13 (PLLCS = 1 => use PLL1 not PLL0).

If I do that, the code stay block on the following test:

while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U)...

Like PLL0 was not enable (and it is TRUE!!) But why this Run when PLL0 is selected for MCGOUTCLK???

0 Kudos
822 Views
arnogir
Senior Contributor II

OK!! In fact, the PLLn is enable if PLLCLKENn is set of if PLLn is selected by PLLS/PLLCS!....

0 Kudos
822 Views
mjbcswitzerland
Specialist V

Hi

Note that the "system" or "core" clock is 150MHz and not the bus clock.

Below is how it is done in the uTasker project for 150Mhz K70 and FS USB OTG (including [hex values] to check with in case the defines are not understandable.

Regards

Mark

    // CPU clocks 150MHz core, 75MHz bus, 25MHz flash
    //
    MCG_C2 = (MCG_C2_RANGE_8M_32M | MCG_C2_LOCRE0);                      // [0xa0] select external clock source
    MCG_C1 = (MCG_C1_CLKS_EXTERN_CLK | MCG_C1_FRDIV_1024);               // [0xa8] switch to external input clock (the FLL input clock is set to as close to its input range as possible, although this is not absolutely necessary since the FLL will not be used)
    while ((MCG_S & MCG_S_IREFST) != 0) {}                               // loop until the FLL source is no longer the internal reference clock
    while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXTERN_CLK) {}      // loop until the external reference clock source is valid
    MCG_C5 = (CLOCK_DIV - 1);                                            // [0x04] now move from state FBE to state PBE
    MCG_C6 = ((CLOCK_MUL - MCG_C6_VDIV0_LOWEST) | MCG_C6_PLLS);          // [0x4e]
    while ((MCG_S & MCG_S_PLLST) == 0) {}                                // loop until the PLLS clock source becomes valid
    while ((MCG_S & MCG_S_LOCK) == 0) {}                                 // loop until PLL locks
    SIM_CLKDIV1 = (((SYSTEM_CLOCK_DIVIDE - 1) << 28) | ((BUS_CLOCK_DIVIDE - 1) << 24) | ((FLEX_CLOCK_DIVIDE - 1) << 20) | ((FLASH_CLOCK_DIVIDE - 1) << 16)); // [0x0125000] prepare bus clock divides
    MCG_C1 = (MCG_C1_CLKS_PLL_FLL | MCG_C1_FRDIV_1024);                  // [0x28] finally move from PBE to PEE mode - switch to PLL clock
    while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL) {}             // loop until the PLL clock is selected

    // USB FS OTG clock
    //
    SIM_SOPT2 |= (SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_USBFSRC_MCGPLL1); // [0x44851000] set the source to MCGPLL1CLK
    SIM_CLKDIV2 |= (((((USB_CLOCK_SOURCE * 2)/48000000) - 1) << 1) | SIM_CLKDIV2_USBFRAC); // [0x0000007] the value of the clock source must be chosen to allow 48MHz to be achieved!
0 Kudos
822 Views
arnogir
Senior Contributor II

Hello

Ok, I think I found where  come from my problem.

Data sheet indicate:

USBFS_Clk.jpg

Then If I well understand, the USB FS Clock MUST be exactly 48MHz to Rune correctly. But this frequency is not reachable with a PLL0 Clk source = 150MHz.

So I can used the unused PLL1, configure it to 120MHz then configure USBFRAC/USBDIV to have 48MHz.

In your exemple, The USBCLock source is also the PLL1:

SIM_SOPT2 |= (SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_USBFSRC_MCGPLL1);

But you do not show how is configured the PLL1. I think the Output frequency of PLL1 should be equal to value of USB_CLOCK_SOURCE. (You do not show its definition) According final value ([0x04]) it seem your PLL1 is set to 96MHz?? (x2 / 4 = 48MHz)

Then I will try to use PLL1 ans see if Ok. But during my search, I seen a think but not found the solution:

Where the PLL0 is enabled? (MCG_C5.PLLCLKEN0) ...???

0 Kudos
822 Views
arnogir
Senior Contributor II

=> It seems the PLL1 is used for DDRClock. And in BSP it is configured to 150MHz I think...???

So the first idea is to used PLL1 which is already set to 150MHz to used it also for the MCGOUTCLK (Core clock). (MCG_C11.PLLCS bit set to 1...) So the PLL0 will only used for the USB set to 120MHz. (PLL0 can also be used by LCDC and SAI, but I not use SAI and LCDC module is on BucClock)

0 Kudos
822 Views
mjbcswitzerland
Specialist V

Hi

I missed adding the PLL1 configuration - below is a reference from a 12MHz crystal on EXTAL0/XTAL0. 120MHz is generated so that it can be used for USB. If DDR is used it is also clocked 120MHz since it is clocked exclusively for the PLL1 output.

Your strategy to use PLL1 at 150MHz and PLL0 at 120MHz (PLL0 exclusively for USB and PLL1 as core clock and DDR) would allow fastest DDR.

Regards

Mark

    // PLL1 configuration from 12MHz crystal - generate 120MHz for use by DDR and for USB to generate 48MHz
    //
    MCG_C11 = (MCG_C11_PLLREFSEL1_OSC0 | MCG_C11_PLLCLKEN1 | (CLOCK_DIV_1 - 1)); // [0x40] use OSCO clock source for PLL1 with input divide set
    MCG_C12 = (CLOCK_MUL_1 - MCG_C12_VDIV1_LOWEST);                      // [0x04] set multiplier
    MCG_C5 = ((CLOCK_DIV - 1) | MCG_C5_PLLSTEN0);                        // [0x20] now move from state FEE to state PBE (or FBE) PLL remains enabled in normal stop modes
    MCG_C6 = ((CLOCK_MUL - MCG_C6_VDIV0_LOWEST) | MCG_C6_PLLS);          // [0x49] set the PLL multiplication factor
    while ((MCG_S & MCG_S_PLLST) == 0) {}                                // loop until the PLLS clock source becomes valid
    while ((MCG_S & MCG_S_LOCK1) == 0) {}                                // loop until PLL locks
0 Kudos