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

TWI demo code on nRF51-DK resets

I'm testing out twi_master_using_app_twi example code on the nRF51-DK.

It appears to wite on the twi bus as expected but the nRF51 resets after executing

// Initialize sensors.
APP_ERROR_CHECK(app_twi_perform(&m_app_twi, lm75b_init_transfers, LM75B_INIT_TRANSFER_COUNT, NULL));

Any ideas?

Thanks,

  • If your device resets after the line you posted, this is likely because app_twi_perform() returned an error code. If you define DEBUG in your project or Makefile, your device should instead enter a eternal loop in the app_error_handler(). Using a debugger you can retrieve the error code which may indicate what has gone wrong.

    (The introduction to error handling in nRF5 projects is worth a read if you are inexperienced in debugging Nordic's products.)

  • I think I discovered the problem.

    nrf_drv_config.h needs to be edited even if you provide a config to nrf_drv_twi_init()

    #define TWI0_ENABLED 1
    
    #if (TWI0_ENABLED == 1)
    #define TWI0_CONFIG_FREQUENCY    NRF_TWI_FREQ_100K
    #define TWI0_CONFIG_SCL          24
    #define TWI0_CONFIG_SDA          25
    #define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
    
    #define TWI0_INSTANCE_INDEX      0
    #endif
    

    Since in nrf_drv_twi.c there is the following:

    #if (TWI0_ENABLED == 1)
    void SPI0_TWI0_IRQHandler(void)
    {
        nrf_drv_twi_int_handler(NRF_TWI0, TWI0_INSTANCE_INDEX);
    }
    #endif // (TWI0_ENABLED == 1)
    
    #if (TWI1_ENABLED == 1)
    void SPI1_TWI1_IRQHandler(void)
    {
        nrf_drv_twi_int_handler(NRF_TWI1, TWI1_INSTANCE_INDEX);
    }
    #endif // (TWI1_ENABLED == 1)
    

    It would appear that an interrupt handler would not exist otherwise, and depending on the startup code the nRF51 may then be lost in space.

    With those changes in place, this seems to do the right thing:

    #include "app_twi.h"
    #include "twi.h"
    #include "nrf_drv_config.h"
    #include "nrf_drv_twi.h"
    
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(0);
    
    void twi_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_twi_init(&m_twi, 0, 0, NULL);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    
        uint8_t reg[] = {0,0};
    
        err_code = nrf_drv_twi_tx(&m_twi, 0x70, reg, 1, true);
        err_code = nrf_drv_twi_rx(&m_twi, 0x70, reg, sizeof(reg), false);
        APP_ERROR_CHECK(err_code);
    }
    

    I'm using SDK v10 + s110

    image description

Related