cancel
Showing results for 
Search instead for 
Did you mean: 

rfalST25xVPollerGenericWriteMessage() fails writing to mailbox

MMitt.1
Associate

Hi,

I have some code for reading/writing to a mailbox from the ST25R3916B transceiver to a ST25DV04KC-I tag. The read passes but the write fails every time.

My reading function looks like this ...

 

bool nfc_read_mailbox(void)
{
    uint8_t pointer;
    uint8_t reg;
    uint8_t pwd[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    uint8_t pwdLen = 8;
    uint8_t pwdNum = 0;
    uint8_t msgLen;
    ReturnCode err;
    uint16_t rcvLen;
    uint8_t rxBuf[256];

    bool result = false;

    memset(&rxBuf[0], 0x00, sizeof(rxBuf));

    /* Open RF configuration security session */
    err = rfalST25xVPollerPresentPassword(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pwdNum, pwd, pwdLen);
    if (err == RFAL_ERR_NONE)
    {
        /* set MB_MODE to 1: Enabling fast transfer mode is authorized.*/
        pointer = ST25DV04K_SYSTEM_CONFIG_MB_MODE;
        reg = ST25DV04K_REG_MB_MODE_FTM_AUTHORIZED;
        err = rfalST25xVPollerWriteConfiguration(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pointer, reg);
        if (err == RFAL_ERR_NONE)
        {
            /* set MB_EN to 1: Enable FTM. Read, update and write */
            pointer = ST25DV04K_DYN_REG_MB_CTRL;
            err = rfalST25xVPollerFastReadDynamicConfiguration(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pointer, &reg);
            if (err == RFAL_ERR_NONE)
            {
                reg |= ST25DV04K_REG_MB_CTRL_DYN_MB_EN;
                err = rfalST25xVPollerFastWriteDynamicConfiguration(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pointer, reg);
                if (err == RFAL_ERR_NONE)
                {
                    /* Read Msg Len */
                    err = rfalST25xVPollerReadMessageLength(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, &msgLen);
                    if (err == RFAL_ERR_NONE)
                    {
                        /* Read Msg */
                        err = rfalST25xVPollerReadMessage(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, 0, 0, rxBuf, sizeof(rxBuf), &rcvLen);
                        if (err == RFAL_ERR_NONE)
                        {
                            result = true;
                        }
                    }
                }
            }
        }
    }

    return result;
}

 

My writing function looks like this ...

 

bool nfc_write_mailbox(char *message)
{
    uint8_t pointer;
    uint8_t reg;
    uint8_t pwd[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    uint8_t pwdLen = 8;
    uint8_t pwdNum = 0;
    uint8_t msgLen;
    ReturnCode err;
    uint16_t rcvLen;
    uint8_t txBuf[256];

    bool result = false;

    memset(&txBuf[0], 0x00, sizeof(txBuf));
    sprintf(txBuf, "%s", message);

    /* Open RF configuration security session */
    err = rfalST25xVPollerPresentPassword(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pwdNum, pwd, pwdLen);
    if (err == RFAL_ERR_NONE)
    {
        /* set MB_MODE to 1: Enabling fast transfer mode is authorized.*/
        pointer = ST25DV04K_SYSTEM_CONFIG_MB_MODE;
        reg = ST25DV04K_REG_MB_MODE_FTM_AUTHORIZED;
        err = rfalST25xVPollerWriteConfiguration(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pointer, reg);

        if (err == RFAL_ERR_NONE)
        {
            /* set MB_EN to 1: Enable FTM. Read, update and write */
            pointer = ST25DV04K_DYN_REG_MB_CTRL;
            err = rfalST25xVPollerFastReadDynamicConfiguration(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pointer, &reg);
            if (err == RFAL_ERR_NONE)
            {
                reg |= ST25DV04K_REG_MB_CTRL_DYN_MB_EN;
                err = rfalST25xVPollerFastWriteDynamicConfiguration(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, pointer, reg);
                if (err == RFAL_ERR_NONE)
                {
                    /* Write Msg */
                    //err = rfalST25xVPollerFastWriteMessage(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, strlen(txBuf), (const uint8_t *)&txBuf, (uint8_t *)&txBuf, sizeof(txBuf));
                    err = rfalST25xVPollerWriteMessage(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, strlen(txBuf), (const uint8_t*) &txBuf, (uint8_t*) &txBuf, sizeof(txBuf) );
                    if (err == RFAL_ERR_NONE)
                    {
                        result = true;
                    }
                }
            }
        }
    }

    return result;
}

 

 

The failure happens in the call to rfalTransceiveBlockingTxRx() in rfalST25xVPollerGenericWriteMessage().

The tx works (line 5 below) but the rx fails (line 6 below) with a timeout (ret=RFAL_ERR_TIMEOUT).

 

ReturnCode rfalTransceiveBlockingTxRx( uint8_t* txBuf, uint16_t txBufLen, uint8_t* rxBuf, uint16_t rxBufLen, uint16_t* actLen, uint32_t flags, uint32_t fwt )
{
    ReturnCode ret;
    
    RFAL_EXIT_ON_ERR( ret, rfalTransceiveBlockingTx( txBuf, txBufLen, rxBuf, rxBufLen, actLen, flags, fwt ) );
    ret = rfalTransceiveBlockingRx();
    
    /* Convert received bits to bytes */
    if( actLen != NULL )
    {
        *actLen = rfalConvBitsToBytes(*actLen);
    }
    
    return ret;
}

 

 

Do I have the write sequence correct or am I missing something?

 

Thanks

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Brian TIDAL
ST Employee

Hi,

RFAL_ERR_TIMEOUT (0x04) means there was no response from the ST25DV04KC. This might be caused by the interface arbitration (see §5.3 of the ST25DV04KC datasheet). 

Regarding the code you provided: parameter #5 (txBuf pointer) of rfalST25xVPollerWriteMessage cannot be the same as the buffer containing the message you would like to write inside the mailbox. This txBuf parameter is a buffer used to build the command (i.e. your message will be copied inside this buffer with the command header). So the code should be rather:

 

 

err = rfalST25xVPollerWriteMessage(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, strlen(message) - 1, message, (uint8_t*) &txBuf, sizeof(txBuf) );

 

 

Make sure txBuf is big enough to store a full command (256 for the message + flags + command code + manufacturer code + uid + msgLen: 268 bytes). I would allocate this buffer outside the stack (e.g global or static) to avoid stack size issue. Regarding the msgLen parameter, it should be the size of the message minus 1 (see §7.6.31 in the datasheet).

I would recommend to read back the static FTM (@0x0D) register to make sure MB_MODE is properly set to 1 and to read back the Dynamic MB_CTRL_Dyn (@0x0D)  register to make sure MB_EN=1 and to check the state of the mailbox (feel free to provide log of those read back). Also make sure to implement retries mechanism when having RFAL_ERR_TIMEOUT or RFAL_ERR_PROTO

A demo of mailbox exchanges is available in the ST25 embedded NFC library (FTM demo) for ST25DVxxK products (this might need some modifications for ST25DVxxKC).

More information on the mailbox management can be found in AN4910.

Rgds

BT

P.-S. Writing MB_MODE=1 should be done only once in your application to avoid cycling the memory. You can simply read the MB_MODE and set it to 1 only in case it is 0.

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

1 REPLY 1
Brian TIDAL
ST Employee

Hi,

RFAL_ERR_TIMEOUT (0x04) means there was no response from the ST25DV04KC. This might be caused by the interface arbitration (see §5.3 of the ST25DV04KC datasheet). 

Regarding the code you provided: parameter #5 (txBuf pointer) of rfalST25xVPollerWriteMessage cannot be the same as the buffer containing the message you would like to write inside the mailbox. This txBuf parameter is a buffer used to build the command (i.e. your message will be copied inside this buffer with the command header). So the code should be rather:

 

 

err = rfalST25xVPollerWriteMessage(RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, strlen(message) - 1, message, (uint8_t*) &txBuf, sizeof(txBuf) );

 

 

Make sure txBuf is big enough to store a full command (256 for the message + flags + command code + manufacturer code + uid + msgLen: 268 bytes). I would allocate this buffer outside the stack (e.g global or static) to avoid stack size issue. Regarding the msgLen parameter, it should be the size of the message minus 1 (see §7.6.31 in the datasheet).

I would recommend to read back the static FTM (@0x0D) register to make sure MB_MODE is properly set to 1 and to read back the Dynamic MB_CTRL_Dyn (@0x0D)  register to make sure MB_EN=1 and to check the state of the mailbox (feel free to provide log of those read back). Also make sure to implement retries mechanism when having RFAL_ERR_TIMEOUT or RFAL_ERR_PROTO

A demo of mailbox exchanges is available in the ST25 embedded NFC library (FTM demo) for ST25DVxxK products (this might need some modifications for ST25DVxxKC).

More information on the mailbox management can be found in AN4910.

Rgds

BT

P.-S. Writing MB_MODE=1 should be done only once in your application to avoid cycling the memory. You can simply read the MB_MODE and set it to 1 only in case it is 0.

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.