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; } } }
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; }