/****************************************************************************************************
* created by sunpeng 2017 all rights reserved!
****************************************************************************************************/
#include "stdint.h"
#include "include.h"
#include "Timer.h"
#include "wireless.h"
#include "uart_api.h"
#include "rotation.h"
#include "power.h"

#if ARCH_MODE == NRF52832_Slave_Mode
//#include "led.h"
#include "beep.h"
#include "button.h"

#if MOTION_SENSOR_TYPE == MOTION_SENSOR_TYPE_9X_ACCEL_GYRO_MAG
#include "app_mpu9250.h"
#endif
//#include "app_74hc595.h"
//#include "74hc595.h"


#elif ARCH_MODE == NRF51822_Peripheral_Mode 
#include "ADC.h"
#elif ARCH_MODE == NRF51802_Peripheral_Mode
#include "beep.h"
#include "ADC.h"
#include "app_util_platform.h"
#include "rRecordGam.h"

#endif


#include "app_timer.h"
#include "ble_advdata.h"
#include "nrf_drv_timer.h"
#include "InnerFlash.h"

/***********************************************************************************************/
static void BellDelayTask(void);
static void PubLic10msTask(void);
static void Public50msTask(void);
static void PubLic100msTask(void);
static void PubLic1000msTask(void);
static void PubLic4000msTask(void);

/***********************************************************************************************/

#if ARCH_MODE == NRF51802_Peripheral_Mode
TIMER_FOR_TIMEOUT_STRUCT rRecordGam_timeout_timer = {.startFlag = false};
#endif
static CB_TIMERS_STRUCT cb_timers;		//所有回调定时器管理

/***********************************************************************************************

***********************************************************************************************/
#define APP_TIMER_OP_QUEUE_SIZE         10                  /**< Size of timer operation queues. */
#if ARCH_MODE == NRF52832_Slave_Mode
#if MOTION_SENSOR_TYPE == MOTION_SENSOR_TYPE_9X_ACCEL_GYRO_MAG
#define MPU9250_READ_INTERVAL           APP_TIMER_TICKS(10) 
#endif
#define LEDS74HC595_READ_INTERVAL       APP_TIMER_TICKS(100) 
#endif

#define PERIOD10MS_READ_INTERVAL        APP_TIMER_TICKS(10) 
#define PERIOD50MS_READ_INTERVAL    	APP_TIMER_TICKS(50) 

#if ARCH_MODE == NRF51802_Peripheral_Mode
#define PERIOD100MS_READ_INTERVAL       APP_TIMER_TICKS(200, APP_TIMER_PRESCALER) 
#define PERIOD1000MS_READ_INTERVAL      APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER)
#else
#define PERIOD100MS_READ_INTERVAL       APP_TIMER_TICKS(100) 
#define PERIOD1000MS_READ_INTERVAL      APP_TIMER_TICKS(1000)
#endif

#if ARCH_MODE == NRF52832_Slave_Mode
#define PERIOD4000MS_READ_INTERVAL      APP_TIMER_TICKS(4000) 
#endif

#if ARCH_MODE == NRF51802_Peripheral_Mode
#define ADC_TIMER_READ_INTERVAL         APP_TIMER_TICKS(5, APP_TIMER_PRESCALER) 
#endif



#if ARCH_MODE == NRF52832_Slave_Mode
#if MOTION_SENSOR_TYPE == MOTION_SENSOR_TYPE_9X_ACCEL_GYRO_MAG
APP_TIMER_DEF(m_mpu9250_timer_id);      		/**< mpu9250数据读取定时器 	*/
#endif
APP_TIMER_DEF(m_74hc595_timer_id);      		/**< 74hc595控制输出定时器 	*/

#endif

APP_TIMER_DEF(m_period10ms_timer_id);      		/**< 公共1ms定时器 			*/
APP_TIMER_DEF(m_period50ms_timer_id);      		/**< 公共50ms定时器 			*/
APP_TIMER_DEF(m_period100ms_timer_id);      	/**< 公共100ms定时器 		*/
APP_TIMER_DEF(m_period1000ms_timer_id);      	/**< 公共1000ms定时器 		*/
#if ARCH_MODE == NRF52832_Slave_Mode
APP_TIMER_DEF(m_period4000ms_timer_id);      	/**< 公共4000ms定时器 		*/
#endif
#if ARCH_MODE == NRF51802_Peripheral_Mode
APP_TIMER_DEF(m_adc_timer_id);      			/**< ADC采样定时器 			*/
#endif

