nrfx_err_t nrfx_twim_xfer(nrfx_twim_t           const * p_instance,
                          nrfx_twim_xfer_desc_t const * p_xfer_desc,
                          uint32_t                      flags)
{
    NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx,
                                     p_xfer_desc->primary_length,
                                     p_xfer_desc->secondary_length));

    nrfx_err_t err_code = NRFX_SUCCESS;
    twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];

    // TXRX and TXTX transfers are supported only in non-blocking mode.
    NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)));
    NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXTX)));

    NRFX_LOG_INFO("Transfer type: %s.", TRANSFER_TO_STR(p_xfer_desc->type));
    NRFX_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.",
                  p_xfer_desc->primary_length,
                  p_xfer_desc->secondary_length);
    NRFX_LOG_DEBUG("Primary buffer data:");
    NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_primary_buf,
                           p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf[0]));
    NRFX_LOG_DEBUG("Secondary buffer data:");
    NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_secondary_buf,
                           p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf[0]));

    err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->p_twim, p_xfer_desc, flags);
    NRFX_LOG_WARNING("Function: %s, error code: %s.",
                     __func__,
                     NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}
Exemplo n.º 2
0
void nrfx_adc_irq_handler(void)
{
    if (m_cb.p_buffer == NULL)
    {
        nrf_adc_event_clear(NRF_ADC_EVENT_END);
        NRFX_LOG_DEBUG("Event: %s.",NRFX_LOG_ERROR_STRING_GET(NRF_ADC_EVENT_END));
        nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
        nrf_adc_disable();
        nrfx_adc_evt_t evt;
        evt.type = NRFX_ADC_EVT_SAMPLE;
        evt.data.sample.sample = (nrf_adc_value_t)nrf_adc_result_get();
        NRFX_LOG_DEBUG("ADC data:");
        NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)(&evt.data.sample.sample), sizeof(nrf_adc_value_t));
        m_cb.state = NRFX_DRV_STATE_INITIALIZED;
        m_cb.event_handler(&evt);
    }
    else if (adc_sample_process())
    {
        NRFX_LOG_DEBUG("Event: %s.", NRFX_LOG_ERROR_STRING_GET(NRF_ADC_EVENT_END));
        nrf_adc_int_disable(NRF_ADC_INT_END_MASK);
        nrfx_adc_evt_t evt;
        evt.type = NRFX_ADC_EVT_DONE;
        evt.data.done.p_buffer = m_cb.p_buffer;
        evt.data.done.size     = m_cb.size;
        m_cb.state = NRFX_DRV_STATE_INITIALIZED;
        NRFX_LOG_DEBUG("ADC data:");
        NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)m_cb.p_buffer, m_cb.size * sizeof(nrf_adc_value_t));
        m_cb.event_handler(&evt);
    }
}
Exemplo n.º 3
0
void nrfx_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl)
{
    NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON);
    nrf_qdec_task_trigger(NRF_QDEC_TASK_READCLRACC);

    *p_acc    = (int16_t)nrf_qdec_accread_get();
    *p_accdbl = (int16_t)nrf_qdec_accdblread_get();

    NRFX_LOG_DEBUG("Accumulators data, ACC register:");
    NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_acc, sizeof(p_acc[0]));
    NRFX_LOG_DEBUG("Accumulators data, ACCDBL register:");
    NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_accdbl, sizeof(p_accdbl[0]));
}
Exemplo n.º 4
0
void nrfx_clock_irq_handler(void)
{
    if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED))
    {
        nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED));
        nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK);

#if defined(USE_WORKAROUND_FOR_ANOMALY_201)
        if (!m_clock_cb.hfclk_started)
        {
            m_clock_cb.hfclk_started = true;
            m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLK_STARTED);
        }
#else
        m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLK_STARTED);
#endif
    }
    if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED))
    {
        nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED));
        nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK);

        m_clock_cb.event_handler(NRFX_CLOCK_EVT_LFCLK_STARTED);
    }
