Beispiel #1
0
void nrf_drv_pwm_complex_playback(nrf_drv_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];
    ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
    ASSERT(playback_count > 0);
    ASSERT(nrf_drv_is_in_RAM(p_sequence_0->values.p_raw));
    ASSERT(nrf_drv_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 & NRF_DRV_PWM_FLAG_STOP)
    {
        shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK;
    }
    else if (flags & NRF_DRV_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);

    start_playback(p_instance, p_cb, flags, NRF_PWM_TASK_SEQSTART0);
}
Beispiel #2
0
ret_code_t nrf_drv_spis_buffers_set(nrf_drv_spis_t const * const  p_instance,
                                    const uint8_t * p_tx_buffer,
                                    uint8_t   tx_buffer_length,
                                    uint8_t * p_rx_buffer,
                                    uint8_t   rx_buffer_length)
{
    spis_cb_t * p_cb = &m_cb[p_instance->instance_id];
    uint32_t err_code;

    VERIFY_PARAM_NOT_NULL(p_rx_buffer);
    VERIFY_PARAM_NOT_NULL(p_tx_buffer);

    // EasyDMA requires that transfer buffers are placed in Data RAM region;
    // signal error if they are not.
    if ((p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_tx_buffer)) ||
        (p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_rx_buffer)))
    {
        err_code = NRF_ERROR_INVALID_ADDR;
        NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
        return err_code;
    }

    switch (p_cb->spi_state)
    {
        case SPIS_STATE_INIT:
        case SPIS_XFER_COMPLETED:
        case SPIS_BUFFER_RESOURCE_CONFIGURED:
            p_cb->tx_buffer      = p_tx_buffer;
            p_cb->rx_buffer      = p_rx_buffer;
            p_cb->tx_buffer_size = tx_buffer_length;
            p_cb->rx_buffer_size = rx_buffer_length;
            err_code             = NRF_SUCCESS;

            spis_state_change(p_instance->p_reg, p_cb, SPIS_BUFFER_RESOURCE_REQUESTED);
            break;

        case SPIS_BUFFER_RESOURCE_REQUESTED:
            err_code = NRF_ERROR_INVALID_STATE;
            break;

        default:
            // @note: execution of this code path would imply internal error in the design.
            err_code = NRF_ERROR_INTERNAL;
            break;
    }

    NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
    return err_code;
}
Beispiel #3
0
ret_code_t nrf_drv_qspi_read(void *   p_rx_buffer,
                             size_t   rx_buffer_length,
                             uint32_t src_address)
{
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
    ASSERT(p_rx_buffer != NULL);

    if (!nrf_drv_is_in_RAM(p_rx_buffer))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    nrf_qspi_read_buffer_set(NRF_QSPI, p_rx_buffer, rx_buffer_length, src_address);
    return qspi_task_perform(NRF_QSPI_TASK_READSTART);
}
Beispiel #4
0
ret_code_t nrf_drv_qspi_write(void const * p_tx_buffer,
                              size_t       tx_buffer_length,
                              uint32_t     dst_address)
{
    ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED);
    ASSERT(p_tx_buffer != NULL);

    if (!nrf_drv_is_in_RAM(p_tx_buffer))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    nrf_qspi_write_buffer_set(NRF_QSPI, p_tx_buffer, tx_buffer_length, dst_address);
    return qspi_task_perform(NRF_QSPI_TASK_WRITESTART);

}
Beispiel #5
0
void nrf_drv_pwm_simple_playback(nrf_drv_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];
    ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
    ASSERT(playback_count > 0);
    ASSERT(nrf_drv_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 & NRF_DRV_PWM_FLAG_STOP)
    {
        shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK;
    }
    else if (flags & NRF_DRV_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);

    start_playback(p_instance, p_cb, flags, odd ? NRF_PWM_TASK_SEQSTART1
                                                : NRF_PWM_TASK_SEQSTART0);
}
Beispiel #6
0
ret_code_t nrf_drv_i2s_start(uint32_t * p_rx_buffer,
                             uint32_t * p_tx_buffer,
                             uint16_t   buffer_size,
                             uint8_t    flags)
{
    ASSERT((p_rx_buffer != NULL) || (p_tx_buffer != NULL));

    uint16_t buffer_half_size = buffer_size / 2;
    ASSERT(buffer_half_size != 0);

    VERIFY_MODULE_INITIALIZED();

    ret_code_t err_code;

    if ((p_rx_buffer != NULL) && !nrf_drv_is_in_RAM(p_rx_buffer))
    {
        err_code = NRF_ERROR_INVALID_ADDR;
        NRF_LOG_WARNING("Function: %s, error code: %s.",
            (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    if ((p_tx_buffer != NULL) && !nrf_drv_is_in_RAM(p_tx_buffer))
    {
        err_code = NRF_ERROR_INVALID_ADDR;
        NRF_LOG_WARNING("Function: %s, error code: %s.",
            (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    // Initially we set up the peripheral to use the first half of each buffer,
    // then in 'I2S_IRQHandler' we will switch to the second half.
    nrf_i2s_transfer_set(NRF_I2S, buffer_half_size, p_rx_buffer, p_tx_buffer);

    m_cb.p_rx_buffer      = p_rx_buffer;
    m_cb.p_tx_buffer      = p_tx_buffer;
    m_cb.buffer_half_size = buffer_half_size;
    m_cb.just_started     = true;

    if ((flags & NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE) &&
        // [synchronized mode makes sense only when both RX and TX are enabled]
        (m_cb.p_rx_buffer != NULL) && (m_cb.p_tx_buffer != NULL))
    {
        m_cb.synchronized_mode = true;
        m_cb.rx_ready          = false;
        m_cb.tx_ready          = false;
    }
    else
    {
        m_cb.synchronized_mode = false;
    }

    nrf_i2s_enable(NRF_I2S);

    m_cb.state = NRF_DRV_STATE_POWERED_ON;

    if (m_cb.p_tx_buffer != NULL)
    {
        // Get from the application the first portion of data to be sent - we
        // need to have it in the transmit buffer before we start the transfer.
        // Unless the synchronized mode is active. In this mode we must wait
        // with this until the first portion of data is received, so here we
        // just make sure that there will be silence on the SDOUT line prior
        // to that moment.
        if (m_cb.synchronized_mode)
        {
            memset(m_cb.p_tx_buffer, 0,
                m_cb.buffer_half_size * sizeof(uint32_t));
        }
        else
        {
            m_cb.handler(NULL, m_cb.p_tx_buffer, m_cb.buffer_half_size);
        }
    }

    nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD);
    nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD);
    nrf_i2s_int_enable(NRF_I2S,
        NRF_I2S_INT_RXPTRUPD_MASK | NRF_I2S_INT_TXPTRUPD_MASK);
    nrf_i2s_task_trigger(NRF_I2S, NRF_I2S_TASK_START);

    err_code = NRF_SUCCESS;
    NRF_LOG_INFO("Function: %s, error code: %s.",
        (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}