/*****************************************************************************
* File Name          : bc45_cli.c
* Author             : CrystalSu
* Version            : V1.0.0.0
* Date               : Feb 12, 2020
* Description        : This file can be modified for using with any project.
******************************************************************************/

#include <string.h>
#include "main.h"
#include "gpio.h"
#include "gptm0.h"
#include "delay.h"

#include "bc45_cli.h"
#include "BC45_Function.h"
#include "BC45_Chip_Function.h"
#include "Systick_For_Timeout.h"
#include "BC45_Board_ASIC_Category.h"

/*Constant register address of BC45 on page 0*/
const uint8_t reg_sec0[57] =
{
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
	0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11,
	0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A,
	0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 
	0x23, 0x24, 0x25, 0x26, 0x27, 0x29, 0x2A, 0x2B, 
	0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 
	0x34, 0x35, 0x36, 0x37, 0x39, 0x3A, 0x3C, 0x3E, 
	0x3F
};

/*Constant register address of BC45 on page 1*/
const uint8_t reg_sec1[19] =
{
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09,
	0x0B, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
	0x2E, 0x2F, 0x37
};

tISO_TagTypeDef tag_type;
tMCU_LowPwrTypeDef lowpwr = SLEEPMODE;
tBC45_WAKEUP_TIMER_PROPERTY Timer_WKUP;
tBC45_CD_TUNING Tunning_Thereshold;
uint8_t runningLoop = 0;
uint8_t typeMask = 0x7;
uint8_t waittingIRQ = 0;
uint8_t stepCalibration = 2;

uint8_t Data_Resp[64];
uint8_t Data_Trans[64];
uint16_t Len_Resp;
uint16_t Len_Trans;
uint8_t Resp;
//uint8_t ISO15693_Speed = 0x11;//Default is 0x00, 0x11 for 26.48 Kbps
nfc_config_t nfca0;
nfc_config_t nfcb0;
nfc_config_t nfca1;
nfc_config_t nfcb1;

/**
 *  Definition of BC45 shell commands
 */
shell_cmds bc45_shell_cmds =
{
	//crystal
  //12,
	13,
  {
	//1.help command
    { "help",
	  "List available commands",
	  bc45_shell_command_help },

	//2.info command
	{ "info",
	  "Print out device informations",
	  bc45_shell_command_info },

	//3.Read/Write register Command
	{"reg",
	 "Register command for reading and writing register on BC45",
	 bc45_shell_command_register},

	//4.RF command
	 {"rf",
	  "Control RF field of reader",
	 bc45_shell_command_rf},

	//5.CD mode for BC45
	{ "cd",
	  "Command which relates with CD mode of BC45",
	  bc45_shell_command_cdmode },

	//6.ISO14443A command
	{"a",
	 "Use to send command for ISO14443A tag type",
	 bc45_shell_command_nfcA},

	//7.ISO14443B command
	{"b",
	 "Use to send command for ISO14443B tag type",
	 bc45_shell_command_nfcB},

	//8.ISO15693 command
	{"v",
	 "Use to send command for ISO15693 tag type",
	 bc45_shell_command_nfcV},

	//9.Scan tag command by following NFC Forum
	 {"scan",
	  "Read Tag's UID (ISO1443A, ISO14443B, ISO15693)",
	  bc45_shell_command_polling_loop},

	//10.MIFARE tag type command
	{"mifare",
	 "Combo command for reading/writing tag mifare type",
	 bc45_shell_command_mifare},

	//11.Tag 2 Type command
	{"t2t",
	 "Combo command for reading/writing tag 2 type",
	 bc45_shell_command_t2t},

	//12.BC45 Reset
	{"reset",
	 "BC45 Reset",
	 bc45_shell_command_reset},
	
	 //13. crystal
	{"setup",
	 "Setup Configuration Register",
		bc45_shell_command_setup},
	}
		
};


void CommandResultAlert(uint8_t status)
{
	uint8_t count;
	
	if(status == _SUCCESS_)
	{		
		GPTM0_CH2_SetOnduty(50);
		Delay_ms(100);
		GPTM0_CH2_SetOnduty(0);
		Delay_ms(100);
		for(count = 0; count < 2; count++)
		{
			LED_GREEN_ON();
			Delay(100);
			LED_GREEN_OFF();
			Delay(100);
		}
  }else
	{
		GPTM0_CH2_SetOnduty(80);
		Delay_ms(500);
		GPTM0_CH2_SetOnduty(0);
		Delay_ms(100);

		for(count = 0; count < 2; count++)
		{
			LED_RED_ON();
			Delay(100);
			LED_RED_OFF();
			Delay(100);
		}
	}	
}

/**
 *  configuration setup command for list available commands
 */
//crystal
int bc45_shell_command_setup(shell_cmd_args * args)
{
	nfc_config_t *nfc;
	
	uint8_t tmpLen;
	uint8_t Address;
	uint8_t Value;
	uint8_t status = FAILED;
	
  /* check arguments */
	if((args->count >4)) goto Invalid;

	else
	{
		tmpLen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-clear", tmpLen, 6) == 0)
		{
			nfca0.nIdx = nfca1.nIdx = nfcb0.nIdx = nfcb1.nIdx = 0;
			htk_UART_Transmit((uint8_t *)"OK\r\n",4);
			return 0;
		}
		if(shell_str_cmp(args->args[0].val, "-a", tmpLen, 2) == 0)
		{
			tmpLen = shell_str_len(args->args[1].val);
			/* Select sector 0 */
			if(shell_str_cmp(args->args[1].val, "-s0", tmpLen, 3) == 0)
				nfc = &nfca0;
			else if(shell_str_cmp(args->args[1].val, "-s1", tmpLen, 3) == 0)
				nfc = & nfca1;
			else goto Invalid;
		}else if(shell_str_cmp(args->args[0].val, "-b", tmpLen, 2) == 0)
		{
			tmpLen = shell_str_len(args->args[1].val);
			/* Select sector 0 */
			if(shell_str_cmp(args->args[1].val, "-s0", tmpLen, 3) == 0)
				nfc = &nfcb0;
			else if(shell_str_cmp(args->args[1].val, "-s1", tmpLen, 3) == 0)
				nfc = & nfcb1;
			else goto Invalid;
		}else goto Invalid;
		
		tmpLen = shell_str_len(args->args[2].val);
		status = customParseHEX((uint8_t *)args->args[2].val, tmpLen, &Address);
		if(status != 0x00) goto Invalid;
		tmpLen = shell_str_len(args->args[3].val);
		status = customParseHEX((uint8_t *)args->args[3].val, tmpLen, &Value);
		if(status != 0x00) goto Invalid;
		nfc->addr[nfc->nIdx] = Address;
		nfc->data[nfc->nIdx] = Value;
		nfc->nIdx++;
		htk_UART_Transmit((uint8_t *)"OK\r\n",4);
		return 0;
	}
	Invalid:
	htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
						"\r\nERROR\r\n", 27);
	return 0;
}


/**
 *  HELP command for list available commands
 */
int bc45_shell_command_help(shell_cmd_args * args)
{
  uint8_t i;
  uint8_t tmpLen = 0;

	for(i=0; i<bc45_shell_cmds.count; i++)
	{
		htk_UART_Transmit( (uint8_t *)"\r\nCMD: ", 7);
		// Print out Command
		tmpLen = shell_str_len((char *)bc45_shell_cmds.cmds[i].cmd);
		htk_UART_Transmit( (uint8_t *)bc45_shell_cmds.cmds[i].cmd, tmpLen);

		if(tmpLen == 4) 
		{
			htk_UART_Transmit( (uint8_t *)",  DESC: ", 9);
		}
		else if(tmpLen ==5)
		{
			htk_UART_Transmit( (uint8_t*)", DESC: ", 8);
		}
		else if(tmpLen == 6)
		{
			htk_UART_Transmit((uint8_t *)",DESC: ", 7);
		}
		else if(tmpLen == 2)
		{
			htk_UART_Transmit((uint8_t *)",    DESC: ", 11);
		}
		else if(tmpLen == 3)
		{
			htk_UART_Transmit((uint8_t *)",   DESC: ", 10);
		}
		else
		{
			htk_UART_Transmit((uint8_t *)",     DESC: ", 12);
		}

		/* Print out Description */
		tmpLen = shell_str_len((char *)bc45_shell_cmds.cmds[i].desc);
		htk_UART_Transmit((uint8_t *)bc45_shell_cmds.cmds[i].desc, tmpLen);
	}

	htk_UART_Transmit((uint8_t*)"\r\n\r\nUse <command> -h for showing the argument of each command"
								"\r\nOK\r\n", 67);

	return 0;
}

/**
 *  INFO command for showing hardware and firmware version
 */
int bc45_shell_command_info(shell_cmd_args * args)
{
	uint8_t dataReg;
	uint8_t tmpBuffer[4] = {0};
	char msg[64];

	/*Show basic information*/
	htk_UART_Transmit(
	(uint8_t*)"\r\nMCU: HT32F52241"
			  "\r\nBC45 Revision: ", 34);

	htk_SPI_writeSingleRegister(0x00, 0x01);
	htk_SPI_readSingleRegister(0x0F, &dataReg);
	htk_SPI_writeSingleRegister(0x00, 0x00);

	dataToHex(&tmpBuffer[0], dataReg);
	htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
	//Check BC45 Revision
	if(dataReg == BC45_RevB)
	{
		htk_UART_Transmit((uint8_t*)" (BC45 RevB)", 12);
	}
	else
	{
		htk_UART_Transmit((uint8_t*)" (BC45 RevA)", 12);
	}
	strcpy(msg,"\r\nFirmware version: 2.0.0.0\r\n");
	htk_UART_Transmit((uint8_t*)msg, strlen(msg));

  return 0;
}

/**
 *  Register command for reading and writing register on BC45 reader
 */
int bc45_shell_command_register(shell_cmd_args * args)
{
	uint8_t tmpData;
	uint8_t tmpLen;
	uint8_t rdAddress;
	uint8_t wrAddress;
	uint8_t wrValue;
	uint8_t tmpBuffer[3];
	uint8_t status = FAILED;
	uint8_t i = 0;

	  /* check arguments */
	if((args->count > 4)||(args->count == 0))
	{
		htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
							"\r\nERROR\r\n", 28);
	}
	/* Read/Write a register with sector specification*/
	else if(args->count >= 3)
	{
		tmpLen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-rd", tmpLen, 3) == 0)
		{
			tmpLen = shell_str_len(args->args[1].val);
			/* Select sector 0 */
			if(shell_str_cmp(args->args[1].val, "-s0", tmpLen, 3) == 0)
			{
				tmpLen = shell_str_len(args->args[2].val);
				status = customParseHEX((uint8_t *)args->args[2].val, tmpLen, &rdAddress);
				if(status == 0x00)
				{
					 /* Check page 0 */
					 for(i = 0; i < sizeof(reg_sec0); i++)
					 {
						 if(rdAddress == reg_sec0[i])
						 {
							 htk_SPI_writeSingleRegister( 0x00, 0x00);
							 htk_UART_Transmit( (uint8_t*)"\r\nSEC[HEX]: 00", 14);
							 /* Read a given address on page 0 */
							 htk_UART_Transmit( (uint8_t *)"\r\nADDR[HEX]: ", 13);
							 dataToHex(&tmpBuffer[0], rdAddress);
							 htk_UART_Transmit( (uint8_t *)tmpBuffer, 2);
							 htk_SPI_readSingleRegister(rdAddress, &tmpData);
							 dataToHex(&tmpBuffer[0], tmpData);
							 htk_UART_Transmit( (uint8_t *)", VAL[HEX]:", 11);
							 htk_UART_Transmit( (uint8_t *)tmpBuffer, 2);
							 htk_UART_Transmit( (uint8_t *)"\r\nOK\r\n", 6);
							 status = _SUCCESS_;
							 break;
						 }
					 }
					 /* Not found a given register on page 0 */
					 if(i == sizeof(reg_sec0))
					 {
						 htk_UART_Transmit(
								 (uint8_t*)"\r\nUnavailable Address"
								 "\r\nERROR\r\n", 30);
						 status = FAILED;
					 }
				}
			}
			/* Select Sector 1 */
			else if(shell_str_cmp(args->args[1].val, "-s1", tmpLen, 3) == 0)
			{
				tmpLen = shell_str_len(args->args[2].val);
				status = customParseHEX((uint8_t *)args->args[2].val, tmpLen, &rdAddress);
				if(status == 0x00)
				{
				 /* Check page 1 */
				 for(i = 0; i < sizeof(reg_sec1); i++)
				 {
					 if(rdAddress == reg_sec1[i])
					 {
						 htk_SPI_writeSingleRegister( 0x00, 0x01);
						 htk_UART_Transmit((uint8_t*)"\r\nSEC[HEX]: 01", 14);
						 /* Read a given address on page 1 */
						 htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
						 dataToHex(&tmpBuffer[0], rdAddress);
						 htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
						 htk_SPI_readSingleRegister( rdAddress, &tmpData);
						 dataToHex(&tmpBuffer[0], tmpData);
						 htk_UART_Transmit((uint8_t *)", VAL[HEX]:", 11);
						 htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
						 htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
						 htk_SPI_writeSingleRegister( 0x00, 0x00);
						 status = _SUCCESS_;
						 break;
					 }
				 }

				 /* Not found a given register on page 1 */
				 if(i == sizeof(reg_sec1))
				 {
					 htk_UART_Transmit(
							 (uint8_t*)"\r\nUnavailable Address"
							 "\r\nERROR\r\n", 30);
					 status = FAILED;
				 }
				}
			}
			else
			{
				htk_UART_Transmit((uint8_t *)"\r\nInvalid sector"
									"\r\nERROR\r\n", 25);
				status = FAILED;
			}
		}
		else if(shell_str_cmp(args->args[0].val, "-wr", tmpLen, 3) == 0)
		{
			tmpLen = shell_str_len(args->args[1].val);
			/* Select sector 0 */
			if(shell_str_cmp(args->args[1].val, "-s0", tmpLen, 3) == 0)
			{
				tmpLen = shell_str_len(args->args[2].val);
				status = customParseHEX((uint8_t *)args->args[2].val, tmpLen, &wrAddress);
				if(status == 0x00)
				{
					/* Check page 0 */
					for(i = 0; i < sizeof(reg_sec0); i++)
					{
						if(wrAddress == reg_sec0[i])
						{
							tmpLen = shell_str_len(args->args[3].val);
							status = customParseHEX((uint8_t *)args->args[3].val, tmpLen, &wrValue);

							/*Select Page 0*/
							htk_SPI_writeSingleRegister(0x00, 0x00);
							/* Write value to the given address */
							htk_SPI_writeSingleRegister(wrAddress, wrValue);
							htk_UART_Transmit((uint8_t*)"\r\nSEC[HEX]: 00", 14);
							htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
							dataToHex(&tmpBuffer[0], wrAddress);
							htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
							htk_UART_Transmit((uint8_t *)", WR[HEX]:", 10);
							dataToHex(&tmpBuffer[0], wrValue);
							htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
							htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
							status = _SUCCESS_;
							break;
						}
					}

					/* Not found a given address on page 0 */
					if(i == sizeof(reg_sec0))
					{
						htk_UART_Transmit(
						(uint8_t*)"\r\nUnavailable Address"
								  "\r\nERROR\r\n", 30);
						status = FAILED;
					}
				}
			}
			/* Select Sector 1 */
			else if(shell_str_cmp(args->args[1].val, "-s1", tmpLen, 3) == 0)
			{
				tmpLen = shell_str_len(args->args[2].val);
				status = customParseHEX((uint8_t *)args->args[2].val, tmpLen, &wrAddress);
				if(status == 0x00)
				{
					/* Check page 1 */
					for(i = 0; i < sizeof(reg_sec1); i++)
					{
						if(wrAddress == reg_sec1[i])
						{
							tmpLen = shell_str_len(args->args[3].val);
							status = customParseHEX((uint8_t *)args->args[3].val, tmpLen, &wrValue);

							/* Select Page 1*/
							htk_SPI_writeSingleRegister(0x00, 0x01);
							/* Write value to the given address */
							htk_SPI_writeSingleRegister(wrAddress, wrValue);
							htk_UART_Transmit((uint8_t*)"\r\nSEC[HEX]: 01", 14);
							htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
							dataToHex(&tmpBuffer[0], wrAddress);
							htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
							htk_UART_Transmit((uint8_t *)", WR[HEX]:", 10);
							dataToHex(&tmpBuffer[0], wrValue);
							htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
							htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);

							/* Set sector back to sector 0*/
							htk_SPI_writeSingleRegister(0x00, 0x00);
							
							status = _SUCCESS_;
							break;
						}
					}

					/* Not found a given address on page 1 */
					if(i == sizeof(reg_sec1))
					{
						htk_UART_Transmit(
						(uint8_t*)"\r\nUnavailable Address"
								  "\r\nERROR\r\n", 30);
						status = FAILED;
					}
				}
			}
			else
			{
				htk_UART_Transmit((uint8_t *)"\r\nInvalid sector"
									"\r\nERROR\r\n", 25);
				status = FAILED;
			}
		}
		else
		{
			htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
								"\r\nERROR\r\n", 27);
			status = FAILED;
		}
	}
	/* Read/Write a register without sector specification*/
	else if(args->count >= 2)
	{
		tmpLen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-rd", tmpLen, 3) == 0)
		{
			tmpLen = shell_str_len(args->args[1].val);
			if(shell_str_cmp(args->args[1].val, "-all", tmpLen, 4) == 0)
			{
				  /* Read all register on page 0 */
				  htk_SPI_writeSingleRegister(0x00, 0x00);
				  htk_UART_Transmit((uint8_t*)"\r\nSEC[HEX]: 00", 14);

				  for(i = 0; i < sizeof(reg_sec0); i++)
				  {
					/*Assign register address*/
					htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
					dataToHex(&tmpBuffer[0], reg_sec0[i]);
					htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
					htk_SPI_readSingleRegister(reg_sec0[i], &tmpData);

					/*Show a value from the register*/
					dataToHex(&tmpBuffer[0], tmpData);
					htk_UART_Transmit((uint8_t *)", VAL[HEX]:", 11);
					htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
				  }
				  htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);

				  /* Read all register on page 1 */
				  htk_SPI_writeSingleRegister( 0x00, 0x01);
				  htk_UART_Transmit((uint8_t*)"\r\nSEC[HEX]: 01", 14);

				  for(i = 0; i < sizeof(reg_sec1); i++)
				  {
					/*Assign register address*/
					htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
					dataToHex(&tmpBuffer[0], reg_sec1[i]);
					htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
					htk_SPI_readSingleRegister(reg_sec1[i], &tmpData);

					/*Show a value from the register*/
					dataToHex(&tmpBuffer[0], tmpData);
					htk_UART_Transmit((uint8_t *)", VAL[HEX]:", 11);
					htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
				  }
				  htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);

				  /*Set back to register page 0*/
				  htk_SPI_writeSingleRegister(0x00, 0x00);
					
					status = _SUCCESS_;
			}
			else
			{
				status = customParseHEX((uint8_t *)args->args[1].val, tmpLen, &rdAddress);
				if(status == 0x00)
				{
					 /* Check page 0 */
					 for(i = 0; i < sizeof(reg_sec0); i++)
					 {
						  if(rdAddress == reg_sec0[i])
						  {
							  htk_SPI_writeSingleRegister(0x00, 0x00);
							  htk_UART_Transmit((uint8_t*)"\r\nSEC[HEX]: 00", 14);
							  htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
							  dataToHex(&tmpBuffer[0], rdAddress);
							  htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
							  htk_SPI_readSingleRegister(rdAddress, &tmpData);
							  dataToHex(&tmpBuffer[0], tmpData);
							  htk_UART_Transmit((uint8_t *)", VAL[HEX]:", 11);
							  htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
							  htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
								status = _SUCCESS_;
							  break;
						  }
					}

					/*The address is not on page 0*/
					if(i == sizeof(reg_sec0))
					{
					 htk_UART_Transmit(
					 (uint8_t*)"\r\nUnavailable Address"
								"\r\nERROR\r\n", 30 );
						status = FAILED;
					}
				}
				else
				{
					htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
										"\r\nERROR\r\n", 27);
					status = FAILED;
				}
			}
		}
		else if(shell_str_cmp(args->args[0].val, "-wr", tmpLen, 3) == 0)
		{
			tmpLen = shell_str_len(args->args[1].val);
			if(shell_str_cmp(args->args[1].val, "-default", tmpLen, 8) == 0)
			{
				//Sector 0
				htk_SPI_writeSingleRegister(0x00, 0x00);
				htk_SPI_writeSingleRegister(0x06, 0x00);
				htk_SPI_writeSingleRegister(0x09, 0x00);
				htk_SPI_writeSingleRegister(0x11, 0x18);
				htk_SPI_writeSingleRegister(0x12, 0x3F);
				htk_SPI_writeSingleRegister(0x13, 0x28);
				htk_SPI_writeSingleRegister(0x14, 0x19);
				htk_SPI_writeSingleRegister(0x15, 0x0F);
				htk_SPI_writeSingleRegister(0x16, 0x0F);
				htk_SPI_writeSingleRegister(0x17, 0x3B);

				htk_SPI_writeSingleRegister(0x19, 0x6B);
				htk_SPI_writeSingleRegister(0x1A, 0x08);
				htk_SPI_writeSingleRegister(0x1B, 0x3D);
				htk_SPI_writeSingleRegister(0x1C, 0xAA);
				htk_SPI_writeSingleRegister(0x1D, 0x04);
				//test
				htk_SPI_writeSingleRegister(0x1E, 0x41);
				//htk_SPI_writeSingleRegister(0x1E, 0x43);
				htk_SPI_writeSingleRegister(0x1F, 0xF0);

				htk_SPI_writeSingleRegister(0x20, 0x05);
				htk_SPI_writeSingleRegister(0x21, 0x06);
				htk_SPI_writeSingleRegister(0x22, 0x03);
				htk_SPI_writeSingleRegister(0x23, 0x63);
				htk_SPI_writeSingleRegister(0x24, 0x63);
				htk_SPI_writeSingleRegister(0x25, 0x23);

				htk_SPI_writeSingleRegister(0x29, 0x08);
				htk_SPI_writeSingleRegister(0x2A, 0x07);
				htk_SPI_writeSingleRegister(0x2B, 0x06);
				htk_SPI_writeSingleRegister(0x2C, 0x0A);
				htk_SPI_writeSingleRegister(0x2D, 0x19);
				htk_SPI_writeSingleRegister(0x2E, 0x20);
				htk_SPI_writeSingleRegister(0x2F, 0x06);

				htk_SPI_writeSingleRegister(0x30, 0x40);
				htk_SPI_writeSingleRegister(0x31, 0x10);
				htk_SPI_writeSingleRegister(0x32, 0x20);
				htk_SPI_writeSingleRegister(0x33, 0x20);
				htk_SPI_writeSingleRegister(0x34, 0x40);
				htk_SPI_writeSingleRegister(0x35, 0x80);
				htk_SPI_writeSingleRegister(0x36, 0x40);
				htk_SPI_writeSingleRegister(0x37, 0x80);

				htk_SPI_writeSingleRegister(0x39, 0x06);
				htk_SPI_writeSingleRegister(0x3A, 0x00);
				htk_SPI_writeSingleRegister(0x3B, 0xF0);
				htk_SPI_writeSingleRegister(0x3C, 0x88);
				htk_SPI_writeSingleRegister(0x3D, 0xF0);
				htk_SPI_writeSingleRegister(0x3E, 0xB8);
				htk_SPI_writeSingleRegister(0x3F, 0x00);

				//Sector 1
				htk_SPI_writeSingleRegister(0x00, 0x01);
				htk_SPI_writeSingleRegister(0x02, 0x00);
				htk_SPI_writeSingleRegister(0x03, 0x00);
				htk_SPI_writeSingleRegister(0x04, 0x00);
				htk_SPI_writeSingleRegister(0x05, 0x00);
				htk_SPI_writeSingleRegister(0x08, 0x00);
				htk_SPI_writeSingleRegister(0x09, 0x00);
				htk_SPI_writeSingleRegister(0x0B, 0x00);
				htk_SPI_writeSingleRegister(0x10, 0x00);
				htk_SPI_writeSingleRegister(0x11, 0x00);
				htk_SPI_writeSingleRegister(0x12, 0x10);
				htk_SPI_writeSingleRegister(0x13, 0x10);
				htk_SPI_writeSingleRegister(0x2E, 0x19);
				htk_SPI_writeSingleRegister(0x2F, 0x45);

				htk_SPI_writeSingleRegister(0x00, 0x00);

				htk_UART_Transmit(
				 (uint8_t*)"\r\nReset all register"
							"\r\nOK\r\n", 26 );
				status = _SUCCESS_;
			}
			else
			{
				/* Convert Address */
				status = customParseHEX((uint8_t *)args->args[1].val, tmpLen, &wrAddress);
				if(status == 0x00)
				{
					/* Check page 0 */
					for(i = 0; i < sizeof(reg_sec0); i++)
					{
						if(wrAddress == reg_sec0[i])
						{
							tmpLen = shell_str_len(args->args[2].val);
							/* Convert Value */
							status = customParseHEX((uint8_t *)args->args[2].val, tmpLen, &wrValue);
							if(status == 0x00)
							{
								/* Select Page 0 */
								htk_SPI_writeSingleRegister( 0x00, 0x00);
								/* Write Value to the given address */
								htk_SPI_writeSingleRegister(wrAddress, wrValue);
								htk_UART_Transmit((uint8_t*)"\r\nSEC[HEX]: 00", 14);
								htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
								dataToHex(&tmpBuffer[0], wrAddress);
								htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
								htk_UART_Transmit((uint8_t *)", WR[HEX]:", 10);
								dataToHex(&tmpBuffer[0], wrValue);
								htk_UART_Transmit((uint8_t *)tmpBuffer, 2);
								htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
								status = _SUCCESS_;
							}
							else
							{
								htk_UART_Transmit(
								(uint8_t *)"\r\nInvalid value"
										   "\r\nERROR\r\n", 24 );
								status = FAILED;
							}
							break;
						}
					}

					/* Not found a given address on page 0 */
					if(i == sizeof(reg_sec0))
					{
						htk_UART_Transmit(
						(uint8_t*)"\r\nUnavailable Address"
								  "\r\nERROR\r\n", 30 );
						status = FAILED;
					}
				}
				else
				{
					htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
										"\r\nERROR\r\n", 27);
					status = FAILED;
				}
			}
		}
		else
		{
			htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
								"\r\nERROR\r\n", 27);
			status = FAILED;
		}		
	}
	else
	{
		tmpLen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-h", tmpLen, 2) == 0)
		{
			/*Show help command*/
			htk_UART_Transmit(
			(uint8_t *)"\r\nUsage: reg command for read/write any register on BC45 reader"
					   "\r\nRead register commands"
			 	  	   "\r\n       reg -rd <sector register -s0 or -s1> <address in hex>"
					   "\r\n       reg -rd <address in hex>"
			    	   "\r\n       reg -rd -all"
				  	   "\r\n"
					   "\r\nWrite register commands"
			           "\r\n       reg -wr <sector register -s0 or -s1> <address in hex> <data in hex>"
					   "\r\n       reg -wr <address in hex> <data in hex>"
					   "\r\n       reg -wr -default : This command will reset all register to default"
					   "\r\n"
					   "\r\nEx > read 1A"
				       "\r\n     SEC[HEX]: 00"
				       "\r\n     ADDR[HEX]: 1A, VAL[HEX]: 08"
					   "\r\n     OK\r\n"
					   "\r\nEx > read -s1 1A"
					   "\r\n     SEC[HEX]: 01"
					   "\r\n     ADDR[HEX]: 2E, VAL[HEX]: 19"
					   "\r\n     OK\r\n", 590 );
		}
		else
		{
			htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
								"\r\nERROR\r\n", 27);
		}
	}
  CommandResultAlert(status);
	return 0;
}