#if CALIBRATION_SUPPORT
    if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO))
    {
        nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_CTTO));
        nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK);

        m_clock_cb.event_handler(NRFX_CLOCK_EVT_CTTO);
    }

    if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE))
    {
#if defined(USE_WORKAROUND_FOR_ANOMALY_192)
        *(volatile uint32_t *)0x40000C34 = 0x00000000;
#endif
        nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_DONE));
        nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK);
        m_clock_cb.cal_state = CAL_STATE_IDLE;
        m_clock_cb.event_handler(NRFX_CLOCK_EVT_CAL_DONE);
    }
#endif // CALIBRATION_SUPPORT
}
uint32_t nrfx_pwm_complex_playback(nrfx_pwm_t const * const p_instance,
                                   nrf_pwm_sequence_t const * p_sequence_0,
                                   nrf_pwm_sequence_t const * p_sequence_1,
                                   uint16_t                   playback_count,
                                   uint32_t                   flags)
{
    pwm_control_block_t * p_cb  = &m_cb[p_instance->drv_inst_idx];
    NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
    NRFX_ASSERT(playback_count > 0);
    NRFX_ASSERT(nrfx_is_in_ram(p_sequence_0->values.p_raw));
    NRFX_ASSERT(nrfx_is_in_ram(p_sequence_1->values.p_raw));

    nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence_0);
    nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence_1);
    nrf_pwm_loop_set(p_instance->p_registers, playback_count);

    uint32_t shorts_mask;
    if (flags & NRFX_PWM_FLAG_STOP)
    {
        shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK;
    }
    else if (flags & NRFX_PWM_FLAG_LOOP)
    {
        shorts_mask = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK;
    }
    else
    {
        shorts_mask = 0;
    }
    nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask);

    NRFX_LOG_INFO("Function: %s, sequence 0 length: %d.",
                  __func__,
                  p_sequence_0->length);
    NRFX_LOG_INFO("Function: %s, sequence 1 length: %d.",
                  __func__,
                  p_sequence_1->length);
    NRFX_LOG_DEBUG("Sequence 0 data:");
    NRFX_LOG_HEXDUMP_DEBUG(p_sequence_0->values.p_raw,
                           p_sequence_0->length * sizeof(uint16_t));
    NRFX_LOG_DEBUG("Sequence 1 data:");
    NRFX_LOG_HEXDUMP_DEBUG(p_sequence_1->values.p_raw,
                           p_sequence_1->length * sizeof(uint16_t));
    return start_playback(p_instance, p_cb, flags, NRF_PWM_TASK_SEQSTART0);
}
Exemplo n.º 6
0
nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance,
                        uint8_t const *     p_data,
                        size_t              length)
{
    uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
    NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
    NRFX_ASSERT(p_data);
    NRFX_ASSERT(length > 0);

    nrfx_err_t err_code;

    if (nrfx_uart_tx_in_progress(p_instance))
    {
        err_code = NRFX_ERROR_BUSY;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }
    p_cb->tx_buffer_length = length;
    p_cb->p_tx_buffer      = p_data;
    p_cb->tx_counter       = 0;
    p_cb->tx_abort         = false;

    NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
    NRFX_LOG_DEBUG("Tx data:");
    NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
                           p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));

    err_code = NRFX_SUCCESS;

    nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY);
    nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTTX);

    tx_byte(p_instance->p_reg, p_cb);

    if (p_cb->handler == NULL)
    {
        if (!tx_blocking(p_instance->p_reg, p_cb))
        {
            // The transfer has been aborted.
            err_code = NRFX_ERROR_FORBIDDEN;
        }
        else
        {
            // Wait until the last byte is completely transmitted.
            while (!nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_TXDRDY))
            {}
            nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX);
        }
        p_cb->tx_buffer_length = 0;
    }

    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}
