void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint) { (void)hint; twi_info_t *twi_info = TWI_INFO(obj); if (twi_info->active) { return; } twi_info->active = true; twi_info->events = 0; twi_info->handler = (void (*)(void))handler; twi_info->evt_mask = event; twi_info->tx_length = tx_length; twi_info->tx = tx; twi_info->rx_length = rx_length; twi_info->rx = rx; twi_info->stop = stop; NRF_TWI_Type *twi = m_twi_instances[TWI_IDX(obj)]; nrf_twi_event_clear(twi, NRF_TWI_EVENT_TXDSENT); nrf_twi_event_clear(twi, NRF_TWI_EVENT_RXDREADY); nrf_twi_event_clear(twi, NRF_TWI_EVENT_STOPPED); nrf_twi_event_clear(twi, NRF_TWI_EVENT_SUSPENDED); nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); (void)nrf_twi_errorsrc_get_and_clear(twi); nrf_twi_address_set(twi, twi_address(address)); nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); // TX only, or TX + RX (after a repeated start). if (tx_length > 0) { nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTTX); nrf_twi_txd_set(twi, *(twi_info->tx)); ++(twi_info->tx); // RX only. } else if (rx_length > 0) { start_asynch_rx(twi_info, twi); // Both 'tx_length' and 'rx_length' are 0 - this case may be used // to test if the slave is presentand ready for transfer (by just // sending the address and checking if it is acknowledged). } else { nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTTX); if (stop) { nrf_twi_task_trigger(twi, NRF_TWI_TASK_STOP); } else { nrf_twi_task_trigger(twi, NRF_TWI_TASK_SUSPEND); nrf_twi_int_enable(twi, NRF_TWI_INT_SUSPENDED_MASK); } twi_info->events |= I2C_EVENT_TRANSFER_COMPLETE; } nrf_twi_int_enable(twi, NRF_TWI_INT_TXDSENT_MASK | NRF_TWI_INT_RXDREADY_MASK | NRF_TWI_INT_STOPPED_MASK | NRF_TWI_INT_ERROR_MASK); }
static void start_twi_write(NRF_TWI_Type *twi, int address) { nrf_twi_event_clear(twi, NRF_TWI_EVENT_STOPPED); nrf_twi_event_clear(twi, NRF_TWI_EVENT_TXDSENT); nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); (void)nrf_twi_errorsrc_get_and_clear(twi); nrf_twi_shorts_set(twi, 0); nrf_twi_address_set(twi, twi_address(address)); nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTTX); }
static void start_twi_read(NRF_TWI_Type *twi, int address) { nrf_twi_event_clear(twi, NRF_TWI_EVENT_STOPPED); nrf_twi_event_clear(twi, NRF_TWI_EVENT_RXDREADY); nrf_twi_event_clear(twi, NRF_TWI_EVENT_ERROR); (void)nrf_twi_errorsrc_get_and_clear(twi); nrf_twi_shorts_set(twi, NRF_TWI_SHORT_BB_SUSPEND_MASK); nrf_twi_address_set(twi, twi_address(address)); nrf_twi_task_trigger(twi, NRF_TWI_TASK_RESUME); nrf_twi_task_trigger(twi, NRF_TWI_TASK_STARTRX); }
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { twi_info_t *twi_info = TWI_INFO(obj); nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; twi_info->transfer_finished = false; ret_code_t ret_code = nrf_drv_twi_tx(twi, twi_address(address), (uint8_t const *)data, length, (stop == 0)); if (ret_code != NRF_SUCCESS) { return 0; } while (!twi_info->transfer_finished) {} return nrf_drv_twi_data_count_get(twi); }
void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint) { (void)stop; (void)hint; if (i2c_active(obj)) { return; } if ((tx_length == 0) && (rx_length == 0)) { return; } twi_info_t *twi_info = TWI_INFO(obj); twi_info->events = 0; twi_info->handler = (void (*)(void))handler; twi_info->event_mask = event; uint8_t twi_addr = twi_address(address); nrf_drv_twi_t const *twi = &m_twi_instances[TWI_IDX(obj)]; if ((tx_length > 0) && (rx_length == 0)) { nrf_drv_twi_xfer_desc_t const xfer = NRF_DRV_TWI_XFER_DESC_TX(twi_addr, (uint8_t *)tx, tx_length); nrf_drv_twi_xfer(twi, &xfer, stop ? 0 : NRF_DRV_TWI_FLAG_TX_NO_STOP); } else if ((tx_length == 0) && (rx_length > 0)) { nrf_drv_twi_xfer_desc_t const xfer = NRF_DRV_TWI_XFER_DESC_RX(twi_addr, rx, rx_length); nrf_drv_twi_xfer(twi, &xfer, 0); } else if ((tx_length > 0) && (rx_length > 0)) { nrf_drv_twi_xfer_desc_t const xfer = NRF_DRV_TWI_XFER_DESC_TXRX(twi_addr, (uint8_t *)tx, tx_length, rx, rx_length); nrf_drv_twi_xfer(twi, &xfer, 0); } }