This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

twi_master_clear_bus fails

Calling twi_master_clear_bus() always returns bus_clear = FALSE. The IF statement is always FALSE even though both SDA and SCL measure high. All 18 SCL's occur in the ELSE but it fails, also. This has worked in the past but recently began failing every time. I tried other previously working firmware versions and they all fail, also. No known events have occurred to cause a hardware failure.

static bool twi_master_clear_bus(void)

{ uint32_t twi_state; bool bus_clear; uint32_t clk_pin_config; uint32_t data_pin_config;

// Save and disable TWI hardware so software can take control over the pins.
twi_state        = NRF_TWI1->ENABLE;
NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;

clk_pin_config =
    NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER];
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] =
    (GPIO_PIN_CNF_SENSE_Disabled  << GPIO_PIN_CNF_SENSE_Pos)
  | (GPIO_PIN_CNF_DRIVE_S0D1    << GPIO_PIN_CNF_DRIVE_Pos)    // STD0, DISC1
  | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
  | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
  | (GPIO_PIN_CNF_DIR_Output    << GPIO_PIN_CNF_DIR_Pos);

data_pin_config =
    NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER];
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] =
    (GPIO_PIN_CNF_SENSE_Disabled  << GPIO_PIN_CNF_SENSE_Pos)
  | (GPIO_PIN_CNF_DRIVE_S0D1    << GPIO_PIN_CNF_DRIVE_Pos)    // STD0, DISC1
  | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
  | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
  | (GPIO_PIN_CNF_DIR_Output    << GPIO_PIN_CNF_DIR_Pos);

TWI_SDA_HIGH();
TWI_SCL_HIGH();
TWI_DELAY();

if ((TWI_SDA_READ() == 1) && (TWI_SCL_READ() == 1))
{
    bus_clear = true;
}
else
{
    uint_fast8_t i;
    bus_clear = false;

    // Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9
    // for slave to respond) to SCL line and wait for SDA come high.
    for (i=18; i--;)
    {
        TWI_SCL_LOW();
        TWI_DELAY();
        TWI_SCL_HIGH();
        TWI_DELAY();

        if (TWI_SDA_READ() == 1)
        {
            bus_clear = true;
            break;
        }
    }
}

NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = clk_pin_config;
NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER]  = data_pin_config;

NRF_TWI1->ENABLE = twi_state;

return bus_clear;

}

Parents
  • Hung Bui,

    Not exactly. After the 18 clocks TWI_SDA_READ() always returns 0 so bus_clear is 0 and the initialization fails. I just found that if TWI_SDA_HIGH() is called before twi_master_init() the initialization passes. But the peripheral (accelerometer) returns bad data (x always 0x10, y always 0x30, z always 0x50). Maybe this means the accelerometer is not responding properly and has failed? Past experience shows that the hardware is seldom the problem - the firmware usually the culprit.

Reply
  • Hung Bui,

    Not exactly. After the 18 clocks TWI_SDA_READ() always returns 0 so bus_clear is 0 and the initialization fails. I just found that if TWI_SDA_HIGH() is called before twi_master_init() the initialization passes. But the peripheral (accelerometer) returns bad data (x always 0x10, y always 0x30, z always 0x50). Maybe this means the accelerometer is not responding properly and has failed? Past experience shows that the hardware is seldom the problem - the firmware usually the culprit.

Children
No Data
Related