/****************************************************************************************************
* created by sunpeng 2017 all rights reserved!
****************************************************************************************************/
#include "include.h"
#include "rotation.h"
#include "uart_api.h"
#include "wireless.h"
#include "power.h"
#include "Timer.h"
#if ARCH_MODE == NRF52832_Slave_Mode
#include "delay.h"
//#include "led.h"
#include "button.h"
#include "nrf_drv_gpiote.h"
#endif
//#include "ledGam.h"

#if CUBE_NX_MODE == CUBE_NX_MODE_2X
extern void change2XOffsetAllColorBuf(void);
#endif

MOUSE_PIN_ENUM prev_pin;
MOUSE_ROLL_STRUCT amr[mr_axis_max]; //6个轴转动状态
MOUSE_PIN_ENUM current_pin[mr_axis_max];  //分离存储当前处理的轴pin，避免冲掉前一个中断处理函数

#if ARCH_MODE == NRF52832_Slave_Mode
COM_NUM_ENUM com1 = COM1;
#elif ARCH_MODE == CC254x_Slave_Mode
COM_NUM_ENUM com2 = COM2, com3 = COM3;
#endif

ROLL_DETECT_QUEUE_STRUCT rollDetQue; //轴实时转动角度缓冲队列

#if ARCH_MODE != NRF51802_Peripheral_Mode
MOUSE_ROLL_PIN_STATUS_QUEUE_STRUCT rollPinStaQue;
#endif

#if ARCH_MODE == NRF51802_Peripheral_Mode
ROLL_ALL_AXIS_STRUCT raas;		//所有面转状态控制

#endif

#if ARCH_MODE == NRF52832_Slave_Mode || ARCH_MODE == NRF51822_Peripheral_Mode


//GPIOTE事件处理函调函数
void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	//
	switch(pin)
	{
		case RotP1: cycleDetect(MOUSE_PIN_1); break;
		case RotP2: cycleDetect(MOUSE_PIN_2); break;
		case RotP3: cycleDetect(MOUSE_PIN_3); break;
		case RotP4: cycleDetect(MOUSE_PIN_4); break;
		case RotP5: cycleDetect(MOUSE_PIN_5); break;
		case RotP6: cycleDetect(MOUSE_PIN_6); break;
		default: break;
	}
	
}

void init_rotation_gpio(void)
{
#if ARCH_MODE == NRF52832_Slave_Mode || ARCH_MODE == NRF51822_Peripheral_Mode
	ret_code_t err_code;	
	
	//初始化GPIOTE程序模块
	err_code = nrf_drv_gpiote_init();
	APP_ERROR_CHECK(err_code);
	
	//以下代码配置P0.XX作为GPIOTE输入，检测该引脚高电平到电平变化时触发事件
	//任意电平变化产生事件
#if ARCH_MODE == NRF52832_Slave_Mode	
	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);   //GPIOTE IN EVENT
#elif ARCH_MODE == NRF51822_Peripheral_Mode
	nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);   //GPIOTE PORT EVENT
#endif
	//开启P0.XX引脚的上拉电阻
	//in_config.pull = NRF_GPIO_PIN_PULLUP;
	
	//配置滚轮编码器P系列引脚为GPIOTE输入
	err_code = nrf_drv_gpiote_in_init(RotP1, &in_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);
	err_code = nrf_drv_gpiote_in_init(RotP2, &in_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);
	err_code = nrf_drv_gpiote_in_init(RotP3, &in_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);
	err_code = nrf_drv_gpiote_in_init(RotP4, &in_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);
	err_code = nrf_drv_gpiote_in_init(RotP5, &in_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);
	err_code = nrf_drv_gpiote_in_init(RotP6, &in_config, in_pin_handler);
	APP_ERROR_CHECK(err_code);

	//配置滚轮编码器N系列管脚设置输入
	nrf_gpio_cfg_input(RotN1, NRF_GPIO_PIN_PULLUP);
	nrf_gpio_cfg_input(RotN2, NRF_GPIO_PIN_PULLUP);
	nrf_gpio_cfg_input(RotN3, NRF_GPIO_PIN_PULLUP);
	nrf_gpio_cfg_input(RotN4, NRF_GPIO_PIN_PULLUP);
	nrf_gpio_cfg_input(RotN5, NRF_GPIO_PIN_PULLUP);
	nrf_gpio_cfg_input(RotN6, NRF_GPIO_PIN_PULLUP);
	
	//使能滚轮编码器P系列管脚所在GPIOTE通道的事件模式
	nrf_drv_gpiote_in_event_enable(RotP1, true);
	nrf_drv_gpiote_in_event_enable(RotP2, true);
	nrf_drv_gpiote_in_event_enable(RotP3, true);
	nrf_drv_gpiote_in_event_enable(RotP4, true);
	nrf_drv_gpiote_in_event_enable(RotP5, true);
	nrf_drv_gpiote_in_event_enable(RotP6, true);	
