This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

TWI is not working with SoftDevice

This seems to be a common problem after searching in this forum. In my case, I need to read from an I2C slave and send the data out in BLE. I have made it work without SoftDevice using this library code http://pastebin.com/qLLAy418 . However, it failed to work with SoftDevice. I also tried with another version which has SoftDevice knobs http://pastebin.com/AV6cQK0x. It doesn't work either. I also tried other code github.com/.../twi_hw_master.c that someone claimed to work (devzone.nordicsemi.com/.../), but it doesn't work for me. Can anyone provide any suggestion on this problem?

  • What does 'doesn't work' mean? Crashes, sends erratically, goes to the hardfault handler, the board bursts into flames, what?

    The TWI handler in the library works with the softdevice quite happily, as it should, they are entirely separate things.

    So what exactly happens when you use the nordic TWI driver from the SDK for your board with and without the softdevice?

  • I used two versions of TWI drivers from nRF51 SDK8.0.0. One is "twi_sw_master.c", and the other is "twi_hw_master.c". For "twi_sw_master.c", when I read it from an I2C slave (with SoftDevice), the code got stopped the while (TWI_SCL_READ() == 0) line in this function:

    static bool twi_master_wait_while_scl_low(void)
    {
    #if TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE != 0
        uint32_t volatile timeout_counter = TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE;
    #endif
        // Pull SCL high just in case if something left it low
        TWI_SCL_HIGH();
        TWI_DELAY();
        while (TWI_SCL_READ() == 0)
        {.....}
    }
    

    I can set TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE to nonzero value to avoid this, but return status is not success. For "twi_hw_master.c", read will just return false.

    If you have a working TWI example with SoftDevice, could you please share?

  • well I wouldn't use the sw one with the softdevice, use the hw one. And if it's returning false, why is it returning false? Is it timing out (timeout --> 0 ) or returning an error?

    I see by the way that twi_hw driver STILL uses the PPI channel to trigger the STOP or SUSPEND task from the BB event. If you have any hardware newer than revision 1 you can change that to use the TWI SHORTS instead, that old PPI hack was just because SHORTS didn't work on the first revision. I wish they'd update that.

    The only possible difference between having a softdevice and not is that the TWI hardware might be suspended for longer before the byte is read and the TWI continues. That shouldn't matter, it just stretches the clock so the master you're reading from should wait before sending the next byte. Does the TWI device you're reading from support clock stretching, it should, it's part of the spec.

  • Thanks for your comment. I also tried the one with TWI SHORTS (although I don't know what SHORTS means here) from here in this post. However, it still has the same behavior with the twi_master_hw.c: it just time out and return false status. Another thing I did was taking some waveform with a logic analyzer. The waveform associated with twi_master_hw.c is like this, which has oscillating SDA but no clock. The I2C slave I was using was MPR121. I didn't find clock stretching information on its datasheet. But my impression was clock stretching was part of I2C protocol, and was not uncommon.

  • I can't make any sense of that logic analyser trace at all. For a start the trace marked data is way too regular, that looks like a clock, and the other one never changes, if it was data it would at least have to go low at some point for a start bit. And if anything was clock stretching the clock line would stay low, not high.

    I think you need to start over and capture a full trace without the softdevice and a full trace with it and see if/where they start to differ. If it works without the softdevice I'd start putting in some delays in the code to simulate the times the softdevice is busy during which the TWI should be in SUSPEND mode (holding SCL low) until the byte is read and it's RESUMEd at which point it should read the next one. That should tell you if the peripheral you're trying to read from is doing the right thing. TWI is a hardware peripheral, SD should make no difference.

Related