xref: /nrf52832-nimble/nordic/nrfx/drivers/include/nrfx_spis.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_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