Ejemplo n.º 1
0
static void spis_irq_handler(NRF_SPIS_Type * p_spis, spis_cb_t * p_cb)
{
    // @note: as multiple events can be pending for processing, the correct event processing order
    // is as follows:
    // - SPI semaphore acquired event.
    // - SPI transaction complete event.

    // Check for SPI semaphore acquired event.
    if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_ACQUIRED))
    {
        nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED);
        NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_ACQUIRED));

        switch (p_cb->spi_state)
        {
            case SPIS_BUFFER_RESOURCE_REQUESTED:
                nrf_spis_tx_buffer_set(p_spis, (uint8_t *)p_cb->tx_buffer, p_cb->tx_buffer_size);
                nrf_spis_rx_buffer_set(p_spis, (uint8_t *)p_cb->rx_buffer, p_cb->rx_buffer_size);

                nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_RELEASE);

                spis_state_change(p_spis, p_cb, SPIS_BUFFER_RESOURCE_CONFIGURED);
                break;

            default:
                // No implementation required.
                break;
        }
    }

    // Check for SPI transaction complete event.
    if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_END))
    {
        nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END);
        NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_END));

        switch (p_cb->spi_state)
        {
            case SPIS_BUFFER_RESOURCE_CONFIGURED:
                spis_state_change(p_spis, p_cb, SPIS_XFER_COMPLETED);
                break;

            default:
                // No implementation required.
                break;
        }
    }
}
Ejemplo n.º 2
0
ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const  p_instance,
                             nrf_drv_spis_config_t const * p_config,
                             nrf_drv_spis_event_handler_t  event_handler)
{
    spis_cb_t * p_cb = &m_cb[p_instance->instance_id];
    
    NRF_SPIS_Type * p_spis = p_instance->p_reg;

    if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED)
    {
        return NRF_ERROR_INVALID_STATE;
    }
    if (p_config == NULL)
    {
        p_config = &m_default_config[p_instance->instance_id];
    }
    if ((uint32_t)p_config->mode > (uint32_t)NRF_DRV_SPIS_MODE_3)
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    if (!event_handler)
    {
        return NRF_ERROR_NULL;
    }
#if PERIPHERAL_RESOURCE_SHARING_ENABLED
    if (nrf_drv_common_per_res_acquire(p_spis,
            m_irq_handlers[p_instance->instance_id]) != NRF_SUCCESS)
    {
        return NRF_ERROR_BUSY;
    }
#endif

    // Configure the SPI pins for input.
    uint32_t mosi_pin;
    uint32_t miso_pin;
    
    if (p_config->miso_pin != NRF_DRV_SPIS_PIN_NOT_USED)
    {
        nrf_gpio_cfg(p_config->miso_pin,
                    NRF_GPIO_PIN_DIR_INPUT,
                    NRF_GPIO_PIN_INPUT_CONNECT,
                    NRF_GPIO_PIN_NOPULL,
                    p_config->miso_drive,
                    NRF_GPIO_PIN_NOSENSE);
        miso_pin = p_config->miso_pin;
    }
    else
    {
        miso_pin = NRF_SPIS_PIN_NOT_CONNECTED;
    }
    
    if (p_config->mosi_pin != NRF_DRV_SPIS_PIN_NOT_USED)
    {
        nrf_gpio_cfg(p_config->mosi_pin,
                     NRF_GPIO_PIN_DIR_INPUT,
                     NRF_GPIO_PIN_INPUT_CONNECT,
                     NRF_GPIO_PIN_NOPULL,
                     NRF_GPIO_PIN_S0S1,
                     NRF_GPIO_PIN_NOSENSE);
        mosi_pin = p_config->mosi_pin;
    }
    else
    {
        mosi_pin = NRF_SPIS_PIN_NOT_CONNECTED;
    }
    
    nrf_gpio_cfg(p_config->csn_pin,
                 NRF_GPIO_PIN_DIR_INPUT,
                 NRF_GPIO_PIN_INPUT_CONNECT,
                 p_config->csn_pullup,
                 NRF_GPIO_PIN_S0S1,
                 NRF_GPIO_PIN_NOSENSE);
    
    nrf_gpio_cfg(p_config->sck_pin,
                 NRF_GPIO_PIN_DIR_INPUT,
                 NRF_GPIO_PIN_INPUT_CONNECT,
                 NRF_GPIO_PIN_NOPULL,
                 NRF_GPIO_PIN_S0S1,
                 NRF_GPIO_PIN_NOSENSE);

    nrf_spis_pins_set(p_spis, p_config->sck_pin, mosi_pin, miso_pin, p_config->csn_pin);
    
    nrf_spis_rx_buffer_set(p_spis, NULL, 0);
    nrf_spis_tx_buffer_set(p_spis, NULL, 0);
    
    // Configure SPI mode.
    nrf_spis_configure(p_spis, (nrf_spis_mode_t) p_config->mode,
                               (nrf_spis_bit_order_t) p_config->bit_order);
    
    // Configure DEF and ORC characters.
    nrf_spis_def_set(p_spis, p_config->def);
    nrf_spis_orc_set(p_spis, p_config->orc);
    
    // Clear possible pending events.
    nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END);
    nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED);
    
    // Enable END_ACQUIRE shortcut.        
    nrf_spis_shorts_enable(p_spis, NRF_SPIS_SHORT_END_ACQUIRE);
    
    m_cb[p_instance->instance_id].spi_state = SPIS_STATE_INIT;
    m_cb[p_instance->instance_id].handler = event_handler;

    
    // Enable IRQ.
    nrf_spis_int_enable(p_spis, NRF_SPIS_INT_ACQUIRED_MASK | NRF_SPIS_INT_END_MASK);
    nrf_drv_common_irq_enable(p_instance->irq, p_config->irq_priority);
    
    p_cb->state = NRF_DRV_STATE_INITIALIZED;
    
    // Enable SPI slave device.        
    nrf_spis_enable(p_spis);
    
    return NRF_SUCCESS;
}