//PMC153
//=========================================================================
//         PB5 |1    14| PB2
//         PB6 |2    13| PB1
//         PB7 |3    12| PB0/INT1
//         VDD |4    11| GND
//         PA7 |5    10| PA0
//         PA6 |6     9| PA4
//   PA5/PRST# |7     8| PA3
//==========================================================================
#include	"extern.h"
#include    "WirlessApp.h"

//=================================局部变量===================================
.ramadr 0							//地址定义为0
word 	gw_Point;
.ramadr system						//以后变量地址由系统自行决定
word    gw_T16Cnt;	

extern byte PackId;
extern byte DelayCnt;

//byte	ColorCnt;
byte 	gb_Flag;
//bit     b_sleep		:	gb_Flag.7	//睡眠模式
//bit		KeyBit		:	gb_Flag.5	//按键长按标志
bit     RX_DR_F		:	gb_Flag.4
bit     Time2ms_F	:   gb_Flag.3
bit     Key_Press_F :   gb_Flag.2
bit     TX_MODE_F   :   gb_Flag.1
bit     TX_TD_F		:   gb_Flag.0

byte MARK0;
bit     Keep_Flash_Enable_F 	: MARK0.0	//保持一直闪烁, 1->保持闪烁
bit 	Flash_Enable_F			: MARK0.1	//闪烁几次
bit   	Freq_Change_Enable_F 	: MARK0.2	//调频允许

byte Flash_Time_Cnt_R;	//闪烁计时
byte Flash_Time_R; 		//闪烁时间
byte Flash_Num_R;		//闪烁次数

//word	T16_TICK;
 byte RegAddr;
 byte RegData;
 byte SPIDDR;
 byte rf_Mode;
 byte rf_rwBuf[WIRLESS_CMD_PACKLEN];
 byte Roll_Code_Buf[WIRLESS_CMD_PACKLEN];
 byte pl_long;
//byte KEY_NOW_STATUS_R;
BYTE KEY_LAST_STATUS_R;
BYTE KEY_STATUS_R;
BYTE KEY_PRESS_DEBOUNC_R;
//BYTE KEY_LOOSEN_DEBOUNC_R;
BYTE TEST_MODE_R;
//BYTE ReadRxDataTimeCnt_R;
BYTE No_Data_Cnt_R;
//BYTE RL_LAST_STATUS_R;       //左右驱动上一个状态
//BYTE FB_LAST_STATUS_R;		 //前进后退上一个状态
//BYTE RL_SWITCH_DELAY_R;		 //左右驱动切换延时
//BYTE FB_SWITCH_DELAY_R;		 //前进后退切换延时
byte LAST_STATUS_R;				//上一个状态
byte SWITCH_DELAY_R;			//状态切换延时

byte Freq_Change_R;			 //频率变化
//byte Freq_Change_Num_R;			//变化次数
word Table_Addr;
byte Freq_Table[5];// = {5,19,33,47,61};

#define PairingPayload 0x55
#define ControlPayload 0xAA


//=================================局部函数====================================注意！！！！！！D

void  SystemStop(void);
void	SysInit(void);
EXTERN void	RW1600_RecivePack(void);
void Key_Scan(void);
void KEY_FUNC(void);
void Match_Code(void);
void Freq_Change(void);
void TEST_MODE(void);
void Test_Func(void);
void Car_Drive(void);
void Get_Rolling_Code(void);
//==============================函数主体========================================



