xref: /nrf52832-nimble/nordic/nrfx/drivers/include/nrfx_spi.h (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
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