Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #5
0
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);
    }
}