We have an unusual issue.
We are using the nrf 17.1 SDK for a custom board with the nrf52840 in tickless idle mode (RTC1) - using the available port_cmsis_systick.c for nrf52.
In our main.c func we do something like this, where we init the clocks and power and then set the prescaler for RTC2 before starting tasks.
static void power_management_init(void)
{
ret_code_t err_code;
err_code = nrf_pwr_mgmt_init();
APP_ERROR_CHECK(err_code);
}
static void init_clocks(void)
{
// NOTE: this is more efficient than older nrfx_clock_lfclk_start (30 uA savings)
sys_lfclk_initialize();
const uint32_t max_timeout_ms = 5000;
uint32_t timeout_ms = max_timeout_ms;
/* NOTE: Waiting will reduce faults, there are some cases where nrf_drv_clock_lfclk_is_running is not
ready and may cause WDT reboots
*/
while (!nrf_drv_clock_lfclk_is_running() && timeout_ms--)
{
nrf_delay_ms(1);
}
// catch failure
if (!nrf_drv_clock_lfclk_is_running())
{
// log and just continue since WDT will reset if it causes a fault
NRF_LOG_ERROR("LFCLK failed to start within %d seconds", max_timeout_ms);
}
}
static void init_power(void)
{
nrfx_power_config_t config = {.dcdcen = true, .dcdcenhv = true};
ret_code_t ret = nrf_drv_power_init(&config);
APP_ERROR_CHECK(ret);
power_management_init();
}
static void init_logs(void)
{
ret_code_t ret;
ret = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(ret);
NRF_LOG_DEFAULT_BACKENDS_INIT();
}
#if defined(ENABLE_RTOS_OVERFLOW_CHECKS)
extern "C"
{
#warning FreeRTOS stack and malloc overflow checks enabled
//! @brief Hook function called if FreeRTOS detects a stack overflow.
//! @param[in] xTask The task handle for the task that overflowed.
//! @param[in] pcTaskName A pointer to the task that overflowed.
//!
//! @note This functionality should be displayed
//!
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
{
while (1)
;
}
void vApplicationMallocFailedHook(void)
{
while (1)
;
}
}
#endif
int main(void)
{
// initialization steps before starting the RTOS
init_logs();
init_clocks();
init_power();
/* For some unknown reason, setting up RTC2 (without using it) improves
the stability of the RTOS tickless idle (RTC1).
If we do not setup RTC2 then after a software reboot the current draw goes to 5mA (it should be less than 150 uA).
Also, FW often stalls after software reboot unless we do this.
*/
nrf_rtc_prescaler_set(NRF_RTC2, 0xfff);
// initalize the watchdog timer.
sys_watchdog_initialize();
sys_watchdog_refresh();
// our task
create_custom_task();
// start FreeRTOS scheduler
vTaskStartScheduler();
for (;;)
{
// in normal operation we won't get here.
// in development, this infinite loop will be visible.
}
}
If we do NOT setup RTC2 then after a software reboot the current draw increases from 150 uA to 5mA.
What could be the reason for this?