/***********************************************************************************************/
//定义Timer0的驱动程序实例。驱动程序实例的ID对应Timer的ID，如NRF_DRV_TIMER_INSTANCE(0)对应Timer0
const nrf_drv_timer_t TIMER_BEEP = NRF_DRV_TIMER_INSTANCE(2);
const nrf_drv_timer_t TIMER_PUBLIC = NRF_DRV_TIMER_INSTANCE(3);
/***********************************************************************************************/
typedef void (*cb_timer_func)(u16 id, u16 times_count);	/*回调定时器回调函数类型 id: 定时器id  times_count: 当前回调次数计数*/
//初始化所有回调定时器
void init_callback_timers(void)
{
	u16 i = 0;
	
	cb_timers.count = 0;
	for(i = 0; i < CB_TIMER_MAX; i++)
	{
		cb_timers.cb_s[i].flag = false;
		cb_timers.cb_s[i].timer_id = 0;
		cb_timers.cb_s[i].type = CB_TIMER_TYPE_Once;
		cb_timers.cb_s[i].timeout = 0;
		cb_timers.cb_s[i].timeout_count = 0;
		cb_timers.cb_s[i].times = 1;
		cb_timers.cb_s[i].times_count = 0;
		cb_timers.cb_s[i].flag = NULL;
	}
}

//触发单个定时回调任务
//  timeout		:	回调时间 (timeout * 1s )
//  timer_id	:   回调定时器id， 如果timer_id=CB_TIMER_ID_Misc,则自动分配timer_id
//	type		:	回调类型（单次回调、多次回调、长期回调）
//	times		:	回调次数，type=CB_TIMER_TYPE_Many时有效
//  cb_func		:	回调函数, 带参数 id: 定时器id  times_count: 当前回调次数计数
//  rtn		    :   true=创建成功  false=创建失败
s8 start_callback_timer(u16 timeout, 
						u16 timer_id,
						CB_TIMER_TYPE_ENUM type, 
						u16 times,
						void (*cb_func)(u16 id, u16 times_count)
						)
{
	u16 i = 0;
	s8 isTimerCreatedFlag = false;
	
	//回调时间为0，返回
	if(0 == timeout)
	{
		return false;
	}
	
	if(NULL == cb_func)
	{
		return false;
	}
	
	if((type <= CB_TIMER_TYPE_MIN) || (type >= CB_TIMER_TYPE_MAX))
	{
		return false;
	}
	
	if(timer_id >= CB_TIMER_MAX)
	{
		return false;
	}
	
	//定时任务达到上限，返回
	if(cb_timers.count >= CB_TIMER_MAX)
	{
		return false;
	}
	
	if(CB_TIMER_ID_Misc == timer_id)		//自动分配timer_id
	{
		for(i = CB_TIMER_ID_Specific; i < CB_TIMER_MAX; i++)
		{
			if(false == cb_timers.cb_s[i].flag)
			{
				cb_timers.cb_s[i].flag = true;
				cb_timers.cb_s[i].timer_id = timer_id;
				cb_timers.cb_s[i].type = type;
				cb_timers.cb_s[i].timeout = timeout;
				cb_timers.cb_s[i].timeout_count = 0;
				cb_timers.cb_s[i].times = times;
				cb_timers.cb_s[i].times_count = 0;
				cb_timers.cb_s[i].cb_func = cb_func;
				
				isTimerCreatedFlag = true;
				break;
			}
		}
	
	}
	else 		//指定timer_id
	{
		if(true == cb_timers.cb_s[timer_id].flag)	//指定timer_id下存在回调任务
		{
			//将timer_id位置上的回调任务移动到空闲位置
			for(i = CB_TIMER_ID_Specific+1; i < CB_TIMER_MAX; i++)
			{
				if(false == cb_timers.cb_s[i].flag)
				{
					cb_timers.cb_s[i].flag 				= cb_timers.cb_s[timer_id].flag 		 ;
					cb_timers.cb_s[i].timer_id 			= cb_timers.cb_s[timer_id].timer_id 	 ;
					cb_timers.cb_s[i].type 				= cb_timers.cb_s[timer_id].type 		 ;
					cb_timers.cb_s[i].timeout 			= cb_timers.cb_s[timer_id].timeout 	 	 ;
					cb_timers.cb_s[i].timeout_count 	= cb_timers.cb_s[timer_id].timeout_count ; 
					cb_timers.cb_s[i].times 			= cb_timers.cb_s[timer_id].times 		 ;
					cb_timers.cb_s[i].times_count 		= cb_timers.cb_s[timer_id].times_count   ;
					cb_timers.cb_s[i].cb_func 			= cb_timers.cb_s[timer_id].cb_func 	     ;
					cb_timers.cb_s[timer_id].flag = false;
					break;
				}
			}
			
			//移动不成功，返回
			if(true == cb_timers.cb_s[timer_id].flag)
			{
				return false;
			}
			
		}
		
		//设置指定位置回调定时器参数
		cb_timers.cb_s[timer_id].flag = true;
		cb_timers.cb_s[timer_id].timer_id = timer_id;
		cb_timers.cb_s[timer_id].type = type;
		cb_timers.cb_s[timer_id].timeout = timeout;
		cb_timers.cb_s[timer_id].timeout_count = 0;
		cb_timers.cb_s[timer_id].times = times;
		cb_timers.cb_s[timer_id].times_count = 0;
		cb_timers.cb_s[timer_id].cb_func = cb_func;
		
		isTimerCreatedFlag = true;
	}
	
	if(false == isTimerCreatedFlag)
	{
		return false;
	}
	
	cb_timers.count++;
	
	return true;
}

