NRF52832 RTC2

Hi  Nordic:

        We are working on a project, using NRF52832, which has the functions of softdevice+bootloader+ble+dfu, the SDK we use is version 17.0.0,

        and RTC2 is used as a 1ms timer. We found that after running for a period of time, 20 devices A device appears in the RTC2 and cannot generate an interrupt.

       Then we deleted the firmware, using the example of the official RTC2 firmware, the interrupt is also unable to enter, we guessed that there is a problem with the internal crystal oscillator.     

        How do we solve this problem

static const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(2);

static uint8_t isSleep = 0;

volatile static uint32_t time_1ms = 0;
#define time_cb_max 32
static TIME_callback time_cb[time_cb_max]={0};


static void rtc_tick_handler(nrf_drv_rtc_int_type_t int_type)
{
	uint32_t err_code;
    if (int_type == NRF_DRV_RTC_INT_COMPARE0)
    {
//		SEGGER_RTT_printf(0,"1");
//		uint32_t tem1 = NRF_RTC0->COUNTER;
		nrf_drv_rtc_counter_clear(&rtc);
		err_code = nrf_drv_rtc_cc_set(&rtc,NRF_DRV_RTC_INT_COMPARE0,HeartTime_Interval*33,true); APP_ERROR_CHECK(err_code);
		if(isSleep==0){
			time_1ms+=HeartTime_Interval;
			for(int i=0;i<time_cb_max;i++) { //SEGGER_RTT_printf(0,"time_cb[%d]=%d\n",i,time_cb[i]);
				if(time_cb[i]){
					time_cb[i]((uint32_t*)(&time_1ms)); 
				}
			}
//			uint32_t tem2 = NRF_RTC0->COUNTER;
//			if(tem2<tem1) tem2 += 16777216;
//			if(tem2-tem1>0)	SEGGER_RTT_printf(0,"rtc_tick_handler(%d)\n",tem2-tem1);
		}
    }
    else if (int_type == NRF_DRV_RTC_INT_TICK)
    {
//        SEGGER_RTT_printf(0,"NRF_DRV_RTC_INT_TICK(0x%X)\n",NRF_RTC0->COUNTER);
    }
}


uint32_t TIME_GetTicks(void)
{
	return time_1ms;
}

int TIME_Regist(TIME_callback cb)
{
	for(int i=0;i<time_cb_max;i++) {
		if(time_cb[i]==cb) return -2;
		if(time_cb[i]==0){
			time_cb[i] = cb;  //回调函数
			return 0;
		}
	}
	return -1;
}

int TIME_UnRegist(TIME_callback cb)
{
	for(int i=0;i<time_cb_max;i++){
		if(time_cb[i] == cb){
			time_cb[i] = 0;
			return 0;
		}
	}
	return -1;
}

uint32_t rtc_sleep(uint8_t is_wearshoes)
{
	uint32_t tem1 = NRF_RTC0->COUNTER;
	uint32_t ret = 0;
	uint32_t err_code;
	isSleep = 1;

	if(is_wearshoes==0){ err_code = nrf_drv_rtc_cc_set(&rtc,0,StandByPower_Interval * 33,true); APP_ERROR_CHECK(err_code);}
	else { err_code = nrf_drv_rtc_cc_set(&rtc,0,LowPower_Interval * 33,true); APP_ERROR_CHECK(err_code);}
	nrf_drv_rtc_counter_clear(&rtc);
	while(nrf_drv_rtc_counter_get(&rtc) != 0);

	for(int i=0;i<5;i++){
		uint32_t cnt1 = NRF_RTC0->COUNTER;
		nrf_pwr_mgmt_run();
//		idle_state_handle();
		uint32_t cnt2 = NRF_RTC0->COUNTER;
		if(cnt2<cnt1) cnt2 += 16777216;
		if(cnt2-cnt1>32) break;
	}
	
	err_code = nrf_drv_rtc_cc_set(&rtc,0,HeartTime_Interval*33,true); APP_ERROR_CHECK(err_code);
	nrf_drv_rtc_counter_clear(&rtc);
	while(nrf_drv_rtc_counter_get(&rtc) != 0);
	isSleep = 0;
	uint32_t tem2 = NRF_RTC0->COUNTER;
	if(tem2<tem1) tem2 += 16777216;
	ret = (tem2-tem1)/32.768;
	return ret;
}

static void cb_timeeWakeup(uint32_t t)
{
	time_1ms += t;
	//SEGGER_RTT_printf(0,"cb_timeeWakeup(%d)\n",time_1ms);
}


void TIME_Init(void)
{
	uint32_t err_code;
	nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
	config.interrupt_priority = RTC2_IRQ_PRIORITY;												
	config.prescaler = 0;// f(RTC) = 32.768kHZ/(prescaler+1) = 8HZ = 125ms
	err_code = nrf_drv_rtc_init(&rtc, &config, rtc_tick_handler); APP_ERROR_CHECK(err_code);
	
	err_code = nrf_drv_rtc_cc_set(&rtc,NRF_DRV_RTC_INT_COMPARE0,HeartTime_Interval*33,true); APP_ERROR_CHECK(err_code);
	nrf_drv_rtc_counter_clear(&rtc);
	nrf_drv_rtc_enable(&rtc);

	Wakeup_Regist(cb_timeeWakeup);
}

Related