nRF5 SDK v17.1.0
TWI transaction manager

The TWI transaction manager library provides functions to create and execute transactions consisting of one or more data transfers via the two-wire interface (TWI).

Transactions can be run in the background or in blocking mode:

Transactions can be requested from different contexts, including interrupt handlers. The library takes care of proper synchronization.

The TWI transaction manager library supports setting transactions with different hardware configurations. For example, if you want to connect slave devices to different pins, you can set up a transaction with parameter p_required_twi_cfg that points to the required hardware configuration. The TWI driver will be reinitialized every time the required configuration will differ from the one from previous transaction.

static nrf_drv_twi_config_t new_configuration =
{
.scl = ARDUINO_13_PIN,
.sda = ARDUINO_12_PIN,
.frequency = NRF_TWI_FREQ_400K,
.interrupt_priority = APP_IRQ_PRIORITY_LOW,
.clear_bus_init = false
};
static nrf_twi_mngr_transfer_t const transfers[] =
{
NRF_TWI_MNGR_WRITE(SLAVE_ADDR, &m_selectors[0], 1, NRF_TWI_MNGR_NO_STOP),
NRF_TWI_MNGR_READ(SLAVE_ADDR, m_master_buffer, sizeof(m_master_buffer), 0)
};
static nrf_twi_mngr_transaction_t transaction_1 =
{
.callback = transaction_callback,
.p_user_data = NULL,
.p_transfers = transfers,
.number_of_transfers = sizeof(transfers) / sizeof(transfers[0]),
.p_required_twi_cfg = NULL
};
static nrf_twi_mngr_transaction_t transaction_2 =
{
.callback = transaction_callback,
.p_user_data = NULL,
.p_transfers = transfers,
.number_of_transfers = sizeof(transfers) / sizeof(transfers[0]),
.p_required_twi_cfg = &new_configuration
};
static nrf_twi_mngr_transaction_t transaction_3 =
{
.callback = transaction_callback,
.p_user_data = NULL,
.p_transfers = transfers,
.number_of_transfers = sizeof(transfers) / sizeof(transfers[0]),
.p_required_twi_cfg = NULL
};
APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &transaction_1));
APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &transaction_2));
APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &transaction_3));

In the code above, the new_configuration is different from the default configuration. In this case, nrf_twi_mngr will schedule and execute transaction_1 and then schedule the other two transactions. However, before executing transaction_2, it will reinitialize TWI hardware with the given configuration. Then, again, before executing transaction_3, TWI hardware will be reinitialized to the default configuration.

You can suppress the generation of a stop condition for selected transfers. In this case, the following transfer will start with a repeated start condition. The following example code shows how to first write one byte (for example, an register address) and then read 4 bytes, without a stop condition in between. Additionally, setting p_required_twi_cfg to NULL will cause using the default hardware setup (the one passed while initializing nrf_twi_mngr instance):

static nrf_twi_mngr_transfer_t const transfers[] =
{
NRF_TWI_MNGR_WRITE(device_address, &register_address, 1, NRF_TWI_MNGR_NO_STOP),
NRF_TWI_MNGR_READ (device_address, p_buffer, 4, 0)
};
static nrf_twi_mngr_transaction_t const transaction =
{
.callback = transaction_callback,
.p_user_data = NULL,
.p_transfers = transfers,
.number_of_transfers = sizeof(transfers)/sizeof(transfers[0]),
.p_required_twi_cfg = NULL
};
APP_ERROR_CHECK(nrf_twi_mngr_schedule(&m_nrf_twi_mngr, &transaction));

The API for this module is available here: TWI transaction manager. See the TWI Transaction Manager Example for a usage example.


Documentation feedback | Developer Zone | Subscribe | Updated