/*******************************************************************************
* 名称: FPPA0
* 功能: 主函数开始
* 形参:       
* 返回: 无
* 说明: 
*******************************************************************************/
void FPPA0(void)
{

	.ADJUST_IC	SYSCLK=IHRC/8,IHRC=16MHZ,Vdd=3.0V;
	//清除RAM
	gw_Point = _SYS(RAM_SIZE)-1;
	a = 0;
	do 
	{
		*gw_Point = a;
	}while(--gw_Point$0);	

	SysInit();
    Wirless_Init();
	Freq_Table[0] = 0x05;
	Freq_Table[1] = 19;
	Freq_Table[2] = 33;
	Freq_Table[3] = 47;
	Freq_Table[4] = 61;
	if(!PB.2)
		TEST_MODE();
	
	//PBC  = 0B1111_0011; //0->输入，1->输出; 
						//PB0[CLK]->输出，PB1[MOSI]->输出
						//PB3[MISO]->输入，PB4[SS]->输出
						//PB2[KEY & Drive_F]->初始化先配置为输入，正常模式下，配置为输出
//	PBPH = 0B0000_1100; //上拉-[MISO R3 R2]	0->禁用， 1->启用
//	PB    = 0B0010_0000; //拉高-[SS]			拉低-[CLK CE]
	
	Flash_Enable_F = 1;
	Keep_Flash_Enable_F = 1;
	Flash_Time_R = 124;
	misc = 0x02;
	clkmd.1 = 1;			//打开看门狗
	 wdreset;
	Freq_Change_R = 5;
	Match_Code();			//对码
	
	
	Flash_Enable_F = 0;
	Keep_Flash_Enable_F = 0;
	
	LED_OFF;
	while(1)	// Loop for Main Process
	{
		if(Time2ms_F)
		{
			Time2ms_F = 0;
			wdreset;
			RW1600_RecivePack();
			if(RX_DR_F)					//有接收到数据
			{
				No_Data_Cnt_R = 0;
				Freq_Change_Enable_F = 0;
				Car_Drive();
				Freq_Change();
			}
			else 						//没有接收到数据
			{
				No_Data_Cnt_R++;
				if(49 < No_Data_Cnt_R)   //没有数据50*2ms，则停止所有驱动
				{
					No_Data_Cnt_R = 0;
					Freq_Change_Enable_F = 1;
					Drive_R = 0;
					Drive_L = 0;
					Drive_B = 0;
					Drive_F = 0;
				}
				if(Freq_Change_Enable_F)
				{
					Freq_Change();
				}
			}			
		}
    }

}