#endif

	//初始化转动检测缓冲队列
	InitRollDetQue(&rollDetQue);

	//初始化管脚状态检测缓冲队列
	InitRollPinStaQue(&rollPinStaQue);
	
}

void uninit_rotation_gpio(void)
{
	nrf_gpio_cfg_output(RotN1);
	nrf_gpio_cfg_output(RotN2);
	nrf_gpio_cfg_output(RotN3);
	nrf_gpio_cfg_output(RotN4);
	nrf_gpio_cfg_output(RotN5);
	nrf_gpio_cfg_output(RotN6);
	
	nrf_gpio_pin_clear(RotN1);
	nrf_gpio_pin_clear(RotN2);
	nrf_gpio_pin_clear(RotN3);
	nrf_gpio_pin_clear(RotN4);
	nrf_gpio_pin_clear(RotN5);
	nrf_gpio_pin_clear(RotN6);
	
	nrf_drv_gpiote_in_event_disable(RotP1);
	nrf_drv_gpiote_in_event_disable(RotP2);
	nrf_drv_gpiote_in_event_disable(RotP3);
	nrf_drv_gpiote_in_event_disable(RotP4);
	nrf_drv_gpiote_in_event_disable(RotP5);
	nrf_drv_gpiote_in_event_disable(RotP6);
	
	nrf_drv_gpiote_in_uninit(RotP1);
	nrf_drv_gpiote_in_uninit(RotP2);
	nrf_drv_gpiote_in_uninit(RotP3);
	nrf_drv_gpiote_in_uninit(RotP4);
	nrf_drv_gpiote_in_uninit(RotP5);
	nrf_drv_gpiote_in_uninit(RotP6);
	
	//nrf_drv_gpiote_uninit();
}

#elif ARCH_MODE == CC254X_Peripheral_Mode
void init_rotation_gpio(void)
{
    //初始化转动检测缓冲队列
    InitRollDetQue(&rollDetQue);

    //初始化管脚状态检测缓冲队列
    InitRollPinStaQue(&rollPinStaQue);

}

#elif ARCH_MODE == NRF51802_Peripheral_Mode
void init_rotation_gpio(void)
{
	nrf_gpio_cfg_output(RotDigital1);
	nrf_gpio_cfg_output(RotDigital2);
	nrf_gpio_cfg_output(RotDigital3);
	nrf_gpio_cfg_output(RotDigital4);
	nrf_gpio_cfg_output(RotDigital5);
	nrf_gpio_cfg_output(RotDigital6);	
	
	nrf_gpio_pin_set(RotDigital1);
	nrf_gpio_pin_set(RotDigital2);
	nrf_gpio_pin_set(RotDigital3);
	nrf_gpio_pin_set(RotDigital4);
	nrf_gpio_pin_set(RotDigital5);
	nrf_gpio_pin_set(RotDigital6);	
	
    //初始化转动检测缓冲队列
    InitRollDetQue(&rollDetQue);

	//初始化所有面色块状态控制数据
	init_RAAS(&raas);

}

//把电压转换成位置
s8 convert_from_voltage_to_position(u16 voltage, ROLL_POSITION_ENUM *position)
{
	if((voltage > 0) && (voltage < 40))
	{
		*position = ROLL_POSITION_0;
	}
	else if((voltage >= 300) && (voltage < 380))
	{
		*position = ROLL_POSITION_90;
	}
	else if((voltage >= 630) && (voltage < 710))
	{
		*position = ROLL_POSITION_180;
	}
	else if((voltage >= 950) && (voltage < 1010))
	{
		*position = ROLL_POSITION_270;
	}
	else
	{
		return false;
	}
	
	return true;
}

