This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR5969: TRF7970 IC for NFC reading ON/OFF Related

Part Number: MSP430FR5969
Other Parts Discussed in Thread: TRF7970A

Hi all,

This is Anil, I have connected MSp430FR5969 to TRF7970 for Reading and writing into the NFC tag. All things are working fine, But here in example coding was like every cycle need to ON/OFF the TRF module. But now I have changed that as per my requirement. so Now I am not doing ON/OFF always TRF module, When its needed then only I am doing. 

So, here my question is that is I am doing correct or every time ON/OFF the TRF module is required?

Thanks,

Anil D.

  • Hi Anil,

    The ON/OFF operation every cycle is to save power when TRF module isn't in use. You can ON/OFF the TRF module according to your requirement.

    B.R
    Winter
  • Hello Winter Yu,

    According to requirement of mine only I am doing ON/OFF the TRF module. Its depend on the Interrupt PIN. If Interrupt is there then only it has to ON/OFF the TRF.

    /////////////////////////////////////////////

             IRQ_OFF;

               DISABLE_TRF;

               // Clear IRQ Flags before enabling TRF7970A

               IRQ_CLR;

               IRQ_ON;

               ENABLE_TRF;

               // Must wait at least 4.8 ms to allow TRF7970A to initialize.

               __delay_cycles(800000);

               // Tx_Uart1_Char('N');

               // __delay_cycles(8000);

               Iso14443aFindTag(); // Scan for 14443A tags

    ///////////////////////////////////////////

    this is how exactly I am doing ON/OFF TRF module.

    Another point is that my program is stuck at a one point.

    void Iso14443aLoop(u08_t cascade_level, u08_t nvb, u08_t *uid)

    {

    ...

    ...

    ...

    ...

    ...

           rx_error_flag = 0;

           coll_poss = 0x21;

           rxtx_state = 1; // The response will be stored in buf[1] upwards

           Iso14443aSelectCommand(select, nvb, uid);

           while (coll_poss < 0x20){

               if(i_reg == 0x00)

                   break;

                  Tx_Uart1_String("Stck\n");

           }

           if (coll_poss == 0x20)

               i_reg = 0x02; // In case coll_poss=0x20 means didn't receive response

    }

    Here in Stuck my program stuck. So what can I do on it.?

    thanks,

    Anil D.

  • Hi Anil,

    You mean your code stuck in below sentence?
    Tx_Uart1_String("Stck\n");

    So where is the coll_poss and i_reg modified?

    B.R
    Winter
  • /*
     * {trf7970.c}
     *
     * {TRF7970 Communication functions}
     *
     * Copyright (C) 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.
     *
    */
    
    /****************************************************************
    * FILENAME: Trf7970.c
    *
    * BRIEF: Contains functions to initialize and execute
    * communication the Trf7970 via the selected interface.
    *
    * Copyright (C) 2010 Texas Instruments, Inc.
    *
    * AUTHOR(S): Reiser Peter        DATE: 02 DEC 2010
    *
    * EDITED BY:
    * *
    *
    ****************************************************************/
    
    //#include "trf7970.h"
    //#include "bnpglobal.h"
    //#include "Spi.h"
    #include "header.h"
    //===============================================================
    
    u08_t    command[2];
    u08_t    direct_mode = 0;
    extern u08_t    buf[300];
    extern u08_t    i_reg;
    #ifdef ENABLE14443A
    	extern u08_t    coll_poss;
    #endif
    extern u08_t    irq_flag;
    extern u08_t    rx_error_flag;
    extern s08_t    rxtx_state;
    extern u08_t    stand_alone_flag;
    
    //===============================================================
    
    void Trf7970ISR(u08_t *irq_status);
    
    //===============================================================
    //                                                              ;
    //===============================================================
    
    void
    Trf7970CommunicationSetup(void)
    {
    	IRQ_PIN_SET;
    	IRQ_EDGE_SET;                                // rising edge interrupt
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970InitialSettings(void)
    {
    	command[0] = SOFT_INIT;
    	Trf7970DirectCommand(command);
    
    	command[0] = IDLE;
    	Trf7970DirectCommand(command);
    
        command[0] = MODULATOR_CONTROL;
        command[1] = 0x01;                    // ASK 100%, no SYS_CLK output
        Trf7970WriteSingle(command, 2);
    }
    
    
    //===============================================================
    // NAME: void Trf7970DirectCommand (u08_t *pbuf)
    //
    // BRIEF: Is used to transmit a Direct Command to Trf7970.
    //
    // INPUTS:
    //    Parameters:
    //        u08_t        *pbuf        Direct Command
    //
    // OUTPUTS:
    //
    // PROCESS:    [1] transmit Direct Command
    //
    // CHANGE:
    // DATE          WHO    DETAIL
    // 24Nov2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970DirectCommand(u08_t *pbuf)
    {
      SpiDirectCommand(pbuf);
    
    }
    
    //===============================================================
    // NAME: void Trf7970DirectMode (void)
    //
    // BRIEF: Is used to start Direct Mode.
    //
    // INPUTS:
    //
    // OUTPUTS:
    //
    // PROCESS:    [1] start Direct Mode
    //
    // NOTE: No stop condition
    //
    // CHANGE:
    // DATE          WHO    DETAIL
    // 24Nov2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970DirectMode(void)
    {
      direct_mode = 1;
    
      SpiDirectMode();
    
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970DisableSlotCounter(void)
    {
      buf[40] = IRQ_MASK;
      buf[41] = IRQ_MASK;                // next slot counter
      Trf7970ReadSingle(&buf[41], 1);
      buf[41] &= 0xFE;                // clear BIT0 in register 0x01
      Trf7970WriteSingle(&buf[40], 2);
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970EnableSlotCounter(void)
    {
      buf[40] = IRQ_MASK;
      buf[41] = IRQ_MASK;                // next slot counter
      Trf7970ReadSingle (&buf[41], 1);
      buf[41] |= BIT0;                // set BIT0 in register 0x01
      Trf7970WriteSingle(&buf[40], 2);
    }
    
    
    
    //===============================================================
    // The Interrupt Service Routine determines how the IRQ should  ;
    // be handled. The Trf7970 IRQ status register is read to       ;
    // determine the cause of the IRQ. Conditions are checked and   ;
    // appropriate actions taken.                                   ;
    //===============================================================
    
    void
    Trf7970ISR(u08_t *irq_status)
    {
    	if(*irq_status == 0xA0)			// BIT5 and BIT7
    	{								// TX active and only 3 bytes left in FIFO
    		//i_reg = 0x00;
    	}
    
    	else if(*irq_status == BIT7)
    	{								// TX complete
    		i_reg = 0x00;
    		Trf7970Reset();				// reset the FIFO after TX
    	}
    
    	else if((*irq_status & BIT1) == BIT1)
    	{								// collision error
    		i_reg = 0x02;				// RX complete
    
    #ifdef ENABLE14443A
    		coll_poss = COLLISION_POSITION;
    		Trf7970ReadSingle(&coll_poss, 1);
    		buf[rxtx_state] = FIFO;					// write the recieved bytes to the correct place of the
    													// buffer;
    		if (coll_poss >= 0x20)
    		{
    			Trf7970ReadCont(&buf[rxtx_state], 5);
    		}
    #endif
    
    		Trf7970StopDecoders();						// reset the FIFO after TX
    
    		Trf7970Reset();
    
    		Trf7970ResetIrqStatus();
    
    		IRQ_CLR;
    	}
    	else if(*irq_status == BIT6)
    	{	// RX flag means that EOF has been recieved
    		// and the number of unread bytes is in FIFOstatus regiter
    		if(rx_error_flag == 0x02)
    		{
    			i_reg = 0x02;
    			return;
    		}
    
    		*irq_status = FIFO_STATUS;
    		Trf7970ReadSingle(irq_status, 1);					// determine the number of bytes left in FIFO
    
    		*irq_status = 0x7F & *irq_status;
    		buf[rxtx_state] = FIFO;						// write the recieved bytes to the correct place of the buffer
    
    		Trf7970ReadCont(&buf[rxtx_state], *irq_status);
    		rxtx_state = rxtx_state + *irq_status;
    
    		Trf7970Reset();					// reset the FIFO after last byte has been read out
    
    		i_reg = 0xFF;					// signal to the recieve funnction that this are the last bytes
    	}
    	else if(*irq_status == 0x60)
    	{									// RX active and 9 bytes allready in FIFO
    		i_reg = 0x01;
    		buf[rxtx_state] = FIFO;
    		Trf7970ReadCont(&buf[rxtx_state], 9);	// read 9 bytes from FIFO
    		rxtx_state = rxtx_state + 9;
    
    		if((IRQ_PORT & IRQ_PIN) == IRQ_PIN)			// if IRQ pin high
    		{
    			Trf7970ReadIrqStatus(irq_status);
    
    			IRQ_CLR;
    
    			if(*irq_status == 0x40)							// end of recieve
    			{
    				*irq_status = FIFO_STATUS;
    				Trf7970ReadSingle(irq_status, 1);					// determine the number of bytes left in FIFO
    
    				*irq_status = 0x7F & *irq_status;
    				buf[rxtx_state] = FIFO;						// write the recieved bytes to the correct place of the buffer
    
    
    				Trf7970ReadCont(&buf[rxtx_state], *irq_status);
    				rxtx_state = rxtx_state + *irq_status;
    
    				i_reg = 0xFF;			// signal to the recieve funnction that this are the last bytes
    				Trf7970Reset();		// reset the FIFO after last byte has been read out
    			}
    			else if(*irq_status == 0x50)	// end of recieve and error
    			{
    				i_reg = 0x02;
    			}
    		}
    		else
    		{
    			Trf7970ReadIrqStatus(irq_status);
    
    			if(irq_status[0] == 0x00)
    			{
    				i_reg = 0xFF;
    			}
    		}
    	}
    	else if((*irq_status & BIT4) == BIT4)				// CRC error
    	{
    		if((*irq_status & BIT5) == BIT5)
    		{
    			i_reg = 0x01;	// RX active
    			rx_error_flag = 0x02;
    		}
    		if((*irq_status & BIT6) == BIT6)			// 4 Bit receive
    		{
    			buf[200] = FIFO;						// write the recieved bytes to the correct place of the buffer
    
    			Trf7970ReadCont(&buf[200], 1);
    
    			Trf7970Reset();
    
    			i_reg = 0x02;	// end of RX
    			rx_error_flag = 0x02;
    		}
    		else
    		{
    			i_reg = 0x02;	// end of RX
    		}
    	}
    	else if((*irq_status & BIT2) == BIT2)	// byte framing error
    	{
    		if((*irq_status & BIT5) == BIT5)
    		{
    			i_reg = 0x01;	// RX active
    			rx_error_flag = 0x02;
    		}
    		else
    			i_reg = 0x02;	// end of RX
    	}
    	else if((*irq_status == BIT0))
    	{						// No response interrupt
    		i_reg = 0x00;
    	}
    	else
    	{						// Interrupt register not properly set
    		i_reg = 0x02;
    
    		Trf7970StopDecoders();	// reset the FIFO after TX
    
    		Trf7970Reset();
    
    		Trf7970ResetIrqStatus();
    
    		IRQ_CLR;
    	}
    }                            // Interrupt Service Routine
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    #pragma vector = PORT3_VECTOR
    __interrupt void
    Trf7970PortB(void)                            // interrupt handler
    {
      u08_t irq_status[4], iso_control;
    
      irq_flag = 0x02;
    
      STOP_COUNTER;                            // stop timer mode
    
      do
      {
        IRQ_CLR;                            // PORT2 interrupt flag clear
    
    	iso_control = ISO_CONTROL;
    	Trf7970ReadSingle(&iso_control, 1);
        Trf7970ReadIrqStatus(irq_status);
    
    	if((iso_control & BIT5) != BIT5)			// RFID mode
    	{
    		Trf7970ISR(irq_status);
    	}
    
      } while((IRQ_PORT & IRQ_PIN) == IRQ_PIN);
      __bic_SR_register_on_exit(LPM0_bits);
    }
    
    //===============================================================
    // NAME: void Trf7970RawWrite (u08_t *pbuf, u08_t length)
    //
    // BRIEF: Is used to write direct to the Trf7970.
    //
    // INPUTS:
    //    Parameters:
    //        u08_t        *pbuf        raw data
    //        u08_t        length        number of data bytes
    //
    // OUTPUTS:
    //
    // PROCESS:    [1] send raw data to Trf7970
    //
    // CHANGE:
    // DATE          WHO    DETAIL
    // 24Nov2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970RawWrite(u08_t *pbuf, u08_t length)
    {
      SpiRawWrite(pbuf, length);
    
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970ReConfig(void)
    {
      //SpiUsciSet();                   // Set the USART
    
    }
    
    //===============================================================
    // NAME: void Trf7970ReadCont (u08_t *pbuf, u08_t length)
    //
    // BRIEF: Is used to read a specified number of Trf7970 registers
    // from a specified address upwards.
    //
    // INPUTS:
    //    Parameters:
    //        u08_t        *pbuf        address of first register
    //        u08_t        length        number of registers
    //
    // OUTPUTS:
    //
    // PROCESS:    [1] read registers
    //            [2] write contents to *pbuf
    //
    // CHANGE:
    // DATE          WHO    DETAIL
    // 24Nov2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970ReadCont(u08_t *pbuf, u08_t length)
    {
      SpiReadCont(pbuf, length);
    
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970ReadIrqStatus(u08_t *pbuf)
    {
      *pbuf = IRQ_STATUS;
      *(pbuf + 1) = IRQ_MASK;
      Trf7970ReadCont(pbuf, 2);           // read second reg. as dummy read
    
    }
    
    //===============================================================
    // NAME: void Trf7970ReadSingle (u08_t *pbuf, u08_t number)
    //
    // BRIEF: Is used to read specified Trf7970 registers.
    //
    // INPUTS:
    //    Parameters:
    //        u08_t        *pbuf        addresses of the registers
    //        u08_t        number        number of the registers
    //
    // OUTPUTS:
    //
    // PROCESS:    [1] read registers
    //            [2] write contents to *pbuf
    //
    // CHANGE:
    // DATE          WHO    DETAIL
    // 24Nov2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970ReadSingle(u08_t *pbuf, u08_t number)
    {
      SpiReadSingle(pbuf, number);
    }
    
    //===============================================================
    // resets FIFO                                                  ;
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970Reset(void)
    
    {
      command[0] = RESET;
      Trf7970DirectCommand(command);
    
    }
    
    //===============================================================
    // resets IRQ Status                                            ;
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970ResetIrqStatus(void)
    {
      u08_t irq_status[4];
      irq_status[0] = IRQ_STATUS;
      irq_status[1] = IRQ_MASK;
    
      Trf7970ReadCont(irq_status, 2);        // read second reg. as dummy read
    }
    
    //===============================================================
    //                                                              ;
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970RunDecoders(void)
    {
      command[0] = RUN_DECODERS;
      Trf7970DirectCommand(command);
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970StopDecoders(void)
    {
      command[0] = STOP_DECODERS;
      Trf7970DirectCommand(command);
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970TransmitNextSlot(void)
    {
      command[0] = TRANSMIT_NEXT_SLOT;
      Trf7970DirectCommand(command);
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970TurnRfOff(void)
    {
      command[0] = CHIP_STATE_CONTROL;
      command[1] = CHIP_STATE_CONTROL;
      Trf7970ReadSingle(&command[1], 1);
      command[1] &= 0x1F;
      Trf7970WriteSingle(command, 2);
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970TurnRfOn(void)
    {
      u08_t write[4];
      write[0] = CHIP_STATE_CONTROL;
    //  write[1] = 0x20;                    // 3.3VDC, Full power out
      write[1] = 0x21;                    // 5VDC, Full power out     changed 11-8-2017
      Trf7970WriteSingle(write, 2);
    
    }
    
    //===============================================================
    // NAME: void SpiWriteCont (u08_t *pbuf, u08_t length)
    //
    // BRIEF: Is used to write to a specific number of reader chip
    // registers from a specific address upwards.
    //
    // INPUTS:
    //    u08_t    *pbuf    address of first register followed by the
    //                    contents to write
    //    u08_t    length    number of registers + 1
    //
    // OUTPUTS:
    //
    // PROCESS:    [1] write to the registers
    //
    // CHANGE:
    // DATE          WHO    DETAIL
    //===============================================================
    
    void
    Trf7970WriteCont(u08_t *pbuf, u08_t length)
    {
      SpiWriteCont(pbuf, length);
    }
    
    //===============================================================
    // 02DEC2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970WriteIsoControl(u08_t iso_control)
    {
      u08_t write[16];
    
     /* write[0] = ISO_CONTROL;
      write[1] = iso_control;
      write[1] &= ~BIT5;
      Trf7970WriteSingle(write, 2);
    
      iso_control &= 0x1F;
      write[0] = IRQ_MASK;
      write[1] = 0x3F;
      Trf7970WriteSingle(write, 2);*/
    
    #ifdef ENABLE15693                // this standard can be disabled in ISO15693.h
      if (iso_control == 0x02)
      {
        write[0] = 0x20;                  //Continuous Write, starting with register 0x00
        write[1] = 0x20;                  //Value for Chip Status Control Register 0x00, 0x20 = +3.3VDC, full power, etc.
        write[2] = 0x02;                  //Value for ISO Control Register 0x01, 0x02 = high tag data rate, etc.
        write[3] = 0x00;
        write[4] = 0x00;
        write[5] = 0xC1;
        write[6] = 0xBB;
        write[7] = 0x00;
        write[8] = 0x30;
        write[9] = 0x1F;
        write[10] = 0x01;
        write[11] = 0x40;
        write[12] = 0x03;
    
        Trf7970WriteCont(write, 13);      //writes registers 0x00:0x0B
      }
    #endif
    
    #ifdef ENABLE14443A            // this standard can be disabled in ISO14443A.h
      if (iso_control == 0x88)                                                               // changed by Anil(23-06-2018)
      {
    //    write[0] = 0x20;
    //    write[1] = 0x20;    //full power out, 3.3VDC
    //    write[2] = 0x88;
    //    write[3] = 0x00;
    //    write[4] = 0x00;
    //    write[5] = 0xC1;
    //    write[6] = 0xBB;
    //    write[7] = 0x20;
    //    write[8] = 0x0E;
    //    write[9] = 0x07;
    //    write[10] = 0x21;
    //    write[11] = 0x20;
    //    write[12] = 0x87;
    //
    //    Trf7970WriteCont(write, 13);
    
    	  write[0] = ISO_CONTROL;
    	  write[1] = 0x88;
    	  Trf7970WriteSingle(write, 2);
    
    	  write[0] = MODULATOR_CONTROL;
    	  write[1] = 0x01;
    	  Trf7970WriteSingle(write, 2);
    
    	  write[0] = ADJUSTABLE_FIFO_LEVEL;			//this is register 0x14
    	  write[1] = 0x0F;
    	  Trf7970WriteSingle(write, 2);
      }
    #endif
    
    #ifdef ENABLE14443B            // this standard can be disabled in ISO14443B.h
      if (iso_control == 0x0C)
      {
        write[0] = 0x20;
        write[1] = 0x20;  //full power out, 3.3VDC
        write[2] = 0x0C;
        write[3] = 0x00;
        write[4] = 0x00;
        write[5] = 0xC1;
        write[6] = 0xBB;
        write[7] = 0x00;
        write[8] = 0x0D;
        write[9] = 0x07;
        write[10] = 0x03;
        write[11] = 0x00;
        write[12] = 0x87;
    
        Trf7970WriteCont(write, 13);
    
        write[0] = IRQ_MASK;
        write[1] = 0x3E;
        Trf7970WriteSingle(write, 2);
    
        write[0] = ADJUSTABLE_FIFO_LEVEL;
        write[1] = 0x0F;
        Trf7970WriteSingle(write, 2);
      }
    #endif
    
    
    }
    
    //===============================================================
    // NAME: void Trf7970WriteSingle (u08_t *pbuf, u08_t length)
    //
    // BRIEF: Is used to write to specified reader chip registers.
    //
    // INPUTS:
    //    u08_t    *pbuf    addresses of the registers followed by the
    //                    contents to write
    //    u08_t    length    number of registers * 2
    //
    // OUTPUTS:
    //
    // PROCESS:    [1] write to the registers
    //
    // CHANGE:
    // DATE          WHO    DETAIL
    // 24Nov2010    RP    Original Code
    //===============================================================
    
    void
    Trf7970WriteSingle(u08_t *pbuf, u08_t length)
    {
      SpiWriteSingle(pbuf, length);
    
    }
    
    
    
    /*
     * {iso14443a.c}
     *
     * {ISO14443A Specific Functions & Anti-collision}
     *
     * Copyright (C) 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.
     *
     */
    
    //#include "iso14443a.h"
    //#include "trf7970.h"
    //#include "NFC_Protocol.h"
    //#include<stdio.h>
    //#include<stdlib.h>
    //#include<string.h>
    //#include "type.h"
    #include "header.h"
    //===============================================================
    
    u08_t	complete_uid[14];
    u08_t	coll_poss = 0;
    u08_t	uid_pos = 0, uid_pos1;
    extern u08_t buf[300];
    extern u08_t i_reg;
    extern u08_t irq_flag;
    extern u08_t rx_error_flag;
    extern s08_t rxtx_state;
    extern u08_t stand_alone_flag;
    extern u08_t remote_flag;
    extern u08_t Tag_Count;
    
    unsigned int addr1=0,address=0;
    unsigned int LEN_OF_READ;
    unsigned char LENGTH_OF_UID=0;
    char UID_ARRAY[50] = {0x00};
    char DUMMY_UID_ARRAY[50] = {0x00};
    char READ_ARRAY[144] = {0x00};
    char ALL_DATA[190]={0x00};
    char DUMMY_READ_ARRAY[144] = {0x00};
    
    extern char check[2];
    extern int incr_addr,Column_Ctr;
    extern unsigned char End_of_String;
    extern char Rx_Data[168];
    extern unsigned char tag_found;
    extern char length;
    extern u08_t PREV_TAG;
    extern unsigned char TIMER_ON;
    extern char COUNT;
    extern unsigned char IR_READY;
    unsigned long int Dummy_Stuck_Variable=0;
    
    // command
    #define REQA	0x26
    #define WUPA	0x52
    
    #define NVB_INIT 0x20
    #define NVB_FULL 0x70
    #define LEVEL1	0x93
    #define LEVEL2	0x95
    #define LEVEL3	0x97
    #define RX_CRC		0x08
    #define NO_RX_CRC	0x88
    
    #define  ENABLE_HOST	1
    
    //===============================================================
    // NAME: void Iso14443aFindTag(void)
    //
    // BRIEF: Is used to detect ISO14443A conform tags in stand alone 
    // mode.
    //
    // INPUTS:
    //	
    // OUTPUTS:
    //
    // PROCESS:	[1] turn on RF driver
    //			[2] do a complete anticollision sequence
    //			[3] turn off RF driver
    //
    // NOTE: If ISO14443A conform Tag is detected, ISO14443A LED will
    //       be turned on.
    //
    // CHANGE:
    // DATE  		WHO	DETAIL
    // 23Nov2010	RP	Original Code
    //===============================================================
    
    void
    Iso14443aFindTag(void)
    {
        Trf7970TurnRfOn();
    
        Trf7970WriteIsoControl(0x88);
    
        // When a PICC is exposed to an unmodulated operating field
        // it shall be able to accept a quest within 5 ms.
        // PCDs should periodically present an unmodulated field of at least
        // 5,1 ms duration. (ISO14443-3)
        McuDelayMillisecond(20);
    
        Iso14443aAnticollision(0x00);						// do a complete anticollision sequence as described1
    
        // in ISO14443-3 standard for type A
        Trf7970TurnRfOff();
    
        Trf7970ResetIrqStatus();
    }
    
    //===============================================================
    // NAME: void Iso14443aAnticollision(u08_t reqa)
    //
    // BRIEF: Is used to start the ISO14443A Anticollision Loop.
    //
    // INPUTS:
    //	Parameters:
    //		u08_t		reqa		REQA or WUPA
    //
    // OUTPUTS:
    //
    // PROCESS:	[1] send REQA or WUPA command
    //			[2] receive ATQA
    //			[3] perform bit frame anticollison loop
    //
    // NOTE: Collisions returned as �(z)�.
    //       Timeouts returned as �()�.
    //
    // CHANGE:
    // DATE  		WHO	DETAIL
    // 23Nov2010	RP	Original Code
    //===============================================================
    
    void
    Iso14443aAnticollision(u08_t reqa)
    {
        static char ch;
        unsigned char Read_Count = 0x00;
        u08_t nvb = NVB_INIT;
        u08_t ui8BlockNumber;
        char checksum=0;
        static char Dummy_Count=0;
        static char Del_Count=0;
    
        rxtx_state = 1;
        Iso14443_config(NO_RX_CRC);
        	McuDelayMillisecond(2);
    //    McuDelayMillisecond(4);
    
        Iso14443a_command(WUPA);			//send WUPA (0x52) to wake up all tags
        if(i_reg == 0xFF || i_reg == 0x02)
        {
            uid_pos = 0;
            //		memset(UID_ARRAY,0,sizeof(UID_ARRAY));
            Iso14443aLoop(0x01, nvb, &buf[40]);			// cascade level 1  // Finding the UID here...
            strncpy(DUMMY_UID_ARRAY,UID_ARRAY,50);
    
            if((stand_alone_flag == 1) && (tag_found == 0) && (Tag_Count != 0))
            {
                memset(READ_ARRAY,0,sizeof(READ_ARRAY));
                address = LOW;
    
                {       //just for when i got more than 5, Zeros in UID
                    Dummy_Count=0;
                    Del_Count = 0;
                    for(ch=0;ch<addr1;ch++)
                    {
                        if(UID_ARRAY[ch] == '0')
                            Dummy_Count++;
                        if(UID_ARRAY[ch] == '\0')
                        {
                            memset(UID_ARRAY,0x00,sizeof(UID_ARRAY));
                            addr1=LOW;                  /// for the UID
                            return;
                        }
                        if(UID_ARRAY[ch] == ':')
                            Del_Count++;
                    }
                    if((Dummy_Count>=6) || (Del_Count < 6))
                    {
                        addr1=LOW;                  /// for the UID
                        Dummy_Count=0;
                        Del_Count = 0;
                        memset(UID_ARRAY,0x00,sizeof(UID_ARRAY));
                        return;
                    }
                }
    
                if((addr1 > 12) && (addr1 < 26))      /////UID of NFC TAG
                {
                    Tx_Uart1_String("DR\n");
                    for (ui8BlockNumber = 4; ui8BlockNumber < 144; ui8BlockNumber=ui8BlockNumber + 4) 	//for dynamically reading all data blocks on tag
                        NFC_TYPE2_READ_4_BLOCKS(ui8BlockNumber);										//reference T2T operation specification (command 0x30)
    
                    memset(ALL_DATA,0,sizeof(ALL_DATA));
                    TB0CTL = MC__STOP| TBCLR;
                    COUNT =0;    							// when response came then i need to clear the re-transmission count
                    LEN_OF_READ = LOW;
    
                    for(ch=0;ch<addr1;ch++)
                    {
                        if(UID_ARRAY[ch] == '\0')
                        {
                            memset(UID_ARRAY,0x00,sizeof(UID_ARRAY));
                            addr1=LOW;					/// for the UID
                            return;
                        }
                    }
    
                    for(Read_Count=0;Read_Count<86;Read_Count++)    //If Read data is not valid
                    {
                        if(DUMMY_READ_ARRAY[Read_Count] < 0x21)
                        {
                            memset(UID_ARRAY,0x00,sizeof(UID_ARRAY));
                            addr1=LOW;                  /// for the UID
                            return;
                        }
                    }
    
                    Tx_Uart1_String("*f;2;");				/// NFC
                    strcat(ALL_DATA,"*f;2;");
                    Tx_Uart1_String(UID_ARRAY);
                    strcat(ALL_DATA,UID_ARRAY);
                    Tx_Uart_String(DUMMY_READ_ARRAY,85);
                    strncat(ALL_DATA,DUMMY_READ_ARRAY,85);
                    ui8BlockNumber = strlen("*f;2;") + strlen(UID_ARRAY) + 85;
                    ALL_DATA[ui8BlockNumber] = ';';
                    Tx_Uart1_Char(';');
                    checksum = Cal_Checksum(ALL_DATA,ui8BlockNumber+1);
                    Valid_CRC(checksum);
                    Tx_Uart1_Char(check[0]);
                    Tx_Uart1_Char(check[1]);
                    Tx_Uart1_Char('#');
                    tag_found = 1;
                    IR_READY = 0;				// if first time tag is detected then i need to disable the tag detection action.
    
                }
                else if(addr1 < 2)
                {
                    memset(ALL_DATA,0,sizeof(ALL_DATA));
                    //				TB0CTL = MC__STOP| TBCLR;
                    COUNT =0;    							// when response came then i need to clear the re-transmission count
                    LEN_OF_READ = LOW;
                    ///// here no data pass because no UID is found
                }
                else// if(start_addr_read1 > 0 )
                {
                    memset(ALL_DATA,0,sizeof(ALL_DATA));
                    TB0CTL = MC__STOP| TBCLR;
                }
            }
        }
    
        if(End_of_String)
        {
            REC_DATA();//Rx_Data);							///check the input data from baseboard is correct or not; if corrct then give response according to the input
            memset(Rx_Data,0x00,MAX_SIZE_Rf);
            End_of_String = LOW;
            incr_addr = LOW;    			 //// for the received data
            Column_Ctr = LOW;   			 // for the column count
        }
        memset(UID_ARRAY,0,sizeof(UID_ARRAY));
        addr1=LOW;					/// for the UID
        Iso14443_config(NO_RX_CRC);
        return;
    }										// Iso14443aAnticollision
    
    
    void UID_CAL(char c)
    {
        UID_ARRAY[addr1++] = hexDigit(c / 0x10);
        UID_ARRAY[addr1++] = hexDigit(c % 0x10);
    }
    
    //===============================================================
    // NAME: void Iso14443aLoop(u08_t select, u08_t nvb, u08_t
    // 			*uid)
    //
    // BRIEF: Is used to run through the cascade levels.
    //
    // INPUTS:
    //	Parameters:
    //		u08_t		select		indicates cascade level
    //		u08_t		nvb			number of valid bits
    //		u08_t		*uid		known part of UID
    //	
    // OUTPUTS:
    //	Globals:
    //		u08_t		complete_uid[14]	stores UID
    //
    // PROCESS:	(ISO14443-3)
    //
    // NOTE: Collisions returned as �(z)�.
    //       Timeouts returned as �()�.
    //
    // CHANGE:
    // DATE  		WHO	DETAIL
    // 23Nov2010	RP	Original Code
    //===============================================================
    
    void Iso14443aLoop(u08_t cascade_level, u08_t nvb, u08_t *uid)
    {
        u08_t	i = 0;
    
        u08_t	nvbytes = 0, nvbits = 0, xbits = 0, found = 0;
        u08_t new_uid[4];
        u08_t select, new_uid1[4], coll_poss1, nvbits1;
        u08_t cascade_level1;
    #ifdef ENABLE_HOST
        u08_t rssi[2];
    #endif
    
        while (cascade_level < 4)
        {
            switch (cascade_level)
            {
            case 1:
                select = 0x93;
                break;
            case 2:
                select = 0x95;
                break;
            case 3:
                select = 0x97;
                break;
            default:
                break;
            }
    
            if((nvb & 0x0F) != 0x00)
            {
                nvbytes = (nvb >> 4) - 2;			// the number of known valid bytes
                xbits = nvb & 0x07;					// the number of known valid bits
    
                // Both are used in the UID calculation
                for(i = 0; i < xbits; i++)
                {
                    nvbits = (nvbits << 1) + 1;
                }
            }
            rx_error_flag = 0;
            coll_poss = 0x21;
            rxtx_state = 1;							// The response will be stored in buf[1] upwards
            Iso14443aSelectCommand(select, nvb, uid);
    
    //        while (coll_poss < 0x20)
    //        {
    //            if(i_reg == 0x00)
    //                break;
    //            Dummy_Stuck_Variable++;
    //            if((Dummy_Stuck_Variable>=3) && ((Dummy_Stuck_Variable<=4)))
    //                Tx_Uart1_String("Stck\n");
    //        }
    
            if (coll_poss == 0x20)
                i_reg = 0x02;						// In case coll_poss=0x20 means didn't receive response
            for(i = 0; i < 5; i++)
            {
                complete_uid[i+uid_pos] = buf[i + 1];
            }
            if(rx_error_flag == 0x02)
            {
                i_reg = 0x02;
            }
            if(i_reg == 0x02 || i_reg == 0x00)		// collision or timeout
            {
                break;
            }
            if(i_reg == 0xff)						// if data received
            {
                for (i=0; i<nvbytes; i++)
                    complete_uid[i+uid_pos] = *(uid + i);
                complete_uid[nvbytes+uid_pos] = (buf[1] &~nvbits) | (*(uid + nvbytes) & nvbits);
                for (i=1; i<(5-nvbytes); i++)
                    complete_uid[i+nvbytes+uid_pos] = buf[1+i];
    
                nvb = NVB_FULL;
                rxtx_state = 1;
                Iso14443aSelectCommand(select, nvb, &complete_uid[uid_pos]);
                			McuDelayMillisecond(6);
    //            McuDelayMillisecond(12);
                if (buf[1] & BIT2)				//uid not complete
                {
                    cascade_level++;
                    uid_pos += 5;
                    nvb = NVB_INIT;
                }
                else				// uid completed, print UID to uart.
                {
    #ifdef ENABLE_HOST
                    Tag_Count++;
                    memset(UID_ARRAY,0,sizeof(UID_ARRAY));
                    addr1=LOW;					/// for the UID
                    //	Tx_Uart1_String("ISO14443 type A: ");
                    //	Tx_Uart1_Char('[');
                    switch (cascade_level)
                    {
    
                    //								case 1:
                    //									for (i=0; i<4; i++)
                    //									{
                    //										charToHex(complete_uid[i]);
                    //										if(i==3)
                    //											Tx_Uart1_Char(';');
                    //										else
                    //											Tx_Uart1_Char(':');
                    //									}
                    //									break;
                    //
                    //								case 2:
                    //									for (i=1; i<4; i++)
                    //									{
                    //										charToHex(complete_uid[i]);
                    //										Tx_Uart1_Char(':');
                    //									}
                    //
                    //									for (i=5; i<9; i++)
                    //									{
                    //										charToHex(complete_uid[i]);
                    //										if(i==8)
                    //										Tx_Uart1_Char(';');
                    //										else
                    //											Tx_Uart1_Char(':');
                    //									}
                    //									break;
                    //
                    //								case 3:
                    //									for (i=1; i<4; i++)
                    //									{
                    //										charToHex(complete_uid[i]);
                    //										Tx_Uart1_Char(':');
                    //									}
                    //									for (i=6; i<9; i++)
                    //									{
                    //										charToHex(complete_uid[i]);
                    //										Tx_Uart1_Char(':');
                    //									}
                    //									for (i=10; i<14; i++)
                    //									{
                    //										charToHex(complete_uid[i]);
                    //										if(i==13)
                    //											Tx_Uart1_Char(';');
                    //										else
                    //											Tx_Uart1_Char(':');
                    //									}
    
                    //////////////////////////////////////////////////////////////
                    case 1:
                        for (i=0; i<4; i++)
                        {
                            UID_CAL(complete_uid[i]);
                            if(i==3)
                                UID_ARRAY[addr1++] = ';';
                            else
                                UID_ARRAY[addr1++] = ':';
                        }
                        break;
    
                    case 2:
                        for (i=1; i<4; i++)
                        {
                            UID_CAL(complete_uid[i]);
                            UID_ARRAY[addr1++] = ':';
                        }
    
                        for (i=5; i<9; i++)
                        {
                            UID_CAL(complete_uid[i]);
                            if(i==8)
                                UID_ARRAY[addr1++] = ';';
                            else
                                UID_ARRAY[addr1++] = ':';
                        }
                        break;
    
                    case 3:
                        for (i=1; i<4; i++)
                        {
                            UID_CAL(complete_uid[i]);
                            UID_ARRAY[addr1++] = ':';
                        }
                        for (i=6; i<9; i++)
                        {
                            UID_CAL(complete_uid[i]);
                            UID_ARRAY[addr1++] = ':';
                        }
                        for (i=10; i<14; i++)
                        {
                            UID_CAL(complete_uid[i]);
                            if(i==13)
                                UID_ARRAY[addr1++] = ';';
                            else
                                UID_ARRAY[addr1++] = ':';
                        }
                        break;
                        /////////////////////////////////////////////////////////////////////////////////
                    default:
                        break;
                    }
                    //	Tx_Uart1_Char(',');
                    rssi[0] = RSSI_LEVELS;			// read RSSI levels
                    Trf7970ReadSingle(rssi, 1);
                    //	charToHex(rssi[0]);
                    //Tx_Uart1_Char(rssi[0]);
                    //	Tx_Uart1_Char(']');
                    //	Tx_Uart1_Char(0x0A);
    #endif
    
                    if(stand_alone_flag == 1)
                        found = 1;
                    i_reg = 0x01;					// do nothing after
                    break;
                }
            }
            _nop();
        }
        if(i_reg == 0x00)							// timer interrupt
        {
            //		if(stand_alone_flag == 1)
            //		{
            //			#ifdef ENABLE_HOST
            //				UartPutChar('(');
            //				UartSendCString("No tag found/Error");
            //				UartPutChar(')');
            //				UartPutCrlf();
            //			#endif
            //		}
        }
    
        if(i_reg == 0x02)									// if collision occured go into anticollision
        {
            for (i=0; i<4; i++)
            {
                new_uid[i] = buf[i+1];
            }
            // a RX interrupt will happen after collision interrupt
            		McuDelayMillisecond(5);
    //        McuDelayMillisecond(10);
    
            if (coll_poss == 0x60 || coll_poss == 0x70)			// if all of 4 or 5 bytes of last level were in collision
            {
                cascade_level++;
                uid_pos += 5;
                coll_poss = 0x20;
            }
            else
            {
                // combine UCLn collected of last loop
                for (i=0; i<nvbytes; i++)
                    new_uid[i] = *(uid + i);
                new_uid[nvbytes] = (new_uid[nvbytes] &~ nvbits) | (*(uid + nvbytes) & nvbits);
    
            }
            // calculate new parameters
            nvbytes = (coll_poss >> 4) - 2;				// how many bytes was collected
            xbits  = coll_poss & 0x07;					// how many bits was collected
            coll_poss++;
            nvbits = 0;
            for (i = 0; i < xbits; i++)
            {
                nvbits = (nvbits << 1) + 1;				// left shift to make a mask for last broken byte (create all bit 1 belong to how many bit in broken byte)
            }
            nvbits1 = (nvbits << 1) + 1;
            nvbits1 = nvbits1 - nvbits;				// bit_mask1 use to seperate next bit after last broken bit
    
            new_uid[nvbytes] = new_uid[nvbytes] & nvbits;		// only keep collsion bits
    
            //back up before loop
            for (i=0; i<=4; i++)
            {
                new_uid1[i] = new_uid[i];
            }
            coll_poss1 = coll_poss;
            uid_pos1 = uid_pos;
            cascade_level1 = cascade_level;
    
            Iso14443aLoop(cascade_level, coll_poss, new_uid);		// recursive call for anticollision procedure
            		McuDelayMillisecond(6);
    //        McuDelayMillisecond(12);
            Iso14443a_halt();
    
            i_reg = 0x01;
            Iso14443a_command(WUPA);
            		McuDelayMillisecond(6);
    //        McuDelayMillisecond(12);
            uid_pos = uid_pos1;
            new_uid1[nvbytes] = new_uid1[nvbytes] + nvbits1;
            Iso14443aLoop(cascade_level1, coll_poss1, new_uid1);		// recursive call for anticollision procedure
        }
    
        if(stand_alone_flag == 1)
        {
            if(found == 1)
            {
                //LED_14443A_ON;
            }
            else
            {
                //LED_14443A_OFF;
            }
        }
    }														// Iso14443aLoop
    
    void ISO14443IRQWaitTimeout(u08_t txtimeout, u08_t rxtimeout)
    {
        i_reg = 0x01;
        while(i_reg != 0x00)
        {
            McuCounterSet();
            COUNT_VALUE = COUNT_1ms * txtimeout;
            irq_flag = 0x00;
            START_COUNTER;						// start timer up mode
            while(irq_flag == 0x00)				// wait for interrupt
            {
            }
    
        }										// wait for end of TX
        RESET_COUNTER;
        //
        i_reg = 0x01;
        while(i_reg == 0x01)		// wait for end of RX or timeout
        {
            McuCounterSet();
            COUNT_VALUE = COUNT_1ms * rxtimeout;
            irq_flag = 0x00;
            START_COUNTER;						// start timer up mode
            while(irq_flag == 0x00)
            {
            }									// wait for interrupt
    
        }
        RESET_COUNTER;
    }
    
    void Iso14443aSelectCommand(u08_t select, u08_t nvb, u08_t *uid)
    {
        u08_t length;
        Iso14443_config(RX_CRC);
    
        length = 5 + (nvb >> 4);
        if((nvb & 0x0F) != 0x00)
        {
            length++;
        }
    
        buf[0] = 0x8F;							// prepare the SELECT command
        if(nvb == 0x70)							// select command, otherwise anticollision command
        {
            buf[1] = 0x91;						// transmit with CRC
        }
        else
        {
            buf[1] = 0x90;
        }
        buf[2] = 0x3D;
        buf[3] = 0x00;
        buf[4] = nvb & 0xF0;					// number of complete bytes
        if((nvb & 0x07) != 0x00)
        {
            buf[4] |= ((nvb & 0x07) << 1) + 1; 	// number of broken bits, last bit is 1 means broken byte
        }
        buf[5] = select;						// can be 0x93, 0x95 or 0x97
        buf[6] = nvb;							// number of valid bits
        buf[7] = *uid;
        buf[8] = *(uid + 1);
        buf[9] = *(uid + 2);
        buf[10] = *(uid + 3);
        buf[11] = *(uid + 4);
    
        Trf7970RawWrite(&buf[0], length);
    
        ISO14443IRQWaitTimeout(5,50);
        //	ISO14443IRQWaitTimeout(5,25);
        	McuDelayMillisecond(1);
    //    McuDelayMillisecond(2);
    }
    
    void Iso14443a_halt()
    {
        Iso14443_config(NO_RX_CRC);
    
        buf[0] = 0x8F;							// prepare the SELECT command
        buf[1] = 0x90;
        buf[2] = 0x3D;
        buf[3] = 0x00;
        buf[4] = 0x20;					// number of complete bytes
        buf[5] = 0x50;						//halt
        buf[6] = 0x00;							// number of valid bits
    
        Trf7970RawWrite(&buf[0], 7);
    
        i_reg = 0x01;
        while(i_reg != 0x00)
        {
            McuCounterSet();
            COUNT_VALUE = COUNT_1ms * 2;		// 2ms for TIMEOUT
            irq_flag = 0x00;
            START_COUNTER;						// start timer up mode
            while(irq_flag == 0x00)				// wait for interrupt
            {
            }
            RESET_COUNTER;
        }										// wait for end of TX
    }
    
    void Iso14443a_command(u08_t command)
    {
        buf[0] = 0x8F;
        buf[1] = 0x90;
        buf[2] = 0x3D;
        buf[3] = 0x00;
        buf[4] = 0x0F;
        buf[5] = command;
    
        rxtx_state = 1;
    
        Trf7970RawWrite(&buf[0], 6);
    
        IRQ_CLR;								// PORT2 interrupt flag clear
        IRQ_ON;
    
        ISO14443IRQWaitTimeout(5,50);
        //	ISO14443IRQWaitTimeout(5,25);
        	McuDelayMillisecond(5);
    //    McuDelayMillisecond(10);
    }
    
    
    void Iso14443_config(u08_t crc)
    {
        Trf7970WriteIsoControl(crc);
        Trf7970ReadSingle(buf,1);
    }
    
    //===============================================================
    // NAME: void NFC_TYPE2_READ_4_BLOCKS(void)
    //
    // BRIEF: Is used to read NFC Type 2 Tag Platform data blocks four at a time in stand alone mode.
    //
    // INPUTS: StartBlock
    //
    // OUTPUTS:4 Blocks Data at time
    //
    // PROCESS:	[1] inside Find Tags Loop
    //			[2] NFC Forum TT2 BLock Data read sequence
    //			[3] Return data to Host
    //			[4] Loop to read all data blocks
    //
    // NOTE:
    //
    // CHANGE:
    // DATE  		WHO	DETAIL
    // 01/18/2014	JDW	Original Code
    //===============================================================
    void NFC_TYPE2_READ_4_BLOCKS(u08_t ui8StartBlock)
    {
        u08_t	i = 1, j = 0;
        u16_t	k;
    
        //buf[0] = SPECIAL_FUNCTION;				//to enable 4-bit RX
        //buf[1] = 0x04;							//setting bit 2 in register 0x10
        //Trf7970WriteSingle(&buf[0], 2);
    
        buf[0] = 0x8F;							//Reset FIFO
        buf[1] = 0x91;							//Send with CRC
        buf[2] = 0x3D;							//Write Continuous
        buf[3] = 0x00;							//upper and middle nibbles of # of bytes going to FIFO
        buf[4] = 0x20;							//lower nibble # and broken # of bytes going to FIFO (in this case 2 complete bytes are going to be transmitted)
        buf[5] = 0x30;							//Read Command
        buf[6] = ui8StartBlock;					//Starting from Block # (called Bno)
    
        rxtx_state = 1;
    
        Trf7970RawWrite(&buf[0], 7);
    
        IRQ_CLR;								// PORT2 interrupt flag clear
        IRQ_ON;
    
    //    ISO14443IRQWaitTimeout(5,50);
    
        i_reg = 0x01;
        irq_flag = 0x00;
        START_COUNTER;										//	Starting Timeout
    
        while(irq_flag == 0x00)
        {
        }													// wait for end of TX interrupt
        RESET_COUNTER;
    
        McuCounterSet();									// TimerA set
        COUNT_VALUE = COUNT_1ms * 20;
        START_COUNTER;										// start timer up mode
    
        irq_flag = 0x00;
    
        while(irq_flag == 0x00)
        {
        }													// wait for interrupt
        RESET_COUNTER;
    
        while(i_reg == 0x01)								// wait for RX complete
        {
            k++;
    
            if(k == 0xFFF0)
            {
                i_reg = 0x00;
                rx_error_flag = 0x00;
            }
        }
    
        //Tx_Uart1_String("In Read Block : \n");
        if( i_reg == 0xFF)
        {		// if received block data in buffer
            if(stand_alone_flag == 1)
            {
                //found = 1;
    #ifdef ENABLE_HOST
                for(j = 0; j < 4; j++)
                {
                    //				Tx_Uart1_String("NFC Type2 Block ");
                    //				charToHex(ui8StartBlock++);
                    //				Tx_Uart1_String(":  [");
                    for(i = 1+(j*4); i < 5+(j*4); i++)
                    {
                        READ_ARRAY[address] = buf[i];
                        DUMMY_READ_ARRAY[address]=READ_ARRAY[address];
                        address++;
    
                        //					Tx_Uart1_Char(buf[i]);
                        //					if(buf[i] == '#')
                        //					{
                        //						//						END_OF_DATA = HIGH;
                        //						//						break;
                        //					}
                    }
                    //				Tx_Uart1_Char(']');
                    //				Tx_Uart1_Char('\n');
                }
    #endif
            }
        }
    }
    
    //===============================================================
    // NAME: void NFC_TYPE2_WRITE_BLOCK(void)
    //
    // BRIEF: Is used to read NFC Type 2 Tag Platform data blocks four at a time in stand alone mode.
    //
    // INPUTS: StartBlock
    //
    // OUTPUTS:4 Blocks Data at time
    //
    // PROCESS:	[1] inside Find Tags Loop
    //			[2] NFC Forum TT2 BLock Data write sequence
    //			[3] Return data to Host
    //			[4] Loop to read all data blocks
    //
    // NOTE:
    //
    // CHANGE:
    // DATE  		WHO	DETAIL
    // 01/18/2014	JDW	Original Code
    //===============================================================
    void NFC_TYPE2_WRITE_BLOCK(u08_t ui8StartBlock, char *uid) //test function on one block for now (01/27/2014, JDW)
    {
        //	u08_t	i = 1, j = 0;
        u16_t	k;
    
        buf[0] = ISO_CONTROL;
        buf[1] = 0x88;							//to RX with CRC
        Trf7970WriteSingle(&buf[0], 2);
    
        buf[0] = SPECIAL_FUNCTION;				//to enable 4-bit RX
        buf[1] = 0x04;							//setting bit 2 in register 0x10
        Trf7970WriteSingle(&buf[0], 2);
    
        buf[0] = 0x8F;							//Reset FIFO
        buf[1] = 0x91;							//Send with CRC
        buf[2] = 0x3D;							//Write Continuous
        buf[3] = 0x00;							//upper and middle nibbles of # of bytes going to FIFO
        buf[4] = 0x60;							//lower nibble # and broken # of bytes going to FIFO (in this case 2 complete bytes are going to be transmitted)
        buf[5] = 0xA2;							//Write Command
        buf[6] = ui8StartBlock;					//Block # (called Bno) to write
        buf[7] = *uid;
        buf[8] = *(uid + 1);
        buf[9] = *(uid + 2);
        buf[10] = *(uid + 3);
    
        rxtx_state = 1;
    
        Trf7970RawWrite(&buf[0], 11);
    
        IRQ_CLR;								// PORT2 interrupt flag clear
        IRQ_ON;
    
        //ISO14443IRQWaitTimeout(5,50);
    
        i_reg = 0x01;
        irq_flag = 0x00;
        START_COUNTER;										//	Starting Timeout
    
        while(irq_flag == 0x00)
        {
        }													// wait for end of TX interrupt
        RESET_COUNTER;
    
        McuCounterSet();									// TimerA set
        COUNT_VALUE = COUNT_1ms * 20;
        START_COUNTER;										// start timer up mode
    
        irq_flag = 0x00;
    
        while(irq_flag == 0x00)
        {
        }													// wait for interrupt
        RESET_COUNTER;
    
        while(i_reg == 0x01)								// wait for RX complete
        {
            k++;
    
            if(k == 0xFFF0)
            {
                i_reg = 0x00;
                rx_error_flag = 0x00;
            }
        }
    
        /*	Tx_Uart1_String("In Write Block : \n");
    	if( i_reg == 0xFF)
    	{		// if received block data in buffer
    		if(stand_alone_flag == 1)
    		{
    			//found = 1;
    #ifdef ENABLE_HOST
    			for(j = 0; j < 4; j++)
    				//				for(j = 0; j < 35; j++)
    			{
    				Tx_Uart1_String("NFC Type2 Block ");
    				//UartPutByte(ui8StartBlock++);
    				Tx_Uart1_String(":  [");
    				for(i = 1+(j*4); i < 5+(j*4); i++)
    				{
    					Tx_Uart1_Char(buf[i]);
    					//charToHex(buf[i]);		// send block data to host
    				}
    				Tx_Uart1_Char(']');
    				Tx_Uart1_Char('\n');
    			}
    
    #endif
    		}
    	}
         */
    }
    
    Hello Winter Yu,

    Its happen in TRF7970ISR code then while collision error occurred then only this coll_poss will get changed.

    Can you tell me something about Collision,

    According to me collision means if 2 or more tags comes in front of Antenna then collision will occur.

    But you know in coding its taken care of Anticollision . So Still I have problem.

    I am going to share my file where I have problem. Please Go through it .

    In ISO144430a code you will get where I was stuck and in trf7970 you will get where that coll_poss value get changed.

    Thanks

    Anil D.

**Attention** This is a public forum