cancel
Showing results for 
Search instead for 
Did you mean: 

PLL_Q for USB

shingadaddy
Senior
Posted on November 18, 2016 at 04:52

STM32L476RG on Nucleo - Porting over the example from EVAL board with 8Mhz Crystal

STM32CubeL4 - HAL demo.

If using the HSE with an input source of 8Mhz supplied by STlink,

1. I believe I need to set HSEBYP = 1 for EXTERNAL CLOCK instead of EXTERNAL CRYSTAL. Right?

2. Shouldn't the PLL_Q setting be 6?   (6 x 8000000 = 48 MHZ) HAL demo for EVAL and PLL has setting of 4 while the schematic shows again, an 8 MHZ crystal..

/* Select PLLSAI output as USB clock source */

  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;

  PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;

  PeriphClkInitStruct.PLLSAI1.PLLSAI1N = 24;

  PeriphClkInitStruct.PLLSAI1.PLLSAI1Q = 4; // ?????????

 

  PeriphClkInitStruct.PLLSAI1.PLLSAI1P = 1;

  PeriphClkInitStruct.PLLSAI1.PLLSAI1M = 1;

  PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;

  PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut= RCC_PLLSAI1_48M2CLK;
8 REPLIES 8
shingadaddy
Senior
Posted on November 18, 2016 at 17:05

Yes on the HSEBYP

Well NO on the PLL....

The data sheet says ''PLL multiplier output''. Misleading

The RM0351 Reference Manual has the formula

So you have to

1. Input a frequency to the PLL within its acceptable range

2. Use PLL_M to DIVIDE the clock source if needed to within that range

In my part case that effects ALL 3 PLL's

3. Use PLL_N as a MULTIPLY. Each PLL has its own N

4. Use PLL outputs  P, Q and R as DIVIDERS.

Your data sheet has the MIN and MAX VCO frequency capabilities of the VCO in multiple RANGES (selectable)

So ''4'' for my setup was correct.

HSE = 8MHZ