/*******************************************************************************
*@ 函数功能: 读滚码函数
*@ 参	 数: 无
*@ 返 回 值: 无
*@ 备	 注: 无
********************************************************************************/
void Get_Rolling_Code(void)
{
	BYTE RC_BUF;

	.if	_SYS(AT_ICE)
	Roll_Code_Buf[0] = 0x01;
	Roll_Code_Buf[1] = 0x00;
	Roll_Code_Buf[2] = 0x00;
	Roll_Code_Buf[3] = 0x00;
	.else
	call    _SYS(ADR.ROLL);     //  读取 Roll:0
	Roll_Code_Buf[0] =   A;
	call    _SYS(ADR.ROLL) +1;  //  读取 Roll:1
	Roll_Code_Buf[1] =   A;
	call    _SYS(ADR.ROLL) +2;  //  读取 Roll:2
	Roll_Code_Buf[2] =   A;
	call    _SYS(ADR.ROLL) +3;  //  读取 Roll:3
	Roll_Code_Buf[3] =   A;
	.endif
	
	Roll_Code_Buf[5]= 16; 
    while(Roll_Code_Buf[5]!=0)         
	  {
			Roll_Code_Buf[6]=Roll_Code_Buf[1];
			Roll_Code_Buf[1]>>=1;
			RC_BUF = Roll_Code_Buf[2]&0x01;
			if(RC_BUF)
			{
				Roll_Code_Buf[1]|=0x80;
			}
			Roll_Code_Buf[2]>>=1;
			RC_BUF = Roll_Code_Buf[6]&0x01;
			if(RC_BUF)
			{
				Roll_Code_Buf[1] ^=0x05;
				Roll_Code_Buf[2] ^=0x88;
			}
			Roll_Code_Buf[5]--;
		}
    Roll_Code_Buf[4] = Roll_Code_Buf[2] >> 4; 
    Roll_Code_Buf[4] = Roll_Code_Buf[4] + 0x80; 
    Roll_Code_Buf[3] = Roll_Code_Buf[2] & 0x0f; 
    Roll_Code_Buf[3] = Roll_Code_Buf[3] + 0x50; 
    Roll_Code_Buf[2] = Roll_Code_Buf[1] >> 4; 
    Roll_Code_Buf[2] = Roll_Code_Buf[2] + 0xb0; 
    Roll_Code_Buf[1] &= 0x0f;                 
    Roll_Code_Buf[1] = Roll_Code_Buf[1] + 0xc0;  

}
/*******************************************************************************
*@ 函数功能: 按键操作
*@ 参	 数: 无
*@ 返 回 值: 无
*@ 备	 注: 无
********************************************************************************/
void Car_Drive(void)
{
	byte Dat_Buf;

	Dat_Buf = ~rf_rwBuf[0];

	if(Dat_Buf == rf_rwBuf[1])			//校验不通过则直接退出程序段
	{
		if(LAST_STATUS_R == rf_rwBuf[0])
		{
			SWITCH_DELAY_R = 0;
			switch(rf_rwBuf[0])
			{
				case 0x01:
							Drive_R = 0;
							Drive_L = 0;
							Drive_B = 0;
							Drive_F = 1;
				break;
				case 0x02:
							Drive_R = 1;
							Drive_L = 0;
							Drive_B = 0;
							Drive_F = 0;
				break;
				case 0x04:
							Drive_R = 0;
							Drive_L = 1;
							Drive_B = 1;
							Drive_F = 0;
				break;
				case 0x08:
							Drive_R = 1;
							Drive_L = 0;
							Drive_B = 0;
							Drive_F = 1;
				break;
				default:
				
				break;
			}
		}
		else 
		{
			Drive_R = 0;
			Drive_L = 0;
			Drive_B = 0;
			Drive_F = 0;
			SWITCH_DELAY_R++;
			if(2 <SWITCH_DELAY_R)
			{
				LAST_STATUS_R = rf_rwBuf[0];
			}
		}
/*
		Dat_Buf = rf_rwBuf[0] & 0x03;
		
		if((0x03 != Dat_Buf) && (0x00 != Dat_Buf) && (RL_LAST_STATUS_R == Dat_Buf))
		{

			RL_SWITCH_DELAY_R = 0;
			if(rf_rwBuf[0].0)     //右转
			{
				Drive_R = 1;
				Drive_L = 0;
			}
			else				  //左转
			{
				Drive_R = 0;
				Drive_L = 1;
			}
		}
		else 
		{
			Drive_R = 0;
			Drive_L = 0;
			RL_SWITCH_DELAY_R++;
			if(2 <RL_SWITCH_DELAY_R)
			{
				RL_LAST_STATUS_R = Dat_Buf;
			}
		}
		
		Dat_Buf = rf_rwBuf[0] & 0x0C;
		
		if((0x0C != Dat_Buf) && (0x00 != Dat_Buf) && (FB_LAST_STATUS_R == Dat_Buf))
		{
				FB_SWITCH_DELAY_R = 0;
				if(rf_rwBuf[0].2)   //后退
				{
					Drive_B = 1;
					Drive_F = 0;
					Drive_R = 0;
					Drive_L = 1;
				}
				else				//前进
				{
					Drive_B = 0;
					Drive_F = 1;
					Drive_R = 1;
					Drive_L = 0;
				}
		}
		else 
		{
			Drive_B = 0;
			Drive_F = 0;
			FB_SWITCH_DELAY_R++;
			if(2 <FB_SWITCH_DELAY_R)
			{
				FB_LAST_STATUS_R = Dat_Buf;
			}
		}
	*/
	}
}