//获取指定ID的已经经过的时间
//timer_id	:定时器ID
//timeout_count	：已经计时过的时间
s8 get_callback_timer_time_passed(u16 timer_id, u16 *timeout_cout)
{
	//指定ID定时器与非指定ID分界线以下的ID不能手动触发停止
	if(timer_id >= CB_TIMER_ID_MAX)
	{
		return false;
	}
	
	*timeout_cout = cb_timers.cb_s[timer_id].timeout_count;
	return true;
}

//手动触发指定回调定时器超时（触发后延迟一秒内执行超时回调）
// timer_id : 定时器id
// rtn 		: true=停止成功  false=停止失败
s8 trig_callback_timer(u16 timer_id)
{
	if(timer_id >= CB_TIMER_ID_Specific)
	{
		return false;
	}
	
	cb_timers.cb_s[timer_id].timeout_count = cb_timers.cb_s[timer_id].timeout - 1;	//计时时间设置到超时时间
	cb_timers.cb_s[timer_id].times_count = cb_timers.cb_s[timer_id].times - 1;		//触发次数清空到最后一次
		
	return true;
}

//停止指定回调定时器（停止后不执行超时回调）
// timer_id : 定时器id
// rtn 		: true=停止成功  false=停止失败
s8 stop_callback_timer(u16 timer_id)
{
	if(timer_id >= CB_TIMER_MAX)
	{
		return false;
	}
	
	//定时器数量统计减少
	if((true == cb_timers.cb_s[timer_id].flag) && (cb_timers.count > 0))
	{
		cb_timers.count--;
	}
	
	cb_timers.cb_s[timer_id].flag = false;
	
	return true;
}

//定时管理回调定时器（每1s循环一次）
void cycle_manage_callback_timers(void)
{
	if(0 == cb_timers.count)
	{
		return;
	}
	
	u16 i = 0;
	u16 count_all = cb_timers.count;
	while(count_all > 0)
	{
		
		if(false == cb_timers.cb_s[i].flag)
		{
			i++;
			if(i >= CB_TIMER_MAX)
			{
				break;
			}
			continue;
		}
		
		//定时到达
		if(cb_timers.cb_s[i].timeout_count >= cb_timers.cb_s[i].timeout)
		{
			void (*cb_func)(u16 id, u16 times_count);
			cb_func = cb_timers.cb_s[i].cb_func;
			cb_func(cb_timers.cb_s[i].timer_id, cb_timers.cb_s[i].times_count);
			switch(cb_timers.cb_s[i].type)
			{
				case CB_TIMER_TYPE_Once:
					//停止计时器
					stop_callback_timer(i);
					break;
				case CB_TIMER_TYPE_Many:
					cb_timers.cb_s[i].times_count++;
					//只有在所有回调次数完成后释放资源
					if(cb_timers.cb_s[i].times_count >= cb_timers.cb_s[i].times)
					{
						//停止计时器
						stop_callback_timer(i);
					}
					else
					{
						cb_timers.cb_s[i].timeout_count = 0;	//清空超时计数，开始下一次回调
					}
					break;
				case CB_TIMER_TYPE_Forever:
					cb_timers.cb_s[i].timeout_count = 0;	//清空超时计数，开始下一次回调
					break;
				default:
					break;
			}
			continue;
		}
		
		cb_timers.cb_s[i].timeout_count++;
		
		i++;
		count_all--;
	}
}

//测试定时回调执行函数
void test_callback_func(u16 timer_id, u16 times_count)
{
	s8 send_str[16] = "";
	
	sprintf((char *)send_str, "Hi %d %d", timer_id, times_count);
	
	//测试回调，向app发送hello
	RfSend(12, (char *)send_str, strlen((char *)send_str));
}

//测试定时回调触发测试
void test_callback_timer(void)
{	
	start_callback_timer(5000, CB_TIMER_ID_Test, CB_TIMER_TYPE_Many, 3, test_callback_func);
}