s8 init_RAAS(ROLL_ALL_AXIS_STRUCT *raas)
{
	u16 i = 0;
	for(i = 0; i < mr_axis_max; i++)
	{
		raas->side[i].position = ROLL_POSITION_MIN;
		raas->side[i].direction = ROLL_DIRECTION_Clockwise;
		raas->side[i].steps = 0;
	}
	
	return true;
}

s8 get_RAAS_position_by_axis(ROLL_ALL_AXIS_STRUCT *raas, u16 axis, ROLL_POSITION_ENUM *position)
{
	if(axis >= mr_axis_max)
	{
		return false;
	}
	
	*position = raas->side[axis].position;
	return true;
}

s8 set_RAAS_position_by_axis(ROLL_ALL_AXIS_STRUCT *raas, u16 axis, ROLL_POSITION_ENUM position)
{
	if(axis >= mr_axis_max)
	{
		return false;
	}
	
	raas->side[axis].position = position;
	return true;
}

s8 get_RAAS_direction_and_steps_by_axis(ROLL_ALL_AXIS_STRUCT *raas, u16 axis, ROLL_DIRECTION_ENUM *direction, u8 *steps)
{
	if(axis >= mr_axis_max)
	{
		return false;
	}
	
	*direction = raas->side[axis].direction;
	*steps = raas->side[axis].steps;
	
	return true;
}

s8 set_RAAS_direction_and_steps_by_axis(ROLL_ALL_AXIS_STRUCT *raas, u16 axis, ROLL_DIRECTION_ENUM direction, u8 steps)
{
	if(axis >= mr_axis_max)
	{
		return false;
	}
	
	raas->side[axis].direction = direction;
	raas->side[axis].steps = steps;
	
	return true;
}


//更新并判断位置是否变化  true=位置变化  false=位置未变化
s8 update_and_judge_position_changing(u16 axis, ROLL_POSITION_ENUM position)
{
	ROLL_POSITION_ENUM positionPrev = ROLL_POSITION_MIN;
	ROLL_DIRECTION_ENUM direction = ROLL_DIRECTION_MIN;
	u8 steps = 0;
	
	//获取上次的位置
	if(false == get_RAAS_position_by_axis(&raas, axis, &positionPrev))
	{
		return false;
	}
	
	//设置上次的位置
	if(false == set_RAAS_position_by_axis(&raas, axis, position))
	{
		return false;
	}

	//开机第一次检测到此转动轴位置，认为位置未变化
	if(ROLL_POSITION_MIN == positionPrev)
	{
		return false;
	}
	
	//位置未变化，返回
	if(positionPrev == position)
	{
		return false;
	}
	
	//位置有变化，计算转动方向和转动步数
	if(false == calc_direction_by_two_position(position, positionPrev, &direction, &steps))
	{
		return false;
	}

	//存储转动方向和转动步数
	if(false == set_RAAS_direction_and_steps_by_axis(&raas, axis, direction, steps))
	{
		return false;
	}
	
	return true;
}

#endif

#define delay_max_forward	1
#define delay_max_backward	1

u8 directionSignTab[]="FB";

#if ARCH_MODE == NRF52832_Slave_Mode || ARCH_MODE == NRF51822_Peripheral_Mode
	const float anglePerStep = (float)360.0f/stepPer360; 		//每步代表的角度 360/44 = 8.181818
#else
	const float anglePerStep = (float)360.0f/stepPer360; 		//每步代表的角度 360/44 = 8.181818
#endif

u16 AnglePer360Tab[stepPer360]={0x0};  				//360度每步转动所占的角度，查表
u16 CurrentAngleAllSidePrev[mr_axis_max]={0x0};  	//所有面轴转动最新角度数据  实时更新，格式：AnglePer360Tab
u16 CurrentAngleAllSide[mr_axis_max]={0x0};  		//所有面轴转动最新角度数据  实时更新，格式：AnglePer360Tab
u16 ZeroAngleAllSide[mr_axis_max]={0x0};  			//所有面零度对应的度数，用来校准，与Flash中常数同步