/*
 * RF field control
 */
int bc45_shell_command_rf(shell_cmd_args * args)
{
	uint8_t tmplen;

	if(args->count != 1)
	{
		htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
							"\r\nERROR\r\n", 27);
	}
	else
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-h", tmplen, 2) == 0)
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUsage: rf command to control RF field of reader"
					   "\r\n       rf -on : Turn on RF field"
					   "\r\n       rf -off : Turn off RF field"
					   "\r\n       rf -reset : Reset RF field by turn off RF 6 ms then turn on RF"
					   "\r\n"
					   "\r\nEx > rf -on"
				       "\r\n     Operating complete"
					   "\r\n     OK\r\n", 241);

			return 0;
		}
		else if(shell_str_cmp(args->args[0].val, "-on", tmplen, 3) == 0)
		{
			BC45_RF_OnOff(RFON);
		}
		else if(shell_str_cmp(args->args[0].val, "-off", tmplen, 4) == 0)
		{
			BC45_RF_OnOff(RFOFF);
		}
		else if(shell_str_cmp(args->args[0].val, "-reset", tmplen, 6) == 0)
		{
			BC45_RF_OnOff(RFRESET);
		}
		else
		{
			htk_UART_Transmit((uint8_t *)"\r\nInvalid argument"
								"\r\nERROR\r\n", 27);
			return 0;
		}

		//htk_UART_Transmit((uint8_t *)"\r\nOperating Complete"
		//	       	   	   	   	     "\r\nOK\r\n", 26);
		htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
	}
	CommandResultAlert(Resp);

	return 0;
}


#define _CD_	1
void ScanUID_LowPwr(void)
{
	uint8_t reg_value;
	uint8_t status;
	
#if _CD_
	/*Enable CDIRQ on BC45*/
	Interrupt_EnableBC45(CDIRQ_Mask);
	/*Start wkup timer*/
	TimerWKUP_Start();
	/*Enter to cd mode with go active*/
	status = BC45_Mode_Selection(BC45_WKUP_CD_MODE);
	if(status == _SUCCESS_)
	{
		switch(lowpwr)
		{
			case SLEEPMODE:
				htk_UART_Transmit((uint8_t*)"Sleep Mode\r\n", 18);
				GotoSleepMode();
				reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
				break;
			case STOPMODE:
				htk_UART_Transmit((uint8_t*)"Deep Sleep1 Mode\r\n", 18);
				GotoStopMode();
				reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
				break;
			default: // Not run into low power mode
				htk_UART_Transmit((uint8_t*)"Normal Mode\r\n", 13);

			  while( BC45_IRQ_PIN() == 0 && runningLoop==1)
				{
					Delay(20);
				}

				reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);

				break;
		}

		/*Check Interrupt IRQ source */
		if(reg_value == CDIRQ_Mask)
		{
			
			/*Waiting until CD IRQ is cleared*/
			while(reg_value == CDIRQ_Mask)
			{
				BC45_Disable_And_ClearFlag_IRQ( ALL_IRQ_SOURCE | CDIRQ_Mask ) ;
				htk_SPI_readSingleRegister(InterruptIRQ, &reg_value);
				reg_value &= CDIRQ_Mask;
			}
			//htk_UART_Transmit((uint8_t *)"\r\nCD IRQ source\r\n", 17);
			/*Exit from CD mode*/
			BC45_CDMode_Exit();
#endif
			
			/*Scan a tag*/			
			if(typeMask & 0x01)
			{
				BC45_ConfigurationNoOfffield(CONFIG_14443A);
				if(ScanUID_ISO14443ATagType()==_SUCCESS_)
					return;

			}

			if(typeMask & 0x02)
			{
				BC45_ConfigurationNoOfffield(CONFIG_14443B);
				if(ScanUID_ISO14443BTagType()==_SUCCESS_)
					return;				
			}
			
			if(typeMask & 0x04)
			{				

				BC45_ConfigurationNoOfffield(CONFIG_15693);
				if(ScanUID_ISO15693TagType()==_SUCCESS_)
					return;

			}
			BC45_RF_OnOff(RFRESET);
			
#if _CD_		
		}
		else
		{
			/*Clear and disable all interrupt*/
			BC45_Disable_And_ClearFlag_IRQ( ALL_IRQ_SOURCE | CDIRQ_Mask ) ;
			/*Exit from CD mode*/
			BC45_CDMode_Exit();
			//htk_UART_Transmit((uint8_t*)"\r\nInterrupt is not CDIRQ", 24);
		}
	}
	else
	{
		htk_UART_Transmit((uint8_t*)"WKUP CD Mode FAILED\r\n", 21);
	}
#endif
}


/**
 *  Card Detect command for entering to Card detect mode
 *  and the MCU enters to low power mode
 */
int bc45_shell_command_cdmode(shell_cmd_args * args)
{
	
	volatile bool b1;
	volatile bool b2;
	volatile bool b3;
	uint8_t tmpLen;
	uint8_t tmpData = 0;
	uint8_t status;
	uint8_t dataTrans[8];
	uint8_t reg_value;
	uint16_t adc_I_avg = 0;
	uint8_t adc_I_int;
	uint8_t adc_I_fraction;
	uint16_t adc_Q_avg = 0;
	uint8_t adc_Q_int;
	uint8_t adc_Q_fraction;
	volatile uint8_t tmpADC_I;
	volatile uint8_t tmpADC_Q;
	uint8_t i;
	uint8_t IRQSrc;
	uint8_t tmpStep;
	uint8_t tmpWkup_Time[3] = {0};

	/* Check arguments */
	if((args->count > 2)||(args->count == 0))
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nInvalid argument"
		"\r\nERROR\r\n", 27 );
	}
	else if(args->count == 2)
	{
		tmpLen = shell_str_len(args->args[0].val);
		/* Setting step of calibration */
		if(shell_str_cmp(args->args[0].val, "-th", tmpLen, 3) == 0)
		{
			tmpLen = shell_str_len(args->args[1].val);
			status = customParseHEX((uint8_t *)args->args[1].val, tmpLen, &tmpStep);
			/*Custom parse hex success*/
			if(status == 0x00)
			{
				/*Step calibration can be 1 - 5*/
				if((tmpStep >= 0x01)&&(tmpStep <= 0x05))
				{
					stepCalibration = tmpStep;
					htk_UART_Transmit((uint8_t*)"\r\nSet step calibration success", 30);
				}
				else
				{
					htk_UART_Transmit((uint8_t*)"\r\nSet step calibration failed", 29);
					stepCalibration = 3;
				}
			}
			else
			{
				htk_UART_Transmit((uint8_t*)"\r\nSet step calibration failed", 29);
				stepCalibration = 3;
			}
		}
		else if(shell_str_cmp(args->args[0].val, "-lpmcu", tmpLen, 6) == 0)
		{
			/*Sleep mode*/
			tmpLen = shell_str_len(args->args[1].val);
			if(shell_str_cmp(args->args[1].val, "-sleep1", tmpLen, 7) == 0)
			{
				htk_UART_Transmit(
				(uint8_t*)"\r\nMCU Low power : sleep mode"
				"\r\nOK\r\n", 40 );
				lowpwr = SLEEPMODE;
			}
			/*Stop mode*/
			else if(shell_str_cmp(args->args[1].val, "-sleep2", tmpLen, 7) == 0)
			{
				htk_UART_Transmit(
				(uint8_t*)"\r\nMCU Low power : deep sleep1 mode"
				"\r\nOK\r\n", 40 );
				lowpwr = STOPMODE;
			}
			/*None low power mode*/
			else if(shell_str_cmp(args->args[1].val, "-normal", tmpLen, 7) == 0)
			{
				htk_UART_Transmit(
				(uint8_t*)"\r\nMCU doesn't run in low power mode"
				"\r\nOK\r\n", 41 );
				lowpwr = NONLOWPWR;
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nInvalid argument"
				"\r\nERROR\r\n", 27 );
			}
		}
		else if(shell_str_cmp(args->args[0].val, "-wkuptime", tmpLen, 9) == 0)
		{
			/* Wake up time period */
			tmpLen = shell_str_len(args->args[1].val);
			if(shell_str_cmp(args->args[1].val, "100", tmpLen, 3) == 0)
			{
				Timer_WKUP.Timer_COUNTER = 0x0A;
				Timer_WKUP.Timer_PRESCALER = 0x06;
				Timer_WKUP.Timer_RELOAD = 0x1A;

				//This period time also is default value
				TimerWKUP_INIT(Timer_WKUP);
				htk_UART_Transmit((uint8_t*)"\r\nWake up timer period is 100 ms"
										    "\r\nOK\r\n", 38);
			}
			else if(shell_str_cmp(args->args[1].val, "200", tmpLen, 3) == 0)
			{
				Timer_WKUP.Timer_COUNTER = 0x0A;
				Timer_WKUP.Timer_PRESCALER = 0x07;
				Timer_WKUP.Timer_RELOAD = 0x1A;

				//This period time also is default value
				TimerWKUP_INIT(Timer_WKUP);
				htk_UART_Transmit((uint8_t*)"\r\nWake up timer period is 200 ms"
										    "\r\nOK\r\n", 38);
			}
			else if(shell_str_cmp(args->args[1].val, "500", tmpLen, 3) == 0)
			{
				Timer_WKUP.Timer_COUNTER = 0x0A;
				Timer_WKUP.Timer_PRESCALER = 0x09;
				Timer_WKUP.Timer_RELOAD = 0x10;

				//This period time also is default value
				TimerWKUP_INIT(Timer_WKUP);
				htk_UART_Transmit((uint8_t*)"\r\nWake up timer period is 500 ms"
										    "\r\nOK\r\n", 38);
			}
			else if(shell_str_cmp(args->args[1].val, "1000", tmpLen, 4) == 0)
			{
				Timer_WKUP.Timer_COUNTER = 0x0A;
				Timer_WKUP.Timer_PRESCALER = 0x0A;
				Timer_WKUP.Timer_RELOAD = 0x10;

				//This period time also is default value
				TimerWKUP_INIT(Timer_WKUP);
				htk_UART_Transmit((uint8_t*)"\r\nWake up timer period is 1000 ms"
										    "\r\nOK\r\n", 39);
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nInvalid argument"
						   "\r\nERROR\r\n", 27 );
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nInvalid argument"
					   "\r\nERROR\r\n", 27 );
		}
	}
	else
	{
		tmpLen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-h", tmpLen, 2) == 0)
		{
			const char menu[] = "\r\nUsage: cd -c : CD mode with continuous (WKUP and Go Active)"
					  "\r\n       cd -w : CD mode with waiting for command"
					  "\r\n               (WKUP and not go active)"
					  "\r\n       cd -cal: Calibrate CD threshold with stand-alone antenna"
					  "\r\n       cd -th: Setup CD Mode sensitivity (1 = loosest , 5 = tightest)"
					  "\r\n       cd -lpmcu: Setup low power of MCU when BC45 entered to cd mode"
					  "\r\n               (-sleep2, -sleep1, -normal)"
					  "\r\n       cd -wkuptime: Setup wake up timer period (100, 200, 500, 1000 ms) "
					  "\r\n"
					  "\r\nEx: cd -lpmcu -sleep"
					  "\r\n    MCU low power : Sleep mode"
					  "\r\n    OK\r\n";
			htk_UART_Transmit((uint8_t*)menu, strlen(menu));

			return 0;
		}
		/* CD mode with go active after woke up */
		if(shell_str_cmp(args->args[0].val, "-c", tmpLen, 2) == 0)
		{
			/*Enable CDIRQ on BC45*/
			Interrupt_EnableBC45(CDIRQ_Mask);
			/*Start wkup timer*/
			TimerWKUP_Start();
			/*Enter to cd mode with go active*/
			status = BC45_Mode_Selection(BC45_WKUP_CD_MODE);
			if(status == _SUCCESS_)
			{
				switch(lowpwr)
				{
					case SLEEPMODE:
						htk_UART_Transmit((uint8_t*)"Sleep Mode\r\n", 18);
						GotoSleepMode();
						reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
						break;
					case STOPMODE:
						htk_UART_Transmit((uint8_t*)"Deep Sleep1 Mode\r\n", 18);
						GotoStopMode();
						reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
						break;
					default: // Not run into low power mode
						htk_UART_Transmit((uint8_t*)"Normal Mode\r\n", 15);
					
					  while( BC45_IRQ_PIN() == 0)
						{
							Delay(20);
						}
						reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
						break;
				}

				/*Check Interrupt IRQ source */
				if(reg_value == CDIRQ_Mask)
				{
					/*Waiting until CD IRQ is cleared*/
					while(reg_value == CDIRQ_Mask)
					{
						BC45_Disable_And_ClearFlag_IRQ( ALL_IRQ_SOURCE | CDIRQ_Mask ) ;
						htk_SPI_readSingleRegister(InterruptIRQ, &reg_value);
						reg_value &= CDIRQ_Mask;
					}
					htk_UART_Transmit((uint8_t *)"\r\nCD IRQ source\r\n", 17);
					/*Exit from CD mode*/
					BC45_CDMode_Exit();
					htk_UART_Transmit((uint8_t*)"\r\n", 2);
					/*Scan a tag*/
					switch(tag_type)
					{
						case ISO14443A_TagType:
							ScanUID_ISO14443ATagType();
							break;
						case ISO15693_TagType:
							ScanUID_ISO15693TagType();
							break;
						case ISO14443B_TagType:
							ScanUID_ISO14443BTagType();
							break;
						default:
							htk_UART_Transmit(
							(uint8_t *)"\r\nTag Type not supported"
							"\r\nFAILED\r\n", 34 );
							break;
					}
				}
				else
				{
					/*Clear and disable all interrupt*/
					BC45_Disable_And_ClearFlag_IRQ( ALL_IRQ_SOURCE | CDIRQ_Mask ) ;
					/*Exit from CD mode*/
					BC45_CDMode_Exit();
					htk_UART_Transmit((uint8_t*)"\r\nInterrupt is not CDIRQ", 24);
				}
			}
			else
			{
				htk_UART_Transmit((uint8_t*)"WKUP CD Mode FAILED\r\n", 21);
			}
		}
		/* CD mode with not go active after woke up */
		else if(shell_str_cmp(args->args[0].val, "-w", tmpLen, 2) == 0)
		{
			/*Enable CDIRQ on BC45*/
			Interrupt_EnableBC45(CDIRQ_Mask);

			/*Start wkup timer*/
			TimerWKUP_Start();

			/*Enter to CD mode*/
			status = BC45_Mode_Selection(BC45_IDLE_CD_MODE);
			if(status == _SUCCESS_)
			{
				switch(lowpwr)
				{
					case SLEEPMODE:
						htk_UART_Transmit((uint8_t*)"\r\Sleep Mode\r\n", 18);
						GotoSleepMode();
						reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
						break;
					case STOPMODE:
						htk_UART_Transmit((uint8_t*)"\r\nDeep Sleep1 Mode\r\n", 18);
						GotoStopMode();
						reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
						break;
					default: // Not run into low power mode
						htk_UART_Transmit((uint8_t*)"\r\nNormal Mode\r\n", 15);

					  while( BC45_IRQ_PIN() == 0)
						{
							Delay(20);
						}
						reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
						break;
				}

				#if 1
				htk_UART_Transmit(
				(uint8_t*)"\r\nThere is interrupt from BC45\r\n",
				32);
				/* Read ADC result */
				htk_UART_Transmit(
				(uint8_t*)"\r\nRead ADC result\r\n",
				19);
				Display_ADC_I_Q();
				htk_UART_Transmit(
				(uint8_t*)"\r\nPress any key to continue...\r\n",
				32);
				/* Waiting for interrupt from Keyboard */
				runningLoop = 1;
				while(runningLoop)
				{
					Delay(20);
				}
				#endif
				
				/* Stop wake up timer and Exit from CD mode*/
				htk_UART_Transmit((uint8_t*)"\r\nStop timer and exit from CD mode",34);
				while(reg_value == CDIRQ_Mask)
				{
					BC45_Disable_And_ClearFlag_IRQ( ALL_IRQ_SOURCE | CDIRQ_Mask ) ;
					htk_SPI_readSingleRegister(InterruptIRQ, &reg_value);
					reg_value &= CDIRQ_Mask;
				}
				BC45_CDMode_Exit();
				#if 1
				htk_UART_Transmit((uint8_t*)"\r\nPress any key to continue...\r\n",32);
				/* Waiting for interrupt from Keyboard */
				runningLoop = 1;
				while(runningLoop)
				{
					Delay(20);
				}
				#endif

				/* Read Tag */
				htk_UART_Transmit((uint8_t*)"\r\nScan Tag\r\n",12);
				switch(tag_type)
				{
					case ISO14443A_TagType:
						ScanUID_ISO14443ATagType();
						break;
					case ISO15693_TagType:
						ScanUID_ISO15693TagType();
						break;
					case ISO14443B_TagType:
						ScanUID_ISO14443BTagType();
						break;
					default:
						htk_UART_Transmit(
						(uint8_t *)"\r\nTag Type not supported"
						"\r\nFAILED\r\n", 34);
						break;
				}
			}
			else
			{
				htk_UART_Transmit((uint8_t*)"WKUP CD Mode FAILED\r\n", 21);
			}
		}
		/* Calibration CD threshold */
		else if(shell_str_cmp(args->args[0].val, "-cal", tmpLen, 4) == 0)
		{
			htk_UART_Transmit(
			(uint8_t*)"\r\nPlease don't place any tag."
			"\r\nCalibrating...\r\n", 47);

			/*BC45 ADC calibration*/
			ADC_Calibration();

			/*Reverse CD threshold for CD IRQ always set*/
			Tunning_Thereshold.CD_Threshold_I_H = 0x00;
			Tunning_Thereshold.CD_Threshold_I_L = 0xFF;
			Tunning_Thereshold.CD_Threshold_Q_H = 0x00;
			Tunning_Thereshold.CD_Threshold_Q_L = 0xFF;
			CD_ADC_Tuning(Tunning_Thereshold);

			/*Store old value of wkup timer */
			tmpWkup_Time[0] = Timer_WKUP.Timer_COUNTER;
			tmpWkup_Time[1] = Timer_WKUP.Timer_PRESCALER;
			tmpWkup_Time[2] = Timer_WKUP.Timer_RELOAD;

			/*Set up wkup timer to be 250 ms*/
			//Timer_WKUP.Timer_COUNTER = 0x0A;
			//Timer_WKUP.Timer_PRESCALER = 0x08;
			//Timer_WKUP.Timer_RELOAD = 0x10;
			//TimerWKUP_INIT(Timer_WKUP);

			IRQSrc = 0x7F & (ALL_IRQ_SOURCE | CDIRQ_Mask);
			htk_SPI_writeSingleRegister( InterruptRq, IRQSrc) ;

		  /*Enable CDIRQ on BC45*/
			Interrupt_EnableBC45(CDIRQ_Mask);
			/*Enter to CD mode*/
			BC45_Mode_Selection(BC45_IDLE_CD_MODE);
			/*Start wkup timer*/
			TimerWKUP_Start();

			LED_RED_ON();
			for(i = 0; i < 6; )
			{
				//debug pin
				//GPIO_SetOutBits(HT_GPIOA, GPIO_PIN_7);
				
				htk_UART_Transmit((uint8_t *)".\r\n", 3);
				switch(lowpwr)
				{
					case SLEEPMODE:
						GotoSleepMode();
						break;
					case STOPMODE:
						GotoStopMode();
						break;
					default:
						/*
						 * Not run into low powre mode
						 * Waiting for IRQ pin rise up
						 * */
						while(BC45_IRQ_PIN() != 1)
						{
							Delay(10);
						}
						break;
				}
				LED_RED_OFF();
				reg_value = Interrupt_GetIrq_SourceBC45(CDIRQ_Mask);
				/*Check interrupt IRQ*/
				if(reg_value == CDIRQ_Mask)
				{
					/*Clear all IRQ source*/
					IRQSrc = 0x7F & (ALL_IRQ_SOURCE | CDIRQ_Mask);
					htk_SPI_writeSingleRegister( InterruptRq, IRQSrc) ;
					
					/*Read ADC I result*/
					htk_SPI_readSingleRegister(ADC_RESULT_I, &tmpData);
					if(i != 0)
					{
						adc_I_avg += tmpData;
					}
					/*Read ADC Q result*/
					htk_SPI_readSingleRegister(ADC_RESULT_Q, &tmpData);
					if(i != 0)
					{
						adc_Q_avg += tmpData;
					}

					/*Increase i value*/
					i++;
					

					htk_UART_Transmit((uint8_t *)".\r\n", 3);

				}
				else
				{
					/*Clear all IRQ source*/
					IRQSrc = 0x7F & (ALL_IRQ_SOURCE | CDIRQ_Mask);
					htk_SPI_writeSingleRegister( InterruptRq, IRQSrc) ;
					htk_UART_Transmit((uint8_t *)"*\r\n", 3);
				}

				/*Waiting for IRQ pin is cleared*/
				//debug pin
				//GPIO_ClearOutBits(HT_GPIOA, GPIO_PIN_7);
				while(BC45_IRQ_PIN() == 1);
				//LED2_RED_OFF();
			}

			/*Average ADC I Value*/
			adc_I_int = (uint8_t)(adc_I_avg / 5);
			adc_I_fraction = (uint8_t)(adc_I_avg % 5);
			if(adc_I_fraction >= 3)
			{
				adc_I_avg = adc_I_int + 1;
			}
			else
			{
				adc_I_avg = adc_I_int;
			}

			/*Average ADC Q Value*/
			adc_Q_int = (uint8_t)(adc_Q_avg / 5);
			adc_Q_fraction = (uint8_t)(adc_Q_avg % 5);
			if(adc_Q_fraction >= 3)
			{
				adc_Q_avg = adc_Q_int + 1;
			}
			else
			{
				adc_Q_avg = adc_Q_int;
			}

			//LED2_RED_OFF();

			dataToHex(&dataTrans[0], ADC_RESULT_I);
			htk_UART_Transmit((uint8_t *)"\r\nADC_I[HEX]: ", 14);
			htk_UART_Transmit((uint8_t *)dataTrans, 2);
			tmpADC_I = (uint8_t)adc_I_avg;
			dataToHex(&dataTrans[0], tmpADC_I);
			htk_UART_Transmit((uint8_t *)", VAL[HEX]:", 11);
			htk_UART_Transmit((uint8_t *)dataTrans, 2);

			dataToHex(&dataTrans[0], ADC_RESULT_Q);
			htk_UART_Transmit((uint8_t *)"\r\nADC_Q[HEX]: ", 14);
			htk_UART_Transmit((uint8_t *)dataTrans, 2);
			tmpADC_Q = (uint8_t)adc_Q_avg;
			dataToHex(&dataTrans[0], tmpADC_Q);
			htk_UART_Transmit((uint8_t *)", VAL[HEX]:", 11);
			htk_UART_Transmit((uint8_t *)dataTrans, 2);

			while(1)
			{
				BC45_Disable_And_ClearFlag_IRQ( ALL_IRQ_SOURCE | CDIRQ_Mask ) ;
				htk_SPI_readSingleRegister(InterruptIRQ, &reg_value);
				if((reg_value & CDIRQ_Mask) == 0x00)
				{
					break;
				}
			}
			status = BC45_CDMode_Exit();

			/*Restore the old value of wake up timer*/
			Timer_WKUP.Timer_COUNTER = tmpWkup_Time[0];
			Timer_WKUP.Timer_PRESCALER = tmpWkup_Time[1];
			Timer_WKUP.Timer_RELOAD = tmpWkup_Time[2];
			TimerWKUP_INIT(Timer_WKUP);

			/*Check follow these condition
			 * 1. ADC I and Q must not equal to zero
			 * 2. Exit from CD mode
			 * */
			b1=(status == _SUCCESS_)?1 : 0;
			b2=(tmpADC_I != 0)?1 : 0;
			b3=(tmpADC_Q != 0)?1 : 0;
			//if((status == _SUCCESS_)&&(tmpADC_I != 0)&&(tmpADC_Q != 0))
			if(b1 && b2 && b3)
			{
				Tunning_Thereshold.CD_Threshold_I_L = tmpADC_I - stepCalibration;

				dataToHex(&dataTrans[0], Tunning_Thereshold.CD_Threshold_I_L);
				htk_UART_Transmit((uint8_t *)"\r\nADC_I_L[HEX]:", 15);
				htk_UART_Transmit((uint8_t *)dataTrans, 2);

				if((adc_I_avg + stepCalibration) > 0x00FF)
				{
					Tunning_Thereshold.CD_Threshold_I_H = 0xFF;
				}
				else
				{
					Tunning_Thereshold.CD_Threshold_I_H = tmpADC_I + stepCalibration;

					dataToHex(&dataTrans[0], Tunning_Thereshold.CD_Threshold_I_H);
					htk_UART_Transmit((uint8_t *)"\r\nADC_I_H[HEX]:", 15);
					htk_UART_Transmit((uint8_t *)dataTrans, 2);
				}

				Tunning_Thereshold.CD_Threshold_Q_L = tmpADC_Q - stepCalibration;

				dataToHex(&dataTrans[0], Tunning_Thereshold.CD_Threshold_Q_L);
				htk_UART_Transmit((uint8_t *)"\r\nADC_Q_L[HEX]:", 15);
				htk_UART_Transmit((uint8_t *)dataTrans, 2);

				if((adc_Q_avg + stepCalibration) > 0x00FF)
				{
					Tunning_Thereshold.CD_Threshold_Q_H = 0xFF;
				}
				else
				{
					Tunning_Thereshold.CD_Threshold_Q_H = tmpADC_Q + stepCalibration;

					dataToHex(&dataTrans[0], Tunning_Thereshold.CD_Threshold_Q_H);
					htk_UART_Transmit((uint8_t *)"\r\nADC_Q_H[HEX]:", 15);
					htk_UART_Transmit((uint8_t *)dataTrans, 2);
				}

				CD_ADC_Tuning(Tunning_Thereshold);

				htk_UART_Transmit(
				(uint8_t*)"\r\nTunning completed"
				"\r\nOK\r\n", 25);
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t*)"\r\nTunning failed"
				"\r\nCan not exit from CDMode"
				"\r\nFAILED\r\n", 52);
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nInvalid argument"
			"\r\nERROR\r\n", 27 );
		}
	}

	return 0;
}


