Some bugs fixed for the use with none 13.56 MHz crystals
This commit is contained in:
parent
e384b912dc
commit
2b8fb8e0f7
|
@ -1,396 +1,401 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
Written and Copyright (C) by Nicolas Kruse
|
Written and Copyright (C) by Nicolas Kruse
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include "nfcemulator.h"
|
#include "nfcemulator.h"
|
||||||
|
|
||||||
static uint8_t RX_MASK[18] = {0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 0, 0};
|
static uint8_t RX_MASK[18] = {0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 0, 0};
|
||||||
static uint8_t TX_MASK[8] = {1, 2, 4, 8, 16, 32, 64, 128};
|
static uint8_t TX_MASK[8] = {1, 2, 4, 8, 16, 32, 64, 128};
|
||||||
static uint16_t FDT_DELAY[2] = {FDT_DELAY_BIT0, FDT_DELAY_BIT1};
|
static uint16_t FDT_DELAY[2] = {FDT_DELAY_BIT0, FDT_DELAY_BIT1};
|
||||||
|
|
||||||
static uint8_t REQA[1] = {0x26};
|
static uint8_t REQA[1] = {0x26};
|
||||||
static uint8_t WUPA[1] = {0x52};
|
static uint8_t WUPA[1] = {0x52};
|
||||||
static uint8_t HLTA[4] = {0x50, 0x00, 0x57, 0}; //'50' '00' CRC_A
|
static uint8_t HLTA[4] = {0x50, 0x00, 0x57, 0}; //'50' '00' CRC_A
|
||||||
static uint8_t ATQA[2] = {0x44, 0x00}; //Anticollision with udi size = double
|
static uint8_t ATQA[2] = {0x44, 0x00}; //Anticollision with udi size = double
|
||||||
static uint8_t SEL_CL1[2] = {0x93, 0x20};
|
static uint8_t SEL_CL1[2] = {0x93, 0x20};
|
||||||
static uint8_t SEL_CL2[2] = {0x95, 0x20};
|
static uint8_t SEL_CL2[2] = {0x95, 0x20};
|
||||||
static uint8_t CT_UID1[5] = {0x88, 0x04, 0xE3, 0xEF, 0}; //uid0 uid1 uid2 uid3 BCC
|
static uint8_t CT_UID1[5] = {0x88, 0x04, 0xE3, 0xEF, 0}; //uid0 uid1 uid2 uid3 BCC
|
||||||
static uint8_t UID2[5] = {0xA2, 0xEF, 0x20, 0x80, 0}; //uid3 uid4 uid5 uid6 BCC
|
static uint8_t UID2[5] = {0xA2, 0xEF, 0x20, 0x80, 0}; //uid3 uid4 uid5 uid6 BCC
|
||||||
static uint8_t SAK_NC[3] = {0x04, 0xDA, 0x17}; //Select acknowledge uid not complete
|
static uint8_t SAK_NC[3] = {0x04, 0xDA, 0x17}; //Select acknowledge uid not complete
|
||||||
static uint8_t SAK_C[3] = {0x00, 0xFE, 0x51}; //Select acknowledge uid complete, Type 2 (PICC not compliant to ISO/IEC 14443-4)
|
static uint8_t SAK_C[3] = {0x00, 0xFE, 0x51}; //Select acknowledge uid complete, Type 2 (PICC not compliant to ISO/IEC 14443-4)
|
||||||
static uint8_t READ[1] = {0x30};
|
static uint8_t READ[1] = {0x30};
|
||||||
static uint8_t WRITE[1] = {0xA2};
|
static uint8_t WRITE[1] = {0xA2};
|
||||||
|
|
||||||
uint8_t *sto; //Pointer to tag content
|
uint8_t *sto; //Pointer to tag content
|
||||||
uint16_t stoSize; //Number of avalible bytes on the tag
|
uint16_t stoSize; //Number of avalible bytes on the tag
|
||||||
|
|
||||||
uint8_t buffer[64];
|
uint8_t buffer[64];
|
||||||
uint8_t rCount = 0;
|
uint8_t rCount = 0;
|
||||||
|
|
||||||
void setupNfcEmulator(uint8_t *storage, uint16_t storageSize)
|
void setupNfcEmulator(uint8_t *storage, uint16_t storageSize)
|
||||||
{
|
{
|
||||||
//clock divider for 8 bit timer0: clk/1 -> 13.5225 MHz
|
//clock divider for 8 bit timer0: clk/1 -> 13.5225 MHz
|
||||||
TCCR0B |= (1<<CS00);
|
TCCR0B |= (1<<CS00);
|
||||||
|
|
||||||
//8 bit timer0: Toggle OC0A on Compare Match and CTC-Mode
|
//8 bit timer0: Toggle OC0A on Compare Match and CTC-Mode
|
||||||
//for 847.5 kHz subcarrier
|
//for 847.5 kHz subcarrier
|
||||||
TCCR0A |= (1<<COM0A0) | (1<<WGM01);
|
TCCR0A |= (1<<COM0A0) | (1<<WGM01);
|
||||||
|
|
||||||
//set up 847.5 kHz subcarrier for sending (8 bit timer0)
|
//set up 847.5 kHz subcarrier for sending (8 bit timer0)
|
||||||
OCR0A = SUBC_OVF;
|
OCR0A = SUBC_OVF;
|
||||||
|
|
||||||
//CTC-Mode and no clock divider for 16 bit timer1: clk/1
|
//CTC-Mode and no clock divider for 16 bit timer1: clk/1
|
||||||
TCCR1B = (1<<WGM12) | (1<<CS10);
|
TCCR1B = (1<<WGM12) | (1<<CS10);
|
||||||
|
|
||||||
//Setup Analog Comparator, Enable (ACD), Set Analog Comparator
|
//Setup Analog Comparator, Enable (ACD), Set Analog Comparator
|
||||||
//Interrupt Flag on Rising Output Edge (ACIS0, ACIS1)
|
//Interrupt Flag on Rising Output Edge (ACIS0, ACIS1)
|
||||||
ACSR = (0<<ACD) | (1<<ACIS0) | (1<<ACIS1);
|
ACSR = (0<<ACD) | (1<<ACIS0) | (1<<ACIS1);
|
||||||
|
|
||||||
addCrc16(HLTA);
|
addCrc16(HLTA);
|
||||||
addBcc(CT_UID1);
|
addBcc(CT_UID1);
|
||||||
addBcc(UID2);
|
addBcc(UID2);
|
||||||
|
|
||||||
stoSize = storageSize;
|
stoSize = storageSize;
|
||||||
sto = storage;
|
sto = storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addCrc16(uint8_t *Data, uint8_t Length)
|
void addCrc16(uint8_t *Data, uint8_t Length)
|
||||||
{
|
{
|
||||||
uint8_t ch;
|
uint8_t ch;
|
||||||
uint16_t wCrc = 0x6363; // ITU-V.41
|
uint16_t wCrc = 0x6363; // ITU-V.41
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ch = *Data++;
|
ch = *Data++;
|
||||||
|
|
||||||
ch = (ch^(uint8_t)((wCrc) & 0x00FF));
|
ch = (ch^(uint8_t)((wCrc) & 0x00FF));
|
||||||
ch = (ch^(ch<<4));
|
ch = (ch^(ch<<4));
|
||||||
wCrc = (wCrc >> 8)^((uint16_t)ch << 8)^((uint16_t)ch<<3)^((uint16_t)ch>>4);
|
wCrc = (wCrc >> 8)^((uint16_t)ch << 8)^((uint16_t)ch<<3)^((uint16_t)ch>>4);
|
||||||
} while (--Length);
|
} while (--Length);
|
||||||
|
|
||||||
*Data = (uint8_t) (wCrc & 0xFF);
|
*Data = (uint8_t) (wCrc & 0xFF);
|
||||||
Data++;
|
Data++;
|
||||||
*Data = (uint8_t) ((wCrc >> 8) & 0xFF);
|
*Data = (uint8_t) ((wCrc >> 8) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addBcc(uint8_t *Data) //add exclusive-OR of 4 bytes
|
void addBcc(uint8_t *Data) //add exclusive-OR of 4 bytes
|
||||||
{
|
{
|
||||||
Data[4] = Data[0] ^ Data[1] ^ Data[2] ^ Data[3];
|
Data[4] = Data[0] ^ Data[1] ^ Data[2] ^ Data[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitForBitend()
|
void waitForBitend()
|
||||||
{
|
{
|
||||||
while(!(TIFR1 & (1<<OCF1A))); //Wait till end of bit-time
|
while(!(TIFR1 & (1<<OCF1A))); //Wait till end of bit-time
|
||||||
TIFR1 |= (1<<OCF1A);
|
TIFR1 |= (1<<OCF1A);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (F_CPU == RFID_FREQU)
|
#if (F_CPU == RFID_FREQU)
|
||||||
void waitForOneBitTime()
|
void waitForOneBitTime()
|
||||||
{
|
{
|
||||||
waitForBitend();
|
waitForBitend();
|
||||||
}
|
}
|
||||||
#elif (F_CPU == 22000000UL)
|
#elif (F_CPU == 22000000UL)
|
||||||
//Skip every 17 bit times 1 cycle
|
//Skip every 17 bit times 1 cycle
|
||||||
void waitForOneBitTime()
|
void waitForOneBitTime()
|
||||||
{
|
{
|
||||||
if (rCount < 17)
|
if (rCount < 7)
|
||||||
{
|
{
|
||||||
OCR1AL = CLC_PBIT / 2 - 1;
|
OCR1AL = CLC_PBIT / 2 - 1;
|
||||||
rCount++;
|
rCount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OCR1AL = CLC_PBIT / 2 - 2;
|
OCR1AL = CLC_PBIT / 2 - 2;
|
||||||
rCount = 0;
|
rCount = 0;
|
||||||
}
|
}
|
||||||
waitForBitend();
|
waitForBitend();
|
||||||
}
|
}
|
||||||
#elif (F_CPU == 13592500UL)
|
#elif (F_CPU == 13592500UL)
|
||||||
//Add every 6 bit times 1 cycle
|
//Add every 6 bit times 1 cycle
|
||||||
void waitForOneBitTime()
|
void waitForOneBitTime()
|
||||||
{
|
{
|
||||||
if (rCount < 6)
|
if (rCount < 6)
|
||||||
{
|
{
|
||||||
OCR1AL = CLC_PBIT / 2 - 1;
|
OCR1AL = CLC_PBIT / 2 - 1;
|
||||||
rCount++;
|
rCount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OCR1AL = CLC_PBIT / 2;
|
OCR1AL = CLC_PBIT / 2;
|
||||||
rCount = 0;
|
rCount = 0;
|
||||||
}
|
}
|
||||||
waitForBitend();
|
waitForBitend();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#error "Not supported frequency, please add support if possible"
|
#error "Not supported frequency, please add support if possible"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void txManchester(uint8_t *data, uint8_t length)
|
void txManchester(uint8_t *data, uint8_t length)
|
||||||
{
|
{
|
||||||
uint8_t txBytePos = 0;
|
uint8_t txBytePos = 0;
|
||||||
uint8_t txbitPos = 0;
|
uint8_t txbitPos = 0;
|
||||||
uint8_t parity = 0;
|
uint8_t parity = 0;
|
||||||
|
|
||||||
TIFR1 |= (1<<OCF1A);
|
TIFR1 |= (1<<OCF1A);
|
||||||
|
|
||||||
//Send SOC
|
//Send SOC
|
||||||
waitForBitend();
|
waitForBitend();
|
||||||
DDRB |= (1<<2);
|
DDRB |= (1<<2);
|
||||||
OCR1A = CLC_PBIT / 2 - 1; //Set Hi- and Low-Bit
|
OCR1A = CLC_PBIT / 2 - 1; //Set Hi- and Low-Bit
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB &= ~(1<<2);
|
DDRB &= ~(1<<2);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (TX_MASK[txbitPos] & data[txBytePos])
|
if (TX_MASK[txbitPos] & data[txBytePos])
|
||||||
{
|
{
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB |= (1<<2);
|
DDRB |= (1<<2);
|
||||||
parity ^= 1;
|
parity ^= 1;
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB &= ~(1<<2);
|
DDRB &= ~(1<<2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB &= ~(1<<2);
|
DDRB &= ~(1<<2);
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB |= (1<<2);
|
DDRB |= (1<<2);
|
||||||
}
|
}
|
||||||
|
|
||||||
txbitPos++;
|
txbitPos++;
|
||||||
|
|
||||||
if (txbitPos > 7)
|
if (txbitPos > 7)
|
||||||
{
|
{
|
||||||
if (parity)
|
if (parity)
|
||||||
{
|
{
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB &= ~(1<<2);
|
DDRB &= ~(1<<2);
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB |= (1<<2);
|
DDRB |= (1<<2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB |= (1<<2);
|
DDRB |= (1<<2);
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB &= ~(1<<2);
|
DDRB &= ~(1<<2);
|
||||||
}
|
}
|
||||||
|
|
||||||
txBytePos++;
|
txBytePos++;
|
||||||
txbitPos=0;
|
txbitPos=0;
|
||||||
parity = 0;
|
parity = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(txBytePos < length);
|
while(txBytePos < length);
|
||||||
|
|
||||||
//Send EOC
|
//Send EOC
|
||||||
waitForOneBitTime();
|
waitForOneBitTime();
|
||||||
DDRB &= ~(1<<2);
|
DDRB &= ~(1<<2);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void resetRxFlags()
|
inline void resetRxFlags()
|
||||||
{
|
{
|
||||||
TCNT1 = 0;
|
TCNT1 = 0;
|
||||||
TIFR1 |= (1<<OCF1A); //Clear Timer Overflow Flag
|
TIFR1 |= (1<<OCF1A); //Clear Timer Overflow Flag
|
||||||
ACSR |= (1<<ACI); //Clear Analog Comparator Interrupt Flag
|
ACSR |= (1<<ACI); //Clear Analog Comparator Interrupt Flag
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rxMiller()
|
uint8_t rxMiller()
|
||||||
{
|
{
|
||||||
uint8_t t;
|
#if (F_CPU > 16000000)
|
||||||
uint16_t cDown = 0xFFF;
|
uint16_t t; //For hi cpu clock a 8 bit variable will overflow (CLCM > 0xFF)
|
||||||
uint8_t bytePos = 0;
|
#else
|
||||||
uint8_t hbitPos = 0;
|
uint8_t t; //For low cpu clock computing time is to low for 16bit a variable
|
||||||
|
#endif
|
||||||
OCR1A = CLCL-1;
|
|
||||||
buffer[0] = 0;
|
uint16_t cDown = 0x0FFF;
|
||||||
|
uint8_t bytePos = 0;
|
||||||
//Wait for transmission end if there is data arriving
|
uint8_t hbitPos = 0;
|
||||||
do
|
|
||||||
{
|
OCR1A = CLCL-1;
|
||||||
if (ACSR & (1<<ACI)) resetRxFlags();
|
buffer[0] = 0;
|
||||||
}
|
|
||||||
while(~TIFR1 & (1<<OCF1A));
|
//Wait for transmission end if there is data arriving
|
||||||
|
do
|
||||||
//Wait for transmission end if there is data arriving
|
{
|
||||||
do
|
if (ACSR & (1<<ACI)) resetRxFlags();
|
||||||
{
|
}
|
||||||
if (TIFR1 & (1<<OCF1A))
|
while(~TIFR1 & (1<<OCF1A));
|
||||||
{
|
|
||||||
TCNT1 = 0;
|
//Wait for transmission end if there is data arriving
|
||||||
TIFR1 |= (1<<OCF1A);
|
do
|
||||||
cDown--;
|
{
|
||||||
if (!cDown) break;
|
if (TIFR1 & (1<<OCF1A))
|
||||||
}
|
{
|
||||||
}
|
TCNT1 = 0;
|
||||||
while(~ACSR & (1<<ACI));
|
TIFR1 |= (1<<OCF1A);
|
||||||
|
cDown--;
|
||||||
if (cDown)
|
if (!cDown) break;
|
||||||
{
|
}
|
||||||
resetRxFlags();
|
}
|
||||||
do
|
while(~ACSR & (1<<ACI));
|
||||||
{
|
|
||||||
if ((ACSR & (1<<ACI)) && (TCNT1 > CMIN))
|
if (cDown)
|
||||||
{
|
{
|
||||||
t = TCNT1;
|
resetRxFlags();
|
||||||
resetRxFlags();
|
do
|
||||||
|
{
|
||||||
hbitPos += (t > CLCS) + (t > CLCM);
|
if ((ACSR & (1<<ACI)) && (TCNT1 > 1))
|
||||||
|
{
|
||||||
if(hbitPos > 17)
|
t = TCNT1;
|
||||||
{
|
resetRxFlags();
|
||||||
bytePos++;
|
|
||||||
hbitPos -= 18;
|
hbitPos += (t > CLCS) + (t > CLCM);
|
||||||
buffer[bytePos] = 0;
|
|
||||||
}
|
if(hbitPos > 17)
|
||||||
|
{
|
||||||
buffer[bytePos] |= RX_MASK[hbitPos];
|
bytePos++;
|
||||||
|
hbitPos -= 18;
|
||||||
hbitPos += 2;
|
buffer[bytePos] = 0;
|
||||||
} //34 or 41 (hbitPos > 17) click cycles
|
}
|
||||||
}
|
|
||||||
while(~TIFR1 & (1<<OCF1A));
|
buffer[bytePos] |= RX_MASK[hbitPos];
|
||||||
}
|
|
||||||
|
hbitPos += 2;
|
||||||
OCR1A = FDT_DELAY[hbitPos & 1]; //Set delay for answer
|
} //34 or 41 (hbitPos > 17) click cycles
|
||||||
TIFR1 |= (1<<OCF1A);
|
}
|
||||||
|
while(~TIFR1 & (1<<OCF1A));
|
||||||
if (hbitPos > 7) bytePos++;
|
}
|
||||||
|
|
||||||
return bytePos;
|
OCR1A = FDT_DELAY[hbitPos & 1]; //Set delay for answer
|
||||||
}
|
TIFR1 |= (1<<OCF1A);
|
||||||
|
|
||||||
void sendData(uint8_t block)
|
if (hbitPos > 7) bytePos++;
|
||||||
{
|
|
||||||
uint8_t i = 0;
|
return bytePos;
|
||||||
uint16_t pos = (uint16_t)block * 4;
|
}
|
||||||
|
|
||||||
for(i=0; i < 16; i++)
|
void sendData(uint8_t block)
|
||||||
{
|
{
|
||||||
if (pos >= stoSize)
|
uint8_t i = 0;
|
||||||
{
|
uint16_t pos = (uint16_t)block * 4;
|
||||||
buffer[i] = 0;
|
|
||||||
}
|
for(i=0; i < 16; i++)
|
||||||
else
|
{
|
||||||
{
|
if (pos >= stoSize)
|
||||||
buffer[i] = sto[pos];
|
{
|
||||||
}
|
buffer[i] = 0;
|
||||||
|
}
|
||||||
pos++;
|
else
|
||||||
}
|
{
|
||||||
|
buffer[i] = sto[pos];
|
||||||
addCrc16(buffer, 16);
|
}
|
||||||
txManchester(buffer, 18);
|
|
||||||
}
|
pos++;
|
||||||
|
}
|
||||||
void receiveData(uint8_t block)
|
|
||||||
{
|
addCrc16(buffer, 16);
|
||||||
uint8_t i = 0;
|
txManchester(buffer, 18);
|
||||||
uint16_t pos = (uint16_t)block * 4;
|
}
|
||||||
uint8_t crc1 = buffer[6];
|
|
||||||
uint8_t crc2 = buffer[7];
|
void receiveData(uint8_t block)
|
||||||
|
{
|
||||||
addCrc16(buffer, 6);
|
uint8_t i = 0;
|
||||||
|
uint16_t pos = (uint16_t)block * 4;
|
||||||
if (buffer[6] == crc1 && buffer[7] == crc2)
|
uint8_t crc1 = buffer[6];
|
||||||
{
|
uint8_t crc2 = buffer[7];
|
||||||
for(i=2; i < 6; i++) //byte 2-5 contains Data
|
|
||||||
{
|
addCrc16(buffer, 6);
|
||||||
if (pos < stoSize) sto[pos] = buffer[i];
|
|
||||||
pos++;
|
if (buffer[6] == crc1 && buffer[7] == crc2)
|
||||||
}
|
{
|
||||||
|
for(i=2; i < 6; i++) //byte 2-5 contains Data
|
||||||
buffer[0] = 0x0A; //ACK
|
{
|
||||||
txManchester(buffer, 1);
|
if (pos < stoSize) sto[pos] = buffer[i];
|
||||||
}
|
pos++;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
buffer[0] = 0x01; //NAK for CRC error
|
buffer[0] = 0x0A; //ACK
|
||||||
txManchester(buffer, 1);
|
txManchester(buffer, 1);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
void checkForNfcReader()
|
buffer[0] = 0x01; //NAK for CRC error
|
||||||
{
|
txManchester(buffer, 1);
|
||||||
uint8_t bytes = 1;
|
}
|
||||||
uint8_t state = 0;
|
}
|
||||||
uint8_t cdow = 8;
|
|
||||||
|
void checkForNfcReader()
|
||||||
if (ACSR & (1<<ACI)) //13.56 MHz carrier available?
|
{
|
||||||
{
|
uint8_t bytes = 1;
|
||||||
AIN1_PRNG &= ~(1<<AIN1_PORT); //Deactivate pull up to increase sensitivity
|
uint8_t state = 0;
|
||||||
|
uint8_t cdow = 8;
|
||||||
while(cdow > 0)
|
|
||||||
{
|
if (ACSR & (1<<ACI)) //13.56 MHz carrier available?
|
||||||
bytes = rxMiller();
|
{
|
||||||
|
AIN1_PORT &= ~(1<<AIN1_BIT); //Deactivate pull up to increase sensitivity
|
||||||
if ((state & 7) == S_READY)
|
|
||||||
{
|
while(cdow > 0)
|
||||||
if (buffer[0] == SEL_CL1[0] && buffer[1] == SEL_CL1[1] )
|
{
|
||||||
{
|
bytes = rxMiller();
|
||||||
txManchester(CT_UID1, sizeof(CT_UID1));
|
|
||||||
}
|
if ((state & 7) == S_READY)
|
||||||
else if (buffer[0] == SEL_CL2[0] && buffer[1] == SEL_CL2[1] )
|
{
|
||||||
{
|
if (buffer[0] == SEL_CL1[0] && buffer[1] == SEL_CL1[1] )
|
||||||
txManchester(UID2, sizeof(UID2));
|
{
|
||||||
}
|
txManchester(CT_UID1, sizeof(CT_UID1));
|
||||||
else if (buffer[0] == SEL_CL1[0] && buffer[1] == 0x70 )
|
}
|
||||||
{
|
else if (buffer[0] == SEL_CL2[0] && buffer[1] == SEL_CL2[1] )
|
||||||
txManchester(SAK_NC, sizeof(SAK_NC));
|
{
|
||||||
}
|
txManchester(UID2, sizeof(UID2));
|
||||||
else if (buffer[0] == SEL_CL2[0] && buffer[1] == 0x70 )
|
}
|
||||||
{
|
else if (buffer[0] == SEL_CL1[0] && buffer[1] == 0x70 )
|
||||||
txManchester(SAK_C, sizeof(SAK_C));
|
{
|
||||||
state++; //Set state to ACTIVE
|
txManchester(SAK_NC, sizeof(SAK_NC));
|
||||||
}
|
}
|
||||||
else
|
else if (buffer[0] == SEL_CL2[0] && buffer[1] == 0x70 )
|
||||||
{
|
{
|
||||||
state &= 8; //Set state to IDLE/HALT
|
txManchester(SAK_C, sizeof(SAK_C));
|
||||||
}
|
state++; //Set state to ACTIVE
|
||||||
}
|
}
|
||||||
else if ((state & 7) == S_ACTIVE)
|
else
|
||||||
{
|
{
|
||||||
if (buffer[0] == READ[0])
|
state &= 8; //Set state to IDLE/HALT
|
||||||
{
|
}
|
||||||
sendData(buffer[1]);
|
}
|
||||||
}
|
else if ((state & 7) == S_ACTIVE)
|
||||||
else if (buffer[0] == WRITE[0])
|
{
|
||||||
{
|
if (buffer[0] == READ[0])
|
||||||
receiveData(buffer[1]);
|
{
|
||||||
}
|
sendData(buffer[1]);
|
||||||
else if (buffer[0] == HLTA[0] && buffer[2] == HLTA[2] )
|
}
|
||||||
{
|
else if (buffer[0] == WRITE[0])
|
||||||
state = S_HALT;
|
{
|
||||||
}
|
receiveData(buffer[1]);
|
||||||
else if(bytes)
|
}
|
||||||
{
|
else if (buffer[0] == HLTA[0] && buffer[2] == HLTA[2] )
|
||||||
state &= 8; //Set state to IDLE/HALT
|
{
|
||||||
}
|
state = S_HALT;
|
||||||
}
|
}
|
||||||
else if (bytes == 1 && (buffer[0] == REQA[0] || buffer[0] == WUPA[0])) //state == S_IDLE
|
else if(bytes)
|
||||||
{
|
{
|
||||||
txManchester(ATQA, sizeof(ATQA));
|
state &= 8; //Set state to IDLE/HALT
|
||||||
state = (state & 8) + S_READY; //Set state to READY
|
}
|
||||||
}
|
}
|
||||||
|
else if (bytes == 1 && (buffer[0] == REQA[0] || buffer[0] == WUPA[0])) //state == S_IDLE
|
||||||
cdow -= (bytes == 0);
|
{
|
||||||
}
|
txManchester(ATQA, sizeof(ATQA));
|
||||||
AIN1_PRNG |= (1<<AIN1_PORT); //Activate pull up to prevent noise from toggling the comparator
|
state = (state & 8) + S_READY; //Set state to READY
|
||||||
}
|
}
|
||||||
ACSR |= (1<<ACI); //Clear comparator interrupt flag
|
|
||||||
|
cdow -= (bytes == 0);
|
||||||
|
}
|
||||||
|
AIN1_PORT |= (1<<AIN1_BIT); //Activate pull up to prevent noise from toggling the comparator
|
||||||
|
}
|
||||||
|
ACSR |= (1<<ACI); //Clear comparator interrupt flag
|
||||||
}
|
}
|
Loading…
Reference in New Issue