1 /* 2 * Copyright (c) 2015 - 2020, 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 #include <hal/nrf_gpio.h> 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /** 44 * @defgroup nrfx_spi SPI driver 45 * @{ 46 * @ingroup nrf_spi 47 * @brief Serial Peripheral Interface master (SPI) driver. 48 */ 49 50 /** @brief Data structure of the Serial Peripheral Interface master (SPI) driver instance. */ 51 typedef struct 52 { 53 NRF_SPI_Type * p_reg; ///< Pointer to a structure with SPI registers. 54 uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only. 55 } nrfx_spi_t; 56 57 #ifndef __NRFX_DOXYGEN__ 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 #endif 71 72 /** @brief Macro for creating an instance of the SPI master driver. */ 73 #define NRFX_SPI_INSTANCE(id) \ 74 { \ 75 .p_reg = NRFX_CONCAT_2(NRF_SPI, id), \ 76 .drv_inst_idx = NRFX_CONCAT_3(NRFX_SPI, id, _INST_IDX), \ 77 } 78 79 /** 80 * @brief This value can be provided instead of a pin number for signals MOSI, 81 * MISO, and Slave Select to specify that the given signal is not used and 82 * therefore does not need to be connected to a pin. 83 */ 84 #define NRFX_SPI_PIN_NOT_USED 0xFF 85 86 /** @brief Configuration structure of the SPI master driver instance. */ 87 typedef struct 88 { 89 uint8_t sck_pin; ///< SCK pin number. 90 uint8_t mosi_pin; ///< MOSI pin number (optional). 91 /**< Set to @ref NRFX_SPI_PIN_NOT_USED 92 * if this signal is not needed. */ 93 uint8_t miso_pin; ///< MISO pin number (optional). 94 /**< Set to @ref NRFX_SPI_PIN_NOT_USED 95 * if this signal is not needed. */ 96 uint8_t ss_pin; ///< Slave Select pin number (optional). 97 /**< Set to @ref NRFX_SPI_PIN_NOT_USED 98 * if this signal is not needed. The driver 99 * supports only active low for this signal. 100 * If the signal must be active high, 101 * it must be controlled externally. */ 102 uint8_t irq_priority; ///< Interrupt priority. 103 uint8_t orc; ///< Overrun character. 104 /**< This character is used when all bytes from the TX buffer are sent, 105 but the transfer continues due to RX. */ 106 nrf_spi_frequency_t frequency; ///< SPI frequency. 107 nrf_spi_mode_t mode; ///< SPI mode. 108 nrf_spi_bit_order_t bit_order; ///< SPI bit order. 109 nrf_gpio_pin_pull_t miso_pull; ///< MISO pull up configuration. 110 } nrfx_spi_config_t; 111 112 /** 113 * @brief SPI master instance default configuration. 114 * This configuration sets up SPI with the following options: 115 * - over-run character set to 0xFF 116 * - clock frequency 4 MHz 117 * - mode 0 enabled (SCK active high, sample on leading edge of clock) 118 * - MSB shifted out first 119 * - MISO pull-up disabled 120 * 121 * @param[in] _pin_sck SCK pin. 122 * @param[in] _pin_mosi MOSI pin. 123 * @param[in] _pin_miso MISO pin. 124 * @param[in] _pin_ss SS pin. 125 */ 126 #define NRFX_SPI_DEFAULT_CONFIG(_pin_sck, _pin_mosi, _pin_miso, _pin_ss) \ 127 { \ 128 .sck_pin = _pin_sck, \ 129 .mosi_pin = _pin_mosi, \ 130 .miso_pin = _pin_miso, \ 131 .ss_pin = _pin_ss, \ 132 .irq_priority = NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \ 133 .orc = 0xFF, \ 134 .frequency = NRF_SPI_FREQ_4M, \ 135 .mode = NRF_SPI_MODE_0, \ 136 .bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST, \ 137 .miso_pull = NRF_GPIO_PIN_NOPULL, \ 138 } 139 140 /** @brief Single transfer descriptor structure. */ 141 typedef struct 142 { 143 uint8_t const * p_tx_buffer; ///< Pointer to TX buffer. 144 size_t tx_length; ///< TX buffer length. 145 uint8_t * p_rx_buffer; ///< Pointer to RX buffer. 146 size_t rx_length; ///< RX buffer length. 147 }nrfx_spi_xfer_desc_t; 148 149 /** 150 * @brief Macro for setting up single transfer descriptor. 151 * 152 * This macro is for internal use only. 153 */ 154 #define NRFX_SPI_SINGLE_XFER(p_tx, tx_len, p_rx, rx_len) \ 155 { \ 156 .p_tx_buffer = (uint8_t const *)(p_tx), \ 157 .tx_length = (tx_len), \ 158 .p_rx_buffer = (p_rx), \ 159 .rx_length = (rx_len), \ 160 } 161 162 /** @brief Macro for setting the duplex TX RX transfer. */ 163 #define NRFX_SPI_XFER_TRX(p_tx_buf, tx_length, p_rx_buf, rx_length) \ 164 NRFX_SPI_SINGLE_XFER(p_tx_buf, tx_length, p_rx_buf, rx_length) 165 166 /** @brief Macro for setting the TX transfer. */ 167 #define NRFX_SPI_XFER_TX(p_buf, length) \ 168 NRFX_SPI_SINGLE_XFER(p_buf, length, NULL, 0) 169 170 /** @brief Macro for setting the RX transfer. */ 171 #define NRFX_SPI_XFER_RX(p_buf, length) \ 172 NRFX_SPI_SINGLE_XFER(NULL, 0, p_buf, length) 173 174 /** 175 * @brief SPI master driver event types, passed to the handler routine provided 176 * during initialization. 177 */ 178 typedef enum 179 { 180 NRFX_SPI_EVENT_DONE, ///< Transfer done. 181 } nrfx_spi_evt_type_t; 182 183 /** @brief SPI master event description with transmission details. */ 184 typedef struct 185 { 186 nrfx_spi_evt_type_t type; ///< Event type. 187 nrfx_spi_xfer_desc_t xfer_desc; ///< Transfer details. 188 } nrfx_spi_evt_t; 189 190 /** @brief SPI master driver event handler type. */ 191 typedef void (* nrfx_spi_evt_handler_t)(nrfx_spi_evt_t const * p_event, 192 void * p_context); 193 194 /** 195 * @brief Function for initializing the SPI master driver instance. 196 * 197 * This function configures and enables the specified peripheral. 198 * 199 * @param[in] p_instance Pointer to the driver instance structure. 200 * @param[in] p_config Pointer to the structure with the initial configuration. 201 * @param[in] handler Event handler provided by the user. If NULL, transfers 202 * will be performed in blocking mode. 203 * @param[in] p_context Context passed to the event handler. 204 * 205 * @retval NRFX_SUCCESS Initialization was successful. 206 * @retval NRFX_ERROR_INVALID_STATE The driver was already initialized. 207 * @retval NRFX_ERROR_BUSY 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 * 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 * 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 The procedure is successful. 238 * @retval NRFX_ERROR_BUSY The driver is not ready for a new transfer. 239 * @retval NRFX_ERROR_NOT_SUPPORTED The provided parameters are not supported. 240 */ 241 nrfx_err_t nrfx_spi_xfer(nrfx_spi_t const * p_instance, 242 nrfx_spi_xfer_desc_t const * p_xfer_desc, 243 uint32_t flags); 244 245 /** 246 * @brief Function for aborting the 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 254 255 void nrfx_spi_0_irq_handler(void); 256 void nrfx_spi_1_irq_handler(void); 257 void nrfx_spi_2_irq_handler(void); 258 259 260 #ifdef __cplusplus 261 } 262 #endif 263 264 #endif // NRFX_SPI_H__ 265