1 /*
2 * Copyright (c) 2021 - 2023, 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 /**< Used only if @p ext_enable is true. */
192 bool ext_enable; ///< True if extended features are to be configured, false otherwise.
193 #endif
194 bool skip_psel_cfg; ///< Skip pin selection configuration.
195 /**< When set to true, the driver does not modify
196 * pin select registers in the peripheral.
197 * Those registers are supposed to be set up
198 * externally before the driver is initialized.
199 * @note When both GPIO configuration and pin
200 * selection are to be skipped, the structure
201 * fields that specify pins can be omitted,
202 * as they are ignored anyway. */
203 } nrfy_spim_config_t;
204
205 /**
206 * @brief Function for configuring the SPIM.
207 *
208 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
209 * @param[in] p_config Pointer to the peripheral configuration structure.
210 */
nrfy_spim_periph_configure(NRF_SPIM_Type * p_reg,nrfy_spim_config_t const * p_config)211 NRFY_STATIC_INLINE void nrfy_spim_periph_configure(NRF_SPIM_Type * p_reg,
212 nrfy_spim_config_t const * p_config)
213 {
214 if (!p_config->skip_psel_cfg)
215 {
216 nrf_spim_pins_set(p_reg,
217 p_config->pins.sck_pin, p_config->pins.mosi_pin, p_config->pins.miso_pin);
218 }
219 nrf_spim_orc_set(p_reg, p_config->orc);
220 #if NRFY_SPIM_HAS_FREQUENCY
221 nrf_spim_frequency_set(p_reg, p_config->frequency);
222 #elif NRFY_SPIM_HAS_PRESCALER
223 nrf_spim_prescaler_set(p_reg, p_config->prescaler);
224 #endif
225 nrf_spim_configure(p_reg, p_config->mode, p_config->bit_order);
226 #if NRFY_SPIM_HAS_EXTENDED
227 if (p_config->ext_enable)
228 {
229 if (!p_config->skip_psel_cfg)
230 {
231 #if NRFY_SPIM_HAS_DCX
232 if (p_config->ext_config.pins.dcx_pin != NRF_SPIM_PIN_NOT_CONNECTED)
233 {
234 nrf_spim_dcx_pin_set(p_reg, p_config->ext_config.pins.dcx_pin);
235 }
236 #endif
237 #if NRFY_SPIM_HAS_HW_CSN
238 if (p_config->ext_config.pins.csn_pin != NRF_SPIM_PIN_NOT_CONNECTED)
239 {
240 nrf_spim_csn_configure(p_reg,
241 p_config->ext_config.pins.csn_pin,
242 p_config->ext_config.csn_pol,
243 p_config->ext_config.csn_duration);
244 }
245 #endif
246 }
247 #if NRFY_SPIM_HAS_RXDELAY
248 nrf_spim_iftiming_set(p_reg, p_config->ext_config.rx_delay);
249 #endif
250 }
251 #endif // NRFY_SPIM_HAS_EXTENDED
252 nrf_barrier_w();
253 }
254
255 /**
256 * @brief Function for initializing the specified SPIM interrupts.
257 *
258 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
259 * @param[in] mask Mask of interrupts to be initialized.
260 * @param[in] irq_priority Interrupt priority.
261 * @param[in] enable True if interrupts associated with the event mask are to be enabled, false otherwise.
262 */
nrfy_spim_int_init(NRF_SPIM_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)263 NRFY_STATIC_INLINE void nrfy_spim_int_init(NRF_SPIM_Type * p_reg,
264 uint32_t mask,
265 uint8_t irq_priority,
266 bool enable)
267 {
268 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_STOPPED);
269 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_ENDRX);
270 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_END);
271 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_ENDTX);
272 __nrfy_internal_spim_event_enabled_clear(p_reg, mask, NRF_SPIM_EVENT_STARTED);
273
274 nrf_barrier_w();
275 NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
276 NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
277 if (enable)
278 {
279 nrf_spim_int_enable(p_reg, mask);
280 }
281 nrf_barrier_w();
282 }
283
284 /**
285 * @brief Function for uninitializing the SPIM interrupts.
286 *
287 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
288 */
nrfy_spim_int_uninit(NRF_SPIM_Type * p_reg)289 NRFY_STATIC_INLINE void nrfy_spim_int_uninit(NRF_SPIM_Type * p_reg)
290 {
291 NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
292 nrf_barrier_w();
293 }
294
295 /**
296 * @brief Function for processing the specified SPIM events.
297 *
298 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
299 * @param[in] mask Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK();
300 * @param[in] p_xfer Pointer to the structure containing buffers associated with the last transaction.
301 * Can be NULL.
302 *
303 * @return Mask of events that were generated and processed.
304 * To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
305 */
nrfy_spim_events_process(NRF_SPIM_Type * p_reg,uint32_t mask,nrfy_spim_xfer_desc_t const * p_xfer)306 NRFY_STATIC_INLINE uint32_t nrfy_spim_events_process(NRF_SPIM_Type * p_reg,
307 uint32_t mask,
308 nrfy_spim_xfer_desc_t const * p_xfer)
309 {
310 uint32_t evt_mask = __nrfy_internal_spim_events_process(p_reg, mask, p_xfer);
311 nrf_barrier_w();
312 return evt_mask;
313 }
314
315 /**
316 * @brief Function for setting the SPIM transaction buffers.
317 *
318 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
319 * @param[in] p_xfer Pointer to the structure containing transaction buffers.
320 */
nrfy_spim_buffers_set(NRF_SPIM_Type * p_reg,nrfy_spim_xfer_desc_t const * p_xfer)321 NRFY_STATIC_INLINE void nrfy_spim_buffers_set(NRF_SPIM_Type * p_reg,
322 nrfy_spim_xfer_desc_t const * p_xfer)
323 {
324 if (p_xfer->p_tx_buffer)
325 {
326 NRFY_CACHE_WB(p_xfer->p_tx_buffer, p_xfer->tx_length);
327 }
328 nrf_spim_tx_buffer_set(p_reg, p_xfer->p_tx_buffer, p_xfer->tx_length);
329 nrf_spim_rx_buffer_set(p_reg, p_xfer->p_rx_buffer, p_xfer->rx_length);
330 nrf_barrier_w();
331 }
332
333 /**
334 * @brief Function for starting the SPIM transaction.
335 *
336 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
337 * @param[in] p_xfer Pointer to the structure containing transaction buffers
338 * if the transaction is to be blocking. NULL for non-blocking transactions.
339 */
nrfy_spim_xfer_start(NRF_SPIM_Type * p_reg,nrfy_spim_xfer_desc_t const * p_xfer)340 NRFY_STATIC_INLINE void nrfy_spim_xfer_start(NRF_SPIM_Type * p_reg,
341 nrfy_spim_xfer_desc_t const * p_xfer)
342 {
343 nrf_spim_task_trigger(p_reg, NRF_SPIM_TASK_START);
344 if (p_xfer)
345 {
346 nrf_barrier_w();
347 while (!nrf_spim_event_check(p_reg, NRF_SPIM_EVENT_END))
348 {}
349 (void)__nrfy_internal_spim_events_process(p_reg,
350 NRFY_EVENT_TO_INT_BITMASK(NRF_SPIM_EVENT_END),
351 p_xfer);
352 }
353 nrf_barrier_w();
354 }
355
356 /**
357 * @brief Function for aborting the ongoing SPIM transaction.
358 *
359 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
360 * @param[in] p_xfer Pointer to the structure containing transaction buffers
361 * if the abort is to be blocking. NULL for non-blocking operation.
362 */
nrfy_spim_abort(NRF_SPIM_Type * p_reg,nrfy_spim_xfer_desc_t const * p_xfer)363 NRFY_STATIC_INLINE void nrfy_spim_abort(NRF_SPIM_Type * p_reg, nrfy_spim_xfer_desc_t const * p_xfer)
364 {
365 nrf_spim_task_trigger(p_reg, NRF_SPIM_TASK_STOP);
366 if (p_xfer)
367 {
368 nrf_barrier_w();
369 uint32_t evt_mask = NRFY_EVENT_TO_INT_BITMASK(NRF_SPIM_EVENT_STOPPED);
370 while (!__nrfy_internal_spim_events_process(p_reg, evt_mask, p_xfer))
371 {}
372 (void)__nrfy_internal_spim_events_process(p_reg,
373 NRFY_EVENT_TO_INT_BITMASK(NRF_SPIM_EVENT_END),
374 NULL);
375 }
376 nrf_barrier_w();
377 }
378
379 /**
380 * @brief Function for getting the SPIM pins configuration.
381 *
382 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
383 * @param[out] p_pins Pointer to the structure to be filled with SPIM pins configuration.
384 */
nrfy_spim_pins_get(NRF_SPIM_Type const * p_reg,nrfy_spim_pins_t * p_pins)385 NRFY_STATIC_INLINE void nrfy_spim_pins_get(NRF_SPIM_Type const * p_reg, nrfy_spim_pins_t * p_pins)
386 {
387 p_pins->sck_pin = nrf_spim_sck_pin_get(p_reg);
388 p_pins->mosi_pin = nrf_spim_mosi_pin_get(p_reg);
389 p_pins->miso_pin = nrf_spim_miso_pin_get(p_reg);
390 }
391
392 #if NRFY_SPIM_HAS_EXTENDED
393 /**
394 * @brief Function for getting the configuration of the SPIM pins used for extended features.
395 *
396 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
397 * @param[out] p_pins Pointer to the structure to be filled with SPIM pins configuration.
398 */
nrfy_spim_ext_pins_get(NRF_SPIM_Type const * p_reg,nrfy_spim_ext_pins_t * p_pins)399 NRFY_STATIC_INLINE void nrfy_spim_ext_pins_get(NRF_SPIM_Type const * p_reg,
400 nrfy_spim_ext_pins_t * p_pins)
401 {
402 p_pins->dcx_pin = nrf_spim_dcx_pin_get(p_reg);
403 #if NRFY_SPIM_HAS_HW_CSN
404 p_pins->csn_pin = nrf_spim_csn_pin_get(p_reg);
405 #endif
406 }
407 #endif
408
409 #if NRFY_SPIM_HAS_ARRAY_LIST
410 /**
411 * @brief Function for enabling or disabling the TX list feature.
412 *
413 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
414 * @param[in] enable True if TX list feature is to be enabled, false otherwise.
415 */
nrfy_spim_tx_list_set(NRF_SPIM_Type * p_reg,bool enable)416 NRFY_STATIC_INLINE void nrfy_spim_tx_list_set(NRF_SPIM_Type * p_reg, bool enable)
417 {
418 if (enable)
419 {
420 nrf_spim_tx_list_enable(p_reg);
421 }
422 else
423 {
424 nrf_spim_tx_list_disable(p_reg);
425 }
426 nrf_barrier_w();
427 }
428
429 /**
430 * @brief Function for enabling or disabling the RX list feature.
431 *
432 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
433 * @param[in] enable True if RX list feature is to be enabled, false otherwise.
434 */
nrfy_spim_rx_list_set(NRF_SPIM_Type * p_reg,bool enable)435 NRFY_STATIC_INLINE void nrfy_spim_rx_list_set(NRF_SPIM_Type * p_reg, bool enable)
436 {
437 if (enable)
438 {
439 nrf_spim_rx_list_enable(p_reg);
440 }
441 else
442 {
443 nrf_spim_rx_list_disable(p_reg);
444 }
445 nrf_barrier_w();
446 }
447 #endif
448
449 /** @refhal{nrf_spim_task_trigger} */
nrfy_spim_task_trigger(NRF_SPIM_Type * p_reg,nrf_spim_task_t task)450 NRFY_STATIC_INLINE void nrfy_spim_task_trigger(NRF_SPIM_Type * p_reg,
451 nrf_spim_task_t task)
452 {
453 nrf_spim_task_trigger(p_reg, task);
454 nrf_barrier_w();
455 }
456
457 /** @refhal{nrf_spim_task_address_get} */
nrfy_spim_task_address_get(NRF_SPIM_Type const * p_reg,nrf_spim_task_t task)458 NRFY_STATIC_INLINE uint32_t nrfy_spim_task_address_get(NRF_SPIM_Type const * p_reg,
459 nrf_spim_task_t task)
460 {
461 return nrf_spim_task_address_get(p_reg, task);
462 }
463
464 /** @refhal{nrf_spim_event_clear} */
nrfy_spim_event_clear(NRF_SPIM_Type * p_reg,nrf_spim_event_t event)465 NRFY_STATIC_INLINE void nrfy_spim_event_clear(NRF_SPIM_Type * p_reg, nrf_spim_event_t event)
466 {
467 nrf_spim_event_clear(p_reg, event);
468 nrf_barrier_w();
469 }
470
471 /** @refhal{nrf_spim_event_check} */
nrfy_spim_event_check(NRF_SPIM_Type const * p_reg,nrf_spim_event_t event)472 NRFY_STATIC_INLINE bool nrfy_spim_event_check(NRF_SPIM_Type const * p_reg, nrf_spim_event_t event)
473 {
474 nrf_barrier_r();
475 bool check = nrf_spim_event_check(p_reg, event);
476 nrf_barrier_r();
477 return check;
478 }
479
480 /** @refhal{nrf_spim_event_address_get} */
nrfy_spim_event_address_get(NRF_SPIM_Type const * p_reg,nrf_spim_event_t event)481 NRFY_STATIC_INLINE uint32_t nrfy_spim_event_address_get(NRF_SPIM_Type const * p_reg,
482 nrf_spim_event_t event)
483 {
484 return nrf_spim_event_address_get(p_reg, event);
485 }
486
487 /** @refhal{nrf_spim_shorts_enable} */
nrfy_spim_shorts_enable(NRF_SPIM_Type * p_reg,uint32_t mask)488 NRFY_STATIC_INLINE void nrfy_spim_shorts_enable(NRF_SPIM_Type * p_reg, uint32_t mask)
489 {
490 nrf_spim_shorts_enable(p_reg, mask);
491 nrf_barrier_w();
492 }
493
494 /** @refhal{nrf_spim_shorts_disable} */
nrfy_spim_shorts_disable(NRF_SPIM_Type * p_reg,uint32_t mask)495 NRFY_STATIC_INLINE void nrfy_spim_shorts_disable(NRF_SPIM_Type * p_reg, uint32_t mask)
496 {
497 nrf_spim_shorts_disable(p_reg, mask);
498 nrf_barrier_w();
499 }
500
501 /** @refhal{nrf_spim_shorts_get} */
nrfy_spim_shorts_get(NRF_SPIM_Type const * p_reg)502 NRFY_STATIC_INLINE uint32_t nrfy_spim_shorts_get(NRF_SPIM_Type const * p_reg)
503 {
504 nrf_barrier_rw();
505 uint32_t shorts = nrf_spim_shorts_get(p_reg);
506 nrf_barrier_r();
507 return shorts;
508 }
509
510 /** @refhal{nrf_spim_int_enable} */
nrfy_spim_int_enable(NRF_SPIM_Type * p_reg,uint32_t mask)511 NRFY_STATIC_INLINE void nrfy_spim_int_enable(NRF_SPIM_Type * p_reg, uint32_t mask)
512 {
513 nrf_spim_int_enable(p_reg, mask);
514 nrf_barrier_w();
515 }
516
517 /** @refhal{nrf_spim_int_disable} */
nrfy_spim_int_disable(NRF_SPIM_Type * p_reg,uint32_t mask)518 NRFY_STATIC_INLINE void nrfy_spim_int_disable(NRF_SPIM_Type * p_reg, uint32_t mask)
519 {
520 nrf_spim_int_disable(p_reg, mask);
521 nrf_barrier_w();
522 }
523
524 /** @refhal{nrf_spim_int_enable_check} */
nrfy_spim_int_enable_check(NRF_SPIM_Type const * p_reg,uint32_t mask)525 NRFY_STATIC_INLINE uint32_t nrfy_spim_int_enable_check(NRF_SPIM_Type const * p_reg, uint32_t mask)
526 {
527 nrf_barrier_rw();
528 uint32_t check = nrf_spim_int_enable_check(p_reg, mask);
529 nrf_barrier_r();
530 return check;
531 }
532
533 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
534 /** @refhal{nrf_spim_subscribe_set} */
nrfy_spim_subscribe_set(NRF_SPIM_Type * p_reg,nrf_spim_task_t task,uint8_t channel)535 NRFY_STATIC_INLINE void nrfy_spim_subscribe_set(NRF_SPIM_Type * p_reg,
536 nrf_spim_task_t task,
537 uint8_t channel)
538 {
539 nrf_spim_subscribe_set(p_reg, task, channel);
540 nrf_barrier_w();
541 }
542
543 /** @refhal{nrf_spim_subscribe_clear} */
nrfy_spim_subscribe_clear(NRF_SPIM_Type * p_reg,nrf_spim_task_t task)544 NRFY_STATIC_INLINE void nrfy_spim_subscribe_clear(NRF_SPIM_Type * p_reg,
545 nrf_spim_task_t task)
546 {
547 nrf_spim_subscribe_clear(p_reg, task);
548 nrf_barrier_w();
549 }
550
551 /** @refhal{nrf_spim_publish_set} */
nrfy_spim_publish_set(NRF_SPIM_Type * p_reg,nrf_spim_event_t event,uint8_t channel)552 NRFY_STATIC_INLINE void nrfy_spim_publish_set(NRF_SPIM_Type * p_reg,
553 nrf_spim_event_t event,
554 uint8_t channel)
555 {
556 nrf_spim_publish_set(p_reg, event, channel);
557 nrf_barrier_w();
558 }
559
560 /** @refhal{nrf_spim_publish_clear} */
nrfy_spim_publish_clear(NRF_SPIM_Type * p_reg,nrf_spim_event_t event)561 NRFY_STATIC_INLINE void nrfy_spim_publish_clear(NRF_SPIM_Type * p_reg,
562 nrf_spim_event_t event)
563 {
564 nrf_spim_publish_clear(p_reg, event);
565 nrf_barrier_w();
566 }
567 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
568
569 /** @refhal{nrf_spim_enable} */
nrfy_spim_enable(NRF_SPIM_Type * p_reg)570 NRFY_STATIC_INLINE void nrfy_spim_enable(NRF_SPIM_Type * p_reg)
571 {
572 nrf_spim_enable(p_reg);
573 nrf_barrier_w();
574 }
575
576 /** @refhal{nrf_spim_disable} */
nrfy_spim_disable(NRF_SPIM_Type * p_reg)577 NRFY_STATIC_INLINE void nrfy_spim_disable(NRF_SPIM_Type * p_reg)
578 {
579 nrf_spim_disable(p_reg);
580 nrf_barrier_w();
581 }
582
583 /** @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)584 NRFY_STATIC_INLINE void nrfy_spim_pins_set(NRF_SPIM_Type * p_reg,
585 uint32_t sck_pin,
586 uint32_t mosi_pin,
587 uint32_t miso_pin)
588 {
589 nrf_spim_pins_set(p_reg, sck_pin, mosi_pin, miso_pin);
590 nrf_barrier_w();
591 }
592
593 /** @refhal{nrf_spim_sck_pin_get} */
nrfy_spim_sck_pin_get(NRF_SPIM_Type const * p_reg)594 NRFY_STATIC_INLINE uint32_t nrfy_spim_sck_pin_get(NRF_SPIM_Type const * p_reg)
595 {
596 nrf_barrier_rw();
597 uint32_t pin = nrf_spim_sck_pin_get(p_reg);
598 nrf_barrier_r();
599 return pin;
600 }
601
602 /** @refhal{nrf_spim_mosi_pin_get} */
nrfy_spim_mosi_pin_get(NRF_SPIM_Type const * p_reg)603 NRFY_STATIC_INLINE uint32_t nrfy_spim_mosi_pin_get(NRF_SPIM_Type const * p_reg)
604 {
605 nrf_barrier_rw();
606 uint32_t pin = nrf_spim_mosi_pin_get(p_reg);
607 nrf_barrier_r();
608 return pin;
609 }
610
611 /** @refhal{nrf_spim_miso_pin_get} */
nrfy_spim_miso_pin_get(NRF_SPIM_Type const * p_reg)612 NRFY_STATIC_INLINE uint32_t nrfy_spim_miso_pin_get(NRF_SPIM_Type const * p_reg)
613 {
614 nrf_barrier_rw();
615 uint32_t pin = nrf_spim_miso_pin_get(p_reg);
616 nrf_barrier_r();
617 return pin;
618 }
619
620
621 #if NRFY_SPIM_HAS_HW_CSN
622 /** @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)623 NRFY_STATIC_INLINE void nrfy_spim_csn_configure(NRF_SPIM_Type * p_reg,
624 uint32_t pin,
625 nrf_spim_csn_pol_t polarity,
626 uint32_t duration)
627 {
628 nrf_spim_csn_configure(p_reg, pin, polarity, duration);
629 nrf_barrier_w();
630 }
631
632 /** @refhal{nrf_spim_csn_pin_get} */
nrfy_spim_csn_pin_get(NRF_SPIM_Type const * p_reg)633 NRFY_STATIC_INLINE uint32_t nrfy_spim_csn_pin_get(NRF_SPIM_Type const * p_reg)
634 {
635 nrf_barrier_rw();
636 uint32_t pin = nrf_spim_csn_pin_get(p_reg);
637 nrf_barrier_r();
638 return pin;
639 }
640 #endif
641
642 #if NRFY_SPIM_HAS_DCX
643 /** @refhal{nrf_spim_dcx_pin_set} */
nrfy_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,uint32_t dcx_pin)644 NRFY_STATIC_INLINE void nrfy_spim_dcx_pin_set(NRF_SPIM_Type * p_reg,
645 uint32_t dcx_pin)
646 {
647 nrf_spim_dcx_pin_set(p_reg, dcx_pin);
648 nrf_barrier_w();
649 }
650
651 /** @refhal{nrf_spim_dcx_pin_get} */
nrfy_spim_dcx_pin_get(NRF_SPIM_Type const * p_reg)652 NRFY_STATIC_INLINE uint32_t nrfy_spim_dcx_pin_get(NRF_SPIM_Type const * p_reg)
653 {
654 nrf_barrier_rw();
655 uint32_t pin = nrf_spim_dcx_pin_get(p_reg);
656 nrf_barrier_r();
657 return pin;
658 }
659
660 /** @refhal{nrf_spim_dcx_cnt_set} */
nrfy_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg,uint32_t count)661 NRFY_STATIC_INLINE void nrfy_spim_dcx_cnt_set(NRF_SPIM_Type * p_reg, uint32_t count)
662 {
663 nrf_spim_dcx_cnt_set(p_reg, count);
664 nrf_barrier_w();
665 }
666 #endif
667
668 #if NRFY_SPIM_HAS_RXDELAY
669 /** @refhal{nrf_spim_iftiming_set} */
nrfy_spim_iftiming_set(NRF_SPIM_Type * p_reg,uint32_t rxdelay)670 NRFY_STATIC_INLINE void nrfy_spim_iftiming_set(NRF_SPIM_Type * p_reg,
671 uint32_t rxdelay)
672 {
673 nrf_spim_iftiming_set(p_reg, rxdelay);
674 nrf_barrier_w();
675 }
676 #endif
677
678 #if NRFY_SPIM_HAS_STALLSTAT
679 /** @refhal{nrf_spim_stallstat_rx_clear} */
nrfy_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg)680 NRFY_STATIC_INLINE void nrfy_spim_stallstat_rx_clear(NRF_SPIM_Type * p_reg)
681 {
682 nrf_spim_stallstat_rx_clear(p_reg);
683 nrf_barrier_w();
684 }
685
686 /** @refhal{nrf_spim_stallstat_rx_get} */
nrfy_spim_stallstat_rx_get(NRF_SPIM_Type const * p_reg)687 NRFY_STATIC_INLINE bool nrfy_spim_stallstat_rx_get(NRF_SPIM_Type const * p_reg)
688 {
689 nrf_barrier_rw();
690 bool stallstat = nrf_spim_stallstat_rx_get(p_reg);
691 nrf_barrier_r();
692 return stallstat;
693 }
694
695 /** @refhal{nrf_spim_stallstat_tx_clear} */
nrfy_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg)696 NRFY_STATIC_INLINE void nrfy_spim_stallstat_tx_clear(NRF_SPIM_Type * p_reg)
697 {
698 nrf_spim_stallstat_tx_clear(p_reg);
699 nrf_barrier_w();
700 }
701
702 /** @refhal{nrf_spim_stallstat_tx_get} */
nrfy_spim_stallstat_tx_get(NRF_SPIM_Type const * p_reg)703 NRFY_STATIC_INLINE bool nrfy_spim_stallstat_tx_get(NRF_SPIM_Type const * p_reg)
704 {
705 nrf_barrier_rw();
706 bool stallstat = nrf_spim_stallstat_tx_get(p_reg);
707 nrf_barrier_r();
708 return stallstat;
709 }
710 #endif // NRFY_SPIM_HAS_STALLSTAT
711
712 #if NRFY_SPIM_HAS_FREQUENCY
713 /** @refhal{nrf_spim_frequency_set} */
nrfy_spim_frequency_set(NRF_SPIM_Type * p_reg,nrf_spim_frequency_t frequency)714 NRFY_STATIC_INLINE void nrfy_spim_frequency_set(NRF_SPIM_Type * p_reg,
715 nrf_spim_frequency_t frequency)
716 {
717 nrf_spim_frequency_set(p_reg, frequency);
718 nrf_barrier_w();
719 }
720 #endif
721
722 #if NRFY_SPIM_HAS_PRESCALER
723 /** @refhal{nrf_spim_prescaler_set} */
nrfy_spim_prescaler_set(NRF_SPIM_Type * p_reg,uint32_t prescaler)724 NRFY_STATIC_INLINE void nrfy_spim_prescaler_set(NRF_SPIM_Type * p_reg, uint32_t prescaler)
725 {
726 nrf_spim_prescaler_set(p_reg, prescaler);
727 nrf_barrier_w();
728 }
729
730 /** @refhal{nrf_spim_prescaler_get} */
nrfy_spim_prescaler_get(NRF_SPIM_Type const * p_reg)731 NRFY_STATIC_INLINE uint32_t nrfy_spim_prescaler_get(NRF_SPIM_Type const * p_reg)
732 {
733 nrf_barrier_rw();
734 uint32_t prescaler = nrf_spim_prescaler_get(p_reg);
735 nrf_barrier_r();
736 return prescaler;
737 }
738 #endif
739
740 /** @refhal{nrf_spim_tx_buffer_set} */
nrfy_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,uint8_t const * p_buffer,size_t length)741 NRFY_STATIC_INLINE void nrfy_spim_tx_buffer_set(NRF_SPIM_Type * p_reg,
742 uint8_t const * p_buffer,
743 size_t length)
744 {
745 nrf_spim_tx_buffer_set(p_reg, p_buffer, length);
746 nrf_barrier_w();
747 }
748
749 /** @refhal{nrf_spim_tx_amount_get} */
nrfy_spim_tx_amount_get(NRF_SPIM_Type const * p_reg)750 NRFY_STATIC_INLINE uint32_t nrfy_spim_tx_amount_get(NRF_SPIM_Type const * p_reg)
751 {
752 nrf_barrier_r();
753 uint32_t amount = nrf_spim_tx_amount_get(p_reg);
754 nrf_barrier_r();
755 return amount;
756 }
757
758 /** @refhal{nrf_spim_tx_maxcnt_get} */
nrfy_spim_tx_maxcnt_get(NRF_SPIM_Type const * p_reg)759 NRFY_STATIC_INLINE uint32_t nrfy_spim_tx_maxcnt_get(NRF_SPIM_Type const * p_reg)
760 {
761 nrf_barrier_rw();
762 uint32_t maxcnt = nrf_spim_tx_maxcnt_get(p_reg);
763 nrf_barrier_r();
764 return maxcnt;
765 }
766
767 /** @refhal{nrf_spim_rx_buffer_set} */
nrfy_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,uint8_t * p_buffer,size_t length)768 NRFY_STATIC_INLINE void nrfy_spim_rx_buffer_set(NRF_SPIM_Type * p_reg,
769 uint8_t * p_buffer,
770 size_t length)
771 {
772 nrf_spim_rx_buffer_set(p_reg, p_buffer, length);
773 nrf_barrier_w();
774 }
775
776 /** @refhal{nrf_spim_tx_amount_get} */
nrfy_spim_rx_amount_get(NRF_SPIM_Type const * p_reg)777 NRFY_STATIC_INLINE uint32_t nrfy_spim_rx_amount_get(NRF_SPIM_Type const * p_reg)
778 {
779 nrf_barrier_r();
780 uint32_t amount = nrf_spim_rx_amount_get(p_reg);
781 nrf_barrier_r();
782 return amount;
783 }
784
785 /** @refhal{nrf_spim_rx_maxcnt_get} */
nrfy_spim_rx_maxcnt_get(NRF_SPIM_Type const * p_reg)786 NRFY_STATIC_INLINE uint32_t nrfy_spim_rx_maxcnt_get(NRF_SPIM_Type const * p_reg)
787 {
788 nrf_barrier_rw();
789 uint32_t maxcnt = nrf_spim_rx_maxcnt_get(p_reg);
790 nrf_barrier_r();
791 return maxcnt;
792 }
793
794 /** @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)795 NRFY_STATIC_INLINE void nrfy_spim_configure(NRF_SPIM_Type * p_reg,
796 nrf_spim_mode_t spi_mode,
797 nrf_spim_bit_order_t spi_bit_order)
798 {
799 nrf_spim_configure(p_reg, spi_mode, spi_bit_order);
800 nrf_barrier_w();
801 }
802
803 /** @refhal{nrf_spim_orc_set} */
nrfy_spim_orc_set(NRF_SPIM_Type * p_reg,uint8_t orc)804 NRFY_STATIC_INLINE void nrfy_spim_orc_set(NRF_SPIM_Type * p_reg,
805 uint8_t orc)
806 {
807 nrf_spim_orc_set(p_reg, orc);
808 nrf_barrier_w();
809 }
810
811 /** @} */
812
__nrfy_internal_spim_event_handle(NRF_SPIM_Type * p_reg,uint32_t mask,nrf_spim_event_t event,uint32_t * p_evt_mask)813 NRFY_STATIC_INLINE bool __nrfy_internal_spim_event_handle(NRF_SPIM_Type * p_reg,
814 uint32_t mask,
815 nrf_spim_event_t event,
816 uint32_t * p_evt_mask)
817 {
818 if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_spim_event_check(p_reg, event))
819 {
820 nrf_spim_event_clear(p_reg, event);
821 if (p_evt_mask)
822 {
823 *p_evt_mask |= NRFY_EVENT_TO_INT_BITMASK(event);
824 }
825 return true;
826 }
827 return false;
828 }
829
830 NRFY_STATIC_INLINE
__nrfy_internal_spim_events_process(NRF_SPIM_Type * p_reg,uint32_t mask,nrfy_spim_xfer_desc_t const * p_xfer)831 uint32_t __nrfy_internal_spim_events_process(NRF_SPIM_Type * p_reg,
832 uint32_t mask,
833 nrfy_spim_xfer_desc_t const * p_xfer)
834 {
835 uint32_t evt_mask = 0;
836
837 nrf_barrier_r();
838 (void)__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_STARTED, &evt_mask);
839
840 bool stop = __nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_STOPPED, &evt_mask);
841
842 bool invalidated = false;
843 if (__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_END, &evt_mask) && p_xfer)
844 {
845 size_t size = stop ? nrf_spim_rx_amount_get(p_reg) : p_xfer->rx_length;
846 NRFY_CACHE_INV(p_xfer->p_rx_buffer, size);
847 invalidated = true;
848 }
849
850 if (__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_ENDRX, &evt_mask) &&
851 p_xfer && !invalidated)
852 {
853 size_t size = stop ? nrf_spim_rx_amount_get(p_reg) : p_xfer->rx_length;
854 NRFY_CACHE_INV(p_xfer->p_rx_buffer, size);
855 }
856
857 (void)__nrfy_internal_spim_event_handle(p_reg, mask, NRF_SPIM_EVENT_ENDTX, &evt_mask);
858
859 return evt_mask;
860 }
861
__nrfy_internal_spim_event_enabled_clear(NRF_SPIM_Type * p_reg,uint32_t mask,nrf_spim_event_t event)862 NRFY_STATIC_INLINE void __nrfy_internal_spim_event_enabled_clear(NRF_SPIM_Type * p_reg,
863 uint32_t mask,
864 nrf_spim_event_t event)
865 {
866 if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
867 {
868 nrf_spim_event_clear(p_reg, event);
869 }
870 }
871
872 #ifdef __cplusplus
873 }
874 #endif
875
876 #endif // NRFY_SPIM_H__
877