Hello,
I am using an nrf52832-based ble chip and try to communicate with cap1293 touch sensor. I'm using SDK 15.3 and started off from the twi_sensor peripheral example.
Running this code, which tries to write a register and then read another one, leads to a fatal error and system reset, but when I tried debugging the code and run it step by step, the code worked. After some experimentation with delays I managed to make it work by inserting a delay (line 28) in nrfx_twim_xfer() function located in nrfx_twim.c. Do you have any idea what kind of problem could cause this issue?
int main(void)
{
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("\r\nTWI sensor example started.");
nrf_gpio_cfg_output(18);
//NRF_LOG_FLUSH();
twi_init();
nrf_delay_ms(100);;
NRF_LOG_INFO("TWI Initialized");
uint8_t data[1] = {0x02};
NRF_LOG_INFO("device address is %x", CAP1293);
twi_write(CAP1293, 0x1F, data, 1); // write a value to a register
twi_read(CAP1293, MANUFACTURE_ID, data, 1); // read manufacturer id which is '5D'
NRF_LOG_INFO("Manufacturer ID is %x",data[0]);
}
void twi_init (void)
{
ret_code_t err_code;
const nrf_drv_twi_config_t twi_cap1293_config = {
.scl = SCL_PIN,
.sda = SDA_PIN,
.frequency = NRF_DRV_TWI_FREQ_100K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = false
};
err_code = nrf_drv_twi_init(&m_twi, &twi_cap1293_config, twi_handler, NULL);
APP_ERROR_CHECK(err_code);
nrf_drv_twi_enable(&m_twi);
}
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
switch (p_event->type)
{
case NRF_DRV_TWI_EVT_DONE:
if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX){
NRF_LOG_INFO("TWI TX DONE");
}
else if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX){
NRF_LOG_INFO("TWI RX DONE");
}
else if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX){
NRF_LOG_INFO("TWI TXRX DONE");
}
else if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX){
NRF_LOG_INFO("TWI TXTX DONE");
}
m_xfer_done = true;
case NRFX_TWIM_EVT_ADDRESS_NACK:
NRF_LOG_INFO("Received NACK after sending address!");
break;
case NRFX_TWIM_EVT_DATA_NACK:
NRF_LOG_INFO("Received NACK after sending data.");
break;
default:
break;
}
}int8_t twi_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t length){
uint32_t err_code;
uint8_t buffer[2] = {0};
buffer[0] = reg_addr;
memcpy(&buffer[1], data, length);
m_xfer_done = false;
NRF_LOG_INFO("buffer and size of buffer %x, %d", &buffer, sizeof(buffer));
err_code = nrf_drv_twi_tx(&m_twi, dev_addr, buffer, sizeof(buffer), false);
APP_ERROR_CHECK(err_code);
while(m_xfer_done == false);
return err_code;
}
int8_t twi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t length)
{
uint32_t err_code;
m_xfer_done = false;
err_code = nrf_drv_twi_tx(&m_twi, dev_addr, ®_addr, sizeof(reg_addr), true);
APP_ERROR_CHECK(err_code);
while (m_xfer_done == false);
m_xfer_done = false;
err_code = nrf_drv_twi_rx(&m_twi, dev_addr, data, length);
APP_ERROR_CHECK(err_code);
while (m_xfer_done == false);
return err_code;
}
nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance,
nrfx_twim_xfer_desc_t const * p_xfer_desc,
uint32_t flags)
{
NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx,
p_xfer_desc->primary_length,
p_xfer_desc->secondary_length));
nrfx_err_t err_code = NRFX_SUCCESS;
twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
// TXRX and TXTX transfers are supported only in non-blocking mode.
NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)));
NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXTX)));
NRFX_LOG_INFO("Transfer type: %s.", TRANSFER_TO_STR(p_xfer_desc->type));
NRFX_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.",
p_xfer_desc->primary_length,
p_xfer_desc->secondary_length);
NRFX_LOG_DEBUG("Primary buffer data:");
NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_primary_buf,
p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf[0]));
NRFX_LOG_DEBUG("Secondary buffer data:");
NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_secondary_buf,
p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf[0]));
err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->p_twim, p_xfer_desc, flags);
nrf_delay_ms(100); // edited by me!! solves fatal error issue.
NRFX_LOG_WARNING("Function: %s, error code: %s.",
__func__,
NRFX_LOG_ERROR_STRING_GET(err_code));
return err_code;
}