http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.c deleted file mode 100644 index 89a04de..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.c +++ /dev/null @@ -1,509 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -#include "nrf_drv_saadc.h" -#include "nrf_assert.h" -#include "nordic_common.h" -#include "nrf_drv_common.h" -#include "app_util_platform.h" - - -typedef enum -{ - NRF_SAADC_STATE_IDLE = 0, - NRF_SAADC_STATE_BUSY = 1 -} nrf_saadc_state_t; - - -typedef struct -{ - nrf_saadc_input_t pselp; - nrf_saadc_input_t pseln; -} nrf_saadc_psel_buffer; - -static const nrf_drv_saadc_config_t m_default_config = NRF_DRV_SAADC_DEFAULT_CONFIG; - -/** @brief SAADC control block.*/ -typedef struct -{ - nrf_drv_saadc_event_handler_t event_handler; ///< Event handler function pointer. - volatile nrf_saadc_value_t * p_buffer; ///< Sample buffer. - volatile uint16_t buffer_size; ///< Size of the sample buffer. -#ifdef NRF52_PAN_28 - volatile uint16_t buffer_pos; ///< Current sample buffer position. -#endif - volatile nrf_saadc_value_t * p_secondary_buffer; ///< Secondary sample buffer. - uint32_t limits_enabled_flags; ///< Enabled limits flags. - uint16_t secondary_buffer_size; ///< Size of the secondary buffer. - nrf_saadc_psel_buffer psel[NRF_SAADC_CHANNEL_COUNT]; ///< Pin configurations of SAADC channels. - nrf_drv_state_t state; ///< Driver initialization state. - nrf_saadc_state_t adc_state; ///< State of the SAADC. -#ifdef NRF52_PAN_28 - uint8_t scan_pos; ///< Current channel scanning position. -#endif - uint8_t active_channels; ///< Number of enabled SAADC channels. -} nrf_drv_saadc_cb_t; - -static nrf_drv_saadc_cb_t m_cb; - -#define LOW_LIMIT_TO_FLAG(channel) ((2*channel+1)) -#define HIGH_LIMIT_TO_FLAG(channel) ((2*channel)) -#define FLAG_IDX_TO_EVENT(idx) ((nrf_saadc_event_t)((uint32_t)NRF_SAADC_EVENT_CH0_LIMITH+4*idx)) -#define LIMIT_EVENT_TO_CHANNEL(event)(uint8_t)(((uint32_t)event-(uint32_t)NRF_SAADC_EVENT_CH0_LIMITH)/8) -#define LIMIT_EVENT_TO_LIMIT_TYPE(event)((((uint32_t)event-(uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) & 4) ? \ - NRF_SAADC_LIMIT_LOW : NRF_SAADC_LIMIT_HIGH) -#define HW_TIMEOUT 10000 - - -void SAADC_IRQHandler(void) -{ - if (nrf_saadc_event_check(NRF_SAADC_EVENT_END)) - { - nrf_saadc_event_clear(NRF_SAADC_EVENT_END); -#ifdef NRF52_PAN_28 - if (m_cb.active_channels == 1) - { -#endif - nrf_drv_saadc_evt_t evt; - evt.type = NRF_DRV_SAADC_EVT_DONE; - evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.p_buffer; - evt.data.done.size = nrf_saadc_amount_get(); - - if (m_cb.p_secondary_buffer == NULL) - { - m_cb.adc_state = NRF_SAADC_STATE_IDLE; - } - else - { - m_cb.p_buffer = m_cb.p_secondary_buffer; - m_cb.buffer_size = m_cb.secondary_buffer_size; - m_cb.p_secondary_buffer = NULL; - nrf_saadc_task_trigger(NRF_SAADC_TASK_START); - } - - m_cb.event_handler(&evt); -#ifdef NRF52_PAN_28 - } - else - { - //PAN-28: scan mode is not working correctly, emulated by interrupts - ++(m_cb.buffer_pos); - uint16_t buffer_pos = m_cb.buffer_pos; - if (buffer_pos == m_cb.buffer_size) - { - nrf_drv_saadc_evt_t evt; - evt.type = NRF_DRV_SAADC_EVT_DONE; - evt.data.done.p_buffer = (nrf_saadc_value_t *)(m_cb.p_buffer); - evt.data.done.size = m_cb.buffer_size; - - m_cb.adc_state = NRF_SAADC_STATE_IDLE; - if (m_cb.p_secondary_buffer == NULL) - { - m_cb.adc_state = NRF_SAADC_STATE_IDLE; - } - else - { - (void)nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *)m_cb.p_secondary_buffer, (uint16_t)m_cb.secondary_buffer_size); - } - m_cb.event_handler(&evt); - } - else - { - uint8_t current_scan_pos = m_cb.scan_pos; - - nrf_saadc_channel_input_set(current_scan_pos, - NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); - - nrf_saadc_buffer_init((nrf_saadc_value_t *)(m_cb.p_buffer + m_cb.buffer_pos), 1); - // Find the next enabled channel. - for (++m_cb.scan_pos; m_cb.scan_pos < NRF_SAADC_CHANNEL_COUNT; ++m_cb.scan_pos) - { - if (m_cb.psel[m_cb.scan_pos].pselp) - { - nrf_saadc_channel_input_set(m_cb.scan_pos, - m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln); - nrf_saadc_task_trigger(NRF_SAADC_TASK_START); - nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); - return; - } - } - //if scanning is done prepare for next round. - for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) - { - if (m_cb.psel[i].pselp) - { - m_cb.scan_pos = i; - break; - } - } - nrf_saadc_channel_input_set(m_cb.scan_pos, - m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln); - nrf_saadc_task_trigger(NRF_SAADC_TASK_START); - } - } -#endif - } - if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED)) - { - nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED); - m_cb.adc_state = NRF_SAADC_STATE_IDLE; - } - else - { - uint32_t limit_flags = m_cb.limits_enabled_flags; - uint32_t flag_idx; - nrf_saadc_event_t event; - while (limit_flags) - { - flag_idx = __CLZ(limit_flags); - limit_flags &= ~((1UL<<31) >> flag_idx); - event = FLAG_IDX_TO_EVENT(flag_idx); - if (nrf_saadc_event_check(event)) - { - nrf_saadc_event_clear(event); - nrf_drv_saadc_evt_t evt; - evt.type = NRF_DRV_SAADC_EVT_LIMIT; - evt.data.limit.channel = LIMIT_EVENT_TO_CHANNEL(event); - evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event); - m_cb.event_handler(&evt); - } - } - } -} - - -ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config, - nrf_drv_saadc_event_handler_t event_handler) -{ - if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) - { - return NRF_ERROR_INVALID_STATE; - } - if (event_handler == NULL) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_config == NULL) - { - p_config = &m_default_config; - } - - m_cb.event_handler = event_handler; - nrf_saadc_resolution_set(p_config->resolution); - nrf_saadc_oversample_set(p_config->oversample); - m_cb.state = NRF_DRV_STATE_INITIALIZED; - m_cb.adc_state = NRF_SAADC_STATE_IDLE; - m_cb.active_channels = 0; - m_cb.limits_enabled_flags = 0; -#ifdef NRF52_PAN_28 - m_cb.buffer_pos = 0; -#endif - - nrf_saadc_int_disable(NRF_SAADC_INT_ALL); - nrf_saadc_event_clear(NRF_SAADC_EVENT_END); - nrf_drv_common_irq_enable(SAADC_IRQn, p_config->interrupt_priority); - nrf_saadc_int_enable(NRF_SAADC_INT_END); - - nrf_saadc_enable(); - - return NRF_SUCCESS; -} - - -void nrf_drv_saadc_uninit(void) -{ - ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); - nrf_drv_common_irq_disable(SAADC_IRQn); - nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP); - - // Wait for ADC being stopped. - uint32_t timeout = HW_TIMEOUT; - while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0 && timeout > 0) - { - --timeout; - } - ASSERT(timeout > 0); - - nrf_saadc_disable(); - nrf_saadc_int_disable(NRF_SAADC_INT_ALL); - - m_cb.adc_state = NRF_SAADC_STATE_IDLE; - - for (uint8_t channel = 0; channel < NRF_SAADC_CHANNEL_COUNT; ++channel) - { - if (m_cb.psel[channel].pselp != NRF_SAADC_INPUT_DISABLED) - { - (void)nrf_drv_saadc_channel_uninit(channel); - } - } - - m_cb.state = NRF_DRV_STATE_UNINITIALIZED; -} - - -ret_code_t nrf_drv_saadc_channel_init(uint8_t channel, - nrf_saadc_channel_config_t const * const p_config) -{ - ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(channel < NRF_SAADC_CHANNEL_COUNT); - //Oversampling can be used only with one channel. - ASSERT((nrf_saadc_oversample_get()==NRF_SAADC_OVERSAMPLE_DISABLED) || (m_cb.active_channels == 0)); - ASSERT((p_config->pin_p <= NRF_SAADC_INPUT_VDD) && (p_config->pin_p > NRF_SAADC_INPUT_DISABLED)); - ASSERT(p_config->pin_n <= NRF_SAADC_INPUT_VDD); - - // A channel can only be initialized if the driver is in the idle state. - if (m_cb.adc_state == NRF_SAADC_STATE_BUSY) - { - return NRF_ERROR_BUSY; - } - - if (!m_cb.psel[channel].pselp) - { - ++m_cb.active_channels; - } - m_cb.psel[channel].pselp = p_config->pin_p; - m_cb.psel[channel].pseln = p_config->pin_n; - nrf_saadc_channel_init(channel, p_config); - -#ifdef NRF52_PAN_28 - nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); -#else - nrf_saadc_channel_input_set(channel, p_config->pin_p, p_config->pin_n); -#endif - return NRF_SUCCESS; -} - - -ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel) -{ - ASSERT(channel <= NRF_SAADC_CHANNEL_COUNT) - ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); - - // A channel can only be uninitialized if the driver is in the idle state. - if (m_cb.adc_state == NRF_SAADC_STATE_BUSY) - { - return NRF_ERROR_BUSY; - } - - if (m_cb.psel[channel].pselp) - { - --m_cb.active_channels; - } - m_cb.psel[channel].pselp = NRF_SAADC_INPUT_DISABLED; - m_cb.psel[channel].pseln = NRF_SAADC_INPUT_DISABLED; - nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); - nrf_drv_saadc_limits_set(channel, NRF_DRV_SAADC_LIMITL_DISABLED, NRF_DRV_SAADC_LIMITH_DISABLED); - - return NRF_SUCCESS; -} - -ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value) -{ - if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) - { - return NRF_ERROR_BUSY; - } - m_cb.adc_state = NRF_SAADC_STATE_BUSY; - nrf_saadc_int_disable(NRF_SAADC_INT_END); - nrf_saadc_buffer_init(p_value, 1); -#ifndef NRF52_PAN_28 - if (m_cb.active_channels > 1) - { - for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) - { - nrf_saadc_channel_input_set(i, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); - } - } -#endif - nrf_saadc_channel_input_set(channel, - m_cb.psel[channel].pselp, m_cb.psel[channel].pseln); - nrf_saadc_task_trigger(NRF_SAADC_TASK_START); - nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); - - uint32_t timeout = HW_TIMEOUT; - while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) && timeout > 0) - { - timeout--; - } - nrf_saadc_event_clear(NRF_SAADC_EVENT_END); - -#ifdef NRF52_PAN_28 - nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); -#else - if (m_cb.active_channels > 1) - { - for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) - { - nrf_saadc_channel_input_set(i, m_cb.psel[i].pselp, m_cb.psel[i].pseln); - } - } -#endif - - nrf_saadc_int_enable(NRF_SAADC_INT_END); - m_cb.adc_state = NRF_SAADC_STATE_IDLE; - - return NRF_SUCCESS; -} - -ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * p_buffer, uint16_t size) -{ - ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); - - nrf_saadc_int_disable(NRF_SAADC_INT_END); - if (m_cb.adc_state == NRF_SAADC_STATE_BUSY) - { - if ( m_cb.p_secondary_buffer) - { - nrf_saadc_int_enable(NRF_SAADC_INT_END); - return NRF_ERROR_BUSY; - } - else - { - m_cb.p_secondary_buffer = p_buffer; - m_cb.secondary_buffer_size = size; -#ifdef NRF52_PAN_28 - if (m_cb.active_channels == 1) -#endif - { - while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0); - nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); - nrf_saadc_buffer_init(p_buffer, size); - } - nrf_saadc_int_enable(NRF_SAADC_INT_END); - return NRF_SUCCESS; - } - } - nrf_saadc_int_enable(NRF_SAADC_INT_END); - m_cb.adc_state = NRF_SAADC_STATE_BUSY; - -#ifdef NRF52_PAN_28 - m_cb.scan_pos = NRF_SAADC_CHANNEL_COUNT; - for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) - { - if (m_cb.psel[i].pselp) - { - m_cb.scan_pos = i; - break; - } - } - - // Find the first enabled channel. - if (m_cb.scan_pos >= NRF_SAADC_CHANNEL_COUNT) - { - return NRF_ERROR_INVALID_STATE; - } - - m_cb.buffer_pos = 0; -#endif - m_cb.p_buffer = p_buffer; - m_cb.buffer_size = size; - m_cb.p_secondary_buffer = NULL; - -#ifdef NRF52_PAN_28 - nrf_saadc_channel_input_set(m_cb.scan_pos, - m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln); - - if (m_cb.active_channels == 1) - { - nrf_saadc_buffer_init(p_buffer, size); - } - else - { - nrf_saadc_buffer_init(p_buffer, 1); - } -#else - nrf_saadc_buffer_init(p_buffer, size); -#endif - - nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); - nrf_saadc_task_trigger(NRF_SAADC_TASK_START); - - return NRF_SUCCESS; -} - -ret_code_t nrf_drv_saadc_sample() -{ - ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); - - ret_code_t err_code = NRF_SUCCESS; - if (m_cb.adc_state == NRF_SAADC_STATE_IDLE) - { - err_code = NRF_ERROR_BUSY; - } - else - { - nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); - } - - return err_code; -} - - -bool nrf_drv_saadc_is_busy(void) -{ - return (m_cb.adc_state == NRF_SAADC_STATE_BUSY); -} - -void nrf_drv_saadc_abort(void) -{ - if (nrf_drv_saadc_is_busy()) - { - nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED); - nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP); - - // Wait for ADC being stopped. - uint32_t timeout = HW_TIMEOUT; - while ((m_cb.adc_state != NRF_SAADC_STATE_IDLE) && (timeout > 0)) - { - --timeout; - } - ASSERT(timeout > 0); - - m_cb.p_buffer = 0; - m_cb.p_secondary_buffer = 0; - } -} - -void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high) -{ - ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(m_cb.event_handler); // only non blocking mode supported - ASSERT(limit_low>=NRF_DRV_SAADC_LIMITL_DISABLED); - ASSERT(limit_high<=NRF_DRV_SAADC_LIMITH_DISABLED); - ASSERT(limit_low<limit_high); - nrf_saadc_channel_limits_set(channel, limit_low, limit_high); - - uint32_t int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_LOW); - if (limit_low == NRF_DRV_SAADC_LIMITL_DISABLED) - { - m_cb.limits_enabled_flags &= ~(0x80000000 >> LOW_LIMIT_TO_FLAG(channel)); - nrf_saadc_int_disable(int_mask); - } - else - { - m_cb.limits_enabled_flags |= (0x80000000 >> LOW_LIMIT_TO_FLAG(channel)); - nrf_saadc_int_enable(int_mask); - } - - int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_HIGH); - if (limit_high == NRF_DRV_SAADC_LIMITH_DISABLED) - { - m_cb.limits_enabled_flags &= ~(0x80000000 >> HIGH_LIMIT_TO_FLAG(channel)); - nrf_saadc_int_disable(int_mask); - } - else - { - m_cb.limits_enabled_flags |= (0x80000000 >> HIGH_LIMIT_TO_FLAG(channel)); - nrf_saadc_int_enable(int_mask); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.h ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.h deleted file mode 100644 index 35fdc01..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/saadc/nrf_drv_saadc.h +++ /dev/null @@ -1,311 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -/** - * @addtogroup nrf_saadc SAADC HAL and driver - * @ingroup nrf_drivers - * @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) APIs. - * @details The SAADC HAL provides basic APIs for accessing the registers of the SAADC peripheral. - * The SAADC driver provides APIs on a higher level. - * - * @defgroup nrf_drv_saadc SAADC driver - * @{ - * @ingroup nrf_saadc - * - * @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) driver. - */ - -#ifndef NRF_DRV_SAADC_H__ -#define NRF_DRV_SAADC_H__ - -#include "nrf_drv_config.h" -#include "nrf_saadc.h" -#include "sdk_errors.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Value that should be set as high limit to disable limit detection. - */ -#define NRF_DRV_SAADC_LIMITH_DISABLED (2047) -/** - * @brief Value that should be set as low limit to disable limit detection. - */ -#define NRF_DRV_SAADC_LIMITL_DISABLED (-2048) - -/** - * @brief Macro for setting @ref nrf_drv_saadc_config_t to default settings. - */ -#define NRF_DRV_SAADC_DEFAULT_CONFIG \ -{ \ - .resolution = SAADC_CONFIG_RESOLUTION, \ - .oversample = SAADC_CONFIG_OVERSAMPLE, \ - .interrupt_priority = SAADC_CONFIG_IRQ_PRIORITY \ -} - -/** - * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings - * in single ended mode. - * - * @param PIN_P Analog input. - */ -#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \ -{ \ - .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ - .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ - .gain = NRF_SAADC_GAIN1_6, \ - .reference = NRF_SAADC_REFERENCE_INTERNAL, \ - .acq_time = NRF_SAADC_ACQTIME_10US, \ - .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ - .pin_p = (nrf_saadc_input_t)(PIN_P), \ - .pin_n = NRF_SAADC_INPUT_DISABLED \ -} - -/** - * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings - * in differential mode. - * - * @param PIN_P Positive analog input. - * @param PIN_N Negative analog input. - */ -#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \ -{ \ - .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ - .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ - .gain = NRF_SAADC_GAIN1_6, \ - .reference = NRF_SAADC_REFERENCE_INTERNAL, \ - .acq_time = NRF_SAADC_ACQTIME_10US, \ - .mode = NRF_SAADC_MODE_DIFFERENTIAL, \ - .pin_p = (nrf_saadc_input_t)(PIN_P), \ - .pin_n = (nrf_saadc_input_t)(PIN_N) \ -} - -/** - * @brief Analog-to-digital converter driver configuration structure. - */ -typedef struct -{ - nrf_saadc_resolution_t resolution; ///< Resolution configuration. - nrf_saadc_oversample_t oversample; ///< Oversampling configuration. - uint8_t interrupt_priority; ///< Interrupt priority. -} nrf_drv_saadc_config_t; - -/** - * @brief Driver event types. - */ -typedef enum -{ - NRF_DRV_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples. - NRF_DRV_SAADC_EVT_LIMIT, ///< Event generated after one of the limits is reached. -} nrf_drv_saadc_evt_type_t; - -/** - * @brief Analog-to-digital converter driver done event data. - */ -typedef struct -{ - nrf_saadc_value_t * p_buffer; ///< Pointer to buffer with converted samples. - uint16_t size; ///< Number of samples in the buffer. -} nrf_drv_saadc_done_evt_t; - -/** - * @brief Analog-to-digital converter driver limit event data. - */ -typedef struct -{ - uint8_t channel; ///< Channel on which the limit was detected. - nrf_saadc_limit_t limit_type; ///< Type of limit detected. -} nrf_drv_saadc_limit_evt_t; - -/** - * @brief Analog-to-digital converter driver event structure. - */ -typedef struct -{ - nrf_drv_saadc_evt_type_t type; ///< Event type. - union - { - nrf_drv_saadc_done_evt_t done; ///< Data for @ref NRF_DRV_SAADC_EVT_DONE event. - nrf_drv_saadc_limit_evt_t limit;///< Data for @ref NRF_DRV_SAADC_EVT_LIMIT event. - } data; -} nrf_drv_saadc_evt_t; - -/** - * @brief ADC event handler. - * - * @param[in] p_event Pointer to an ADC event. The event structure is allocated on - * the stack, so it is valid only within the context of - * the event handler. - */ -typedef void (*nrf_drv_saadc_event_handler_t)(nrf_drv_saadc_evt_t const * p_event); - -/** - * @brief Function for initializing the SAADC. - * - * @param[in] p_config Pointer to a configuration structure. If NULL, the default one is used. - * @param[in] event_handler Event handler provided by the user. - * - * @retval NRF_SUCCESS If initialization was successful. - * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. - * @retval NRF_ERROR_INVALID_PARAM If event_handler is NULL. - */ -ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config, - nrf_drv_saadc_event_handler_t event_handler); - -/** - * @brief Function for uninitializing the SAADC. - * - * This function stops all ongoing conversions and disables all channels. - */ -void nrf_drv_saadc_uninit(void); - -/** - * @brief Function for getting the address of a SAMPLE SAADC task. - * - * @return Task address. - */ -__STATIC_INLINE uint32_t nrf_drv_saadc_sample_task_get(void) -{ - return nrf_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE); -} - - -/** - * @brief Function for initializing an SAADC channel. - * - * This function configures and enables the channel. - * - * @retval NRF_SUCCESS If initialization was successful. - * @retval NRF_ERROR_INVALID_STATE If the ADC was not initialized. - * @retval NRF_ERROR_NO_MEM If the specified channel was already allocated. - */ -ret_code_t nrf_drv_saadc_channel_init(uint8_t channel, - nrf_saadc_channel_config_t const * const p_config); - - -/** - * @brief Function for uninitializing an SAADC channel. - * - * @retval NRF_SUCCESS If uninitialization was successful. - * @retval NRF_ERROR_BUSY If the ADC is busy. - */ -ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel); - -/** - * @brief Function for starting SAADC sampling. - * - * @retval NRF_SUCCESS If ADC sampling was triggered. - * @retval NRF_ERROR_BUSY If ADC is in idle state. - */ -ret_code_t nrf_drv_saadc_sample(void); - -/** - * @brief Blocking function for executing a single ADC conversion. - * - * This function selects the desired input, starts a single conversion, - * waits for it to finish, and returns the result. - * - * The function will fail if ADC is busy. - * - * @param[in] channel Channel. - * @param[out] p_value Pointer to the location where the result should be placed. - * - * @retval NRF_SUCCESS If conversion was successful. - * @retval NRF_ERROR_BUSY If the ADC driver is busy. - */ -ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value); - -/** - * @brief Function for issuing conversion of data to the buffer. - * - * This function is non-blocking. The application is notified about filling the buffer by the event handler. - * Conversion will be done on all enabled channels. If the ADC is in idle state, the function will set up Easy - * DMA for the conversion. The ADC will be ready for sampling and wait for the SAMPLE task. It can be - * triggered manually by the @ref nrf_drv_saadc_sample function or by PPI using the @ref NRF_SAADC_TASK_SAMPLE - * task. If one buffer is already set and the conversion is ongoing, calling this function will - * result in queuing the given buffer. The driver will start filling the issued buffer when the first one is - * completed. If the function is called again before the first buffer is filled, it will return with error. - * - * @param[in] buffer Result buffer. - * @param[in] size Buffer size in words. - * - * @retval NRF_SUCCESS If conversion was successful. - * @retval NRF_ERROR_BUSY If the driver already has two buffers set. - */ -ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * buffer, uint16_t size); - -/** - * @brief Function for retrieving the SAADC state. - * - * @retval true If the ADC is busy. - * @retval false If the ADC is ready. - */ -bool nrf_drv_saadc_is_busy(void); - -/** - * @brief Function for aborting ongoing and buffered conversions. - * @note @ref NRF_DRV_SAADC_EVT_DONE event will be generated if there is a conversion in progress. - * Event will contain number of words in the sample buffer. - */ -void nrf_drv_saadc_abort(void); - -/** - * @brief Function for setting the SAADC channel limits. - * When limits are enabled and the result exceeds the defined bounds, the limit handler function is called. - * - * @param[in] channel SAADC channel number. - * @param[in] limit_low Lower limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to - * @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results below this value will trigger - * the handler function. Set to @ref NRF_DRV_SAADC_LIMITL_DISABLED to disable this limit. - * @param[in] limit_high Upper limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to - * @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results above this value will trigger - * the handler function. Set to @ref NRF_DRV_SAADC_LIMITH_DISABLED to disable this limit. - */ -void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high); - -/** - * @brief Function for converting a GPIO pin number to an analog input pin number used in the channel - * configuration. - * - * @param[in] pin GPIO pin. - * - * @return Value representing an analog input pin. The function returns @ref NRF_SAADC_INPUT_DISABLED - * if the specified pin is not an analog input. - */ -__STATIC_INLINE nrf_saadc_input_t nrf_drv_saadc_gpio_to_ain(uint32_t pin) -{ - // AIN0 - AIN3 - if (pin >= 2 && pin <= 5) - { - //0 means "not connected", hence this "+ 1" - return (nrf_saadc_input_t)(pin - 2 + 1); - } - // AIN4 - AIN7 - else if (pin >= 28 && pin <= 31) - { - return (nrf_saadc_input_t)(pin - 24 + 1); - } - else - { - return NRF_SAADC_INPUT_DISABLED; - } -} - -#ifdef __cplusplus -} -#endif - -#endif // NRF_DRV_SAADC_H__ - -/** @} */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/config/sdio_config.h ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/config/sdio_config.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/config/sdio_config.h deleted file mode 100644 index 715280b..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/config/sdio_config.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ -#ifndef SDIO_CONFIG_H -#define SDIO_CONFIG_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define SDIO_CONFIG_CLOCK_PIN_NUMBER 24 -#define SDIO_CONFIG_DATA_PIN_NUMBER 25 - -#ifdef __cplusplus -} -#endif - -#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.c deleted file mode 100644 index cc479a0..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.c +++ /dev/null @@ -1,217 +0,0 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -#include <stdint.h> - -#include "nrf.h" -#include "nrf_delay.h" -#include "sdio.h" -#include "nrf_gpio.h" - -#include "sdio_config.h" - -/*lint ++flb "Enter library region" */ - -/*lint -e717 -save "Suppress do {} while (0) for these macros" */ -#define SDIO_CLOCK_HIGH() do { NRF_GPIO->OUTSET = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line high */ -#define SDIO_CLOCK_LOW() do { NRF_GPIO->OUTCLR = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line low */ -#define SDIO_DATA_HIGH() do { NRF_GPIO->OUTSET = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line high */ -#define SDIO_DATA_LOW() do { NRF_GPIO->OUTCLR = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line low */ -#define SDIO_DATA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as output */ -#define SDIO_CLOCK_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Configures SCL pin as output */ -/*lint -restore */ - -/*lint -emacro(845,SDIO_DATA_INPUT) // A zero has been given as right argument to operator '|'" */ - -#define SDIO_DATA_INPUT() do { \ - nrf_gpio_cfg_input(25, NRF_GPIO_PIN_NOPULL); \ -} while (0) - -#define SDIO_DATA_READ() ((NRF_GPIO->IN >> SDIO_CONFIG_DATA_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SDA */ -#define SDIO_CLOCK_READ() ((NRF_GPIO->IN >> SDIO_CONFIG_CLOCK_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SCL */ -#define SDIO_DELAY() nrf_delay_us(10) /*!< Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient. */ - -void sdio_init(void) -{ - SDIO_CLOCK_HIGH(); - SDIO_DATA_HIGH(); - SDIO_CLOCK_OUTPUT(); - SDIO_DATA_INPUT(); - - // If slave is stuck in the middle of transfer, clock out bits until the slave ACKs the transfer - for (uint_fast8_t i = 16; i--;) - { - SDIO_DELAY(); - SDIO_CLOCK_LOW(); - SDIO_DELAY(); - SDIO_CLOCK_HIGH(); - SDIO_DELAY(); - - if (SDIO_DATA_READ()) - { - break; - } - } - - for (uint_fast8_t i = 5; i--;) - { - SDIO_DELAY(); - SDIO_CLOCK_LOW(); - SDIO_DELAY(); - SDIO_CLOCK_HIGH(); - } - - SDIO_DATA_OUTPUT(); - SDIO_DATA_HIGH(); - - SDIO_DELAY(); -} - -uint8_t sdio_read_byte(uint8_t address) -{ - uint8_t data_byte = 0; - - SDIO_DATA_OUTPUT(); - - for (uint_fast8_t i = 8; i--;) - { - SDIO_DELAY(); - - SDIO_CLOCK_LOW(); - - if (address & (1U << i)) - { - SDIO_DATA_HIGH(); - } - else - { - SDIO_DATA_LOW(); - } - - SDIO_DELAY(); - - SDIO_CLOCK_HIGH(); - } - - nrf_delay_us(20); - - SDIO_DATA_INPUT(); - - for (uint_fast8_t i = 8; i--;) - { - SDIO_CLOCK_LOW(); - SDIO_DELAY(); - SDIO_CLOCK_HIGH(); - SDIO_DELAY(); - data_byte |= (uint8_t)(SDIO_DATA_READ() << i); - } - - SDIO_DATA_HIGH(); - SDIO_DATA_OUTPUT(); - - SDIO_DELAY(); - - return data_byte; -} - -void sdio_read_burst(uint8_t * target_buffer, uint8_t target_buffer_size) -{ - uint_fast8_t address = 0x63; - - SDIO_DATA_OUTPUT(); - - for (uint_fast8_t bit_index=8; bit_index--;) - { - SDIO_CLOCK_LOW(); - - if (address & (1U << bit_index)) - { - SDIO_DATA_HIGH(); - } - else - { - SDIO_DATA_LOW(); - } - - SDIO_CLOCK_HIGH(); - } - - SDIO_DATA_INPUT(); - - for (uint_fast8_t target_buffer_index = 0; target_buffer_index < target_buffer_size; target_buffer_index++) - { - target_buffer[target_buffer_index] = 0; - - for (uint_fast8_t bit_index = 8; bit_index--;) - { - SDIO_CLOCK_LOW(); - SDIO_CLOCK_HIGH(); - target_buffer[target_buffer_index] |= (uint8_t)(SDIO_DATA_READ() << bit_index); - } - } -} - -void sdio_write_byte(uint8_t address, uint8_t data_byte) -{ - // Add write indication bit - address |= 0x80; - - SDIO_DATA_OUTPUT(); - - for (uint_fast8_t i = 8; i--;) - { - SDIO_DELAY(); - - SDIO_CLOCK_LOW(); - - if (address & (1U << i)) - { - SDIO_DATA_HIGH(); - } - else - { - SDIO_DATA_LOW(); - } - - SDIO_DELAY(); - - SDIO_CLOCK_HIGH(); - } - - SDIO_DELAY(); - - for (uint_fast8_t i = 8; i--;) - { - SDIO_CLOCK_LOW(); - - if (data_byte & (1U << i)) - { - SDIO_DATA_HIGH(); - } - else - { - SDIO_DATA_LOW(); - } - - SDIO_DELAY(); - - SDIO_CLOCK_HIGH(); - - SDIO_DELAY(); - } - - SDIO_DATA_HIGH(); - - SDIO_DELAY(); -} - -/*lint --flb "Leave library region" */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.h ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.h deleted file mode 100644 index ffbde5c..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/sdio/sdio.h +++ /dev/null @@ -1,77 +0,0 @@ - /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -#ifndef SDIO_H -#define SDIO_H - -#ifdef __cplusplus -extern "C" { -#endif - -/*lint ++flb "Enter library region" */ - -#include <stdbool.h> -#include <stdint.h> - -/** @file -* @brief 2-wire serial interface driver (compatible with ADNS2080 mouse sensor driver) -* -* -* @defgroup nrf_drivers_sdio SDIO driver -* @{ -* @ingroup nrf_drivers -* @brief 2-wire serial interface driver. -*/ - -/** - * @brief Function for initializing 2-wire serial interface and trying to handle stuck slaves. - * - */ -void sdio_init(void); - -/** - * @brief Function for reading a byte over 2-wire serial interface. - * - * Developer needs to implement this function in a way that suits the hardware. - * @param address Register address to read from - * @return Byte read - */ -uint8_t sdio_read_byte(uint8_t address); - -/** - * @brief Function for reading several bytes over 2-wire serial interface using burst mode. - * - * Developer needs to implement this function in a way that suits the hardware. - * @param target_buffer Buffer location to store read bytes to - * @param target_buffer_size Bytes allocated for target_buffer - */ -void sdio_read_burst(uint8_t *target_buffer, uint8_t target_buffer_size); - -/** - * @brief Function for writing a byte over 2-wire serial interface. - * - * Developer needs to implement this function in a way that suits the hardware. - * @param address Register address to write to - * @param data_byte Data byte to write - */ -void sdio_write_byte(uint8_t address, uint8_t data_byte); - -/** - *@} - **/ - -/*lint --flb "Leave library region" */ -#ifdef __cplusplus -} -#endif - -#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.c ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.c deleted file mode 100644 index fa68a7d..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.c +++ /dev/null @@ -1,655 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -#include "nrf_drv_spi.h" -#include "nrf_drv_common.h" -#include "nrf_gpio.h" -#include "nrf_assert.h" -#include "app_util_platform.h" - - -#ifndef NRF52 - // Make sure SPIx_USE_EASY_DMA is 0 for nRF51 (if a common - // "nrf_drv_config.h" file is provided for nRF51 and nRF52). - #undef SPI0_USE_EASY_DMA - #define SPI0_USE_EASY_DMA 0 - #undef SPI1_USE_EASY_DMA - #define SPI1_USE_EASY_DMA 0 - #undef SPI2_USE_EASY_DMA - #define SPI2_USE_EASY_DMA 0 -#endif - -// This set of macros makes it possible to exclude parts of code when one type -// of supported peripherals is not used. -#if ((SPI0_ENABLED && SPI0_USE_EASY_DMA) || \ - (SPI1_ENABLED && SPI1_USE_EASY_DMA) || \ - (SPI2_ENABLED && SPI2_USE_EASY_DMA)) - #define SPIM_IN_USE -#endif -#if ((SPI0_ENABLED && !SPI0_USE_EASY_DMA) || \ - (SPI1_ENABLED && !SPI1_USE_EASY_DMA) || \ - (SPI2_ENABLED && !SPI2_USE_EASY_DMA)) - #define SPI_IN_USE -#endif -#if defined(SPIM_IN_USE) && defined(SPI_IN_USE) - // SPIM and SPI combined - #define CODE_FOR_SPIM(code) if (p_instance->use_easy_dma) { code } - #define CODE_FOR_SPI(code) else { code } -#elif defined(SPIM_IN_USE) && !defined(SPI_IN_USE) - // SPIM only - #define CODE_FOR_SPIM(code) { code } - #define CODE_FOR_SPI(code) -#elif !defined(SPIM_IN_USE) && defined(SPI_IN_USE) - // SPI only - #define CODE_FOR_SPIM(code) - #define CODE_FOR_SPI(code) { code } -#else - #error "Wrong configuration." -#endif - -#ifdef SPIM_IN_USE -#ifdef NRF52_PAN_23 -#define END_INT_MASK (NRF_SPIM_INT_ENDTX_MASK | NRF_SPIM_INT_ENDRX_MASK) -#else -#define END_INT_MASK NRF_SPIM_INT_END_MASK -#endif -#endif - -// Control block - driver instance local data. -typedef struct -{ - nrf_drv_spi_handler_t handler; - nrf_drv_spi_evt_t evt; // Keep the struct that is ready for event handler. Less memcpy. - nrf_drv_state_t state; - volatile bool transfer_in_progress; - - // [no need for 'volatile' attribute for the following members, as they - // are not concurrently used in IRQ handlers and main line code] - uint8_t ss_pin; - uint8_t orc; - uint8_t bytes_transferred; - - bool tx_done : 1; - bool rx_done : 1; -} spi_control_block_t; -static spi_control_block_t m_cb[SPI_COUNT]; - -static nrf_drv_spi_config_t const m_default_config[SPI_COUNT] = { -#if SPI0_ENABLED - NRF_DRV_SPI_DEFAULT_CONFIG(0), -#endif -#if SPI1_ENABLED - NRF_DRV_SPI_DEFAULT_CONFIG(1), -#endif -#if SPI2_ENABLED - NRF_DRV_SPI_DEFAULT_CONFIG(2), -#endif -}; - -#if PERIPHERAL_RESOURCE_SHARING_ENABLED - #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n - #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) - - #if SPI0_ENABLED - IRQ_HANDLER(0); - #endif - #if SPI1_ENABLED - IRQ_HANDLER(1); - #endif - #if SPI2_ENABLED - IRQ_HANDLER(2); - #endif - static nrf_drv_irq_handler_t const m_irq_handlers[SPI_COUNT] = { - #if SPI0_ENABLED - IRQ_HANDLER_NAME(0), - #endif - #if SPI1_ENABLED - IRQ_HANDLER_NAME(1), - #endif - #if SPI2_ENABLED - IRQ_HANDLER_NAME(2), - #endif - }; -#else - #define IRQ_HANDLER(n) void SPI##n##_IRQ_HANDLER(void) -#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED - - -ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, - nrf_drv_spi_config_t const * p_config, - nrf_drv_spi_handler_t handler) -{ - spi_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; - } - -#if PERIPHERAL_RESOURCE_SHARING_ENABLED - if (nrf_drv_common_per_res_acquire(p_instance->p_registers, - m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS) - { - return NRF_ERROR_BUSY; - } -#endif - - if (p_config == NULL) - { - p_config = &m_default_config[p_instance->drv_inst_idx]; - } - - p_cb->handler = handler; - - uint32_t mosi_pin; - uint32_t miso_pin; - // Configure pins used by the peripheral: - // - SCK - output with initial value corresponding with the SPI mode used: - // 0 - for modes 0 and 1 (CPOL = 0), 1 - for modes 2 and 3 (CPOL = 1); - // according to the reference manual guidelines this pin and its input - // buffer must always be connected for the SPI to work. - if (p_config->mode <= NRF_DRV_SPI_MODE_1) - { - nrf_gpio_pin_clear(p_config->sck_pin); - } - else - { - nrf_gpio_pin_set(p_config->sck_pin); - } - NRF_GPIO->PIN_CNF[p_config->sck_pin] = - (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) - | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) - | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) - | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) - | (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - // - MOSI (optional) - output with initial value 0, - if (p_config->mosi_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - mosi_pin = p_config->mosi_pin; - nrf_gpio_pin_clear(mosi_pin); - nrf_gpio_cfg_output(mosi_pin); - } - else - { - mosi_pin = NRF_SPI_PIN_NOT_CONNECTED; - } - // - MISO (optional) - input, - if (p_config->miso_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - miso_pin = p_config->miso_pin; - nrf_gpio_cfg_input(miso_pin, NRF_GPIO_PIN_NOPULL); - } - else - { - miso_pin = NRF_SPI_PIN_NOT_CONNECTED; - } - // - Slave Select (optional) - output with initial value 1 (inactive). - if (p_config->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_set(p_config->ss_pin); - nrf_gpio_cfg_output(p_config->ss_pin); - } - m_cb[p_instance->drv_inst_idx].ss_pin = p_config->ss_pin; - - CODE_FOR_SPIM - ( - NRF_SPIM_Type * p_spim = p_instance->p_registers; - nrf_spim_pins_set(p_spim, p_config->sck_pin, mosi_pin, miso_pin); - nrf_spim_frequency_set(p_spim, - (nrf_spim_frequency_t)p_config->frequency); - nrf_spim_configure(p_spim, - (nrf_spim_mode_t)p_config->mode, - (nrf_spim_bit_order_t)p_config->bit_order); - - nrf_spim_orc_set(p_spim, p_config->orc); - - if (p_cb->handler) - { - nrf_spim_int_enable(p_spim, END_INT_MASK | NRF_SPIM_INT_STOPPED_MASK); - } - - nrf_spim_enable(p_spim); - ) - CODE_FOR_SPI - ( - NRF_SPI_Type * p_spi = p_instance->p_registers; - nrf_spi_pins_set(p_spi, p_config->sck_pin, mosi_pin, miso_pin); - nrf_spi_frequency_set(p_spi, - (nrf_spi_frequency_t)p_config->frequency); - nrf_spi_configure(p_spi, - (nrf_spi_mode_t)p_config->mode, - (nrf_spi_bit_order_t)p_config->bit_order); - - m_cb[p_instance->drv_inst_idx].orc = p_config->orc; - - if (p_cb->handler) - { - nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK); - } - - nrf_spi_enable(p_spi); - ) - - if (p_cb->handler) - { - nrf_drv_common_irq_enable(p_instance->irq, p_config->irq_priority); - } - - p_cb->transfer_in_progress = false; - p_cb->state = NRF_DRV_STATE_INITIALIZED; - - return NRF_SUCCESS; -} - -void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance) -{ - spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); - - if (p_cb->handler) - { - nrf_drv_common_irq_disable(p_instance->irq); - } - - #define DISABLE_ALL 0xFFFFFFFF - - CODE_FOR_SPIM - ( - NRF_SPIM_Type * p_spim = p_instance->p_registers; - if (p_cb->handler) - { - nrf_spim_int_disable(p_spim, DISABLE_ALL); - if (p_cb->transfer_in_progress) - { - // Ensure that SPI is not performing any transfer. - nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP); - while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) {} - p_cb->transfer_in_progress = false; - } - } - nrf_spim_disable(p_spim); - ) - CODE_FOR_SPI - ( - NRF_SPI_Type * p_spi = p_instance->p_registers; - if (p_cb->handler) - { - nrf_spi_int_disable(p_spi, DISABLE_ALL); - } - nrf_spi_disable(p_spi); - ) - #undef DISABLE_ALL - -#if PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common_per_res_release(p_instance->p_registers); -#endif - - p_cb->state = NRF_DRV_STATE_UNINITIALIZED; -} - -ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, - uint8_t const * p_tx_buffer, - uint8_t tx_buffer_length, - uint8_t * p_rx_buffer, - uint8_t rx_buffer_length) -{ - nrf_drv_spi_xfer_desc_t xfer_desc; - xfer_desc.p_tx_buffer = p_tx_buffer; - xfer_desc.p_rx_buffer = p_rx_buffer; - xfer_desc.tx_length = tx_buffer_length; - xfer_desc.rx_length = rx_buffer_length; - - return nrf_drv_spi_xfer(p_instance, &xfer_desc, 0); -} - -static void finish_transfer(spi_control_block_t * p_cb) -{ - // If Slave Select signal is used, this is the time to deactivate it. - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_set(p_cb->ss_pin); - } - - // By clearing this flag before calling the handler we allow subsequent - // transfers to be started directly from the handler function. - p_cb->transfer_in_progress = false; - p_cb->evt.type = NRF_DRV_SPI_EVENT_DONE; - p_cb->handler(&p_cb->evt); -} - -#ifdef SPI_IN_USE -// This function is called from IRQ handler or, in blocking mode, directly -// from the 'nrf_drv_spi_transfer' function. -// It returns true as long as the transfer should be continued, otherwise (when -// there is nothing more to send/receive) it returns false. -static bool transfer_byte(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) -{ - // Read the data byte received in this transfer and store it in RX buffer, - // if needed. - volatile uint8_t rx_data = nrf_spi_rxd_get(p_spi); - if (p_cb->bytes_transferred < p_cb->evt.data.done.rx_length) - { - p_cb->evt.data.done.p_rx_buffer[p_cb->bytes_transferred] = rx_data; - } - - ++p_cb->bytes_transferred; - - // Check if there are more bytes to send or receive and write proper data - // byte (next one from TX buffer or over-run character) to the TXD register - // when needed. - // NOTE - we've already used 'p_cb->bytes_transferred + 1' bytes from our - // buffers, because we take advantage of double buffering of TXD - // register (so in effect one byte is still being transmitted now); - // see how the transfer is started in the 'nrf_drv_spi_transfer' - // function. - uint16_t bytes_used = p_cb->bytes_transferred + 1; - if (bytes_used < p_cb->evt.data.done.tx_length) - { - nrf_spi_txd_set(p_spi, p_cb->evt.data.done.p_tx_buffer[bytes_used]); - return true; - } - else if (bytes_used < p_cb->evt.data.done.rx_length) - { - nrf_spi_txd_set(p_spi, p_cb->orc); - return true; - } - - return (p_cb->bytes_transferred < p_cb->evt.data.done.tx_length || - p_cb->bytes_transferred < p_cb->evt.data.done.rx_length); -} - -static void spi_xfer(NRF_SPI_Type * p_spi, - spi_control_block_t * p_cb, - nrf_drv_spi_xfer_desc_t const * p_xfer_desc) -{ - p_cb->bytes_transferred = 0; - nrf_spi_int_disable(p_spi, NRF_SPI_INT_READY_MASK); - - nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); - - // Start the transfer by writing some byte to the TXD register; - // if TX buffer is not empty, take the first byte from this buffer, - // otherwise - use over-run character. - nrf_spi_txd_set(p_spi, - (p_xfer_desc->tx_length > 0 ? p_xfer_desc->p_tx_buffer[0] : p_cb->orc)); - - // TXD register is double buffered, so next byte to be transmitted can - // be written immediately, if needed, i.e. if TX or RX transfer is to - // be more that 1 byte long. Again - if there is something more in TX - // buffer send it, otherwise use over-run character. - if (p_xfer_desc->tx_length > 1) - { - nrf_spi_txd_set(p_spi, p_xfer_desc->p_tx_buffer[1]); - } - else if (p_xfer_desc->rx_length > 1) - { - nrf_spi_txd_set(p_spi, p_cb->orc); - } - - // For blocking mode (user handler not provided) wait here for READY - // events (indicating that the byte from TXD register was transmitted - // and a new incoming byte was moved to the RXD register) and continue - // transaction until all requested bytes are transferred. - // In non-blocking mode - IRQ service routine will do this stuff. - if (p_cb->handler) - { - nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK); - } - else - { - do { - while (!nrf_spi_event_check(p_spi, NRF_SPI_EVENT_READY)) {} - nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); - } while (transfer_byte(p_spi, p_cb)); - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_set(p_cb->ss_pin); - } - } -} -#endif // SPI_IN_USE - -#ifdef SPIM_IN_USE -__STATIC_INLINE void spim_int_enable(NRF_SPIM_Type * p_spim, bool enable) -{ - if (!enable) - { - nrf_spim_int_disable(p_spim, END_INT_MASK | NRF_SPIM_INT_STOPPED_MASK); - } - else - { - nrf_spim_int_enable(p_spim, END_INT_MASK | NRF_SPIM_INT_STOPPED_MASK); - } -} - -__STATIC_INLINE void spim_list_enable_handle(NRF_SPIM_Type * p_spim, uint32_t flags) -{ -#ifndef NRF52_PAN_46 - if (NRF_DRV_SPI_FLAG_TX_POSTINC & flags) - { - nrf_spim_tx_list_enable(p_spim); - } - else - { - nrf_spim_tx_list_disable(p_spim); - } - - if (NRF_DRV_SPI_FLAG_RX_POSTINC & flags) - { - nrf_spim_rx_list_enable(p_spim); - } - else - { - nrf_spim_rx_list_disable(p_spim); - } -#endif -} - -static ret_code_t spim_xfer(NRF_SPIM_Type * p_spim, - spi_control_block_t * p_cb, - nrf_drv_spi_xfer_desc_t const * p_xfer_desc, - uint32_t flags) -{ - // EasyDMA requires that transfer buffers are placed in Data RAM region; - // signal error if they are not. - if ((p_xfer_desc->p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_tx_buffer)) || - (p_xfer_desc->p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_rx_buffer))) - { - p_cb->transfer_in_progress = false; - return NRF_ERROR_INVALID_ADDR; - } - - nrf_spim_tx_buffer_set(p_spim, p_xfer_desc->p_tx_buffer, p_xfer_desc->tx_length); - nrf_spim_rx_buffer_set(p_spim, p_xfer_desc->p_rx_buffer, p_xfer_desc->rx_length); - -#ifdef NRF52_PAN_23 - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDTX); - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDRX); -#else - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END); -#endif - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_STOPPED); - - spim_list_enable_handle(p_spim, flags); - - if (!(flags & NRF_DRV_SPI_FLAG_HOLD_XFER)) - { - nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START); - } - - if (!p_cb->handler) - { -#ifdef NRF52_PAN_23 - while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDTX) || - !nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDRX)) {} -#else - while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)){} -#endif - // Stop the peripheral after transaction is finished. - nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP); - while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) {} - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_set(p_cb->ss_pin); - } - } - else - { - spim_int_enable(p_spim, !(flags & NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER)); - } - return NRF_SUCCESS; -} -#endif - -ret_code_t nrf_drv_spi_xfer(nrf_drv_spi_t const * const p_instance, - nrf_drv_spi_xfer_desc_t const * p_xfer_desc, - uint32_t flags) -{ - spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(p_tx_buffer != NULL || tx_buffer_length == 0); - ASSERT(p_rx_buffer != NULL || rx_buffer_length == 0); - - if (p_cb->transfer_in_progress) - { - return NRF_ERROR_BUSY; - } - else - { - if (p_cb->handler && !(flags & (NRF_DRV_SPI_FLAG_REPEATED_XFER | NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER))) - { - p_cb->transfer_in_progress = true; - } - } - - p_cb->evt.data.done = *p_xfer_desc; - p_cb->tx_done = false; - p_cb->rx_done = false; - - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_clear(p_cb->ss_pin); - } - CODE_FOR_SPIM - ( - return spim_xfer(p_instance->p_registers, p_cb, p_xfer_desc, flags); - ) - CODE_FOR_SPI - ( - if (flags) - { - p_cb->transfer_in_progress = false; - return NRF_ERROR_NOT_SUPPORTED; - } - spi_xfer(p_instance->p_registers, p_cb, p_xfer_desc); - return NRF_SUCCESS; - ) -} -#ifdef SPIM_IN_USE -static void irq_handler_spim(NRF_SPIM_Type * p_spim, spi_control_block_t * p_cb) -{ - ASSERT(p_cb->handler); - -#ifdef NRF52_PAN_23 - if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) - { - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_STOPPED); - finish_transfer(p_cb); - } - else - { - if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDTX)) - { - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDTX); - p_cb->tx_done = true; - } - if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDRX)) - { - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDRX); - p_cb->rx_done = true; - } - if (p_cb->tx_done && p_cb->rx_done) - { - nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP); - } - } -#else - if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)) - { - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END); - finish_transfer(p_cb); - } -#endif -} - -uint32_t nrf_drv_spi_start_task_get(nrf_drv_spi_t const * p_instance) -{ - NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; - return nrf_spim_task_address_get(p_spim, NRF_SPIM_TASK_START); -} - -uint32_t nrf_drv_spi_end_event_get(nrf_drv_spi_t const * p_instance) -{ - NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; - return nrf_spim_event_address_get(p_spim, NRF_SPIM_EVENT_END); -} -#endif // SPIM_IN_USE - -#ifdef SPI_IN_USE -static void irq_handler_spi(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) -{ - ASSERT(p_cb->handler); - - nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); - - if (!transfer_byte(p_spi, p_cb)) - { - finish_transfer(p_cb); - } -} -#endif // SPI_IN_USE - -#if SPI0_ENABLED -IRQ_HANDLER(0) -{ - spi_control_block_t * p_cb = &m_cb[SPI0_INSTANCE_INDEX]; - #if SPI0_USE_EASY_DMA - irq_handler_spim(NRF_SPIM0, p_cb); - #else - irq_handler_spi(NRF_SPI0, p_cb); - #endif -} -#endif // SPI0_ENABLED - -#if SPI1_ENABLED -IRQ_HANDLER(1) -{ - spi_control_block_t * p_cb = &m_cb[SPI1_INSTANCE_INDEX]; - #if SPI1_USE_EASY_DMA - irq_handler_spim(NRF_SPIM1, p_cb); - #else - irq_handler_spi(NRF_SPI1, p_cb); - #endif -} -#endif // SPI1_ENABLED - -#if SPI2_ENABLED -IRQ_HANDLER(2) -{ - spi_control_block_t * p_cb = &m_cb[SPI2_INSTANCE_INDEX]; - #if SPI2_USE_EASY_DMA - irq_handler_spim(NRF_SPIM2, p_cb); - #else - irq_handler_spi(NRF_SPI2, p_cb); - #endif -} -#endif // SPI2_ENABLED http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a1481cb2/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.h ---------------------------------------------------------------------- diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.h deleted file mode 100644 index 1e0c900..0000000 --- a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/drivers_nrf/spi_master/nrf_drv_spi.h +++ /dev/null @@ -1,376 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRANTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - */ - -/**@file - * @addtogroup nrf_spi Serial peripheral interface (SPI) - * @ingroup nrf_drivers - * @brief Serial peripheral interface (SPI) APIs. - * - * - * @addtogroup nrf_spi_master SPI master HAL and driver - * @ingroup nrf_spi - * @brief SPI master APIs. - */ - -#ifndef NRF_DRV_SPI_H__ -#define NRF_DRV_SPI_H__ - -#include "nordic_common.h" -#include "nrf_drv_config.h" -#include "nrf_spi.h" -#include "nrf_spim.h" -#include "sdk_errors.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(NRF52) - #define NRF_DRV_SPI_PERIPHERAL(id) \ - (CONCAT_3(SPI, id, _USE_EASY_DMA) == 1 ? \ - (void *)CONCAT_2(NRF_SPIM, id) \ - : (void *)CONCAT_2(NRF_SPI, id)) - #define SPI2_IRQ SPIM2_SPIS2_SPI2_IRQn - #define SPI2_IRQ_HANDLER SPIM2_SPIS2_SPI2_IRQHandler -#else - #define NRF_DRV_SPI_PERIPHERAL(id) (void *)CONCAT_2(NRF_SPI, id) -#endif -#define SPI0_IRQ SPI0_TWI0_IRQn -#define SPI0_IRQ_HANDLER SPI0_TWI0_IRQHandler -#define SPI1_IRQ SPI1_TWI1_IRQn -#define SPI1_IRQ_HANDLER SPI1_TWI1_IRQHandler - - -/** - * @defgroup nrf_drv_spi_master SPI master driver - * @{ - * @ingroup nrf_spi_master - * - * @brief Multi-instance SPI master driver. - */ - -/** - * @brief SPI master driver instance data structure. - */ -typedef struct -{ - void * p_registers; ///< Pointer to the structure with SPI/SPIM peripheral instance registers. - IRQn_Type irq; ///< SPI/SPIM peripheral instance IRQ number. - uint8_t drv_inst_idx; ///< Driver instance index. - bool use_easy_dma; ///< True if the peripheral with EasyDMA (SPIM) shall be used. -} nrf_drv_spi_t; - -/** - * @brief Macro for creating an SPI master driver instance. - */ -#define NRF_DRV_SPI_INSTANCE(id) \ -{ \ - .p_registers = NRF_DRV_SPI_PERIPHERAL(id), \ - .irq = CONCAT_3(SPI, id, _IRQ), \ - .drv_inst_idx = CONCAT_3(SPI, id, _INSTANCE_INDEX), \ - .use_easy_dma = CONCAT_3(SPI, id, _USE_EASY_DMA) \ -} - -/** - * @brief This value can be provided instead of a pin number for signals MOSI, - * MISO, and Slave Select to specify that the given signal is not used and - * therefore does not need to be connected to a pin. - */ -#define NRF_DRV_SPI_PIN_NOT_USED 0xFF - -/** - * @brief SPI data rates. - */ -typedef enum -{ - NRF_DRV_SPI_FREQ_125K = NRF_SPI_FREQ_125K, ///< 125 kbps. - NRF_DRV_SPI_FREQ_250K = NRF_SPI_FREQ_250K, ///< 250 kbps. - NRF_DRV_SPI_FREQ_500K = NRF_SPI_FREQ_500K, ///< 500 kbps. - NRF_DRV_SPI_FREQ_1M = NRF_SPI_FREQ_1M, ///< 1 Mbps. - NRF_DRV_SPI_FREQ_2M = NRF_SPI_FREQ_2M, ///< 2 Mbps. - NRF_DRV_SPI_FREQ_4M = NRF_SPI_FREQ_4M, ///< 4 Mbps. - NRF_DRV_SPI_FREQ_8M = NRF_SPI_FREQ_8M ///< 8 Mbps. -} nrf_drv_spi_frequency_t; - -/** - * @brief SPI modes. - */ -typedef enum -{ - NRF_DRV_SPI_MODE_0 = NRF_SPI_MODE_0, ///< SCK active high, sample on leading edge of clock. - NRF_DRV_SPI_MODE_1 = NRF_SPI_MODE_1, ///< SCK active high, sample on trailing edge of clock. - NRF_DRV_SPI_MODE_2 = NRF_SPI_MODE_2, ///< SCK active low, sample on leading edge of clock. - NRF_DRV_SPI_MODE_3 = NRF_SPI_MODE_3 ///< SCK active low, sample on trailing edge of clock. -} nrf_drv_spi_mode_t; - -/** - * @brief SPI bit orders. - */ -typedef enum -{ - NRF_DRV_SPI_BIT_ORDER_MSB_FIRST = NRF_SPI_BIT_ORDER_MSB_FIRST, ///< Most significant bit shifted out first. - NRF_DRV_SPI_BIT_ORDER_LSB_FIRST = NRF_SPI_BIT_ORDER_LSB_FIRST ///< Least significant bit shifted out first. -} nrf_drv_spi_bit_order_t; - -/** - * @brief SPI master driver instance configuration structure. - */ -typedef struct -{ - uint8_t sck_pin; ///< SCK pin number. - uint8_t mosi_pin; ///< MOSI pin number (optional). - /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED - * if this signal is not needed. */ - uint8_t miso_pin; ///< MISO pin number (optional). - /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED - * if this signal is not needed. */ - uint8_t ss_pin; ///< Slave Select pin number (optional). - /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED - * if this signal is not needed. The driver - * supports only active low for this signal. - * If the signal should be active high, - * it must be controlled externally. */ - uint8_t irq_priority; ///< Interrupt priority. - uint8_t orc; ///< Over-run character. - /**< This character is used when all bytes from the TX buffer are sent, - but the transfer continues due to RX. */ - nrf_drv_spi_frequency_t frequency; ///< SPI frequency. - nrf_drv_spi_mode_t mode; ///< SPI mode. - nrf_drv_spi_bit_order_t bit_order; ///< SPI bit order. -} nrf_drv_spi_config_t; - -/** - * @brief SPI master instance default configuration. - */ -#define NRF_DRV_SPI_DEFAULT_CONFIG(id) \ -{ \ - .sck_pin = CONCAT_3(SPI, id, _CONFIG_SCK_PIN), \ - .mosi_pin = CONCAT_3(SPI, id, _CONFIG_MOSI_PIN), \ - .miso_pin = CONCAT_3(SPI, id, _CONFIG_MISO_PIN), \ - .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, \ - .irq_priority = CONCAT_3(SPI, id, _CONFIG_IRQ_PRIORITY), \ - .orc = 0xFF, \ - .frequency = NRF_DRV_SPI_FREQ_4M, \ - .mode = NRF_DRV_SPI_MODE_0, \ - .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, \ -} - -#define NRF_DRV_SPI_FLAG_TX_POSTINC (1UL << 0) /**< TX buffer address incremented after transfer. */ -#define NRF_DRV_SPI_FLAG_RX_POSTINC (1UL << 1) /**< RX buffer address incremented after transfer. */ -#define NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2) /**< Interrupt after each transfer is suppressed, and the event handler is not called. */ -#define NRF_DRV_SPI_FLAG_HOLD_XFER (1UL << 3) /**< Set up the transfer but do not start it. */ -#define NRF_DRV_SPI_FLAG_REPEATED_XFER (1UL << 4) /**< Flag indicating that the transfer will be executed multiple times. */ - -/** - * @brief Single transfer descriptor structure. - */ -typedef struct -{ - uint8_t const * p_tx_buffer; ///< Pointer to TX buffer. - uint8_t tx_length; ///< TX buffer length. - uint8_t * p_rx_buffer; ///< Pointer to RX buffer. - uint8_t rx_length; ///< RX buffer length. -}nrf_drv_spi_xfer_desc_t; - - -/** - * @brief Macro for setting up single transfer descriptor. - * - * This macro is for internal use only. - */ -#define NRF_DRV_SPI_SINGLE_XFER(p_tx, tx_len, p_rx, rx_len) \ - { \ - .p_tx_buffer = (uint8_t const *)(p_tx), \ - .tx_length = (tx_len), \ - .p_rx_buffer = (p_rx), \ - .rx_length = (rx_len), \ - } - -/** - * @brief Macro for setting duplex TX RX transfer. - */ -#define NRF_DRV_SPI_XFER_TRX(p_tx_buf, tx_length, p_rx_buf, rx_length) \ - NRF_DRV_SPI_SINGLE_XFER(p_tx_buf, tx_length, p_rx_buf, rx_length) - -/** - * @brief Macro for setting TX transfer. - */ -#define NRF_DRV_SPI_XFER_TX(p_buf, length) \ - NRF_DRV_SPI_SINGLE_XFER(p_buf, length, NULL, 0) - -/** - * @brief Macro for setting RX transfer. - */ -#define NRF_DRV_SPI_XFER_RX(p_buf, length) \ - NRF_DRV_SPI_SINGLE_XFER(NULL, 0, p_buf, length) - -/** - * @brief SPI master driver event types, passed to the handler routine provided - * during initialization. - */ -typedef enum -{ - NRF_DRV_SPI_EVENT_DONE, ///< Transfer done. -} nrf_drv_spi_evt_type_t; - -typedef struct -{ - nrf_drv_spi_evt_type_t type; ///< Event type. - union - { - nrf_drv_spi_xfer_desc_t done; ///< Event data for DONE event. - } data; -} nrf_drv_spi_evt_t; - -/** - * @brief SPI master driver event handler type. - */ -typedef void (*nrf_drv_spi_handler_t)(nrf_drv_spi_evt_t const * p_event); - - -/** - * @brief Function for initializing the SPI master driver instance. - * - * This function configures and enables the specified peripheral. - * - * @param[in] p_instance Pointer to the instance structure. - * @param[in] p_config Pointer to the structure with the initial configuration. - * If NULL, the default configuration is used. - * @param handler Event handler provided by the user. If NULL, transfers - * will be performed in blocking mode. - * - * @retval NRF_SUCCESS If initialization was successful. - * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. - * @retval NRF_ERROR_BUSY If some other peripheral with the same - * instance ID is already in use. This is - * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED - * is set to a value other than zero. - */ -ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, - nrf_drv_spi_config_t const * p_config, - nrf_drv_spi_handler_t handler); - -/** - * @brief Function for uninitializing the SPI master driver instance. - * - * @param[in] p_instance Pointer to the instance structure. - */ -void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance); - -/** - * @brief Function for starting the SPI data transfer. - * - * If an event handler was provided in the @ref nrf_drv_spi_init call, this function - * returns immediately and the handler is called when the transfer is done. - * Otherwise, the transfer is performed in blocking mode, which means that this function - * returns when the transfer is finished. - * - * @note Peripherals using EasyDMA (for example, SPIM) require the transfer buffers - * to be placed in the Data RAM region. If they are not and an SPIM instance is - * used, this function will fail with the error code NRF_ERROR_INVALID_ADDR. - * - * @param[in] p_instance Pointer to the instance structure. - * @param[in] p_tx_buffer Pointer to the transmit buffer. Can be NULL - * if there is nothing to send. - * @param tx_buffer_length Length of the transmit buffer. - * @param[in] p_rx_buffer Pointer to the receive buffer. Can be NULL - * if there is nothing to receive. - * @param rx_buffer_length Length of the receive buffer. - * - * @retval NRF_SUCCESS If the operation was successful. - * @retval NRF_ERROR_BUSY If a previously started transfer has not finished - * yet. - * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data - * RAM region. - */ -ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, - uint8_t const * p_tx_buffer, - uint8_t tx_buffer_length, - uint8_t * p_rx_buffer, - uint8_t rx_buffer_length); - - -/** - * @brief Function for starting the SPI data transfer with additional option flags. - * - * Function enables customizing the transfer by using option flags. - * - * Additional options are provided using the flags parameter: - * - * - @ref NRF_DRV_SPI_FLAG_TX_POSTINC and @ref NRF_DRV_SPI_FLAG_RX_POSTINC<span></span>: - * Post-incrementation of buffer addresses. Supported only by SPIM. - * - @ref NRF_DRV_SPI_FLAG_HOLD_XFER<span></span>: Driver is not starting the transfer. Use this - * flag if the transfer is triggered externally by PPI. Supported only by SPIM. Use - * @ref nrf_drv_twi_start_task_get to get the address of the start task. - * - @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER<span></span>: No user event handler after transfer - * completion. This also means no interrupt at the end of the transfer. Supported only by SPIM. - * If @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER is used, the driver does not set the instance into - * busy state, so you must ensure that the next transfers are set up when SPIM is not active. - * @ref nrf_drv_spi_end_event_get function can be used to detect end of transfer. Option can be used - * together with @ref NRF_DRV_SPI_FLAG_REPEATED_XFER to prepare a sequence of SPI transfers - * without interruptions. - * - @ref NRF_DRV_SPI_FLAG_REPEATED_XFER<span></span>: Prepare for repeated transfers. You can set - * up a number of transfers that will be triggered externally (for example by PPI). An example is - * a TXRX transfer with the options @ref NRF_DRV_SPI_FLAG_RX_POSTINC, - * @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER, and @ref NRF_DRV_SPI_FLAG_REPEATED_XFER. After the - * transfer is set up, a set of transfers can be triggered by PPI that will read, for example, - * the same register of an external component and put it into a RAM buffer without any interrupts. - * @ref nrf_drv_spi_end_event_get can be used to get the address of the END event, which can be - * used to count the number of transfers. If @ref NRF_DRV_SPI_FLAG_REPEATED_XFER is used, - * the driver does not set the instance into busy state, so you must ensure that the next - * transfers are set up when SPIM is not active. Supported only by SPIM. - * @note Function is intended to be used only in non-blocking mode. - * - * @param p_instance SPI instance. - * @param p_xfer_desc Pointer to the transfer descriptor. - * @param flags Transfer options (0 for default settings). - * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. - * @retval NRF_ERROR_NOT_SUPPORTED If the provided parameters are not supported. - * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data - * RAM region. - */ -ret_code_t nrf_drv_spi_xfer(nrf_drv_spi_t const * const p_instance, - nrf_drv_spi_xfer_desc_t const * p_xfer_desc, - uint32_t flags); - -/** - * @brief Function for returning the address of a SPIM start task. - * - * This function should be used if @ref nrf_drv_spi_xfer was called with the flag @ref NRF_DRV_SPI_FLAG_HOLD_XFER. - * In that case, the transfer is not started by the driver, but it must be started externally by PPI. - * - * @param[in] p_instance SPI instance. - * - * @return Start task address. - */ -uint32_t nrf_drv_spi_start_task_get(nrf_drv_spi_t const * p_instance); - -/** - * @brief Function for returning the address of a END SPIM event. - * - * A END event can be used to detect the end of a transfer if the @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER - * option is used. - * - * @param[in] p_instance SPI instance. - * - * @return END event address. - */ -uint32_t nrf_drv_spi_end_event_get(nrf_drv_spi_t const * p_instance); -#ifdef __cplusplus -} -#endif - -#endif // NRF_DRV_SPI_H__ - -/** @} */
