/*
 * @brief I2CM bus master example using polling mode
 *
 * @note
 * Copyright(C) NXP Semiconductors, 2014
 * All rights reserved.
 *
 * @par
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * LPC products.  This software is supplied "AS IS" without any warranties of
 * any kind, and NXP Semiconductors and its licensor disclaim any and
 * all warranties, express or implied, including all implied warranties of
 * merchantability, fitness for a particular purpose and non-infringement of
 * intellectual property rights.  NXP Semiconductors assumes no responsibility
 * or liability for the use of the software, conveys no license or rights under any
 * patent, copyright, mask work right, or any other intellectual property rights in
 * or to any products. NXP Semiconductors reserves the right to make changes
 * in the software without notification. NXP Semiconductors also makes no
 * representation or warranty that such application will be suitable for the
 * specified use without further testing or modification.
 *
 * @par
 * Permission to use, copy, modify, and distribute this software and its
 * documentation is hereby granted, under NXP Semiconductors' and its
 * licensor's relevant copyrights in the software, without fee, provided that it
 * is used in conjunction with NXP Semiconductors microcontrollers.  This
 * copyright, permission, and disclaimer notice must appear in all copies of
 * this code.
 */

#include "board.h"

#include "Hal_Reg.h"
#include "MFRC522.h"
#include "typea.h"
#include "Mifare.h"
#include "RC522_API.h"



#define NFC_ID_STING_LENGTH 13

/*****************************************************************************
 * Private types/enumerations/variables
 ****************************************************************************/

/* I2CM transfer record */
static I2CM_XFER_T  i2cmXferRec;
/* System clock is set to 24MHz, I2C clock is set to 600kHz */
#define I2C_CLK_DIVIDER         (40)
/* 100KHz I2C bit-rate */
#define I2C_BITRATE             (100000)

/* 7-bit I2C addresses of I/O expander */
/* Note: The ROM code requires the address to be between bits [6:0]
         bit 7 is ignored */
#define I2C_ADDR_7BIT           (0x60)

#define I2C_ADDR_7BIT_PN512           (0x50 >> 1)

/* SysTick rate in Hz */
#define TICKRATE_HZ             (1000)

#define TASK_LOOP               while (true)
#define EVENT_LED_BUMP          0x01
#define EVENT_LED_TOGGLE        0x02


#define	LED_RED					0
#define	LED_GREEN				1
#define	LED_BLUE				2

/* file local variables */
static volatile int intErrCode;
static volatile uint32_t ticks;
static uint8_t txData[16];
static uint8_t rxData[16];
static uint32_t event_flag;

/*****************************************************************************
 * Public types/enumerations/variables
 ****************************************************************************/

/*****************************************************************************
 * Private functions
 ****************************************************************************/

/* Initializes pin muxing for I2C interface */
static void Init_I2C_PinMux(void)
{
#if (defined(BOARD_NXP_LPCXPRESSO_812) || defined(BOARD_LPC812MAX) || defined(BOARD_NXP_LPCXPRESSO_824))
	/* Enable the clock to the Switch Matrix */
	Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
#if defined(BOARD_NXP_LPCXPRESSO_824)
	Chip_SWM_EnableFixedPin(SWM_FIXED_I2C0_SDA);
	Chip_SWM_EnableFixedPin(SWM_FIXED_I2C0_SCL);
#else
	/* Connect the I2C_SDA and I2C_SCL signals to port pins(P0.10, P0.11) */
	Chip_SWM_MovablePinAssign(SWM_I2C_SDA_IO, 10);
	Chip_SWM_MovablePinAssign(SWM_I2C_SCL_IO, 11);
#endif

	/* Enable Fast Mode Plus for I2C pins */
	//Chip_IOCON_PinSetI2CMode(LPC_IOCON, IOCON_PIO10, PIN_I2CMODE_FASTPLUS);
	//Chip_IOCON_PinSetI2CMode(LPC_IOCON, IOCON_PIO11, PIN_I2CMODE_FASTPLUS);
	
	
	// wenxue
	Chip_IOCON_PinSetI2CMode(LPC_IOCON, IOCON_PIO10, PIN_I2CMODE_FASTPLUS ); 
	Chip_IOCON_PinSetI2CMode(LPC_IOCON, IOCON_PIO11, PIN_I2CMODE_FASTPLUS);
	

	/* Disable the clock to the Switch Matrix to save power */
	Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);
#else
	/* Configure your own I2C pin muxing here if needed */
#warning "No I2C pin muxing defined"
#endif
}

/* Setup I2C handle and parameters */
static void setupI2CMaster()
{
	/* Enable I2C clock and reset I2C peripheral */
	Chip_I2C_Init(LPC_I2C);

	/* Setup clock rate for I2C */
//	Chip_I2C_SetClockDiv(LPC_I2C, I2C_CLK_DIVIDER);
	Chip_I2C_SetClockDiv(LPC_I2C, 20); // wenxue

	/* Setup I2CM transfer rate */
	//Chip_I2CM_SetBusSpeed(LPC_I2C, I2C_BITRATE);
	
	LPC_I2C->MSTTIME = 0x0000;	// wenxue

	/* Enable Master Mode */
	Chip_I2CM_Enable(LPC_I2C);
}