/*
 *  Include NFC Type A command
 */
int bc45_shell_command_nfcA(shell_cmd_args * args)
{
	uint8_t tx_buffer[64] = {0};
	uint8_t rx_buffer[16] = {0};
	uint16_t tx_len = 0;
	uint16_t rx_len = 0;
	uint8_t tmplen;
	volatile uint8_t counter;
	uint8_t level;
	volatile uint8_t Resp = 0xEE;
	uint8_t status;
	uint8_t Num_Coll;
	uint8_t Coll_Pos;
	uint8_t *tmpStr;
	nfcA_Command_t nfcA_command = A_NOCOMMAND;


	if((args->count > 4)||(args->count == 0))
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nInvalid argument"
				   "\r\nERROR\r\n", 27);
	}
	else if(args->count == 1)
	{
		tmplen = shell_str_len(args->args[0].val);
		/*Help option command*/
		if(shell_str_cmp(args->args[0].val, "-h", tmplen, 2) == 0)
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUsage: a -setup : ISO14443A configuration"
					   "\r\n       a -wupa : ISO14443A wake up command"
					   "\r\n       a -reqa : ISO14443A request command"
					   "\r\n       a -hlta : ISO14443A halt command"
					   "\r\n       a -anticol <level 1 - 3> : ISO14443A anti-collision command"
					   "\r\n       a -sel <level 1 - 3> <UID to select> : ISO14443A select command"
 					   "\r\n       a -getuid : Req-Anti-Sel combo command to get UID"
					   "\r\n       a -trans -crc <data in hex> : Transparent command with CRC"
				       "\r\n       a -trans -nocrc <data in hex> : Transparent command without CRC"
					   "\r\n"
					   "\r\nEx: a -wupa"
					   "\r\n    Successful operation"
					   "\r\n    <ATQA response 2 bytes>"
					   "\r\nEx: a -anticol 1"
					   "\r\n    Successful operation"
					   "\r\n    <UID 3 bytes and BCC 1 byte>"
					   "\r\nOK\r\n",  663);
			return 0;
		}
		else if(shell_str_cmp(args->args[0].val, "-wupa", tmplen, 5) == 0)
		{
			Resp = ISO14443A_WakeUp(rx_buffer, &rx_len);
			nfcA_command = A_WUPA;
		}
		else if(shell_str_cmp(args->args[0].val, "-reqa", tmplen, 5) == 0)
		{
			Resp = ISO14443A_Request(rx_buffer, &rx_len);
			nfcA_command = A_REQA;
		}
		else if(shell_str_cmp(args->args[0].val, "-hlta", tmplen, 5) == 0)
		{
			Resp = ISO14443A_Halt(rx_buffer, &rx_len);
			nfcA_command = A_HLTA;
		}
		else if(shell_str_cmp(args->args[0].val, "-setup", tmplen, 6) == 0)
		{
			BC45_Configuration(CONFIG_14443A);
			nfcA_command = A_SETUP;
			Resp = _SUCCESS_;
		}
		else if(shell_str_cmp(args->args[0].val, "-getuid", tmplen, 7) == 0)
		{
			/*Request mode (TypeA)*/
			tx_buffer[0] = 0x00; //Request Type A
			tx_buffer[1] = 0x00;
			/*Combo command type A : Request + AntiColl + Select*/

			BC45_RF_OnOff(RFRESET);
			BC45_ConfigurationNoOfffield(CONFIG_14443A);
			Resp = ISO14443A_Command(A_Req_Anti_Sel, tx_buffer, 2, rx_buffer, &rx_len);

			nfcA_command = A_GETUID;
		}
		else
		{
			Resp = 0xEE;
			htk_UART_Transmit((uint8_t *)"\r\nUnavailable argument", 22);
			nfcA_command = A_NOCOMMAND;
		}

		switch(Resp)
		 {
		  	case _SUCCESS_:					
		  		//htk_UART_Transmit((uint8_t *)"\r\nOperation Success", 19);
		  		if(nfcA_command == A_GETUID)
		  		{
		  			//htk_UART_Transmit((uint8_t *)"\r\nUID: ", 7);						
						htk_UART_Transmit((uint8_t *)"\r\n", 2);						
			   		/*Convert UID type A from HEX to CHAR*/
			   		UIDTypeA_BytesToChar(&rx_buffer[2], tx_buffer, &rx_len);
			   		htk_UART_Transmit(tx_buffer, rx_len + 1);
		  		}
		  		else if((nfcA_command == A_REQA) || (nfcA_command == A_WUPA))
		  		{
		  			for(counter = 0; counter < rx_len; counter++)
		  			{
		  				dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
		  			}

		  			htk_UART_Transmit((uint8_t*)"\r\nATQA : ", 9);
		  			htk_UART_Transmit(tx_buffer, counter * 2);
		  		}
		  		else
		  		{
		  			//Do nothing for halt and config commands
		  		}

		  		htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
		   		break;
		     case NO_RESPONSE:
		       	htk_UART_Transmit((uint8_t*)"\r\nNo Response"
		       								"\r\nERROR\r\n", 22);
				break;
		     case ASIC_EXE_TIMEOUT:
		       	htk_UART_Transmit((uint8_t*)"\r\nTimeout"
		       								"\r\nERROR\r\n", 18);
		       	break;
		     default:
				htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
				  							 "\r\nERROR\r\n", 27);
				break;
	    }
	}
	else if(args->count == 2)
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-anticol", tmplen, 8) == 0)
		{
			tmplen = shell_str_len(args->args[1].val);
			status = customParseHEX((uint8_t *)args->args[1].val, tmplen, &level);
			if(status == 0x00)
			{
				/*Check level of AntiCol command*/
				if((level >= 1) && (level <=3))
				{
					Resp = ISO14443A_Anticoll(level, 0x00, &Num_Coll, &Coll_Pos, rx_buffer, &rx_len);
				}
				else
				{
					Resp = 0xEE;
				}

				/* Check response */
				if(Resp == _SUCCESS_)
				{
					//htk_UART_Transmit((uint8_t *)"\r\nOperation Success", 19);

					if(level == 1)
					{
						htk_UART_Transmit((uint8_t *)"\r\nUID level 1 : ", 16);
					}
					else if(level == 2)
					{
						htk_UART_Transmit((uint8_t *)"\r\nUID level 2 : ", 16);
					}
					else
					{
						htk_UART_Transmit((uint8_t *)"\r\nUID level 3 : ", 16);
					}

					for(counter = 0; counter < rx_len; counter++)
					{
						dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
					}
					htk_UART_Transmit(tx_buffer, counter * 2);
					htk_UART_Transmit((uint8_t*)"\r\nOK\r\n", 6);
				}
				else if(Resp == 0xEE)
				{
					htk_UART_Transmit(
					(uint8_t *)"\r\nUnavailable level of AntiCol command"
							   "\r\nERROR\r\n", 47);
				}
				else
				{
					if(level == 1)
					{
						htk_UART_Transmit(
						(uint8_t *)"\r\nAnti-Collission level 1", 25);
					}
					else if(level == 2)
					{
						htk_UART_Transmit(
						(uint8_t *)"\r\nAnti-Collission level 2", 25);
					}
					else
					{
						htk_UART_Transmit(
						(uint8_t *)"\r\nAnti-Collission level 3", 25);
					}

					htk_UART_Transmit((uint8_t *)"\r\nERROR\r\n", 9);
				}
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nUnavailable level of AntiCol command"
						   "\r\nERROR\r\n", 47);
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
		}
	}
	else if((args->count == 3) || (args->count == 4))
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-sel", tmplen, 4) == 0)
		{
			tmplen = shell_str_len(args->args[1].val);
			status = customParseHEX((uint8_t *)args->args[1].val, tmplen, &level);
			if(status == 0x00)
			{
				tmplen = shell_str_len(args->args[2].val);
				tmpStr = (uint8_t *)args->args[2].val;
				for(counter = 0; counter < (tmplen/2); counter++)
				{
					status = customParseHEX((tmpStr + (counter*2)), 2, &tx_buffer[counter]);
					if(status != 0x00)
					{
						htk_UART_Transmit((uint8_t *)"\r\nUID FAILED\r\n", 14);
						CommandResultAlert(Resp);
						return 0;
					}
				}

				/* Send select A command */
				if((level >= 1) && (level <= 3))
				{
					Resp = ISO14443A_Select(level, tx_buffer, rx_buffer, &rx_len);
				}
				else
				{
					Resp = 0xEE;
				}

				/* Check response */
				if(Resp == _SUCCESS_)
				{
					//htk_UART_Transmit((uint8_t *)"\r\nOperation Success", 19);

					if(level == 1)
					{
						htk_UART_Transmit((uint8_t *)"\r\nSAK level 1 : ", 16);
					}
					else if(level == 2)
					{
						htk_UART_Transmit((uint8_t *)"\r\nSAK level 2 : ", 16);
					}
					else
					{
						htk_UART_Transmit((uint8_t *)"\r\nSAK level 3 : ", 16);
					}

					for(counter = 0; counter < rx_len; counter++)
					{
						dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
					}
					htk_UART_Transmit(tx_buffer, counter * 2);
					htk_UART_Transmit((uint8_t*)"\r\nOK\r\n", 6);
				}
				else if(Resp == 0xEE)
				{
					htk_UART_Transmit(
					(uint8_t *)"\r\nUnavailable level of select command"
							   "\r\nERROR\r\n", 46);
				}
				else
				{
					if(level == 1)
					{
						htk_UART_Transmit((uint8_t *)"\r\nSelect level 1", 16);
					}
					else if(level == 2)
					{
						htk_UART_Transmit((uint8_t *)"\r\nSelect level 2", 16);
					}
					else
					{
						htk_UART_Transmit((uint8_t *)"\r\nSelect level 3", 16);
					}

					htk_UART_Transmit((uint8_t *)"\r\nERROR\r\n", 9);
				}
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nUnavailable level of select command"
						   "\r\nERROR\r\n", 46);
			}
		}
		else if(shell_str_cmp(args->args[0].val, "-trans", tmplen, 6) == 0)
		{
			//Check CRC configuration
			tmplen = shell_str_len(args->args[1].val);
			if(shell_str_cmp(args->args[1].val, "-crc", tmplen, 4) == 0)
			{
				nfcA_command = A_TRANS_CRC;
			}
			else if(shell_str_cmp(args->args[1].val, "-nocrc", tmplen, 6) == 0)
			{
				nfcA_command = A_TRANS_NOCRC;
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nUnavailable argument"
						   "\r\nERROR\r\n", 31);
				nfcA_command = A_NOCOMMAND;
				CommandResultAlert(Resp);
				return 0;
			}

			//Transform data for transmission
			if(nfcA_command != A_NOCOMMAND)
			{
				tmplen = shell_str_len(args->args[2].val);
				if((tmplen >= 2) && (tmplen <= 128))
				{
					tmpStr = (uint8_t *)args->args[2].val;
					for(counter = 0; counter < (tmplen/2); counter++)
					{
						status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter]);
						if(status != 0x00)
						{
							htk_UART_Transmit(
							(uint8_t *)"\r\nWrong data input. Please re-check"
									   "\r\nERROR\r\n", 44);
							CommandResultAlert(Resp);
							return 0;
						}
					}

					tx_len = counter;
					if(nfcA_command == A_TRANS_CRC)
					{
						Resp = Transparent_With_CRC( tx_buffer, tx_len, 0x0C, rx_buffer, &rx_len );
					}
					else
					{
						Resp = Transparent_Without_CRC( tx_buffer, tx_len, 0x0C, rx_buffer, &rx_len );
					}
				}
				else
				{
					htk_UART_Transmit(
					(uint8_t *)"\r\nUnavailable argument"
							   "\r\nERROR\r\n", 31);
				}
			}

			switch(Resp)
			 {
			  	case _SUCCESS_:
						//htk_UART_Transmit((uint8_t *)"\r\nOperation Success"
						//					"\r\nTransmit : ", 32);
						htk_UART_Transmit((uint8_t *)"\r\nTransmit : ", 13);
						htk_UART_Transmit((uint8_t *)args->args[2].val, tmplen);
						htk_UART_Transmit((uint8_t *)"\r\nReceive : ", 12);

		  			for(counter = 0; counter < (uint8_t)rx_len; counter++)
		  			{
		  				dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
		  			}
		  			htk_UART_Transmit(tx_buffer, (rx_len * 2));
		  			htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
			   		break;
			    case NO_RESPONSE:
			     	htk_UART_Transmit((uint8_t*)"\r\nNo Response"
			       								"\r\nERROR\r\n", 22);
						break;
			    case ASIC_EXE_TIMEOUT:
			     	htk_UART_Transmit((uint8_t*)"\r\nTimeout"
			       								"\r\nERROR\r\n", 18);
			      break;
			    default:
						htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
					  							 "\r\nERROR\r\n", 27);
					break;
		    }
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
		}
	}
	else
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nUnavailable argument"
				   "\r\nERROR\r\n", 31 );
	}
	CommandResultAlert(Resp);
	return 0;
}


