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

TWI scan no device found

Hello, I've been trying to setup TWI with 3 sensors and so far I had no luck (custom board). Here's the situation:

1) 3 sensors are connected to nrf52820, SCL to P0.15, SDA to P0.14

2) External pull up resistors, 10k

3) Sensors are powered up using P0.08

On startup, I'm setting P0.08 to high, which powers up the sensors. After that I initialize and start TWI using the following code (mostly from TWI scan example):

#define SDA_PIN NRF_GPIO_PIN_MAP(0, 14)
#define SCL_PIN NRF_GPIO_PIN_MAP(0, 15)

void twi_init(void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
        .scl = SCL_PIN,
        .sda = SDA_PIN,
        .frequency = NRF_DRV_TWI_FREQ_100K,
        .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
        .clear_bus_init = false};

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);

    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

Next, with a delay, I start scanning for I2C devices, using the code below (mostly from TWI scan example):

void scan(void)
{
    ret_code_t err_code;
    uint8_t address;
    uint8_t sample_data;
    bool detected_device = false;

    for (address = 1; address <= TWI_ADDRESSES; address++)
    {
        err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
        if (err_code == NRF_SUCCESS)
        {
            detected_device = true;
        }
    }


    set_scan_characteristic_value(detected_device);
}

But no i2c devices are detected. `nrf_drv_twi_rx` always returns `NRF_ERROR_INTERNAL`. Checking SCL and SDA after TWI init, SCL is high, and SDA is low. Unfortunately I don't have an oscilloscope to check the SCL. Can you please guide me to the right direction? 

I'm using NRF5 SDK 17.0.2

Parents
  • Checking SCL and SDA after TWI init, SCL is high, and SDA is low.

    Bad sign. On an idle I²C bus, both lines need to be high, or rather pulled up by the pullup resistor.

    Sensors are powered up using P0.08

    Those GPIO pins are current limited - do you reach the voltage for correct sensor operation?

  • Bad sign. On an idle I²C bus, both lines need to be high, or rather pulled up by the pullup resistor.

    I have pull up resistors on both SCL and SDA. Do I need to disable internal pull ups for this to function correctly? I've tried

    nrf_gpio_cfg_input(SDA_PIN, NRF_GPIO_PIN_NOPULL);
    NRF_GPIO->PIN_CNF[SDA_PIN] |= (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos);
    NRF_GPIO->PIN_CNF[SDA_PIN] |= ((GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos));
    
    nrf_gpio_cfg_input(SCL_PIN, NRF_GPIO_PIN_NOPULL);
    NRF_GPIO->PIN_CNF[SCL_PIN] |= (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos);
    NRF_GPIO->PIN_CNF[SCL_PIN] |= ((GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos));

    And also

    #define TWI_PIN_INIT(_pin) nrf_gpio_cfg((_pin),                     \
                                            NRF_GPIO_PIN_DIR_INPUT,     \
                                            NRF_GPIO_PIN_INPUT_CONNECT, \
                                            NRF_GPIO_PIN_NOPULL,        \
                                            NRF_GPIO_PIN_S0D1,          \
                                            NRF_GPIO_PIN_NOSENSE)

    And also

    #define SCL_PIN_INIT_CONF     ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
                                  | (GPIO_PIN_CNF_DRIVE_S0D1     << GPIO_PIN_CNF_DRIVE_Pos) \
                                  | (GPIO_PIN_CNF_PULL_Pullup    << GPIO_PIN_CNF_PULL_Pos)  \
                                  | (GPIO_PIN_CNF_INPUT_Connect  << GPIO_PIN_CNF_INPUT_Pos) \
                                  | (GPIO_PIN_CNF_DIR_Input      << GPIO_PIN_CNF_DIR_Pos))

    but they didn't make any difference.

    Those GPIO pins are current limited - do you reach the voltage for correct sensor operation?

    The sensors I'm using require microamps to function, and I've set GPIO_PIN_CNF_DRIVE_H0H1 on P0.08. The output voltage is 2.98 which is in range for the sensors.

Reply
  • Bad sign. On an idle I²C bus, both lines need to be high, or rather pulled up by the pullup resistor.

    I have pull up resistors on both SCL and SDA. Do I need to disable internal pull ups for this to function correctly? I've tried

    nrf_gpio_cfg_input(SDA_PIN, NRF_GPIO_PIN_NOPULL);
    NRF_GPIO->PIN_CNF[SDA_PIN] |= (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos);
    NRF_GPIO->PIN_CNF[SDA_PIN] |= ((GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos));
    
    nrf_gpio_cfg_input(SCL_PIN, NRF_GPIO_PIN_NOPULL);
    NRF_GPIO->PIN_CNF[SCL_PIN] |= (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos);
    NRF_GPIO->PIN_CNF[SCL_PIN] |= ((GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos));

    And also

    #define TWI_PIN_INIT(_pin) nrf_gpio_cfg((_pin),                     \
                                            NRF_GPIO_PIN_DIR_INPUT,     \
                                            NRF_GPIO_PIN_INPUT_CONNECT, \
                                            NRF_GPIO_PIN_NOPULL,        \
                                            NRF_GPIO_PIN_S0D1,          \
                                            NRF_GPIO_PIN_NOSENSE)

    And also

    #define SCL_PIN_INIT_CONF     ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
                                  | (GPIO_PIN_CNF_DRIVE_S0D1     << GPIO_PIN_CNF_DRIVE_Pos) \
                                  | (GPIO_PIN_CNF_PULL_Pullup    << GPIO_PIN_CNF_PULL_Pos)  \
                                  | (GPIO_PIN_CNF_INPUT_Connect  << GPIO_PIN_CNF_INPUT_Pos) \
                                  | (GPIO_PIN_CNF_DIR_Input      << GPIO_PIN_CNF_DIR_Pos))

    but they didn't make any difference.

    Those GPIO pins are current limited - do you reach the voltage for correct sensor operation?

    The sensors I'm using require microamps to function, and I've set GPIO_PIN_CNF_DRIVE_H0H1 on P0.08. The output voltage is 2.98 which is in range for the sensors.

Children
No Data
Related