Hello,
I'm trying to read (and later write) ISO 14443/A tags (without encryption, encryption will be done in application level). For this application, I use a CRLC632 and an ATMega 1284 CPU. I suppose SPI interconnection between CPU and CLRC is correct as I can send a frame from CPU to CLRC, compute CRC and read expected value from CLRC.
// Adresses des registres
#define CmdPage 0x00
#define CmdCommand 0x01
#define CmdFIFOData 0x02
#define CmdPrimaryStatus 0x03
#define CmdFIFOLength 0x04
#define CmdSecondayStatus 0x05
#define CmdInterruptEn 0x06
#define CmdInterruptRq 0x07
#define CtrlPage 0x08
#define CtrlControl 0x09
#define CtrlErrorFlag 0x0A
#define CtrlCollPos 0x0B
#define CtrlTimerValue 0x0C
#define CtrlCRCResultLSB 0x0D
#define CtrlCRCResultMSB 0x0E
#define CtrlBitFraming 0x0F
#define TxPage 0x10
#define TxControl 0x11
#define TxCwConductance 0x12
#define TxModConductance 0x13
#define TxCoderControl 0x14
#define TxModWidth 0x15
#define TxModWidthSOF 0x16
#define TxTypeBFraming 0x17
#define RxPage 0x18
#define RxControl1 0x19
#define RxDecoderControl 0x1A
#define RxBitPhase 0x1B
#define RxThreshold 0x1C
#define RxBPSKDemControl 0x1D
#define RxControl2 0x1E
#define RxClockQControl 0x1F
#define RfPage 0x20
#define RfRxWait 0x21
#define RfChannelRedundancy 0x22
#define RfCRCPresetLSB 0x23
#define RfCRCPresetMSB 0x24
#define RfTimeSlotPeriod 0x25
#define RfMFOUTSelect 0x26
#define RfPreSet27 0x27
#define FifoPage 0x28
#define FifoLevel 0x29
#define FifoTimerClock 0x2A
#define FifoTimerControl 0x2B
#define FifoTimerReload 0x2C
#define FifoIRQPinConfig 0x2D
#define FifoPreSet2E 0x2E
#define FifoPreSet2F 0x2F
// Commandes
#define C_StartUp 0x3F
#define C_Idle 0x00
#define C_Transmit 0x1A
#define C_Receive 0x16
#define C_Transceive 0x1E
#define C_WriteE2 0x01
#define C_ReadE2 0x03
#define C_LoadKeyE2 0x0B
#define C_LoadKey 0x19
#define C_Authent1 0x0C
#define C_Authent2 0x14
#define C_LoadConfig 0x07
#define C_CalcCRC 0x12
void
clrc632_init()
{
clrc632_write_register(CmdCommand, C_StartUp);
// Le registre Command est lu jusqu'à ce que les 6 bits valent 0x00.
while(clrc632_read_register(CmdCommand) & 0x3F);
// Page 2
// 0100 1011 (modulation et réglagex de TX1 et TX2)
// TX2inv = 1
// TX2Cw = 0
// TX2RFEn = 1
// TX1RFEn = 1
clrc632_write_register(TxControl, 0x4B);
// Résistance d'antenne minimale
clrc632_write_register(TxCwConductance, 0x3F);
// Résistance de sortie du module
clrc632_write_register(TxModConductance, 0x02);
// 0001 1001 Mifare ISO/ISC 14443A
clrc632_write_register(TxCoderControl, 0x19);
// Modulation
clrc632_write_register(TxModWidth, 0x3F);
clrc632_write_register(TxModWidthSOF, 0x3F);
// TxTypeBFraming ?
// Page 3
// 0111 0011 (gain)
clrc632_write_register(RxControl1, 0x73);
// 0010 1000
clrc632_write_register(RxDecoderControl, 0x28);
// RxBitPhase ?
// RxThreshold ?
// RxBPSKDemControl ?
// 0100 0001
clrc632_write_register(RxControl2, 0x41);
clrc632_write_register(RxClockQControl, 0x00);
// Page 4
clrc632_write_register(RfRxWait, 0x06);
// 0000 0011 (parité)
clrc632_write_register(RfChannelRedundancy, 0x03);
// RfCRCPresetLSB ?
// RfCRCPresetMSB ?
clrc632_write_register(RfTimeSlotPeriod, 0x00);
// 0000 0000
clrc632_write_register(RfMFOUTSelect, 0x00);
// Page 5
clrc632_write_register(FifoLevel, 0x08);
clrc632_write_register(FifoTimerClock, 0x07);
clrc632_write_register(FifoTimerControl, 0x06);
clrc632_write_register(FifoTimerReload, 0x0A);
// Flush FIFO
clrc632_write_register(CtrlControl, 0x01);
// Idle
clrc632_write_register(CmdCommand, C_Idle);
return;
}
I don't send here sources of clrc632_read*() and other clrc632_write*() functions.
To access to ISO 14443/A tag, I have written:
typedef struct
{
union
{
struct
{
uint8_t cmd;
uint8_t addr;
};
uint8_t data[2];
};
uint8_t crc1;
uint8_t crc2;
} mifare_commande;
typedef union
{
struct
{
uint16_t bloc;
uint16_t crc;
};
uint8_t data[4];
} mifare_donnees;
uint8_t
iso14443a_read(uint8_t adresse, uint16_t *bloc)
{
mifare_commande commande;
mifare_donnees donnees;
uint8_t i;
uint8_t longueur;
while(clrc632_read_register(CmdCommand) & 0x3F);
commande.cmd = 0x30;
commande.addr = adresse;
// CRC
clrc632_write_register(RfCRCPresetMSB, 0x63);
clrc632_write_register(RfCRCPresetLSB, 0x63);
clrc632_write(CmdFIFOData, commande.data, 2);
clrc632_write_register(CmdCommand, C_CalcCRC);
while((clrc632_read_register(CmdSecondayStatus) & 0x20) == 0);
clrc632_write_register(CmdCommand, C_Idle);
commande.crc1 = clrc632_read_register(CtrlCRCResultMSB);
commande.crc2 = clrc632_read_register(CtrlCRCResultLSB);
clrc632_write(CmdFIFOData, (uint8_t *) &commande, sizeof(commande));
clrc632_write_register(CmdCommand, C_Transceive);
_delay_ms(10);
longueur = clrc632_read_register(CmdFIFOLength);
for(i = 0; i < longueur; i++)
{
donnees.data[i] = CmdFIFOData;
}
clrc632_read(donnees.data, longueur);
if (longueur == sizeof(donnees))
{
(*bloc) = donnees.bloc;
}
else
{
(*bloc) = 0x0000;
clrc632_write_register(CmdCommand, C_Idle);
return(longueur);
}
I'm not sure I have understand how to read for example block 0. I have created a frame 0x30 0x00. CLRC632 computes CRC (0xA8 0x02) and I try to send 0x30 0x00 0xA8 0x02. Tag is not detected and fifo remains empty. I suppose I have misunderstood something...
Second question: chip continuously emits carrier. I suppose I have to change configuration to only emit carrier when chip tries to detect a tag but datasheet is not very clear.
Help will be welcome,
JB