Re: nRF52832 hardware cycle count freezing at chip start


Thiago Silveira
 

Hi Vinayak,

> I assume, you mean, you are using nRF52832 chip and your custom board; and using a Zephyr build using the BOARD=nrf52_pca10040.
> Do you have the 32KHz crystal mounted in your custom PCB? If not, you will need to use the internal RC oscillator by enabling CONFIG_CLOCK_CONTROL_NRF5_K32SRC_RC=y.

Good question! I checked and yes, we have the 32KHz crystal mounted in our custom PCB. We also tested with the nRF52 DK (the physical nrf52_pca10040 board).
We do use the nrf52_pca10040 board to build for our custom PCB, with some modifications in our prj.conf to suit our board (mainly UART TX/RX).

> Currently there is no watchdog driver for nRF52 contributed yet to Zephyr. I am not an expert on this peripheral, but I do notice in your code, you enable interrupt from the watchdog peripheral, hope you have setup interrupt handler correctly, clear the events and kick the dog sufficiently, etc.
> If your application needs watchdog, I would advise you implement a watchdog driver following the Zephyr driver model (include/watchdog.h and in drivers/watchdog folder). We will be glad to review your driver and a simple sample application. 

We do kick the dog sufficiently, and the watchdog is working fine apart from this initial hiccup. I'm not so sure about the events (other than clearing the channel).
Following your suggestions, I'm going to explore a little further the watchdog in nRF52832 and implement a driver following the Zephyr driver model.
Hopefully I could merge this back into upstream for the 1.10 release (as 1.09 is feature frozen)?

> Please remember that nRF52 is a ultra low power chip and there is no functional ARM systick timer, the system timer is implemented using the NRF_RTC peripheral.
> The resolution of each tick is in 32KHz units. If you print in busywait, you will see lot of lines with same values until each 32KHz (*if* UART tx time is very much less than 30.517 us, which I doubt).
> Ok, you want to wait 100 microseconds and your printk inside the “for” loop in k_busy_wait consumes more time (I am certain) and the loop does not break out correctly.

> Could you please explain the symptoms of the problem without any of your debugging (printk influences the k_busy_wait) ?

The 100 microseconds sample is just a way to show that k_cycle_get_32() is frozen. The only purpose is to test the NRF_RTC peripheral, not to wait any specified amount of time.
The first time it repeats 211 thousand times, with k_cycle_get_32() returning zero, and the second time it repeats only a dozen times, with k_cycle_get_32() returning increasing values.
That is evidence enough of what is happening, even though the waiting time may not be exactly 100 microseconds. Because waiting is not the intention, I don't think the debug influences the output that much.

However, I think that is a moot point now. I think your advice about the watchdog interrupts and events is correct.
I'm going to explore that further and report back to you guys.

Thanks so much for the help,

Thiago

2017-08-19 2:00 GMT-03:00 Chettimada, Vinayak Kariappa <vinayak.kariappa.chettimada@...>:

Hi Thiago,


2) We're building for the nrf52_pca10040. I think we are enabling it: CONFIG_CLOCK_CONTROL_NRF5_K32SRC_XTAL=y

I assume, you mean, you are using nRF52832 chip and your custom board; and using a Zephyr build using the BOARD=nrf52_pca10040.
Do you have the 32KHz crystal mounted in your custom PCB? If not, you will need to use the internal RC oscillator by enabling CONFIG_CLOCK_CONTROL_NRF5_K32SRC_RC=y.
 
3) TICKLESS_IDLE is enabled, but TICKLESS_KERNEL is disabled.
4) I'm sorry, I can't pinpoint it right now to you. I'm going to investigate further here and report back. We've started experiencing this problem at the start of this week, but we were at a two-week development hiatus before then.
The only thing we added as the watchdog. The watchdog code is as follows:

void wdt_init(uint32_t reload_ms) {
NRF_WDT->CONFIG = 0x01 | 0x08;
NRF_WDT->CRV = (reload_ms / 1000) * 32678;
        SYS_LOG_WRN("%d: %d or %u", reload_ms, NRF_WDT->CRV, NRF_WDT->CRV);
NRF_WDT->INTENSET = WDT_INTENSET_TIMEOUT_Msk;
NRF_WDT->TASKS_START = 1;
}

void wdt_reload(uint8_t channel) {
NRF_WDT->RR[channel] = NRF_WDT_RR_VALUE;
}

I attached our .config to the original gist, it is there at the end now: https://gist.github.com/durub/edda1fbf6a6c8f1c7f88960d26916ddf

I tried just now to reproduce the problem without any of our code (but using our .config), and the problem still persists. Our main is:
void main() {
k_busy_wait(100);
}


Currently there is no watchdog driver for nRF52 contributed yet to Zephyr. I am not an expert on this peripheral, but I do notice in your code, you enable interrupt from the watchdog peripheral, hope you have setup interrupt handler correctly, clear the events and kick the dog sufficiently, etc.
If your application needs watchdog, I would advise you implement a watchdog driver following the Zephyr driver model (include/watchdog.h and in drivers/watchdog folder). We will be glad to review your driver and a simple sample application. 

We've tested this main using nrf52_pca10040 and our PCB. Sample of the final of the faulty output:
0 0 3
0 0 3
(a lot of equal lines)
0 0 3
0 0 3
0 shell> 30 30 3
30 56 3

I must say that this problem is happening intermittently. Now, the simple main is always working (a lot of successive resets with nrfjprog --reset -f nrf52):
shell> 38 38 3
38 64 3
shell> 38 38 3
38 65 3
shell> 38 38 3
38 64 3
shell> 38 38 3
38 65 3
shell> 38 38 3
38 65 3
shell> 38 38 3
38 64 3
shell> 38 38 3
38 65 3
shell> 38 38 3
38 64 3
shell> 38 38 3
38 64 3

Please remember that nRF52 is a ultra low power chip and there is no functional ARM systick timer, the system timer is implemented using the NRF_RTC peripheral.
The resolution of each tick is in 32KHz units. If you print in busywait, you will see lot of lines with same values until each 32KHz (*if* UART tx time is very much less than 30.517 us, which I doubt).
Ok, you want to wait 100 microseconds and your printk inside the “for” loop in k_busy_wait consumes more time (I am certain) and the loop does not break out correctly.

Could you please explain the symptoms of the problem without any of your debugging (printk influences the k_busy_wait) ?

Regards,
Vinayak

Join users@lists.zephyrproject.org to automatically receive all group messages.