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