TWI Manager - TWI delayed after start condition

Hello,

I've used the TWI manager to implemented a burst of transfers to and from two devices on a single bus. Basically it waits for both devices to give a data-ready interrupt via GPIOTE, and then it schedules that block of transactions (36 in total). It runs reliably, but when I examine the bus, it looks like there is sometimes a large delay (several ms) between the start condition and the start of the transfer.

Here is a wide screenshot of the lines (so you can see how it generally runs smoothly) with the anomaly at the center:

Here's a zoomed in shot of the anomaly, with 2.26ms of delay shown:

This is especially problematic because after the interrupt, there is only 2.5ms before the data registers on the sensor will start to get overwritten (unfortunately there is no FIFO or SPI interface, otherwise this wouldn't be an issue).

My understanding is that using the TWI manager in scheduled/background mode is supposed to be non-blocking. It's clear that the transaction does start fairly quickly, but what else could be interfering with the operation like this? I do have a SPI bus configured as well (but it's not running currently, and it's using the SPI2 instance, and this manager is using TWI0, so there should be no interference). If it matters, I'm using SDK 17.1 and the latest S113 softdevice.

Thank you!

TWI Config below

#define I2C_MAX_PENDING_TRANSACTIONS    35
NRF_TWI_MNGR_DEF(m_nrf_twi0_mngr, I2C_MAX_PENDING_TRANSACTIONS, 0);

ret_code_t err_code;
    nrf_drv_twi_config_t config = {
            .scl                = SCL1_PIN_NUMBER,
            .sda                = SDA1_PIN_NUMBER,
            .frequency          = NRF_DRV_TWI_FREQ_400K,
            .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
            .clear_bus_init     = true
    };

    err_code = nrf_twi_mngr_init(&m_nrf_twi0_mngr, &config);
    APP_ERROR_CHECK(err_code);

Parents
  • Hi,

    Which SDK version are you using?

    Is the TWI instance configured to use EasyDMA? This is configured through the following configs in your sdk_config.h file:

    // <q> TWI0_USE_EASY_DMA  - Use EasyDMA (if present)
    #ifndef TWI0_USE_EASY_DMA
    #define TWI0_USE_EASY_DMA 0
    #endif
    
    
    // <q> TWI1_USE_EASY_DMA  - Use EasyDMA (if present)
    #ifndef TWI1_USE_EASY_DMA
    #define TWI1_USE_EASY_DMA 0
    #endif

    TWI will be more affected by other interrupts in your application, as you need to update the data pointer for each byte being sent/received. However, according to the transfer diagrams, both TWI and TWIM should send the address and send/receive at least one byte before there is any pause in transmission (TWI/TWIM).

    Which GPIOs are you using for SCL/SDA? Have you tried different pins?

    Are you seeing this behavior with other TWI/I2C slaves, or could it be the slave doing some clock stretching, etc? Would be a bit strange if this happens before the address is written to the bus.

    Can you share the full logic trace file that shows this happening?

    Best regards,
    Jørgen

  • Hi Jørgen,

    I'm using SDK 17.1 and Easy DMA is enabled in sdk_config.h (though each transfer loaded into the queue has its own static pointers to the data to send and received). Is it possible the softdevice is causing this interruption? I know that's theoretically possible, but it seems odd that it would cause an initiated TWI transfer to stall.

    I'm using pins 0.11 (SDA) and 0.12 (SCL). I could try different pins, but it would result in some fly-wires that might degrade performance.

    Regarding clock stretching, I don't have other devices to immediately test with this board, but as you mentioned it happens before the address (I find this is always the case), which seems to rule out the slave stretching the clock. The slave devices are TI FDC2214, for the record. I generally expect predicable behavior from TI chips.

    I'm attempting to attach the full Saleae trace file, but this isn't letting me upload it in this comment. I'll see if I can add it to the original post.

    [Edit]: It appears to only let me upload a CSV. The trace file is much smaller and probably easier to work with, but it won't allow me to upload it. Let me know if I can send it over somehow.

    digital.csv

    Channels 0 and 1 are SCL and SDA, respectively. Channels 2 and 3 are the interrupts that trigger the burst transfer.

    Thanks for your help,

    Dylan

Reply
  • Hi Jørgen,

    I'm using SDK 17.1 and Easy DMA is enabled in sdk_config.h (though each transfer loaded into the queue has its own static pointers to the data to send and received). Is it possible the softdevice is causing this interruption? I know that's theoretically possible, but it seems odd that it would cause an initiated TWI transfer to stall.

    I'm using pins 0.11 (SDA) and 0.12 (SCL). I could try different pins, but it would result in some fly-wires that might degrade performance.

    Regarding clock stretching, I don't have other devices to immediately test with this board, but as you mentioned it happens before the address (I find this is always the case), which seems to rule out the slave stretching the clock. The slave devices are TI FDC2214, for the record. I generally expect predicable behavior from TI chips.

    I'm attempting to attach the full Saleae trace file, but this isn't letting me upload it in this comment. I'll see if I can add it to the original post.

    [Edit]: It appears to only let me upload a CSV. The trace file is much smaller and probably easier to work with, but it won't allow me to upload it. Let me know if I can send it over somehow.

    digital.csv

    Channels 0 and 1 are SCL and SDA, respectively. Channels 2 and 3 are the interrupts that trigger the burst transfer.

    Thanks for your help,

    Dylan

Children
No Data
Related