2025-04-28 10:30 AM - edited 2025-04-28 10:57 AM
I am working with an ST25R3916b, utilizing the RFAL library. I am trying to work with a card that does not always send back a CRC over NFC, so I need to be able to disable the CRC RX checks dynamically. My txrx function looks like:
static int st25r_nfca_rxtx_rf(const struct device *dev, uint8_t *tx_data, uint16_t tx_bitlen,
uint8_t *rx_data, uint16_t rx_size, uint16_t *rx_bitlen)
{
LOG_DBG("Transmitting and receiving using RF interface");
ReturnCode ret;
rfalTransceiveContext ctx = {
.txBuf = tx_data,
.txBufLen = tx_bitlen,
.rxBuf = rx_data,
.rxBufLen = rx_size,
.rxRcvdLen = rx_bitlen,
.flags =
(uint32_t)((NFC_ST25R_DATA(dev)->tx_crc) ? RFAL_TXRX_FLAGS_CRC_TX_AUTO
: RFAL_TXRX_FLAGS_CRC_TX_MANUAL) |
(uint32_t)((NFC_ST25R_DATA(dev)->rx_crc_keep)
? RFAL_TXRX_FLAGS_CRC_RX_KEEP
: RFAL_TXRX_FLAGS_CRC_RX_REMV) |
(uint32_t)RFAL_TXRX_FLAGS_NFCIP1_OFF | (uint32_t)RFAL_TXRX_FLAGS_AGC_ON |
(uint32_t)RFAL_TXRX_FLAGS_NFCV_FLAG_AUTO |
(uint32_t)((NFC_ST25R_DATA(dev)->tx_parity) ? RFAL_TXRX_FLAGS_PAR_TX_AUTO
: RFAL_TXRX_FLAGS_PAR_TX_NONE) |
(uint32_t)((NFC_ST25R_DATA(dev)->rx_parity) ? RFAL_TXRX_FLAGS_PAR_RX_KEEP
: RFAL_TXRX_FLAGS_PAR_RX_REMV) |
(uint32_t)((NFC_ST25R_DATA(dev)->rx_crc_check)
? RFAL_TXRX_FLAGS_CRC_RX_AUTO
: RFAL_TXRX_FLAGS_CRC_RX_MANUAL),
.fwt = rfalConvUsTo1fc(NFC_ST25R_DATA(dev)->timeout_us),
};
LOG_INF("Transceive flags: 0x%08X", ctx.flags);
/* Start transceiving bits over NFC */
ret = rfalStartTransceive(&ctx);
if (ret) {
LOG_ERR("Failed to start transceive (err %d)", ret);
return -EIO;
}
do {
rfalWorker();
ret = rfalGetTransceiveStatus();
} while (rfalIsTransceiveInTx() && (ret == ERR_BUSY));
if (rfalIsTransceiveInRx()) {
ret = RFAL_ERR_NONE;
}
if (ret) {
LOG_ERR("Failed to transceive Tx Bits (err %d)", ret);
return -EIO;
}
/* Block until Rx is complete */
ret = rfalTransceiveBlockingRx();
if (ret == RFAL_ERR_CRC) {
LOG_ERR("CRC check failed");
/* continue */
} else if (ret) {
LOG_ERR("Failed to transceive Rx Bits (err %d)", ret);
return -ENOMSG;
}
/* Convert received bits to bytes */
*rx_bitlen = rfalConvBitsToBytes(*rx_bitlen);
return 0;
}
Before calling this function, I will set the property for NFC_ST25R_DATA(dev)->rx_crc_check to false: effectively producing the transceive flags 0x00000080. However, I will always receive an ERR_CRC from rfal_rfst25r3916.c:2515:
static void rfalTransceiveRx( void )
{
...
switch( gRFAL.TxRx.state )
{
...
case RFAL_TXRX_STATE_RX_ERR_CHECK:
...
else if( (irqs & ST25R3916_IRQ_MASK_CRC) != 0U )
{
gRFAL.TxRx.status = RFAL_ERR_CRC;
gRFAL.TxRx.state = RFAL_TXRX_STATE_RX_READ_DATA;
/* Check if there's a specific error handling for this */
rfalErrorHandling();
break;
}
...
}
Is how I am trying to disable the CRC check not the correct way or is there another way I should be doing this?
2025-04-29 2:04 AM - edited 2025-04-29 2:32 AM
Hi kwolff,
your procedure looks right. Do you get this ERR_CRC only for your special frames are also for frames with normal good CRC?
Also you probably want to receive the CRC, i.e. setting RFAL_TXRX_FLAGS_CRC_RX_KEEP. Which RFAL version are you using?
BR, Ulysses