CLRC632 and ISO 14443/A tag

cancel
Showing results for 
Search instead for 
Did you mean: 

CLRC632 and ISO 14443/A tag

61 Views
jbertrand
Contributor I

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

0 Kudos
0 Replies