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