#include "sdk_common.h"
#include "app_timer.h"
#include "bsp_time.h"
#include "nrf_drv_timer.h"
#include "SEGGER_RTT.h"
#include "system.h"
#include "app_timer.h"
#include "nrf_drv_rtc.h"
#include "nrf_pwr_mgmt.h"
#include "exception.h"

/********************** 变量区 *************************/
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 10
static TIME_callback time_cb[time_cb_max]={0};

/********************** 函数声明区 *************************/

static void bsp_rtc_init_process(void)
{
	if(Except_TxError(EXCEPT_RTC_INIT,"bsp_rtc_init_error\r\n") == 0)
	{
		Process_Stop(bsp_rtc_init_process);
	}
}

static void bsp_rtc_config_process(void)
{
	if(Except_TxError(EXCEPT_RTC_INIT,"bsp_rtc_config_error\r\n") == 0)
	{
		Process_Stop(bsp_rtc_config_process);
	}
}

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)
    {
//		DEBUG_LOG("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);
		
		if(err_code != NRF_SUCCESS)
		{
			//再来一次还是不行，就上报错误。
			err_code = nrf_drv_rtc_cc_set(&rtc,NRF_DRV_RTC_INT_COMPARE0,HeartTime_Interval*33,true);
			if(err_code != NRF_SUCCESS)
			{
				Process_Start(0,"rtc_config",bsp_rtc_config_process);
			}
		}

		if(isSleep==0){
			time_1ms+=HeartTime_Interval;
			for(int i=0;i<time_cb_max;i++) { //DEBUG_LOG("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)	DEBUG_LOG("rtc_tick_handler(%d)\n",tem2-tem1);
		}
    }
    else if (int_type == NRF_DRV_RTC_INT_TICK)
    {
//        DEBUG_LOG("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(uint8_t 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)
{
	uint8_t b =0;
	for(uint8_t i=0;i<time_cb_max;i++){
		if(time_cb[i] == cb){
			for(b=i ; b < (time_cb_max-1);b++){
				 time_cb[b] = time_cb[b+1];
			}
			return 0;
		}
	}
	return -1;
}

//int CheckPending_IRQ(int *result,int result_size)
//{
//        int index = 0,i = 0;
//        
//        /* Check which interrupt is pending. Will not work properly if there are more than one pending */
//        for (i = POWER_CLOCK_IRQn; i <= FPU_IRQn; i++)
//        {
//                        if (NVIC_GetPendingIRQ(i))
//                        {
//                                        if(index < result_size)result[index++] = i;
//                        }
//        }

//        return index;
//}

//static void idle_state_handle(void)
//{
//    ret_code_t         err_code;
//                int                                        pending_number_before = 0,pending_number_after = 0;
//                int                                 result[2][60],i;
//                uint32_t                 region_start,region_end,p_evt_id_before = 0xff,p_evt_id_after = 0xff,ispr0_before = 0,ispr0_after = 0,ispr1_before = 0,ispr1_after = 0;

////    err_code = nrf_ble_lesc_request_handler();
////    APP_ERROR_CHECK(err_code);
//                

//                CRITICAL_REGION_ENTER();
//        
//        
//                region_start = NRF_RTC2->COUNTER;
//                pending_number_before = CheckPending_IRQ(&result[0][0],60);
//                sd_evt_get(&p_evt_id_before);
//                ispr0_before = NVIC->ISPR[0];
//                ispr1_before = NVIC->ISPR[1];
//                
//                nrf_pwr_mgmt_run();
//                
//                ispr0_after = NVIC->ISPR[0];
//                ispr1_after = NVIC->ISPR[1];
//                sd_evt_get(&p_evt_id_after);
//                pending_number_after = CheckPending_IRQ(&result[1][0],60);
//                region_end = NRF_RTC2->COUNTER;
//        
//        
//                CRITICAL_REGION_EXIT();
//        
//                DEBUG_LOG("*******wakeup result start*******\n");
//                
//                if (pending_number_before)
//                { 
//                                for(i=0;i<pending_number_before;i++)DEBUG_LOG("pending_total_before[%d]:%d\n",i,result[0][i]);
//                                memset(&result[0][0],0,60);
//                }
//                
//                if(p_evt_id_before != 0xff)DEBUG_LOG("p_evt_id_before:%d\n",p_evt_id_before);
//                
//                if (pending_number_after)
//                { 
//                                for(i=0;i<pending_number_after;i++)DEBUG_LOG("pending_total_after[%d]:%d\n",i,result[1][i]);
//                                memset(&result[1][0],0,60);
//                }
//                
//                if(p_evt_id_after != 0xff)DEBUG_LOG("p_evt_id_after:%d\n",p_evt_id_after);
//                
//                DEBUG_LOG("before---NVIC->ISPR[0]:0x%X, NVIC->ISPR[1]:0x%X\n",ispr0_before,ispr1_before);
//                DEBUG_LOG("after----NVIC->ISPR[0]:0x%X, NVIC->ISPR[1]:0x%X\n",ispr0_after,ispr1_after);
//                
//                DEBUG_LOG("*******wakeup result end*******\n");
//                
//                DEBUG_LOG("region times: %d\n",region_end-region_start);

//}

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);
		if(err_code != NRF_SUCCESS)
		{
			//再来一次还是不行，就上报错误。
			err_code = nrf_drv_rtc_cc_set(&rtc,0,StandByPower_Interval * 33,true);
			if(err_code != NRF_SUCCESS)
			{
				Process_Start(0,"rtc_config",bsp_rtc_config_process);
			}
		}
	}
	else 
	{ 
		err_code = nrf_drv_rtc_cc_set(&rtc,0,LowPower_Interval * 33,true);
		if(err_code != NRF_SUCCESS)
		{
			//再来一次还是不行，就上报错误。
			err_code = nrf_drv_rtc_cc_set(&rtc,0,LowPower_Interval * 33,true);
			if(err_code != NRF_SUCCESS)
			{
				Process_Start(0,"rtc_config",bsp_rtc_config_process);
			}
		}
	}
	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); 
	if(err_code != NRF_SUCCESS)
	{
		//再来一次还是不行，就上报错误。
		err_code = nrf_drv_rtc_cc_set(&rtc,0,HeartTime_Interval*33,true); 
		if(err_code != NRF_SUCCESS)
		{
			Process_Start(0,"rtc_config",bsp_rtc_config_process);
		}
	}
	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;
	//DEBUG_LOG("cb_timeeWakeup(%d)\n",time_1ms);
}


//=== 系统滴答时间初始化 ===//
void TIME_Init(void)
{
	int 				ret = 0;
	ret_code_t 	errCode;
	
	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
	errCode = nrf_drv_rtc_init(&rtc, &config, rtc_tick_handler); 
	if(errCode != NRF_SUCCESS)ret = -1;
	
	errCode = nrf_drv_rtc_cc_set(&rtc,NRF_DRV_RTC_INT_COMPARE0,HeartTime_Interval*33,true);
	if(errCode != NRF_SUCCESS)
	{
		//再来一次还是不行，就上报错误。
		errCode = nrf_drv_rtc_cc_set(&rtc,NRF_DRV_RTC_INT_COMPARE0,HeartTime_Interval*33,true);
		if(errCode != NRF_SUCCESS)
		{
			Process_Start(0,"rtc_config",bsp_rtc_config_process);
		}
	}
	nrf_drv_rtc_counter_clear(&rtc);
	nrf_drv_rtc_enable(&rtc);

	Wakeup_Regist(cb_timeeWakeup);
	
	if(ret == -1)
	{
		Process_Start(0,"rtc_init",bsp_rtc_init_process);
	}
}

