cancel
Showing results for 
Search instead for 
Did you mean: 

st25r100 How to use function "rfalTransceiveBlockingTxRx" send 36 bits data

wenjie
Associate II

@Ulysses HERNIOSUS 

Dear Ulysses,

Sorry to bother you again.

 

code : 

err = rfalTransceiveBlockingTxRx(tx_buf, sizeof(tx_buf), rx_buf, sizeof(rx_buf), &actlen, RFAL_TXRX_FLAGS_CRC_TX_MANUAL|RFAL_TXRX_FLAGS_PAR_TX_NONE|RFAL_TXRX_FLAGS_CRC_RX_KEEP|RFAL_TXRX_FLAGS_PAR_RX_REMV|RFAL_TXRX_FLAGS_CRC_RX_MANUAL, 71680U);
 
I want to send 4 bytes data and 4 bits parity, how do i combine those 36 bits data to 5 bytes data and send with function rfalTransceiveBlockingTxRx.
 
for example:
data_enc: 03, de, 59, bd
parity_enc: 00, 00, 00, 00
tx_buf: 03, bc, 65, e9, 05
is it correct? can rfalTransceiveBlockingTxRx send 4bit data?
 
Thanks
1 ACCEPTED SOLUTION

Accepted Solutions

Hi,

as communicated in previous posts: Go step by step! First verify your CRC and parity and bit oriented sending is working using a well-known command without crypto. E.g. use a T2T and perform a read block using the mentioned methods. Only then move to your crypto.

BR, Ulysses

View solution in original post

5 REPLIES 5
Ulysses HERNIOSUS
ST Employee

Hi, 

  • the frame cannot be sent using the blocking byte-oriented rfalTransceiveBlockingTxRx(). You need to use the bit-oriented rfalStartTransceive().... interface.
  • I think your parity encoding is incorrect. It should be odd parity so 03 1 de 1 59 1 bd 1

Yes, you can also transfer 4 bits.

Ulysses

RFAL has to use st25r200WriteFifo to send data which can only send full bytes. I don't think RFAL can send bits.

I'm trying reading block data from M1 card which need encoded parity. When encoded parity is the same as normal parity and use rfalTransceiveBlockingTxRx and RFAL_TXRX_FLAGS_PAR_TX_AUTO, I can read data successfully. So encoding is correct. Nothing is wrong but sending 36 bits data ifself.

Could you help check whether my code is wrong or RFAL doesn't support incomplete bytes sending?

 

code:

rfalTransceiveContext ctx;
    ctx.txBuf = tx_buf;
    ctx.txBufLen = 36;
    ctx.rxBuf = rx_buf;
    ctx.rxBufLen = sizeof(rx_buf) * 8;
    ctx.rxRcvdLen = &actlen;
    ctx.flags = RFAL_TXRX_FLAGS_CRC_TX_MANUAL|RFAL_TXRX_FLAGS_PAR_TX_NONE|RFAL_TXRX_FLAGS_CRC_RX_KEEP|RFAL_TXRX_FLAGS_PAR_RX_REMV|RFAL_TXRX_FLAGS_CRC_RX_MANUAL;
    ctx.fwt = 71680U;
    err = rfalStartTransceive(&ctx);
    do{
        rfalWorker();
        err = rfalGetTransceiveStatus();
    }
    while( (rfalIsTransceiveInTx()) && (err == RFAL_ERR_BUSY) );
    platformLog("err: %d, actlen: %d\r\n", err, actlen);
    err = rfalTransceiveBlockingRx();

Hi,

yes, only full bytes are written into FIFO. But nbtx bits tell how many bits to transmit from the last byte.

There is no need to call rfalIsTransceiveInTx() or rfalTransceiveBlockingRx(). Just wait until rfalGetTransceiveStatus() does not return RFAL_ERR_BUSY anymore.

From a first glimpse the rest look correct.

BR, Ulysses

I'm trying reading block data from M1 card which need encoded parity. Everything is right but received error code 4. May I ask what's the possible reason for receiving error code 4?
 
code:
//authentication succeed, start to send read command
if(ret == 0)
  {
    uint8_t rx_buf[21];

    uint8_t crc_arr[2] = {MIFARE_CLASSIC_CMD_READ, addr};
    uint8_t data[4] = {MIFARE_CLASSIC_CMD_READ, addr, 0x00, 0x00};
    uint16_t crc = crc14a_calc(crc_arr, sizeof(crc_arr));
    data[2] = crc & 0x00FF;
    data[3] = crc >> 8;
    platformLog("sending: %02x, %02x, %02x, %02x\r\n", data[0], data[1], data[2], data[3]);
   
    //calculate the parity
    uint8_t parity[4];
    for(int i=0; i<4; i++)
    {
      parity[i] = parity8(data[i]);
    }

    platformLog("parity: %02x, %02x, %02x, %02x\r\n", parity[0], parity[1], parity[2], parity[3]);

    //encrypt the data and parity
    uint8_t data_enc[4] = {0};
    uint8_t parity_enc[4] = {0};
    uint8_t enc;
    for(int i=0; i<4; i++)
    {
      enc = 0;
      for(int j=0; j<8; j++)
      {
        enc |= crypto1_encrypt((data[i] >> j) & 1, 0) << j;
      }
      data_enc[i] = enc;
      parity_enc[i] |= crypto1_encrypt((parity[i] & 1), 1) & 1;
    }
    platformLog("data_enc: %02x, %02x, %02x, %02x\r\n", data_enc[0], data_enc[1], data_enc[2], data_enc[3]);
    platformLog("parity_enc: %02x, %02x, %02x, %02x\r\n", parity_enc[0], parity_enc[1], parity_enc[2], parity_enc[3]);

    //pack the data and parity
    uint8_t tx_buf[5];
    pack_data_parity(data_enc, sizeof(data_enc), parity_enc, sizeof(parity_enc), tx_buf, sizeof(tx_buf));
    platformLog("tx_buf: %02x, %02x, %02x, %02x, %02x\r\n", tx_buf[0], tx_buf[1], tx_buf[2], tx_buf[3], tx_buf[4]);
   
    //send the reading request
    uint16_t actlen;
    rfalTransceiveContext ctx;
    ctx.txBuf = tx_buf;
    ctx.txBufLen = 0x0024;
    ctx.rxBuf = rx_buf;
    ctx.rxBufLen = sizeof(rx_buf) * 8;
    ctx.rxRcvdLen = &actlen;
    ctx.flags = RFAL_TXRX_FLAGS_CRC_TX_MANUAL|RFAL_TXRX_FLAGS_PAR_TX_NONE|RFAL_TXRX_FLAGS_CRC_RX_KEEP|RFAL_TXRX_FLAGS_PAR_RX_REMV|RFAL_TXRX_FLAGS_CRC_RX_MANUAL;
    ctx.fwt = 71680U;
    err = rfalStartTransceive(&ctx);
    do{
        rfalWorker();
        err = rfalGetTransceiveStatus();
    }
    while(err == RFAL_ERR_BUSY);
    platformLog("err: %d, actlen: %d\r\n", err, actlen);

Hi,

as communicated in previous posts: Go step by step! First verify your CRC and parity and bit oriented sending is working using a well-known command without crypto. E.g. use a T2T and perform a read block using the mentioned methods. Only then move to your crypto.

BR, Ulysses