M=1    (Full HSE freq into all 3 PLL's )

N=24   (Multiplied by 24 sets VCO freq of 192Mhz)

Q=4     Divides 192Mhz to 48Mhz

This stuff can vary from part to part so be on the lookout. This PLL stuff, judging by the smattering of posts and confusing possibilities in the docs results in endless possibilities of snipe hunting.

Posted on November 18, 2016 at 17:34

This PLL stuff, judging by the smattering of posts and confusing possibilities in the docs results in endless possibilities of snipe hunting.

I think some of that comes from the over reliance of automated tools to select parameters and clock tree settings, rather than understanding the relatively simple mechanics and relationships involved.

The PLL here has a single VCO, and comparison frequency (defined by M and N), and then 3 taps that divide down the VCO clock (P, Q, R), which need to be at least 2x because the clock is pulsing rather than having 50/50 duty cycle the rest of the chip needs.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
shingadaddy
Senior
Posted on November 18, 2016 at 18:07

100% agree! Even with me coming into this ST and their new line I have had good reason NOT to get too deep because all (well MOST) things just work 🙂 All the while I know I need to know these things at the register level for when we do our own I/P. Or as in this case - When I hit a STUMP! Hopefully not many stumps left. Still no enumeration or basic recogintion when connected. No VBUS sense and no pull up applied to DP or DM (can't remember which - FULL SPEED) hints to me the clocks are fouled (Usb core not running) That HSEBYP might be the ticket. I'll get to that today hopefully. I think I can actually work on this contiguously for a bit now. I'll poke HSE out the MCO and MDS its running.

shingadaddy
Senior
Posted on November 18, 2016 at 22:31

Okay I'm in a HAL demo (clive1- I know - not your favorite but) here's the files names and code to look at.

Trying to decide where to put this HSE bypass bit control in my code, I did a search for HSEBYP. It sure seems to me that this was an afterthought in the hal stuff.In the file stm32l4xx_hal_rcc_ex.c, in function RCCEx_PLLSAI1_Config its check here at LINE NUMBER 2427:

   

    case RCC_PLLSOURCE_HSE:

 (Line:2427)

      if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY) && HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP))

      {

        status = HAL_ERROR;

      }

      break;

    default:

      status = HAL_ERROR;

      break;

    }

   

    if(status == HAL_OK)

    {

      /* Set PLLSAI1 clock source and divider M */

      MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai1->PLLSAI1Source | (PllSai1->PLLSAI1M - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLM));

    }

  }

 

  if(status == HAL_OK)

  {

    /* Disable the PLLSAI1 */

    __HAL_RCC_PLLSAI1_DISABLE();

    /* Get Start Tick*/

    tickstart = HAL_GetTick();

    /* Wait till PLLSAI1 is ready to be updated */

    while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET)

    {

      if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)

      {

        status = HAL_TIMEOUT;

        break;

      }

    }

    if(status == HAL_OK)   

    {

      if(Divider == DIVIDER_P_UPDATE)

      {

        assert_param(IS_RCC_PLLSAI1P_VALUE(PllSai1->PLLSAI1P));

        /* Configure the PLLSAI1 Division factor P and Multiplication factor N*/

#if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)

        MODIFY_REG(RCC->PLLSAI1CFGR,

                   RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV,

                   (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |

                   (PllSai1->PLLSAI1P << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV)));

#else

        MODIFY_REG(RCC->PLLSAI1CFGR,

                   RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1P,

                   (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |

                   ((PllSai1->PLLSAI1P >> 4U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1P)));

#endif /* RCC_PLLSAI1P_DIV_2_31_SUPPORT */

      }

      else if(Divider == DIVIDER_Q_UPDATE)

      {

        assert_param(IS_RCC_PLLSAI1Q_VALUE(PllSai1->PLLSAI1Q));

        /* Configure the PLLSAI1 Division factor Q and Multiplication factor N*/

        MODIFY_REG(RCC->PLLSAI1CFGR,

                   RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q,

                   (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |

                   (((PllSai1->PLLSAI1Q >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q)));

      }

      else

      {

        assert_param(IS_RCC_PLLSAI1R_VALUE(PllSai1->PLLSAI1R));

        /* Configure the PLLSAI1 Division factor R and Multiplication factor N*/

        MODIFY_REG(RCC->PLLSAI1CFGR,

                   RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R,

                   (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |

                   (((PllSai1->PLLSAI1R >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R)));

      }

      /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/

      __HAL_RCC_PLLSAI1_ENABLE();

      /* Get Start Tick*/

      tickstart = HAL_GetTick();

      /* Wait till PLLSAI1 is ready */

      while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)

      {

        if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)

        {

          status = HAL_TIMEOUT;

          break;

        }

      }

      if(status == HAL_OK)   

      {

        /* Configure the PLLSAI1 Clock output(s) */

        __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PllSai1->PLLSAI1ClockOut);

      }

    }

  }

 

  return status;

}

It seems as though if this bit is set, this causes the ''status'' to reflect ''HAL_ERROR''

Following on in the code it looks like if THATS the case, the rest of the PLL setup gets skipped?

Another oddity when looking at the register this bit is in, it states that the HSEBYP bit is uneffected

by a reset.

I DO want to use an external clock but of course I need it to go to the PLLSAI and I need the PLL control.

Any hints on maybe the best place to ha-- uh PUT this in just in case it upsets something else somewhere else?

Thanks folks

shingadaddy
Senior
Posted on November 20, 2016 at 16:18

Manual:

''External source (HSE bypass)

In this mode, an external clock source must be provided. It can have a frequency of up to

48 MHz. You select this mode by setting the HSEBYP and HSEON bits in the Clock control

register (RCC_CR). The external clock signal (square, sinus or triangle) with ~40-60 % duty

cycle depending on the frequency (refer to the datasheet) has to drive the OSC_IN pin while

the OSC_OUT pin can be used a GPIO. See Figure 13.''

Apparently NOT...AS a simple test, and with the project having the HSEBYP NOT set, I have the STLINK 8 MHZ clock connected to OSC IN pin. I have ONLY the HSE clock configured and enable and it drives ALL 3 of my PLL's And I have sys clock set as source from PLL. And yes - a blinking loop driven LED And yes the processor is running. At 80Mhz or 40Mhz or 10 Mhz - whatever I set the HSE driven, sysclk connected PLL output''DIVIDER'' (not MULTIPLIER as in the manual) too. So HSE is running. Even with HSEBYP = 0. No need to check MCO.

