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

nrf_drv_twi_tx & rx with Adafruit PN532

I have the Adafruit PN532 Shield v1.3 mounted to an nRF52840 DK, trying to run the ble_nfc_pairing_reference_c example from SDK 17. With no modification to the example code, I was getting the following output.

  

After some debugging I found the error was returning from the nrf_drv_twi_tx function with these default arguments passed. 

To investigate, I flashed the twi_scanner example and successfully found the PN532 at address 0x24. 

Since this doesn't match the PN532_I2C_ADDRESS being passed in the nfc reference example, I changed (0x48 >> 1) to (0x24). This resulted in the following output. 

The only difference being that the tx function seemed to send data successfully, but the nrf_drv_twi_rx function that passes those same parameters was returning a wild error while trying to read the acknowledgement. 

Since I was getting two different error scenarios, I re-extracted a fresh SDK 17 and tried again, but the exact behavior occurred. Does anyone know what is going on here?

My theory is that either there is something wrong with the Adafruit hardware, or these parameters are not configured correctly, unless I'm missing something. 

Any help here would be much appreciated. 

Thanks in advance!

Sam

  • Hello Sam,

    The only difference being that the tx function seemed to send data successfully, but the nrf_drv_twi_rx function that passes those same parameters was returning a wild error while trying to read the acknowledgement. 

    Could you make sure to pass the returned error code to an APP_ERROR_CHECK, and make sure that you have DEBUG defined in your preprocessor defines - like shown in the included image?
      
    Enabling DEBUG in your preprocessor defines makes the APP_ERROR_CHECK write a detailed error message to the log, before the device is reset.
    Please do this, and post the entire debug message, so we may look into what's the root issue here.

    Do you have access to a logic analyzer by any chance?

    Looking forward to resolving this issue together!

    Best regards,
    Karl

  • Thank you Karl, apologies for taking a bit on the replay. I did as you instructed and got the following error check message. 

    I also ran the SCL, SDA, and IRQ pins through a logic analyzer and can see that the message was indeed sent as well as acknowledged it seems...?

    This seems to confirm an earlier suspicion I had that it may be the IRQ pin that is causing this issue, but your guess will definitely be better than mine, and I'm still not sure how I'd go about solving this. Let me know if there's other info you need, your help is much appreciated. 

    Thanks, 

    Sam

  • Hello Sam,

    Sam_Rall said:
    Thank you Karl, apologies for taking a bit on the replay.

    Do not worry about that at all. I am happy to help!

    Sam_Rall said:
    I did as you instructed and got the following error check message. 

    Thank you, that is very helpful!
    So, you are getting an NRF_ERROR_DRV_TWI_ERR_ANACK, which from the documentation reads: 

    NRF_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address in polling mode.

    This indicates that your slave device did not acknowledge the address being sent as part of the rx command. This could indicate that the device does not recognize the address you attempted to reach. However, from your log it seems that a previous write command is received. Could you check that the address you are trying to read in the rx command is exposed in the slave device?

    Sam_Rall said:
    I also ran the SCL, SDA, and IRQ pins through a logic analyzer and can see that the message was indeed sent as well as acknowledged it seems...?

    Great! This makes things alot easier. As you can see, it seems all the transfers are fine up until the very last transfer - in which SDA remains high during the ninth clock pulse, indicating a NACK. Could you check that the address you were trying to access here was in fact valid?

    Sam_Rall said:
    This seems to confirm an earlier suspicion I had that it may be the IRQ pin that is causing this issue

    Could you elaborate on this - why did you suspect that the IRQ pin might affect this, and how is the IRQ pin connected to the TWI transfer in your application?

    Looking forward to resolving this issue together!

    Best regards,
    Karl

  • Could you check that the address you are trying to read in the rx command is exposed in the slave device?

    I'm not totally sure how I'd go about confirming whether the address is exposed? I've found that the twi_scanner example finds the device at 0x24, which makes sense given the address parameters in adafruitPN532.h .

    #define PN532_I2C_ADDRESS   (0x48 >> 1) ///< Address of the I2C peripheral of the Adafruit PN532 Shield.
    

    Does this answer this question as well? I'm not sure. 

    Could you check that the address you were trying to access here was in fact valid?

    As far as the IRQ pin, from the trace it seems to be staying high when, I was under the impression it needed to read a 0 for the firmware to pick up the acknowledgement. Honestly though that is just an estimated theory that I gathered from these functions that get called the init function. 

    I want to be clear that this was my best guess, I don't want to spin off in a wild goose chase. 

    Thanks again for your help, 

    Sam

  • Hello Sam,

    Sam_Rall said:
    I'm not totally sure how I'd go about confirming whether the address is exposed? I've found that the twi_scanner example finds the device at 0x24, which makes sense given the address parameters in adafruitPN532.h .

    The scanner finding it on address 0x24 indicates that the device acknowledged this address, when the master requested it - i.e the slave pulled down the SDA line at the ninth clock cycle, to acknowledge the centrals request ( as per the TWI protocol ).

    Sam_Rall said:
    Does this answer this question as well? I'm not sure. 

    Do you have the datasheet for the module you are using? I think most of our answers will lie there.
    Reading the datasheet to understand how the communication with the device is implemented is a lot easier than trying to parse it from the driver directly.
    The datasheet will detail how to go about controlling, configuring and communicating with the device over TWI.

    Sam_Rall said:
    As far as the IRQ pin, from the trace it seems to be staying high when, I was under the impression it needed to read a 0 for the firmware to pick up the acknowledgement. Honestly though that is just an estimated theory that I gathered from these functions that get called the init function. 

    This too will be detailed in the modules datasheet - what the IRQ is used for, and how it is used.
    From the code you have shared, I suspect that the IRQ is used to indicate that the slave is ready to transfer data, or receive commands.

    Please see if you can find the datasheet, and these two sections in particular. You may also post the datasheet here for me to take a look at it - but I highly recommend that you familiarize with it on your own first. Navigating the datasheet is essential to all microcontroller programming.

    Looking forward to resolving this together!

    Best regards,
    Karl

Related