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;
}
}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