#include "user_nfc.h"
#include "user_spi.h"
#include "lpcd.h"

static nfc_work_s nfc_work = {
	.work_type = NFC_TYPE_RST_START,
	.nfc_delay_count = 0,
	.nfc_param = {
		{.init_stat = false,.version = 0,.loss_delay = 0,.card_stat = NFC_CARD_NULL,.elecStat = false,.idA = {0},.idB = {0},},
		{.init_stat = false,.version = 0,.loss_delay = 0,.card_stat = NFC_CARD_NULL,.elecStat = false,.idA = {0},.idB = {0},},
		{.init_stat = false,.version = 0,.loss_delay = 0,.card_stat = NFC_CARD_NULL,.elecStat = false,.idA = {0},.idB = {0},},
		{.init_stat = false,.version = 0,.loss_delay = 0,.card_stat = NFC_CARD_NULL,.elecStat = false,.idA = {0},.idB = {0},},
		{.init_stat = false,.version = 0,.loss_delay = 0,.card_stat = NFC_CARD_NULL,.elecStat = false,.idA = {0},.idB = {0},},
	},
};

static unsigned char uid_length = 0;
static unsigned char CT[2];//卡类型
static unsigned char IDA[15];//存A卡ID
static unsigned char PassWd[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
static unsigned char RWDATA[16];

static uint8_t nfc_cs_idx = 0;
static vUser_nfc_upload_card_stat_func xUpload_card_stat = NULL;

tmosTaskID user_nfc_task_id = INVALID_TASK_ID;
static uint16_t user_nfc_task_process_event(uint8_t task_id, uint16_t events);

static void set_nfc_cs(bool stat)
{
	switch(nfc_cs_idx)
	{
		case 0:{
			if(stat == true)
			{
				NFC_01_CS_ON;
			}
			else{
				NFC_01_CS_OFF;
			}
		}break;
		case 1:{
			if(stat == true)
			{
				NFC_02_CS_ON;
			}
			else{
				NFC_02_CS_OFF;
			}
		}break;
		case 2:{
			if(stat == true)
			{
				NFC_03_CS_ON;
			}
			else{
				NFC_03_CS_OFF;
			}
		}break;
		case 3:{
			if(stat == true)
			{
				NFC_04_CS_ON;
			}
			else{
				NFC_04_CS_OFF;
			}
		}break;
		case 4:{
			if(stat == true)
			{
				NFC_05_CS_ON;
			}
			else{
				NFC_05_CS_OFF;
			}
		}break;
	}
}

/*******************************************************************************
  * @函数名称   user_nfc_gpio_init
  * @函数说明   GPIO初始化
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static void user_nfc_gpio_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    USER_NFC_GPIO_RCC_ENABLE;

	//输出端口初始化
    GPIO_InitStructure.GPIO_Pin = NFC_01_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_01_CS_GPIO, &GPIO_InitStructure);
    NFC_01_CS_OFF;

    GPIO_InitStructure.GPIO_Pin = NFC_02_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_02_CS_GPIO, &GPIO_InitStructure);
    NFC_02_CS_OFF;

	GPIO_InitStructure.GPIO_Pin = NFC_03_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_03_CS_GPIO, &GPIO_InitStructure);
    NFC_03_CS_OFF;

	GPIO_InitStructure.GPIO_Pin = NFC_04_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_04_CS_GPIO, &GPIO_InitStructure);
    NFC_04_CS_OFF;

	GPIO_InitStructure.GPIO_Pin = NFC_05_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_05_CS_GPIO, &GPIO_InitStructure);
    NFC_05_CS_OFF;

    GPIO_InitStructure.GPIO_Pin = NFC_01_RST_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_01_RST_GPIO, &GPIO_InitStructure);
    NFC_01_RST_DISABLE;

    GPIO_InitStructure.GPIO_Pin = NFC_02_RST_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_02_RST_GPIO, &GPIO_InitStructure);
    NFC_02_RST_DISABLE;

	GPIO_InitStructure.GPIO_Pin = NFC_03_RST_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_03_RST_GPIO, &GPIO_InitStructure);
    NFC_03_RST_DISABLE;

	GPIO_InitStructure.GPIO_Pin = NFC_04_RST_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_04_RST_GPIO, &GPIO_InitStructure);
    NFC_04_RST_DISABLE;

	GPIO_InitStructure.GPIO_Pin = NFC_05_RST_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(NFC_05_RST_GPIO, &GPIO_InitStructure);
    NFC_05_RST_DISABLE;
}

/*********************************************************************************************************
** Function name:       NFC_HardReset
** Descriptions:        FM175xx硬件复位
** input parameters:    N/A       
** output parameters:   N/A
** Returned value:      true：操作成功 ERROR：操作失败    
*********************************************************************************************************/
void NFC_HardReset(void)
{   
  	switch(nfc_cs_idx)
	{
		case 0:{
			NFC_01_RST_ENABLE;
		}break;
		case 1:{
			NFC_02_RST_ENABLE
		}break;
		case 2:{
			NFC_03_RST_ENABLE
		}break;
		case 3:{
			NFC_04_RST_ENABLE
		}break;
		case 4:{
			NFC_05_RST_ENABLE
		}break;
	}
	Delay_Ms(1);
	switch(nfc_cs_idx)
	{
		case 0:{
			NFC_01_RST_DISABLE;
		}break;
		case 1:{
			NFC_02_RST_DISABLE
		}break;
		case 2:{
			NFC_03_RST_DISABLE
		}break;
		case 3:{
			NFC_04_RST_DISABLE
		}break;
		case 4:{
			NFC_05_RST_DISABLE
		}break;
	}
	Delay_Ms(1);
}

/*********************************************************************************************************
** Function name:       NFC_HPD
** Descriptions:        硬件低功耗操作
** input parameters:    mode = 1 退出HPD模式 ，mode = 0 进入HPD模式  
** output parameters:   N/A
** Returned value:      NONE  
*********************************************************************************************************/
void NFC_HardPowerdown(uint8_t mode)
{    
	if(mode == 0x00)
	{
		switch(nfc_cs_idx)
		{
			case 0:{
				NFC_01_RST_ENABLE;
			}break;
			case 1:{
				NFC_02_RST_ENABLE
			}break;
			case 2:{
				NFC_03_RST_ENABLE
			}break;
			case 3:{
				NFC_04_RST_ENABLE
			}break;
			case 4:{
				NFC_05_RST_ENABLE
			}break;
		}                              /* 读卡芯片进入硬件低功耗       */               
  }
	else{
    switch(nfc_cs_idx)
		{
			case 0:{
				NFC_01_RST_DISABLE;
			}break;
			case 1:{
				NFC_02_RST_DISABLE
			}break;
			case 2:{
				NFC_03_RST_DISABLE
			}break;
			case 3:{
				NFC_04_RST_DISABLE
			}break;
			case 4:{
				NFC_05_RST_DISABLE
			}break;
		}                             /* 读卡芯片退出硬件低功耗       */ 
  }
}

/*******************************************************************************
  * @函数名称 ReadRawRC
  * @函数说明 读寄存器
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
unsigned char ReadRawRC(unsigned char Address)
{
	unsigned char ucAddr;
	unsigned char ucResult=0;
	ucAddr = ((Address<<1)&0x7E)|0x80;
	set_nfc_cs(true);
	SPI_ReadWriteByte(ucAddr);//向总线写多个数据
	//SPI_WriteNBytes(SPI1,&ucAddr,1);  
	ucResult = SPI_ReadWriteByte(0xFF);//向总线读多个数据
	//SPI_ReadNBytes(SPI1,&ucResult,1);  
	set_nfc_cs(false);
	return ucResult;
}

/*******************************************************************************
  * @函数名称 WriteRawRC
  * @函数说明 写寄存器
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
void WriteRawRC(unsigned char Address, unsigned char value)
{  
	unsigned char ucAddr;
	uint8_t write_buffer[2]={0};
	ucAddr = ((Address<<1)&0x7E);

	set_nfc_cs(true);
	SPI_ReadWriteByte(ucAddr);//向总线写多个数据
	SPI_ReadWriteByte(value);//向总线写多个数据
	set_nfc_cs(false);
}

/*******************************************************************************
  * @函数名称 SetBitMask
  * @函数说明 设置位
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
void SetBitMask(unsigned char reg,unsigned char mask)  
{
  char tmp = 0x0;
  tmp = ReadRawRC(reg);
  WriteRawRC(reg,tmp | mask);  // set bit mask
}

/*******************************************************************************
  * @函数名称 ClearBitMask
  * @函数说明 清除位
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
void ClearBitMask(unsigned char reg,unsigned char mask)  
{
  char tmp = 0x0;
  tmp = ReadRawRC(reg);
  WriteRawRC(reg, tmp & ~mask);  // clear bit mask
} 

/*******************************************************************************
  * @函数名称 Card_Check
  * @函数说明 检测卡片类型以及卡片的信息
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
static bool Card_Check(void)
{
	bool stat = false;

	stat = TyteA_Read(CT, IDA);

	if(stat == true)
	{
		memset(nfc_work.nfc_param[nfc_cs_idx].idA, 0, 8);
		if(CT[0] == 0x04 && CT[1] == 0x00)
		{
			nfc_work.nfc_param[nfc_cs_idx].idA[4] = IDA[0];
			nfc_work.nfc_param[nfc_cs_idx].idA[5] = IDA[1];
			nfc_work.nfc_param[nfc_cs_idx].idA[6] = IDA[2];
			nfc_work.nfc_param[nfc_cs_idx].idA[7] = IDA[3];
		}
		else if(CT[0] == 0x44 && CT[1] == 0x00){
			nfc_work.nfc_param[nfc_cs_idx].idA[1] = IDA[1];
			nfc_work.nfc_param[nfc_cs_idx].idA[2] = IDA[2];
			nfc_work.nfc_param[nfc_cs_idx].idA[3] = IDA[3];
			nfc_work.nfc_param[nfc_cs_idx].idA[4] = IDA[5];
			nfc_work.nfc_param[nfc_cs_idx].idA[5] = IDA[6];
			nfc_work.nfc_param[nfc_cs_idx].idA[6] = IDA[7];
			nfc_work.nfc_param[nfc_cs_idx].idA[7] = IDA[8];
		}
	}
	
	return stat;
}

/*******************************************************************************
  * @函数名称 user_nfc_task
  * @函数说明 任务执行程序
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
static void prvUser_nfc_upload_card_stat(uint8_t idx, bool stat, unsigned char *card)
{
	PRINT("No.%d read card = %s,%02X%02X%02X%02X\n",idx, (stat == true)?"true":"false",
			card[4], card[5], card[6], card[7]);
	if(xUpload_card_stat != NULL)
	{
		xUpload_card_stat(idx, stat, card);
	}
}

/*******************************************************************************
  * @函数名称 nfc_rst_enable
  * @函数说明 复位开始
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
static void nfc_rst_enable(void)
{
  	NFC_01_RST_ENABLE;
	NFC_02_RST_ENABLE;
	NFC_03_RST_ENABLE;
	NFC_04_RST_ENABLE;
	NFC_05_RST_ENABLE;
}

/*******************************************************************************
  * @函数名称 nfc_rst_disable
  * @函数说明 复位结束
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
static void nfc_rst_disable(void)
{
	NFC_01_RST_DISABLE;
	NFC_02_RST_DISABLE;
	NFC_03_RST_DISABLE;
	NFC_04_RST_DISABLE;
	NFC_05_RST_DISABLE;
}

/*******************************************************************************
  * @函数名称 user_nfc_task
  * @函数说明 任务执行程序
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
static void user_nfc_task(void)
{
	bool stat = false;
	if(nfc_work.nfc_delay_count > 0)
	{
		nfc_work.nfc_delay_count--;
	}
	else{
		switch(nfc_work.work_type)
		{
			case NFC_TYPE_RST_START:{
				PRINT("NFC_TYPE_RST_START\n");
				nfc_rst_disable();
				Delay_Ms(2);
				nfc_rst_enable();
				Delay_Ms(2);
				nfc_rst_disable();
				nfc_work.nfc_delay_count = 2;
				nfc_work.work_type = NFC_TYPE_RST_END;
			}break;
			case NFC_TYPE_RST_END:{
				PRINT("NFC_TYPE_RST_END\n");
				nfc_cs_idx = 0;
				nfc_work.nfc_delay_count = 2;
				nfc_work.work_type = NFC_TYPE_INIT;
			}break;
			case NFC_TYPE_INIT:{
				uint8_t id = Read_Reg(VersionReg);
				PRINT("No.%d NFC_TYPE_INIT,id=0x%02X\n", nfc_cs_idx, id);
				Lpcd_Init_Register();	                /* 扩展寄存器初始化 */
				nfc_work.nfc_param[nfc_cs_idx].init_stat = true;
				nfc_work.nfc_delay_count = 2;
				nfc_cs_idx++;
				if(nfc_cs_idx >= USER_NFC_MAX_COUNT)
				{
					nfc_cs_idx = 0;
					nfc_work.work_type = NFC_TYPE_CARD_CHECK;
				}
			}break;
			case NFC_TYPE_CARD_CHECK:{
				stat = Card_Check();
				nfc_work.nfc_delay_count = 10;
				
				if(stat == true)
				{
					nfc_work.nfc_param[nfc_cs_idx].loss_delay = ID_LOSE_DELAY_COUNT;
					if(nfc_work.nfc_param[nfc_cs_idx].card_stat != NFC_CARD_IN)
					{
						nfc_work.nfc_param[nfc_cs_idx].card_stat = NFC_CARD_IN;
						prvUser_nfc_upload_card_stat(nfc_cs_idx, true, nfc_work.nfc_param[nfc_cs_idx].idA);
					}
				}
				else{
					if(nfc_work.nfc_param[nfc_cs_idx].loss_delay > 0)
					{
						nfc_work.nfc_param[nfc_cs_idx].loss_delay--;
					}
					else{
						memset(nfc_work.nfc_param[nfc_cs_idx].idA, 0, 8);
						if(nfc_work.nfc_param[nfc_cs_idx].card_stat != NFC_CARD_NO)
						{
							nfc_work.nfc_param[nfc_cs_idx].card_stat = NFC_CARD_NO;
							prvUser_nfc_upload_card_stat(nfc_cs_idx, false, nfc_work.nfc_param[nfc_cs_idx].idA);
						}
					}
				}
				nfc_cs_idx++;
				if(nfc_cs_idx >= USER_NFC_MAX_COUNT)
				{
					nfc_cs_idx = 0;
					nfc_work.work_type = NFC_TYPE_CARD_CHECK;
				}
			}break;
			default:
				break;
		}
	}
}

