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

How to solve twi "NRF_ERROR_INTERNAL"?

With a little research, I came to the probably erroneous conclusion that the "NRF_ERROR_INTERNAL" error I keep getting is likely caused by my not using a twi event handler.

So my questions: is using a twi handler a must? Or is it generally recommended (because it will save a lot of trouble, for example)

If it's not a must, or not really that recommended, how do I deal with this twi "NRF_ERROR_INTERNAL" error?

The reason I do not want to use a handler is that I don't want to complicate things, but it seems that it now has an opposite effect.

My code:

static const nrf_drv_twi_t m_twi_ms_5837 = NRF_DRV_TWI_INSTANCE(0);



void twi_init (void)  
{
ret_code_t err_code;
               
        const nrf_drv_twi_config_t twi_mma_7660_config = {
           .scl                = 19,
       .sda                = 20,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH
    };
    
    err_code = nrf_drv_twi_init(&m_twi_ms_5837, &twi_mma_7660_config, NULL, NULL);
    APP_ERROR_CHECK(err_code);
    
    nrf_drv_twi_enable(&m_twi_ms_5837);
}



uint32_t ms5837_cmd_read(uint8_t *data, uint8_t length, uint8_t register_address)
{
    		uint32_t err_code = nrf_drv_twi_tx(&m_twi_ms_5837, MS5837_TWI_ADDR, &register_address, 1, true);
	if (NRF_SUCCESS == err_code)
    err_code = nrf_drv_twi_rx(&m_twi_ms_5837, MS5837_TWI_ADDR, data, length, false);
	APP_ERROR_CHECK(err_code);
		return err_code;	
}		

#And the function that's giving the error mentioned in the title:

static ret_code_t twi_transfer(nrf_drv_twi_t const * const p_instance,
                               uint8_t                     address,
                               uint8_t const             * p_data,
                               uint32_t                    length,
                               bool                        xfer_pending,
                               bool                        is_tx)
{
    ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON);
    ASSERT(length > 0);

    control_block_t * p_cb = &m_cb[p_instance->instance_id];

    bool is_busy = false;
    CRITICAL_REGION_ENTER();
    if (p_cb->transfer_in_progress)
    {
        is_busy = true;
    }
    else
    {
        p_cb->transfer_in_progress = true;
    }
    CRITICAL_REGION_EXIT();
    if (is_busy)
    {
        return NRF_ERROR_BUSY;
    }

    transfer_t * p_transfer = &p_cb->transfer;
    p_transfer->address         = address;
    p_transfer->length          = (uint16_t)length;
    p_transfer->p_data          = (uint8_t *)p_data;
    p_transfer->count           = 0;
    p_transfer->xfer_pending    = xfer_pending;
    p_transfer->is_tx           = is_tx;
    p_transfer->error_condition = false;

    state_machine(p_instance, p_transfer->is_tx ? TX_ADDR_REQ : RX_ADDR_REQ);

    if (!m_handlers[p_instance->instance_id])
    {
        // blocking mode
        sm_evt_t evt = p_transfer->is_tx ? TX_DONE : RX_DONE;
        do
        {
            if (twi_action_wait(p_instance) == false)
            {
                nrf_twi_event_clear(p_instance->p_reg, NRF_TWI_EVENTS_ERROR);
                evt = ON_ERROR;
            }
            nrf_twi_event_clear(p_instance->p_reg, p_transfer->end_event);
            state_machine(p_instance, evt);

            if (p_transfer->error_condition)
            {
                p_cb->transfer_in_progress = false;
                return NRF_ERROR_INTERNAL;
            }
            }
            while (p_transfer->count < p_transfer->length);
        p_cb->transfer_in_progress = false;
    }
    return NRF_SUCCESS;
}

#Specifically :

  if (p_transfer->error_condition)
            {
                p_cb->transfer_in_progress = false;
                return NRF_ERROR_INTERNAL;
            }
Related