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
  • I added TWI_SDA_READ() and TWI_SCL_READ() just before the if statement for testing. Found that if TWI_SDA_HIGH() and TWI_SCL_HIGH() are called in main() both SDA and SCL are read as high. But if these commands are removed from main() both SDA and SCL are read as low even though TWI_SDA_HIGH() and TWI_SCL_HIGH() are in twi_master_clear_bus just before the if statement.

    main()
    
          TWI_SDA_HIGH();						//+++ REQUIRED SO TWI_MASTER_INIT() PASSES
          TWI_SCL_HIGH();						//+++ REQUIRED SO TWI_MASTER_INIT() PASSES
    
          if (!twi_master_init())           // configure SCK, SDA pins
              while(1);                       // stay here if initialization fails
    
    twi_master_clear_bus()
    
        TWI_SDA_HIGH();
        TWI_SCL_HIGH();
        TWI_DELAY();
    
        sda = TWI_SDA_READ();
        scl = TWI_SCL_READ();
        if ((TWI_SDA_READ() == 1) && (TWI_SCL_READ() == 1))
        {
            bus_clear = true;
        }
        else
    
Reply
  • I added TWI_SDA_READ() and TWI_SCL_READ() just before the if statement for testing. Found that if TWI_SDA_HIGH() and TWI_SCL_HIGH() are called in main() both SDA and SCL are read as high. But if these commands are removed from main() both SDA and SCL are read as low even though TWI_SDA_HIGH() and TWI_SCL_HIGH() are in twi_master_clear_bus just before the if statement.

    main()
    
          TWI_SDA_HIGH();						//+++ REQUIRED SO TWI_MASTER_INIT() PASSES
          TWI_SCL_HIGH();						//+++ REQUIRED SO TWI_MASTER_INIT() PASSES
    
          if (!twi_master_init())           // configure SCK, SDA pins
              while(1);                       // stay here if initialization fails
    
    twi_master_clear_bus()
    
        TWI_SDA_HIGH();
        TWI_SCL_HIGH();
        TWI_DELAY();
    
        sda = TWI_SDA_READ();
        scl = TWI_SCL_READ();
        if ((TWI_SDA_READ() == 1) && (TWI_SCL_READ() == 1))
        {
            bus_clear = true;
        }
        else
    
Children
No Data
Related