So best I have found is an aged post by clive1 that states the HSEBYP is only there to allow the OSC OUT pin to be freed up and used as a GPIO. It has nothing to do with an external clock source being FUNCTIONAL OR NOT if that external source is stuck into the device on the OSC IN PIN.

So again, vague and ambiguous leads to snipe hunt.

One thing I did find was that my project still had UART 1 configured and VBUS sense enable to detect USB POWERED from a host. In my mind I wonder if that POPPED something in the device. I would have thought the uart driver might get angry having a hard 5V stuck on it and maybe welded the innards.

Possible?

I'm checking the interrupts to make sure AGAIN that they are set up right. Then I'll try a second Nucleo board.

Anyone having an L4 with EVAL HAL USB DEVICE functional, feel free to speak up. On Nucleo would be a confidence booster plus -

 Yeah I'm here on Sunday. All day looks like.

shingadaddy
Senior
Posted on November 21, 2016 at 21:06

SO checked a few things again and still no interrupt firing when I plug cable in. No applied pull up from micro on DP.

Still acts like not getting VBUS. Check voltage RIGHT TO THE PA9 PIN (42) this time.

So I'm to the point where I decide to just go ahead and roll a CUBEMX project for stm32L476RG.Just enabling the USB device only, with HSE as clock, with VBUS sensing and see if I have missed

something in the clock setup that MX might uncover. That (at first) doesn't provide ANY sound advice other than seeing where the HSE bypass is set and it graphically showing me the OSC/PLL/CLOCK setup I have is okay. So I double check that stuff and try again. NOTHING. No pull up voltage applied to DP when I insert cable. Still seems like CLOCK weirdo or some VBUS sensing problem.

Then I see this little yellow exclamation point in the cubemx pinout screen on TIM1.

Floating over that give me a very, very, very, very cryptic message as follows:

*********

TIM: Timer Partly disabled conflict with:

Requires channel 1 and 2, 1 and 3 or 1 and 2 and 3 to be set either as a clock, a triggersource or in input capture mode. For TIM15 only the sestting of channel 1 and 2 is necessary or/and

USB_OTG_FS: Activate_VBUS VBUS swensing or/and

Channel1 must be in Input Capture Direct Mode to activate that mode or/and

An ITRX or TI1_ED must be selected as Clock/trigger source or/and

At least one channel must be set in output mode or/and

USB_OTG_FS: Mode Device_Only or/and

activated only when a channel is configured in output and not all in forced_output. Not available if ETR is used as a Clock Source or Trigger Source.

**********

THAT blows my mind---- Does this somehow boil down to I need a timer configured to use VBUS sense?

Where is THAT in the manual?

There WAS a timer configured in the DEMO in the EVAL code but I DID (of course) disable all that.

Help me put my mind back together with a translation please.

Again:

STM32L EVAL board project ported over to Nucleo.

USB B type connector with pinout checked about a dozen times

Clock config believed to be correct. (CubeMX agrees)

Interrupts armed/enabled. Handlers defined and included in project.

Any help greatly appreciated.

shingadaddy
Senior
Posted on November 22, 2016 at 16:20

Apparently these CUBEMX indications are just warnings about enabling USB will limit capabilities for using timer one on PA11 and PA12.

Also similar warnings regarding enabling VBUS sensing on PA9.

The REAL story I've stumbled into is all the blood red changes from 1.2 to 1.5.0 in the HAL library files. (And further with the introduction of the 1.5.2 ''PATCH'')

I can't see how anything USB would have ever worked with 1.2 library files unless some heavy tinkering went  on...

shingadaddy
Senior
Posted on December 02, 2016 at 00:30

On Nucleo, with its 32.768 crystal you can use the MSI trimmed with the 32.768 OR the HSE in Bypass with the 8 MHZ clock from STLink via MCO jumpers for your 48MHZ USB clock. Proven both ways.

Follow on if interested.

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/CubeL4%20Eval%20USB%20DEVICE%20CDC%20standalone%20-%20Truestudio%206&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx&currentviews=51]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex%5fmx%5fstm32%2fCubeL4%20Eval%20USB%20DEVICE%20CDC%20standalone%20%2d%20Truestudio%206&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https%3A%2F%2Fmy%2Est%2Ecom%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex%5Fmx%5Fstm32%2FAllItems%2Easpx&currentviews=51