Clock Control Configuration Confirmation

Hello,

I am utilizing a Laird (now ezurio) bl5340 module on my custom board which requires the internal 13.5pF caps to be set for the high frequency 32Mhz clock source as specified by their datasheet:



I have done this by adding the following to my custom board deconfig file as shown here:



Within my custom board I'm also using an external 32kHz clock for the low frequency control with 5ppm accuracy in the hope of getting better BLE performance. I would like confirmation that the above config file will correctly utilize the external clock source. Here are the schematics for how we hooked up the clock:

  


Used this information from the Laird data sheet to determine this configuration for the wiring:



My question is regarding my defconfig file and if those options are correct. When I look at the bl5340_dvk defconfig file for example, they have the same settings for the HFXO clock, so I think that is right, but that dev kit also uses an external low frequency oscillator, but I don't see an explicit config for setting the low frequency controller to use the external source. Am I misunderstanding what the "CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y" option does? Is this not required, and does the system automatically know to utilize the external source? Do I need to set "CONFIG_CLOCK_CONTROL_NRF_K32SRC_20PPM=y" as that is the lowest option, my source is rated at 5ppm? I'm using MPSL (switches between ble and custom layer for synch purposes) so I believe these timings actually do impact how the radio resources get split up and I would like to be as efficient as possible and utilize this very nice clock source to its fullest. I'm assuming I don't need to set any of the internal LFXO caps due to our rail to rail clock setup? Help is greatly appreciated. 

Parents
  • Hi,

    The configuration for the HFXO looks correct.

    When I look at the bl5340_dvk defconfig file for example, they have the same settings for the HFXO clock, so I think that is right, but that dev kit also uses an external low frequency oscillator, but I don't see an explicit config for setting the low frequency controller to use the external source. Am I misunderstanding what the "CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y" option does? Is this not required, and does the system automatically know to utilize the external source?

    CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y is needed to use the external oscillator source. I assume the development kit for the module doesn't set this as default since the module doesn't have the crystal internally.

    Do I need to set "CONFIG_CLOCK_CONTROL_NRF_K32SRC_20PPM=y" as that is the lowest option, my source is rated at 5ppm?

    Yes, this config is for crystalls/oscillators with 0-20ppm accuracy.

    I'm assuming I don't need to set any of the internal LFXO caps due to our rail to rail clock setu

    It doesn't hurt to explicitly disable the internal load caps by adding:

    CONFIG_SOC_LFXO_CAP_EXTERNAL=y

    You also need to set the XOSC32KI.BYPASS register, to bypass the LFCLK crystall oscillator when using a rail-to-rail external source.

    This can be done by adding:

    #include <zephyr/init.h>
    #include <nrf.h>
    
    static int lfclk_bypass_full_swing(void)
    {
    	NRF->OSCILLATORS.XOSC32KI.BYPASS=1;
    	return 0;
    }
    
    SYS_INIT(lfclk_bypass_full_swing, EARLY,0);
    

     

    Best regards,
    Bendik

  • Thank you so much Bendik! That was very helpful.

  • Hey Bendik, 

    I spoke too soon. That include <nrf.h> file doesn't define any "NRF" struct. I'm attempting to use ncs 2.9.0. I also don't see any NRF struct inside of the zephyr/init.h file. The docs linked are helpful for understanding the registers but don't indicate how I can access or modify them. Please advise. 

  • I'm dumb. I found the base address and offset for the bypass register within the link you posted. Ty again bendik. 

    I tried:

    #define NRF_XOSC32KI_BYPASS_REG (*(volatile uint32_t *)(0x40004000UL + 0x6C0UL)) // Register for bypassing the LFCLK crystal oscillator, board dependant and needs to be updated to use the board config to determine base address
    
    static int lfclk_bypass_full_swing(void)
    {
     NRF_XOSC32KI_BYPASS_REG = 1;
     return 0;
    }
    
    SYS_INIT(lfclk_bypass_full_swing, EARLY,0);


    Unfortunately, this causes the system to hang and I get no output. I need some more guidance here. 

Reply
  • I'm dumb. I found the base address and offset for the bypass register within the link you posted. Ty again bendik. 

    I tried:

    #define NRF_XOSC32KI_BYPASS_REG (*(volatile uint32_t *)(0x40004000UL + 0x6C0UL)) // Register for bypassing the LFCLK crystal oscillator, board dependant and needs to be updated to use the board config to determine base address
    
    static int lfclk_bypass_full_swing(void)
    {
     NRF_XOSC32KI_BYPASS_REG = 1;
     return 0;
    }
    
    SYS_INIT(lfclk_bypass_full_swing, EARLY,0);


    Unfortunately, this causes the system to hang and I get no output. I need some more guidance here. 

Children
Related