1 /*
2 * Copyright (c) 2021 - 2025, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRFY_SPIM_H__
35 #define NRFY_SPIM_H__
36
37 #include <nrfx.h>
38 #include <hal/nrf_spim.h>
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 typedef struct nrfy_spim_xfer_desc_t nrfy_spim_xfer_desc_t;
45
46 NRFY_STATIC_INLINE bool __nrfy_internal_spim_event_handle(NRF_SPIM_Type * p_reg,
47 uint32_t mask,
48 nrf_spim_event_t event,
49 uint32_t * p_evt_mask);
50
51 NRFY_STATIC_INLINE
52 uint32_t __nrfy_internal_spim_events_process(NRF_SPIM_Type * p_reg,
53 uint32_t mask,
54 nrfy_spim_xfer_desc_t const * p_xfer);
55
56 NRFY_STATIC_INLINE void __nrfy_internal_spim_event_enabled_clear(NRF_SPIM_Type * p_reg,
57 uint32_t mask,
58 nrf_spim_event_t event);
59
60 /**
61 * @defgroup nrfy_spim SPIM HALY
62 * @{
63 * @ingroup nrf_spim
64 * @brief Hardware access layer with cache and barrier support for managing the SPIM peripheral.
65 */
66
67 #if NRF_SPIM_HAS_HW_CSN || defined(__NRFX_DOXYGEN__)
68 /** @refhal{NRF_SPIM_HAS_HW_CSN} */
69 #define NRFY_SPIM_HAS_HW_CSN 1
70 #else
71 #define NRFY_SPIM_HAS_HW_CSN 0
72 #endif
73
74 #if NRF_SPIM_HAS_DCX || defined(__NRFX_DOXYGEN__)
75 /** @refhal{NRF_SPIM_HAS_DCX} */
76 #define NRFY_SPIM_HAS_DCX 1
77 #else
78 #define NRFY_SPIM_HAS_DCX 0
79 #endif
80
81 #if NRF_SPIM_HAS_RXDELAY || defined(__NRFX_DOXYGEN__)
82 /** @refhal{NRF_SPIM_HAS_RXDELAY} */
83 #define NRFY_SPIM_HAS_RXDELAY 1
84 #else
85 #define NRFY_SPIM_HAS_RXDELAY 0
86 #endif
87
88 #if NRF_SPIM_HAS_STALLSTAT || defined(__NRFX_DOXYGEN__)
89 /** @refhal{NRF_SPIM_HAS_STALLSTAT} */
90 #define NRFY_SPIM_HAS_STALLSTAT 1
91 #else
92 #define NRFY_SPIM_HAS_STALLSTAT 0
93 #endif
94
95 #if NRF_SPIM_HAS_EXTENDED || defined(__NRFX_DOXYGEN__)
96 /** @refhal{NRF_SPIM_HAS_EXTENDED} */
97 #define NRFY_SPIM_HAS_EXTENDED 1
98 #else
99 #define NRFY_SPIM_HAS_EXTENDED 0
100 #endif
101
102 #if NRF_SPIM_HAS_ARRAY_LIST || defined(__NRFX_DOXYGEN__)
103 /** @refhal{NRF_SPIM_HAS_ARRAY_LIST} */
104 #define NRFY_SPIM_HAS_ARRAY_LIST 1
105 #else
106 #define NRFY_SPIM_HAS_ARRAY_LIST 0
107 #endif
108
109 #if NRF_SPIM_HAS_FREQUENCY || defined(__NRFX_DOXYGEN__)
110 /** @refhal{NRF_SPIM_HAS_FREQUENCY} */
111 #define NRFY_SPIM_HAS_FREQUENCY 1
112 #else
113 #define NRFY_SPIM_HAS_FREQUENCY 0
114 #endif
115
116 #if NRF_SPIM_HAS_PRESCALER || defined(__NRFX_DOXYGEN__)
117 /** @refhal{NRF_SPIM_HAS_PRESCALER} */
118 #define NRFY_SPIM_HAS_PRESCALER 1
119 #else
120 #define NRFY_SPIM_HAS_PRESCALER 0
121 #endif
122
123 /** @brief Structure describing single SPIM transfer. */
124 struct nrfy_spim_xfer_desc_t
125 {
126 uint8_t const * p_tx_buffer; ///< Pointer to the TX data buffer.
127 size_t tx_length; ///< TX data buffer length.
128 uint8_t * p_rx_buffer; ///< Pointer to the RX data buffer.
129 size_t rx_length; ///< RX data buffer length.
130 };
131
132 #if NRFY_SPIM_HAS_EXTENDED
133 /** @brief Configuration structure for SPIM pins used for extended features. */
134 typedef struct
135 {
136 #if NRFY_SPIM_HAS_DCX
137 uint32_t dcx_pin; ///< D/CX pin number.
138 /**< Set to @ref NRF_SPIM_PIN_NOT_CONNECTED if this signal is not needed. */
139 #endif
140 #if NRFY_SPIM_HAS_HW_CSN
141 uint32_t csn_pin; ///< CSN pin number.
142 /**< Set to @ref NRF_SPIM_PIN_NOT_CONNECTED if this signal is not needed. */
143 #endif
144 } nrfy_spim_ext_pins_t;
145
146 /** @brief Configuration structure for SPIM extended features. */
147 typedef struct
148 {
149 nrfy_spim_ext_pins_t pins; ///< Pin configuration structure.
150 #if NRFY_SPIM_HAS_HW_CSN
151 nrf_spim_csn_pol_t csn_pol; ///< Polarity of the CSN pin.
152 uint8_t csn_duration; ///< Minimum duration between the edge of CSN and the edge of SCK.
153 /**< Also, minimum duration of CSN inactivity between transactions.
154 * The value is specified in number of 64 MHz clock cycles (15.625 ns). */
155 #endif
156 #if NRFY_SPIM_HAS_RXDELAY
157 uint8_t rx_delay; ///< Sample delay for input serial data on MISO.
158 /**< This value specifies the delay between the occurrence
159 * of the SCK sampling edge and actual sampling operation,
160 * expressed in number of 64 MHz clock cycles (15.625 ns). */
161 #endif
162 } nrfy_spim_ext_config_t;
163 #endif // NRFY_SPIM_HAS_EXTENDED
164
165 /** @brief SPIM pins configuration structure. */
166 typedef struct
167 {
168 uint32_t sck_pin; ///< SCK pin number.
169 uint32_t mosi_pin; ///< MOSI pin number.
170 /**< Set to @ref NRF_SPIM_PIN_NOT_CONNECTED if this signal is not needed. */
171 uint32_t miso_pin; ///< MISO pin number.
172 /**< Set to @ref NRF_SPIM_PIN_NOT_CONNECTED if this signal is not needed. */
173 } nrfy_spim_pins_t;
174
175 /** @brief SPIM configuration structure. */
176 typedef struct
177 {
178 nrfy_spim_pins_t pins; ///< Pin configuration structure.
179 uint8_t orc; ///< Overrun character.
180 /**< This character is transmitted when the TX buffer gets exhausted,
181 but the transaction continues due to RX. */
182 #if NRFY_SPIM_HAS_FREQUENCY
183 nrf_spim_frequency_t frequency; ///< SPIM frequency.
184 #elif NRFY_SPIM_HAS_PRESCALER
185 uint32_t prescaler; ///< SPIM prescaler value.
186 #endif
187 nrf_spim_mode_t mode; ///< SPIM mode.
188 nrf_spim_bit_order_t bit_order; ///< SPIM bit order.
189 #if NRFY_SPIM_HAS_EXTENDED
190 nrfy_spim_ext_config_t ext_config; ///< Extended features configuration structure.
191 #endif
192 bool skip_psel_cfg; ///< Skip pin selection configuration.
193 /**< When set to true, the driver does not modify
194 * pin select registers in the peripheral.
195 * Those registers are supposed to be set up
196 * externally before the driver is initialized.
197 * @note When both GPIO configuration and pin
198 * selection are to be skipped, the structure
199 * fields that specify pins can be omitted,
200 * as they are ignored anyway. */
201 } nrfy_spim_config_t;
202
203 /**
204 * @brief Function for configuring the SPIM.
205 *
206 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
207 * @param[in] p_config Pointer to the peripheral configuration structure.
208 */
nrfy_spim_periph_configure(NRF_SPIM_Type * p_reg,nrfy_spim_config_t const * p_config)209 NRFY_STATIC_INLINE void nrfy_spim_periph_configure(NRF_SPIM_Type * p_reg,
210 nrfy_spim_config_t const * p_config)
211 {
212 if (!p_config->skip_psel_cfg)
213 {
214 nrf_spim_pins_set(p_reg,
215 p_config->pins.sck_pin, p_config->pins.mosi_pin, p_config->pins.miso_pin);
216 #if NRFY_SPIM_HAS_DCX
217 nrf_spim_dcx_pin_set(p_reg, p_config->ext_config.pins.dcx_pin);
218 #endif
219 #if NRFY_SPIM_HAS_HW_CSN
220 nrf_spim_csn_configure(p_reg,
221 p_config->ext_config.pins.csn_pin,
222 p_config->ext_config.csn_pol,
223 p_config->ext_config.csn_duration);
224 #endif
225 }
226 nrf_spim_orc_set(p_reg, p_config->orc);
227 #if NRFY_SPIM_HAS_FREQUENCY
228 nrf_spim_frequency_set(p_reg, p_config->frequency);
229 #elif NRFY_SPIM_HAS_PRESCALER
230 nrf_spim_prescaler_set(p_reg, p_config->prescaler);
231 #endif
232 nrf_spim_configure(p_reg, p_config->mode, p_config->bit_order);
233 #if NRFY_SPIM_HAS_RXDELAY
234 nrf_spim_iftiming_set(p_reg, p_config->ext_config.rx_delay);
235 #endif
236 nrf_barrier_w();
237 }
238
239 /**
240 * @brief Function for initializing the specified SPIM interrupts.
241 *
242 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
243 * @param[in] mask Mask of interrupts to be initialized.
244 * @param[in] irq_priority Interrupt priority.
245 * @param[in] enable True if interrupts associated with the event mask are to be enabled, false otherwise.
246 */
nrfy_spim_int_init(NRF_SPIM_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)247 NRFY_STATIC_INLINE void nrfy_spim_int_init(NRF_SPIM_Type * p_reg,
248 uint32_t mask,
249 uint8_t irq_priority,
250 bool enable)
251 {
252 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_STOPPED);
253 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_ENDRX);
254 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_END);
255 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_ENDTX);
256 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_STARTED);
257
258 nrf_barrier_w();
259 NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
260 NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
261 if (enable)
262 {
263 nrf_spim_int_enable(p_reg, mask);
264 }
265 nrf_barrier_w();
266 }
267
268 /**
269 * @brief Function for uninitializing the SPIM interrupts.
270 *
271 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
272 */
nrfy_spim_int_uninit(NRF_SPIM_Type * p_reg)273 NRFY_STATIC_INLINE void nrfy_spim_int_uninit(NRF_SPIM_Type * p_reg)
274 {
275 NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
276 nrf_barrier_w();
277 }
278
279 /**
280 * @brief Function for processing the specified SPIM events.
281 *
282 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
283 * @param[in] mask Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK();
284 * @param[in] p_xfer Pointer to the structure containing buffers associated with the last transaction.
285 * Can be NULL.
286 *
287 * @return Mask of events that were generated and processed.
288 * To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
289 */
nrfy_spim_events_process(NRF_SPIM_Type * p_reg,uint32_t mask,nrfy_spim_xfer_desc_t const * p_xfer)290 NRFY_STATIC_INLINE uint32_t nrfy_spim_events_process(NRF_SPIM_Type * p_reg,
291 uint32_t mask,
292 nrfy_spim_xfer_desc_t const * p_xfer)
293 {
294 uint32_t evt_mask = __nrfy_internal_spim_events_process(p_reg, mask, p_xfer);
295 nrf_barrier_w();
296 return evt_mask;
297 }
298
299 /**
300 * @brief Function for setting the SPIM transaction buffers.
301 *
302 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
303 * @param[in] p_xfer Pointer to the structure containing transaction buffers.
304 */
nrfy_spim_buffers_set(NRF_SPIM_Type * p_reg,nrfy_spim_xfer_desc_t const * p_xfer)305 NRFY_STATIC_INLINE void nrfy_spim_buffers_set(NRF_SPIM_Type * p_reg,
306 nrfy_spim_xfer_desc_t const * p_xfer)
307 {
308 if (p_xfer->p_tx_buffer)
309 {
310 NRFY_CACHE_WB(p_xfer->p_tx_buffer, p_xfer->tx_length);
311 }
312 nrf_spim_tx_buffer_set(p_reg, p_xfer->p_tx_buffer, p_xfer->tx_length);
313 nrf_spim_rx_buffer_set(p_reg, p_xfer->p_rx_buffer, p_xfer->rx_length);
314 nrf_barrier_w();
315 }
316
317 /**
318 * @brief Function for starting the SPIM transaction.
319 *
320 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
321 * @param[in] p_xfer Pointer to the structure containing transaction buffers
322 * if the transaction is to be blocking. NULL for non-blocking transactions.
323 */
nrfy_spim_xfer_start(NRF_SPIM_Type * p_reg,nrfy_spim_xfer_desc_t const * p_xfer)324 NRFY_STATIC_INLINE void nrfy_spim_xfer_start(NRF_SPIM_Type * p_reg,
325 nrfy_spim_xfer_desc_t const * p_xfer)
326 {
327 nrf_spim_task_trigger(p_reg, NRF_SPIM_TASK_START);
328 if (p_xfer)
329 {
330 nrf_barrier_w();
331 while (!nrf_spim_event_check(p_reg, NRF_SPIM_EVENT_END))
332 {}
333 (void)__nrfy_internal_spim_events_process(p_reg,
334 NRFY_EVENT_TO_INT_BITMASK(NRF_SPIM_EVENT_END),
335 p_xfer);
336 }
337 nrf_barrier_w();
338 }
339
340 /**
341 * @brief Function for aborting the ongoing SPIM transaction.
342 *
343 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
344 * @param[in] p_xfer Pointer to the structure containing transaction buffers
345 * if the abort is to be blocking. NULL for non-blocking operation.
346 */
nrfy_spim_abort(NRF_SPIM_Type * p_reg,nrfy_spim_xfer_desc_t const * p_xfer)347 NRFY_STATIC_INLINE void nrfy_spim_abort(NRF_SPIM_Type * p_reg, nrfy_spim_xfer_desc_t const * p_xfer)
348 {
349 nrf_spim_task_trigger(p_reg, NRF_SPIM_TASK_STOP);
350 if (p_xfer)
351 {
352 nrf_barrier_w();
353 uint32_t evt_mask = NRFY_EVENT_TO_INT_BITMASK(NRF_SPIM_EVENT_STOPPED);
354 while (!__nrfy_internal_spim_events_process(p_reg, evt_mask, p_xfer))
355 {}
356 (void)__nrfy_internal_spim_events_process(p_reg,
357 NRFY_EVENT_TO_INT_BITMASK(NRF_SPIM_EVENT_END),
358 NULL);
359 }
360 nrf_barrier_w();
361 }
362
363 /**
364 * @brief Function for getting the SPIM pins configuration.
365 *
366 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
367 * @param[out] p_pins Pointer to the structure to be filled with SPIM pins configuration.
368 */
nrfy_spim_pins_get(NRF_SPIM_Type const * p_reg,nrfy_spim_pins_t * p_pins)369 NRFY_STATIC_INLINE void nrfy_spim_pins_get(NRF_SPIM_Type const * p_reg, nrfy_spim_pins_t * p_pins)
370 {
371 p_pins->sck_pin = nrf_spim_sck_pin_get(p_reg);
372 p_pins->mosi_pin = nrf_spim_mosi_pin_get(p_reg);
373 p_pins->miso_pin = nrf_spim_miso_pin_get(p_reg);
374 }
375
376 #if NRFY_SPIM_HAS_EXTENDED
377 /**
378 * @brief Function for getting the configuration of the SPIM pins used for extended features.
379 *
380 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
381 * @param[out] p_pins Pointer to the structure to be filled with SPIM pins configuration.
382 */
nrfy_spim_ext_pins_get(NRF_SPIM_Type const * p_reg,nrfy_spim_ext_pins_t * p_pins)383 NRFY_STATIC_INLINE void nrfy_spim_ext_pins_get(NRF_SPIM_Type const * p_reg,
384 nrfy_spim_ext_pins_t * p_pins)
385 {
386 p_pins->dcx_pin = nrf_spim_dcx_pin_get(p_reg);
387 #if NRFY_SPIM_HAS_HW_CSN
388 p_pins->csn_pin = nrf_spim_csn_pin_get(p_reg);
389 #endif
390 }
391 #endif
392
393 #if NRFY_SPIM_HAS_ARRAY_LIST
394 /**
395 * @brief Function for enabling or disabling the TX list feature.
396 *
397 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
398 * @param[in] enable True if TX list feature is to be enabled, false otherwise.
399 */
nrfy_spim_tx_list_set(NRF_SPIM_Type * p_reg,bool enable)400 NRFY_STATIC_INLINE void nrfy_spim_tx_list_set(NRF_SPIM_Type * p_reg, bool enable)
401 {
402 if (enable)
403 {
404 nrf_spim_tx_list_enable(p_reg);
405 }
406 else
407 {
408 nrf_spim_tx_list_disable(p_reg);
409 }
410 nrf_barrier_w();
411 }
412
413 /**
414 * @brief Function for enabling or disabling the RX list feature.
415 *
416 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
417 * @param[in] enable True if RX list feature is to be enabled, false otherwise.
418 */
nrfy_spim_rx_list_set(NRF_SPIM_Type * p_reg,bool enable)419 NRFY_STATIC_INLINE void nrfy_spim_rx_list_set(NRF_SPIM_Type * p_reg, bool enable)
420 {
421 if (enable)
422 {
423 nrf_spim_rx_list_enable(p_reg);
424 }
425 else
426 {
427 nrf_spim_rx_list_disable(p_reg);
428 }
429 nrf_barrier_w();
430 }
431 #endif
432
433 /** @refhal{nrf_spim_task_trigger} */
nrfy_spim_task_trigger(NRF_SPIM_Type * p_reg,nrf_spim_task_t task)434 NRFY_STATIC_INLINE void nrfy_spim_task_trigger(NRF_SPIM_Type * p_reg,
435 nrf_spim_task_t task)
436 {
437 nrf_spim_task_trigger(p_reg, task);
438 nrf_barrier_w();
439 }
440
441 /** @refhal{nrf_spim_task_address_get} */
nrfy_spim_task_address_get(NRF_SPIM_Type const * p_reg,nrf_spim_task_t task)442 NRFY_STATIC_INLINE uint32_t nrfy_spim_task_address_get(NRF_SPIM_Type const * p_reg,
443 nrf_spim_task_t task)
444 {
445 return nrf_spim_task_address_get(p_reg, task);
446 }
447
448 /** @refhal{nrf_spim_event_clear} */
nrfy_spim_event_clear(NRF_SPIM_Type * p_reg,nrf_spim_event_t event)449 NRFY_STATIC_INLINE void nrfy_spim_event_clear(NRF_SPIM_Type * p_reg, nrf_spim_event_t event)
450 {
451 nrf_spim_event_clear(p_reg, event);
452 nrf_barrier_w();
453 }
454
455 /** @refhal{nrf_spim_event_check} */
nrfy_spim_event_check(NRF_SPIM_Type const * p_reg,nrf_spim_event_t event)456 NRFY_STATIC_INLINE bool nrfy_spim_event_check(NRF_SPIM_Type const * p_reg, nrf_spim_event_t event)
457 {
458 nrf_barrier_r();
459 bool check = nrf_spim_event_check(p_reg, event);
460 nrf_barrier_r();
461 return check;
462 }
463
464 /** @refhal{nrf_spim_event_address_get} */
nrfy_spim_event_address_get(NRF_SPIM_Type const * p_reg,nrf_spim_event_t event)465 NRFY_STATIC_INLINE uint32_t nrfy_spim_event_address_get(NRF_SPIM_Type const * p_reg,
466 nrf_spim_event_t event)
467 {
468 return nrf_spim_event_address_get(p_reg, event);
469 }
470
471 /** @refhal{nrf_spim_shorts_enable} */
nrfy_spim_shorts_enable(NRF_SPIM_Type * p_reg,uint32_t mask)472 NRFY_STATIC_INLINE void nrfy_spim_shorts_enable(NRF_SPIM_Type * p_reg, uint32_t mask)
473 {
474 nrf_spim_shorts_enable(p_reg, mask);
475 nrf_barrier_w();
476 }
477
478 /** @refhal{nrf_spim_shorts_disable} */
nrfy_spim_shorts_disable(NRF_SPIM_Type * p_reg,uint32_t mask)479 NRFY_STATIC_INLINE void nrfy_spim_shorts_disable(NRF_SPIM_Type * p_reg, uint32_t mask)
480 {
481 nrf_spim_shorts_disable(p_reg, mask);
482 nrf_barrier_w();
483 }
484
485 /** @refhal{nrf_spim_shorts_get} */
nrfy_spim_shorts_get(NRF_SPIM_Type const * p_reg)486 NRFY_STATIC_INLINE uint32_t nrfy_spim_shorts_get(NRF_SPIM_Type const * p_reg)
487 {
488 nrf_barrier_rw();
489 uint32_t shorts = nrf_spim_shorts_get(p_reg);
490 nrf_barrier_r();
491 return shorts;
492 }
493
494 /** @refhal{nrf_spim_int_enable} */
nrfy_spim_int_enable(NRF_SPIM_Type * p_reg,uint32_t mask)495 NRFY_STATIC_INLINE void nrfy_spim_int_enable(NRF_SPIM_Type * p_reg, uint32_t mask)
496 {
497 nrf_spim_int_enable(p_reg, mask);
498 nrf_barrier_w();
499 }
500
501 /** @refhal{nrf_spim_int_disable} */
nrfy_spim_int_disable(NRF_SPIM_Type * p_reg,uint32_t mask)502 NRFY_STATIC_INLINE void nrfy_spim_int_disable(NRF_SPIM_Type * p_reg, uint32_t mask)
503 {
504 nrf_spim_int_disable(p_reg, mask);
505 nrf_barrier_w();
506 }
507
508 /** @refhal{nrf_spim_int_enable_check} */
nrfy_spim_int_enable_check(NRF_SPIM_Type const * p_reg,uint32_t mask)509 NRFY_STATIC_INLINE uint32_t nrfy_spim_int_enable_check(NRF_SPIM_Type const * p_reg, uint32_t mask)
510 {
511 nrf_barrier_rw();
512 uint32_t check = nrf_spim_int_enable_check(p_reg, mask);
513 nrf_barrier_r();
514 return check;
515 }
516
517 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
518 /** @refhal{nrf_spim_subscribe_set} */
nrfy_spim_subscribe_set(NRF_SPIM_Type * p_reg,nrf_spim_task_t task,uint8_t channel)519 NRFY_STATIC_INLINE void nrfy_spim_subscribe_set(NRF_SPIM_Type * p_reg,
520 nrf_spim_task_t task,
521 uint8_t channel)
522 {
523 nrf_spim_subscribe_set(p_reg, task, channel);
524 nrf_barrier_w();
525 }
526
527 /** @refhal{nrf_spim_subscribe_clear} */
nrfy_spim_subscribe_clear(NRF_SPIM_Type * p_reg,nrf_spim_task_t task)528 NRFY_STATIC_INLINE void nrfy_spim_subscribe_clear(NRF_SPIM_Type * p_reg,
529 nrf_spim_task_t task)
530 {
531 nrf_spim_subscribe_clear(p_reg, task);
532 nrf_barrier_w();
533 }
534
535 /** @refhal{nrf_spim_publish_set} */
nrfy_spim_publish_set(NRF_SPIM_Type * p_reg,nrf_spim_event_t event,uint8_t channel)536 NRFY_STATIC_INLINE void nrfy_spim_publish_set(NRF_SPIM_Type * p_reg,
537 nrf_spim_event_t event,
538 uint8_t channel)
539 {
540 nrf_spim_publish_set(p_reg, event, channel);
541 nrf_barrier_w();
542 }
543
544 /** @refhal{nrf_spim_publish_clear} */
nrfy_spim_publish_clear(NRF_SPIM_Type * p_reg,nrf_spim_event_t event)545 NRFY_STATIC_INLINE void nrfy_spim_publish_clear(NRF_SPIM_Type * p_reg,
546 nrf_spim_event_t event)
547 {
548 nrf_spim_publish_clear(p_reg, event);
549 nrf_barrier_w();
550 }
551 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
552
553 /** @refhal{nrf_spim_enable} */
nrfy_spim_enable(NRF_SPIM_Type * p_reg)554 NRFY_STATIC_INLINE void nrfy_spim_enable(NRF_SPIM_Type * p_reg)
555 {
556 nrf_spim_enable(p_reg);
557 nrf_barrier_w();
558 }
559
560 /** @refhal{nrf_spim_disable} */
nrfy_spim_disable(NRF_SPIM_Type * p_reg)561 NRFY_STATIC_INLINE void nrfy_spim_disable(NRF_SPIM_Type * p_reg)
562 {
563 nrf_spim_disable(p_reg);
564 nrf_barrier_w();
565 }
566
567 /** @refhal{nrf_spim_enable_check} */
nrfy_spim_enable_check(NRF_SPIM_Type const * p_reg)568 NRFY_STATIC_INLINE bool nrfy_spim_enable_check(NRF_SPIM_Type const * p_reg)
569 {
570 nrf_barrier_rw();
571 bool check = nrf_spim_enable_check(p_reg);
572 nrf_barrier_r();
573 return check;
574 }
575
576 /** @refhal{nrf_spim_pins_set} */
nrfy_spim_pins_set(NRF_SPIM_Type * p_reg,uint32_t sck_pin,uint32_t mosi_pin,uint32_t miso_pin)577 NRFY_STATIC_INLINE void nrfy_spim_pins_set(NRF_SPIM_Type * p_reg,
578 uint32_t sck_pin,
579 uint32_t mosi_pin,
580 uint32_t miso_pin)
581 {
582 nrf_spim_pins_set(p_reg, sck_pin, mosi_pin, miso_pin);
583 nrf_barrier_w();
584 }
585
586 /** @refhal{nrf_spim_sck_pin_get} */
nrfy_spim_sck_pin_get(NRF_SPIM_Type const * p_reg)587 NRFY_STATIC_INLINE uint32_t nrfy_spim_sck_pin_get(NRF_SPIM_Type const * p_reg)
588 {
589 nrf_barrier_rw();
590 uint32_t pin = nrf_spim_sck_pin_get(p_reg);
591 nrf_barrier_r();
592 return pin;
593 }
594
595 /** @refhal{nrf_spim_mosi_pin_get} */
nrfy_spim_mosi_pin_get(NRF_SPIM_Type const * p_reg)596 NRFY_STATIC_INLINE uint32_t nrfy_spim_mosi_pin_get(NRF_SPIM_Type const * p_reg)
597 {
598 nrf_barrier_rw();
599 uint32_t pin = nrf_spim_mosi_pin_get(p_reg);
600 nrf_barrier_r();
601 return pin;
602 }
603
604 /** @refhal{nrf_spim_miso_pin_get} */
nrfy_spim_miso_pin_get(NRF_SPIM_Type const * p_reg)605 NRFY_STATIC_INLINE uint32_t nrfy_spim_miso_pin_get(NRF_SPIM_Type const * p_reg)
606 {
607 nrf_barrier_rw();
608 uint32_t pin = nrf_spim_miso_pin_get(p_reg);
609 nrf_barrier_r();
610 return pin;
611 }
612
613
614 #if NRFY_SPIM_HAS_HW_CSN
615 /** @refhal{nrf_spim_csn_configure} */
nrfy_spim_csn_configure(NRF_SPIM_Type * p_reg,uint32_t pin,nrf_spim_csn_pol_t polarity,uint32_t duration)616 NRFY_STATIC_INLINE void nrfy_spim_csn_configure(NRF_SPIM_Type * p_reg,
617 uint32_t pin,
618 nrf_spim_csn_pol_t polarity,
619 uint32_t duration)
620 {
621 nrf_spim_csn_configure(p_reg, pin, polarity, duration);
622 nrf_barrier_w();
623 }
624
625 /** @refhal{nrf_spim_csn_pin_get} */
nrfy_spim_csn_pin_get(NRF_SPIM_Type const * p_reg)626 NRFY_STATIC_INLINE uint32_t nrfy_spim_csn_pin_get(NRF_SPIM_Type const * p_reg)
627 {
628 nrf_barrier_rw();
629 uint32_t pin = nrf_spim_csn_pin_get(p_reg);
630 nrf_barrier_r();
631 return pin;
632 }
633 #endif
634
635 #if NRFY_SPIM_HAS_DCX
636 /** @refhal{nrf_spim_dcx_pin_set} */
nrfy_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,uint32_t dcx_pin)637 NRFY_STATIC_INLINE void nrfy_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,
638 uint32_t dcx_pin)
639 {
640 nrf_spim_dcx_pin_set(p_reg, dcx_pin);
641 nrf_barrier_w();
642 }
643
644 /** @refhal{nrf_spim_dcx_pin_get} */
nrfy_spim_dcx_pin_get(NRF_SPIM_Type const * p_reg)645 NRFY_STATIC_INLINE uint32_t nrfy_spim_dcx_pin_get(NRF_SPIM_Type const * p_reg)
646 {
647 nrf_barrier_rw();
648 uint32_t pin = nrf_spim_dcx_pin_get(p_reg);
649 nrf_barrier_r();
650 return pin;
651 }
652
653 /** @refhal{nrf_spim_dcx_cnt_set} */
nrfy_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg,uint32_t count)654 NRFY_STATIC_INLINE void nrfy_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg, uint32_t count)
655 {
656 nrf_spim_dcx_cnt_set(p_reg, count);
657 nrf_barrier_w();
658 }
659 #endif
660
661 #if NRFY_SPIM_HAS_RXDELAY
662 /** @refhal{nrf_spim_iftiming_set} */
nrfy_spim_iftiming_set(NRF_SPIM_Type * p_reg,uint32_t rxdelay)663 NRFY_STATIC_INLINE void nrfy_spim_iftiming_set(NRF_SPIM_Type * p_reg,
664 uint32_t rxdelay)
665 {
666 nrf_spim_iftiming_set(p_reg, rxdelay);
667 nrf_barrier_w();
668 }
669 #endif
670
671 #if NRFY_SPIM_HAS_STALLSTAT
672 /** @refhal{nrf_spim_stallstat_rx_clear} */
nrfy_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg)673 NRFY_STATIC_INLINE void nrfy_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg)
674 {
675 nrf_spim_stallstat_rx_clear(p_reg);
676 nrf_barrier_w();
677 }
678
679 /** @refhal{nrf_spim_stallstat_rx_get} */
nrfy_spim_stallstat_rx_get(NRF_SPIM_Type const * p_reg)680 NRFY_STATIC_INLINE bool nrfy_spim_stallstat_rx_get(NRF_SPIM_Type const * p_reg)
681 {
682 nrf_barrier_rw();
683 bool stallstat = nrf_spim_stallstat_rx_get(p_reg);
684 nrf_barrier_r();
685 return stallstat;
686 }
687
688 /** @refhal{nrf_spim_stallstat_tx_clear} */
nrfy_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg)689 NRFY_STATIC_INLINE void nrfy_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg)
690 {
691 nrf_spim_stallstat_tx_clear(p_reg);
692 nrf_barrier_w();
693 }
694
695 /** @refhal{nrf_spim_stallstat_tx_get} */
nrfy_spim_stallstat_tx_get(NRF_SPIM_Type const * p_reg)696 NRFY_STATIC_INLINE bool nrfy_spim_stallstat_tx_get(NRF_SPIM_Type const * p_reg)
697 {
698 nrf_barrier_rw();
699 bool stallstat = nrf_spim_stallstat_tx_get(p_reg);
700 nrf_barrier_r();
701 return stallstat;
702 }
703 #endif // NRFY_SPIM_HAS_STALLSTAT
704
705 #if NRFY_SPIM_HAS_FREQUENCY
706 /** @refhal{nrf_spim_frequency_set} */
nrfy_spim_frequency_set(NRF_SPIM_Type * p_reg,nrf_spim_frequency_t frequency)707 NRFY_STATIC_INLINE void nrfy_spim_frequency_set(NRF_SPIM_Type * p_reg,
708 nrf_spim_frequency_t frequency)
709 {
710 nrf_spim_frequency_set(p_reg, frequency);
711 nrf_barrier_w();
712 }
713 #endif
714
715 #if NRFY_SPIM_HAS_PRESCALER
716 /** @refhal{nrf_spim_prescaler_set} */
nrfy_spim_prescaler_set(NRF_SPIM_Type * p_reg,uint32_t prescaler)717 NRFY_STATIC_INLINE void nrfy_spim_prescaler_set(NRF_SPIM_Type * p_reg, uint32_t prescaler)
718 {
719 nrf_spim_prescaler_set(p_reg, prescaler);
720 nrf_barrier_w();
721 }
722
723 /** @refhal{nrf_spim_prescaler_get} */
nrfy_spim_prescaler_get(NRF_SPIM_Type const * p_reg)724 NRFY_STATIC_INLINE uint32_t nrfy_spim_prescaler_get(NRF_SPIM_Type const * p_reg)
725 {
726 nrf_barrier_rw();
727 uint32_t prescaler = nrf_spim_prescaler_get(p_reg);
728 nrf_barrier_r();
729 return prescaler;
730 }
731 #endif
732
733 /** @refhal{nrf_spim_tx_buffer_set} */
nrfy_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,uint8_t const * p_buffer,size_t length)734 NRFY_STATIC_INLINE void nrfy_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,
735 uint8_t const * p_buffer,
736 size_t length)
737 {
738 nrf_spim_tx_buffer_set(p_reg, p_buffer, length);
739 nrf_barrier_w();
740 }
741
742 /** @refhal{nrf_spim_tx_amount_get} */
nrfy_spim_tx_amount_get(NRF_SPIM_Type const * p_reg)743 NRFY_STATIC_INLINE uint32_t nrfy_spim_tx_amount_get(NRF_SPIM_Type const * p_reg)
744 {
745 nrf_barrier_r();
746 uint32_t amount = nrf_spim_tx_amount_get(p_reg);
747 nrf_barrier_r();
748 return amount;
749 }
750
751 /** @refhal{nrf_spim_tx_maxcnt_get} */
nrfy_spim_tx_maxcnt_get(NRF_SPIM_Type const * p_reg)752 NRFY_STATIC_INLINE uint32_t nrfy_spim_tx_maxcnt_get(NRF_SPIM_Type const * p_reg)
753 {
754 nrf_barrier_rw();
755 uint32_t maxcnt = nrf_spim_tx_maxcnt_get(p_reg);
756 nrf_barrier_r();
757 return maxcnt;
758 }
759
760 /** @refhal{nrf_spim_rx_buffer_set} */
nrfy_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,uint8_t * p_buffer,size_t length)761 NRFY_STATIC_INLINE void nrfy_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,
762 uint8_t * p_buffer,
763 size_t length)
764 {
765 nrf_spim_rx_buffer_set(p_reg, p_buffer, length);
766 nrf_barrier_w();
767 }
768
769 /** @refhal{nrf_spim_tx_amount_get} */
nrfy_spim_rx_amount_get(NRF_SPIM_Type const * p_reg)770 NRFY_STATIC_INLINE uint32_t nrfy_spim_rx_amount_get(NRF_SPIM_Type const * p_reg)
771 {
772 nrf_barrier_r();
773 uint32_t amount = nrf_spim_rx_amount_get(p_reg);
774 nrf_barrier_r();
775 return amount;
776 }
777
778 /** @refhal{nrf_spim_rx_maxcnt_get} */
nrfy_spim_rx_maxcnt_get(NRF_SPIM_Type const * p_reg)779 NRFY_STATIC_INLINE uint32_t nrfy_spim_rx_maxcnt_get(NRF_SPIM_Type const * p_reg)
780 {
781 nrf_barrier_rw();
782 uint32_t maxcnt = nrf_spim_rx_maxcnt_get(p_reg);
783 nrf_barrier_r();
784 return maxcnt;
785 }
786
787 /** @refhal{nrf_spim_configure} */
nrfy_spim_configure(NRF_SPIM_Type * p_reg,nrf_spim_mode_t spi_mode,nrf_spim_bit_order_t spi_bit_order)788 NRFY_STATIC_INLINE void nrfy_spim_configure(NRF_SPIM_Type * p_reg,
789 nrf_spim_mode_t spi_mode,
790 nrf_spim_bit_order_t spi_bit_order)
791 {
792 nrf_spim_configure(p_reg, spi_mode, spi_bit_order);
793 nrf_barrier_w();
794 }
795
796 /** @refhal{nrf_spim_orc_set} */
nrfy_spim_orc_set(NRF_SPIM_Type * p_reg,uint8_t orc)797 NRFY_STATIC_INLINE void nrfy_spim_orc_set(NRF_SPIM_Type * p_reg,
798 uint8_t orc)
799 {
800 nrf_spim_orc_set(p_reg, orc);
801 nrf_barrier_w();
802 }
803
804 /** @} */
805
__nrfy_internal_spim_event_handle(NRF_SPIM_Type * p_reg,uint32_t mask,nrf_spim_event_t event,uint32_t * p_evt_mask)806 NRFY_STATIC_INLINE bool __nrfy_internal_spim_event_handle(NRF_SPIM_Type * p_reg,
807 uint32_t mask,
808 nrf_spim_event_t event,
809 uint32_t * p_evt_mask)
810 {
811 if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_spim_event_check(p_reg, event))
812 {
813 nrf_spim_event_clear(p_reg, event);
814 if (p_evt_mask)
815 {
816 *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
817 }
818 return true;
819 }
820 return false;
821 }
822
823 NRFY_STATIC_INLINE
__nrfy_internal_spim_events_process(NRF_SPIM_Type * p_reg,uint32_t mask,nrfy_spim_xfer_desc_t const * p_xfer)824 uint32_t __nrfy_internal_spim_events_process(NRF_SPIM_Type * p_reg,
825 uint32_t mask,
826 nrfy_spim_xfer_desc_t const * p_xfer)
827 {
828 uint32_t evt_mask = 0;
829
830 nrf_barrier_r();
831 (void)__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_STARTED, &evt_mask);
832
833 bool stop = __nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_STOPPED, &evt_mask);
834
835 bool invalidated = false;
836 if (__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_END, &evt_mask) && p_xfer)
837 {
838 size_t size = stop ? nrf_spim_rx_amount_get(p_reg) : p_xfer->rx_length;
839 NRFY_CACHE_INV(p_xfer->p_rx_buffer, size);
840 invalidated = true;
841 }
842
843 if (__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_ENDRX, &evt_mask) &&
844 p_xfer && !invalidated)
845 {
846 size_t size = stop ? nrf_spim_rx_amount_get(p_reg) : p_xfer->rx_length;
847 NRFY_CACHE_INV(p_xfer->p_rx_buffer, size);
848 }
849
850 (void)__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_ENDTX, &evt_mask);
851
852 return evt_mask;
853 }
854
__nrfy_internal_spim_event_enabled_clear(NRF_SPIM_Type * p_reg,uint32_t mask,nrf_spim_event_t event)855 NRFY_STATIC_INLINE void __nrfy_internal_spim_event_enabled_clear(NRF_SPIM_Type * p_reg,
856 uint32_t mask,
857 nrf_spim_event_t event)
858 {
859 if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
860 {
861 nrf_spim_event_clear(p_reg, event);
862 }
863 }
864
865 #ifdef __cplusplus
866 }
867 #endif
868
869 #endif // NRFY_SPIM_H__
870