int bc45_shell_command_nfcB(shell_cmd_args * args)
{
	uint8_t tx_buffer[64] = {0};
	uint8_t rx_buffer[16] = {0};
	uint16_t tx_len = 0;
	uint16_t rx_len = 0;
	uint8_t tmplen;
	volatile uint8_t counter;
	volatile uint8_t Resp = 0xEE;
	uint8_t status;
	uint8_t Slot_Num;
	uint8_t param[4] = {0x00, 0x08, 0x01, 0x00};
	uint8_t *tmpStr;
	nfcB_Command_t nfcB_command = B_NOCOMMAND;

	if((args->count > 3)||(args->count == 0))
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nInvalid argument"
				   "\r\nERROR\r\n", 27);
	}
	else if(args->count == 1)
	{
		tmplen = shell_str_len(args->args[0].val);
		/*Help option command*/
		if(shell_str_cmp(args->args[0].val, "-h", tmplen, 2) == 0)
		{
			const char menu[] = "\r\nUsage: b -setup : ISO14443B configuration"
					   "\r\n       b -reqb : ISO14443B request command"
					   "\r\n       b -wupb : ISO14443B wake up command"
					   "\r\n       b -attrib <PUPI 4 bytes> : ISO14443B ATTRIB command"
					   "\r\n       b -halt <PUPI 4 bytes> : ISO14443B halt command"
 					   "\r\n       a -getuid : Req-attrib combo command to get UID"
				       "\r\n       b -trans -crc <data in hex> : Transparent command with CRC"
				       "\r\n       b -trans -nocrc <data in hex> : Transparent command without CRC"
					   "\r\n"
					   "\r\nEx: b -reqb"
					   "\r\n    Operation Success"
					   "\r\n    ATQB: <ATQB response>"
					   "\r\nEx: b -attrib 01020304"
					   "\r\n    Operation Success"
					   "\r\n    <Response data>"
					   "\r\nOK\r\n";
			
			htk_UART_Transmit(
			(uint8_t *)menu,  strlen(menu));
			return 0;
		}
		else if(shell_str_cmp(args->args[0].val, "-wupb", tmplen, 5) == 0)
		{
			Resp = ISO14443B_WakeUp(0x00, 0x00, &Slot_Num, rx_buffer, &rx_len);
			nfcB_command = B_WUPB;
		}
		else if(shell_str_cmp(args->args[0].val, "-reqb", tmplen, 5) == 0)
		{
			Resp = ISO14443B_Request( 0x00, 0x00, &Slot_Num, rx_buffer, &rx_len);
			nfcB_command = B_REQB;
		}
		else if(shell_str_cmp(args->args[0].val, "-setup", tmplen, 6) == 0)
		{
			BC45_Configuration(CONFIG_14443B);
			//htk_UART_Transmit((uint8_t*)"\r\nOperation Success"
			//							"\r\nOK\r\n", 25);
			htk_UART_Transmit((uint8_t*)"\r\nOK\r\n", 6);		
			CommandResultAlert(_SUCCESS_);
			return 0;
		}
		else if(shell_str_cmp(args->args[0].val, "-getuid", tmplen, 7) == 0)
		{
			uint8_t Running_state = 0;
			/*Scanning a Tag ISO14443B*/
			//BC45_ConfigurationNoOfffield(CONFIG_14443B);
			BC45_Configuration(CONFIG_14443B);
			//htk_UART_Transmit((uint8_t *)"Scanning a Tag ISO14443B\r\n",26);
			Resp = ScanCertificateFlow_ISO14443BTagType(&Running_state);
			CommandResultAlert(Resp);
			return 0;
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);

			return 0;
		}


		switch(Resp)
		{
		  case _SUCCESS_:
		  	//htk_UART_Transmit((uint8_t *)"\r\nOperation Success", 19);
				for(counter = 0; counter < rx_len; counter++)
				{
					dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
				}
				htk_UART_Transmit((uint8_t*)"\r\nATQB: ", 8);
				htk_UART_Transmit(tx_buffer, counter * 2);
		  	htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
		   	break;
		  case NO_RESPONSE:
		   	htk_UART_Transmit((uint8_t*)"\r\nNo Response"
		       								"\r\nERROR\r\n", 22);
				break;
		  case ASIC_EXE_TIMEOUT:
		   	htk_UART_Transmit((uint8_t*)"\r\nTimeout"
		       								"\r\nERROR\r\n", 18);
		    break;
		  default:
				htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
				  							 "\r\nERROR\r\n", 27);
				break;
	    }
	}
	else if(args->count == 2)
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-attrib", tmplen, 7) == 0)
		{
			tmplen = shell_str_len(args->args[1].val);
			tmpStr = (uint8_t *)args->args[1].val;

			if(tmplen <= 8)
			{
				for(counter = 0; counter < (tmplen/2); counter++)
				{
					status = customParseHEX((tmpStr + (counter*2)), 2, &tx_buffer[counter]);
					if(status != 0x00)
					{
						htk_UART_Transmit((uint8_t *)"\r\nPUPI FAILED\r\n", 14);
						CommandResultAlert(FAILED);
						return 0;
					}
				}
			}
			else
			{
				htk_UART_Transmit((uint8_t *)"\r\nPlease check PUPI again\r\n", 27);
				CommandResultAlert(FAILED);
				return 0;
			}

			Resp = ISO14443B_ATTRIB( tx_buffer, param, NULL, 0x00, rx_buffer, &rx_len);
			nfcB_command = B_ATTRI;
		}
		else if(shell_str_cmp(args->args[0].val, "-halt", tmplen, 5) == 0)
		{
			tmplen = shell_str_len(args->args[1].val);
			tmpStr = (uint8_t *)args->args[1].val;
			for(counter = 0; counter < (tmplen/2); counter++)
			{
				status = customParseHEX((tmpStr + (counter*2)), 2, &tx_buffer[counter]);
				if(status != 0x00)
				{
					htk_UART_Transmit((uint8_t *)"\r\nPUPI FAILED\r\n", 14);
					CommandResultAlert(FAILED);
					return 0;
				}
			}

			Resp = ISO14443B_Halt( tx_buffer, rx_buffer, &rx_len);
			nfcB_command = B_HLTB;
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
			CommandResultAlert(FAILED);
			return 0;
		}

		switch(Resp)
		{
		 	case _SUCCESS_:
		 		//htk_UART_Transmit((uint8_t *)"\r\nOperation Success\r\n", 21);
				for(counter = 0; counter < rx_len; counter++)
				{
					dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
				}
				htk_UART_Transmit(tx_buffer, counter * 2);
		  	htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
		   	break;
		  case NO_RESPONSE:
		    htk_UART_Transmit((uint8_t*)"\r\nNo Response"
		       								"\r\nERROR\r\n", 22);
				break;
		  case ASIC_EXE_TIMEOUT:
		    htk_UART_Transmit((uint8_t*)"\r\nTimeout"
		       								"\r\nERROR\r\n", 18);
		    break;
		  default:
				htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
				  							 "\r\nERROR\r\n", 27);
				break;
	  }
	}
	else//transparent command
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-trans", tmplen, 6) == 0)
		{
			//Check CRC configuration
			tmplen = shell_str_len(args->args[1].val);
			if(shell_str_cmp(args->args[1].val, "-crc", tmplen, 4) == 0)
			{
				nfcB_command = B_TRANS_CRC;
			}
			else if(shell_str_cmp(args->args[1].val, "-nocrc", tmplen, 6) == 0)
			{
				nfcB_command = B_TRANS_NOCRC;
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nUnavailable argument"
						   "\r\nERROR\r\n", 31);
				nfcB_command = B_NOCOMMAND;
				CommandResultAlert(FAILED);
				return 0;
			}

			//Transform data for transmission
			if(nfcB_command != B_NOCOMMAND)
			{
				tmplen = shell_str_len(args->args[2].val);
				if((tmplen >= 2) && (tmplen <= 128))
				{
					tmpStr = (uint8_t *)args->args[2].val;
					for(counter = 0; counter < (tmplen/2); counter++)
					{
						status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter]);
						if(status != 0x00)
						{
							htk_UART_Transmit(
							(uint8_t *)"\r\nWrong data input. Please re-check"
									   "\r\nERROR\r\n", 44);
							return 0;
						}
					}

					tx_len = counter;
					if(nfcB_command == B_TRANS_CRC)
					{
						Resp = Transparent_With_CRC( tx_buffer, tx_len, 0x0C, rx_buffer, &rx_len );
					}
					else
					{
						Resp = Transparent_Without_CRC( tx_buffer, tx_len, 0x0C, rx_buffer, &rx_len );
					}
				}
				else
				{
					htk_UART_Transmit(
					(uint8_t *)"\r\nUnavailable argument"
							   "\r\nERROR\r\n", 31);
				}
			}

			switch(Resp)
			{
				case _SUCCESS_:
					//htk_UART_Transmit((uint8_t *)"\r\nOperation Success"
					//					"\r\nTransmit : ", 32);
					htk_UART_Transmit((uint8_t *)"\r\nTransmit : ", 13);
					htk_UART_Transmit((uint8_t *)args->args[2].val, tmplen);
					htk_UART_Transmit((uint8_t *)"\r\nReceive : ", 12);

					for(counter = 0; counter < (uint8_t)rx_len; counter++)
					{
						dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
					}
					htk_UART_Transmit(tx_buffer, (rx_len * 2));
					htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
					break;
			  case NO_RESPONSE:
			   	htk_UART_Transmit((uint8_t*)"\r\nNo Response"
			       								"\r\nERROR\r\n", 22);
					break;
			  case ASIC_EXE_TIMEOUT:
			    htk_UART_Transmit((uint8_t*)"\r\nTimeout"
			       								"\r\nERROR\r\n", 18);
			    break;
			  default:
					htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
					  							 "\r\nERROR\r\n", 27);
					break;
		    }
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
		}
	}
  CommandResultAlert(Resp);
	return 0;
}


/*
 * Inventory 16 slots command to get UID and total card
 */
uint8_t BC45_ISO15693_Inven16Slots(uint8_t speed, uint8_t mask_len, uint8_t *mask_value,
								   uint8_t *collFlag, uint8_t *collPos, uint8_t *uid, uint8_t *total_card)
{
	uint8_t  tx_buffer[56] = {0};
	uint8_t  rx_buffer[200] = {0};
	uint16_t tx_len = 0;
	uint16_t rx_len = 0;
	volatile uint8_t  Resp;
	uint8_t  mask_byte = 0;
	volatile uint16_t counter;
	uint8_t  uid_count;
	uint8_t  index;
	volatile uint8_t  SlotMarker;
	uint8_t  Rx_speed;
	uint8_t  UID_Store[16][9] = {0};

	BC45_CRC_Setting( TxCRC_Enable, RxCRC_Enable ) ;
	Rx_speed = speed & 0x0F;
	*total_card = 0;

	//None AFI mode, Inventory 16 slots command
	tx_buffer[tx_len++] = Request_Flag_ISO15693( speed, 0x00, INVENTORY_16_SLOTS_MODE ) ;
	tx_buffer[tx_len++] = ISO15693_INVENTORY_RF_CMD ;
	tx_buffer[tx_len++] = mask_len ;

	//Check mask length (numbers of byte)
	if((mask_len % 8) != 0)
	{
		mask_byte = mask_len / 8;
		mask_byte++;
	}
	else
	{
		mask_byte = mask_len / 8;
	}

	//Fill mask value to tx buffer
	for( counter = 0 ; counter < mask_byte ; counter++ )
	{
		tx_buffer[tx_len++] = *( mask_value + counter ) ;
	}

	//Count numbers of slot
	for(SlotMarker = 0; SlotMarker < 16; SlotMarker++)
	{
		// Slot Number
		if ( SlotMarker == 0x00 )
		{
			Resp = BC45_Transceive( &tx_buffer[0], tx_len, &rx_buffer[0], &rx_len ) ;
		}
		else
		{	// Sending EOF only
			// Tx Config, Set bit Send 1 pulse, Bit 7
			BC45_Set_Send1Pulse_Bit() ;
			BC45_Flush_FIFO() ;

			if ( (Rx_speed == RX_1_SUB_HIGH) || (Rx_speed == RX_2_SUB_HIGH ) )
			{
				Delay(5) ; // (512*13*8 + 4192)/fc = 4.24ms
			}
			else
			{	//Low Data Rate
				Delay(20) ; // (2048*13*8 + 4192)/fc = 16ms
			}

			Resp = BC45_Transceive( &tx_buffer[0], 0, &rx_buffer[0], &rx_len ) ;
		}

		// Check response of transceive function
		if( Resp == ASIC_EXE_TIMEOUT )
		{	// exit immediately
			BC45_Clear_Send1Pulse_Bit() ;
			*(total_card) = 0 ;

			return ASIC_EXE_TIMEOUT ;
		}
		else if(Resp != NO_RESPONSE )
		{
			if ( Resp == _SUCCESS_ )
			{	// Check Len Resp
				if ( rx_len == LEN_ISO15693_INVENTORY_RF_RESP )
				{
					// Store UID
					for(counter = 0 ; counter < (uint8_t)(rx_len - 1) ; counter++)
					{
						UID_Store[*total_card][counter] = rx_buffer[counter + 1] ;
					}
				}
				else
				{
					// Store UID
					for(counter = 0 ; counter < rx_len ; counter++)
					{
						UID_Store[*total_card][counter] = rx_buffer[counter + 1] ;
					}
				}
				*total_card = *total_card + 1;
			}
			else // Fail
			{
				*collFlag = 1;
				*(collPos + SlotMarker) = 1;
			}
		}
	}

	// Tx Config, Clear bit Send 1 pulse, Bit 7
	BC45_Clear_Send1Pulse_Bit() ;
	// Clear index for store UID
	index = 0;

	if ( *total_card != 0 )
	{
		for(counter = 0; counter < (*total_card); counter++)
		{
			Resp = ISO15693_Stay_Quiet(speed, 0x00, &UID_Store[counter][1], rx_buffer, &rx_len) ;

			for(uid_count = 0; uid_count < 9; uid_count++)
			{
				uid[index++] = UID_Store[counter][uid_count];
			}
		}

		return _SUCCESS_ ;
	}
	else
	{
		return NO_RESPONSE ;
	}
}

