cancel
Showing results for 
Search instead for 
Did you mean: 

RFAL Manual RX CRC

kwolff
Visitor

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?

1 REPLY 1
Ulysses HERNIOSUS
ST Employee

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