/***********************************************************************************************/
//Timer事件回调函数
void timer2_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    switch (event_type)
    {
	case NRF_TIMER_EVENT_COMPARE2:
		BellDelayTask();
		break;
	default:
		break;
    }
}
#if ARCH_MODE != NRF51802_Peripheral_Mode
//Public Timer事件回调函数
void timer_public_event_handler(nrf_timer_event_t event_type, void* p_context)
{
    switch (event_type)
    {
	case NRF_TIMER_EVENT_COMPARE3:
#if ARCH_MODE != NRF51802_Peripheral_Mode
		PubLic10msTask();
#endif
		break;	
	default:
		break;
    }
}

#endif

/**********************************************************************************************
 * 描  述 : init_beep_timer函数
 * 参  数 : 无
 * 返回值 : 无
 ***********************************************************************************************/ 
uint32_t init_beep_timer(void)
{
    uint32_t err_code = NRF_SUCCESS;

#if ARCH_MODE == NRF51802_Peripheral_Mode
#else
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
	
	//初始化定时器，初始化时会注册timer_led_event_handler事件回调函数
	err_code = nrf_drv_timer_init(&TIMER_BEEP, &timer_cfg, timer2_event_handler);
	APP_ERROR_CHECK(err_code);

    //设置定时器捕获/比较通道及该通道的比较值，使能通道的比较中断
#if HW_VOICE_TYPE == HW_VOICE_TYPE_SPEAKER
    set_beep_timer_period(500);		//控制单线JQ8400音乐播放模块, 250us定时
#else
    set_beep_timer_period(100);
#endif
#endif	
	return err_code;
}

void uninit_beep_timer(void)
{
#if ARCH_MODE == NRF51802_Peripheral_Mode
#else
	nrf_drv_timer_uninit(&TIMER_BEEP);
#endif
}

/**********************************************************************************************
 * 描  述 : enable_beep_timer函数
 * 参  数 : 无
 * 返回值 : 无
 ***********************************************************************************************/ 
void enable_beep_timer(void)
{
#if ARCH_MODE == NRF51802_Peripheral_Mode
#else
    //启动定时器
    nrf_drv_timer_enable(&TIMER_BEEP);
#endif
}

/**********************************************************************************************
 * 描  述 : disable_beep_timer函数
 * 参  数 : 无
 * 返回值 : 无
 ***********************************************************************************************/ 
void disable_beep_timer(void)
{
#if ARCH_MODE == NRF51802_Peripheral_Mode
	
#else
    //禁用定时器
    nrf_drv_timer_disable(&TIMER_BEEP);
#endif
}

/**********************************************************************************************
 * 描  述 : set_beep_timer_period函数
 * 参  数 : uint32_t period 蜂鸣器周期 单位：us
 * 返回值 : 无
 ***********************************************************************************************/ 
void set_beep_timer_period(uint32_t period)
{
#if ARCH_MODE == NRF51802_Peripheral_Mode
#else
	disable_beep_timer();
    //设置定时器捕获/比较通道及该通道的比较值，使能通道的比较中断
    nrf_drv_timer_extended_compare(
         &TIMER_BEEP, NRF_TIMER_CC_CHANNEL2, nrf_drv_timer_us_to_ticks(&TIMER_BEEP, period/2), NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, true);
    enable_beep_timer();
#endif
}

/**********************************************************************************************
 * 描  述 : init_public_timer函数
 * 参  数 : 无
 * 返回值 : 无
 ***********************************************************************************************/ 
uint32_t init_public_timer(void)
{
    uint32_t err_code = NRF_SUCCESS;
	
#if ARCH_MODE != NRF51802_Peripheral_Mode
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
	
	err_code = nrf_drv_timer_init(&TIMER_PUBLIC, &timer_cfg, timer_public_event_handler);
	APP_ERROR_CHECK(err_code);
	
    //设置定时器捕获/比较通道及该通道的比较值，使能通道的比较中断
    nrf_drv_timer_extended_compare(
         &TIMER_PUBLIC, NRF_TIMER_CC_CHANNEL3, nrf_drv_timer_ms_to_ticks(&TIMER_PUBLIC, 10), NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK, true);
#endif
	
	return err_code;
}

void uninit_public_timer(void)
{
#if ARCH_MODE != NRF51802_Peripheral_Mode
	nrf_drv_timer_uninit(&TIMER_PUBLIC);
#endif
}

/**********************************************************************************************
 * 描  述 : enable_public_timer函数
 * 参  数 : 无
 * 返回值 : 无
 ***********************************************************************************************/ 
void enable_public_timer(void)
{
#if ARCH_MODE != NRF51802_Peripheral_Mode
    //启动定时器
    nrf_drv_timer_enable(&TIMER_PUBLIC);
#endif
}

/**********************************************************************************************
 * 描  述 : disable_public_timer函数
 * 参  数 : 无
 * 返回值 : 无
 ***********************************************************************************************/ 
