/*
* Copyright © 2013 Texas Instruments Incorporated - http://www.ti.com/ 
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/


#ifndef RFID_H
#define RFID_H

#include "hardware.h"
#include "buffer.h"
#include <stdint.h>
#define RFID_VERSION_STR  "RFID_v1.0"
#define RFID_VERSION_LENGTH 9


class RFID {
public:
	//SystemCall
	static word Call(word opcode, byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	static word Call(word opcode, byte s1, word s2);
	static word Call(word opcode, byte s1);

	static void Timing(byte type, word value);
    static int run();
    static bool isNFC_TargetMode;
    static bool isProtocolError;
    static bool isTXfinish;

    static bool isTargetActivated;
    static bool isRFFieldOn;
    static void callbackInit(bool (*callback)());
	static void SetupFrame(byte mode);
	static void writeCmd(byte cmd);
	static bool callback();
    static bool (*callbackFunction)();

private:
//


    static bool functionDummy();

	static void reset();
	static bool isNFCActive;
//     static void setHigherBaudrate();

//     static bool LongFrameFlag;
	static bool isRxMultiple;
//     //static bool isNFC_Passive_Target;
	static byte current_frame_type;
	static byte current_frame_param;
//     static byte baud;
	static byte bitFrame;
//
	static byte BitCollision();
//
	static word Init(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	static word version(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	static word setTimeouts(byte *sendbuf, word sendlen);
	static word transceive(byte cmd, byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	static void calcFifoLen(byte sendlen, byte bitFrameCount, byte &highByte, byte &lowByte);
	static void HFField(char state);
	static void FieldReset(word msec);

	static word FrameType(byte option, byte param);
	static void Setup14443A_Bitframe(byte sendlen);
	static void Setup14443A_Byteframe();
//     static void Setup14443B_Byteframe();
     static word baudrate_air(byte baudrate);
//     static bool WaitModemState(byte state, word timeout);
//     static void SetupNFC_Byteframe();
//     static void SetupFELICA_Byteframe();
//     static void ClearBits(byte adr, byte mask);
//     static void SetBits(byte adr, byte mask);

//     static byte AACC();
    static word readMailbox(byte *recbuf, word &reclen);
	static word control(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word modeDetection(byte *recbuf, word &reclen);
//     static word checkPON(byte *recbuf, word &reclen);
     static word checkTargetActivated(byte *recbuf, word &reclen);
//
//    //This functions are in the file RFID_TestCases.cpp and used to test and debug parts of the RFID Layer and other functions
//    static void SpiStressTest(byte *sendbuf, word sendlen, byte *recbuf, word reclen); //function found in Sample Folder!
//    static void RegisterReadOut(byte *sendbuf, word sendlen, byte *recbuf, word reclen); //Reads all necessary Register from PN512
//
//     static bool firstRun;
//
     //AAC configuration and sub methods
     static word aacConfiguration(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgSensRes(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgNfcid1(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgSelRes(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgProtSel(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgNfcid2(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgSysCode(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgNfcid3(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word setPupi(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgAtqb(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgAfi(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word sgPadding(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
     static word getLfT3tMax(word sendlen, byte *recbuf, word &reclen);
	 static word sgLfT3tFlags(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	 static word sgLfT3tIdentifier(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	 static word sgLfProtocolType(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	 static word sgLfAdvFeat(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	 static word sgLfConBitrF(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);
	 static word sgLnNfcDep(byte *sendbuf, word sendlen, byte *recbuf, word &reclen);


     struct _AAC;
     static _AAC AACconfig;

     static Array<10> nfcid1;
     static Array<8>  nfcid2;

     static byte stmReceiveMode;

#define	RCV_IDLE			0
#define	RCV_SDD_COMPLETE	1
#define	RCV_TX_FINISH_IRQ	2
#define	RCV_RX_IRQ			3
#define	RCV_STOP			4
#define	RCV_RECEIVING		5



};


// Hardware GPIO definition
/*! Enable pin for TRF7970: P2.3 */
#define TRF_ENABLEBIT           BIT1
/*! Sets Enable pin as output */
#define TRF_ENABLESET()         {P4DIR |= TRF_ENABLEBIT;}
/*! Enables the TRF7970 */
#define TRF_ENABLE()            {P4OUT |= TRF_ENABLEBIT;}
/*! Disables the TRF7970 */
#define TRF_DISABLE()           {P4OUT &= ~TRF_ENABLEBIT;}