int bc45_shell_command_nfcV(shell_cmd_args * args)
{
	uint8_t tx_buffer[32] = {0};
	uint8_t rx_buffer[16] = {0};
	uint16_t tx_len;
	uint16_t rx_len;
	uint8_t tmplen;
	volatile uint8_t counter;
	volatile uint8_t Resp = 0xEE;
	uint8_t status;
	uint8_t mask_len = 0x00;
	uint8_t mask_value[8] = {0};
	uint8_t collPos[16] = {0};
	uint8_t collFlag = 0;
	uint8_t collCount;
	uint8_t collSlot;
	uint8_t UID[16][9] = {0};
	uint8_t uidCount;
	uint8_t TotalCard;
	uint8_t tmpTotal;
	uint8_t *tmpStr;
	uint8_t rxlen;
	
	
	nfcV_Command_t nfcV_command = V_NOCOMMAND;

	if((args->count > 4) || (args->count == 0))
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nInvalid argument"
				   "\r\nERROR\r\n", 27);
	}
	else if(args->count == 1)
	{
		tmplen = shell_str_len(args->args[0].val);
		/*Help option command*/
		if(shell_str_cmp(args->args[0].val, "-h", tmplen, 2) == 0)
		{
			const char menu[] = "\r\nUsage: v -setup : ISO15693 configuration (TX: 1 out of 4, RX: 1 Sub High)"
					   "\r\n       v -inv1 : ISO15693 inventory 1 slot command"
					   "\r\n       v -inv16: ISO15693 inventory 16 slot command"
					   "\r\n       v -quiet <UID> : ISO15693 quiet command"
					   "\r\n       v -rd <address in hex> <UID>: Read single block command"
					   "\r\n       v -wr <address in hex> <data in hex> <UID>: Write single block command"
					   "\r\n       v -trans -crc <data in hex> : ISO15693 transparent command with CRC"
					   "\r\n       v -trans -nocrc  <data in hex> : ISO15693 transparent command without CRC"
					   "\r\n"
					   "\r\nEx: v -inv1"
					   "\r\n    Operation Success"
					   "\r\n    <UID response>"
					   "\r\nOK\r\n";
			htk_UART_Transmit(
			(uint8_t *)menu,  strlen(menu));
			return 0;
		}
		else if(shell_str_cmp(args->args[0].val, "-setup", tmplen, 6) == 0)
		{
			BC45_Configuration(CONFIG_15693);
			//htk_UART_Transmit((uint8_t *)"\r\nOperation Success"
			//							"\r\nOK\r\n", 25);
			htk_UART_Transmit((uint8_t*)"\r\nOK\r\n", 6);		
			CommandResultAlert(_SUCCESS_);
			return 0;
		}
		else if(shell_str_cmp(args->args[0].val, "-inv1", tmplen, 5) == 0)
		{
			  mask_len = 0x00;
			  mask_value[0] = 0x00;
			  /*Send inventory 1 slot command*/
			  Resp = ISO15693_Inv_Req_1_Slot(ISO15693_Speed, 0x00, 0x00,
					  	  mask_len, &mask_value[0], rx_buffer, &rx_len);
			  if(Resp == _SUCCESS_)
			  {
				//htk_UART_Transmit((uint8_t *)"\r\nOperation Success", 19);
				#if 0
				htk_UART_Transmit((uint8_t*)"\r\nUID: ", 7);
				for(counter = 0; counter < rx_len; counter++)
				{
					dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
				}
				htk_UART_Transmit(tx_buffer, counter * 2);
				htk_UART_Transmit((uint8_t*)"\r\nOK\r\n", 6);
				#else
				
				htk_UART_Transmit((uint8_t*)"\r\n",2);	
				UID15693_BytesToChar(&rx_buffer[0], &tx_buffer[0], &rxlen, INV_1_SLOT);
				htk_UART_Transmit(tx_buffer, rxlen);
				htk_UART_Transmit((uint8_t*)"OK\r\n", 4);
				#endif
			  }
			  else
			  {
			    htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
			     							 "\r\nERROR\r\n", 27);
			  }
		}
		else if(shell_str_cmp(args->args[0].val, "-inv16", tmplen, 6) == 0)
		{
			htk_UART_Transmit((uint8_t *)"\r\nInventory 16 slots command", 28);

			mask_len = 0;
			mask_value[0] = 0;
			collFlag = 0;
			collCount = 0;
			collSlot = 0;
			for(counter = 0; counter < 16; counter++)
			{
				collPos[counter] = 0;
			}
			TotalCard = 0;
			tmpTotal = 0;

			Resp = BC45_ISO15693_Inven16Slots(ISO15693_Speed, mask_len, mask_value,
											  &collFlag, collPos, &UID[0][0], &tmpTotal);

			if(tmpTotal != 0)
			{
				htk_UART_Transmit((uint8_t*)"\r\n",2);	
				TotalCard += tmpTotal;
				for(counter = 0; counter < tmpTotal; counter++)
				{
					// Send UID through serial communication
					#if 0
					htk_UART_Transmit((uint8_t*)"UID: ", 5);
					for(uidCount = 0; uidCount < 9; uidCount++)
					{
						dataToHex(&tx_buffer[uidCount*2], UID[counter][uidCount]);
					}
					htk_UART_Transmit(tx_buffer, uidCount * 2);
					htk_UART_Transmit((uint8_t*)"\r\n",2);	
					#else
					UID15693_BytesToChar(UID[counter], &tx_buffer[0], &rxlen, INV_1_SLOT);
					htk_UART_Transmit(tx_buffer, rxlen);
					#endif
				}
			}

			if(collFlag == 1)
			{
				//Check the collision position
				for(counter = 0; counter < 16; counter++)
				{
					if(collPos[counter] == 1)
					{
						collCount++;
					}
				}
			}

			while(collCount != 0)
			{
				for(counter = 0; counter < 16; counter++)
				{
					if(collPos[counter] == 1)
					{
						collSlot = counter;
						break;
					}
				}

				mask_len = mask_len + 4;

				if((mask_len % 8) != 0)
				{
					mask_value[mask_len/8] = counter;
				}
				else
				{
					counter = counter << 4;
					mask_value[(mask_len/8) - 1] |= counter;
				}

				//Clear collision flag
				collFlag = 0;

				Resp = BC45_ISO15693_Inven16Slots(ISO15693_Speed, mask_len, mask_value,
												   &collFlag, collPos, &UID[0][0], &tmpTotal);

				if(tmpTotal != 0)
				{
					TotalCard += tmpTotal;
					for(counter = 0; counter < tmpTotal; counter++)
					{
						#if 0
						//Send UID through serial communication
						htk_UART_Transmit((uint8_t*)"\r\nUID: ", 7);
						for(uidCount = 0; uidCount < 9; uidCount++)
						{
							dataToHex(&tx_buffer[uidCount*2], UID[counter][uidCount]);
						}
						htk_UART_Transmit(tx_buffer, uidCount * 2);
						#else
						UID15693_BytesToChar(UID[counter], &tx_buffer[0], &rxlen, INV_1_SLOT);
						htk_UART_Transmit(tx_buffer, rxlen);
						#endif
					}
				}

				if(collFlag == 0)
				{
					collCount--;
					mask_len = 0;
					collPos[collSlot] = 0;
				}
			}

			//Show total card
			htk_UART_Transmit((uint8_t*)"\r\nTotal Card: ", 14);
			data_to_dec(tx_buffer, TotalCard);
			htk_UART_Transmit(tx_buffer, 2);
			htk_UART_Transmit((uint8_t*)"\r\n", 2);
			htk_UART_Transmit((uint8_t*)"OK\r\n", 4);
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
		}
	}
	else if(args->count == 2)
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-quiet", tmplen, 6) == 0)
		{
			tmplen = shell_str_len(args->args[1].val);
			if((tmplen >= 16) && (tmplen <= 18))
			{
				tmpStr = (uint8_t *)args->args[1].val;
				for(counter = 0; counter < (tmplen/2); counter++)
				{
					status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter]);
					if(status != 0x00)
					{
						htk_UART_Transmit(
						(uint8_t *)"\r\nWrong UID input. Please re-check"
								   "\r\nERROR\r\n", 43);
						CommandResultAlert(FAILED);
						return 0;
					}
				}

				tx_len = counter;
				Resp = ISO15693_Stay_Quiet(ISO15693_Speed, 0x00, tx_buffer, rx_buffer, &rx_len) ;

				if(Resp == _SUCCESS_)
				{
					htk_UART_Transmit((uint8_t *)"\r\nOperation Success"
												 "\r\nOK\r\n", 25);
				}
				else
				{
			    	htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
			    	 							 "\r\nERROR\r\n", 27);
				}				
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nWrong UID's length"
						   "\r\nERROR\r\n", 29);
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
		}
	}
	else if(args->count == 3)//Transparent and read single block command
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-trans", tmplen, 6) == 0)
		{
			//Check CRC configuration
			tmplen = shell_str_len(args->args[1].val);
			if(shell_str_cmp(args->args[1].val, "-crc", tmplen, 4) == 0)
			{
				nfcV_command = V_TRANS_CRC;
			}
			else if(shell_str_cmp(args->args[1].val, "-nocrc", tmplen, 6) == 0)
			{
				nfcV_command = V_TRANS_NOCRC;
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nUnavailable argument"
						   "\r\nERROR\r\n", 31);
				nfcV_command = V_NOCOMMAND;
				CommandResultAlert(FAILED);
				return 0;
			}

			//Transform data for transmission
			if(nfcV_command != V_NOCOMMAND)
			{
				tmplen = shell_str_len(args->args[2].val);
				if((tmplen >= 2) && (tmplen <= 128))
				{
					tmpStr = (uint8_t *)args->args[2].val;
					for(counter = 0; counter < (tmplen/2); counter++)
					{
						status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter]);
						if(status != 0x00)
						{
							htk_UART_Transmit(
							(uint8_t *)"\r\nWrong data input. Please re-check"
									   "\r\nERROR\r\n", 44);
							CommandResultAlert(FAILED);
							return 0;
						}
					}

					tx_len = counter;
					if(nfcV_command == V_TRANS_CRC)
					{
						Resp = Transparent_With_CRC( tx_buffer, tx_len, 0x0C, rx_buffer, &rx_len );
					}
					else
					{
						Resp = Transparent_Without_CRC( tx_buffer, tx_len, 0x0C, rx_buffer, &rx_len );
					}
				}
				else
				{
					htk_UART_Transmit(
					(uint8_t *)"\r\nUnavailable argument"
							   "\r\nERROR\r\n", 31);
				}
			}

			//Check Response
			switch(Resp)
			 {
			  	case _SUCCESS_:
					htk_UART_Transmit((uint8_t *)"\r\nOperation Success"
										"\r\nTransmit : ", 32);
					htk_UART_Transmit((uint8_t *)args->args[2].val, tmplen);
					htk_UART_Transmit((uint8_t *)"\r\nReceive : ", 12);

		  			for(counter = 0; counter < (uint8_t)rx_len; counter++)
		  			{
		  				dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
		  			}
		  			htk_UART_Transmit(tx_buffer, (rx_len * 2));
		  			htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
			   		break;
			     case NO_RESPONSE:
			       	htk_UART_Transmit((uint8_t*)"\r\nNo Response"
			       								"\r\nERROR\r\n", 22);
					break;
			     case ASIC_EXE_TIMEOUT:
			       	htk_UART_Transmit((uint8_t*)"\r\nTimeout"
			       								"\r\nERROR\r\n", 18);
			       	break;
			     default:
					htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
					  							 "\r\nERROR\r\n", 27);
					break;
		    }
		}
		else if(shell_str_cmp(args->args[0].val, "-rd", tmplen, 3) == 0)
		{
			tmplen = shell_str_len(args->args[1].val);
			if(tmplen == 2)
			{
				//Convert address
				status = customParseHEX((uint8_t*)args->args[1].val, 2, &tx_buffer[0]);
				if(status == 0x00)
				{
					//Convert UID
					tmplen = shell_str_len(args->args[2].val);
					if((tmplen >= 16) && (tmplen <= 18))
					{
						tmpStr = (uint8_t *)args->args[2].val;
						for(counter = 0; counter < (tmplen/2); counter++)
						{
							status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter + 1]);
							if(status != 0x00)
							{
								htk_UART_Transmit(
								(uint8_t *)"\r\nWrong UID input. Please re-check"
										   "\r\nERROR\r\n", 43);
								return 0;
							}
						}
						tx_len = counter;
					}
					else
					{
						htk_UART_Transmit(
						(uint8_t *)"\r\nWrong UID's length"
								   "\r\nERROR\r\n", 29);
						return 0;
					}

					Resp = ISO15693_Read_Single_Block( ISO15693_Speed, 0x00, &tx_buffer[1], tx_buffer[0], rx_buffer, &rx_len );

					if(Resp == _SUCCESS_)
					{
						htk_UART_Transmit((uint8_t *)"\r\nOperation Success"
										  "\r\nReceive : ", 31);

			  			for(counter = 0; counter < (uint8_t)rx_len; counter++)
			  			{
			  				dataToHex(&tx_buffer[counter*2], rx_buffer[counter]);
			  			}
			  			htk_UART_Transmit(tx_buffer, (rx_len * 2));
			  			htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
					}
					else
					{
				    	htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
				    	 							 "\r\nERROR\r\n", 27);
					}
				}
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nInvalid address"
						   "\r\nERROR\r\n", 26);
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
		}
	}
	else if(args->count == 4)
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-wr", tmplen, 3) == 0)
		{
			//Convert address
			tmplen = shell_str_len(args->args[1].val);
			status = customParseHEX((uint8_t*)args->args[1].val, 2, &tx_buffer[0]);
			if(status == 0x00)
			{
				//Convert data
				tmplen = shell_str_len(args->args[2].val);
				tmpStr = (uint8_t *)args->args[2].val;
				for(counter = 0; counter < (tmplen/2); counter++)
				{
					status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter + 1]);
					if(status != 0x00)
					{
						htk_UART_Transmit(
						(uint8_t *)"\r\nWrong data input. Please re-check"
								   "\r\nERROR\r\n", 44);
						CommandResultAlert(FAILED);
						return 0;
					}
				}

				tx_len = counter;

				//Convert UID
				tmplen = shell_str_len(args->args[3].val);
				if((tmplen >= 16) && (tmplen <= 18))
				{
					tmpStr = (uint8_t *)args->args[3].val;
					for(counter = 0; counter < (tmplen/2); counter++)
					{
						status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter + tx_len + 1]);
						if(status != 0x00)
						{
							htk_UART_Transmit(
							(uint8_t *)"\r\nWrong UID input. Please re-check"
									   "\r\nERROR\r\n", 43);
							CommandResultAlert(FAILED);
							return 0;
						}
					}
				}
				else
				{
					htk_UART_Transmit(
					(uint8_t *)"\r\nWrong UID's length"
							   "\r\nERROR\r\n", 29);
					CommandResultAlert(FAILED);
					return 0;
				}

				Resp = ISO15693_Write_Single_Block( ISO15693_Speed, 0x01, &tx_buffer[tx_len + 1], tx_len,
						&tx_buffer[0], rx_buffer, &rx_len );

				if(Resp == _SUCCESS_)
				{
					htk_UART_Transmit((uint8_t *)"\r\nOperation Success"
												 "\r\nOK\r\n", 24);
				}
				else
				{
				   	htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
				   	 							 "\r\nERROR\r\n", 27);
				}
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nInvalid address"
						   "\r\nERROR\r\n", 26);
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUnavailable argument"
					   "\r\nERROR\r\n", 31);
		}
	}
	else
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nUnavailable argument"
				   "\r\nERROR\r\n", 31 );
	}
	CommandResultAlert(Resp);

	return 0;
}


/**
 *  Polling Loop command
 *
 *  > poll -h
 *  > Usage: -poll
 *           -poll -l : Scan Tag's UID by looping
 *  NOTE: Press any key for breaking loop.
 *
 *  Ex: poll
 *      Scanning a Tag ISO14443A
 *      Scanning a Tag ISO14443B
 *      Scanning a Tag ISO15693
 *
 */
int bc45_shell_command_polling_loop(shell_cmd_args * args)
{
	uint8_t tmplen,status, mask;
	uint8_t return_t;
	uint8_t Running_state;
	/* check arguments */
	if(args->count > 2)
	{
        htk_UART_Transmit(
		(uint8_t *)"\r\nInvalid argument"
                   "\r\nERROR\r\n", 27);
	}
	else if(args->count == 2)
	{
		tmplen = strlen(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-start", tmplen, 6) == 0)
		{
			runningLoop = 1;
			htk_UART_Transmit((uint8_t *)"\r\nScanning...\r\n",15);
			htk_UART_Transmit(
			(uint8_t*)"Press any key to stop...\r\n",
			26);
			
			tmplen = strlen(args->args[1].val);
			status = customParseHEX((uint8_t *)args->args[1].val, tmplen, &mask);
			if(status == 0x00)
			{
				typeMask = mask;
			}

		}		/* Loop for scanning option command */
		else if(shell_str_cmp(args->args[0].val, "-l", tmplen, 2) == 0)
		{
			htk_UART_Transmit(
			(uint8_t*)"\r\nLoop running start..."
			"\r\nOK\r\n", 29);

			tmplen = strlen(args->args[1].val);
			status = customParseHEX((uint8_t *)args->args[1].val, tmplen, &mask);
			if(status == 0x00)
			{
				typeMask = mask;
			}

			runningLoop = 1;

			/*Off On field @1st time*/
			BC45_RF_OnOff(RFRESET);

			while(runningLoop)
			{
				/*Scanning a Tag ISO14443A*/
				if(typeMask & 0x01)
				{
					tag_type = ISO14443A_TagType;
					BC45_ConfigurationNoOfffield(CONFIG_14443A);
					//htk_UART_Transmit((uint8_t *)"\r\nScanning a Tag ISO14443A",26);
					return_t = ScanCertificateFlow_ISO14443ATagType(&Running_state);
					if(return_t == _SUCCESS_ )
					{
						/*No execute next command and No off field*/
						//runningLoop = 0;
						//break;
					}
					else
					{
						if(Running_state != 0)
						{
							/*No execute next command and off field*/
							BC45_RF_OnOff(RFRESET);
							//runningLoop = 0;
							//break;
						}
					}
					Delay_ms(5);
				}
				
				/*Scanning a Tag ISO14443B*/
				if(typeMask & 0x02)
				{
					tag_type = ISO14443B_TagType;
					BC45_ConfigurationNoOfffield(CONFIG_14443B);
					//htk_UART_Transmit((uint8_t *)"\r\nScanning a Tag ISO14443B",26);
					return_t = ScanCertificateFlow_ISO14443BTagType(&Running_state);
					if(return_t == _SUCCESS_ )
					{
						/*No execute next command and No off field*/
						//runningLoop = 0;
						//break;
					}
					else
					{
						if(Running_state != 0)
						{
							/*No execute next command and off field*/
							BC45_RF_OnOff(RFRESET);
							//runningLoop = 0;			//crystal
							//break;
						}
					}
					Delay_ms(5);
				}
				
				/*Scanning a Tag ISO15693*/
				if(typeMask & 0x04)
				{
					tag_type = ISO15693_TagType;
					BC45_ConfigurationNoOfffield(CONFIG_15693);
					//htk_UART_Transmit((uint8_t *)"\r\nScanning a Tag ISO15693",25);
					return_t = ScanCertificateFlow_ISO15693TagType(&Running_state);
					if(return_t == _SUCCESS_ )
					{
						/*No execute next command and No off field*/
						//runningLoop = 0;
						//break;
					}
					else
					{
						if(Running_state != 0)
						{
							/*No execute next command and off field*/
							BC45_RF_OnOff(RFRESET);
							//runningLoop = 0;
							//break;
						}
					}
					Delay_ms(5);
				}

				/*Close field before next loop*/
				BC45_RF_OnOff(RFRESET);
			}

			/*Check loop scanning is stopped */
			if(runningLoop == 0)
			{
				htk_UART_Transmit(
				(uint8_t*)"\r\nStop loop running"
				"\r\nOK\r\n", 25);
			}
	}
	else if(args->count == 1)
	{
		tmplen = shell_str_len(args->args[0].val);
		/*Help option command*/
		if(shell_str_cmp(args->args[0].val, "-h", tmplen, 2) == 0)
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nUsage: -poll"
			"\r\n       -poll -l : Scan Tag's UID by looping"
			"\r\nNOTE: Press any key for breaking loop."
			"\r\n"
			"\r\nEx: poll"
			"\r\n    Scanning a Tag ISO14443A"
			"\r\n    Scanning a Tag ISO14443B"
			"\r\n    Scanning a Tag ISO15693"
			"\r\n    OK\r\n", 210
			);
		}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nInvalid argument"
			"\r\nFAIL\r\n", 26);
		}
	}
	/*Scan a tag by once time*/
	else
	{
		/*Scanning a Tag ISO14443A*/
		tag_type = ISO14443A_TagType;
		BC45_RF_OnOff(RFRESET);
		BC45_ConfigurationNoOfffield(CONFIG_14443A);
		htk_UART_Transmit((uint8_t *)"\r\nScanning a Tag ISO14443A\r\n",28);
		return_t = ScanCertificateFlow_ISO14443ATagType(&Running_state);
		if(return_t == _SUCCESS_ )
		{
			/*No execute next command and No off field*/
			return 0;
		}
		else
		{
			if(Running_state != 0)
			{
				/*No execute next command and off field*/
				BC45_RF_OnOff(RFRESET);
				return 0;
			}
		}

		/*Scanning a Tag ISO14443B*/
		tag_type = ISO14443B_TagType;
		BC45_ConfigurationNoOfffield(CONFIG_14443B);
		htk_UART_Transmit((uint8_t *)"\r\nScanning a Tag ISO14443B",26);
		return_t = ScanCertificateFlow_ISO14443BTagType(&Running_state);
		if(return_t == _SUCCESS_ )
		{
			/*No execute next command and No off field*/
			return 0;
		}
		else
		{
			if(Running_state != 0)
			{
				/*No execute next command and off field*/
				BC45_RF_OnOff(RFRESET);
				return 0;
			}
		}

		/*Scanning a Tag ISO15693*/
		tag_type = ISO15693_TagType;
		BC45_ConfigurationNoOfffield(CONFIG_15693);
		htk_UART_Transmit((uint8_t *)"\r\nScanning a Tag ISO15693",25);
		return_t = ScanCertificateFlow_ISO15693TagType(&Running_state);
		if(return_t == _SUCCESS_ )
		{
			/*No execute next command and No off field*/
			return 0;
		}
		else
		{
			if(Running_state != 0)
			{
				/*No execute next command and off field*/
				BC45_RF_OnOff(RFRESET);
				return 0;
			}
		}
	}
	return 0;
}



/*
 * MIFARE read/write memory command
 */
