

#include "RC522Config.h"
#include "board.h"
//#include "i2cm_11u6x.h"
#include "i2cm_8xx.h" // wenxue

extern void SetupXferRecAndExecute_LPC800(uint8_t devAddr,
								   uint8_t *txBuffPtr,
								   uint16_t txSize,
								   uint8_t *rxBuffPtr,
								   uint16_t rxSize);

/* I2CM transfer record */
static I2CM_XFER_T  i2cmXferRec;

/* I2C bit-rate */
#define I2C_BITRATE         (400000)
#define I2C_RD_CMD_BIT      (0x01)
#define I2C_RST_1()     Chip_GPIO_SetPinState(LPC_GPIO, 1,  3, true);
#define I2C_RST_0()     Chip_GPIO_SetPinState(LPC_GPIO, 1,  3, false);

volatile unsigned long int dwSysTickCnt = 0;
//void SysTick_Handler(void)
//{
//	dwSysTickCnt++;
//}

void delay_ms(uint32_t time)
{
	dwSysTickCnt = 0;
	while(dwSysTickCnt <= time) {
		__WFI();
	}
}

volatile uint32_t recv_cnt_i2c = 0;
volatile unsigned char recv_rec[50];
volatile unsigned char cccl_rec[50];
volatile unsigned char setl_rec[50];

extern uint32_t Chip_I2CM_XferHandler_MG(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer, unsigned char debug1);
void SetupXferRecAndExecute(unsigned char devAddr,
                            unsigned char *txBuffPtr,
                            uint16_t txSize,
                            unsigned char *rxBuffPtr,
                            uint16_t rxSize,
                            unsigned char debug)
{
	
	 // SetupXferRecAndExecute_LPC800(devAddr,txBuffPtr,txSize,rxBuffPtr,rxSize);

	
//  uint32_t ret = 0;
//  /* Setup I2C transfer record */
//  i2cmXferRec.slaveAddr = devAddr;
//  i2cmXferRec.options = 0;
//  i2cmXferRec.status = 0;
//  i2cmXferRec.txSz = txSize;
//  i2cmXferRec.rxSz = rxSize;
//  i2cmXferRec.txBuff = txBuffPtr;
//  i2cmXferRec.rxBuff = rxBuffPtr;
//        
//  /* set the transfer status as busy */
//  i2cmXferRec.status = I2CM_STATUS_BUSY;
//  /* Clear controller state. */
//  LPC_I2C0->CONCLR = I2C_CON_SI | I2C_CON_STO | I2C_CON_STA | I2C_CON_AA;
//  /* Enter to Master Transmitter mode */
//  LPC_I2C0->CONSET = I2C_CON_I2EN | I2C_CON_STA;
//  recv_cnt_i2c = 0;
//  memset((void *)recv_rec, 0x00, 50);
//  memset((void *)cccl_rec, 0x00, 50);
//  memset((void *)setl_rec, 0x00, 50);
//  while (ret == 0) {
//          /* wait for status change interrupt */
//          while ( Chip_I2CM_StateChanged(LPC_I2C0) == 0) {}
//          /* call state change handler */
//          ret = Chip_I2CM_XferHandler_MG(LPC_I2C0, &i2cmXferRec, debug);
//  }
}

#define I2C_CON_FLAGS (I2C_CON_AA | I2C_CON_SI | I2C_CON_STO | I2C_CON_STA)
/* Master transfer state change handler handler */


