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