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