Exemplo n.º 7
0
void nrfx_rng_irq_handler(void)
{
    nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY);

    uint8_t rng_value = nrf_rng_random_value_get();

    m_rng_hndl(rng_value);

    NRFX_LOG_DEBUG("Event: NRF_RNG_EVENT_VALRDY.");
}
static void comp_execute_handler(nrf_comp_event_t event, uint32_t event_mask)
{
    if (nrf_comp_event_check(event) && nrf_comp_int_enable_check(event_mask))
    {
        nrf_comp_event_clear(event);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(event));

        m_comp_event_handler(event);
    }
}
Exemplo n.º 9
0
static void irq_handler(NRF_RTC_Type * p_reg,
                        uint32_t       instance_id,
                        uint32_t       channel_count)
{
    uint32_t i;
    uint32_t int_mask = (uint32_t)NRF_RTC_INT_COMPARE0_MASK;
    nrf_rtc_event_t event = NRF_RTC_EVENT_COMPARE_0;

    for (i = 0; i < channel_count; i++)
    {
        if (nrf_rtc_int_is_enabled(p_reg,int_mask) && nrf_rtc_event_pending(p_reg,event))
        {
            nrf_rtc_event_disable(p_reg,int_mask);
            nrf_rtc_int_disable(p_reg,int_mask);
            nrf_rtc_event_clear(p_reg,event);
            NRFX_LOG_DEBUG("Event: %s, instance id: %lu.", EVT_TO_STR(event), instance_id);
            m_handlers[instance_id]((nrfx_rtc_int_type_t)i);
        }
        int_mask <<= 1;
        event    = (nrf_rtc_event_t)((uint32_t)event + sizeof(uint32_t));
    }
    event = NRF_RTC_EVENT_TICK;
    if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_TICK_MASK) &&
        nrf_rtc_event_pending(p_reg, event))
    {
        nrf_rtc_event_clear(p_reg, event);
        NRFX_LOG_DEBUG("Event: %s, instance id: %lu.", EVT_TO_STR(event), instance_id);
        m_handlers[instance_id](NRFX_RTC_INT_TICK);
    }

    event = NRF_RTC_EVENT_OVERFLOW;
    if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_OVERFLOW_MASK) &&
        nrf_rtc_event_pending(p_reg, event))
    {
        nrf_rtc_event_clear(p_reg,event);
        NRFX_LOG_DEBUG("Event: %s, instance id: %lu.", EVT_TO_STR(event), instance_id);
        m_handlers[instance_id](NRFX_RTC_INT_OVERFLOW);
    }
}
Exemplo n.º 10
0
void nrfx_clock_irq_handler(void)
{
    if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED))
    {
        nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED));
        nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK);

        m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLK_STARTED);
    }
    if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED))
    {
        nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED));
        nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK);

        m_clock_cb.event_handler(NRFX_CLOCK_EVT_LFCLK_STARTED);
    }
#if CALIBRATION_SUPPORT
    if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO))
    {
        nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_CTTO));
        nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK);

        m_clock_cb.event_handler(NRFX_CLOCK_EVT_CTTO);
    }

    if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE))
    {
        nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_DONE));
        nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK);
        m_clock_cb.cal_state = CAL_STATE_IDLE;
        m_clock_cb.event_handler(NRFX_CLOCK_EVT_CAL_DONE);
    }