int bc45_shell_command_mifare(shell_cmd_args *args)
{
    uint16_t i = 0;
    uint8_t  tmpBuffer[64] = {0,};
    uint8_t  tmpCnt  = 0;
    uint8_t  tmpLen  = 0;
    uint8_t  tmpData = 0;

    uint8_t  tmpKey[12]  = "000000000000";
    uint8_t  keyType     =  0;
    uint8_t  keyVal[6]   = {0,};
    uint8_t  blockNum    =  0;
    uint8_t  dataTmp[32] = "00000000000000000000000000000000";
    uint8_t  dataVal[16] = {0,};

    uint8_t  rxData[64] = {0,};
    uint16_t rxDataLen  =  0;
    uint8_t  status = FAILED;

    // ISO14443A Configuration
    BC45_Configuration(CONFIG_14443A);

    tmpCnt = args->count;
    if(tmpCnt == 0)
    {
        htk_UART_Transmit((uint8_t *)"\r\nUsage: mifare -h"
                                     "\r\nOK\r\n", 24);
    }
    else
    {
        tmpLen = shell_str_len(args->args[0].val);
        // help options
        if(shell_str_cmp(args->args[0].val, "-h", tmpLen, 2) == 0)
        {
            htk_UART_Transmit((uint8_t *)
                    "\r\nUsage: mifare -cread  : MIFARE combo read  block"
                    "\r\n       mifare -cwrite : MIFARE combo write block"
                    "\r\nOK\r\n", 106);
        }
        else if(shell_str_cmp(args->args[0].val, "-cread", tmpLen, 6) == 0)
        {
            // combo command: scan + loadkey + authen + read
            // example: mifare -cread ka ffffffffffff 9
            // READ with KEY-TYPE: A, 0xFFFFFFFFFFFF, BLOCK-NUM: 9

            if(tmpCnt == 2)
            {
                tmpLen = shell_str_len(args->args[1].val);
                if(shell_str_cmp(args->args[1].val, "-h", tmpLen, 2) == 0)
                {
                    // help for 'CREAD' command
                    htk_UART_Transmit((uint8_t *)
                            "\r\nusage: mifare -cread [keyType] [keyValue(HEX)] [blockNum(DEC)]"
                            "\r\n              --"
                            "\r\n              combo read block"
                            "\r\n              keyType  <ka, kb>             : Key-A, Key-B"
                            "\r\n              keyValue <12-bytes ASCII-HEX> : Expand from Key-Value 6 bytes"
                            "\r\n              blockNum <DEC>                : Block-Number in decimal"
                            "\r\n"
                            "\r\nexample: mifare -cread ka FFFFFFFFFFFF 9"
                            "\r\n         **Read Block-Number 9 with KEY-A : 0xFFFFFFFFFFFF"
                            "\r\nOK\r\n", 432);
                }
                else
                {
                    // FAILED invalid parameter
                    htk_UART_Transmit((uint8_t *)
                            "\r\nInvalid parameter. See mifare -cread -h"
                            "\r\nERROR\r\n", 50);
                }
            }
            else if(tmpCnt == 4)
            {
                // 1.check keyType <KEY-A, KEY-B>
                tmpLen = shell_str_len(args->args[1].val);
                if(shell_str_cmp(args->args[1].val, "ka", tmpLen, 2) == 0)
                {
                    keyType = USE_KEY_A;
                }
                else if(shell_str_cmp(args->args[1].val, "kb", tmpLen, 2) == 0)
                {
                    keyType = USE_KEY_B;
                }
                else
                {
                    // FAILED
                    htk_UART_Transmit((uint8_t *)
                            "\r\nInvalid keyType. See mifare -cread -h"
                            "\r\nERROR\r\n", 48);
										CommandResultAlert(FAILED);
                    return -1;
                }

                // 2.check keyValue (6-bytes HEX)
                tmpLen = shell_str_len(args->args[2].val);
                if(tmpLen > 12)
                {
                    // FAILED
                    htk_UART_Transmit((uint8_t *)
                            "\r\nInvalid keyValue. See mifare -cread -h"
                            "\r\nERROR\r\n", 49);
									  CommandResultAlert(FAILED);
                    return -1;
                }
                else
                {
                    // (HEX ONLY)---------------------------------------------//
                    for(i = 0; i < tmpLen; i++)
                    {
                        if((args->args[2].val[i] < '0') || (args->args[2].val[i] > '9'))
                        {
                            if((args->args[2].val[i] < 'a') || (args->args[2].val[i] > 'f'))
                            {
                                htk_UART_Transmit((uint8_t *)
                                        "\r\nInvalid keyValue. See mifare -cread -h"
                                        "\r\nERROR\r\n", 49);
															  CommandResultAlert(FAILED);
                                return -1;
                            }
                        }
                    }
                    //--------------------------------------------------------//

                    if(tmpLen < 12) // Need padding zero
                    {               // EX. aabb = 00000000aabb
                        for(i = 0; i < tmpLen; i++)
                        {
                            tmpKey[12 - (tmpLen - i)] = args->args[2].val[i];
                        }
                        // convert to HEX and copy to keyValue buffer
                        for(i = 0; i < 6; i++)
                        {
                            customParseHEX((uint8_t *)&tmpKey[i * 2], 2, &tmpData);
                            keyVal[i] = tmpData;
                        }
                    }
                    else // equal 12, no need to padding
                    {
                        for(i = 0; i < 6; i++)
                        {
                            customParseHEX((uint8_t *)&args->args[2].val[i * 2], 2, &tmpData);
                            keyVal[i] = tmpData;
                        }
                    }
                }

                // 3.check block number
                // (DECIMAL ONLY) --------------------------------------------//
                tmpLen = shell_str_len(args->args[3].val);
                for(i = 0; i < tmpLen; i++)
                {
                    if((args->args[3].val[i] < '0') || (args->args[3].val[i] > '9'))
                    {
                        htk_UART_Transmit((uint8_t *)
                                "\r\nInvalid blockNumber. See mifare -cread -h"
                                "\r\nERROR\r\n", 52);
											  CommandResultAlert(FAILED);
                        return -1;
                    }
                }
                //------------------------------------------------------------//
                blockNum = (uint8_t)shell_parse_int(args->args[3].val);

                // printout information
                htk_UART_Transmit((uint8_t*)
                        "\r\nMIFARE-COMBO-READ > KEY-TYPE:", 31);
                if(keyType == USE_KEY_A)
                {
                    htk_UART_Transmit((uint8_t*)" A, 0x", 6);
                }
                else
                {
                    htk_UART_Transmit((uint8_t*)" B, 0x", 6);
                }
                for(i = 0; i < 6; i++)
                {
                    dataToHex(&tmpBuffer[i * 2], keyVal[i]);
                }
                htk_UART_Transmit(tmpBuffer, 12);
                htk_UART_Transmit((uint8_t*)", BLOCK-NUM: ", 13);
                htk_UART_Transmit((uint8_t*)args->args[3].val, tmpLen);

                // operate command
                status = ISO14443A_Req_Anti_Select_LoadKey_Authent_Read(
                                REQ_MODE_REQA,
                                0x00,
                                keyType,
                                keyVal,
                                blockNum,
                                rxData,
                                &rxDataLen);
                if(status == _SUCCESS_)
                {
                    // printout data
                    htk_UART_Transmit((uint8_t*)"\r\n\nUID:  ", 9);
                    tmpLen = rxDataLen - 16; // Minus 16 : Neglect data block size
                    for(i = 0; i < tmpLen; i++)
                    {
                        dataToHex(&tmpBuffer[i * 2], rxData[i]);
                    }
                    htk_UART_Transmit(tmpBuffer, (tmpLen * 2));

                    for(i = 0; i < (rxDataLen - tmpLen); i++)
                    {
                        dataToHex(&tmpBuffer[i * 2], rxData[i + tmpLen]);
                    }
                    htk_UART_Transmit((uint8_t*)"\r\nData: ", 8);
                    htk_UART_Transmit(tmpBuffer, ((rxDataLen - tmpLen) * 2));

                    htk_UART_Transmit((uint8_t*)"\r\nOK\r\n", 6);
                }
                else
                {
                    // Signaling with RED LED if no response
                    //LED2_RED_ON();
                    //Delay(100);
                    //LED2_RED_OFF();
                    //Delay(100);

                    htk_UART_Transmit((uint8_t*)"\r\n"
                                                "\r\nERROR\r\n", 11);
                }
            }
            else
            {
                // FAILED invalid parameter
                htk_UART_Transmit((uint8_t *)
                        "\r\nInvalid parameter. See mifare -cread -h"
                        "\r\nERROR\r\n", 50);
            }
        }
        else if(shell_str_cmp(args->args[0].val, "-cwrite", tmpLen, 7) == 0)
        {
            // combo command: scan + loadkey + authen + write
            // example: mifare -cwrite ka ffffffffffff 9 000102030405060708090A0B0C0D0E0F
            // READ with KEY-TYPE: A, 0xFFFFFFFFFFFF, BLOCK-NUM: 9,
            //           DATA: 000102030405060708090A0B0C0D0E0F

            if(tmpCnt == 2)
            {
                tmpLen = shell_str_len(args->args[1].val);
                if(shell_str_cmp(args->args[1].val, "-h", tmpLen, 2) == 0)
                {
                    // help for 'CWRITE' command
                    htk_UART_Transmit((uint8_t *)
                            "\r\nusage: mifare -cwrite [keyType] [keyValue(HEX)] [blockNum(DEC)] [dataValue(HEX)]"
                            "\r\n              --"
                            "\r\n              combo write block"
                            "\r\n              keyType   <ka, kb>             : Key-A, Key-B"
                            "\r\n              keyValue  <12-bytes ASCII-HEX> : Expand from Key-Value 6 bytes"
                            "\r\n              blockNum  <DEC>                : Block-Number in decimal"
                            "\r\n              dataValue <32-bytes ASCII-HEX> : Expand from Data-Value 16 bytes"
                            "\r\n"
                            "\r\nexample: mifare -cwrite ka FFFFFFFFFFFF 9 000102030405060708090A0B0C0D0E0F"
                            "\r\n         **Write Block-Number 9 with KEY-A : 0xFFFFFFFFFFFF"
                            "\r\n           DATA : 000102030405060708090A0B0C0D0E0F"
                            "\r\nOK\r\n", 621);
                }
                else
                {
                    // FAILED invalid parameter
                    htk_UART_Transmit((uint8_t *)
                            "\r\nInvalid parameter. See mifare -cwrite -h"
                            "\r\nERROR\r\n", 51);
                }
            }
            else if(tmpCnt == 5)
            {
                // 1.check keyType <KEY-A, KEY-B>
                tmpLen = shell_str_len(args->args[1].val);
                if(shell_str_cmp(args->args[1].val, "ka", tmpLen, 2) == 0)
                {
                    keyType = USE_KEY_A;
                }
                else if(shell_str_cmp(args->args[1].val, "kb", tmpLen, 2) == 0)
                {
                    keyType = USE_KEY_B;
                }
                else
                {
                    // FAILED
                    htk_UART_Transmit((uint8_t *)
                            "\r\nInvalid keyType. See mifare -cwrite -h"
                            "\r\nERROR\r\n", 49);
									  CommandResultAlert(FAILED);
                    return -1;
                }

                // 2.check keyValue (6-bytes HEX)
                tmpLen = shell_str_len(args->args[2].val);
                if(tmpLen > 12)
                {
                    // FAILED
                    htk_UART_Transmit((uint8_t *)
                            "\r\nInvalid keyValue. See mifare -cwrite -h"
                            "\r\nERROR\r\n", 50);
									  CommandResultAlert(FAILED);
                    return -1;
                }
                else
                {
                    // (HEX ONLY)---------------------------------------------//
                    for(i = 0; i < tmpLen; i++)
                    {
                        if((args->args[2].val[i] < '0') || (args->args[2].val[i] > '9'))
                        {
                            if((args->args[2].val[i] < 'a') || (args->args[2].val[i] > 'f'))
                            {
                                htk_UART_Transmit((uint8_t *)
                                        "\r\nInvalid keyValue. See mifare -cwrite -h"
                                        "\r\nERROR\r\n", 50);
															  CommandResultAlert(FAILED);
                                return -1;
                            }
                        }
                    }
                    //--------------------------------------------------------//

                    if(tmpLen < 12) // Need padding zero
                    {               // EX. aabb = 00000000aabb
                        for(i = 0; i < tmpLen; i++)
                        {
                            tmpKey[12 - (tmpLen - i)] = args->args[2].val[i];
                        }
                        // convert to HEX and copy to keyValue buffer
                        for(i = 0; i < 6; i++)
                        {
                            customParseHEX((uint8_t *)&tmpKey[i * 2], 2, &tmpData);
                            keyVal[i] = tmpData;
                        }
                    }
                    else // equal 12, no need to padding
                    {
                        for(i = 0; i < 6; i++)
                        {
                            customParseHEX((uint8_t *)&args->args[2].val[i * 2], 2, &tmpData);
                            keyVal[i] = tmpData;
                        }
                    }
                }

                // 3.check block number
                // (DECIMAL ONLY) --------------------------------------------//
                tmpLen = shell_str_len(args->args[3].val);
                for(i = 0; i < tmpLen; i++)
                {
                    if((args->args[3].val[i] < '0') || (args->args[3].val[i] > '9'))
                    {
                        htk_UART_Transmit((uint8_t *)
                                "\r\nInvalid blockNumber. See mifare -cwrite -h"
                                "\r\nERROR\r\n", 53);
											  CommandResultAlert(FAILED);
                        return -1;
                    }
                }
                //------------------------------------------------------------//
                blockNum = (uint8_t)shell_parse_int(args->args[3].val);

                // 4.check dataValue (16-bytes HEX)
                tmpLen = shell_str_len(args->args[4].val);
                if(tmpLen > 32)
                {
                    // FAILED
                    htk_UART_Transmit((uint8_t *)
                            "\r\nInvalid dataValue. See mifare -cwrite -h"
                            "\r\nERROR\r\n", 51);
									  CommandResultAlert(FAILED);
                    return -1;
                }
                else
                {
                    // (HEX ONLY)---------------------------------------------//
                    for(i = 0; i < tmpLen; i++)
                    {
                        if((args->args[4].val[i] < '0') || (args->args[4].val[i] > '9'))
                        {
                            if((args->args[4].val[i] < 'a') || (args->args[4].val[i] > 'f'))
                            {
                                htk_UART_Transmit((uint8_t *)
                                        "\r\nInvalid dataValue. See mifare -cwrite -h"
                                        "\r\nERROR\r\n", 51);
															  CommandResultAlert(FAILED);
                                return -1;
                            }
                        }
                    }
                    //--------------------------------------------------------//
                    if(tmpLen < 32) // Need padding zero
                    {
                        // EX. aabb = 00000000 00000000 00000000 0000aabb
                        for(i = 0; i < tmpLen; i++)
                        {
                            dataTmp[32 - (tmpLen - i)] = args->args[4].val[i];
                        }
                        // convert to HEX and copy to dataValue buffer
                        for(i = 0; i < 16; i++)
                        {
                            customParseHEX((uint8_t *)&dataTmp[i * 2], 2, &tmpData);
                            dataVal[i] = tmpData;
                        }
                    }
                    else // equal 32, no need to padding
                    {
                        for(i = 0; i < 16; i++)
                        {
                            customParseHEX((uint8_t *)&args->args[4].val[i * 2], 2, &tmpData);
                            dataVal[i] = tmpData;
                        }
                    }
                }

                // printout information
                htk_UART_Transmit((uint8_t*)
                        "\r\nMIFARE-COMBO-WRITE > KEY-TYPE:", 32);
                if(keyType == USE_KEY_A)
                {
                    htk_UART_Transmit((uint8_t*)" A, 0x", 6);
                }
                else
                {
                    htk_UART_Transmit((uint8_t*)" B, 0x", 6);
                }
                for(i = 0; i < 6; i++)
                {
                    dataToHex(&tmpBuffer[i * 2], keyVal[i]);
                }
                htk_UART_Transmit(tmpBuffer, 12);
                htk_UART_Transmit((uint8_t*)", BLOCK-NUM: ", 13);
                tmpLen = shell_str_len(args->args[3].val);
                htk_UART_Transmit((uint8_t*)args->args[3].val, tmpLen);
                htk_UART_Transmit((uint8_t*)",\r\nDATA-VAL: ", 13);
                for(i = 0; i < 16; i++)
                {
                    dataToHex(&tmpBuffer[i * 2], dataVal[i]);
                }
                htk_UART_Transmit(tmpBuffer, 32);

                // operate command
                status = ISO14443A_Req_Anti_Select_LoadKey_Authent_Write(
                                                REQ_MODE_REQA,
                                                0x00,
                                                keyType,
                                                keyVal,
                                                blockNum,
                                                dataVal,
                                                rxData,
                                                &rxDataLen);
                if(status == _SUCCESS_)
                {
                    // printout data
                    htk_UART_Transmit((uint8_t*)"\r\n\nUID:  ", 9);
                    for(i = 0; i < rxDataLen; i++)
                    {
                        dataToHex(&tmpBuffer[i * 2], rxData[i]);
                    }
                    htk_UART_Transmit(tmpBuffer, (rxDataLen * 2));

                    htk_UART_Transmit((uint8_t*)"\r\nOK\r\n", 6);
                }
                else
                {
                    // Signaling with RED LED if no response
                    //LED2_RED_ON();
                    //Delay(100);
                    //LED2_RED_OFF();
                    //Delay(100);

                    htk_UART_Transmit((uint8_t*)"\r\n"
                                                "\r\nERROR\r\n", 11);
                }
            }
            else
            {
                // FAILED invalid parameter
                htk_UART_Transmit((uint8_t *)
                        "\r\nInvalid parameter. See mifare -cwrite -h"
                        "\r\nERROR\r\n", 51);
            }
        }
        else
        {
            htk_UART_Transmit((uint8_t *)
                    "\r\nInvalid command. See mifare -h"
                    "\r\nERROR\r\n", 41);
        }
    }
    CommandResultAlert(status);
    return 0;
}


/*
 * BC45 mifare read/write memory
 */
uint8_t BC45_Tag2Type_ReadWrite_Block(uint8_t cmd, uint8_t address, uint8_t *data, uint16_t *datalen)
{
	uint8_t i;
	uint8_t Resp;
	uint8_t tx_buffer[64] = {0};
	uint8_t rx_buffer[16] = {0};
	uint16_t tx_len;
	uint16_t rx_len;

	BC45_RF_OnOff(RFOFF);
	Delay(20);
	BC45_RF_OnOff(RFON);
	Delay(20);

	/*Request mode (TypeA)*/
	tx_buffer[0] = 0x00; //Request Type A
	tx_buffer[1] = 0x00;
	/*Combo command type A : Request + AntiColl + Select*/
	Resp = ISO14443A_Command(A_Req_Anti_Sel, tx_buffer, 2, rx_buffer, &rx_len);

	if(Resp == _SUCCESS_)
	{
		//htk_UART_Transmit((uint8_t *)"\r\nOperation Success", 19);
		htk_UART_Transmit((uint8_t *)"\r\nUID: ", 7);
		/*Convert UID type A from HEX to CHAR*/
		UIDTypeA_BytesToChar(&rx_buffer[2], tx_buffer, &rx_len);
		htk_UART_Transmit(tx_buffer, rx_len + 1);
	}
	else
	{
    	htk_UART_Transmit((uint8_t *)"\r\nOperation Failed"
    	 							 "\r\nERROR\r\n", 27);
    	return Resp;
	}


	if(cmd == T2T_READ)
	{
		Resp = ISO14443A_Read_Mifare_Block( address, rx_buffer, &rx_len, CHECK_DISABLE );
		if(Resp == _SUCCESS_)
		{
			htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
			dataToHex(&tx_buffer[0], address);
			htk_UART_Transmit((uint8_t *)tx_buffer, 2);
			htk_UART_Transmit((uint8_t *)"\r\nVAL[HEX]:", 13);
			for(i = 0; i < rx_len; i++)
			{
				dataToHex(&tx_buffer[i * 2], rx_buffer[i]);
			}
			htk_UART_Transmit(tx_buffer, (rx_len * 2));
			htk_UART_Transmit((uint8_t *)"\r\n", 2);
		}
		else
		{
			htk_UART_Transmit((uint8_t *)"\r\nResponse: NAK"
										 "\r\nTag 2 Type read Failed"
	    	 							 "\r\nERROR\r\n", 48);
	    	return Resp;
		}
	}
	else if(cmd == T2T_WRITE)
	{
		/* Convert data from input buffer to tmp buffer*/
		tx_len = *datalen;
		for(i = 0; i < (uint8_t)tx_len; i++)
		{
			tx_buffer[i] = *(data + i);
		}
		Resp = ISO14443A_Write_Mifare_Block(address, tx_buffer, rx_buffer, &rx_len, CHECK_DISABLE);

		if(Resp == _SUCCESS_)
		{
			htk_UART_Transmit((uint8_t *)"\r\nADDR[HEX]: ", 13);
			dataToHex(&tx_buffer[0], address);
			htk_UART_Transmit((uint8_t *)tx_buffer, 2);

			for(i = 0; i < rx_len; i++)
			{
				dataToHex(&tx_buffer[i * 2], rx_buffer[i]);
			}
			htk_UART_Transmit((uint8_t *)"\r\nResponse: ACK\r\n", 15);
		}
		else
		{
			htk_UART_Transmit((uint8_t *)"\r\nResponse: NAK"
										 "\r\nTag 2 Type write Failed"
	    	 							 "\r\nERROR\r\n", 48);
	    	return Resp;
		}
	}
	else
	{
    	htk_UART_Transmit((uint8_t *)"\r\nInvalid Command"
    	 							 "\r\nERROR\r\n", 26);
		return ERROR;
	}

	return Resp;
}



/*
 * Tag 2 type read/write memory command
 */
int bc45_shell_command_t2t(shell_cmd_args * args)
{
	uint8_t tmplen;
	uint8_t address;
	uint8_t counter;
	uint8_t *tmpStr;
	uint8_t status = FAILED;
	uint8_t tx_buffer[16] = {0};
	uint8_t rx_buffer[16] = {0};
	uint16_t rx_len;
	uint16_t tx_len;	

	BC45_Configuration(CONFIG_14443A);

	if((args->count == 0) || (args->count > 3))
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nInvalid argument"
				   "\r\nERROR\r\n", 27);
	}
	else if(args->count == 2)
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-rd", tmplen, 3) == 0)
		{
			/*Convert string address to hex address*/
			tmplen = shell_str_len(args->args[1].val);
			status = customParseHEX((uint8_t *)args->args[1].val, tmplen, &address);
			if(status == 0x00)
			{
				status = BC45_Tag2Type_ReadWrite_Block(T2T_READ, address, rx_buffer, &rx_len);
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nWrong data input. Please re-check"
						   "\r\nERROR\r\n", 44);
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nInvalid argument"
					   "\r\nERROR\r\n", 27);
		}
	}
	else if(args->count == 3)
	{
		tmplen = shell_str_len(args->args[0].val);
		if(shell_str_cmp(args->args[0].val, "-wr", tmplen, 3) == 0)
		{
			/*Convert string address to hex address*/
			tmplen = shell_str_len(args->args[1].val);
			status = customParseHEX((uint8_t *)args->args[1].val, tmplen, &address);
			if(status == 0x00)
			{
				tmplen = shell_str_len(args->args[2].val);
				/* Maximum length of data to be written*/
				if(tmplen <= 32)
				{
					tmpStr = (uint8_t *)args->args[2].val;
					for(counter = 0; counter < (tmplen/2); counter++)
					{
						status = customParseHEX((tmpStr + (counter * 2)), 2, &tx_buffer[counter]);
						if(status != 0x00)
						{
							htk_UART_Transmit(
							(uint8_t *)"\r\nWrong data input. Please re-check"
									   "\r\nERROR\r\n", 44);
							CommandResultAlert(FAILED);
							return 0;
						}
					}

					tx_len = counter;
					status = BC45_Tag2Type_ReadWrite_Block(T2T_WRITE, address, tx_buffer, &tx_len);
				}
				else
				{
					htk_UART_Transmit(
					(uint8_t *)"\r\nWrong data input. Please re-check"
							   "\r\nERROR\r\n", 44);
					CommandResultAlert(FAILED);
					return 0;
				}
			}
			else
			{
				htk_UART_Transmit(
				(uint8_t *)"\r\nWrong data input. Please re-check"
						   "\r\nERROR\r\n", 44);
				CommandResultAlert(FAILED);
				return 0;
			}
		}
		else
		{
			htk_UART_Transmit(
			(uint8_t *)"\r\nInvalid argument"
					   "\r\nERROR\r\n", 27);
		}
	}
	else
	{
		htk_UART_Transmit(
			(uint8_t *)"\r\nUsage: -t2t -rd <block address> : Perform read block command in Tag 2 Type"
					   "\r\n       -t2t -wr <block address> <data in hex>: Perform write block command in Tag 2 Type"
					   "\r\n"
					   "\r\nEx> -t2t -rd 10"
					   "\r\n    Operation Success"
					   "\r\n    UID: xxxx"
					   "\r\n"
					   "\r\n    ADDR[HEX]: 10"
					   "\r\n    VAL[HEX]: <data 16 bytes>"
					   "\r\n    OK\r\n", 285 );
	}
  CommandResultAlert(status);
	return 0;
}

/*
 * Tag 2 type read/write memory command
 */
int bc45_shell_command_reset(shell_cmd_args * args)
{
	
	if((args->count > 0))
	{
		htk_UART_Transmit(
		(uint8_t *)"\r\nInvalid argument"
				   "\r\nERROR\r\n", 27);
	}
	else
	{
		BC45_Configuration(CONFIG_14443A);
		htk_UART_Transmit((uint8_t *)"\r\nOK\r\n", 6);
	}
  CommandResultAlert(_SUCCESS_);
	return 0;
}

/**
 *  shell command processing
 *
 */
uint8_t bc45__shellProcess(uint8_t * commandLine)
{
  uint16_t status;
  /* Modify for use with setup mode of BC45*/
  status = shell_process_cmds(&bc45_shell_cmds, (char *)commandLine);
  switch (status)
  {
    case SHELL_PROCESS_ERR_CMD_UNKN:
    	htk_UART_Transmit((uint8_t *)"\r\nERROR: Unknown command\r\n", 26);
    	break;
    case SHELL_PROCESS_ERR_ARGS_LEN:
    	htk_UART_Transmit((uint8_t *)"\r\nERROR: Argument length\r\n", 26);
    	break;
    case SHELL_PROCESS_ERR_ARGS_MAX:
    	htk_UART_Transmit((uint8_t *)"\r\nERROR: Too many arguments\r\n", 29);
    	break;
    default: // OK
    	break;
  }
  return status;
}

/**
 *  shell command prompt
 *
 */
uint8_t bc45__commandPrompt(uint8_t * pBuffer, uint8_t * pBufferLen,
		                      uint8_t * prompt,  uint8_t promptLen)
{
  static uint8_t startPrompt = 0;
  static uint8_t * pData;
  uint8_t tmpData;
  static uint8_t dataCounter = 0;

  if(startPrompt == 0)
  {
    startPrompt = 1;
    pData = pBuffer;
    * pData = '\0';
    dataCounter = 0;
    htk_UART_Transmit((uint8_t *)prompt, promptLen);
  }
  // Create pBuffer from rxFIFO
  while(rxFIFO.entries > 0)
  {
    // get data from rxFIFO
    htk_ringBufferRead(&rxFIFO, &tmpData);
		switch(tmpData)
		{
			case '\r': // 0x0D Enter
				startPrompt = 0;
				* pBufferLen = dataCounter;
				return (uint8_t)shell_str_len((char *)pBuffer);
			break;
			case 0x08:
			case 0x7F: // delete (127)
				if(pData > pBuffer)
				{
					* (--pData) = '\0';
					dataCounter--;
					htk_UART_Transmit(&tmpData, 1);
				}
			break;
			default:
				if((tmpData >= ' ')&&(tmpData < 127))
				{
					* pData++ = tmpData;
					* pData = '\0';
					dataCounter++;
					htk_UART_Transmit(&tmpData, 1);
				}
			break;
		}
  }
  return 0;
}

/* Global functions ----------------------------------------------------------------------------------------*/
/*
 * @brief Configure BC45 tag type communication
 * @param tagtype: Tag type definition
 *                 - CONFIG_14443A
 *                 - CONFIG_14443B
 *                 - CONFIG_15693
 * @retval None
 * */
