1 /* 2 * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef NRFX_SPIS_H__ 33 #define NRFX_SPIS_H__ 34 35 #include <nrfx.h> 36 #include <hal/nrf_spis.h> 37 #include <hal/nrf_gpio.h> 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /** 44 * @defgroup nrfx_spis SPI slave driver 45 * @{ 46 * @ingroup nrf_spis 47 * @brief SPI Slave peripheral driver. 48 */ 49 50 /** @brief SPI slave driver instance data structure. */ 51 typedef struct 52 { 53 NRF_SPIS_Type * p_reg; //!< Pointer to a structure with SPIS registers. 54 uint8_t drv_inst_idx; //!< Driver instance index. 55 } nrfx_spis_t; 56 57 enum { 58 #if NRFX_CHECK(NRFX_SPIS0_ENABLED) 59 NRFX_SPIS0_INST_IDX, 60 #endif 61 #if NRFX_CHECK(NRFX_SPIS1_ENABLED) 62 NRFX_SPIS1_INST_IDX, 63 #endif 64 #if NRFX_CHECK(NRFX_SPIS2_ENABLED) 65 NRFX_SPIS2_INST_IDX, 66 #endif 67 #if NRFX_CHECK(NRFX_SPIS3_ENABLED) 68 NRFX_SPIS3_INST_IDX, 69 #endif 70 NRFX_SPIS_ENABLED_COUNT 71 }; 72 73 /** @brief Macro for creating an SPI slave driver instance. */ 74 #define NRFX_SPIS_INSTANCE(id) \ 75 { \ 76 .p_reg = NRFX_CONCAT_2(NRF_SPIS, id), \ 77 .drv_inst_idx = NRFX_CONCAT_3(NRFX_SPIS, id, _INST_IDX), \ 78 } 79 80 /** 81 * @brief This value can be provided instead of a pin number for the signals MOSI 82 * and MISO to specify that the given signal is not used and therefore 83 * does not need to be connected to a pin. 84 */ 85 #define NRFX_SPIS_PIN_NOT_USED 0xFF 86 87 /** @brief Default pull-up configuration of the SPI CS. */ 88 #define NRFX_SPIS_DEFAULT_CSN_PULLUP NRF_GPIO_PIN_NOPULL 89 /** @brief Default drive configuration of the SPI MISO. */ 90 #define NRFX_SPIS_DEFAULT_MISO_DRIVE NRF_GPIO_PIN_S0S1 91 92 /** @brief SPI slave driver event types. */ 93 typedef enum 94 { 95 NRFX_SPIS_BUFFERS_SET_DONE, //!< Memory buffer set event. Memory buffers have been set successfully to the SPI slave device, and SPI transaction can be done. 96 NRFX_SPIS_XFER_DONE, //!< SPI transaction event. SPI transaction has been completed. 97 NRFX_SPIS_EVT_TYPE_MAX //!< Enumeration upper bound. 98 } nrfx_spis_evt_type_t; 99 100 /** @brief SPI slave driver event structure. */ 101 typedef struct 102 { 103 nrfx_spis_evt_type_t evt_type; //!< Type of the event. 104 size_t rx_amount; //!< Number of bytes received in the last transaction. This parameter is only valid for @ref NRFX_SPIS_XFER_DONE events. 105 size_t tx_amount; //!< Number of bytes transmitted in the last transaction. This parameter is only valid for @ref NRFX_SPIS_XFER_DONE events. 106 } nrfx_spis_evt_t; 107 108 /** @brief SPI slave instance default configuration. */ 109 #define NRFX_SPIS_DEFAULT_CONFIG \ 110 { \ 111 .sck_pin = NRFX_SPIS_PIN_NOT_USED, \ 112 .mosi_pin = NRFX_SPIS_PIN_NOT_USED, \ 113 .miso_pin = NRFX_SPIS_PIN_NOT_USED, \ 114 .csn_pin = NRFX_SPIS_PIN_NOT_USED, \ 115 .mode = NRF_SPIS_MODE_0, \ 116 .bit_order = NRF_SPIS_BIT_ORDER_MSB_FIRST, \ 117 .csn_pullup = NRFX_SPIS_DEFAULT_CSN_PULLUP, \ 118 .miso_drive = NRFX_SPIS_DEFAULT_MISO_DRIVE, \ 119 .def = NRFX_SPIS_DEFAULT_DEF, \ 120 .orc = NRFX_SPIS_DEFAULT_ORC, \ 121 .irq_priority = NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY, \ 122 } 123 124 /** @brief SPI peripheral device configuration data. */ 125 typedef struct 126 { 127 uint32_t miso_pin; //!< SPI MISO pin (optional). 128 /**< Set @ref NRFX_SPIS_PIN_NOT_USED 129 * if this signal is not needed. */ 130 uint32_t mosi_pin; //!< SPI MOSI pin (optional). 131 /**< Set @ref NRFX_SPIS_PIN_NOT_USED 132 * if this signal is not needed. */ 133 uint32_t sck_pin; //!< SPI SCK pin. 134 uint32_t csn_pin; //!< SPI CSN pin. 135 nrf_spis_mode_t mode; //!< SPI mode. 136 nrf_spis_bit_order_t bit_order; //!< SPI transaction bit order. 137 nrf_gpio_pin_pull_t csn_pullup; //!< CSN pin pull-up configuration. 138 nrf_gpio_pin_drive_t miso_drive; //!< MISO pin drive configuration. 139 uint8_t def; //!< Character clocked out in case of an ignored transaction. 140 uint8_t orc; //!< Character clocked out after an over-read of the transmit buffer. 141 uint8_t irq_priority; //!< Interrupt priority. 142 } nrfx_spis_config_t; 143 144 145 /** 146 * @brief SPI slave driver event handler type. 147 * 148 * @param[in] p_event Pointer to the event structure. The structure is 149 * allocated on the stack so it is valid only until 150 * the event handler returns. 151 * @param[in] p_context Context set on initialization. 152 */ 153 typedef void (*nrfx_spis_event_handler_t)(nrfx_spis_evt_t const * p_event, 154 void * p_context); 155 156 /** 157 * @brief Function for initializing the SPI slave driver instance. 158 * 159 * @note When the nRF52 Anomaly 109 workaround for SPIS is enabled, this function 160 * initializes the GPIOTE driver as well, and uses one of GPIOTE channels 161 * to detect falling edges on CSN pin. 162 * 163 * @param[in] p_instance Pointer to the driver instance structure. 164 * @param[in] p_config Pointer to the structure with initial configuration. 165 * @param[in] event_handler Function to be called by the SPI slave driver upon event. 166 * Must not be NULL. 167 * @param[in] p_context Context passed to the event handler. 168 * 169 * @retval NRFX_SUCCESS If the initialization was successful. 170 * @retval NRFX_ERROR_INVALID_STATE If the instance is already initialized. 171 * @retval NRFX_ERROR_INVALID_PARAM If an invalid parameter is supplied. 172 * @retval NRFX_ERROR_BUSY If some other peripheral with the same 173 * instance ID is already in use. This is 174 * possible only if @ref nrfx_prs module 175 * is enabled. 176 * @retval NRFX_ERROR_INTERNAL GPIOTE channel for detecting falling edges 177 * on CSN pin cannot be initialized. Possible 178 * only when using nRF52 Anomaly 109 workaround. 179 */ 180 nrfx_err_t nrfx_spis_init(nrfx_spis_t const * const p_instance, 181 nrfx_spis_config_t const * p_config, 182 nrfx_spis_event_handler_t event_handler, 183 void * p_context); 184 185 /** 186 * @brief Function for uninitializing the SPI slave driver instance. 187 * 188 * @param[in] p_instance Pointer to the driver instance structure. 189 */ 190 void nrfx_spis_uninit(nrfx_spis_t const * const p_instance); 191 192 /** 193 * @brief Function for preparing the SPI slave instance for a single SPI transaction. 194 * 195 * This function prepares the SPI slave device to be ready for a single SPI transaction. It configures 196 * the SPI slave device to use the memory supplied with the function call in SPI transactions. 197 * 198 * When either the memory buffer configuration or the SPI transaction has been 199 * completed, the event callback function will be called with the appropriate event 200 * @ref nrfx_spis_evt_type_t. Note that the callback function can be called before returning from 201 * this function, because it is called from the SPI slave interrupt context. 202 * 203 * @note This function can be called from the callback function context. 204 * 205 * @note Client applications must call this function after every @ref NRFX_SPIS_XFER_DONE event if 206 * the SPI slave driver should be prepared for a possible new SPI transaction. 207 * 208 * @note Peripherals using EasyDMA (including SPIS) require the transfer buffers 209 * to be placed in the Data RAM region. If this condition is not met, 210 * this function will fail with the error code NRFX_ERROR_INVALID_ADDR. 211 * 212 * @param[in] p_instance Pointer to the driver instance structure. 213 * @param[in] p_tx_buffer Pointer to the TX buffer. Can be NULL when the buffer length is zero. 214 * @param[in] p_rx_buffer Pointer to the RX buffer. Can be NULL when the buffer length is zero. 215 * @param[in] tx_buffer_length Length of the TX buffer in bytes. 216 * @param[in] rx_buffer_length Length of the RX buffer in bytes. 217 * 218 * @retval NRFX_SUCCESS If the operation was successful. 219 * @retval NRFX_ERROR_INVALID_STATE If the operation failed because the SPI slave device is in an incorrect state. 220 * @retval NRFX_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data 221 * RAM region. 222 * @retval NRFX_ERROR_INVALID_LENGTH If provided lengths exceed the EasyDMA limits for the peripheral. 223 * @retval NRFX_ERROR_INTERNAL If the operation failed because of an internal error. 224 */ 225 nrfx_err_t nrfx_spis_buffers_set(nrfx_spis_t const * const p_instance, 226 uint8_t const * p_tx_buffer, 227 size_t tx_buffer_length, 228 uint8_t * p_rx_buffer, 229 size_t rx_buffer_length); 230 231 232 void nrfx_spis_0_irq_handler(void); 233 void nrfx_spis_1_irq_handler(void); 234 void nrfx_spis_2_irq_handler(void); 235 void nrfx_spis_3_irq_handler(void); 236 237 238 /** @} */ 239 240 #ifdef __cplusplus 241 } 242 #endif 243 244 #endif // NRFX_SPIS_H__ 245 246