#endif // CALIBRATION_SUPPORT
}
Exemplo n.º 11
0
void nrfx_qdec_irq_handler(void)
{
    nrfx_qdec_event_t event;
    if ( nrf_qdec_event_check(NRF_QDEC_EVENT_SAMPLERDY) &&
         nrf_qdec_int_enable_check(NRF_QDEC_INT_SAMPLERDY_MASK) )
    {
        nrf_qdec_event_clear(NRF_QDEC_EVENT_SAMPLERDY);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_SAMPLERDY));

        event.type = NRF_QDEC_EVENT_SAMPLERDY;
        event.data.sample.value = (int8_t)nrf_qdec_sample_get();
        m_qdec_event_handler(event);
    }

    if ( nrf_qdec_event_check(NRF_QDEC_EVENT_REPORTRDY) &&
         nrf_qdec_int_enable_check(NRF_QDEC_INT_REPORTRDY_MASK) )
    {
        nrf_qdec_event_clear(NRF_QDEC_EVENT_REPORTRDY);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_REPORTRDY));

        event.type = NRF_QDEC_EVENT_REPORTRDY;

        event.data.report.acc    = (int16_t)nrf_qdec_accread_get();
        event.data.report.accdbl = (uint16_t)nrf_qdec_accdblread_get();
        m_qdec_event_handler(event);
    }

    if ( nrf_qdec_event_check(NRF_QDEC_EVENT_ACCOF) &&
         nrf_qdec_int_enable_check(NRF_QDEC_INT_ACCOF_MASK) )
    {
        nrf_qdec_event_clear(NRF_QDEC_EVENT_ACCOF);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_ACCOF));

        event.type = NRF_QDEC_EVENT_ACCOF;
        m_qdec_event_handler(event);
    }
}
Exemplo n.º 12
0
uint32_t nrfx_pwm_simple_playback(nrfx_pwm_t const * const p_instance,
                                  nrf_pwm_sequence_t const * p_sequence,
                                  uint16_t                   playback_count,
                                  uint32_t                   flags)
{
    pwm_control_block_t * p_cb  = &m_cb[p_instance->drv_inst_idx];
    NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
    NRFX_ASSERT(playback_count > 0);
    NRFX_ASSERT(nrfx_is_in_ram(p_sequence->values.p_raw));

    // To take advantage of the looping mechanism, we need to use both sequences
    // (single sequence can be played back only once).
    nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence);
    nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence);
    bool odd = (playback_count & 1);
    nrf_pwm_loop_set(p_instance->p_registers,
        (playback_count / 2) + (odd ? 1 : 0));

    uint32_t shorts_mask;
    if (flags & NRFX_PWM_FLAG_STOP)
    {
        shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK;
    }
    else if (flags & NRFX_PWM_FLAG_LOOP)
    {
        shorts_mask = odd ? NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK
                          : NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK;
    }
    else
    {
        shorts_mask = 0;
    }
    nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask);

    NRFX_LOG_INFO("Function: %s, sequence length: %d.",
                  __func__,
                  p_sequence->length);
    NRFX_LOG_DEBUG("Sequence data:");
    NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence->values.p_raw,
                           p_sequence->length * sizeof(uint16_t));
    return start_playback(p_instance, p_cb, flags,
        odd ? NRF_PWM_TASK_SEQSTART1 : NRF_PWM_TASK_SEQSTART0);
}
Exemplo n.º 13
0
static void uart_irq_handler(NRF_UART_Type *        p_uart,
                             uart_control_block_t * p_cb)
{
    if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) &&
        nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR))
    {
        nrfx_uart_event_t event;
        nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR);
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_UART_EVENT_ERROR));
        nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
                                     NRF_UART_INT_MASK_ERROR);
        if (!p_cb->rx_enabled)
        {
            nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
        }
        event.type                   = NRFX_UART_EVT_ERROR;
        event.data.error.error_mask  = nrf_uart_errorsrc_get_and_clear(p_uart);
        event.data.error.rxtx.bytes  = p_cb->rx_buffer_length;
        event.data.error.rxtx.p_data = p_cb->p_rx_buffer;

        // Abort transfer.
        p_cb->rx_buffer_length = 0;
        p_cb->rx_secondary_buffer_length = 0;

        p_cb->handler(&event,p_cb->p_context);
    }
    else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) &&
             nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY))
    {
        rx_byte(p_uart, p_cb);
        if (p_cb->rx_buffer_length == p_cb->rx_counter)
        {
            if (p_cb->rx_secondary_buffer_length)
            {
                uint8_t * p_data     = p_cb->p_rx_buffer;
                size_t    rx_counter = p_cb->rx_counter;

                // Switch to secondary buffer.
                p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length;
                p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer;
                p_cb->rx_secondary_buffer_length = 0;
                p_cb->rx_counter = 0;
                rx_done_event(p_cb, rx_counter, p_data);
            }
            else
            {
                if (!p_cb->rx_enabled)
                {
                    nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX);
                }
                nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY |
                                             NRF_UART_INT_MASK_ERROR);
                p_cb->rx_buffer_length = 0;
                rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
            }
        }
    }

    if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
    {
        if (p_cb->tx_counter < p_cb->tx_buffer_length &&
            !p_cb->tx_abort)
        {
            tx_byte(p_uart, p_cb);
        }
        else
        {
            nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY);
            if (p_cb->tx_buffer_length)
            {
                tx_done_event(p_cb, p_cb->tx_buffer_length);
            }
        }
    }

    if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO))
    {
        nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO);

        // RXTO event may be triggered as a result of abort call. In th
        if (p_cb->rx_enabled)
        {
            nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX);
        }
        if (p_cb->rx_buffer_length)
        {
            p_cb->rx_buffer_length = 0;
            rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer);
        }
    }
}
Exemplo n.º 14
0
nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance,
                         uint8_t const *      p_data,
                         size_t               length)
{
    uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];
    NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED);
    NRFX_ASSERT(p_data);
    NRFX_ASSERT(length > 0);
    NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length));

    nrfx_err_t err_code;

    // EasyDMA requires that transfer buffers are placed in DataRAM,
    // signal error if the are not.
    if (!nrfx_is_in_ram(p_data))
    {
        err_code = NRFX_ERROR_INVALID_ADDR;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    if (nrfx_uarte_tx_in_progress(p_instance))
    {
        err_code = NRFX_ERROR_BUSY;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }
    p_cb->tx_buffer_length = length;
    p_cb->p_tx_buffer      = p_data;

    NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length);
    NRFX_LOG_DEBUG("Tx data:");
    NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer,
                           p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0]));

    err_code = NRFX_SUCCESS;

    nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
    nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
    nrf_uarte_tx_buffer_set(p_instance->p_reg, p_cb->p_tx_buffer, p_cb->tx_buffer_length);
    nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTTX);

    if (p_cb->handler == NULL)
    {
        bool endtx;
        bool txstopped;
        do
        {
            endtx     = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX);
            txstopped = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED);
        }
        while ((!endtx) && (!txstopped));

        if (txstopped)
        {
            err_code = NRFX_ERROR_FORBIDDEN;
        }
        p_cb->tx_buffer_length = 0;
    }

    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}