uint32_t Chip_I2CM_XferHandler_MG(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer, unsigned char debug1)
{
	
	
	return 0;
	
//  uint32_t cclr = I2C_CON_FLAGS;
//  uint32_t temp;
//  temp = Chip_I2CM_GetCurState(pI2C);

//        recv_rec[recv_cnt_i2c] = temp;
//        recv_cnt_i2c++;
//	switch (temp) {
//	case 0x08:		/* Start condition on bus */
//	case 0x10:		/* Repeated start condition */
//		pI2C->DAT = (xfer->slaveAddr << 1) | (xfer->txSz == 0);
//		break;

//	/* Tx handling */
//	case 0x20:		/* SLA+W sent NAK received */
//	case 0x30:		/* DATA sent NAK received */
//		if ((xfer->options & I2CM_XFER_OPTION_IGNORE_NACK) == 0) {
//			xfer->status = I2CM_STATUS_NAK;
//			cclr &= ~I2C_CON_STO;
//			break;
//		}

//	case 0x18:		/* SLA+W sent and ACK received */
//	case 0x28:		/* DATA sent and ACK received */
//		if (!xfer->txSz) {
//			if (xfer->rxSz) {
//				cclr &= ~I2C_CON_STA;
//			}
//			else {
//				xfer->status = I2CM_STATUS_OK;
//				cclr &= ~I2C_CON_STO;
//			}

//		}
//		else {
//			pI2C->DAT = *xfer->txBuff++;
//			xfer->txSz--;
//		}
//		break;

//	/* Rx handling */
//	case 0x58:		/* Data Received and NACK sent */
//	case 0x50:		/* Data Received and ACK sent */
//		*xfer->rxBuff++ = pI2C->DAT;
//		xfer->rxSz--;

//	case 0x40:		/* SLA+R sent and ACK received */
//		if ((xfer->rxSz > 1) || (xfer->options & I2CM_XFER_OPTION_LAST_RX_ACK)) {
//			cclr &= ~I2C_CON_AA;
//		}
//		if (xfer->rxSz == 0) {
//			xfer->status = I2CM_STATUS_OK;
//			cclr &= ~I2C_CON_STO;
//		}
//		break;

//	/* NAK Handling */
//	case 0x48:		/* SLA+R sent NAK received */
//		xfer->status = I2CM_STATUS_SLAVE_NAK;
//		cclr &= ~I2C_CON_STO;
//		break;

//	case 0x38:		/* Arbitration lost */
//		xfer->status = I2CM_STATUS_ARBLOST;
//		break;

//	case 0x00:		/* Bus Error */
//		xfer->status = I2CM_STATUS_BUS_ERROR;
//		cclr &= ~I2C_CON_STO;
//		break;

//	default:
//		xfer->status = I2CM_STATUS_ERROR;
//		cclr &= ~I2C_CON_STO;
//		break;
//	}
//  
//	/* Set clear control flags */
//	pI2C->CONSET = cclr ^ I2C_CON_FLAGS;
//	pI2C->CONCLR = cclr;
//        setl_rec[recv_cnt_i2c-1] = cclr ^ I2C_CON_FLAGS;
//        cccl_rec[recv_cnt_i2c-1] = cclr;
//	return xfer->status != I2CM_STATUS_BUSY;
}

void I2C0_IRQHandler(void)
{
//	/* Call I2CM ISR function with the I2C device and transfer rec */
//  Chip_I2CM_XferHandler(LPC_I2C0, &i2cmXferRec);
}

void i2c_init(void)
{
  /* Enable IOCON clock */
  Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);
// I2C Init  	
  Chip_SYSCTL_PeriphReset(RESET_I2C0);
//  Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 4,  (IOCON_FUNC1 | IOCON_FASTI2C_EN) | IOCON_DIGMODE_EN);
//  Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 5,  (IOCON_FUNC1 | IOCON_FASTI2C_EN) | IOCON_DIGMODE_EN);
//	
//  Chip_IOCON_PinMuxSet(LPC_IOCON, 1, 3,  (IOCON_FUNC0 | IOCON_MODE_PULLUP | IOCON_DIGMODE_EN));
//	Chip_IOCON_PinMuxSet(LPC_IOCON, 1, 4,  (IOCON_FUNC0 | IOCON_MODE_PULLUP | IOCON_DIGMODE_EN));
//	Chip_GPIO_SetPinDIROutput(LPC_GPIO, 1, 3);
//	Chip_GPIO_SetPinDIROutput(LPC_GPIO, 1, 4);
//	Chip_GPIO_SetPinState(LPC_GPIO, 1, 3, true);
//	Chip_GPIO_SetPinState(LPC_GPIO, 1, 4, true);
//	
//  Chip_I2CM_Init(LPC_I2C0);

//  /* Setup I2CM transfer rate */
//  Chip_I2CM_SetBusSpeed(LPC_I2C0, 400000);
//  
//  //NVIC_EnableIRQ(I2C0_IRQn);
//  NVIC_DisableIRQ(I2C0_IRQn);
}


volatile unsigned char rx522_buf[1024];
volatile unsigned char tx_buffer[1024];

/**************************************************************************************************
** IN:			    unsigned char regAddr			Register address
** 							unsigned char * buff			in-data address
** 							unsigned char num					number of bytes to be written
** FUNC:				MCU related(low level) write register
**************************************************************************************************/
void iic_Write_reg(unsigned char reg_add, unsigned char *buff, unsigned char num)
{
	uint8_t i;
  tx_buffer[0] = reg_add;
	
	for(i=0; i<num; i++) {
		tx_buffer[i+1] = *buff;
		buff++;
	}
	
	SetupXferRecAndExecute(0x28, (unsigned char *)tx_buffer, 1+num, (unsigned char *)rx522_buf, 0, 1);
}

