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