This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nRF52832 LFCLK external signal and soft device

Hello,

I try to set up an external signal for the LFCLK on a nrf52832. From this question:

  • I know the nrf52832 can do this (signal on XL1 pin, XL2 grounded).
  • I know I must set the bits "bypass" and "external clock" in LFCLKSRC register.

But I don't know how to set these bits through the SDK functions, with a running soft device.

  • Defines like CLOCK_LFCLKSRC_BYPASS_xxx and CLOCK_LFCLKSRC_EXTERNAL_xxx dont exist in the SDK 11.0.0.
  • The function softdevice_handler_init() (through SOFTDEVICE_HANDLER_APPSH_INIT()) hasn't the required parameter in the nrf_clock_lf_cfg_t structure.
  • The function softdevice_handler_init() forces LFCLK configuration and the LFCLKSRC register can't be set after the soft device initialization.

Can someone give me a valid code example?

Thanks !

  • Hi,

    As the post you linked to says you start the clock the same way you start any LF crystal, ie. you call

    SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, false);
    

    Substitute NRF_CLOCK_LFCLKSRC_XTAL_20_PPM with the accuracy of the external clock source you are using.

    Since the SoftDevice uses the LF clock for synchronization is must be left on at all times while the SoftDevice is running.

    Best regards,

    Øyvind

  • Thanks for your quick answer. The method you describe was ok for an old SDK, now softdevice_handler_init (and SOFTDEVICE_HANDLER_INIT and SOFTDEVICE_HANDLER_APPSH_INIT) takes a nrf_clock_lf_cfg_t structure as the first parameter. With the SDK 111.0.0, I use:

    	#define NRF_CLOCK_LFCLKSRC {							\
    	.source        = NRF_CLOCK_LF_SRC_SYNTH,				\
    	.rc_ctiv       = 0,									\
    	.rc_temp_ctiv  = 0,									\
    	.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM	\
    }
    nrf_clock_lf_cfg_t clockLfCfg = NRF_CLOCK_LFCLKSRC;
    SOFTDEVICE_HANDLER_APPSH_INIT(&clockLfCfg, true);
    

    But I need to set the "bypass" and "external clock" bits in LFCLKSRC register and nrf_clock_lf_cfg_t doesn't help me to do that...

    Do you have any example code to do that?

    -> See my own answer

  • With other answers and some studying, I have found the solution:

    • external clock signal must be connected to XL1 pin,
    • XL2 pin may be left floating or be grounded (if the signal voltage isn't rail-to-rail),
    • LFCLK MUST be configured for external clock signal and started BEFORE enabling the softdevice,
    • the softdevice may now be initialized with NRF_CLOCK_LF_SRC_XTAL for the LFCLK.

    Here is a code example (for the nRF52832) :

    /* Defines not available in the SDK 11.0.0 */
    /* Register: CLOCK_LFCLKSRC */
    /* Description: Clock source for the LFCLK */
    
    /* Bits 16 : Enable or disable bypass of LFCLK crystal oscillator with external clock source */
    #define CLOCK_LFCLKSRC_BYPASS_Pos (16UL) /*!< Position of BYPASS field. */
    #define CLOCK_LFCLKSRC_BYPASS_Msk (0x1UL << CLOCK_LFCLKSRC_SRC_Pos) /*!< Bit mask of BYPASS field. */
    #define CLOCK_LFCLKSRC_BYPASS_Disabled (0UL) /*!< Disabled bypass */
    #define CLOCK_LFCLKSRC_BYPASS_Enabled (1UL) /*!< Enable bypass */
    
    /* Bits 17 : Enable or disable external source for LFCLK */
    #define CLOCK_LFCLKSRC_EXTERNAL_Pos (17UL) /*!< Position of EXTERNAL field. */
    #define CLOCK_LFCLKSRC_EXTERNAL_Msk (0x1UL << CLOCK_LFCLKSRC_SRC_Pos) /*!< Bit mask of EXTERNAL field. */
    #define CLOCK_LFCLKSRC_EXTERNAL_Disabled (0UL) /*!< Disabled external source */
    #define CLOCK_LFCLKSRC_EXTERNAL_Enabled (1UL) /*!< Enable external source */
    
    /* Configuring LFCLK to use an external signal */
    NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) |
    	(CLOCK_LFCLKSRC_BYPASS_Enabled << CLOCK_LFCLKSRC_BYPASS_Pos ) |
    	(CLOCK_LFCLKSRC_EXTERNAL_Enabled << CLOCK_LFCLKSRC_EXTERNAL_Pos);
    
    /* Starting LFCLK */
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_LFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
    	/* Nothing to do */
    }
    
    /* Initialising softdevice with a 'crystal' for LFCLK source (and no scheduler) */
    nrf_clock_lf_cfg_t clockLfCfg = {
    	.source        = NRF_CLOCK_LF_SRC_XTAL,
    	.rc_ctiv       = 0,
    	.rc_temp_ctiv  = 0,
    	.xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM
    };
    SOFTDEVICE_HANDLER_INIT(&clockLfCfg, NULL);
    
Related