/************************************************************
	更新所有面零度机器常数
************************************************************/
u8 updateZeroAngleAllSide(u8 *buf)
{
	u16 i=0;
	
	for(i=0;i<ADC_CHAN_SIGN_MAX;i++)
	{
		ZeroAngleAllSide[i] = (*(buf + i*2))*256 + (*(buf + i*2+1));
	}
	return true;
}

/************************************************************
	初始化360度每步转动所占的角度  角度范围【0,360】
************************************************************/
u8 initAnglePer360Tab(void)
{
	u16 i=0;

	for(i=0;i<stepPer360;i++)
	{
		AnglePer360Tab[i] = (u16)(anglePerStep*(float)(i));
		//if(AnglePer360Tab[i] >= 360)
		{
		//	AnglePer360Tab[i] = 359;
		}
	}
	return true;
}

/************************************************************
	更新指定面的最新角度数据到全局变量，实现缓存上一次角度值并存储本次角度值功能
************************************************************/
u8 updateCurrentAngleBySide(u8 side, u16 angle)
{

	return false;
}

/************************************************************
	获取缓存中指定面最新角度功能
************************************************************/
int getCurrentAngleBySide(u8 side, u16 *angle)
{
	u16 i=0;
	u8 side_upper_sign = side;
	if(side >=  'a')
	{
		side_upper_sign = side - 0x20;
	}
	for(i=0;i<mr_axis_max;i++)
	{
		if(ADC_CHAN_SIGN[i] == side_upper_sign)
		{
			*angle = CurrentAngleAllSide[i];
			return true;
		}
	}
	return false;
}

int setCurrentAngleBySide(u8 side, u16 angle)
{
	u16 i=0;
	u8 side_upper_sign = side;
	if(side >=  'a')
	{
		side_upper_sign = side - 0x20;
	}
	for(i=0;i<mr_axis_max;i++)
	{
		if(ADC_CHAN_SIGN[i] == side_upper_sign)
		{
			CurrentAngleAllSide[i] = angle;
			return true;
		}
	}
	return false;
}

u8 sendRotationAngleBySide(u8 cmd)
{

	return true;
}


/********************************************************************************************/
int getPinState(MOUSE_PIN_ENUM pin,
                int pinNum
                )
{
#if ARCH_MODE == NRF51802_Peripheral_Mode

#else	
    switch(pin)
    {
    case MOUSE_PIN_1:
        if(1 == pinNum)
        {
            return GET_PIN_IN_STATUS_PIN1;
        }
        else
        {
            return GET_PIN_IN_STATUS_PIN11;
        }
    case MOUSE_PIN_2:
        if(1 == pinNum)
        {
            return GET_PIN_IN_STATUS_PIN2;
        }
        else
        {
            return GET_PIN_IN_STATUS_PIN12;
        }
    case MOUSE_PIN_3:
        if(1 == pinNum)
        {
            return GET_PIN_IN_STATUS_PIN3;
        }
        else
        {
            return GET_PIN_IN_STATUS_PIN13;
        }
    case MOUSE_PIN_4:
        if(1 == pinNum)
        {
            return GET_PIN_IN_STATUS_PIN4;
        }
        else
        {
            return GET_PIN_IN_STATUS_PIN14;
        }
    case MOUSE_PIN_5:
        if(1 == pinNum)
        {
            return GET_PIN_IN_STATUS_PIN5;
        }
        else
        {
            return GET_PIN_IN_STATUS_PIN15;
        }
    case MOUSE_PIN_6:
        if(1 == pinNum)
        {
            return GET_PIN_IN_STATUS_PIN6;
        }
        else
        {
            return GET_PIN_IN_STATUS_PIN16;
        }
	default:
		break;
    }
#endif
    return 0;
}
/************************************************************
初始化6路滚轮传感器转动方向识别数据结构初始值
	鼠标滚轮传感器两路信号识别方式：
		两路信号编号分别为1、2号，1号管脚为外部中断触发，上升沿下降沿都触发中断
		通过一号脚中断后判断一号二号的电平高低判断当前转动方向
		
************************************************************/
int initDetectVariable(void)
{
    u16 i=0;
    //init pre direction same with the prev_prev direction
    for(i=0;i<mr_axis_max;i++)
    {
        amr[i].lStepCnt = 0;
        amr[i].iTimCnt = iTimCntMin;
        amr[i].prev_direction = ROLL_DIRECTION_Clockwise;
        amr[i].prev_prev_direction = ROLL_DIRECTION_Clockwise;
        amr[i].uncertainStep_Flag = false;
        amr[i].current_direction = ROLL_DIRECTION_Clockwise;
#if ROTATION_DETECT_MODE == ROTATION_DETECT_20_40_ACK_MODE || ROTATION_DETECT_MODE == ROTATION_DETECT_15_30_ACK_MODE
		amr[i].prevPin2Status = 1;
#endif
    }
    current_pin[MOUSE_PIN_1] = MOUSE_PIN_1;
    current_pin[MOUSE_PIN_2] = MOUSE_PIN_2;
    current_pin[MOUSE_PIN_3] = MOUSE_PIN_3;
    current_pin[MOUSE_PIN_4] = MOUSE_PIN_4;
    current_pin[MOUSE_PIN_5] = MOUSE_PIN_5;
    current_pin[MOUSE_PIN_6] = MOUSE_PIN_6;
          
    //init all roll detect input pin pointer to physical pin

    prev_pin = MOUSE_PIN_1; //上一次转动的pin，pin=面
    
    return true;
}

