ds3231 RTC changes the internal clock frequency in nrf52840

Hello,

I want to compare the RTC's counter_get_value() ticks with the internal clocks k_uptime_ticks() ticks. The problem is when the RTC is connected with our nrf 52840 through I2C it changes the internal clocks frequency, Im not syncronizing the clocks in any way. The 32768Hz frequenzy on the internal clock goes down to like 4096Hz and on some other nrf52840 cards to ~1600Hz(It weird I know).

Parents
  • We get this same issue with the sampe "Maxim DS3231 TCXO RTC Sample Application" 

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.8.0/zephyr/samples/drivers/counter/maxim_ds3231/README.html

    We modified the function set_aligned_clock a bit, to write to the terminal before and after the call on "k_sleep(K_msec(10000));". We print t2 - t1, this seems correct, 327690 ticks, but measuring with a stop watch it took 95 seconds. Almost 10 times 10 000msec. Mind you this is the only change we made to the sample. We use the same overlay file.

    The changes to the function:

    static void set_aligned_clock(const struct device *ds3231)
    {
    	if (!IS_ENABLED(CONFIG_APP_SET_ALIGNED_CLOCK)) {
    		return;
    	}
    
    	uint32_t syncclock_Hz = maxim_ds3231_syncclock_frequency(ds3231);
    	uint32_t syncclock = maxim_ds3231_read_syncclock(ds3231);
    	uint32_t now = 0;
    	int rc = counter_get_value(ds3231, &now);
    	uint32_t align_hour = now + 3600 - (now % 3600);
    
    	struct maxim_ds3231_syncpoint sp = {
    		.rtc = {
    			.tv_sec = align_hour,
    			.tv_nsec = (uint64_t)NSEC_PER_SEC * syncclock / syncclock_Hz,
    		},
    		.syncclock = syncclock,
    	};
    
    	struct k_poll_signal ss;
    	struct sys_notify notify;
    	struct k_poll_event sevt = K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
    							    K_POLL_MODE_NOTIFY_ONLY,
    							    &ss);
    
    	k_poll_signal_init(&ss);
    	sys_notify_init_signal(&notify, &ss);
    
    	uint32_t t0 = k_uptime_get_32();
    
    	rc = maxim_ds3231_set(ds3231, &sp, &notify);
    
    	printk("\nSet %s at %u ms past: %d\n", format_time(sp.rtc.tv_sec, sp.rtc.tv_nsec),
    	       syncclock, rc);
    
    	/* Wait for the set to complete */
    	rc = k_poll(&sevt, 1, K_FOREVER);
    
    	uint32_t t1 = k_uptime_ticks();
    	printk("begins the timer");
    
    	/* Delay so log messages from sync can complete */
    	k_sleep(K_MSEC(10000));
    	printk("stops the timer");
    	uint32_t t2 = k_uptime_ticks();
    
    	printk("Synchronize final: %d %d in %u ms\n", rc, ss.result, t2 - t1);
    
    	rc = maxim_ds3231_get_syncpoint(ds3231, &sp);
    	printk("wrote sync %d: %u %u at %u\n", rc,
    	       (uint32_t)sp.rtc.tv_sec, (uint32_t)sp.rtc.tv_nsec,
    	       sp.syncclock);
    }

    Our deck:

  • You have to know how much tics do you have at 1 second

    This value should be your reference

    LOG_INF("CONFIG_SYS_CLOCK_TICKS_PER_SEC = %d", CONFIG_SYS_CLOCK_TICKS_PER_SEC);

  • CONFIG_SYS_CLOCK_TICKS_PER_SEC  is set to 32768 in autoconfig.h

Reply Children
No Data
Related