void disable_public_timer(void)
{
#if ARCH_MODE != NRF51802_Peripheral_Mode
    //禁用定时器
    nrf_drv_timer_disable(&TIMER_PUBLIC);
#endif
}

/**@brief Function for timerout handler.
 *
 * @details Handle specific task when timeout reach 1ms.
 */
static void period10ms_timeout_handler(void * p_context)
{
	uint32_t err_code = NRF_SUCCESS;
  
	UNUSED_PARAMETER(p_context);
	
	//1ms user program
	PubLic10msTask();

	if ((err_code != NRF_SUCCESS) &&
		(err_code != NRF_ERROR_INVALID_STATE) &&
		(err_code != BLE_ERROR_INVALID_CONN_HANDLE)&&
		(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)		
		)
	{
		APP_ERROR_HANDLER(err_code);
	}
}

/**@brief Function for timerout handler.
 *
 * @details Handle specific task when timeout reach period50ms.
 */
static void period50ms_timeout_handler(void * p_context)
{
	uint32_t err_code = NRF_SUCCESS;
  
	UNUSED_PARAMETER(p_context);
	
	//50ms user program
	Public50msTask();
	
	if ((err_code != NRF_SUCCESS) &&
		(err_code != NRF_ERROR_INVALID_STATE) &&
		(err_code != BLE_ERROR_INVALID_CONN_HANDLE)&&
		(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)		
		)
	{
		APP_ERROR_HANDLER(err_code);
	}
}

/**@brief Function for timerout handler.
 *
 * @details Handle specific task when timeout reach 100ms.
 */
static void period100ms_timeout_handler(void * p_context)
{
	uint32_t err_code = NRF_SUCCESS;
  
	UNUSED_PARAMETER(p_context);
	
	//100ms user program
	PubLic100msTask();
	
	if ((err_code != NRF_SUCCESS) &&
		(err_code != NRF_ERROR_INVALID_STATE) &&
		(err_code != BLE_ERROR_INVALID_CONN_HANDLE)&&
		(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)		
		)
	{
		APP_ERROR_HANDLER(err_code);
	}
}

/**@brief Function for timerout handler.
 *
 * @details Handle specific task when timeout reach 100ms.
 */
static void period1000ms_timeout_handler(void * p_context)
{
	uint32_t err_code = NRF_SUCCESS;
  
	UNUSED_PARAMETER(p_context);
	
	//1000ms user program
	PubLic1000msTask();
		
	if ((err_code != NRF_SUCCESS) &&
		(err_code != NRF_ERROR_INVALID_STATE) &&
		(err_code != BLE_ERROR_INVALID_CONN_HANDLE)&&
		(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)		
		)
	{
		APP_ERROR_HANDLER(err_code);
	}
}

/**@brief Function for timerout handler.
 *
 * @details Handle specific task when timeout reach 100ms.
 */
static void period4000ms_timeout_handler(void * p_context)
{
	uint32_t err_code = NRF_SUCCESS;
  
	UNUSED_PARAMETER(p_context);
	
	//4000ms user program
	PubLic4000msTask();
	
	if ((err_code != NRF_SUCCESS) &&
		(err_code != NRF_ERROR_INVALID_STATE) &&
		(err_code != BLE_ERROR_INVALID_CONN_HANDLE)&&
		(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)		
		)
	{
		APP_ERROR_HANDLER(err_code);
	}
}
#if ARCH_MODE == NRF51802_Peripheral_Mode

/**@brief Function for timerout handler.
 *
 * @details Handle specific task when timeout reach 100ms.
 */
static void adc_timeout_handler(void * p_context)
{
	uint32_t err_code = NRF_SUCCESS;
  
	UNUSED_PARAMETER(p_context);
	
	//---------------手动触发电源电压测量-----------------
	trig_adc_sample_for_power_measure();	
		
	if ((err_code != NRF_SUCCESS) &&
		(err_code != NRF_ERROR_INVALID_STATE) &&
		(err_code != BLE_ERROR_INVALID_CONN_HANDLE)&&
		(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)		
		)
	{
		APP_ERROR_HANDLER(err_code);
	}
}
#endif

/**@brief Function for the Timer initialization.
 *
 * @details Initializes the timer module.
 */
