nRF5340 with DS3231 as LXFO

Hi,

I would like to seek a guidance with proper usage of DS3231 as LFXO with nRF5340.

HW:

Custom board, DS3231 32kHz output connected to nRF's X1 with pull-up resistor. X2 floating. INT/SQW floating (we don't need sub-seconds accuracy). Both SOC and IC powered on the same 3.3 rail.

Software:

nRF Connect SDK 3.1.1.

Active-low input gpio-hog on DS3231 reset/nonitor pin.

Default devicetree settings for builtin LFXO in SOC:

&lfxo {
load-capacitors = "internal";
load-capacitance-picofarad = <7>;
};
DS3131's devicetree:
	ds3231@68 {
		compatible = "maxim,ds3231-mfd";
		reg = <0x68>;
		status = "okay";
		temp_sensor: temp_sensor {
			compatible = "maxim,ds3231-sensor";
			status = "okay";
		};
		rtc: rtc {
			compatible = "maxim,ds3231-rtc";
			status = "okay";
			isw-gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; // DUMMY
			freq-32khz-gpios = <&gpio0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; // DUMMY
		};
	};
During AI inspection of my code, LLM accused me of heresy because I just happily configured app to use external osclllator "as-is" thinking it will just work. Is that correct?
App's config:
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_20PPM=y
Despite that, saving system time to RTC (after time sync over BLE) and restoring it from RTC (on boot) work fine, because internal RCs are actually used for all of this?
(and I only get some drift)
How should I properly leverage externally connected (to X1) 32kHz clock? While I don't need sub-seconds accuracy, I would like system time to be as accurate as possible with that HW setup (even though device most likely will not be powered-on continuously for days).

The 32.768 kHz crystal oscillator (LFXO) is designed to work with external sources.

The following external sources are supported:
  • A low swing clock. The signal should be applied to the XL1 pin with the XL2 pin grounded. Set OSCILLATORS.XOSC32KI.BYPASS=Disabled.
  • A rail-to-rail clock. The signal should be applied to the XL1 pin with the XL2 pin left unconnected. Set OSCILLATORS.XOSC32KI.BYPASS=Enabled.
So I should set it to bypass=enabled.
Question is when to do it safely?
I suppose I can keep all bootloaders (on APP and NET) using internal LFXO (RC) as I don't need accurate timestamps there and internal HFXO is accurate enough for all USB (in ex. serial recovery) operations in bootloader:
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
So it leaves setup of primary app on APP core and ipc_radio on NET core.
Do they both need to use the same LFXO (in ex both RC or both external) or they just need to be independently stable? (ipc_radio for accurate timings and app for my stable system time needs)?
I've read somewhere that LXFO has to be configured (in my case to bypass mode) before HFXO is started.
 Clock Control Configuration Confirmation suggest some way to do it.
How can I inject that init code especially in ipc_radio, without copying sources?
Can I use BOARD_EARLY_INIT_HOOK or something similar?
And the most important, how should devicetree and config look like for RC bypass to work?
I suppose I need
&lfxo {
    load-capacitors = "external";
};
(is status = "okay" needed or driver reads this property regardless because it has to?)
and enable external oscillator even when we are in fact not using oscillator:
CLOCK_CONTROL_NRF_K32SRC_XTAL=y
Can you comment?
Thanks in advance!
Parents
  • Hello,

    The clock driver does not support external clock sources, but you should be able to work around this by setting the bypass register early on boot before the clock driver init as Bendik suggested in the post you linked (Clock Control Configuration Confirmation). 

    I suggest you start with something simple like the "Hello World" sample first to verify that you are able to run it with your external clock source (CLOCK_CONTROL_NRF_K32SRC_XTAL must be set to =y). Since the system timer used by Zephyr relies on this clock source, the program will not reach main() unless the LF clock was started (this assumes the default CONFIG_SYSTEM_CLOCK_WAIT_FOR_STABILITY is selected).

    how should devicetree and config look like for RC bypass to work?
    I suppose I need

    Yes, you should select "external" for the load caps.

    Best regards,

    Vidar 

Reply
  • Hello,

    The clock driver does not support external clock sources, but you should be able to work around this by setting the bypass register early on boot before the clock driver init as Bendik suggested in the post you linked (Clock Control Configuration Confirmation). 

    I suggest you start with something simple like the "Hello World" sample first to verify that you are able to run it with your external clock source (CLOCK_CONTROL_NRF_K32SRC_XTAL must be set to =y). Since the system timer used by Zephyr relies on this clock source, the program will not reach main() unless the LF clock was started (this assumes the default CONFIG_SYSTEM_CLOCK_WAIT_FOR_STABILITY is selected).

    how should devicetree and config look like for RC bypass to work?
    I suppose I need

    Yes, you should select "external" for the load caps.

    Best regards,

    Vidar 

Children
No Data
Related