Hello. I'm trying to understand twi_sensor sample code on nRF51. (nRF51_SDK_10.0.0_dc26b5e\examples\peripheral\twi_sensor)
I have a trouble finding where the function twi_handler() in main.c is called.
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
ret_code_t err_code;
static sample_t m_sample;
switch(p_event->type)
{
case NRF_DRV_TWI_RX_DONE:
read_data(&m_sample);
m_xfer_done = true;
break;
case NRF_DRV_TWI_TX_DONE:
if(m_set_mode_done != true)
{
m_set_mode_done = true;
return;
}
m_xfer_done = false;
/* Read 4 bytes from the specified address. */
err_code = nrf_drv_twi_rx(&m_twi_mma_7660, MMA7660_ADDR, (uint8_t*)&m_sample, sizeof(m_sample), false);
APP_ERROR_CHECK(err_code);
break;
default:
break;
}
}
I know that the address of twi_handler() is passed to nrf_drv_twi_init() and stored in m_handlers. And I guess this handler should be called somewhere in twi_transfer() inside nrf_drv_twi_tx().
- nrf_drv_twi_tx() of main.c:
void MMA7660_set_mode(void)
{
ret_code_t err_code;
/* Writing to MMA7660_REG_MODE "1" enables the accelerometer. */
uint8_t reg[2] = {MMA7660_REG_MODE, ACTIVE_MODE};
err_code = nrf_drv_twi_tx(&m_twi_mma_7660, MMA7660_ADDR, reg, sizeof(reg), false);
APP_ERROR_CHECK(err_code);
while(m_set_mode_done == false);
}
- twi_transfer() of nrf_drv_twi.c:
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;
}
Can you help me find where this handler is called? It will be very helpful for me to get into the next step. Thanks.