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_SPI_H__ 33 #define NRFX_SPI_H__ 34 35 #include <nrfx.h> 36 #include <hal/nrf_spi.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * @defgroup nrfx_spi SPI driver 44 * @{ 45 * @ingroup nrf_spi 46 * @brief SPI peripheral driver. 47 */ 48 49 /** 50 * @brief SPI master driver instance data structure. 51 */ 52 typedef struct 53 { 54 NRF_SPI_Type * p_reg; ///< Pointer to a structure with SPI registers. 55 uint8_t drv_inst_idx; ///< Driver instance index. 56 } nrfx_spi_t; 57 58 enum { 59 #if NRFX_CHECK(NRFX_SPI0_ENABLED) 60 NRFX_SPI0_INST_IDX, 61 #endif 62 #if NRFX_CHECK(NRFX_SPI1_ENABLED) 63 NRFX_SPI1_INST_IDX, 64 #endif 65 #if NRFX_CHECK(NRFX_SPI2_ENABLED) 66 NRFX_SPI2_INST_IDX, 67 #endif 68 NRFX_SPI_ENABLED_COUNT 69 }; 70 71 /** 72 * @brief Macro for creating an SPI master driver instance. 73 */ 74 #define NRFX_SPI_INSTANCE(id) \ 75 { \ 76 .p_reg = NRFX_CONCAT_2(NRF_SPI, id), \ 77 .drv_inst_idx = NRFX_CONCAT_3(NRFX_SPI, id, _INST_IDX), \ 78 } 79 80 /** 81 * @brief This value can be provided instead of a pin number for signals MOSI, 82 * MISO, and Slave Select to specify that the given signal is not used and 83 * therefore does not need to be connected to a pin. 84 */ 85 #define NRFX_SPI_PIN_NOT_USED 0xFF 86 87 /** 88 * @brief SPI master driver instance configuration structure. 89 */ 90 typedef struct 91 { 92 uint8_t sck_pin; ///< SCK pin number. 93 uint8_t mosi_pin; ///< MOSI pin number (optional). 94 /**< Set to @ref NRFX_SPI_PIN_NOT_USED 95 * if this signal is not needed. */ 96 uint8_t miso_pin; ///< MISO pin number (optional). 97 /**< Set to @ref NRFX_SPI_PIN_NOT_USED 98 * if this signal is not needed. */ 99 uint8_t ss_pin; ///< Slave Select pin number (optional). 100 /**< Set to @ref NRFX_SPI_PIN_NOT_USED 101 * if this signal is not needed. The driver 102 * supports only active low for this signal. 103 * If the signal should be active high, 104 * it must be controlled externally. */ 105 uint8_t irq_priority; ///< Interrupt priority. 106 uint8_t orc; ///< Over-run character. 107 /**< This character is used when all bytes from the TX buffer are sent, 108 but the transfer continues due to RX. */ 109 nrf_spi_frequency_t frequency; ///< SPI frequency. 110 nrf_spi_mode_t mode; ///< SPI mode. 111 nrf_spi_bit_order_t bit_order; ///< SPI bit order. 112 } nrfx_spi_config_t; 113 114 /** 115 * @brief SPI master instance default configuration. 116 */ 117 #define NRFX_SPI_DEFAULT_CONFIG \ 118 { \ 119 .sck_pin = NRFX_SPI_PIN_NOT_USED, \ 120 .mosi_pin = NRFX_SPI_PIN_NOT_USED, \ 121 .miso_pin = NRFX_SPI_PIN_NOT_USED, \ 122 .ss_pin = NRFX_SPI_PIN_NOT_USED, \ 123 .irq_priority = NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \ 124 .orc = 0xFF, \ 125 .frequency = NRF_SPI_FREQ_4M, \ 126 .mode = NRF_SPI_MODE_0, \ 127 .bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST, \ 128 } 129 130 /** 131 * @brief Single transfer descriptor structure. 132 */ 133 typedef struct 134 { 135 uint8_t const * p_tx_buffer; ///< Pointer to TX buffer. 136 size_t tx_length; ///< TX buffer length. 137 uint8_t * p_rx_buffer; ///< Pointer to RX buffer. 138 size_t rx_length; ///< RX buffer length. 139 } nrfx_spi_xfer_desc_t; 140 141 /** 142 * @brief Macro for setting up single transfer descriptor. 143 * 144 * This macro is for internal use only. 145 */ 146 #define NRFX_SPI_SINGLE_XFER(p_tx, tx_len, p_rx, rx_len) \ 147 { \ 148 .p_tx_buffer = (uint8_t const *)(p_tx), \ 149 .tx_length = (tx_len), \ 150 .p_rx_buffer = (p_rx), \ 151 .rx_length = (rx_len), \ 152 } 153 154 /** 155 * @brief Macro for setting duplex TX RX transfer. 156 */ 157 #define NRFX_SPI_XFER_TRX(p_tx_buf, tx_length, p_rx_buf, rx_length) \ 158 NRFX_SPI_SINGLE_XFER(p_tx_buf, tx_length, p_rx_buf, rx_length) 159 160 /** 161 * @brief Macro for setting TX transfer. 162 */ 163 #define NRFX_SPI_XFER_TX(p_buf, length) \ 164 NRFX_SPI_SINGLE_XFER(p_buf, length, NULL, 0) 165 166 /** 167 * @brief Macro for setting RX transfer. 168 */ 169 #define NRFX_SPI_XFER_RX(p_buf, length) \ 170 NRFX_SPI_SINGLE_XFER(NULL, 0, p_buf, length) 171 172 /** 173 * @brief SPI master driver event types, passed to the handler routine provided 174 * during initialization. 175 */ 176 typedef enum 177 { 178 NRFX_SPI_EVENT_DONE, ///< Transfer done. 179 } nrfx_spi_evt_type_t; 180 181 typedef struct 182 { 183 nrfx_spi_evt_type_t type; ///< Event type. 184 nrfx_spi_xfer_desc_t xfer_desc; ///< Transfer details. 185 } nrfx_spi_evt_t; 186 187 /** 188 * @brief SPI master driver event handler type. 189 */ 190 typedef void (* nrfx_spi_evt_handler_t)(nrfx_spi_evt_t const * p_event, 191 void * p_context); 192 193 /** 194 * @brief Function for initializing the SPI master driver instance. 195 * 196 * This function configures and enables the specified peripheral. 197 * 198 * @param[in] p_instance Pointer to the driver instance structure. 199 * @param[in] p_config Pointer to the structure with initial configuration. 200 * 201 * @param handler Event handler provided by the user. If NULL, transfers 202 * will be performed in blocking mode. 203 * @param p_context Context passed to event handler. 204 * 205 * @retval NRFX_SUCCESS If initialization was successful. 206 * @retval NRFX_ERROR_INVALID_STATE If the driver was already initialized. 207 * @retval NRFX_ERROR_BUSY If some other peripheral with the same 208 * instance ID is already in use. This is 209 * possible only if @ref nrfx_prs module 210 * is enabled. 211 */ 212 nrfx_err_t nrfx_spi_init(nrfx_spi_t const * const p_instance, 213 nrfx_spi_config_t const * p_config, 214 nrfx_spi_evt_handler_t handler, 215 void * p_context); 216 217 /** 218 * @brief Function for uninitializing the SPI master driver instance. 219 * 220 * @param[in] p_instance Pointer to the driver instance structure. 221 */ 222 void nrfx_spi_uninit(nrfx_spi_t const * const p_instance); 223 224 /** 225 * @brief Function for starting the SPI data transfer. 226 * 227 * If an event handler was provided in the @ref nrfx_spi_init call, this function 228 * returns immediately and the handler is called when the transfer is done. 229 * Otherwise, the transfer is performed in blocking mode, which means that this function 230 * returns when the transfer is finished. 231 * 232 * @param p_instance Pointer to the driver instance structure. 233 * @param p_xfer_desc Pointer to the transfer descriptor. 234 * @param flags Transfer options (0 for default settings). 235 * Currently, no additional flags are available. 236 * 237 * @retval NRFX_SUCCESS If the procedure was successful. 238 * @retval NRFX_ERROR_BUSY If the driver is not ready for a new transfer. 239 * @retval NRFX_ERROR_NOT_SUPPORTED If the provided parameters are not supported. 240 */ 241 nrfx_err_t nrfx_spi_xfer(nrfx_spi_t const * const p_instance, 242 nrfx_spi_xfer_desc_t const * p_xfer_desc, 243 uint32_t flags); 244 245 /** 246 * @brief Function for aborting ongoing transfer. 247 * 248 * @param[in] p_instance Pointer to the driver instance structure. 249 */ 250 void nrfx_spi_abort(nrfx_spi_t const * p_instance); 251 252 253 void nrfx_spi_0_irq_handler(void); 254 void nrfx_spi_1_irq_handler(void); 255 void nrfx_spi_2_irq_handler(void); 256 257 258 /** @} */ 259 260 #ifdef __cplusplus 261 } 262 #endif 263 264 #endif // NRFX_SPI_H__ 265