From 4085ae3ddfbbf10c8ccbd3dccd43452c40a1fe40 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Fri, 13 Mar 2015 12:24:52 +0200 Subject: Add bootloader, nfclib and sensorlib --- nfclib/iso14443b.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 nfclib/iso14443b.c (limited to 'nfclib/iso14443b.c') diff --git a/nfclib/iso14443b.c b/nfclib/iso14443b.c new file mode 100644 index 0000000..a7cd7fb --- /dev/null +++ b/nfclib/iso14443b.c @@ -0,0 +1,339 @@ +//***************************************************************************** +// +// iso14443B.c - ISO 14443B implementation. +// +// Copyright (c) 2010-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +//***************************************************************************** + +#include +#include +#include +#include "inc/hw_types.h" +#include "driverlib/sysctl.h" +#include "trf79x0.h" +#include "iso14443b.h" + +//***************************************************************************** +// +// Set up registers for ISO 14443 B 106Kbit/s operation. This function must +// be called after initializing the TRF79x0 (for example with TRF79x0Init() +// or TRF79x0Command() with argument \b TRF79X0_SOFT_INIT_CMD) and before +// calling any of the other ISO14443B functions. +// +//***************************************************************************** +void +ISO14443BSetupRegisters(void) +{ + // + // Set the ISO format to ISO1443B 106Kbps. + // + TRF79x0WriteRegister(TRF79X0_ISO_CONTROL_REG, + TRF79X0_ISO_CONTROL_14443B_106K); + + // + // Set the TX pulse to 106ns (0x20 * 73.7ns). + // + TRF79x0WriteRegister(TRF79X0_TX_PULSE_LENGTH_CTRL_REG, 0x20); + + // + // Set the RX No response wait time to 529us (0xe * 37.76us). + // + TRF79x0WriteRegister(TRF79X0_RX_NO_RESPONSE_WAIT_REG, 0x0e); + + // + // Set the RX wait time to 66us (7 * 9.44us). + // + TRF79x0WriteRegister(TRF79X0_RX_WAIT_TIME_REG, 0x07); + + // + // Set the SYSCLK to 6.78MHz and the Modulation 10% ASK. + // + TRF79x0WriteRegister(TRF79X0_MODULATOR_CONTROL_REG, TRF79X0_MOD_CTRL_SYS_CLK_6_78MHZ); + + // + // Configure the Special Settings Register. + // + TRF79x0WriteRegister(TRF79X0_RX_SPECIAL_SETTINGS_REG, + (TRF79x0ReadRegister(TRF79X0_RX_SPECIAL_SETTINGS_REG) & 0x0f) | + TRF79X0_RX_SP_SET_M848); + + // + // Configure the Test Settings Register. + // + TRF79x0WriteRegister(TRF79X0_TEST_SETTING1_REG, 0x20); + + + // + // Set the regulator voltage to be automatic. + // + TRF79x0WriteRegister(TRF79X0_REGULATOR_CONTROL_REG, + TRF79X0_REGULATOR_CTRL_AUTO_REG); +} + +//***************************************************************************** +// +// Power on the field and wait for a time that is long enough to guarantee +// that all cards in the field will be initialized. +// +//***************************************************************************** +void +ISO14443BPowerOn(void) +{ + unsigned char ucReg; + + // + // Enable RF field and receiver. + // + ucReg = TRF79x0ReadRegister(TRF79X0_CHIP_STATUS_CTRL_REG); + TRF79x0WriteRegister(TRF79X0_CHIP_STATUS_CTRL_REG, + ucReg | TRF79X0_STATUS_CTRL_RF_ON); + + // + // Wait 5ms (as per ISO 14443-3 clause 5). + // + SysCtlDelay(((SysCtlClockGet() / 3) * 5) / 1000); +} + +//***************************************************************************** +// +// Power off the field and wait for some time. +// +//***************************************************************************** +void +ISO14443BPowerOff(void) +{ + unsigned char ucReg; + + // + // Disable RF field and receiver. + // + ucReg = TRF79x0ReadRegister(TRF79X0_CHIP_STATUS_CTRL_REG); + + TRF79x0WriteRegister(TRF79X0_CHIP_STATUS_CTRL_REG, + ucReg & ~TRF79X0_STATUS_CTRL_RF_ON); + + // + // Wait 5ms. + // + SysCtlDelay(((SysCtlClockGet() / 3) * 5) / 1000); +} + +int +ISO14443BHalt(unsigned char *pucPUPI) +{ + unsigned char ucResponse; + unsigned int uiRxSize; + + // + // HLTA command. + // + unsigned char pucHLTA[5]; + + pucHLTA[0] = 0x50; + pucHLTA[1] = pucPUPI[0]; + pucHLTA[2] = pucPUPI[1]; + pucHLTA[3] = pucPUPI[2]; + pucHLTA[4] = pucPUPI[3]; + + TRF79x0Transceive(pucHLTA, sizeof(pucHLTA), 0, &ucResponse, &uiRxSize, NULL, + TRF79X0_TRANSCEIVE_CRC); + + // + // Valid answer to HLTB received. + if((uiRxSize == 1) && (ucResponse == 0)) + return(uiRxSize); + else + return(0); +} + +//***************************************************************************** +// +// Transceive ISO 14443-B SlotMARKER command. +// +// \param ucSlot is the slot number for the following operations, must between 1~15 +// +//***************************************************************************** +void +ISO14443BSlotMARKER(unsigned char ucSlot) +{ + unsigned char ucAPn; + + ucAPn = (ucSlot << 4) | 0x05; + + TRF79x0Transceive(&ucAPn, 1, 0, 0, 0, 0, TRF79X0_TRANSCEIVE_CRC); +// TRF79x0Send(&ucAPn, 1, 0, TRF79X0_TRANSCEIVE_TX_CRC); +} + +//***************************************************************************** +// +// Transceive ISO 14443-B REQB type command. +// +// \param ucCmd is the command, either \b ISO14443B_REQB or \b ISO14443B_WUPB +// \param ucAFI is the application family identifier +// \param ucN is the number of the time slot that was used in anticollision process, +// must between 0 ~ 4 +// \param piATQB is a pointer to an integer to store the received ATQB and +// will be set to -1 if a collision occurred. +// +// \return true if at least one card responded and false +// otherwise. +// +// \note User code usually does not need to call this function since it is +// implicitly called in ISO14443BSelect(), ISO14443bSelectFirst() or +// ISO14443BSelectNext(). +// +//***************************************************************************** +int +ISO14443BREQB(unsigned char ucCmd, unsigned char ucAFI, unsigned char ucN, + unsigned char *pucATQB, unsigned int *puiATQBSize) +{ + unsigned char pucREQB[3]; + unsigned char pucResponse[12]; + unsigned int uiRxSize; + int i, slotTotal, slot; + + switch(ucN) + { + case 0: slotTotal = 1; break; + case 1: slotTotal = 2; break; + case 2: slotTotal = 4; break; + case 3: slotTotal = 8; break; + case 4: slotTotal = 16; break; + default: slotTotal = 1; break; + } + + uiRxSize = sizeof(pucResponse); + pucResponse[0] = 0; + + // + // Transmit WUPB/REQB, receive ATQB. + // + pucREQB[0] = 0x05; + pucREQB[1] = ucAFI; + pucREQB[2] = ucCmd | ucN; + + // + // the first byte of ATQB is 0x50 + // + TRF79x0Transceive(pucREQB, sizeof(pucREQB), 0, pucResponse, &uiRxSize, 0, + TRF79X0_TRANSCEIVE_CRC); + + // + // check if needing to scan slot + // + slot = 1; + while((pucResponse[0] != 0x50) && (slot < slotTotal)) + { + uiRxSize = 12; + pucResponse[0] = 0; + + TRF79x0IRQClearCauses(TRF79X0_WAIT_RXEND); + // + // the order of the two function must not reversed, because the TRF79x0ReceiveAgain() called + // TRF79x0Command(TRF79X0_RESET_FIFO_CMD); to reset receive FIFO + // the most important action TRF79x0ReceiveAgain() done is to set g_sRXState.uiMaxLength as uiRxSize + // in order to enable the TRF7970A interrupt to continue receive data + // + ISO14443BSlotMARKER(slot++); + TRF79x0ReceiveAgain(pucResponse, &uiRxSize); + }; + + // + // Valid ATQB received. Was transmitted LSByte first. + // + if(pucResponse[0] == 0x50) + { + if(pucATQB != NULL) + { + for(i = 0; i < uiRxSize; i++) + pucATQB[i] = pucResponse[i]; + } + *puiATQBSize = uiRxSize; + + // + // Return true + // + return(1); + } + else + { + // + // No response at all + // + return(0); + } +} + +//***************************************************************************** +// +// Transceive ISO 14443-3 ATTRIB command. +// EOF_SOF indicate the PCD capability to support suppression of the EOF and/or SOF +// from PICC to PCD, which may reduce communication overhead. +// The suppression of EOF and/or SOF is optional for the PICC. +// SOF/EOF suppression applies only for communications at fc / 128 (~ 106 kbit/s). +// For bit rates higher than fc / 128 (~ 106 kbit/s) the PICC shall always provide SOF and EOF +// EOF_SOF set 0 indicate SOF&EOF required. +// +// ucTR1 & ucTR0 must between 0~2 +// +//***************************************************************************** +int +ISO14443BATTRIB(unsigned char *pucPUPI, unsigned char ucTR0, unsigned char ucTR1, unsigned char ucEOF_SOF, + unsigned char ucMaxFrameSize, unsigned char ucBitRateD2C, unsigned char ucBitRateC2D, + unsigned char ucProtocolType, unsigned char ucCID, unsigned char *A2ATTRIB) +{ + unsigned char pucResponse[3]; + unsigned int uiRxSize; + unsigned char pucATTRIB[9]; + + uiRxSize = sizeof(pucResponse); + + // + // ATTRIB command. + // + pucATTRIB[0] = 0x1D; + pucATTRIB[1] = pucPUPI[0]; + pucATTRIB[2] = pucPUPI[1]; + pucATTRIB[3] = pucPUPI[2]; + pucATTRIB[4] = pucPUPI[3]; + pucATTRIB[5] = (ucTR0 << 6) | (ucTR1 << 4) | (ucEOF_SOF << 3) | (ucEOF_SOF << 2); + pucATTRIB[6] = (ucBitRateC2D << 6) | (ucBitRateD2C << 4) | ucMaxFrameSize; + pucATTRIB[7] = ucProtocolType & 0x0F; + pucATTRIB[8] = ucCID & 0x0F; + + // + // Transmit ATTRIB without higher layer INF, receive answer to ATTRIB command without higher layer response + // + TRF79x0Transceive(pucATTRIB, sizeof(pucATTRIB), 0, pucResponse, &uiRxSize, NULL, + TRF79X0_TRANSCEIVE_CRC); + + if(uiRxSize == 1 ) + { + // + // Valid answer to ATTRIB command received, return it as an char, uiRxSize NOT including two CRC bytes + // + if(A2ATTRIB != NULL) + *A2ATTRIB = pucResponse[0]; + + return(uiRxSize); + } + else + { + return(0); + } +} -- cgit v1.3.1