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

twi_scanner only detects I2C devices in debug mode

Hello all

I copied the peripheral>twi_scanner example and adapted it to the nRF52833 chip on our custom board.

I have 4 chips (0x0b, 0x48, 0x52, 0x68) that use I2C on the custom board.
If I simply connect / erase / download the program, "no device" is found
If I debug (F5) the program and step through, the devices are found.

What am I missing?

The way I will go about it is the following:

Attempt 1) Compare debug and release configurations, adapt if needed
Attempt 2) Build the twi_scanner code step by step, see if any command is "board specific" and cannot be adapted from nRF52840/nRF52833 to our own board

Any other ideas?

Thank you, in advance, for your time and help.
Tell me if there is anything I can share (preprocessor directives, code, details about the custom board...)

Have a great Friday

Jerome

Parents Reply Children
  • Hi Kenneth

    Thank you for your time and help

    So essentially, the sensors are discovered but something else is wrong.

    I used my picoscope 2000 and here's what I get (with UART/putty and without), both while debugging (F5) or uploading to the target.

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    
    #include "nrf_delay.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /* TWI instance ID. */
    #if TWI0_ENABLED
    #define TWI_INSTANCE_ID     0
    #elif TWI1_ENABLED
    #define TWI_INSTANCE_ID     1
    #endif
    
     /* Number of possible TWI addresses. */
     #define TWI_ADDRESSES      127
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    
    /**
     * @brief TWI initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_config = {
           .scl                = DH_SCL,
           .sda                = DH_SDA,
           .frequency          = NRF_DRV_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = true
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_config, NULL, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        ret_code_t err_code;
        uint8_t address;
        uint8_t sample_data;
        uint8_t old_sample_data;
        bool detected_device = false;
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("TWI scanner started.");
        twi_init();
    
        for (address = 1; address <= TWI_ADDRESSES; address++)
        {
            err_code = nrf_drv_twi_rx(&m_twi, address, &sample_data, sizeof(sample_data));
            nrf_delay_ms(100);
            NRF_LOG_INFO("Error code: %d", err_code);
            if (err_code == NRF_SUCCESS)
            {
                detected_device = true;
                NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
            }
            old_sample_data = sample_data;
        }
    
        if (!detected_device)
        {
        NRF_LOG_INFO("No device was found.");
        }
    
        while (true)
        {
          /* Empty loop. */
        }
    }
    
    /** @} */
    

  • Are you sure that the nrf_delay_ms() works as expected when not debugging? Can it be that the compiler may optimize it away?

    A read sequence typically is:

    [START] device_address + read bit, device_register [re-START] device_address, sample_data [STOP]

    Though in your case it seems you are consistenly receiving NRF_ERROR_DRV_TWI_ERR_ANACK, which means "NACK received after sending the address in polling mode".

    So this is indeed strange.

Related