void timers_init(void)
{
    uint32_t err_code;
	// 初始化定时器模块
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

#if MOTION_SENSOR_TYPE == MOTION_SENSOR_TYPE_9X_ACCEL_GYRO_MAG
	// 创建一个周期执行的定时器，用于读取MPU9250数据
	err_code = app_timer_create(&m_mpu9250_timer_id,
							APP_TIMER_MODE_REPEATED,
							mpu9250_timeout_handler);
	APP_ERROR_CHECK(err_code);	
#endif	
	// 创建一个周期执行的定时器，用于定时刷新74hc595 控制的LED灯阵列
	err_code = app_timer_create(&m_74hc595_timer_id,
							APP_TIMER_MODE_REPEATED,
							period10ms_timeout_handler);
	APP_ERROR_CHECK(err_code);	
	
	// 创建一个周期执行的定时器，用于循环1ms定时
	err_code = app_timer_create(&m_period10ms_timer_id,
							APP_TIMER_MODE_REPEATED,
							period10ms_timeout_handler);
	APP_ERROR_CHECK(err_code);	
	
	// 创建一个周期执行的定时器，用于循环50ms定时
	err_code = app_timer_create(&m_period50ms_timer_id,
							APP_TIMER_MODE_REPEATED,
							period50ms_timeout_handler);
	APP_ERROR_CHECK(err_code);	
	
	// 创建一个周期执行的定时器，用于循环100ms定时
	err_code = app_timer_create(&m_period100ms_timer_id,
							APP_TIMER_MODE_REPEATED,
							period100ms_timeout_handler);
	APP_ERROR_CHECK(err_code);	
	
							
	// 创建一个周期执行的定时器，用于循环1000ms定时
	err_code = app_timer_create(&m_period1000ms_timer_id,
							APP_TIMER_MODE_REPEATED,
							period1000ms_timeout_handler);
	APP_ERROR_CHECK(err_code);	
							
#if ARCH_MODE == NRF52832_Slave_Mode
	// 创建一个周期执行的定时器，用于循环4000ms定时
	err_code = app_timer_create(&m_period4000ms_timer_id,
							APP_TIMER_MODE_REPEATED,
							period4000ms_timeout_handler);
	APP_ERROR_CHECK(err_code);	
#elif ARCH_MODE == NRF51802_Peripheral_Mode
	// 创建一个周期执行的定时器，用于ADC采样定时
	err_code = app_timer_create(&m_adc_timer_id,
							APP_TIMER_MODE_REPEATED,
							adc_timeout_handler);
	APP_ERROR_CHECK(err_code);	
#endif
}