/**********************************************************
    定时器中定时递增TimCnt计数值  1ms每次
**********************************************************/
void timerAddTimCnt(void)
{
	u16 icntmr2 = 0;
    for(icntmr2=0;icntmr2<mr_axis_max;icntmr2++)
    {
        amr[icntmr2].iTimCnt++;
        if(amr[icntmr2].iTimCnt >= iTimCntMax)
        {
            amr[icntmr2].iTimCnt = iTimCntMin;//iTimCntMin + 1;
        }
    }
}

#if ARCH_MODE == CC254X_Peripheral_Mode || ARCH_MODE == NRF51822_Peripheral_Mode 
s8 gAllPinStatus[mr_axis_max] = {1,1,1,1,1,1};
//判断特定转动加测P系列IO 是否变化, 如果变化返回true并存储最新status
s8 isPinStatusChanged(MOUSE_PIN_ENUM pin, s8 status)
{
    if(status == gAllPinStatus[pin] )
    {
        return false;
    }
    gAllPinStatus[pin] = status;
    return true;
}
#endif

#if ARCH_MODE == NRF51822_Peripheral_Mode

//定时检测N系列转动管脚回调(超时1s未检测到电平从低变高，主动变高)
// timer_id: 定时器ID
// times_count: 当前回调执行次数
void callback_RotPxDetect(u16 timer_id, u16 times_count)
{
	//检测与timer_id同名的N系列管脚
	if(true == cycleDetect((MOUSE_PIN_ENUM)timer_id))
	{
		//检测成功，停止回调定时器
		stop_callback_timer(timer_id);
	}
}

#if ARCH_MODE != NRF51802_Peripheral_Mode
/************************************************************
//全部：6路外部中断P类管脚电平状态检测
************************************************************/
s8 cycleDetectAllPin(void)
{
	u8 i = 0;
    s8 status1 = 0;				//管脚1 	电平状态
    s8 status11 = 0;			//管脚11 	电平状态（管脚1的配对管脚）
    u32 time = 0;				//时间戳
       
	for(i = 0; i < mr_axis_max; i++)
	{
		status1 = getPinState((MOUSE_PIN_ENUM)i, 1);
		if(false == isPinStatusChanged((MOUSE_PIN_ENUM)i, status1))
		{
			continue;			//管脚状态未变化，检测下一个管脚
		}
		
		status11 = getPinState((MOUSE_PIN_ENUM)i, 2);
		get_auto_add_per_10ms_timer_cnt(&time);
		
		//缓存状态检测数据
		PutRollPinStaQue(&rollPinStaQue, (MOUSE_PIN_ENUM *)&i, &status1, &status11, &time, 1);
	}
	
    return true;
}
#endif    
#endif