/*******************************************************************************
  * @函数名称   vUser_nfc_set_upload_key_stat_func
  * @函数说明   设置上报NFC读卡信息的回调函数
  * @输入参数  	func：函数指针
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void vUser_nfc_set_upload_key_stat_func(vUser_nfc_upload_card_stat_func func)
{
	xUpload_card_stat = func;
}

/*******************************************************************************
  * @函数名称   user_nfc_task_process_event
  * @函数说明   task的event处理回调函数,需要在注册task时候,传进去
  * @输入参数  	task_id：任务ID
               events：事件
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
static uint16_t user_nfc_task_process_event(uint8_t task_id, uint16_t events)
{
    //event 处理
    if(events & (1 << NFC_QUEUE_TIME))
    {
		user_nfc_task();
        return (events ^ (1 << NFC_QUEUE_TIME)); //异或的方式清除该事件运行标志，并返回未运行的事件标志
    }
    return 0;
}

/*******************************************************************************
  * @函数名称   vUser_nfc_task_start
  * @函数说明   NFC任务开始
  * @输入参数  	无
  * @输出参数   无
  * @返回参数   无
*******************************************************************************/
void vUser_nfc_task_start(void)
{
    bStatus_t stat = tmos_start_reload_task(user_nfc_task_id, (1 << NFC_QUEUE_TIME), MS1_TO_SYSTEM_TIME(USER_NFC_INTERVAL));
	// PRINT("NFC task start=%d\n", stat);
}

/*******************************************************************************
  * @函数名称 vUser_nfc_init
  * @函数说明 初始化
  * @输入参数 无
  * @输出参数 无
  * @返回参数 无
  *****************************************************************************/
void vUser_nfc_init(void)
{
	user_nfc_gpio_init();
	user_spi_Init();

	user_nfc_task_id  = TMOS_ProcessEventRegister(user_nfc_task_process_event);
    PRINT("user_nfc_task_id=%d\n", user_nfc_task_id);
}