/*******************************************************************************
* 名称: SystemStop
* 功能: 睡眠
* 形参:       
* 返回: 无
* 说明: 
*******************************************************************************/
/*
void SystemStop(void)
{
	Wirless_Sleep();
	.disgint;
	$  T16M   STOP;			// 关闭T16
	.CLKMD.2 =   1;			// 启动低时钟
    .CLKMD   =   0B1101_0100;// IHRC/8 -> ILRC/4;
	.CLKMD.4 =   0;          // 关闭 IHRC，以达省电效果
	engint;
    stopsys;				// 进入低耗电状态
	nop;nop;nop;nop;
	nop;nop;nop;nop;
    CLKMD.4 =   1;			// 启动高速时钟
	nop;nop;nop;nop;
    .CLKMD   =   0B0011_1100;// ILRC/4 -> IHRC/8;
	.CLKMD.2 =   0;          
	nop;nop;nop;nop;
	Wirless_WeakUp();
	$ t16m SYSCLK,/4,bit13;// 打开T16
}
*/
/*******************************************************************************
* 名称: Interrupt
* 功能: 中断处理函数
* 形参:       
* 返回: 无
* 说明: 
*******************************************************************************/
void Interrupt(void)
{
	pushaf;
/*
	if (Intrq.PA0)
	{	
		Intrq.PA0	=	0;
	}
	*/
	if(intrq.t16)		//1MS
	{
		intrq.t16 = 0;
		stt16 gw_T16Cnt;
		Time2ms_F = 1;

		if(Flash_Enable_F)
		{
			Flash_Time_Cnt_R++;
			if(Flash_Time_R < Flash_Time_Cnt_R)
			{
				Flash_Time_Cnt_R = 0;
				PB ^= 0x20;
				if(!Keep_Flash_Enable_F)
					{
						Flash_Num_R--;
						if(0 == Flash_Num_R)
						{
							Flash_Enable_F = 0;
						}
					}
			}
		}
	}
	popaf;
}
/*******************************************************************************
* 名称: SysInit
* 功能: 系统初始化
* 形参:       
* 返回: 无
* 说明: 
*******************************************************************************/
void	SysInit(void)
{
	pac     = 0b_1111_1111;   //0->输入， 1->输出
	paph 	= 0b_0000_0000;		//1->开上拉
	pa      = 0b_0000_0000;
	
	PBC  = 0B1111_0011; //0->输入，1->输出; 
						//PB0[CLK]->输出，PB1[MOSI]->输出
						//PB3[MISO]->输入，PB4[SS]->输出
						//PB2[KEY & Drive_F]->初始化先配置为输入，正常模式下，配置为输出
	PB    = 0B0000_0000; //拉高-[SS]			拉低-[CLK CE]
  	PBPH = 0B0000_1100; //上拉-[MISO R3 R2]	0->禁用， 1->启用

	Get_Rolling_Code();

	//定时2MS/2us = 2*1000 = 2000
	gw_T16Cnt = 8192 - 1000;		
	stt16 gw_T16Cnt;
	$ t16m SYSCLK,/4,bit13;

	intrq = 0;
	inten.2 = 1;
	engint;
}

/***************************************************
*@ 函数功能: 按键扫描
*
*****************************************************/
void Key_Scan(void)
{

	BYTE BUF0;
		/*
	BUF0 = PA;
	BUF0 = ~BUF0;
	BUF0 &= 0x19;
	BUF1 = PB;
	BUF1 = ~BUF1;
	BUF1 &= 0x04;
	BUF0 = BUF0|BUF1;
	*/
	BUF0 = 0;
	if(!KEY)
		BUF0 = 0x01;
	if(BUF0 == KEY_LAST_STATUS_R)
	{
		KEY_PRESS_DEBOUNC_R++;
		if(5 < KEY_PRESS_DEBOUNC_R)
		{
			KEY_PRESS_DEBOUNC_R = 0;
			KEY_STATUS_R = BUF0;
		}
	}
	else 
	{
		KEY_LAST_STATUS_R = BUF0;
		KEY_PRESS_DEBOUNC_R = 0;
	}
}

