I have an issue with the Select card using the CLRC663.
I'm communicating with the chip via the SPI interface without using the NXP library. I'm currently able to get the ATQA response from the REQA command. But as soon as I attempt sending the select card for anti-collision I get no response from the card. At least this is what the CLRC663 chip is telling me.
I have tried multiple things and checked all the register setting them to values that I believe should work.
The process that I am currently trying is using the following sequence for setting the registers:
Set_Timer_Control(TIMER_0_SELECTED, CLRC663_TCONTROL_STOPRX | CLRC663_TCONTROL_START_TX_END | CLRC663_TCONTROL_AUTO_RESTART | CLRC663_TCONTROL_CLK_13MHZ); // configure Timer 0. Set timer to 13.56 MHz clock, start at the end of Tx, Auto restart and stop after Rx.
Set_Timer_Control(TIMER_1_SELECTED, CLRC663_TCONTROL_STOPRX | CLRC663_TCONTROL_START_TX_END | CLRC633_TCONTROL_1_CASCADE | CLRC663_TCONTROL_CLK_13MHZ); // configure Timer 1. Set timer to 13.56 MHz clock, start at the end of Timer 0, Auto restart and stop after Rx.
Set_Timer_Control(TIMER_2_SELECTED, CLRC663_TCONTROL_2_LFO_TRIMMING_NO_UNDERFLOW | CLRC663_TCONTROL_CLK_13MHZ); // configure Timer 2. Set timer to 13.56 MHz clock. Used for LFO trimming.
Set_Timer_Reload(TIMER_2_SELECTED, 0x03FF);
Set_Timer_Control(TIMER_3_SELECTED, TCONTROL_CLK_13MHZ); // configure Timer 3. Not started, set to 13.56 MHz clock.
WriteRegisterByte(FIFO_CONTROL, 0xB0); // Flush FIFO
WriteRegisterByte(RX_BIT_CTRL, 0x80); // Receive bits after collision replaced with zeros.
WriteRegisterByte(DRV_MODE, CLRC663_DRVMODE_TX2INV); // Invert transmitter 2 at pin
WriteRegisterByte(TX_AMP, 0x00); // Output Amplitude 0; TVDD 100mV
WriteRegisterByte(DRV_CON, 0x01); // Tx Envelope
// WriteRegisterByte(TXL, 0x05); // Factory set. Don't change?
WriteRegisterByte(RX_SOF_DETECTION, 0x00); // Clear SOF detection
WriteRegisterByte(RECEIVE, 0x12); // Signal over envelope (ISO14443A) collision detection 1/2 signal strength.
// Load Protocol
WriteRegisterByte(COMMAND, 0x00) // Command Idle.
WriteRegisterByte(FIFO_CONTROL, 0xB0); // Flush FIFO
WriteRegisterByte(IRQ0, 0x7F); // Clear the interrupts
WriteRegisterByte(IRQ1, 0x7F);
WriteRegisterByte(FIFO_DATA, 0x00); // Load protocol for ISO-14443A
WriteRegisterByte(FIFO_DATA, 0x00);
WriteRegisterByte(COMMAND, COMMAND_LOAD_PROTOCOL);
WriteRegisterByte(IRQ0_EN, IRQ0_ENABLE_IDLE_IRQ); // Enable IRQ sources: Idle
while ( !(Get_IRQ0_Value() & IRQ0_IDLE_IRQ) ) // Wait for Idle. Command to finish.
;
WriteRegisterByte(FIFO_CTRL, 0xB0);
// Apply Register Set.
WriteRegisterByte(TX_CRC_PRESET, 0x18); // Preset value 0x6363, CRC16 - CRC not used.
WriteRegisterByte(RX_CRC_PRESET, 0x18); // Preset value 0x6363, CRC16 - CRC not used.
WriteRegisterByte(TX_DATA_NUM, 0x08); // Data is sent!
WriteRegisterByte(TX_MODE_WIDTH, 0x20); // Length of pulse modulation in Carrier
WriteRegisterByte(TX_SYM_1_0_BURST_LEN, 0x00); // Symbol 0 and 1 burst lengths are 8 bits.
WriteRegisterByte(FRAME_CTRL, 0xCF); // Start symbol = Symbol 2; Stop symbol = Symbol 2.
WriteRegisterByte(RX_CTRL, 0x04); // Rx Baudrate 106k baud
WriteRegisterByte(RX_THRESHOLD, 0x32); // Set minimum levels for Rx and phase shift.
WriteRegisterByte(RX_ANALOG, 0x00); // Set gain and filter levels.
WriteRegisterByte(RX_WAIT, 0x90); // Set Rx waiting time.
WriteRegisterByte(TX_WAIT_CTRL, 0xC0); // Wait until the end of the Rx data.
WriteRegisterByte(TX_WAIT_LO, 0x0B); // Wait time between the receive and send data streams.
Set_Timer_Reload(TIMER_0_SELECTED, 0x08DB);
Set_Timer_Reload(TIMER_1_SELECTED, 0x0000);
WriteRegisterByte(DRV_MODE, 0X89);
WriteRegisterByte(STATUS, 0x00); // Mifare Crypto1 is disabled.
The selection consists of:
WriteRegisterByte(TX_DATA_NUM, 0x08); // Data is sent!
WriteRegisterByte(RX_BIT_CTRL, 0x00); // Cleared to look for a collision.
WriteRegisterByte(COMMAND, 0x00) // Command Idle.
WriteRegisterByte(FIFO_CONTROL, 0xB0); // Flush FIFO
WriteRegisterByte(TX_DATA_NUM, 0x0F); // Data is sent!
WriteRegisterByte(IRQ0_EN, IRQ0_ENABLE_RX_IRQ | IRQ0_ENABLE_ERR_IRQ); // Enable IRQ sources: Idle
WriteRegisterByte(FIFO_DATA, 0x93); // Write Select Command into FIFO
WriteRegisterByte(FIFO_DATA, 0x20);
WriteRegisterByte(COMMAND, COMMAND_TRANSCEIVE);
IRQ0_Value = Get_IRQ0_Value();
IRQ1_Value = Get_IRQ1_Value();
while ( !(IRQ1_Value & IRQ1_TIMER_1) ) // While the timer interrupt hasn't triggered.
{
IRQ1_Value = Get_IRQ1_Value();
if (IRQ0_Value & IRQ0_RX_IRQ)
break;
IRQ0_Value = Get_IRQ0_Value();
}
WriteRegisterByte(COMMAND, 0x00) // Command Idle.
FifoDataLength = ReadRegisterByte(FIFO_LENGTH);
ReadRegisterArray(FIFO_DATA, ResponseDataArray, FifoDataLength);
The timers are set up so that a time out will occur if the card does not respond, which would be the case if a card is not present.
When I run the same sequence but have the REQA as the data being sent then the card responds.
What I'm not sure is if the registry settings are correct. Also I assume that all the data that is in the FIFO is sent during the Transceive command writing (0x00, 0x07) and not just the first byte. I haven't found any where to set the number of bytes to be sent and it appears that it is all the data in the FIFO (fifo length).
I have tried to send the REQA first and then the Select card after getting a response but this also fails to obtain a response from the card.
I have already been through the Application Note that covers the Card selection. I moved on from that as it didn't have any timing to check if the card was detected. This also failed to elicit a response from the card or at least the CLRC663 did not give an acknowledgement that the card had responded.
Another side question while I'm going I noticed that the clear FIFO command that is put in the sample codes is 0xB0, I don't understand why the LoAlert bit is being written to when the data sheet states that it is a read only bit? To me the value should be 0x90 for clearing the FIFO.