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

How do I recover from a failed I2C write?

By design, the TI LP55231 LED driver IC will fail the TWI write of the reset register (0x3D). It's necessary to reset the IC in an edge use case. I'm using the nRF51822 HW TWI driver and cannot recover from this. The first write returns without error (NRF_SUCCESS). Successive TWI writes return with an internal error (NRF_ERROR_INTERNAL). Manually clearing the bus does not seem to work. Re-initializing the driver seems an extreme workaround. Is there a trick to this?

snip:

 data[0]=LP55231_RESET_REGISTER;
 data[1]=LP55231_RESET_VALUE;
 retcode = nrf_drv_twi_tx( &TWI_DRIVER, IC_ADDRESS, data, 2, false );
 APP_ERROR_CHECK( retcode );

nRF51822_xxAC/256/32/S130

  • Just skip APP_ERROR_CHECK and replace it with if statement, or if you really want to do this properly, define your own fault handler in this form: void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info). This essentially overrides the weakly defined app_error_fault_handler so you can define routine to handle specific error from your code.

    For example:

    /**
     * Function is implemented as weak so that it can be overwritten by custom application error handler
     * when needed.
     */
    void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
    {
        // On assert, the system can only recover with a reset.
    #ifndef DEBUG
        NVIC_SystemReset(); // Override this if you like, so it does not reboot
    #else
    
    #ifdef BSP_DEFINES_ONLY
        LEDS_ON(LEDS_MASK); // Only runs if you have Board Support Package with LEDs configured
    #else
        UNUSED_VARIABLE(bsp_indication_set(BSP_INDICATE_FATAL_ERROR));
        // This call can be used for debug purposes during application development.
        // @note CAUTION: Activating this code will write the stack to flash on an error.
        //                This function should NOT be used in a final product.
        //                It is intended STRICTLY for development/debugging purposes.
        //                The flash write will happen EVEN if the radio is active, thus interrupting
        //                any communication.
        //                Use with care. Uncomment the line below to use.
        //ble_debug_assert_handler(error_code, line_num, p_file_name);
    #endif // BSP_DEFINES_ONLY
    
        app_error_log(id, pc, info);
    //    app_error_save_and_stop(id, pc, info); // You may want to continue your code execution.
    
    #endif // DEBUG
    }
    
  • Thanks but that doesn't help. ALL successive writes fail with NRF_ERROR_INTERNAL after the initial problem.

  • Then you will have to uninit nrf_drv_twi, and init again. Do this in the error handler.

Related