/**********************************************************
*@ 函数功能: 按键功能实现
*@
***********************************************************/
/*
void KEY_FUNC(void)
{
	if(KEY_STATUS_R)
	{
		rf_rwBuf[0] = KEY_STATUS_R;
		RW1600_start_TXsend_data();
	}
}
*/
/*************************************************************************************************
*@函数功能: 此函数为RX端的对码程序
*@备	注: 对码流程-> 1: 在公共频道下，配置为发射模式，发射RX的地址，如果收到ACK
						: 说明TX端接收到RX端的数据，RX端把本机地址设置到收发地址后退出。
					   2: 如果在公共频道下，RX端发射数据没有收到ACK，则自动切换到接收模式，
					    : 把RX本身的地址设置到收发地址里等待接收数据，如果在接收模式下
						: 接收到数据则退出，说明TX端与RX端之前配对过，并且TX端没有断电。
						: 如果在接收模式下还是没有接收到数据，则切换回步骤1
						
**************************************************************************************************/
/* 对码程序跑一圈需要30ms*/
void Match_Code(void)
{
	byte num;
	while(1)
	{
		// if(LED_PIN)
			// LED_OFF;
		// else 
			// LED_ON;
			
		wdreset;
		rf_Mode = Rf_PTX_Mode;    //切换到tx模式
		RW1600_ModeSwitch(); 
		DelayCnt = 30;
		Delay100US();
	
		pl_long = WIRLESS_CMD_PACKLEN;
		RW1600_start_TXsend_data();   //发送数据,发送最慢需要10ms
		
		Table_Addr = Roll_Code_Buf;
		Set_TX_RX_ADDR();
		SPI_CE_LOW();
		DelayCnt = 30;
		Delay100US();
		rf_Mode = Rf_PRX_Mode;    //切换到RX模式
		RW1600_ModeSwitch();   
		if(TX_TD_F)              //如果发射模式下收到ACK信号，则配置为接收模式后直接退出对码程序段
		{
			return;
		}
		num = 16;
	    //在发射模式下没有收到ACK，则配置为接收模式，如果有收到数据，则退出对码程序块
		do
		{
			RW1600_RecivePack(); 
			DelayCnt = 10;
			Delay100US();
			if(RX_DR_F)
			{
				return;
			}
			num--;
		}while(num);
		rf_rwBuf[0] = Public_Address_0;
		rf_rwBuf[1] = Public_Address_1;
		rf_rwBuf[2] = Public_Address_2;
		rf_rwBuf[3] = Public_Address_3;
		rf_rwBuf[4] = Public_Address_4;
		Table_Addr = rf_rwBuf;
		Set_TX_RX_ADDR();
		//Freq_Change();
		
	}
}
/************************************************************
*@ 函数功能: 变频
*************************************************************/
void Freq_Change(void)
{
	
	
	Freq_Change_R += 14;
	if(33 < Freq_Change_R)
	{
		Freq_Change_R = 5;
	}
	RegData = Freq_Change_R;
	Set_Freq_Point();
	

	/*
	Table_Addr = Freq_Table;
	Table_Addr += Freq_Change_R;
	RegData = *Table_Addr; //
	Set_Freq_Point();
	Freq_Change_R +=2;
	if(4 < Freq_Change_R)
	{
		Freq_Change_R -= 5;
	}
	*/
}
/************************************************************
*@ 函数功能: 测试模式
*************************************************************/
void TEST_MODE(void)
{
	TEST_MODE_R = 0;
	while(1)
	{
		if(Time2ms_F)
		{
			Time2ms_F =0;
			Key_Scan();
			Test_Func();
			if(TX_MODE_F)
			{
					pl_long = 16;
					RW1600_start_TXsend_data();   //发送数据
					
					DelayCnt = 30;
					Delay100US();
			}
			
		}
	}
}

/*****************************************************
*@ 函数功能: 测试功能
******************************************************/
void Test_Func(void)
{
	
			if(KEY_STATUS_R.0)
			{
				if(!Key_Press_F)
				{
					Key_Press_F = 1;
					TEST_MODE_R++;
					SPI_CE_LOW();
					Flash_Time_Cnt_R = 0;
					Flash_Time_R = 100;
					switch(TEST_MODE_R)
					{
						case 1:
							LED_ON;
							Flash_Num_R = 1;
							
							RegData = 5;
							Set_Freq_Point();
							rf_Mode=0x80;
							RW1600_ModeSwitch();				//载波
							
						break;
						case 2:
							LED_ON;
							Flash_Num_R = 3;
							
							RegData = 45;
							Set_Freq_Point();
						break;
						case 3:
							LED_ON;
							Flash_Num_R = 5;
							
							RegData = 75;
							Set_Freq_Point();
						break;
						case 4:
							LED_ON;
							Flash_Num_R = 2;
							
							RegData = 5;
							Set_Freq_Point();
							rf_Mode = Rf_PTX_Mode;
							RW1600_ModeSwitch();       //切换到对对应的模式
							TX_MODE_F = 1;
						break;
						case 5:
							LED_OFF;
							Flash_Num_R = 5;
							
							RegData = 45;
							Set_Freq_Point();
						    
						break;
						case 6:
							LED_OFF;
							Flash_Num_R = 7;
							
							RegData = 75;
							Set_Freq_Point();
							
						break;
						case 7:
							LED_OFF;
							Flash_Num_R = 2;
							
							TX_MODE_F = 0;
							RegData = 5;
							Set_Freq_Point();
							rf_Mode = Rf_PRX_Mode;
							RW1600_ModeSwitch();
						break;
						case 8:
							LED_ON;
							Flash_Num_R = 3;
							
							RegData = 45;
							Set_Freq_Point();
							
						break;
						case 9:
							LED_ON;
							Flash_Num_R = 5;
							
							RegData = 75;
							Set_Freq_Point();
							TEST_MODE_R = 0;
						break;
						default:
						break;
					}
					Keep_Flash_Enable_F = 0;
					Flash_Enable_F = 1;
					DelayCnt = 25;Delay100US();					  //延迟>=2MS
					SPI_CE_HIGH();
				}
			}
			else
			{
				Key_Press_F = 0;
			}
}
