#define IRQ_PIN			BIT2
#define IRQ_PIN_SET		P2DIR &= ~IRQ_PIN
#define IRQ_PORT		P2IN
#define IRQ_INT_ON		P2IE |= IRQ_PIN		// IRQ on P2.1
#define IRQ_INT_OFF		P2IE &= ~IRQ_PIN		// IRQ on P2.1
#define IRQ_EDGE_SET	P2IES &= ~IRQ_PIN		// rising edge interrupt
#define IRQ_CLR			P2IFG &= ~IRQ_PIN
#define IRQ_REQ_REG		P2IFG

#define IRQ_IS_SET()            (IRQ_PORT & IRQ_PIN)

typedef enum
{
	BOARD_INIT = 0,
	P2P_INITATIOR_MODE,
	P2P_PASSIVE_TARGET_MODE,
	P2P_ACTIVE_TARGET_MODE,
	CARD_EMULATION_TYPE_A,
	CARD_EMULATION_TYPE_B,
	TYPE_A_RW,
	TYPE_B_RW,
	TYPE_F_RW,
	TYPE_V_RW
} TRF_Mode_t;
typedef enum {
	FREQ_STAND_BY = 0, // Used for Board Initialization
	FREQ_106_KBPS,
	FREQ_212_KBPS,
	FREQ_424_KBPS
} Frequency_t;

typedef enum {
	IRQ_STATUS_IDLE = 0x00,
	IRQ_STATUS_NO_RESPONSE = 0x01,
	IRQ_STATUS_RF_FIELD_CHANGE = 0x04,
	IRQ_STATUS_ERROR = 0x10,
	IRQ_STATUS_FIFO_HIGH_OR_LOW = 0x20,
	IRQ_STATUS_RX_COMPLETE = 0x40,
	IRQ_STATUS_TX_COMPLETE = 0x80,
	IRQ_STATUS_TIME_OUT = 0xFF
} IRQ_flag_t;

typedef enum {
	IRQ_STATUS_NFC_COLLISION_ERROR = 0x01,
	IRQ_STATUS_NFC_COLLISION_AVOID_FINISHED = 0x02,
	IRQ_STATUS_NFC_RF_FIELD_CHANGE = 0x04,
	IRQ_STATUS_NFC_SDD_COMPLETE = 0x08,
	IRQ_STATUS_NFC_PROTOCOL_ERROR = 0x10
}IRQ_NFC_flags;

typedef enum {
	IRQ_STATUS_RFID_NO_RESPONSE_INT = 0x01,
	IRQ_STATUS_RFID_COLLISION_ERROR = 0x02,
	IRQ_STATUS_RFID_FRAMING_OR_EOF_ERROR = 0x04,
	IRQ_STATUS_RFID_PARITY_ERROR = 0x08,
	IRQ_STATUS_RFID_CRC_ERROR = 0x10
}IRQ_RFID_flags;

typedef enum
{
	CRC_BIT_DISABLE = 0,
	CRC_BIT_ENABLE
} CRC_t;

typedef enum
{
	FALSE = 0,
	TRUE
}bool_t;

typedef enum
{
	STATUS_FAIL_T	= 0,
	STATUS_SUCCESS_T
}status_;

IRQ_flag_t TRF797x_irqHandler(word timeout_ms);

void TRF797x_setup(void);
void TRF797x_directCommand(byte command);
void TRF797x_rawWrite(byte *pbuf, uint8_t length);
void TRF797x_readSingle(byte *pbuf, uint8_t reg);
void TRF797x_readCont(byte *pbuf, uint8_t reg, uint8_t length);
void TRF797x_writeSingle(byte data, uint8_t reg);
void TRF797x_writeCont(byte *pbuf, uint8_t reg, uint8_t length);

void TRF797x_resetFIFO(void);
word TRF797x_Init(TRF_Mode_t mode, Frequency_t frequency);

status_ TRF797x_writeFIFO(byte *pbuf, CRC_t crc_bit, byte length, byte broken_bits);
void TRF797x_setP2PTargetFlag(bool target_flag);
void TRF797x_setP2PInitiatorFlag(bool initiator_flag);
void TRF797x_displayMode(void);
word TRF797x_checkExternalField(void);


#endif //RFID_h