void BC45_Configuration(uint8_t tagtype)
{	
  /*Re-Init BC45 reader and turn on RF field*/
  Initial_BC45_Board();
	
  BC45_Board_ASIC_Command(OFF_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);
  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);

  /*Configure tag type communication*/
  switch(tagtype)
  {
    case CONFIG_14443A:
      Resp = ISO14443A_Command(A_Config_ISO14443A, NULL, 0, &Data_Resp[0], &Len_Resp);
      htk_SPI_writeSingleRegister(ModWidth, 0x11);
      htk_SPI_writeSingleRegister(ModWidthSOF, 0x11);
      if(Resp != _SUCCESS_)
      {
    	  htk_UART_Transmit((uint8_t*)"\r\nISO14443A Configuration failed", 34);
      }
      else
      {
    	  //htk_UART_Transmit((uint8_t*)"\r\nISO14443A Configuration success", 35);
      }
      break;
    case CONFIG_15693:
      Resp = ISO15693_Config(ISO15693_Speed);
      if(Resp != _SUCCESS_)
      {
    	  htk_UART_Transmit((uint8_t*)"\r\nISO15693 Configuration failed", 33);
      }
      else
      {
    	  //htk_UART_Transmit((uint8_t*)"\r\nISO15693 Configuration success", 34);
      }
      break;
    case CONFIG_14443B:
      Resp = ISO14443B_Command(B_Config_ISO14443B, NULL, 0, &Data_Resp[0], &Len_Resp);
      if(Resp != _SUCCESS_)
      {
    	  htk_UART_Transmit((uint8_t*)"\r\nISO14443B Configuration failed", 34);
      }
      else
      {
    	  //htk_UART_Transmit((uint8_t*)"\r\nISO14443B Configuration success", 35);
      }
      break;
    default:
      Resp = ERROR;
      htk_UART_Transmit((uint8_t*)"\r\nBC45 Configuration failed",29);
      break;
  }
}


/*
 * @Display ADC result I and Q
 * @retval None
 * */
void Display_ADC_I_Q(void)
{
  uint8_t reg_value;
  uint8_t dataTrans[8];

  /*Read system control register address 0x09*/
  htk_SPI_readSingleRegister(SYSTEM_CONTROL, &reg_value);
  byteToChar(&reg_value, &dataTrans[0]);
  htk_UART_Transmit((uint8_t*)"System Control reg: ", 20);
  htk_UART_Transmit(&dataTrans[0], 4);

  /*Read wake up timer control register address 0x2D*/
  htk_SPI_readSingleRegister(WAKEUP_TIME_CONTROL, &reg_value);
  byteToChar(&reg_value, &dataTrans[0]);
  htk_UART_Transmit((uint8_t*)"WKUP Time Control reg: ", 23);
  htk_UART_Transmit(&dataTrans[0], 4);

  /*Read ADC I result*/
  htk_SPI_readSingleRegister(ADC_RESULT_I, &reg_value);
  byteToChar(&reg_value, &dataTrans[0]);
  htk_UART_Transmit((uint8_t*)"ADC Res I\r\n", 11);
  htk_UART_Transmit( &dataTrans[0], 4);

  /*Read ADC Q result*/
  htk_SPI_readSingleRegister(ADC_RESULT_Q, &reg_value);
  byteToChar(&reg_value, &dataTrans[0]);
  htk_UART_Transmit((uint8_t*)"ADC Res Q\r\n", 11);
  htk_UART_Transmit( &dataTrans[0], 4);
}


/*
 * @brief Configure BC45 tag type communication
 * @param tagtype: Tag type definition
 *                 - CONFIG_14443A
 *                 - CONFIG_14443B
 *                 - CONFIG_15693
 * @retval None
 * */
void BC45_ConfigurationNoOfffield(uint8_t tagtype)
{
	int i;
  /*Re-Init BC45 reader and turn on RF field*/
  //Initial_BC45_Board();
  //BC45_Board_ASIC_Command(OFF_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  //Delay(50);
  //BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);

  /*Configure tag type communication*/
  switch(tagtype)
  {
    case CONFIG_14443A:
      Resp = ISO14443A_Command(A_Config_ISO14443A, NULL, 0, &Data_Resp[0], &Len_Resp);
      htk_SPI_writeSingleRegister(ModWidth, 0x11);
      htk_SPI_writeSingleRegister(ModWidthSOF, 0x11);

			//crystal
			htk_SPI_writeSingleRegister(0x00, 0x01);	//sector1
			for(i=0;i<nfca1.nIdx;i++)
				htk_SPI_writeSingleRegister(nfca1.addr[i], nfca1.data[i]);
			htk_SPI_writeSingleRegister(0x00, 0x00);	//sector0
			for(i=0;i<nfca0.nIdx;i++)
				htk_SPI_writeSingleRegister(nfca0.addr[i], nfca0.data[i]);
				
      if(Resp != _SUCCESS_)
      {
    	  htk_UART_Transmit((uint8_t*)"\r\nISO14443A Configuration failed\r\n", 32);
      }
      else
      {
    	  //htk_UART_Transmit((uint8_t*)"\r\nISO14443A Configuration success\r\n", 33);
      }
      break;
    case CONFIG_15693:
      Resp = ISO15693_Config(ISO15693_Speed);
      if(Resp != _SUCCESS_)
      {
    	  htk_UART_Transmit((uint8_t*)"\r\nISO15693 Configuration failed\r\n", 31);
      }
      else
      {
    	  //htk_UART_Transmit((uint8_t*)"\r\nISO15693 Configuration success\r\n", 32);
      }
      break;
    case CONFIG_14443B:
      Resp = ISO14443B_Command(B_Config_ISO14443B, NULL, 0, &Data_Resp[0], &Len_Resp);
			//crystal
			htk_SPI_writeSingleRegister(0x00, 0x01);	//sector1
			for(i=0;i<nfcb1.nIdx;i++)
				htk_SPI_writeSingleRegister(nfcb1.addr[i], nfcb1.data[i]);
			htk_SPI_writeSingleRegister(0x00, 0x00);	//sector0
			for(i=0;i<nfcb0.nIdx;i++)
				htk_SPI_writeSingleRegister(nfcb0.addr[i], nfcb0.data[i]);

		if(Resp != _SUCCESS_)
      {
    	  htk_UART_Transmit((uint8_t*)"\r\nISO14443B Configuration failed\r\n", 32);
      }
      else
      {
    	  //htk_UART_Transmit((uint8_t*)"\r\nISO14443B Configuration success\r\n", 33);
      }
      break;
    default:
      Resp = ERROR;
      htk_UART_Transmit((uint8_t*)"\r\nBC45 Configuration failed\r\n",27);
      break;
  }
}


/*
 * @brief Scan UID of an ISO14443A tag type
 * @param	None
 * @retval 	Response from scanning
 * 			- _SUCCESS_
 * 			- NO_RESPONSE
 *			- ERROR
 * 			- ASIC_EXE_TIMEOUT
 * */
uint8_t ScanUID_ISO14443ATagType(void)
{
  uint8_t response;
	
	//Len_Resp = 0;

  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);

  /*Request mode (TypeA)*/
  Data_Trans[0] = REQ_MODE_REQA;
  Data_Trans[1] = 0x00;
  /*Combo command type A : Request + AntiColl + Select*/
  Resp = ISO14443A_Command(A_Req_Anti_Sel, Data_Trans, 2, Data_Resp, &Len_Resp);
  /*Check Response from type A transmitted command*/
	switch(Resp)
	{
		case _SUCCESS_:
			//htk_UART_Transmit( (uint8_t*)"Success\r\n", 9);
			/*Convert UID type A from HEX to CHAR*/
			UIDTypeA_BytesToChar(&Data_Resp[2], Data_Trans, &Len_Resp);
			htk_UART_Transmit(Data_Trans, Len_Resp);
		  htk_UART_Transmit((uint8_t*)"\r\n", 2);

			#if 0
			/*Signaling with green LED if success*/
			LED_GREEN_ON();
			Delay(100);
			LED_GREEN_OFF();
			Delay(100);
		
			GPTM0_CH2_SetOnduty(50);
			Delay_ms(100);
			GPTM0_CH2_SetOnduty(0);
			Delay_ms(100);
			#endif

			response = _SUCCESS_;
			CommandResultAlert(response);
			break;
		case NO_RESPONSE:
			//htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);

			#if 0
			/*Signaling with RED LED if no response*/
			LED_RED_ON();
			Delay(100);
			LED_RED_OFF();
			Delay(100);
			#endif

			response = NO_RESPONSE;
			break;
		case ASIC_EXE_TIMEOUT:
			htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
			response = ASIC_EXE_TIMEOUT;
			break;
		default:
			htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);

			#if 0
			/*Signaling with BLUE LED if received error*/
			LED_GREEN_ON();
			Delay(100);
			LED_GREEN_OFF();
			Delay(100);
			LED_RED_ON();
			Delay(100);
			LED_RED_OFF();
			Delay(100);
			#endif

			response = ERROR;
			break;
    }

    BC45_Board_ASIC_Command(OFF_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
    Delay(50);
    BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
    Delay(50);		
    return response;
}

uint8_t SelectUID_ISO14443ATagType(void)
{
  uint8_t response;

  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);

  /*Request mode (TypeA)*/
  Data_Trans[0] = REQ_MODE_REQA;
  Data_Trans[1] = 0x00;
  /*Combo command type A : Request + AntiColl + Select*/
  Resp = ISO14443A_Command(A_Req_Anti_Sel, Data_Trans, 2, Data_Resp, &Len_Resp);
  /*Check Response from type A transmitted command*/
   switch(Resp)
    {
    	case _SUCCESS_:
    		htk_UART_Transmit( (uint8_t*)"Success\r\n", 11);
    		/*Convert UID type A from HEX to CHAR*/
    		UIDTypeA_BytesToChar(&Data_Resp[2], Data_Trans, &Len_Resp);
    		htk_UART_Transmit(Data_Trans, Len_Resp+1);

    		/*Signaling with green LED if success*/
    		LED_GREEN_ON();
    		Delay(100);
    		LED_GREEN_OFF();
    		Delay(100);

    		response = _SUCCESS_;
    		break;
        case NO_RESPONSE:
        	htk_UART_Transmit((uint8_t*)"No Response\r\n", 15);

        	/*Signaling with RED LED if no response*/
    		LED_RED_ON();
    		Delay(100);
    		LED_RED_OFF();
    		Delay(100);

			response = NO_RESPONSE;
			break;
        case ASIC_EXE_TIMEOUT:
        	htk_UART_Transmit((uint8_t*)"Timeout\r\n", 11);
        	response = ASIC_EXE_TIMEOUT;
        	break;
        default:
        	htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 17);

        	/*Signaling with BLUE LED if received error*/
    		LED_GREEN_ON();
    		Delay(100);
    		LED_GREEN_OFF();
    		Delay(100);
    		LED_RED_ON();
    		Delay(100);
    		LED_RED_OFF();
    		Delay(100);

			response = ERROR;
			break;
    }
    return response;
}

/*
 * @brief Scan UID of an ISO14443B tag type
 * @retval Response from scanning
 *         - _SUCCESS_
 *         - NO_RESPONSE
 *         - ASIC_EXE_TIMEOUT
 *         - ERROR
 * */
uint8_t ScanUID_ISO14443BTagType(void)
{
  uint8_t response;

  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);

  Data_Trans[0] = 0x00;	//AFI coding
  Data_Trans[1] = 0x00; //Slot number
  /*Send command type B wake up for getting PUPI*/
  Resp = ISO14443B_Command(B_WakeUp, Data_Trans, 2, Data_Resp, &Len_Resp);
  /*Check Response type B : Wake up command*/
	switch(Resp)
	{
		case _SUCCESS_:
			//htk_UART_Transmit((uint8_t*)"Success\r\n", 9);
			/*Convert UID type B from HEX to CHAR*/
			UIDTypeB_BytesToChar(&Data_Resp[0], Data_Trans, &Len_Resp);
			htk_UART_Transmit(&Data_Trans[0], Len_Resp);

			#if 0
			/*Signaling with green LED if success*/
			LED_GREEN_ON();
			Delay(100);
			LED_GREEN_OFF();
			Delay(100);
			#endif

			response = _SUCCESS_;
		  CommandResultAlert(response);
			break;
		case NO_RESPONSE:
			//htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);

			#if 0
			/*Signaling with RED LED if no response*/
			LED_RED_ON();
			Delay(100);
			LED_RED_OFF();
			Delay(100);
			#endif

			response = NO_RESPONSE;
			break;
		case ASIC_EXE_TIMEOUT:
			htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
			response = ASIC_EXE_TIMEOUT;
			break;
		default:
			htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);

			#if 0
				/*Signaling with BLUE LED if received error*/
			LED_GREEN_ON();
			Delay(100);
			LED_GREEN_OFF();
			Delay(100);
			LED_RED_ON();
			Delay(100);
			LED_RED_OFF();
			Delay(100);
			#endif

			response = ERROR;
			break;
	}

	BC45_Board_ASIC_Command(OFF_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
	Delay(50);
	BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
	Delay(50);
	return response;
}

uint8_t SelectUID_ISO14443BTagType(void)
{
  uint8_t response;

  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);

  Data_Trans[0] = 0x00;	//AFI coding
  Data_Trans[1] = 0x00; //Slot number
  /*Send command type B wake up for getting PUPI*/
  Resp = ISO14443B_Command(B_WakeUp, Data_Trans, 2, Data_Resp, &Len_Resp);
  /*Check Response type B : Wake up command*/
   switch(Resp)
    {
    	case _SUCCESS_:
    		  htk_UART_Transmit((uint8_t*)"Success\r\n", 9);
    		  /*Convert UID type B from HEX to CHAR*/
    		  UIDTypeB_BytesToChar(&Data_Resp[0], Data_Trans, &Len_Resp);
    		  htk_UART_Transmit(&Data_Trans[0], Len_Resp+1);

			#if 0
    		  /*Signaling with green LED if success*/
    		  LED_GREEN_ON();
    		  Delay(100);
    		  LED_GREEN_OFF();
    		  Delay(100);
			#endif

			  response = _SUCCESS_;
				CommandResultAlert(response);
			  break;
        case NO_RESPONSE:
        	  //htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);

				#if 0
        	  /*Signaling with RED LED if no response*/
        	  LED_RED_ON();
        	  Delay(100);
        	  LED_RED_OFF();
        	  Delay(100);
				#endif

			  response = NO_RESPONSE;
			  break;
        case ASIC_EXE_TIMEOUT:
        	  htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
			  response = ASIC_EXE_TIMEOUT;
			  break;
        default:
        	  htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);

				#if 0
        	  /*Signaling with BLUE LED if received error*/
    		  LED_GREEN_ON();
    		  Delay(100);
    		  LED_GREEN_OFF();
    		  Delay(100);
					LED_RED_ON();
					Delay(100);
					LED_RED_OFF();
					Delay(100);
				#endif

			  response = ERROR;
			  break;
    }
    return response;
}

/*
 * @brief Scan UID of an ISO15693 tag type
 * @retval Response from scanning
 *         - _SUCCESS_
 *         - NO_RESPONSE
 *         - ASIC_EXE_TIMEOUT
 *         - ERROR
 * */
uint8_t ScanUID_ISO15693TagType(void)
{
	uint8_t response;
	uint8_t mask_len;
	uint8_t mask_value;
	uint8_t numTags;
	uint8_t countTags;
	uint8_t num_uid;
	uint8_t num_data;
	uint8_t len_data;
	uint8_t iso15693_uid[12] = {0};

  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);

  mask_len = 0x00;
  mask_value = NULL;
  /*Send inventory 1 slot command*/
  Resp = ISO15693_Inv_Req_1_Slot(ISO15693_Speed, 0x00, 0x00,
		  	  mask_len, &mask_value, Data_Resp,  &Len_Resp );

  /*Check response from the inventory 1 slot command*/
  if(Resp == _SUCCESS_)
  {
  	//htk_UART_Transmit((uint8_t*)"Success\r\n", 9);
  	/*Check number of tag (In this case should be 1)*/
   	numTags = (uint8_t)(Len_Resp/8);

    /*Show number of tag (Should be 1)*/
    //byteToChar(&numTags, Data_Trans);
    //htk_UART_Transmit(Data_Trans, 4);
   	/*Clear num_data variable for counting on Data_Resp buffer*/
    num_data = 0;
    /*Store ISO15693 tag's UID*/
    for(countTags = 0; countTags < numTags; countTags++)
    {
      for(num_uid = 0; num_uid < 12; num_uid++)
      {
        iso15693_uid[num_uid] = Data_Resp[num_data];
        num_data++;
      }
      UID15693_BytesToChar(&iso15693_uid[0], &Data_Trans[0], &len_data, INV_1_SLOT);
      htk_UART_Transmit(Data_Trans, len_data+1);
    }

		#if 0
    /*Signaling with green LED if success*/
    LED_GREEN_ON();
		Delay(100);
		LED_GREEN_OFF();
		Delay(100);
		#endif

    response = _SUCCESS_;
		CommandResultAlert(response);
  }
  else
  {
		switch(Resp)
		{
			case NO_RESPONSE:
				//htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);

				 /*Signaling with RED LED if no response*/
				#if 0
				LED_RED_ON();
				Delay(100);
				LED_RED_OFF();
				Delay(100);
				#endif
				response = NO_RESPONSE;
				break;
			case ASIC_EXE_TIMEOUT:
				htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
				response = ASIC_EXE_TIMEOUT;
				break;
			default:
				htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);

				#if 0
				/*Signaling with BLUE LED if received error*/
				LED_GREEN_ON();
				Delay(100);
				LED_GREEN_OFF();
				Delay(100);
				LED_RED_ON();
				Delay(100);
				LED_RED_OFF();
				Delay(100);
				#endif
				response = ERROR;
				break;
		}
  }

  BC45_Board_ASIC_Command(OFF_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);
  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);
  return response;
}

uint8_t SelectUID_ISO15693TagType(void)
{
    uint8_t response;
    uint8_t mask_len;
    uint8_t mask_value;
    uint8_t numTags;
    uint8_t countTags;
    uint8_t num_uid;
    uint8_t num_data;
    uint8_t len_data;
    uint8_t iso15693_uid[12] = {0};

  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(50);

  mask_len = 0x00;
  mask_value = NULL;
  /*Send inventory 1 slot command*/
  Resp = ISO15693_Inv_Req_1_Slot(ISO15693_Speed, 0x00, 0x00,
		  	  mask_len, &mask_value, Data_Resp,  &Len_Resp );

  htk_UART_Transmit((uint8_t*)"\r\n", 2);
  /*Check response from the inventory 1 slot command*/
  if(Resp == _SUCCESS_)
  {
  	htk_UART_Transmit((uint8_t*)"Success\r\n", 9);
  	/*Check number of tag (In this case should be 1)*/
   	numTags = (uint8_t)(Len_Resp/8);

   	/*Clear num_data variable for counting on Data_Resp buffer*/
    num_data = 0;
    /*Store ISO15693 tag's UID*/
    for(countTags = 0; countTags < numTags; countTags++)
    {
      for(num_uid = 0; num_uid < 12; num_uid++)
      {
        iso15693_uid[num_uid] = Data_Resp[num_data];
        num_data++;
      }
      UID15693_BytesToChar(&iso15693_uid[0], &Data_Trans[0], &len_data, INV_1_SLOT);
      htk_UART_Transmit(Data_Trans, len_data+1);
    }

    /*Signaling with green LED if success*/
    LED_GREEN_ON();
	Delay(100);
	LED_GREEN_OFF();
	Delay(100);

    response = _SUCCESS_;
  }
  else
  {
      switch(Resp)
      {
          case NO_RESPONSE:
          	htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);

          	 /*Signaling with RED LED if no response*/
      		LED_RED_ON();
      		Delay(100);
      		LED_RED_OFF();
      		Delay(100);
      		response = NO_RESPONSE;
			break;
          case ASIC_EXE_TIMEOUT:
           	htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
            response = ASIC_EXE_TIMEOUT;
            break;
          default:
          	htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);

          	/*Signaling with BLUE LED if received error*/
    		  LED_GREEN_ON();
    		  Delay(100);
    		  LED_GREEN_OFF();
    		  Delay(100);
					LED_RED_ON();
					Delay(100);
					LED_RED_OFF();
					Delay(100);
            response = ERROR;
            break;
      }
  }
  return response;
}
/*
 * @brief Scan ISO14443A tag type follow certificate Flow
 * @param	None
 * @retval 	Response from scanning
 * 			- _SUCCESS_
 * 			- NO_RESPONSE
 *			- ERROR
 * 			- ASIC_EXE_TIMEOUT
 * */