/**************************************************************************************************
** IN:			    unsigned char reg_add			Register address
**  						unsigned char *Read				buffer address of data output
** 							unsigned char num					number of bytes to be read
** FUNC:				MCU related(low level) read register
**************************************************************************************************/
void iic_Read_reg(unsigned char reg_add, unsigned char *Read, unsigned char num)
{
  unsigned char tx_buffer[3];
  tx_buffer[0] = reg_add;

  SetupXferRecAndExecute(0x28, tx_buffer, 1, Read, num, 1);
}




unsigned char rc_tx_buffer[3];
unsigned char rc_tx_buffer[3];
#define I2C_CON_FLAGS (I2C_CON_AA | I2C_CON_SI | I2C_CON_STO | I2C_CON_STA)
#define cmdMAX_INPUT_SIZE	60


/**************************************************************************************************
** IN:			    unsigned char regAddr			Register address
** FUNC:				read data from register
**************************************************************************************************/
unsigned char  RcGetReg(unsigned char regAddr)
{
  rc_tx_buffer[0] = regAddr;
  /* Read LM75 temerature sensor */
  SetupXferRecAndExecute(0x28, rc_tx_buffer, 1, rc_tx_buffer, 1, 0);
  return rc_tx_buffer[0];
}


/**************************************************************************************************
** IN:			    unsigned char regAddr			Register address
**							unsigned char value				Register value to be written
** FUNC:				write data into register
**************************************************************************************************/
void RcSetReg(unsigned char regAddr,unsigned char rVal)
{
  rc_tx_buffer[0] = regAddr;
  rc_tx_buffer[1] = rVal;
  SetupXferRecAndExecute(0x28, (unsigned char *)rc_tx_buffer, 2, (unsigned char *)rc_tx_buffer, 0, 0); 
}


/**************************************************************************************************
** IN:			    unsigned char regAddr			Register address
**							unsigned char ModifyVal		Register value to be modified: 1=set / 0=clear
**							unsigned char MaskByte		mask byte value
** OUT:					-
**************************************************************************************************/
void RcModifyReg(unsigned char RegAddr,unsigned char ModifyVal,unsigned char MaskByte)
{
    unsigned char RegVal;

    RegVal = RcGetReg(RegAddr);
    if(ModifyVal)
    {
        RegVal |= MaskByte;
    }
    else
    {
        RegVal &= (~MaskByte);
    }
    RcSetReg(RegAddr, RegVal);
}


/**************************************************************************************************
** IN:			    unsigned char *DataBfr		Output data buffer
**							unsigned char Len					number of bytes to be read
**************************************************************************************************/
void ReadFIFO(unsigned char *DataBfr,unsigned char Len)
{
	iic_Read_reg(REG_FIFODATA, DataBfr, Len);
}

/**************************************************************************************************
** IN:			    unsigned char *DataBfr		Input data buffer
**							unsigned char Len					number of bytes to be written
**************************************************************************************************/
void WriteFIFO(unsigned char *DataBfr,unsigned char Len)
{
	iic_Write_reg(REG_FIFODATA, DataBfr, Len);
}

/**************************************************************************************************
** set GPIO state
**************************************************************************************************/
void Board_NFC_RST_Set(bool high)
{
 //Chip_GPIO_SetPinState(LPC_GPIO, 1, 3, high);
	
  Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 27, high);
}

/**************************************************************************************************
** disable i2c
**************************************************************************************************/
void Board_NFC_DeInit(void)
{
  //disable i2c int and disable i2c clock
 // NVIC_DisableIRQ(I2C0_IRQn);
//  Chip_I2CM_DeInit(LPC_I2C0);
}

/**************************************************************************************************
** init GPIOs connected to RC522 
**************************************************************************************************/
void mcu_pin_init(void) 
{
	// LPC824 GPIO init
	// mfrc reset pin
	Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 27, true);
  Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 27);
//  
//	// mfrc irq pin
	Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, 13, true);
  Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, 0, 13);
}

/**************************************************************************************************
** Reset the chip
** _______   1ms   __________
**        |_______|
**************************************************************************************************/
void PcdReset(void)
{
	//unsigned char i;
	unsigned int i;
	// GPIO = LOW
  Board_NFC_RST_Set(0);
	// delay 1ms appr.
  for(i=0; i<5000; i++){;}
	// GPIO = HIGH
  Board_NFC_RST_Set(1);
	// delay 1ms appr.
  for(i=0; i<5000; i++){;}
}

/**************************************************************************************************
** Set chip to powerdown mode
**************************************************************************************************/
void PcdStop(void)
{	
  // RC522 Power down
  Board_NFC_RST_Set(0);
	// disable I2C
	Board_NFC_DeInit();
}