void application_timers_start(void)
{
    uint32_t err_code;
	
#if ARCH_MODE == NRF52832_Slave_Mode
#if MOTION_SENSOR_TYPE == MOTION_SENSOR_TYPE_9X_ACCEL_GYRO_MAG
    // Start application timers.
    err_code = app_timer_start(m_mpu9250_timer_id, MPU9250_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif	
    // Start application timers.
    err_code = app_timer_start(m_74hc595_timer_id, LEDS74HC595_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif	
    // Start application timers.
    
	err_code = app_timer_start(m_period10ms_timer_id, PERIOD10MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
	
    // Start application timers.
    err_code = app_timer_start(m_period50ms_timer_id, PERIOD50MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
	
    // Start application timers.
    err_code = app_timer_start(m_period100ms_timer_id, PERIOD100MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
	
    // Start application timers.
    err_code = app_timer_start(m_period1000ms_timer_id, PERIOD1000MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);

#if ARCH_MODE == NRF52832_Slave_Mode
    // Start application timers.
    err_code = app_timer_start(m_period4000ms_timer_id, PERIOD4000MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#elif ARCH_MODE == NRF51802_Peripheral_Mode
    // Start application timers.
    err_code = app_timer_start(m_adc_timer_id, ADC_TIMER_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif
}

void application_timers_resume_from_power_saving(void)
{
    uint32_t err_code;
	
#if ARCH_MODE == NRF52832_Slave_Mode
#if MOTION_SENSOR_TYPE == MOTION_SENSOR_TYPE_9X_ACCEL_GYRO_MAG
    // Start application timers.
    err_code = app_timer_start(m_mpu9250_timer_id, MPU9250_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif	
    // Start application timers.
    err_code = app_timer_start(m_74hc595_timer_id, LEDS74HC595_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif	
    // Start application timers.
    
	err_code = app_timer_start(m_period10ms_timer_id, PERIOD10MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
	
    // Start application timers.
    //err_code = app_timer_start(m_period50ms_timer_id, PERIOD50MS_READ_INTERVAL, NULL);
    //APP_ERROR_CHECK(err_code);
	
    // Start application timers.
    //err_code = app_timer_start(m_period100ms_timer_id, PERIOD100MS_READ_INTERVAL, NULL);
    //APP_ERROR_CHECK(err_code);
	
    // Start application timers.
    err_code = app_timer_start(m_period1000ms_timer_id, PERIOD1000MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);

#if ARCH_MODE == NRF52832_Slave_Mode
    // Start application timers.
    err_code = app_timer_start(m_period4000ms_timer_id, PERIOD4000MS_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#elif ARCH_MODE == NRF51802_Peripheral_Mode
    // Start application timers.
    err_code = app_timer_start(m_adc_timer_id, ADC_TIMER_READ_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif
}

void application_timers_stop_for_power_saving(void)
{
    uint32_t err_code;
	
#if ARCH_MODE == NRF52832_Slave_Mode
#if MOTION_SENSOR_TYPE == MOTION_SENSOR_TYPE_9X_ACCEL_GYRO_MAG
    // Stop application timers.
    err_code = app_timer_stop(m_mpu9250_timer_id);
    APP_ERROR_CHECK(err_code);
#endif	
    // Stop application timers.
    err_code = app_timer_stop(m_74hc595_timer_id);
    APP_ERROR_CHECK(err_code);
#endif	
    // Stop application timers.
    
	err_code = app_timer_stop(m_period10ms_timer_id);
    APP_ERROR_CHECK(err_code);
	
    // Stop application timers.
    //err_code = app_timer_stop(m_period50ms_timer_id);
    //APP_ERROR_CHECK(err_code);
	
    // Stop application timers.
    //err_code = app_timer_stop(m_period100ms_timer_id);
    //APP_ERROR_CHECK(err_code);
	
    // Stop application timers.
    err_code = app_timer_stop(m_period1000ms_timer_id);
    APP_ERROR_CHECK(err_code);

#if ARCH_MODE == NRF52832_Slave_Mode
    // Stop application timers.
    err_code = app_timer_stop(m_period4000ms_timer_id);
    APP_ERROR_CHECK(err_code);
#elif ARCH_MODE == NRF51802_Peripheral_Mode
    // Stop application timers.
    err_code = app_timer_stop(m_adc_timer_id);
    APP_ERROR_CHECK(err_code);
#endif
}


/************************************************
	  蜂鸣器专用定时器
************************************************/
static void BellDelayTask(void)	  //beep  timer2
{
	//-------------------蜂鸣器定时检测--------------------
	ring_beep_cycle();
}


/***********************************************************************/
static u8 auto_add_per_10ms_timer_EN_Flag = false;		//每10ms定时计数器使能标志
static u32 auto_add_per_10ms_timer_cnt = 0;			//每10ms定时计数器计数

void enable_auto_add_per_10ms_timer(void)		//开启每10ms定时计数器
{
	auto_add_per_10ms_timer_EN_Flag = true;
	auto_add_per_10ms_timer_cnt = 0;
}

void disable_auto_add_per_10ms_timer(void)		//关闭每10ms定时计数器
{
	auto_add_per_10ms_timer_EN_Flag = false;
}

void add_auto_add_per_10ms_timer_cnt(void)		//自增每10ms定时计数器计数值
{
	if(true == auto_add_per_10ms_timer_EN_Flag)
	{
		auto_add_per_10ms_timer_cnt++;
	}
}

s8 get_auto_add_per_10ms_timer_cnt(u32 *time)		//获取每10ms定时计数器计数值
{
	*time = auto_add_per_10ms_timer_cnt;
	return true;
}

static s8 is_init_flag = false;
void test_auto_add_per_10ms_timer(void)
{
	u32 tim_cnt = 0;
	if(false == is_init_flag)
	{
		enable_auto_add_per_10ms_timer();
		is_init_flag = true;
	}
	else
	{
		get_auto_add_per_10ms_timer_cnt(&tim_cnt);
		if(0 == tim_cnt)
		{
			
		}
	}
}

/***********************************************************************/

/************************************************
	  每隔 10ms  执行一次
************************************************/
static void PubLic10msTask(void)	//1ms TIM3
{
	//---------------转动检测编码器定时计数-------------
	timerAddTimCnt();
	
	//10ms自增计数器
	add_auto_add_per_10ms_timer_cnt();
	
#if ARCH_MODE == NRF51802_Peripheral_Mode
	//-------------------蜂鸣器定时检测--------------------
	ring_beep_cycle();
#endif
	
}
/************************************************
	  每隔 50ms  执行一次
************************************************/
static void Public50msTask(void)	//50ms  App Timer
{
	//按钮超时检测
	cycle_add_btn_det_timeout();
	
	//无线连接时处理上传队列
	if(true == wireless_connected_Flag)
	{
		//------------------上传日志队列-----------------------
		cycle_process_log_queue();
	}
	
#if ARCH_MODE != NRF51802_Peripheral_Mode
	//-------------------转动检测管脚状态队列--------------------
	cycleProcessPinStatus();
#endif
}

/************************************************
	  每隔 100ms  执行一次
************************************************/
static void PubLic100msTask(void)	//100ms App Timer
{
#if MOTION_SENSOR_TYPE != MOTION_SENSOR_TYPE_NONE
	//----------------3轴角度数据检测定时--------------
	angle_3x_detect_Cnt++;
	if(angle_3x_detect_Cnt > 1)   //10*100ms = 1s  每1s检测一次3轴角度数据 
	{
		angle_3x_detect_Cnt = 0;
		if(true == angle_3x_upload_en_Flag)
		{
			angle_3x_detect_Flag = true;
		}
		else
		{
			angle_3x_detect_Flag = false;
		}
	}
#endif
	
	//-------------------普通功能按键定时检测--------------------
	general_button_event_detect();
	
	//----------------Led  定时排入LED执行队列------------
	iTimCntLedShineIntervalCnt++;
	if(iTimCntLedShineIntervalCnt >= iTimCntLedShineIntervalMax)
	{
		iTimCntLedShineIntervalCnt = 0;
		performRollLedShine();   //从LED转动提示队列中获取一个转动步骤并排入LED执行队列
	}
	
	//-------------离线教学排入LED执行队列-----------------
	if(true == LedTeachQueueEnable_Flag)
	{
//		cycle_check_tledGam_every_100ms_task();
	}
		
	//---------------上传转动角度缓冲队列数据---------------
	send_mouse_rotation_queue();
	
}

/************************************************
	  每隔 1000ms  执行一次
************************************************/
static void PubLic1000msTask(void)    //1000ms  App Timer
{
	//---------------------串口接收------------------
	if(RF_RecEN_Flag == true)
	{
#if PROTOCOL_DATA_SOURCE == PROTOCOL_DATA_SOURCE_UART
		COMAppCmdCheckByte_Flag = true; //使能  串口字符串协议解析程序
#endif
	}
	
#if ARCH_MODE == NRF52832_Slave_Mode
	//------------离线教学功能，排入队列---------------
//	tled_check_every_1s_task();
			
	//--------------处理普通按键队列-------------------	
	cycleProcessKeyMotion();
	
	//-----------定时更新抢吃灯游戏中闪烁灯-------------
//	cycle_check_eledGam_shining_leds();

	//------------回调定时器1s定时管理定时器------------
	cycle_manage_callback_timers();
		
	//------------------------------------------------
#elif ARCH_MODE == NRF51802_Peripheral_Mode
	if(true == DEBUG_FLAG)
	{
		//cycle_upload_all_adc_channel_values();
	}
#endif
	
#if ARCH_MODE == NRF51802_Peripheral_Mode
	if(true == wireless_connected_Flag)
	{
		//竞速记录器游戏定时到时处理
		if(true == add_TIMER_FOR_TIMEOUT_STRUCT(&rRecordGam_timeout_timer))
		{
			rRecordGam_timeout_cb();
		}
	}
#endif	
}

#if ARCH_MODE == NRF52832_Slave_Mode
/************************************************
	  每隔 4000ms  执行一次
************************************************/
static void PubLic4000msTask(void)    //4000ms  App Timer
{
	//---------定时检测充电中、满led提示是否超时----------
	periodDetectChargeShiningTimeout();
	
	//-----------定时检查是否允许关机--------------------
	cycleCheckSystemOff();

	//-------------定时检查游戏成绩缓存------------------
//	cycle_check_game_score(4);
	
	//------------定期执行充电闪烁灯---------------------
//	do_cycle_check_charging_led_shine();
		
#if HW_VOICE_TYPE == HW_VOICE_TYPE_SPEAKER
	//----------检查是否设置扬声器声音小于30%--------------
	cycleCheckSetSpeakerVoiceLower();
#endif
	
	//------------------------------------------------
	
}
#endif

/**************************************************************************/
//初始化超时结构体
u8 init_TIMER_FOR_TIMEOUT_STRUCT(TIMER_FOR_TIMEOUT_STRUCT *timeout, u32 cntMax, s8 cycleFlag)
{
	timeout->cnt = 0;
	timeout->cntMax = cntMax;
	timeout->flag = false;
	timeout->cycleFlag = cycleFlag;
	timeout->startFlag = true;
	return true;
}

//轮询计数处理
u8 add_TIMER_FOR_TIMEOUT_STRUCT(TIMER_FOR_TIMEOUT_STRUCT *timeout)
{
	if(false == timeout->startFlag)
	{
		return false;
	}
	
	if(false == timeout->cycleFlag)
	{
		if(true == timeout->flag) //单次定时模式，跳过
		{
			return false;
		}
	}
	
	timeout->cnt++;
	if(timeout->cnt >= timeout->cntMax)
	{
		timeout->cnt = 0;
		timeout->flag = true;
		return true;
	}
	return false;						
}

//主动触发超时
u8 trig_timeout_TIMER_FOR_TIMEOUT_STRUCT(TIMER_FOR_TIMEOUT_STRUCT *timeout)
{
	timeout->cnt = timeout->cntMax;
	
	return true;
}
/*********************************************end of file*********************************************/
