This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

TWI_XFER is returning NRF_Success but the Data NACK is received

HI,

I'm having a problem when I use the function nrf_drv_twi_xfer. The function returns the error code NRF_SUCCESS, but using the event handler I notice that I'm receiving DATA NACK and the receiving buffer is empty, I didn't recieve a response from the device.

I'm trying to communicate with a CryptoMemory over I2C. In my circuit I have two slaves, a sensor and the cryptomemory, both using the same TWI instance. I have been able to communicate with the sensor without problem using the nrf_drv_twi_tx and nrf_drv_twi_rx functions. 

Reading the Crypto Memory datasheet I think is necessary to work with the Xfer function because it works with commands when in needs an input to give an output. The sensor works different, you can simply write to it or you can just read the register, it's no necessary to indicante a command to have an answer like it does in the Crypto Memory.

I have define my xfer_descriptor like this:

static nrf_drv_twi_xfer_desc_t Cryp_xfer = NRF_DRV_TWI_XFER_DESC_TXRX(Cryp_Addr, tx_cryp, sizeof(tx_cryp), rx_cryp_data, sizeof(rx_cryp_data));

and when  I use the function nrf_drv_twi_xfer is define like this:

err_code1 = nrf_drv_twi_xfer(&m_twi_Acc_Cryp, &Cryp_xfer, flags);

where: 

  • err_code1 is code error returned by the function
  • m_twi_Acc_Cryp is the TWI instance
  • Cryp_xfer is the xfer descriptor above
  • flags is define as NRF_DRV_TWI_FLAG_TX_NO_STOP;

My TWI initialization is using a TWI event handler, so is not in blocking mode. 

What I'm missing? I something configured wrong?

Thanks for your help.

  • Hi 

    Which version of the SDK are you using?

    What have you set the flags to when you call the xfer function?

    Have you probed the bus to see what is going on, and which byte the slave is NACK-ing?

    Could you send me a link to the Crypto Memory datasheet if you have one?

    Best regards
    Torbjørn

  • Hi Torbjorn,

    I'm using the SDK 15.3.0.

    The flags is set to NRF_DRV_TWI_FLAG_TX_NO_STOP.

    No, I haven't probed the bus to see which byte the slave is NACK-ing.

    This is the link to the Crypto Memory datasheet.--> http://ww1.microchip.com/downloads/en/DeviceDoc/20005927A.pdf

    Thanks for your help.

    Best regards,

    Julio

  • Hi Julio

    What is the content of the data you are trying to send?

    IE the value of the tx_cryp array. 

    I would suggest finding some tool to probe the signals, as this makes it a lot easier to debug interfacing issues like these. 

    Best regards
    Torbjørn

  • Hi Torbjorn,

    I have try using two commands: Random and Read.

    This array is declared like this:

    static uint8_t  tx_cryp[5];

    It has 5 elements, for the Read Command these are the 5 elements:

    tx_cryp[0] = Command; //This value is 0x03. 
    tx_cryp[1] = Read; //This value is 0x02.
    tx_cryp[2] = 0x00U; //This means  I want to read 4 bytes from the "Configuration zone".
    tx_cryp[3] = 0x00U;
    tx_cryp[4] = 0x03U; //This offset is just to read four bytes in block one.

    For the Random Command:

    tx_cryp[0] = Command; //This value is 0x03. 
    tx_cryp[1] = Random; //This value is 0x1B.
    tx_cryp[2] = 0x01U; //This means  I want to generate a random number without updating the EEPROM seed.
    tx_cryp[3] = 0x00U;
    tx_cryp[4] = 0x00U; 

    I have also try adding more elements to the array. These elements were the number of bytes sent as the first element of the array and add two elements at the end that were the checksum of the message, but this was left in 0x00 both elements because I don't know how to calculate this checksum.

    I will use an oscilloscope to probe the signals and see at what moment the NACK is sent.

    Thanks.

    Best regards,

    Julio

  • Hi

    I assume the sensor might NACK the transaction if the checksum fails?

    I found the following section in the datasheet regarding the checksum:

    "CRC-16 verification of the count and packet bytes. The CRC polynomial is 0x8005. The initial register value should be zero and after the last bit of the count and packet have been transmitted, the internal CRC register should have a value that matches the checksum bytes in the block. The first CRC byte transmitted (N-1) is the least-significant byte of the CRC value, so the last byte of the group is the most-significant byte of the CRC."

    With some luck you might find some source code online showing how to use the sensor, if you don't have a lot of experience implementing CRC algorithms ;)

    Best regards
    Torbjørn

Related