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 stuck and blocked

Hi,

I'm connecting to a proximity sensor, IQS263 over TWI interface and having some weird problems.

I'm using the same code I used to connect with the Invensense MPU 9250 so I know that on the same platform, the same code works fine with no problems.

For the IQS263 part I need to pull a RDY line high (which I do via GPIO).

Then I just init the TWI in the standard manner and start trying to talk to the device.

It just seems to hang and tracing down through nrf_drv_twi.c it seems this never happens

        if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT))

if I look in function twi_x_start_transfer basically that it gets stuck here

        while (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, (uint8_t *)p_data, length, no_stop))
    {}

Note the first bit of code here is down in twi_transfer and appears to just never get a TXD sent...

I'm working remotely at the moment so I can't scope the part/TWI bus to check what's happening so it could likely be a HW issue as I said the TWI code runs on another board for a different device..

My configuration is like this

    static uint32_t twi_master_init(void)
{
    uint32_t err_code;
    const nrf_drv_twi_config_t config =
    {
        .scl                = PROXIMITY_I2C_SCL,
        .sda                = PROXIMITY_I2C_SDA,
        .frequency          = TWI0_CONFIG_FREQUENCY,
        .interrupt_priority = TWI0_CONFIG_IRQ_PRIORITY
    };
    
    err_code = nrf_drv_twi_init(&m_twi_master, &config, NULL /*twi_handler*/, NULL);
    APP_ERROR_CHECK(err_code);
    
    nrf_drv_twi_enable(&m_twi_master);
    
    RMLOG("I2C sensor is at address 0x%02X SCL is %u and SDA is %u",
          IQS263_ADDR,
          PROXIMITY_I2C_SCL,
          PROXIMITY_I2C_SDA);

And sending looks like this...

static int i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data)
{

    uint32_t err_code=0;
    
    if (!twi_inited) {
        return -1;
    }

    // We need to pull the RDY line low
    nrf_gpio_cfg_output(PROXIMITY_I2C_RDY);
    nrf_gpio_pin_clear(PROXIMITY_I2C_RDY);
    
    RMLOG("R[0x%02X]: A: 0x%02X L: %u", slave_addr, reg_addr, length);

    // Write the register we want to read
    err_code = nrf_drv_twi_tx(&m_twi_master, slave_addr, &reg_addr, 1, true);
    if (err_code != NRF_SUCCESS) {
        RMLOG("Failed to write register to read");
        return -1;
    }

    RMLOG("Going to read it");
    
    // Read it
    err_code = nrf_drv_twi_rx(&m_twi_master, slave_addr, data, length);
    if (err_code != NRF_SUCCESS) {
        RMLOG("Failed to read register");
    }
    else {
        RMLOG("First byte of response was 0x%02X", *data);
    }

    
    // Let it float high.. well, it should have a pull up high actually...
    nrf_gpio_pin_set(PROXIMITY_I2C_RDY);

    RMLOG("Finished");
    
    return 0;
    
}

Any help appreciated if someone has an idea off the top of their head...

Parents
  • Hi,

    If I understand you correctly you are using a GPIO on the nRF52 to pull down the RDY pin whenever you want to read data. However the way I read the datasheet, and after skimming through this IQS263 driver, that is not the way to go. I think the IQS263 is controlling the pin, pulling it low whenever it has new data available. What you should do is to set up an interrupt triggering on a negative edge on the RDY signal. When the interrupt is triggered you can read data.

    I think the datasheet is a little vague on this though, so I might be wrong.

  • It's a nice part, its got some crazy range for a capacitive prox pickup... best out of about 5 chips I tried.

    Plus works across the V range of the Nordic.. so its a nice tidy combo.

Reply Children
No Data
Related