/* Function to setup and execute I2C transfer request */
void SetupXferRecAndExecute_LPC800(uint8_t devAddr,
								   uint8_t *txBuffPtr,
								   uint16_t txSize,
								   uint8_t *rxBuffPtr,
								   uint16_t rxSize)
{
	/* Setup I2C transfer record */
	i2cmXferRec.slaveAddr = devAddr;
	i2cmXferRec.status = 0;
	i2cmXferRec.txSz = txSize;
	i2cmXferRec.rxSz = rxSize;
	i2cmXferRec.txBuff = txBuffPtr;
	i2cmXferRec.rxBuff = rxBuffPtr;

	Chip_I2CM_XferBlocking(LPC_I2C, &i2cmXferRec);
}

/* Function to build the LED value for the PCA9532 LED driver & I/O expander */
static uint32_t build_led(uint32_t t1)
{
	uint32_t i, k, out_val = 0;

	for (i = 0; i < 16; i++) {
		k = ((t1 >> i) & 0x01) ? 0x01 : 0x00;
		out_val |= (k << (i * 2));
	}

	return out_val;
}

/* Function sends update to the I/O expander */
static void sendI2CMaster(uint16_t i2c_addr, uint32_t ledStateOut)
{
	int index = 0;

	txData[index++] = (uint8_t) 0x16;							/* I2C device regAddr */
	txData[index++] = (uint8_t) ((ledStateOut)     & 0xff);		/* I2C device regVal */
	txData[index++] = (uint8_t) ((ledStateOut >> 8)  & 0xff);		/* I2C device regVal */
	txData[index++] = (uint8_t) ((ledStateOut >> 16) & 0xff);		/* I2C device regVal */
	txData[index++] = (uint8_t) ((ledStateOut >> 24) & 0xff);		/* I2C device regVal */

	SetupXferRecAndExecute(i2c_addr, txData, 5, rxData, 0);
}

/*****************************************************************************
 * Public functions
 ****************************************************************************/

/**
 * @brief	Handle interrupt from SysTick timer
 * @return	Nothing
 */
void SysTick_Handler(void)
{
	ticks++;

	if ((ticks % 50) == 0) {
		event_flag |= EVENT_LED_BUMP;
	}
	if ((ticks % 125) == 0) {
		event_flag |= EVENT_LED_TOGGLE;
	}
}



/**
 * @brief	Main routine for I2CM example
 * @return	Function should not exit
 */
int main(void)
{
uint32_t i=0;
	uint32_t led_ct = 0;
	uint8_t snr[150];
	char read_id[NFC_ID_STING_LENGTH]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
	char status=0;
	char Green_Status=0,Red_Status=0;

	unsigned char atqa[2] = {0x0,0x0};
	unsigned char sak = 0;	
	unsigned char din[30];
	unsigned char dout[30];

	unsigned char key[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
	

	/* Generic Initialization */
	SystemCoreClockUpdate();
	Board_Init();

	/* Clear activity LED */
 Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 12);  // Red
 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 12, true);
	
 Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 16); // Green
 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 16, true);
	
 Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 27); // Blue
 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 27, true);
	
	
 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 12, false); // Red On
	
//////////////////////////////////////////////////////////////////////
	// D4 D5 D6 Config
 Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 0x17);
 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 0x17, false);
	
 Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 0x18);
 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 0x18, false);
	
 Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 0x1A);
 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 0x1A, false);
/////////////////////////////////////////////////////////////////////	
	

	
	// delay 1ms appr.
//  for(led_ct=0; led_ct<5000; led_ct++){;}
//  Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 27, false);
//	for(led_ct=0; led_ct<5000; led_ct++){;}
//  Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 27, true);
//  for(led_ct=0; led_ct<5000; led_ct++){;}
	

 // init MCU control pins: RST and IRQ
	mcu_pin_init();

	/* Setup I2C pin muxing */
	Init_I2C_PinMux();

	/* Allocate I2C handle, setup I2C rate, and initialize I2C clocking */
	setupI2CMaster();
	
while(1)	 
{
   // *********** Config **********************
	// reset the chip
	PcdReset();
	
	// config chip for TypeA@106kbps
	PcdConfig();		
	
	
		// ********** Mifare operation *************
		// activate card
		if(!status)	
			status = PiccActiveCard(atqa, snr, &sak);
		
		// authenticate with Sector0 
		if(!status)	
			status = PiccAuthKey(0x60,snr, key, 0x0);
		else if(1==Green_Status)
		{
			Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 12, false); // ¿¨ÒÆ¿¨ÁË,ºìµÆÁÁ
		  Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 16, true);  // ÂÌµÆÃð
		}
		
		// read block 0
		if(!status)	
			status = PiccRead(0x1, dout); 

		// write 0xAA t0 block 1
		if(!status)	
			memset(din, 0xAA, 16);
		
		if(!status)	
			status = PiccWrite(0x01, din);
		// read block 1
		if(!status)
			status = PiccRead(0x01, dout);
		
		if(!status)
		  status = read_NFC_Card(read_id);
				
	  if(!status)
		{
			Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 16, false); // ¿¨¶ÁÈ¡³É¹¦,µãÁÁÂÌµÆ
			Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 12, true);  // ºìµÆÃð
			Green_Status=1;
		}
       			
		status=0;
		
		for( i=0;i<5000;i++);
		 for( i=0;i<5000;i++);
	  //delay_ms(500);			
	}
}
