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.

  • 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,

      Here are a couple of pictures of the fault in action.  I'll try to pin it down better, but from the pictures you can see that we had a TWIM interrupt and are scheduling the next transaction.  However, the next (current) transaction points to a read descriptor on the stack, which is corrupted, as you can see by the TWI cfg.  I believe a couple of weeks ago I was able to catch a "blocking" twi_perform that actually completed a different transaction when it returned.  That's why it seems to me that the perform waited on a transaction that was already in the queue, leaving the transaction I wanted to wait on (and which had descriptors on the stack) in the queue.  Then when this interrupt occurs, and the descriptor gets pulled from the queue, my blocking register read function has already gone out of scope.   That's all just my hypothesis.  I'll try to get some more concrete evidence, or something more repeatable.  I'm also working on this issue and can probably use that test setup for both issues.

        

  • HI Rune,

      I've been delayed slightly - will get back to this in about a week.

  • 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

Related