I'm thinking of incorporating a TWI slave with nRF52832.
I'm using SDK 17.0.2.
I want to set up a register and read/write multiple bytes with TWI, but I don't know how to write the twis_event_handler process.
Are there any good samples?
I'm thinking of incorporating a TWI slave with nRF52832.
I'm using SDK 17.0.2.
I want to set up a register and read/write multiple bytes with TWI, but I don't know how to write the twis_event_handler process.
Are there any good samples?
Hi,
Please take a look at the TWIS driver.
There is also a sample implementation mentioned here: https://docs.nordicsemi.com/bundle/sdk_nrf5_v17.1.0/page/hardware_driver_twis_slave.html#twi_slave_asynchronous_mode:~:text=void%20twis_event_handler(nrf_drv_twis_evt_t%20const%20*%20const%20p_event)
Please also take a look at the TWIS implementation guide: https://devzone.nordicsemi.com/guides/nrf-connect-sdk-guides/b/peripherals/posts/twi-ic2-implementation-with-nrfx-twis-driver#mcetoc_1fc9idhsd3
Regards,
Priyanka
Thank you for the information.
Currently, I can read from the master, but write operations don't work properly because an NRFX_TWIS_EVT_GENERAL_ERROR occurs.
When I look with a protocol analyzer, I can see that ACKs are returned up to the slave address and register address, but no ACK is returned for data, and in the slave event, I can read the register address but not the data.
What do you think is the cause?
I've attached the source code for the current event handler.
void twis_event_handler(nrf_drv_twis_evt_t const * p_event)
{
static bool address_received = false;
switch (p_event->type)
{
case NRFX_TWIS_EVT_READ_REQ:
nrf_drv_twis_tx_prepare(&m_twis, &m_twi_register[m_register_address], TWI_BUFFER_SIZE - m_register_address);
NRF_LOG_INFO("Read request: register address = 0x%02X", m_register_address);
break;
case NRFX_TWIS_EVT_WRITE_REQ:
if (!address_received) {
NRF_LOG_INFO("Preparing to receive register address...");
nrf_drv_twis_rx_prepare(&m_twis, &m_register_address, 1);
} else {
NRF_LOG_INFO("Register address received: 0x%02X", m_register_address);
if (m_register_address < TWI_BUFFER_SIZE) {
NRF_LOG_INFO("Preparing to write data to register 0x%02X", m_register_address);
nrf_drv_twis_rx_prepare(&m_twis, &m_twi_register[m_register_address], TWI_BUFFER_SIZE - m_register_address);
} else {
NRF_LOG_ERROR("Invalid register address: 0x%02X", m_register_address);
}
}
break;
case NRFX_TWIS_EVT_WRITE_DONE:
if (!address_received) {
address_received = true;
NRF_LOG_INFO("Register address 0x%02X received", m_register_address);
} else {
address_received = false;
NRF_LOG_INFO("Data written to register 0x%02X: 0x%02X", m_register_address, m_twi_register[m_register_address]);
}
break;
case NRFX_TWIS_EVT_READ_DONE:
NRF_LOG_INFO("Read completed");
break;
case NRFX_TWIS_EVT_READ_ERROR:
NRF_LOG_ERROR("TWIS EVT READ ERROR");
break;
case NRFX_TWIS_EVT_WRITE_ERROR:
NRF_LOG_ERROR("TWIS EVT WRITE ERROR");
break;
case NRFX_TWIS_EVT_GENERAL_ERROR:
NRF_LOG_ERROR("TWIS EVT GENERAL ERROR");
break;
default:
break;
}
}Hi,
Could you try to prepare the data buffer earlier, in the NRFX_TWIS_EVT_WRITE_REQ phase, irrespective of whether the register address has been received?
You could also make sure that the nrf_drv_twis_rx_prepare() is called quickly enough for the data phase.
Because right now, if there’s a timing issue or race condition, the slave may not have the data buffer ready in time, causing the master to not receive an ACK for the data phase.
Regards,
Priyanka
Hi,
Could you try to prepare the data buffer earlier, in the NRFX_TWIS_EVT_WRITE_REQ phase, irrespective of whether the register address has been received?
You could also make sure that the nrf_drv_twis_rx_prepare() is called quickly enough for the data phase.
Because right now, if there’s a timing issue or race condition, the slave may not have the data buffer ready in time, causing the master to not receive an ACK for the data phase.
Regards,
Priyanka