/************************************************************
//单路：6路外部中断P类管脚电平状态检测
************************************************************/
s8 cycleDetect(MOUSE_PIN_ENUM pin)
{
    s8 status1 = 0;				//管脚1 	电平状态
    s8 status11 = 0;			//管脚11 	电平状态（管脚1的配对管脚）
    u32 time = 0;				//时间戳
       
    status11 = getPinState(pin, 2);
    status1 = getPinState(pin, 1);
#if ARCH_MODE == CC254X_Peripheral_Mode	/*|| ARCH_MODE == NRF51822_Peripheral_Mode*/ 
    if(false == isPinStatusChanged(pin, status1))
    {
        return false;   		//管脚状态未变化，返回
    }
#endif
    
	get_auto_add_per_10ms_timer_cnt(&time);
    
    //缓存状态检测数据
    PutRollPinStaQue(&rollPinStaQue, &pin, &status1, &status11, &time, 1);
	
    return true;
}

s8 doCycleProcessPinStatus(u16 *dataLen)
{
    MOUSE_PIN_ENUM pin = MOUSE_PIN_MIN;
    s8 status1 = 0;				//管脚1 	电平状态
    s8 status11 = 0;				//管脚11 	电平状态（对应管脚1）
    u32 time = 0;				//时间戳
    u16 i = 0;	
            
    for(i = 0; i < *dataLen; i++)
    {
        if(false == GetRollPinStaQue(&rollPinStaQue, &pin, &status1, &status11, &time))
        {
            continue;
        }
        
        judgePin1UpDown(&(current_pin[pin]), amr+pin, &status1, &status11, &time);
    }
    
    return true;
}


//定时处理管脚状态队列
s8 cycleProcessPinStatus(void)
{
    u16 dataLen = 0;
    
    dataLen = GetRollPinStaQueLen(&rollPinStaQue);	
    if(0 == dataLen)
    {
        return false;
    }
    
    if(false == doCycleProcessPinStatus(&dataLen))
    {
        return false;
    }
    
    return true;
}

/************************************************************
通过1号、2号管脚电平判断单步转动方向：
		1号电平   2号电平	方向
		1			1		前
		1			0		后
		0			1		后
		0			0		前
************************************************************/
s8 judgePin1UpDown( MOUSE_PIN_ENUM *pin, 
					MOUSE_ROLL_STRUCT *mr, 
					s8 *status1, 
					s8 *status11,
					u32 *time)
{
	if(mr->iTimCnt < iTimCntMin)
	{
		mr->iTimCnt = iTimCntMin;
		//return false; //test 
	}

		
	return true;
}

/************************************************************
转动步计数增减
************************************************************/
s8 stepAddMinus(ROLL_DIRECTION_ENUM directionNow,//单步转动方向
				MOUSE_PIN_ENUM *pin,
				MOUSE_ROLL_STRUCT *mr,
				u32 *time
				)
{
	return true;
}

//将转动检测到的动作压入缓冲队列
void mouse_rotation_queue(
							MOUSE_PIN_ENUM *pin,
							MOUSE_ROLL_STRUCT *mr,
							u32 *time
							)
{
	if(mr->lStepCnt >= stepPer360)
	{
		mr->lStepCnt = 0;
		return;
	}
	if(*pin >= ADC_CHAN_SIGN_MAX)
	{
		*pin = MOUSE_PIN_1;
		return;
	}

	PutRollDetQue(&rollDetQue, time, (u8 *)&ADC_CHAN_SIGN[*pin], &AnglePer360Tab[mr->lStepCnt], 1);
}

#if ARCH_MODE == NRF51802_Peripheral_Mode

