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 NRF_SPIM_H__
33 #define NRF_SPIM_H__
34 
35 #include <nrfx.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /**
42  * @defgroup nrf_spim_hal SPIM HAL
43  * @{
44  * @ingroup nrf_spim
45  * @brief   Hardware access layer for managing the SPIM peripheral.
46  */
47 
48 /**
49  * @brief This value can be used as a parameter for the @ref nrf_spim_pins_set
50  *        function to specify that a given SPI signal (SCK, MOSI, or MISO)
51  *        shall not be connected to a physical pin.
52  */
53 #define NRF_SPIM_PIN_NOT_CONNECTED  0xFFFFFFFF
54 
55 /** @brief Macro for checking if the hardware chip select function is available. */
56 #define NRF_SPIM_HW_CSN_PRESENT                        \
57     (NRFX_CHECK(SPIM0_FEATURE_HARDWARE_CSN_PRESENT) || \
58      NRFX_CHECK(SPIM1_FEATURE_HARDWARE_CSN_PRESENT) || \
59      NRFX_CHECK(SPIM2_FEATURE_HARDWARE_CSN_PRESENT) || \
60      NRFX_CHECK(SPIM3_FEATURE_HARDWARE_CSN_PRESENT) || \
61      NRFX_CHECK(SPIM4_FEATURE_HARDWARE_CSN_PRESENT))
62 
63 /** @brief Macro for checking if the DCX pin control is available. */
64 #define NRF_SPIM_DCX_PRESENT                  \
65     (NRFX_CHECK(SPIM0_FEATURE_DCX_PRESENT) || \
66      NRFX_CHECK(SPIM1_FEATURE_DCX_PRESENT) || \
67      NRFX_CHECK(SPIM2_FEATURE_DCX_PRESENT) || \
68      NRFX_CHECK(SPIM3_FEATURE_DCX_PRESENT) || \
69      NRFX_CHECK(SPIM4_FEATURE_DCX_PRESENT))
70 
71 /** @brief Macro for checking if the RXDELAY function is available. */
72 #define NRF_SPIM_RXDELAY_PRESENT                  \
73     (NRFX_CHECK(SPIM0_FEATURE_RXDELAY_PRESENT) || \
74      NRFX_CHECK(SPIM1_FEATURE_RXDELAY_PRESENT) || \
75      NRFX_CHECK(SPIM2_FEATURE_RXDELAY_PRESENT) || \
76      NRFX_CHECK(SPIM3_FEATURE_RXDELAY_PRESENT) || \
77      NRFX_CHECK(SPIM4_FEATURE_RXDELAY_PRESENT))
78 
79 #if defined(NRF_SPIM_DCX_PRESENT) || defined(__NRFX_DOXYGEN__)
80 /**
81  * @brief This value specified in the DCX line configuration causes this line
82  *        to be set low during whole transmission (all transmitted bytes are
83  *        marked as command bytes). Any lower value causes the DCX line to be
84  *        switched from low to high after this number of bytes is transmitted
85  *        (all remaining bytes are marked as data bytes).
86  */
87 #define NRF_SPIM_DCX_CNT_ALL_CMD 0xF
88 #endif
89 
90 /** @brief SPIM tasks. */
91 typedef enum
92 {
93     NRF_SPIM_TASK_START   = offsetof(NRF_SPIM_Type, TASKS_START),   ///< Start SPI transaction.
94     NRF_SPIM_TASK_STOP    = offsetof(NRF_SPIM_Type, TASKS_STOP),    ///< Stop SPI transaction.
95     NRF_SPIM_TASK_SUSPEND = offsetof(NRF_SPIM_Type, TASKS_SUSPEND), ///< Suspend SPI transaction.
96     NRF_SPIM_TASK_RESUME  = offsetof(NRF_SPIM_Type, TASKS_RESUME)   ///< Resume SPI transaction.
97 } nrf_spim_task_t;
98 
99 /** @brief SPIM events. */
100 typedef enum
101 {
102     NRF_SPIM_EVENT_STOPPED = offsetof(NRF_SPIM_Type, EVENTS_STOPPED), ///< SPI transaction has stopped.
103     NRF_SPIM_EVENT_ENDRX   = offsetof(NRF_SPIM_Type, EVENTS_ENDRX),   ///< End of RXD buffer reached.
104     NRF_SPIM_EVENT_END     = offsetof(NRF_SPIM_Type, EVENTS_END),     ///< End of RXD buffer and TXD buffer reached.
105     NRF_SPIM_EVENT_ENDTX   = offsetof(NRF_SPIM_Type, EVENTS_ENDTX),   ///< End of TXD buffer reached.
106     NRF_SPIM_EVENT_STARTED = offsetof(NRF_SPIM_Type, EVENTS_STARTED)  ///< Transaction started.
107 } nrf_spim_event_t;
108 
109 /**
110  * @brief SPIM shortcuts.
111  */
112 typedef enum
113 {
114     NRF_SPIM_SHORT_END_START_MASK = SPIM_SHORTS_END_START_Msk, ///< Shortcut between END event and START task.
115     NRF_SPIM_ALL_SHORTS_MASK      = SPIM_SHORTS_END_START_Msk  ///< All SPIM shortcuts.
116 } nrf_spim_short_mask_t;
117 
118 /** @brief SPIM interrupts. */
119 typedef enum
120 {
121     NRF_SPIM_INT_STOPPED_MASK = SPIM_INTENSET_STOPPED_Msk,  ///< Interrupt on STOPPED event.
122     NRF_SPIM_INT_ENDRX_MASK   = SPIM_INTENSET_ENDRX_Msk,    ///< Interrupt on ENDRX event.
123     NRF_SPIM_INT_END_MASK     = SPIM_INTENSET_END_Msk,      ///< Interrupt on END event.
124     NRF_SPIM_INT_ENDTX_MASK   = SPIM_INTENSET_ENDTX_Msk,    ///< Interrupt on ENDTX event.
125     NRF_SPIM_INT_STARTED_MASK = SPIM_INTENSET_STARTED_Msk,  ///< Interrupt on STARTED event.
126     NRF_SPIM_ALL_INTS_MASK    = SPIM_INTENSET_STOPPED_Msk |
127                                 SPIM_INTENSET_ENDRX_Msk   |
128                                 SPIM_INTENSET_END_Msk     |
129                                 SPIM_INTENSET_ENDTX_Msk   |
130                                 SPIM_INTENSET_STARTED_Msk   ///< All SPIM interrupts.
131 } nrf_spim_int_mask_t;
132 
133 /** @brief SPI master data rates. */
134 typedef enum
135 {
136     NRF_SPIM_FREQ_125K = SPIM_FREQUENCY_FREQUENCY_K125,    ///< 125 kbps.
137     NRF_SPIM_FREQ_250K = SPIM_FREQUENCY_FREQUENCY_K250,    ///< 250 kbps.
138     NRF_SPIM_FREQ_500K = SPIM_FREQUENCY_FREQUENCY_K500,    ///< 500 kbps.
139     NRF_SPIM_FREQ_1M   = SPIM_FREQUENCY_FREQUENCY_M1,      ///< 1 Mbps.
140     NRF_SPIM_FREQ_2M   = SPIM_FREQUENCY_FREQUENCY_M2,      ///< 2 Mbps.
141     NRF_SPIM_FREQ_4M   = SPIM_FREQUENCY_FREQUENCY_M4,      ///< 4 Mbps.
142     // [conversion to 'int' needed to prevent compilers from complaining
143     //  that the provided value (0x80000000UL) is out of range of "int"]
144     NRF_SPIM_FREQ_8M   = (int)SPIM_FREQUENCY_FREQUENCY_M8, ///< 8 Mbps.
145 #if defined(SPIM_FREQUENCY_FREQUENCY_M16) || defined(__NRFX_DOXYGEN__)
146     NRF_SPIM_FREQ_16M  = SPIM_FREQUENCY_FREQUENCY_M16,     ///< 16 Mbps.
147 #endif
148 #if defined(SPIM_FREQUENCY_FREQUENCY_M32) || defined(__NRFX_DOXYGEN__)
149     NRF_SPIM_FREQ_32M  = SPIM_FREQUENCY_FREQUENCY_M32      ///< 32 Mbps.
150 #endif
151 } nrf_spim_frequency_t;
152 
153 /** @brief SPI modes. */
154 typedef enum
155 {
156     NRF_SPIM_MODE_0, ///< SCK active high, sample on leading edge of clock.
157     NRF_SPIM_MODE_1, ///< SCK active high, sample on trailing edge of clock.
158     NRF_SPIM_MODE_2, ///< SCK active low, sample on leading edge of clock.
159     NRF_SPIM_MODE_3  ///< SCK active low, sample on trailing edge of clock.
160 } nrf_spim_mode_t;
161 
162 /** @brief SPI bit orders. */
163 typedef enum
164 {
165     NRF_SPIM_BIT_ORDER_MSB_FIRST = SPIM_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
166     NRF_SPIM_BIT_ORDER_LSB_FIRST = SPIM_CONFIG_ORDER_LsbFirst  ///< Least significant bit shifted out first.
167 } nrf_spim_bit_order_t;
168 
169 #if (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
170 /** @brief SPI CSN pin polarity. */
171 typedef enum
172 {
173     NRF_SPIM_CSN_POL_LOW  = SPIM_CSNPOL_CSNPOL_LOW, ///< Active low (idle state high).
174     NRF_SPIM_CSN_POL_HIGH = SPIM_CSNPOL_CSNPOL_HIGH ///< Active high (idle state low).
175 } nrf_spim_csn_pol_t;
176 #endif // (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
177 
178 
179 /**
180  * @brief Function for activating the specified SPIM task.
181  *
182  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
183  * @param[in] task  Task to be activated.
184  */
185 NRF_STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg,
186                                              nrf_spim_task_t task);
187 
188 /**
189  * @brief Function for getting the address of the specified SPIM task register.
190  *
191  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
192  * @param[in] task  The specified task.
193  *
194  * @return Address of the specified task register.
195  */
196 NRF_STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type const * p_reg,
197                                                      nrf_spim_task_t       task);
198 
199 /**
200  * @brief Function for clearing the specified SPIM event.
201  *
202  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
203  * @param[in] event Event to be cleared.
204  */
205 NRF_STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type *  p_reg,
206                                             nrf_spim_event_t event);
207 
208 /**
209  * @brief Function for retrieving the state of the SPIM event.
210  *
211  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
212  * @param[in] event Event to be checked.
213  *
214  * @retval true  The event has been generated.
215  * @retval false The event has not been generated.
216  */
217 NRF_STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type const * p_reg,
218                                             nrf_spim_event_t      event);
219 
220 /**
221  * @brief Function for getting the address of the specified SPIM event register.
222  *
223  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
224  * @param[in] event The specified event.
225  *
226  * @return Address of the specified event register.
227  */
228 NRF_STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type const * p_reg,
229                                                       nrf_spim_event_t      event);
230 
231 /**
232  * @brief Function for enabling the specified shortcuts.
233  *
234  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
235  * @param[in] mask  Shortcuts to be enabled.
236  */
237 NRF_STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg,
238                                               uint32_t        mask);
239 
240 /**
241  * @brief Function for disabling the specified shortcuts.
242  *
243  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
244  * @param[in] mask  Shortcuts to be disabled.
245  */
246 NRF_STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg,
247                                                uint32_t        mask);
248 
249 /**
250  * @brief Function for getting the shortcut setting.
251  *
252  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
253  *
254  * @return Current shortcut configuration.
255  */
256 NRF_STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type const * p_reg);
257 
258 /**
259  * @brief Function for enabling the specified interrupts.
260  *
261  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
262  * @param[in] mask  Mask of interrupts to be enabled.
263  */
264 NRF_STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg,
265                                            uint32_t        mask);
266 
267 /**
268  * @brief Function for disabling the specified interrupts.
269  *
270  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
271  * @param[in] mask  Mask of interrupts to be disabled.
272  */
273 NRF_STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg,
274                                             uint32_t        mask);
275 
276 /**
277  * @brief Function for checking if the specified interrupts are enabled.
278  *
279  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
280  * @param[in] mask  Mask of interrupts to be checked.
281  *
282  * @return Mask of enabled interrupts.
283  */
284 NRF_STATIC_INLINE uint32_t nrf_spim_int_enable_check(NRF_SPIM_Type const * p_reg, uint32_t mask);
285 
286 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
287 /**
288  * @brief Function for setting the subscribe configuration for a given
289  *        SPIM task.
290  *
291  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
292  * @param[in] task    Task for which to set the configuration.
293  * @param[in] channel Channel through which to subscribe events.
294  */
295 NRF_STATIC_INLINE void nrf_spim_subscribe_set(NRF_SPIM_Type * p_reg,
296                                               nrf_spim_task_t task,
297                                               uint8_t         channel);
298 
299 /**
300  * @brief Function for clearing the subscribe configuration for a given
301  *        SPIM task.
302  *
303  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
304  * @param[in] task  Task for which to clear the configuration.
305  */
306 NRF_STATIC_INLINE void nrf_spim_subscribe_clear(NRF_SPIM_Type * p_reg,
307                                                 nrf_spim_task_t task);
308 
309 /**
310  * @brief Function for setting the publish configuration for a given
311  *        SPIM event.
312  *
313  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
314  * @param[in] event   Event for which to set the configuration.
315  * @param[in] channel Channel through which to publish the event.
316  */
317 NRF_STATIC_INLINE void nrf_spim_publish_set(NRF_SPIM_Type *  p_reg,
318                                             nrf_spim_event_t event,
319                                             uint8_t          channel);
320 
321 /**
322  * @brief Function for clearing the publish configuration for a given
323  *        SPIM event.
324  *
325  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
326  * @param[in] event Event for which to clear the configuration.
327  */
328 NRF_STATIC_INLINE void nrf_spim_publish_clear(NRF_SPIM_Type *  p_reg,
329                                               nrf_spim_event_t event);
330 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
331 
332 /**
333  * @brief Function for enabling the SPIM peripheral.
334  *
335  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
336  */
337 NRF_STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg);
338 
339 /**
340  * @brief Function for disabling the SPIM peripheral.
341  *
342  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
343  */
344 NRF_STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg);
345 
346 /**
347  * @brief Function for configuring SPIM pins.
348  *
349  * If a given signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
350  * value instead of its pin number.
351  *
352  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
353  * @param[in] sck_pin  SCK pin number.
354  * @param[in] mosi_pin MOSI pin number.
355  * @param[in] miso_pin MISO pin number.
356  */
357 NRF_STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg,
358                                          uint32_t        sck_pin,
359                                          uint32_t        mosi_pin,
360                                          uint32_t        miso_pin);
361 
362 /**
363  * @brief Function for getting the SCK pin selection.
364  *
365  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
366  *
367  * @return SCK pin selection.
368  */
369 NRF_STATIC_INLINE uint32_t nrf_spim_sck_pin_get(NRF_SPIM_Type const * p_reg);
370 
371 /**
372  * @brief Function for getting the MOSI pin selection.
373  *
374  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
375  *
376  * @return MOSI pin selection.
377  */
378 NRF_STATIC_INLINE uint32_t nrf_spim_mosi_pin_get(NRF_SPIM_Type const * p_reg);
379 
380 /**
381  * @brief Function for getting the MISO pin selection.
382  *
383  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
384  *
385  * @return MISO pin selection.
386  */
387 NRF_STATIC_INLINE uint32_t nrf_spim_miso_pin_get(NRF_SPIM_Type const * p_reg);
388 
389 #if (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
390 /**
391  * @brief Function for configuring the SPIM hardware CSN pin.
392  *
393  * If this signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
394  * value instead of its pin number.
395  *
396  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
397  * @param[in] pin      CSN pin number.
398  * @param[in] polarity CSN pin polarity.
399  * @param[in] duration Minimum duration between the edge of CSN and the edge of SCK
400  *                     and minimum duration of CSN must stay unselected between transactions.
401  *                     The value is specified in number of 64 MHz clock cycles (15.625 ns).
402  */
403 NRF_STATIC_INLINE void nrf_spim_csn_configure(NRF_SPIM_Type *    p_reg,
404                                               uint32_t           pin,
405                                               nrf_spim_csn_pol_t polarity,
406                                               uint32_t           duration);
407 #endif // (NRF_SPIM_HW_CSN_PRESENT) || defined(__NRFX_DOXYGEN__)
408 
409 #if NRF_SPIM_DCX_PRESENT || defined(__NRFX_DOXYGEN__)
410 /**
411  * @brief Function for configuring the SPIM DCX pin.
412  *
413  * If this signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
414  * value instead of its pin number.
415  *
416  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
417  * @param[in] dcx_pin DCX pin number.
418  */
419 NRF_STATIC_INLINE void nrf_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,
420                                             uint32_t        dcx_pin);
421 
422 /**
423  * @brief Function for getting the DCX pin selection.
424  *
425  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
426  *
427  * @return DCX pin selection.
428  */
429 NRF_STATIC_INLINE uint32_t nrf_spim_dcx_pin_get(NRF_SPIM_Type const * p_reg);
430 
431 /**
432  * @brief Function for configuring the number of command bytes.
433  *
434  * Maximum value available for dividing the transmitted bytes into command
435  * bytes and data bytes is @ref NRF_SPIM_DCX_CNT_ALL_CMD - 1.
436  * The @ref NRF_SPIM_DCX_CNT_ALL_CMD value passed as the @c count parameter
437  * causes all transmitted bytes to be marked as command bytes.
438  *
439  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
440  * @param[in] count Number of command bytes preceding the data bytes.
441  */
442 NRF_STATIC_INLINE void nrf_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg,
443                                             uint32_t        count);
444 #endif // NRF_SPIM_DCX_PRESENT || defined(__NRFX_DOXYGEN__)
445 
446 #if NRF_SPIM_RXDELAY_PRESENT || defined(__NRFX_DOXYGEN__)
447 /**
448  * @brief Function for configuring the extended SPIM interface.
449  *
450  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
451  * @param[in] rxdelay Sample delay for input serial data on MISO,
452  *                    specified in 64 MHz clock cycles (15.625 ns) from the sampling edge of SCK.
453  */
454 NRF_STATIC_INLINE void nrf_spim_iftiming_set(NRF_SPIM_Type * p_reg,
455                                              uint32_t        rxdelay);
456 #endif // NRF_SPIM_RXDELAY_PRESENT || defined(__NRFX_DOXYGEN__)
457 
458 #if defined(SPIM_STALLSTAT_RX_Msk) || defined(__NRFX_DOXYGEN__)
459 /**
460  * @brief Function for clearing stall status for RX EasyDMA RAM accesses.
461  *
462  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
463  */
464 NRF_STATIC_INLINE void nrf_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg);
465 
466 /**
467  * @brief Function for getting stall status for RX EasyDMA RAM accesses.
468  *
469  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
470  *
471  * @return Stall status of RX EasyDMA RAM accesses.
472  */
473 NRF_STATIC_INLINE bool nrf_spim_stallstat_rx_get(NRF_SPIM_Type const * p_reg);
474 #endif // defined(SPIM_STALLSTAT_RX_Msk) || defined(__NRFX_DOXYGEN__)
475 
476 #if defined(SPIM_STALLSTAT_TX_Msk) || defined(__NRFX_DOXYGEN__)
477 /**
478  * @brief Function for clearing stall status for TX EasyDMA RAM accesses.
479  *
480  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
481  */
482 NRF_STATIC_INLINE void nrf_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg);
483 
484 /**
485  * @brief Function for getting stall status for TX EasyDMA RAM accesses.
486  *
487  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
488  *
489  * @return Stall status of TX EasyDMA RAM accesses.
490  */
491 NRF_STATIC_INLINE bool nrf_spim_stallstat_tx_get(NRF_SPIM_Type const * p_reg);
492 #endif // defined(SPIM_STALLSTAT_TX_Msk) || defined(__NRFX_DOXYGEN__)
493 
494 /**
495  * @brief Function for setting the SPI master data rate.
496  *
497  * @param[in] p_reg     Pointer to the structure of registers of the peripheral.
498  * @param[in] frequency SPI frequency.
499  */
500 NRF_STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type *      p_reg,
501                                               nrf_spim_frequency_t frequency);
502 
503 /**
504  * @brief Function for setting the transmit buffer.
505  *
506  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
507  * @param[in] p_buffer Pointer to the buffer with data to send.
508  * @param[in] length   Maximum number of data bytes to transmit.
509  */
510 NRF_STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,
511                                               uint8_t const * p_buffer,
512                                               size_t          length);
513 
514 /**
515  * @brief Function for setting the receive buffer.
516  *
517  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
518  * @param[in] p_buffer Pointer to the buffer for received data.
519  * @param[in] length   Maximum number of data bytes to receive.
520  */
521 NRF_STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,
522                                               uint8_t *       p_buffer,
523                                               size_t          length);
524 
525 /**
526  * @brief Function for setting the SPI configuration.
527  *
528  * @param[in] p_reg         Pointer to the structure of registers of the peripheral.
529  * @param[in] spi_mode      SPI mode.
530  * @param[in] spi_bit_order SPI bit order.
531  */
532 NRF_STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type *      p_reg,
533                                           nrf_spim_mode_t      spi_mode,
534                                           nrf_spim_bit_order_t spi_bit_order);
535 
536 /**
537  * @brief Function for setting the over-read character.
538  *
539  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
540  * @param[in] orc   Over-read character that is clocked out in case of
541  *                  an over-read of the TXD buffer.
542  */
543 NRF_STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg,
544                                         uint8_t         orc);
545 
546 /**
547  * @brief Function for enabling the TX list feature.
548  *
549  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
550  */
551 NRF_STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg);
552 
553 /**
554  * @brief Function for disabling the TX list feature.
555  *
556  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
557  */
558 NRF_STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg);
559 
560 /**
561  * @brief Function for enabling the RX list feature.
562  *
563  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
564  */
565 NRF_STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg);
566 
567 /**
568  * @brief Function for disabling the RX list feature.
569  *
570  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
571  */
572 NRF_STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg);
573 
574 
575 #ifndef NRF_DECLARE_ONLY
576 
nrf_spim_task_trigger(NRF_SPIM_Type * p_reg,nrf_spim_task_t task)577 NRF_STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg,
578                                              nrf_spim_task_t task)
579 {
580     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
581 }
582 
nrf_spim_task_address_get(NRF_SPIM_Type const * p_reg,nrf_spim_task_t task)583 NRF_STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type const * p_reg,
584                                                      nrf_spim_task_t       task)
585 {
586     return (uint32_t)((uint8_t *)p_reg + (uint32_t)task);
587 }
588 
nrf_spim_event_clear(NRF_SPIM_Type * p_reg,nrf_spim_event_t event)589 NRF_STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type *  p_reg,
590                                             nrf_spim_event_t event)
591 {
592     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
593     nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
594 }
595 
nrf_spim_event_check(NRF_SPIM_Type const * p_reg,nrf_spim_event_t event)596 NRF_STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type const * p_reg,
597                                             nrf_spim_event_t      event)
598 {
599     return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
600 }
601 
nrf_spim_event_address_get(NRF_SPIM_Type const * p_reg,nrf_spim_event_t event)602 NRF_STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type const * p_reg,
603                                                       nrf_spim_event_t      event)
604 {
605     return (uint32_t)((uint8_t *)p_reg + (uint32_t)event);
606 }
607 
nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg,uint32_t mask)608 NRF_STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg,
609                                               uint32_t        mask)
610 {
611     p_reg->SHORTS |= mask;
612 }
613 
nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg,uint32_t mask)614 NRF_STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg,
615                                                uint32_t        mask)
616 {
617     p_reg->SHORTS &= ~(mask);
618 }
619 
nrf_spim_shorts_get(NRF_SPIM_Type const * p_reg)620 NRF_STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type const * p_reg)
621 {
622     return p_reg->SHORTS;
623 }
624 
nrf_spim_int_enable(NRF_SPIM_Type * p_reg,uint32_t mask)625 NRF_STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg,
626                                            uint32_t        mask)
627 {
628     p_reg->INTENSET = mask;
629 }
630 
nrf_spim_int_disable(NRF_SPIM_Type * p_reg,uint32_t mask)631 NRF_STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg,
632                                             uint32_t        mask)
633 {
634     p_reg->INTENCLR = mask;
635 }
636 
nrf_spim_int_enable_check(NRF_SPIM_Type const * p_reg,uint32_t mask)637 NRF_STATIC_INLINE uint32_t nrf_spim_int_enable_check(NRF_SPIM_Type const * p_reg, uint32_t mask)
638 {
639     return p_reg->INTENSET & mask;
640 }
641 
642 #if defined(DPPI_PRESENT)
nrf_spim_subscribe_set(NRF_SPIM_Type * p_reg,nrf_spim_task_t task,uint8_t channel)643 NRF_STATIC_INLINE void nrf_spim_subscribe_set(NRF_SPIM_Type * p_reg,
644                                               nrf_spim_task_t task,
645                                               uint8_t         channel)
646 {
647     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
648             ((uint32_t)channel | SPIM_SUBSCRIBE_START_EN_Msk);
649 }
650 
nrf_spim_subscribe_clear(NRF_SPIM_Type * p_reg,nrf_spim_task_t task)651 NRF_STATIC_INLINE void nrf_spim_subscribe_clear(NRF_SPIM_Type * p_reg,
652                                                 nrf_spim_task_t task)
653 {
654     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
655 }
656 
nrf_spim_publish_set(NRF_SPIM_Type * p_reg,nrf_spim_event_t event,uint8_t channel)657 NRF_STATIC_INLINE void nrf_spim_publish_set(NRF_SPIM_Type *  p_reg,
658                                             nrf_spim_event_t event,
659                                             uint8_t          channel)
660 {
661     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
662             ((uint32_t)channel | SPIM_PUBLISH_STARTED_EN_Msk);
663 }
664 
nrf_spim_publish_clear(NRF_SPIM_Type * p_reg,nrf_spim_event_t event)665 NRF_STATIC_INLINE void nrf_spim_publish_clear(NRF_SPIM_Type *  p_reg,
666                                               nrf_spim_event_t event)
667 {
668     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
669 }
670 #endif // defined(DPPI_PRESENT)
671 
nrf_spim_enable(NRF_SPIM_Type * p_reg)672 NRF_STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg)
673 {
674     p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos);
675 }
676 
nrf_spim_disable(NRF_SPIM_Type * p_reg)677 NRF_STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg)
678 {
679     p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos);
680 }
681 
nrf_spim_pins_set(NRF_SPIM_Type * p_reg,uint32_t sck_pin,uint32_t mosi_pin,uint32_t miso_pin)682 NRF_STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg,
683                                          uint32_t        sck_pin,
684                                          uint32_t        mosi_pin,
685                                          uint32_t        miso_pin)
686 {
687     p_reg->PSEL.SCK  = sck_pin;
688     p_reg->PSEL.MOSI = mosi_pin;
689     p_reg->PSEL.MISO = miso_pin;
690 }
691 
nrf_spim_sck_pin_get(NRF_SPIM_Type const * p_reg)692 NRF_STATIC_INLINE uint32_t nrf_spim_sck_pin_get(NRF_SPIM_Type const * p_reg)
693 {
694     return p_reg->PSEL.SCK;
695 }
696 
nrf_spim_mosi_pin_get(NRF_SPIM_Type const * p_reg)697 NRF_STATIC_INLINE uint32_t nrf_spim_mosi_pin_get(NRF_SPIM_Type const * p_reg)
698 {
699     return p_reg->PSEL.MOSI;
700 }
701 
nrf_spim_miso_pin_get(NRF_SPIM_Type const * p_reg)702 NRF_STATIC_INLINE uint32_t nrf_spim_miso_pin_get(NRF_SPIM_Type const * p_reg)
703 {
704     return p_reg->PSEL.MISO;
705 }
706 
707 #if NRF_SPIM_HW_CSN_PRESENT
nrf_spim_csn_configure(NRF_SPIM_Type * p_reg,uint32_t pin,nrf_spim_csn_pol_t polarity,uint32_t duration)708 NRF_STATIC_INLINE void nrf_spim_csn_configure(NRF_SPIM_Type *    p_reg,
709                                               uint32_t           pin,
710                                               nrf_spim_csn_pol_t polarity,
711                                               uint32_t           duration)
712 {
713     p_reg->PSEL.CSN = pin;
714     p_reg->CSNPOL = polarity;
715     p_reg->IFTIMING.CSNDUR = duration;
716 }
717 #endif // NRF_SPIM_HW_CSN_PRESENT
718 
719 #if NRF_SPIM_DCX_PRESENT
nrf_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,uint32_t dcx_pin)720 NRF_STATIC_INLINE void nrf_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,
721                                             uint32_t        dcx_pin)
722 {
723     p_reg->PSELDCX = dcx_pin;
724 }
725 
nrf_spim_dcx_pin_get(NRF_SPIM_Type const * p_reg)726 NRF_STATIC_INLINE uint32_t nrf_spim_dcx_pin_get(NRF_SPIM_Type const * p_reg)
727 {
728     return p_reg->PSELDCX;
729 }
730 
nrf_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg,uint32_t dcx_cnt)731 NRF_STATIC_INLINE void nrf_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg,
732                                             uint32_t        dcx_cnt)
733 {
734     p_reg->DCXCNT = dcx_cnt;
735 }
736 #endif // NRF_SPIM_DCX_PRESENT
737 
738 #if NRF_SPIM_RXDELAY_PRESENT
nrf_spim_iftiming_set(NRF_SPIM_Type * p_reg,uint32_t rxdelay)739 NRF_STATIC_INLINE void nrf_spim_iftiming_set(NRF_SPIM_Type * p_reg,
740                                              uint32_t        rxdelay)
741 {
742     p_reg->IFTIMING.RXDELAY = rxdelay;
743 }
744 #endif // NRF_SPIM_RXDELAY_PRESENT
745 
746 #if defined(SPIM_STALLSTAT_RX_Msk)
nrf_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg)747 NRF_STATIC_INLINE void nrf_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg)
748 {
749     p_reg->STALLSTAT &= ~(SPIM_STALLSTAT_RX_Msk);
750 }
751 
nrf_spim_stallstat_rx_get(NRF_SPIM_Type const * p_reg)752 NRF_STATIC_INLINE bool nrf_spim_stallstat_rx_get(NRF_SPIM_Type const * p_reg)
753 {
754     return (p_reg->STALLSTAT & SPIM_STALLSTAT_RX_Msk) != 0;
755 }
756 #endif // defined(SPIM_STALLSTAT_RX_Msk)
757 
758 #if defined(SPIM_STALLSTAT_TX_Msk)
nrf_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg)759 NRF_STATIC_INLINE void nrf_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg)
760 {
761     p_reg->STALLSTAT &= ~(SPIM_STALLSTAT_TX_Msk);
762 }
763 
nrf_spim_stallstat_tx_get(NRF_SPIM_Type const * p_reg)764 NRF_STATIC_INLINE bool nrf_spim_stallstat_tx_get(NRF_SPIM_Type const * p_reg)
765 {
766     return (p_reg->STALLSTAT & SPIM_STALLSTAT_TX_Msk) != 0;
767 }
768 #endif // defined(SPIM_STALLSTAT_TX_Msk)
769 
nrf_spim_frequency_set(NRF_SPIM_Type * p_reg,nrf_spim_frequency_t frequency)770 NRF_STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type *      p_reg,
771                                               nrf_spim_frequency_t frequency)
772 {
773     p_reg->FREQUENCY = (uint32_t)frequency;
774 }
775 
nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,uint8_t const * p_buffer,size_t length)776 NRF_STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,
777                                               uint8_t const * p_buffer,
778                                               size_t          length)
779 {
780     p_reg->TXD.PTR    = (uint32_t)p_buffer;
781     p_reg->TXD.MAXCNT = length;
782 }
783 
nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,uint8_t * p_buffer,size_t length)784 NRF_STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,
785                                               uint8_t * p_buffer,
786                                               size_t    length)
787 {
788     p_reg->RXD.PTR    = (uint32_t)p_buffer;
789     p_reg->RXD.MAXCNT = length;
790 }
791 
nrf_spim_configure(NRF_SPIM_Type * p_reg,nrf_spim_mode_t spi_mode,nrf_spim_bit_order_t spi_bit_order)792 NRF_STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type *      p_reg,
793                                           nrf_spim_mode_t      spi_mode,
794                                           nrf_spim_bit_order_t spi_bit_order)
795 {
796     uint32_t config = (spi_bit_order == NRF_SPIM_BIT_ORDER_MSB_FIRST ?
797         SPIM_CONFIG_ORDER_MsbFirst : SPIM_CONFIG_ORDER_LsbFirst);
798     switch (spi_mode)
799     {
800     default:
801     case NRF_SPIM_MODE_0:
802         config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
803                   (SPIM_CONFIG_CPHA_Leading    << SPIM_CONFIG_CPHA_Pos);
804         break;
805 
806     case NRF_SPIM_MODE_1:
807         config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
808                   (SPIM_CONFIG_CPHA_Trailing   << SPIM_CONFIG_CPHA_Pos);
809         break;
810 
811     case NRF_SPIM_MODE_2:
812         config |= (SPIM_CONFIG_CPOL_ActiveLow  << SPIM_CONFIG_CPOL_Pos) |
813                   (SPIM_CONFIG_CPHA_Leading    << SPIM_CONFIG_CPHA_Pos);
814         break;
815 
816     case NRF_SPIM_MODE_3:
817         config |= (SPIM_CONFIG_CPOL_ActiveLow  << SPIM_CONFIG_CPOL_Pos) |
818                   (SPIM_CONFIG_CPHA_Trailing   << SPIM_CONFIG_CPHA_Pos);
819         break;
820     }
821     p_reg->CONFIG = config;
822 }
823 
nrf_spim_orc_set(NRF_SPIM_Type * p_reg,uint8_t orc)824 NRF_STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg,
825                                         uint8_t         orc)
826 {
827     p_reg->ORC = orc;
828 }
829 
830 
nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg)831 NRF_STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg)
832 {
833     p_reg->TXD.LIST = SPIM_TXD_LIST_LIST_ArrayList << SPIM_TXD_LIST_LIST_Pos;
834 }
835 
nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg)836 NRF_STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg)
837 {
838     p_reg->TXD.LIST = SPIM_TXD_LIST_LIST_Disabled << SPIM_TXD_LIST_LIST_Pos;
839 }
840 
nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg)841 NRF_STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg)
842 {
843     p_reg->RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList << SPIM_RXD_LIST_LIST_Pos;
844 }
845 
nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg)846 NRF_STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg)
847 {
848     p_reg->RXD.LIST = SPIM_RXD_LIST_LIST_Disabled << SPIM_RXD_LIST_LIST_Pos;
849 }
850 
851 #endif // NRF_DECLARE_ONLY
852 
853 /** @} */
854 
855 #ifdef __cplusplus
856 }
857 #endif
858 
859 #endif // NRF_SPIM_H__
860