Exemplo n.º 15
0
static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb)
{

#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
    /* Handle only workaround case. Can be used without TWIM handler in IRQs. */
    if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
    {
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
        nrf_twim_int_disable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
        if (p_twim->FREQUENCY == 0)
        {
            // Set enable to zero to reset TWIM internal state.
            nrf_twim_disable(p_twim);
            nrf_twim_enable(p_twim);

            // Set proper frequency.
            nrf_twim_frequency_set(p_twim, p_cb->bus_frequency);
            twim_list_enable_handle(p_twim, p_cb->flags);

            // Start proper transmission.
            nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
            return;
        }
    }
#endif

    NRFX_ASSERT(p_cb->handler);

    if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
    {
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
        NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
        if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
        {
            nrf_twim_int_disable(p_twim, p_cb->int_mask);
            p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK;
            nrf_twim_int_enable(p_twim, p_cb->int_mask);

            nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
            nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
            return;
        }
    }

    nrfx_twim_evt_t event;

    if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
    {
        NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED));
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
        event.xfer_desc = p_cb->xfer_desc;
        if (p_cb->error)
        {

            event.xfer_desc.primary_length = (p_cb->xfer_desc.type == NRFX_TWIM_XFER_RX) ?
                nrf_twim_rxd_amount_get(p_twim) : nrf_twim_txd_amount_get(p_twim);
            event.xfer_desc.secondary_length = (p_cb->xfer_desc.type == NRFX_TWIM_XFER_TXRX) ?
                nrf_twim_rxd_amount_get(p_twim) : nrf_twim_txd_amount_get(p_twim);

        }
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX);
        if (!p_cb->repeated || p_cb->error)
        {
            nrf_twim_shorts_set(p_twim, 0);
            p_cb->int_mask = 0;
            nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
        }
    }
    else
    {
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
        NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED));
        if (p_cb->xfer_desc.type == NRFX_TWIM_XFER_TX)
        {
            event.xfer_desc = p_cb->xfer_desc;
            if (!p_cb->repeated)
            {
                nrf_twim_shorts_set(p_twim, 0);
                p_cb->int_mask = 0;
                nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
            }
        }
        else
        {
            nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
            p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
            nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
            nrf_twim_int_enable(p_twim, p_cb->int_mask);
            nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
            nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
            return;
        }
    }

    uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim);
    if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK)
    {
        event.type = NRFX_TWIM_EVT_ADDRESS_NACK;
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_ADDRESS_NACK));
    }
    else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK)
    {
        event.type = NRFX_TWIM_EVT_DATA_NACK;
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DATA_NACK));
    }
    else
    {
        event.type = NRFX_TWIM_EVT_DONE;
        NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DONE));
    }

    if (!p_cb->repeated)
    {
        p_cb->busy = false;
    }
    p_cb->handler(&event, p_cb->p_context);
}
Exemplo n.º 16
0
__STATIC_INLINE nrfx_err_t twim_xfer(twim_control_block_t        * p_cb,
                                     NRF_TWIM_Type               * p_twim,
                                     nrfx_twim_xfer_desc_t const * p_xfer_desc,
                                     uint32_t                      flags)
{
    nrfx_err_t err_code = NRFX_SUCCESS;
    nrf_twim_task_t  start_task = NRF_TWIM_TASK_STARTTX;
    nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED;

    if (!nrfx_is_in_ram(p_xfer_desc->p_primary_buf))
    {
        err_code = NRFX_ERROR_INVALID_ADDR;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }
    /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */
    nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK);
    if (p_cb->busy)
    {
        nrf_twim_int_enable(p_twim, p_cb->int_mask);
        err_code = NRFX_ERROR_BUSY;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }
    else
    {
        p_cb->busy = ((NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER & flags) ||
                      (NRFX_TWIM_FLAG_REPEATED_XFER & flags)) ? false: true;
    }

    p_cb->xfer_desc = *p_xfer_desc;
    p_cb->repeated = (flags & NRFX_TWIM_FLAG_REPEATED_XFER) ? true : false;
    nrf_twim_address_set(p_twim, p_xfer_desc->address);

    nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
    nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);

    twim_list_enable_handle(p_twim, flags);
    switch (p_xfer_desc->type)
    {
    case NRFX_TWIM_XFER_TXTX:
        NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_REPEATED_XFER));
        NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_HOLD_XFER));
        NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER));
        if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf))
        {
            err_code = NRFX_ERROR_INVALID_ADDR;
            NRFX_LOG_WARNING("Function: %s, error code: %s.",
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }
        nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX);
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX);
        while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED))
        {}
        NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED));
        nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
        p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
        break;
    case NRFX_TWIM_XFER_TXRX:
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
        if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf))
        {
            err_code = NRFX_ERROR_INVALID_ADDR;
            NRFX_LOG_WARNING("Function: %s, error code: %s.",
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }
        nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length);
        nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK |
                                    NRF_TWIM_SHORT_LASTRX_STOP_MASK);
        p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
        break;
    case NRFX_TWIM_XFER_TX:
        nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
        if (NRFX_TWIM_FLAG_TX_NO_STOP & flags)
        {
            nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK);
            p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK;
            nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);
            evt_to_wait = NRF_TWIM_EVENT_SUSPENDED;
        }
        else
        {
            nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK);
            p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
        }
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
        break;
    case NRFX_TWIM_XFER_RX:
        nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length);
        nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK);
        p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK;
        start_task = NRF_TWIM_TASK_STARTRX;
        nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
        break;
    default:
        err_code = NRFX_ERROR_INVALID_PARAM;
        break;
    }

    if (!(flags & NRFX_TWIM_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRFX_TWIM_XFER_TXTX))
    {
        nrf_twim_task_trigger(p_twim, start_task);
    }

    if (p_cb->handler)
    {
        if (flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER)
        {
            p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK;
        }
        nrf_twim_int_enable(p_twim, p_cb->int_mask);

#if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
        if ((flags & NRFX_TWIM_FLAG_HOLD_XFER) && ((p_xfer_desc->type == NRFX_TWIM_XFER_TX) ||
                                                   (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX)))
        {
            p_cb->flags = flags;
            twim_list_enable_handle(p_twim, 0);
            p_twim->FREQUENCY = 0;
            nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED);
            nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK);
        }
#endif
    }
    else
    {
        while (!nrf_twim_event_check(p_twim, evt_to_wait))
        {
            if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
            {
                NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR));
                nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);
                nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
                nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);
                evt_to_wait = NRF_TWIM_EVENT_STOPPED;
            }
        }

        uint32_t errorsrc =  nrf_twim_errorsrc_get_and_clear(p_twim);

        p_cb->busy = false;

        if (errorsrc)
        {
            err_code = twi_process_error(errorsrc);
        }
    }
    return err_code;
}