//压入转动队列
void potentiometer_rotation_queue(	u16 axis,						//转动轴代号
							ROLL_DIRECTION_ENUM direction,	//转动方向
							u8 steps						//转动步数（一步90度）
							)
{
	u8 i = 0;
	
	if(0 == steps)
	{
		return;
	}
	
	if(axis >= mr_axis_max)
	{
		return;
	}
	
	if((direction <= ROLL_DIRECTION_MIN) || (direction >= ROLL_DIRECTION_MAX))
	{
		return;
	}
	
	for(i = 0; i < steps; i++)
	{
		PutRollDetQue(&rollDetQue, 0, (u8 *)&axis, (u16 *)&direction, 1);
	}
}
#endif

/************************************************************
	定时检测转动角度缓冲队列是否有数据，若有通过网络上传App
************************************************************/
s8 send_mouse_rotation_queue(void)
{
	
	return true;
}

#define BesidePinTabAxisMax 6
#define BesidePinTabSideMax 4
MOUSE_PIN_ENUM BesidePinTab[BesidePinTabAxisMax][BesidePinTabSideMax]={MOUSE_PIN_1};
/***************************************************
初始化6个面所有相邻的四个面
***************************************************/
void initBesidePins(void)
{

}

/***************************************************
判断prev_pin所代表的面与new_pin代表的面是否相邻
***************************************************/
int judgeBesidePins(MOUSE_PIN_ENUM *prev_pin,MOUSE_PIN_ENUM *new_pin)
{
	int flag = false;
	u16 i=0;
	for(i=0;i<BesidePinTabSideMax;i++)
	{
		if(BesidePinTab[*prev_pin][i] == *new_pin)
		{
			flag = true;
		}
	}
	return flag;
}


#if ARCH_MODE == CC254X_Peripheral_Mode
#elif ARCH_MODE == NRF51822_Peripheral_Mode
#elif ARCH_MODE == NRF51802_Peripheral_Mode
#else
/***************************************************
	执行面转动Led灯闪烁命令分发到灯控板
***************************************************/
u8 performRollLedShine(void)
{
	u8 crollSide = 0x0;
	//print_wifi("performRollLedShine->\n");
	if(true == GetRollQueue(&ledRollQueue, &crollSide))
	{
		//---perform roll led shine---
//		RollLed(crollSide, 1);
		return true;
	}
	return false;
}
#endif

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

//初始化管脚状态缓冲队列
void InitRollPinStaQue(MOUSE_ROLL_PIN_STATUS_QUEUE_STRUCT *dataS)
{
	u16 i=0;
	for(i=0;i<MOUSE_ROLL_STEP_PIN_STATUS_MAX;i++)
	{
		dataS->step[i].pin = MOUSE_PIN_MIN;
		dataS->step[i].status1 = 0x0;
		dataS->step[i].status11 = 0x0;
		dataS->step[i].time = 0x0;
	}

	dataS->head = 0x0;
	dataS->tail = 0x0;
}

//获取队列长度
u16 GetRollPinStaQueLen(MOUSE_ROLL_PIN_STATUS_QUEUE_STRUCT *dataS)
{
	u16 len = 0;
	if(dataS->tail > dataS->head)
	{
		len = dataS->tail - dataS->head;
	}
	else if(dataS->head > dataS->tail)
	{
		len = MOUSE_ROLL_STEP_PIN_STATUS_MAX - dataS->head + dataS->tail;
	}
	return len;
}

//写入一个数据到队列
s8 PutRollPinStaQue(MOUSE_ROLL_PIN_STATUS_QUEUE_STRUCT *dataS, MOUSE_PIN_ENUM *pin, s8 *status1, s8 *status11, u32 *time, u16 dataLen)
{
	u16 i=0;
	

	return true;
}

//获取队列中队首一个成员，改变读head
s8 GetRollPinStaQue(MOUSE_ROLL_PIN_STATUS_QUEUE_STRUCT *dataS, MOUSE_PIN_ENUM *pin, s8 *status1, s8 *status11, u32 *time)
{

	return true;
}

//将队列所有管脚状态数据转换成字符串形式输出
// str			: 输出字符串
// strLenMax	: str最大存储长度
s8 ConvertRollPinStaQueAllPinStatusToStr(MOUSE_ROLL_PIN_STATUS_QUEUE_STRUCT *dataS, u8 *str, u16 strLenMax)
{


	return true;
}


/*********************************************end of file*********************************************/
