Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf_twi_mngr_perform blocking

I've been using the nrf_twi_mngr_perform() function assuming that my transaction was complete when the function returned.  Because of this, I felt safe keeping my descriptors on the stack.  However, it appears to me that if there are other transactions pending (placed via nrf_twi_mngr_schedule), the transaction you want to block on will be queued, and you will instead block on whatever the oldest transaction in the queue is.  Unfortunately for me, my function exits, my descriptors go out of scope, and then my transaction is executed sometime later.   It would be nice if the queue was double-ended and you could "pop from the back (or front)" when a "perform" was called vs a "schedule".

At this point, it seems to me that one shouldn't mix the use of "schedule" and "perform".  Is that correct?  Or am I mis-using the library?  Thanks.

I'm working on a custom board based on the nRF52832. I'm developing on Win 8.1 using SES and a J-Link Plus. SDK version 14.1.

Parents
  • I am not 100% sure I understand what your problem is, the description of what you are doing seems like a correct way queue and perform blocking and non-blocking TWI operations. Let me know if I misunderstood you.

    It is perfectly fine to mix "schedule" and "perform" calls to the nrf_twi_mngr. Schedule calls will not block but return immediately. Scheduled operations will be performed when the bus is available. Perform calls can queue one or more operations and will block until the operation is done. Perform calls should not return early, so you shouldn't be able to end up out of scope.

    Take care to check all return values from these API calls. Error codes have to be handled, or you may experience packets never being sent.

    Best regards,
    Rune Holmgren

  • Hi Rune,  I'm uploading a project that can be used to recreate the issue.  The README provides more details.Debug_Test.zip

  • Thank you. I have been talking a bit with the SDK team regarding this, and I'll look into the project you sent me and follow it up with the SDK team. Hopefully, we will figure out what is the issue here. It may be a few days.

    Best regards,
    Rune Holmgren

  • Hi,

    Sorry for the delay, have you figured this issue out in the meanwhile? Let me know if you have any further details and still need help with this.

    I had a look at your project, and I can't spot any cause of the issue from looking at the source code. Unfortunately, I do not have an MPU6050 available so I am unable to actually run and debug your project on actual hardware. I had a peek at some projects using motion control with our chip and found that the MPU-9250 has at least been used successfully. It looks similar enough that I assume the MPU6050 shouldn't be an issue if you can find the bug in your firmware.

    Best regards,
    Rune Holmgren

Reply
  • Hi,

    Sorry for the delay, have you figured this issue out in the meanwhile? Let me know if you have any further details and still need help with this.

    I had a look at your project, and I can't spot any cause of the issue from looking at the source code. Unfortunately, I do not have an MPU6050 available so I am unable to actually run and debug your project on actual hardware. I had a peek at some projects using motion control with our chip and found that the MPU-9250 has at least been used successfully. It looks similar enough that I assume the MPU6050 shouldn't be an issue if you can find the bug in your firmware.

    Best regards,
    Rune Holmgren

Children
  • Hi Rune,

      You should be able to see the issue with any I2C target.  The readme has some notes on porting.  If you're co-located with Kenneth, he is working on another issue (probably related) and has this MPU part on order.  Perhaps you can share:

    devzone.nordicsemi.com/.../i2c-reads-stuck

  • Hi,

    Thanks for your patience. I was able to borrow a sensor from a colleague who happened to have one (not quite the same model, but it responded to the TWI commands so close enough). With that, I was able to reproduce the issue and debug it. Below you can see a screenshot of the crashed state where the device hardfaulted shortly after attempting to schedule a TWI operation.

    I did some further digging, and it seems the device has a timeout of only 5 set two places in the variable "TWITimeout". When this timeout is hit the device is not able to recover correctly. Simply setting this timeout to 50 instead of 5 seems to have resolved the issue for me. I don't see a reason it needs to be as low as 5, so you can try to experiment with this value to find the lowest stable value.

    (A note, I would recommend putting this number in a define rather than having a number hardcoded in two places)

    Best regards,
    Rune Holmgren

  • Thanks for that Rune.  A timeout of 5 is equal to 2.5 ms, which is enough time for 100 bytes on the I2C running at 400KHz (if I'm not mistaken).  That seems like plenty of time to complete a single byte read (of course there's a couple of bytes of overhead and the slave can delay the return value but I haven't seen anything on the order of a millisecond...)

    That said, I agree that I can't trigger the fault with a longer delay. 

    I'd like to look at this some more because I'm fairly certain that I had this problem without hitting my timeout function in my application code.  I'll get back to you in a few days.

Related