Пример #1
0
void nrf_drv_radio802154_swi_init(void)
{
    m_ntf_r_ptr = 0;
    m_ntf_w_ptr = 0;

    nrf_egu_int_enable(SWI_EGU,
                       NTF_INT |
                       TIMESLOT_EXIT_INT |
                       REQ_INT);

    NVIC_SetPriority(SWI_IRQn, NRF_DRV_RADIO802154_NOTIFICATION_SWI_PRIORITY);
    NVIC_ClearPendingIRQ(SWI_IRQn);
    NVIC_EnableIRQ(SWI_IRQn);
}
static uint32_t start_playback(nrfx_pwm_t const * const p_instance,
                               pwm_control_block_t * p_cb,
                               uint8_t               flags,
                               nrf_pwm_task_t        starting_task)
{
    p_cb->state = NRFX_DRV_STATE_POWERED_ON;
    p_cb->flags = flags;

    if (p_cb->handler)
    {
        // The notification about finished playback is by default enabled,
        // but this can be suppressed.
        // The notification that the peripheral has stopped is always enabled.
        uint32_t int_mask = NRF_PWM_INT_LOOPSDONE_MASK |
                            NRF_PWM_INT_STOPPED_MASK;

        // The workaround for nRF52 Anomaly 109 "protects" DMA transfers by
        // handling interrupts generated on SEQEND0 and SEQEND1 events (see
        // 'nrfx_pwm_init'), hence these events must be always enabled
        // to generate interrupts.
        // However, the user handler is called for them only when requested
        // (see 'irq_handler').
#if defined(USE_DMA_ISSUE_WORKAROUND)
        int_mask |= NRF_PWM_INT_SEQEND0_MASK | NRF_PWM_INT_SEQEND1_MASK;
#else
        if (flags & NRFX_PWM_FLAG_SIGNAL_END_SEQ0)
        {
            int_mask |= NRF_PWM_INT_SEQEND0_MASK;
        }
        if (flags & NRFX_PWM_FLAG_SIGNAL_END_SEQ1)
        {
            int_mask |= NRF_PWM_INT_SEQEND1_MASK;
        }
#endif
        if (flags & NRFX_PWM_FLAG_NO_EVT_FINISHED)
        {
            int_mask &= ~NRF_PWM_INT_LOOPSDONE_MASK;
        }

        nrf_pwm_int_set(p_instance->p_registers, int_mask);
    }
#if defined(USE_DMA_ISSUE_WORKAROUND)
    else
    {
        nrf_pwm_int_set(p_instance->p_registers,
            NRF_PWM_INT_SEQEND0_MASK | NRF_PWM_INT_SEQEND1_MASK);
    }
#endif

    nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_STOPPED);

    if (flags & NRFX_PWM_FLAG_START_VIA_TASK)
    {
        uint32_t starting_task_address =
            nrf_pwm_task_address_get(p_instance->p_registers, starting_task);

#if defined(USE_DMA_ISSUE_WORKAROUND)
        // To "protect" the initial DMA transfer it is required to start
        // the PWM by triggering the proper task from EGU interrupt handler,
        // it is not safe to do it directly via PPI.
        p_cb->starting_task_address = starting_task_address;
        nrf_egu_int_enable(DMA_ISSUE_EGU,
            nrf_egu_int_get(DMA_ISSUE_EGU, p_instance->drv_inst_idx));
        return (uint32_t)nrf_egu_task_trigger_address_get(DMA_ISSUE_EGU,
            p_instance->drv_inst_idx);
#else
        return starting_task_address;
#endif
    }

    nrf_pwm_task_trigger(p_instance->p_registers, starting_task);
    return 0;
}