Hello,
I followed the guide of "PicoPass 32K(S) Card Operations with the TRF79xxA",and got the sample code of picopass.c,I can get the UID of the card which means command "ACTALL" and the function "calculate crc" are correct. Later, I try to read content with the read command. I also can get the data of block 0 is UID. I continue reading the next block, and I get the data below:
Select command received bytes:0A
iClass UID: [D802E000F7FF12E0]
Block 00 Data: [ D802E000F7FF12E026B8]
Read command received bytes:0A
Block 01 Data: [ 12FFFFFFE97FFF3C9427]
Read command received bytes:0A
Block 02 Data: [ FEFFFFFFFFFFFFFF5574]
Read command received bytes:0A
When I am trying to update some of the blocks, I found the function PicoPass_UPDATE is uncomplete. So I implemented the function. But it can't work. I will attach my code below to figure it out some bug or my iClass card can't update by the sample.
Many thanks for any reply.
graph1:iClass wirte and read. graph2:iClass other block data.
Testing card:
HID iCLASS TEST CARD
PART NO. 2004PGGNN
FORMAT: H10301
F/C = 99
ID = 1002
typedef union
{
uint16_t value;
struct
{
uint8_t lowByte;
uint8_t highByte;
};
} crc16_t;
#define CRC_POLYNOME 0x8408
#define CRC_PRESET_VALUE 0xE012
#define CRC_CHECK_VALUE 0x0000
extern uint8_t g_trf_buffer[NFC_FIFO_SIZE];
static volatile trf_status_t m_trf_status;
/**
* This function calculates a crc16 over a uint8_t array
* with LSB first.
*
* @param Datag_trf_buffer Pointer to data to calculate crc16 for.
* @param SizeOfDatag_trf_buffer Length of the data g_trf_bufferfer (Datag_trf_buffer)
* @param polynom Value of the generator polynom.
* 0x8408 is recommended.
* @param Initial_Value Initial value of crc16.
* 0xFFFF is recommended for
* host to reader communication.
* @return Calculated crc16
*/
uint16_t GetCrc(uint8_t *pDatag_trf_buffer, uint8_t g_trf_bufferLen, uint16_t polynom, uint16_t initialValue)
{
uint16_t crc16 = initialValue;
uint8_t byteCounter, bitCounter;
for (byteCounter = 0; byteCounter < g_trf_bufferLen; byteCounter++)
{
crc16 ^= pDatag_trf_buffer[byteCounter];
for (bitCounter = 0; bitCounter < 8; bitCounter++)
{
if ((crc16 & 0x0001) == 0)
{
crc16 >>= 1;
}
else
{
crc16 = (crc16 >> 1) ^ polynom;
}
}
}
return (crc16);
}
//addr is the block to update, p_block_data is the data to be sent,block_size is the size of sent data,p_out_data store the reply of update
uint8_t iclass_cmd_update(uint8_t addr, uint8_t* p_block_data, uint8_t block_size, uint8_t* p_out_data)
{
//SHELL FOR COMMAND
uint8_t bTxbuffer[17];
crc16_t crc16;
uint8_t ui8Offset = 0;
uint8_t out_data_len;
GUAP_Delay_ms(2); //delay
out_data_len = 0;
bTxbuffer[ui8Offset++] = 0x8F; // reset FIFO
bTxbuffer[ui8Offset++] = 0x90; // sending without CRC
bTxbuffer[ui8Offset++] = 0x3D; // write continuous from 1D
bTxbuffer[ui8Offset++] = 0x00; // upper and middle nibbles of transmit byte length
bTxbuffer[ui8Offset++] = 0xC0; // lower and broken nibbles of transmit byte length
bTxbuffer[ui8Offset++] = 0x27; // UPDATE
bTxbuffer[ui8Offset++] = addr; // BLOCK #addr
memcpy(&bTxbuffer[ui8Offset], p_block_data, block_size); // Data to write to tag
ui8Offset += block_size;
crc16.value = GetCrc(&bTxbuffer[6], 9, CRC_POLYNOME, CRC_PRESET_VALUE);
bTxbuffer[ui8Offset++] = crc16.lowByte;
bTxbuffer[ui8Offset++] = crc16.highByte;
TRF79xxA_writeRaw(bTxbuffer, ui8Offset); //issuing the READ command
m_trf_status = TRF79xxA_waitRxData(30, 20); // 30 millisecond TX timeout, 20 millisecond RX timeout
if (m_trf_status == RX_COMPLETE)
{ // if received block data in g_trf_bufferfer
uint8_t g_trf_buffer_len = TRF79xxA_getRxBytesReceived();
if (0 != g_trf_buffer_len && NULL != p_out_data)
{
out_data_len = g_trf_buffer_len;
memcpy(p_out_data, g_trf_buffer, g_trf_buffer_len);
//Response will be contents written to the block (8 bytes)
}
}
else
{
// clear any IRQs
TRF79xxA_resetIrqStatus();
}
return out_data_len;
}