#include "exception.h"
#include "system.h"
#include "bsp_time.h"
#include "nrf_delay.h"
#include "hal_wearshoes.h"

//系统函数
void FPS_process(void)
{
	#if DEBUG_FPS
	static uint32_t tem1 = 0;
	static uint32_t tem2 = 0;
	static uint32_t fps_max=0;
	static uint32_t cnt_max=0;
	uint32_t fps;
	
	tem2 = NRF_RTC0->COUNTER;
	if(tem2<tem1) tem2 += 16777216;
	fps = (tem2-tem1)/32.768;
	if(fps_max<fps){
		fps_max = fps;
		cnt_max = tem2-tem1;
	}

	static uint32_t tim=0;
	if(TIME_GetTicks()-tim>=5000){ tim = TIME_GetTicks();
		SEGGER_RTT_printf(0,"fps=%dms,cnt=%d\n",fps_max,cnt_max);
		fps_max = 0;
	}
	tem1 = NRF_RTC0->COUNTER;
	#endif
}

//休眠时间 ms
uint32_t systermSleepTime = 1000;
static uint8_t sleep_num = 0;
static Sleep_cb sleep_cb[sleep_cb_max]={0};
int Sleep_Regist(Sleep_cb cb)
{
	for(int i=0;i<sleep_cb_max;i++) {
		if(sleep_cb[i]==cb) return -1;
		if(sleep_cb[i]==0){
			sleep_num++;
			sleep_cb[i] = cb;  //回调函数
			return 0;
		}
	}
	SEGGER_RTT_printf(0,"Sleep_Regist too many!\n");
	return -2;
}

void Sleep_Event(void)
{
	for(int i=0;i<sleep_num;i++) { //SEGGER_RTT_printf(0,"time_cb[%d]=%d\n",i,time_cb[i]);
		if(sleep_cb[i]){
			sleep_cb[i](systermSleepTime);  //回调函数
		}
	}
}

static uint8_t wakeup_num = 0;
static Sleep_cb wakeup_cb[wakeup_cb_max]={0};
int Wakeup_Regist(Sleep_cb cb)
{
	for(int i=0;i<wakeup_cb_max;i++) {
		if(wakeup_cb[i]==cb) return -1;
		if(wakeup_cb[i]==0){
			wakeup_num++;
			wakeup_cb[i] = cb;  //回调函数
			return 0;
		}
	}
//	SEGGER_RTT_printf(0,"Wakeup_Regist too many!\n");
	return -2;
}

void Wakeup_Event(void)
{
	for(int i=0;i<wakeup_num;i++) { //SEGGER_RTT_printf(0,"time_cb[%d]=%d\n",i,time_cb[i]);
		if(wakeup_cb[i]){
			wakeup_cb[i](systermSleepTime);  //回调函数
		}
	}
}

//app进程管理

static uint16_t process_dex = 0;
static PROCESS_t mProcess[process_max];

int Process_Start(uint16_t peroid,const char *name,PROCESS_cb cb)
{	
	for(uint8_t i=0;i<process_dex;i++){
		if(mProcess[i].cb==cb){	//已经存在
			mProcess[i].enable =1;
			mProcess[i].Peroid = peroid;
			mProcess[i].tim = TIME_GetTicks();
			return 1;
		}
	}
	
	if(process_dex>=process_max) return -1;
	mProcess[process_dex].cb = cb;
	mProcess[process_dex].enable =1;
	mProcess[process_dex].Peroid = peroid;
	mProcess[process_dex].tim = TIME_GetTicks();
	#if ProcessTime_EN
	mProcess[process_dex].name = name;
	#endif
	process_dex++;
//	SEGGER_RTT_printf(0,"process num(%d)\n",process_dex);
	return 0;
}

void Process_Stop(PROCESS_cb cb)
{
	for(uint8_t i=0;i<process_dex;i++){
		if(mProcess[i].cb==cb){	//找到
			mProcess[i].enable = 0;
			return;
		}
	}
}

void Process_SetHoldOn(PROCESS_cb cb,uint8_t holdon)
{
	for(uint8_t i=0;i<process_dex;i++){
		if(mProcess[i].cb==cb){	//找到
			if(mProcess[i].holdon!=holdon) mProcess[i].holdon = (holdon&0x01);
			return;
		}
	}
}

void Process_UpdatePeroid(PROCESS_cb cb,uint16_t Peroid)
{
	for(uint8_t i=0;i<process_dex;i++){
		if(mProcess[i].cb==cb){	//找到
			   mProcess[i].Peroid = Peroid;
			return;
		}
	}
}

uint16_t Process_GetPeroid(PROCESS_cb cb)
{
	for(uint8_t i=0;i<process_dex;i++){
		if(mProcess[i].cb==cb){	//找到
			   return mProcess[i].Peroid;
		}
	}
	return 0;
}

const char *Test =NULL;
int Process_App(void)
{
	int ret = 0;
	uint8_t i = 0;

	for(i=0;i<process_dex;i++){
		Except_Get_Cur_Porcess_ID(i);
		if(mProcess[i].enable==0) continue;
		if(mProcess[i].cb){
			#if ProcessTime_EN
			uint32_t useTime = NRF_RTC0->COUNTER;
			#endif
			if(mProcess[i].Peroid ==0) mProcess[i].cb();
			else if(TIME_GetTicks()-mProcess[i].tim >= mProcess[i].Peroid ){
				mProcess[i].tim = TIME_GetTicks();
				mProcess[i].cb();
			}
			#if ProcessTime_EN
			if(NRF_RTC0->COUNTER<useTime) useTime = (NRF_RTC0->COUNTER+16777216-useTime);
			else useTime = (NRF_RTC0->COUNTER-useTime);
			useTime = useTime*1000/32.768;
			if(mProcess[i].useTime<useTime)	mProcess[i].useTime = useTime;
			#endif
		}
		if(mProcess[i].holdon) ret = 1;	//不能进入低功耗
		
	}
	#if ProcessTime_EN
	static uint32_t tem1 = 0;
	static uint32_t tem2 = 0;
	static uint32_t fps_max=0;
	uint32_t fps;
	
	tem2 = NRF_RTC0->COUNTER;
	if(tem2<tem1) tem2 += 16777216;
	fps = (tem2-tem1)*1000/32.768;
	if(fps_max<fps){
		fps_max = fps;
	}
	
	static uint32_t tim =0;
	if(TIME_GetTicks()-tim>=DisInterval){ tim = TIME_GetTicks();
//		SEGGER_RTT_printf(0,"\n========== infomation ==========\n");
		SEGGER_RTT_printf(0,"\n============ Tatol(%d process) : %d us ==========\n",process_dex,fps_max);
		for(i=0;i<process_dex;i++){
			if(mProcess[i].useTime>500)
				SEGGER_RTT_printf(0,"[%d]%s : %d us\n",i,mProcess[i].name,mProcess[i].useTime);
			mProcess[i].useTime = 0;
		}
		SEGGER_RTT_printf(0,"\n",fps_max);
		fps_max = 0;
	}
	tem1 = NRF_RTC0->COUNTER;
	#endif
	return ret;
}

//大循环
void USR_Process(void)
{
	//app进程调度
	if(Process_App()==0){	//进入低功耗模式
		Sleep_Event();
		systermSleepTime = rtc_sleep(hal_wearshoes_is_wearshoes());
		if(systermSleepTime==0){ 
			systermSleepTime = 13;
			nrf_delay_ms(systermSleepTime);
		}
		Wakeup_Event();
	}
	
	FPS_process();
}



