How to enable NRF52840 to use external 32MHz crystal?

Hi all,

I'm trying to get a UART connection running at 460800 bps, and it fails about 1-5% of the time, meaning that I receive less bytes than I expect. This happens a lot less when I set the speed down to 115200 bps.

I read on the datasheet that "the external crystal oscillator must be enabled to obtain sufficient clock accuracy", page 512. I am using a u-blox Nina B301 (NRF52840), and that unit has a 32MHz oscillator attached to it.

I'm looking at the registers for the clock, and I get:

TASKS_HFCLKSTART -> 0x0

TASKS_HFCLKSTOP -> 0x0

EVENTS_HFCLKSTARTED -> 0x0

HFCLKSTAT -> 0x10000

I am assuming this tells me the clock is working from the internal 64MHz oscillator, I'm not actively doing any initialisation of the clock.

I'd like to activate the 32MHz external oscillator, but I am a bit lost with Zephyr on that driver. I only set

CONFIG_CLOCK_CONTROL=y
But I don't know any other settings or how to change the registers once the system has started.
Any help is greatly appreciated!
Cheers,
Alberto
PS.: 
I'm running on Windows 11, using a J-link debugger and SDK2.5.0 on VS Code. All else seems to work well.

Parents
  • Hey   

    Thanks for your quick replies.

    I managed to turn on the External Clock with:

    /* To strictly comply with UART timing, enable external XTAL oscillator */
    void enable_xtal(void)
    {
    	struct onoff_manager *clk_mgr;
    	static struct onoff_client cli = {};
    
    	clk_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
    	sys_notify_init_spinwait(&cli.notify);
    	(void)onoff_request(clk_mgr, &cli);
    }

    inside my "main()", and after checking the registers, it looks like all is set correctly.

    Unfortunately I cannot use the RTS/CTS lines due to the data coming from an external device over which we have no control. Not a big deal, it's bursts of 33 bytes at 200Hz (5ms), and mostly into the micro.

    I checked the error registers, actually, I check them constantly after each burst of data reception, and there are no errors.

    Bottom line is, the serial interface with the active external crystal works very well and the data is received correctly. I am able to decode the stream as it's coming in and the buffer changes ok.

    In terms of activating the clock, this has been resolved, thank you very much!

    I want to open a new thread regarding the reading of the UARTE buffers.

    Cheers,

    Alberto

Reply
  • Hey   

    Thanks for your quick replies.

    I managed to turn on the External Clock with:

    /* To strictly comply with UART timing, enable external XTAL oscillator */
    void enable_xtal(void)
    {
    	struct onoff_manager *clk_mgr;
    	static struct onoff_client cli = {};
    
    	clk_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
    	sys_notify_init_spinwait(&cli.notify);
    	(void)onoff_request(clk_mgr, &cli);
    }

    inside my "main()", and after checking the registers, it looks like all is set correctly.

    Unfortunately I cannot use the RTS/CTS lines due to the data coming from an external device over which we have no control. Not a big deal, it's bursts of 33 bytes at 200Hz (5ms), and mostly into the micro.

    I checked the error registers, actually, I check them constantly after each burst of data reception, and there are no errors.

    Bottom line is, the serial interface with the active external crystal works very well and the data is received correctly. I am able to decode the stream as it's coming in and the buffer changes ok.

    In terms of activating the clock, this has been resolved, thank you very much!

    I want to open a new thread regarding the reading of the UARTE buffers.

    Cheers,

    Alberto

Children
  • thanks. Alberto

    I use such code to set the extern Clock. but after run the code. I find the DK would run to right status. the extern clock is working.

    But, In my own designed board. the cystal chip is different from DK.  and after the code is run. I find the exten clock did not work.

    HFCLKSTAT  src = 0. means it is using internal clock.

    what can I check now?

    thanks.

Related