示例#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);
}
nrfx_err_t nrfx_pwm_init(nrfx_pwm_t const * const p_instance,
                         nrfx_pwm_config_t const * p_config,
                         nrfx_pwm_handler_t        handler)
{
    NRFX_ASSERT(p_config);

    nrfx_err_t err_code;

    pwm_control_block_t * p_cb  = &m_cb[p_instance->drv_inst_idx];

    if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
    {
        err_code = NRFX_ERROR_INVALID_STATE;
        NRFX_LOG_WARNING("Function: %s, error code: %s.",
                         __func__,
                         NRFX_LOG_ERROR_STRING_GET(err_code));
        return err_code;
    }

    p_cb->handler = handler;

    configure_pins(p_instance, p_config);

    nrf_pwm_enable(p_instance->p_registers);
    nrf_pwm_configure(p_instance->p_registers,
        p_config->base_clock, p_config->count_mode, p_config->top_value);
    nrf_pwm_decoder_set(p_instance->p_registers,
        p_config->load_mode, p_config->step_mode);

    nrf_pwm_shorts_set(p_instance->p_registers, 0);
    nrf_pwm_int_set(p_instance->p_registers, 0);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_LOOPSDONE);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND0);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND1);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_STOPPED);

    // The workaround for nRF52 Anomaly 109 "protects" DMA transfers by handling
    // interrupts generated on SEQEND0 and SEQEND1 events (this ensures that
    // the 64 MHz clock is ready when data for the next sequence to be played
    // is read). Therefore, the PWM interrupt must be enabled even if the event
    // handler is not used.
#if defined(USE_DMA_ISSUE_WORKAROUND)
    NRFX_IRQ_PRIORITY_SET(DMA_ISSUE_EGU_IRQn, p_config->irq_priority);
    NRFX_IRQ_ENABLE(DMA_ISSUE_EGU_IRQn);
#else
    if (p_cb->handler)
#endif
    {
        NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_instance->p_registers),
            p_config->irq_priority);
        NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_instance->p_registers));
    }

    p_cb->state = NRFX_DRV_STATE_INITIALIZED;

    err_code = NRFX_SUCCESS;
    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}
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);
}
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);
}
示例#5
0
ret_code_t nrf_drv_pwm_init(nrf_drv_pwm_t const * const p_instance,
                            nrf_drv_pwm_config_t const * p_config,
                            nrf_drv_pwm_handler_t        handler)
{
    ASSERT(p_config)
    pwm_control_block_t * p_cb  = &m_cb[p_instance->drv_inst_idx];

    if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    p_cb->handler = handler;

    configure_pins(p_instance, p_config);

    nrf_pwm_enable(p_instance->p_registers);
    nrf_pwm_configure(p_instance->p_registers,
        p_config->base_clock, p_config->count_mode, p_config->top_value);
    nrf_pwm_decoder_set(p_instance->p_registers,
        p_config->load_mode, p_config->step_mode);

    nrf_pwm_shorts_set(p_instance->p_registers, 0);
    nrf_pwm_int_set(p_instance->p_registers, 0);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_LOOPSDONE);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND0);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND1);
    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_STOPPED);

    if (p_cb->handler)
    {
        nrf_drv_common_irq_enable(nrf_drv_get_IRQn(p_instance->p_registers),
            p_config->irq_priority);
    }

    p_cb->state = NRF_DRV_STATE_INITIALIZED;

    return NRF_SUCCESS;
}
示例#6
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);
}