uint8_t ScanCertificateFlow_ISO14443ATagType(uint8_t *Running_state)
{
	uint8_t response;

	*Running_state = 0;
	/*WUPA mode (TypeA)*/
	Data_Trans[0] = REQ_MODE_REQA;
	Data_Trans[1] = 0x00;
	/*Command type A : WakeUp*/
	Resp = ISO14443A_Command(A_WakeUp,Data_Trans,0,Data_Resp, &Len_Resp);
	/*Check Response from type A transmitted command*/
	switch(Resp)
	{
		case _SUCCESS_:
			//htk_UART_Transmit( (uint8_t*)"\r\nWUPA:", 7);
			////htk_UART_Transmit( (uint8_t*)"Success:0x", 10);
			//UIDTypeA_BytesToChar(&Data_Resp[0], Data_Trans, &Len_Resp);
			//htk_UART_Transmit(&Data_Trans[4], 4);
			//htk_UART_Transmit( (uint8_t*)"\r\n", 2);
		  htk_UART_Transmit( (uint8_t*)"\r\nAOK1", 6);
			response = _SUCCESS_;
			break;
		case NO_RESPONSE:
			//htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);
		  htk_UART_Transmit( (uint8_t*)"A1", 2);
			response = NO_RESPONSE;
			break;
		case ASIC_EXE_TIMEOUT:
			//htk_UART_Transmit( (uint8_t*)"WUPA:", 5);
			//htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
		  htk_UART_Transmit( (uint8_t*)"A2", 2);
			response = ASIC_EXE_TIMEOUT;
			break;
		default:
			//htk_UART_Transmit( (uint8_t*)"WUPA:", 5);
			//htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);
		  htk_UART_Transmit( (uint8_t*)"A3", 2);
			response = ERROR;
			break;
	}

	if(response != _SUCCESS_)
	{
	   return response;
	}

	(*Running_state)++;
	/*SLEEP A mode (TypeA)*/
	Data_Trans[0] = REQ_MODE_REQA;
	Data_Trans[1] = 0x00;
	/*Command type A : WakeUp*/
	//htk_UART_Transmit( (uint8_t*)"SLEEPA:", 7);
	Resp = ISO14443A_Command(A_Halt,Data_Trans,0,Data_Resp, &Len_Resp);
	/*Check Response from type A transmitted command*/
	switch(Resp)
	{
		case _SUCCESS_:
			//htk_UART_Transmit( (uint8_t*)"Success\r\n", 9);
		  htk_UART_Transmit( (uint8_t*)"\r\nAOK2", 6);
			response = _SUCCESS_;
			break;
		case NO_RESPONSE:
			//htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);
		  htk_UART_Transmit( (uint8_t*)"A4", 2);
			response = NO_RESPONSE;
			break;
		case ASIC_EXE_TIMEOUT:
			//htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
		  htk_UART_Transmit( (uint8_t*)"A5", 2);
			response = ASIC_EXE_TIMEOUT;
			break;
		default:
			//htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);
		  htk_UART_Transmit( (uint8_t*)"A6", 2);
			response = ERROR;
			break;
	}

	if(response != _SUCCESS_)
	{
	   return response;
	}

	(*Running_state)++;
	/*Request mode (TypeA)*/
	Data_Trans[0] = REQ_MODE_WUPA;
	Data_Trans[1] = 0x00;
	/*Combo command type A : Request + AntiColl + Select*/
	//htk_UART_Transmit( (uint8_t*)"WUPA+AC+SEL:", 12);
	Resp = ISO14443A_Command(A_Req_Anti_Sel, Data_Trans, 2, Data_Resp, &Len_Resp);
	/*Check Response from type A transmitted command*/
	switch(Resp)
	{
		case _SUCCESS_:
			//htk_UART_Transmit( (uint8_t*)"Success\r\n", 9);
			/*Convert UID type A from HEX to CHAR*/
			//UIDTypeA_BytesToChar(&Data_Resp[2], Data_Trans, &Len_Resp);
			//htk_UART_Transmit(Data_Trans, Len_Resp+1);
		  htk_UART_Transmit( (uint8_t*)"\r\nAOK3", 6);
			response = _SUCCESS_;
			break;
		case NO_RESPONSE:
			//htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);
		  htk_UART_Transmit( (uint8_t*)"A7", 2);
			response = NO_RESPONSE;
			break;
		case ASIC_EXE_TIMEOUT:
			//htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
		  htk_UART_Transmit( (uint8_t*)"A8", 2);
			response = ASIC_EXE_TIMEOUT;
			break;
		default:
			//htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);
		  htk_UART_Transmit( (uint8_t*)"A9", 2);
			response = ERROR;
			break;
	}

	return response;
}

/*
 * @brief Scan ISO14443B tag type follow certificate Flow
 * @retval Response from scanning
 *         - _SUCCESS_
 *         - NO_RESPONSE
 *         - ASIC_EXE_TIMEOUT
 *         - ERROR
 * */
uint8_t ScanCertificateFlow_ISO14443BTagType(uint8_t *Running_state)
{
  uint8_t response;

  BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
  Delay(6);
	
	
  *Running_state = 0;
  Data_Trans[0] = 0x00;	//AFI coding
  Data_Trans[1] = 0x00; //Slot number
  /*Send command type B wake up for getting PUPI*/

  Resp = ISO14443B_Command(B_WakeUp, Data_Trans, 2, Data_Resp, &Len_Resp);
  /*Check Response type B : Wake up command*/
  switch(Resp)
  {
   	case _SUCCESS_:
			//htk_UART_Transmit( (uint8_t*)"\r\nWUPB:", 7);
			//for(counter = 0; counter < Len_Resp; counter++)
			//{
			//	dataToHex(&Data_Trans[counter*2], Data_Resp[counter]);
			//}
			//htk_UART_Transmit((uint8_t*)"\r\nATQB: ", 8);
			//htk_UART_Transmit(Data_Trans, counter * 2);
			//htk_UART_Transmit((uint8_t*)"\r\n",2);
		  htk_UART_Transmit( (uint8_t*)"\r\nBOK1", 6);
			response = _SUCCESS_;
			break;
		case NO_RESPONSE:
			htk_UART_Transmit( (uint8_t*)"B1", 2);
			response = NO_RESPONSE;
			break;
		case ASIC_EXE_TIMEOUT:
			//htk_UART_Transmit( (uint8_t*)"WUPB:", 5);
			//htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
		  htk_UART_Transmit( (uint8_t*)"B2", 2);
			response = ASIC_EXE_TIMEOUT;
			break;
		default:
			//htk_UART_Transmit( (uint8_t*)"WUPB:", 5);
			//htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);
		  htk_UART_Transmit( (uint8_t*)"B3", 2);

			response = ERROR;
			break;
  }

  if(response != _SUCCESS_)
	{
		return response;
	}

	#if 1
   (*Running_state)++;
   Data_Trans[0] = 0x00;	//AFI coding
   Data_Trans[1] = 0x00; //Slot number
	 /*Send command type B wake up for getting PUPI*/
   Resp = ISO14443B_Command(B_WakeUp, Data_Trans, 2, Data_Resp, &Len_Resp);
     /*Check Response type B : Wake up command*/
      switch(Resp)
       {
       	case _SUCCESS_:
       		  //htk_UART_Transmit( (uint8_t*)"\r\nWUPB:", 7);
       		  ////htk_UART_Transmit((uint8_t*)"Success\r\n", 9);
       		  /*Convert UID type B from HEX to CHAR*/
       		  //UIDTypeB_BytesToChar(&Data_Resp[0], Data_Trans, &Len_Resp);
       		  //htk_UART_Transmit(&Data_Trans[0], Len_Resp+1);
				    htk_UART_Transmit( (uint8_t*)"\r\nBOK2", 6);
   			    response = _SUCCESS_;
   			  break;
           case NO_RESPONSE:
           	  //htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);
					 htk_UART_Transmit( (uint8_t*)"B4", 2);
   			  response = NO_RESPONSE;
   			  break;
           case ASIC_EXE_TIMEOUT:
           	  //htk_UART_Transmit( (uint8_t*)"\r\nWUPB:", 7);
           	  //htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
					 htk_UART_Transmit( (uint8_t*)"B5", 2);
   			  response = ASIC_EXE_TIMEOUT;
   			  break;
           default:
           	  //htk_UART_Transmit( (uint8_t*)"\r\nWUPB:", 7);
           	  //htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);
					 htk_UART_Transmit( (uint8_t*)"B6", 2);

   			  response = ERROR;
   			  break;
       }

      if(response != _SUCCESS_)
	 {
	   return response;
	 }

	#endif
   (*Running_state)++;
	 Data_Trans[0] = Data_Resp[0]; //Info from WUPB
	 Data_Trans[1] = Data_Resp[1]; //Info from WUPB
	 Data_Trans[2] = Data_Resp[2]; //Info from WUPB
	 Data_Trans[3] = Data_Resp[3]; //Info from WUPB
	 Data_Trans[4] = Data_Resp[4]; //Info from WUPB
	 Data_Trans[5] = Data_Resp[5]; //Info from WUPB
	 Data_Trans[6] = 0x01; //Info from WUPB
	 Data_Trans[7] = 0x00; //Info from WUPB
	 /*Send command type B wake up for getting PUPI*/
	 //htk_UART_Transmit( (uint8_t*)"ATTRIB:", 7);
	 Resp = ISO14443B_Command(B_ATTRIB, Data_Trans, 8, Data_Resp, &Len_Resp);
	 /*Check Response type B : Wake up command*/
	 switch(Resp)
	 {
       	case _SUCCESS_:
       		//htk_UART_Transmit((uint8_t*)"Success\r\n", 9);
				htk_UART_Transmit( (uint8_t*)"\r\nBOK3", 6);
   			  response = _SUCCESS_;
   			  break;
        case NO_RESPONSE:
          //htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);
				htk_UART_Transmit( (uint8_t*)"B7", 2);
   			  response = NO_RESPONSE;
   			  break;
        case ASIC_EXE_TIMEOUT:
          //htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
				htk_UART_Transmit( (uint8_t*)"B8", 2);
   			  response = ASIC_EXE_TIMEOUT;
   			  break;
        default:
          //htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);
				htk_UART_Transmit( (uint8_t*)"B9", 2);
   			  response = ERROR;
   			  break;
    }
    return response;
}

/*
 * @brief Scan ISO15693 tag type follow certificate Flow
 * @retval Response from scanning
 *         - _SUCCESS_
 *         - NO_RESPONSE
 *         - ASIC_EXE_TIMEOUT
 *         - ERROR
 * */
uint8_t ScanCertificateFlow_ISO15693TagType(uint8_t *Running_state)
{
		uint8_t loop_t;

		uint8_t response;
    uint8_t mask_len;
    uint8_t mask_value;

    BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
    Delay(6);

    for(loop_t = 0;loop_t<1;loop_t++)
    {
			*Running_state = loop_t;
			mask_len = 0x00;
			mask_value = NULL;
			/*Send inventory 1 slot command*/
			Resp = ISO15693_Inv_Req_1_Slot(ISO15693_Speed, 0x00, 0x00,
						mask_len, &mask_value, Data_Resp,  &Len_Resp );

			/*Check response from the inventory 1 slot command*/
			if(Resp == _SUCCESS_)
			{
				//too much output will lead to test failure
				#if 0	
				uint8_t numTags;
				uint8_t countTags;
				uint8_t num_uid;
				uint8_t num_data;
				uint8_t len_data;
				uint8_t iso15693_uid[12] = {0};

				htk_UART_Transmit( (uint8_t*)"\r\nINVENTORY:", 12);
				/*Check number of tag (In this case should be 1)*/
				numTags = (uint8_t)(Len_Resp/8);

				/*Show number of tag (Should be 1)*/
				//byteToChar(&numTags, Data_Trans);
				/*Clear num_data variable for counting on Data_Resp buffer*/
				num_data = 0;
				/*Store ISO15693 tag's UID*/
				for(countTags = 0; countTags < numTags; countTags++)
				{
					for(num_uid = 0; num_uid < 12; num_uid++)
					{
					iso15693_uid[num_uid] = Data_Resp[num_data];
					num_data++;
					}
					UID15693_BytesToChar(&iso15693_uid[0], &Data_Trans[0], &len_data, INV_1_SLOT);
					htk_UART_Transmit(Data_Trans, len_data+1);
				}
				#endif
				htk_UART_Transmit( (uint8_t*)"\r\nVOK1", 6);
				response = _SUCCESS_;
			}
			else
			{
				switch(Resp)
				{
					case NO_RESPONSE:
						//htk_UART_Transmit( (uint8_t*)"4", 1);
						//if(loop_t > 0)
						{
							//htk_UART_Transmit( (uint8_t*)"\r\nINVENTORY:", 12);
							//htk_UART_Transmit((uint8_t*)"No Response\r\n", 13);
							htk_UART_Transmit( (uint8_t*)"V1", 2);
						}
					response = NO_RESPONSE;
					break;
					case ASIC_EXE_TIMEOUT:
					//htk_UART_Transmit( (uint8_t*)"\r\nINVENTORY:", 12);
					//htk_UART_Transmit((uint8_t*)"Timeout\r\n", 9);
					htk_UART_Transmit( (uint8_t*)"V2", 2);
					response = ASIC_EXE_TIMEOUT;
					break;
					default:
					//htk_UART_Transmit( (uint8_t*)"\r\nINVENTORY:", 12);
					//htk_UART_Transmit((uint8_t*)"Receive Error\r\n", 15);
					htk_UART_Transmit( (uint8_t*)"V3", 2);
					response = ERROR;
					break;
				}

				if(response != _SUCCESS_)
				{
					return response;
				}
			}
		}

		return response;
}


/*
 * @brief Turn on/off RF of BC45
 * @param  rf_field : RF Field definition
 * 					- RFON
 * 					- RFOFF
 * 					- RFRESET
 * @retval None
 * */
void BC45_RF_OnOff(uint8_t rf_field)
{
	switch(rf_field)
	{
		case RFON:
			BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
			break;
		case RFOFF:
			BC45_Board_ASIC_Command(OFF_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
			break;
		default:
			//Initial_BC45_Board();
			BC45_Board_ASIC_Command(OFF_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
			Delay(6);
			BC45_Board_ASIC_Command(ON_Field_BC45, NULL, 0, &Data_Resp[0], &Len_Resp);
			break;

	}
}

/**
  * @brief  Use to convert UID Type A from data (HEX) to character.
  * @param  byesUID: Pointer points to data UID (HEX).
  * @param  charUID: Pointer to data buffer for storing
  * 			     output character of data UID.
  * @param  ouputlen: Length of character of data UID.
  * @retval None
  */
void UIDTypeA_BytesToChar(uint8_t *bytesUID, uint8_t *charUID, uint16_t  *outputlen)
{
    uint8_t i;
    uint8_t j = 4;
    uint8_t temp_dataH;
    uint8_t temp_dataL;

    /*Set "UID:" to first 4 bytes of output buffer*/
    *charUID = 'U';
    *(charUID + 1) = 'I';
    *(charUID + 2) = 'D';
    *(charUID + 3) = ':';
    /*Looping following number of type A's UID*/
    for(i = 0; i < (*outputlen)-2; i++)
    {
        temp_dataH = (*(bytesUID + i) & 0xF0) >> 4;
        if(temp_dataH <= 0x09)
        {
            temp_dataH = temp_dataH + '0';
        }
        else
        {
            temp_dataH = (temp_dataH - 0x0A) + 'A';
        }

        temp_dataL = (*(bytesUID + i) & 0x0F);
        if(temp_dataL <= 0x09)
        {
            temp_dataL = temp_dataL + '0';
        }
        else
        {
            temp_dataL = (temp_dataL - 0x0A) + 'A';
        }

        *(charUID + j) = temp_dataH;
        j++;
        *(charUID + j) = temp_dataL;
        j++;
    }
    //*(charUID + j) = '\r';
    //j++;
    //*(charUID + j) = '\n';
    *outputlen = j;
}


/**
  * @brief  Use to convert UID Type 15693 from data (HEX) to character.
  * @param  InputUID: Pointer points to data UID (HEX).
  * @param  OutputUID: Pointer to data buffer for storing
  * 			  output character of data UID.
  * @param  ouputlen: Length of character of data UID.
  * @param  Inv: This is inventory slot command.
  * 			- INV_16_SLOTS
  * 			- INV_1_SLOT
  * @retval None
  */
void UID15693_BytesToChar(uint8_t *InputUID, uint8_t *OutputUID, uint8_t *outputlen, uint8_t Inv)
{
    uint8_t i;
    uint8_t j = 7;
    uint8_t temp_dataH;
    uint8_t temp_dataL;

    /*Check the command is inventory 16 slots*/
    if(Inv == INV_16_SLOTS)
    {
    	/*Check flag response from a tag.*/
    	/*Success*/
    	if(*(InputUID + 1) == 0x01)
    	{
    	    *OutputUID = 'U';
    	    *(OutputUID + 1) = 'I';
    	    *(OutputUID + 2) = 'D';
    	    *(OutputUID + 3) = ':';
    	    *(OutputUID + 4) = ' ';
    	    *(OutputUID + 5) = ' ';
    	    *(OutputUID + 6) = ' ';

    	    /*
    	     * ISO15693 has 12 bytes data response.
    	     * Last 8 bytes are UID (UID7 - UID0).
    	     */
    	    //for(i = 11; i > 3; i--)
					for(i = 4; i < 12; i++)
    	    {
    	    	temp_dataH = (*(InputUID + i) & 0xF0) >> 4;
    	        if(temp_dataH <= 0x09)
    	        {
    	        	temp_dataH = temp_dataH + '0';
    	        }
    	        else
    	        {
    	        	temp_dataH = (temp_dataH - 0x0A) + 'A';
    	        }

    	        temp_dataL = (*(InputUID + i) & 0x0F);
    	        if(temp_dataL <= 0x09)
    	        {
    	        	temp_dataL = temp_dataL + '0';
    	        }
    	        else
    	        {
    	        	temp_dataL = (temp_dataL - 0x0A) + 'A';
    	        }

    	        *(OutputUID + j) = temp_dataH;
    	        j++;
    	        *(OutputUID + j) = temp_dataL;
    	        j++;
    	    }

    	    *(OutputUID + j) = '\r';
    	    j++;
    	    *(OutputUID + j) = '\n';
					j++;
    	    *outputlen = j;
    	}
    	/*False*/
    	else
    	{
    		//Receive
    		*OutputUID = 'R';
    		*(OutputUID + 1) = 'e';
    		*(OutputUID + 2) = 'c';
    		*(OutputUID + 3) = 'e';
    		*(OutputUID + 4) = 'i';
    		*(OutputUID + 5) = 'v';
    		*(OutputUID + 6) = 'e';
    		*(OutputUID + 7) = ' ';
    		*(OutputUID + 8) = 'E';
    		*(OutputUID + 9) = 'r';
    		*(OutputUID + 10) = 'r';
    		*(OutputUID + 11) = 'o';
    		*(OutputUID + 12) = 'r';
    		*(OutputUID + 13) = '\r';
    		*(OutputUID + 14) = '\n';
    		*outputlen = 14;
    	}
    }
    /*The command is inventory 1 slots*/
    else
    {
	    *OutputUID = 'U';
	    *(OutputUID + 1) = 'I';
	    *(OutputUID + 2) = 'D';
	    *(OutputUID + 3) = ':';
 	    *(OutputUID + 4) = ' ';
 	    *(OutputUID + 5) = ' ';
 	    *(OutputUID + 6) = ' ';

	    /*
	     * ISO15693 has 9 bytes data response.
	     * Last 8 bytes are UID (UID7 - UID0).
	     */
        //for(i = 8; i >= 1; i--)
			  for(i = 1; i <9; i++)
        {
            temp_dataH = (*(InputUID + i) & 0xF0) >> 4;
            if(temp_dataH <= 0x09)
            {
                temp_dataH = temp_dataH + '0';
            }
            else
            {
                temp_dataH = (temp_dataH - 0x0A) + 'A';
            }

            temp_dataL = (*(InputUID + i) & 0x0F);
            if(temp_dataL <= 0x09)
            {
                temp_dataL = temp_dataL + '0';
            }
            else
            {
                temp_dataL = (temp_dataL - 0x0A) + 'A';
            }

            *(OutputUID + j) = temp_dataH;
            j++;
            *(OutputUID + j) = temp_dataL;
            j++;
        }
        *(OutputUID + j) = '\r';
        j++;
        *(OutputUID + j) = '\n';
				j++;

        *outputlen = j;
    }
}


/**
  * @brief  Use to convert PUPI of Type B from data (HEX) to character.
  * @param  byesUID: Pointer points to data PUPI (HEX).
  * @param  charUID: Pointer to data buffer for storing
  * 			  output character of data PUPI.
  * @param	outputLen: Length of character of data PUPI.
  * @retval None
  */
void UIDTypeB_BytesToChar(uint8_t *bytesUID, uint8_t *charUID, uint16_t *outputLen)
{
    uint8_t i;
    uint8_t j = 5;
    uint8_t temp_dataH;
    uint8_t temp_dataL;

    /*Set "PUPI:" to first 5 bytes of output buffer*/
    *charUID = 'P';
    *(charUID + 1) = 'U';
    *(charUID + 2) = 'P';
    *(charUID + 3) = 'I';
    *(charUID + 4) = ':';
    /*Looping following number of type B's PUPI*/
    for(i = 0; i < 4; i++)
    {
        temp_dataH = (*(bytesUID + i) & 0xF0) >> 4;
        if(temp_dataH <= 0x09)
        {
            temp_dataH = temp_dataH + '0';
        }
        else
        {
            temp_dataH = (temp_dataH - 0x0A) + 'A';
        }

        temp_dataL = (*(bytesUID + i) & 0x0F);
        if(temp_dataL <= 0x09)
        {
            temp_dataL = temp_dataL + '0';
        }
        else
        {
            temp_dataL = (temp_dataL - 0x0A) + 'A';
        }

        *(charUID + j) = temp_dataH;
        j++;
        *(charUID + j) = temp_dataL;
        j++;
    }
    *(charUID + j) = '\r';
    j++;
    *(charUID + j) = '\n';

    *outputLen = j;
}


/**
  * @brief  Convert byte of data to character
  * @param	inputByte: Byte of data to be convert
  * @param  outputChar: Characters of the input data
  *                     with '\r' and '\n' at last.
  * @retval None
  */
void byteToChar(uint8_t *inputByte, uint8_t *outputChar)
{
    uint8_t temp_dataH;
    uint8_t temp_dataL;

    /*Seperate 4 bits of data (first 4 bits and last 4 bits)*/
    temp_dataH = (*(inputByte) & 0xF0) >> 4;
    temp_dataL = (*(inputByte) & 0x0F);

    /*Check 4 bits high*/
    if(temp_dataH <= 0x09)
    {
        temp_dataH = temp_dataH + '0';
    }
    else
    {
        temp_dataH = (temp_dataH - 0x0A) + 'A';
    }

    /*Check 4 bits low*/
    if(temp_dataL <= 0x09)
    {
        temp_dataL = temp_dataL + '0';
    }
    else
    {
        temp_dataL = (temp_dataL - 0x0A) + 'A';
    }

    /*Assign to output buffer (include '\r' and '\n')*/
    *outputChar = temp_dataH;
    *(outputChar + 1) = temp_dataL;
    *(outputChar + 2) = '\r';
    *(outputChar + 3) = '\n';
}
