1 /*
2  * Copyright (c) 2015 - 2024, 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 #ifndef NRF_PDM_H_
34 #define NRF_PDM_H_
35 
36 #include <nrfx.h>
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 #if !defined(NRF_PDM0) && defined(NRF_PDM)
43 #define NRF_PDM0 NRF_PDM
44 #endif
45 
46 /**
47  * @defgroup nrf_pdm_hal PDM HAL
48  * @{
49  * @ingroup nrf_pdm
50  * @brief   Hardware access layer for managing the Pulse Density Modulation (PDM) peripheral.
51  */
52 
53 #if defined(PDM_MCLKCONFIG_SRC_Msk) || defined(__NRFX_DOXYGEN__)
54 /** @brief Symbol indicating whether master clock source configuration is available. */
55 #define NRF_PDM_HAS_MCLKCONFIG 1
56 #else
57 #define NRF_PDM_HAS_MCLKCONFIG 0
58 #endif
59 
60 #if defined(PDM_RATIO_RATIO_Msk) || defined(__NRFX_DOXYGEN__)
61 /** @brief Symbol indicating whether ratio configuration is available. */
62 #define NRF_PDM_HAS_RATIO_CONFIG 1
63 #else
64 #define NRF_PDM_HAS_RATIO_CONFIG 0
65 #endif
66 
67 #if defined(PDM_DMA_PTR_PTR_Msk) || defined(__NRFX_DOXYGEN__)
68 /** @brief Symbol indicating whether dedicated DMA register is present. */
69 #define NRF_PDM_HAS_DMA_REG 1
70 #else
71 #define NRF_PDM_HAS_DMA_REG 0
72 #endif
73 
74 #if (defined(PDM_TASKS_DMA_START_START_Msk) && defined(PDM_EVENTS_DMA_END_END_Msk)) || \
75     defined(__NRFX_DOXYGEN__)
76 /** @brief Symbol indicating whether PDM DMA tasks and events are present. */
77 #define NRF_PDM_HAS_DMA_TASKS_EVENTS 1
78 #else
79 #define NRF_PDM_HAS_DMA_TASKS_EVENTS 0
80 #endif
81 
82 /** @brief Minimum value of PDM gain. */
83 #define NRF_PDM_GAIN_MINIMUM  0x00
84 /** @brief Default value of PDM gain. */
85 #define NRF_PDM_GAIN_DEFAULT  0x28
86 /** @brief Maximum value of PDM gain. */
87 #define NRF_PDM_GAIN_MAXIMUM  0x50
88 
89 
90 /** @brief PDM gain type. */
91 typedef uint8_t nrf_pdm_gain_t;
92 
93 /** @brief PDM tasks. */
94 typedef enum
95 {
96 #if NRF_PDM_HAS_DMA_TASKS_EVENTS
97     NRF_PDM_TASK_START = offsetof(NRF_PDM_Type, TASKS_DMA.START), ///< Starts continuous PDM transfer.
98     NRF_PDM_TASK_STOP  = offsetof(NRF_PDM_Type, TASKS_DMA.STOP),  ///< Stops PDM transfer.
99 #else
100     NRF_PDM_TASK_START = offsetof(NRF_PDM_Type, TASKS_START),     ///< Starts continuous PDM transfer.
101     NRF_PDM_TASK_STOP  = offsetof(NRF_PDM_Type, TASKS_STOP),      ///< Stops PDM transfer.
102 #endif
103 } nrf_pdm_task_t;
104 
105 /** @brief PDM events. */
106 typedef enum
107 {
108     NRF_PDM_EVENT_STARTED = offsetof(NRF_PDM_Type, EVENTS_STARTED), ///< PDM transfer is started.
109     NRF_PDM_EVENT_STOPPED = offsetof(NRF_PDM_Type, EVENTS_STOPPED), ///< PDM transfer is finished.
110 #if NRF_PDM_HAS_DMA_TASKS_EVENTS
111     NRF_PDM_EVENT_END     = offsetof(NRF_PDM_Type, EVENTS_DMA.END), ///< The PDM has written the last sample specified by MAXCNT (or the last sample after a STOP task has been received) to Data RAM.
112 #else
113     NRF_PDM_EVENT_END     = offsetof(NRF_PDM_Type, EVENTS_END),     ///< The PDM has written the last sample specified by MAXCNT (or the last sample after a STOP task has been received) to Data RAM.
114 #endif
115 } nrf_pdm_event_t;
116 
117 /** @brief PDM interrupt masks. */
118 typedef enum
119 {
120     NRF_PDM_INT_STARTED = PDM_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event.
121     NRF_PDM_INT_STOPPED = PDM_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event.
122 #if NRF_PDM_HAS_DMA_TASKS_EVENTS
123     NRF_PDM_INT_END     = PDM_INTENSET_DMAEND_Msk   ///< Interrupt on EVENTS_END event.
124 #else
125     NRF_PDM_INT_END     = PDM_INTENSET_END_Msk      ///< Interrupt on EVENTS_END event.
126 #endif
127 } nrf_pdm_int_mask_t;
128 
129 /** @brief PDM clock frequency. */
130 typedef enum
131 {
132     NRF_PDM_FREQ_1000K = PDM_PDMCLKCTRL_FREQ_1000K,   ///< PDM_CLK = 1.000 MHz.
133     NRF_PDM_FREQ_1032K = PDM_PDMCLKCTRL_FREQ_Default, ///< PDM_CLK = 1.032 MHz.
134     NRF_PDM_FREQ_1067K = PDM_PDMCLKCTRL_FREQ_1067K,   ///< PDM_CLK = 1.067 MHz.
135 #if defined(PDM_PDMCLKCTRL_FREQ_1231K) || defined(__NRFX_DOXYGEN__)
136     NRF_PDM_FREQ_1231K = PDM_PDMCLKCTRL_FREQ_1231K,   ///< PDM_CLK = 1.231 MHz.
137 #endif
138 #if defined(PDM_PDMCLKCTRL_FREQ_1280K) || defined(__NRFX_DOXYGEN__)
139     NRF_PDM_FREQ_1280K = PDM_PDMCLKCTRL_FREQ_1280K,   ///< PDM_CLK = 1.280 MHz.
140 #endif
141 #if defined(PDM_PDMCLKCTRL_FREQ_1333K) || defined(__NRFX_DOXYGEN__)
142     NRF_PDM_FREQ_1333K = PDM_PDMCLKCTRL_FREQ_1333K    ///< PDM_CLK = 1.333 MHz.
143 #endif
144 } nrf_pdm_freq_t;
145 
146 
147 #if NRF_PDM_HAS_RATIO_CONFIG
148 /** @brief PDM ratio between PDM_CLK and output sample rate. */
149 typedef enum
150 {
151     NRF_PDM_RATIO_64X = PDM_RATIO_RATIO_Ratio64, ///< Ratio of 64.
152     NRF_PDM_RATIO_80X = PDM_RATIO_RATIO_Ratio80  ///< Ratio of 80.
153 } nrf_pdm_ratio_t;
154 #endif
155 
156 /** @brief PDM operation mode. */
157 typedef enum
158 {
159     NRF_PDM_MODE_STEREO = PDM_MODE_OPERATION_Stereo,  ///< Sample and store one pair (Left + Right) of 16-bit samples per RAM word.
160     NRF_PDM_MODE_MONO   = PDM_MODE_OPERATION_Mono     ///< Sample and store two successive Left samples (16 bit each) per RAM word.
161 } nrf_pdm_mode_t;
162 
163 /** @brief PDM sampling mode. */
164 typedef enum
165 {
166     NRF_PDM_EDGE_LEFTFALLING = PDM_MODE_EDGE_LeftFalling,  ///< Left (or mono) is sampled on falling edge of PDM_CLK.
167     NRF_PDM_EDGE_LEFTRISING  = PDM_MODE_EDGE_LeftRising    ///< Left (or mono) is sampled on rising edge of PDM_CLK.
168 } nrf_pdm_edge_t;
169 
170 #if NRF_PDM_HAS_MCLKCONFIG
171 /** @brief PDM master clock source selection. */
172 typedef enum
173 {
174     NRF_PDM_MCLKSRC_PCLK32M = PDM_MCLKCONFIG_SRC_PCLK32M, ///< 32MHz peripheral clock.
175     NRF_PDM_MCLKSRC_ACLK    = PDM_MCLKCONFIG_SRC_ACLK     ///< Audio PLL clock.
176 } nrf_pdm_mclksrc_t;
177 #endif
178 
179 /**
180  * @brief Function for triggering a PDM task.
181  *
182  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
183  * @param[in] task  PDM task.
184  */
185 NRF_STATIC_INLINE void nrf_pdm_task_trigger(NRF_PDM_Type * p_reg, nrf_pdm_task_t task);
186 
187 /**
188  * @brief Function for getting the address of a PDM task register.
189  *
190  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
191  * @param[in] task  PDM task.
192  *
193  * @return Address of the specified PDM task.
194  */
195 NRF_STATIC_INLINE uint32_t nrf_pdm_task_address_get(NRF_PDM_Type const * p_reg,
196                                                     nrf_pdm_task_t       task);
197 
198 /**
199  * @brief Function for retrieving the state of the PDM event.
200  *
201  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
202  * @param[in] event Event to be checked.
203  *
204  * @retval true  The event has been generated.
205  * @retval false The event has not been generated.
206  */
207 NRF_STATIC_INLINE bool nrf_pdm_event_check(NRF_PDM_Type const * p_reg, nrf_pdm_event_t event);
208 
209 /**
210  * @brief Function for clearing a PDM event.
211  *
212  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
213  * @param[in] event PDM event.
214  */
215 NRF_STATIC_INLINE void nrf_pdm_event_clear(NRF_PDM_Type * p_reg, nrf_pdm_event_t event);
216 
217 /**
218  * @brief Function for getting the address of a PDM event register.
219  *
220  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
221  * @param[in] event PDM event.
222  *
223  * @return Address of the specified PDM event.
224  */
225 NRF_STATIC_INLINE uint32_t nrf_pdm_event_address_get(NRF_PDM_Type const * p_reg,
226                                                      nrf_pdm_event_t      event);
227 
228 /**
229  * @brief Function for enabling PDM interrupts.
230  *
231  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
232  * @param[in] mask  Mask of interrupts to be enabled.
233  *                  Use @ref nrf_pdm_int_mask_t values for bit masking.
234  */
235 NRF_STATIC_INLINE void nrf_pdm_int_enable(NRF_PDM_Type * p_reg, uint32_t mask);
236 
237 /**
238  * @brief Function for checking if the specified interrupts are enabled.
239  *
240  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
241  * @param[in] mask  Mask of interrupts to be checked.
242  *                  Use @ref nrf_pdm_int_mask_t values for bit masking.
243  *
244  * @return Mask of enabled interrupts.
245  */
246 NRF_STATIC_INLINE uint32_t nrf_pdm_int_enable_check(NRF_PDM_Type const * p_reg, uint32_t mask);
247 
248 /**
249  * @brief Function for disabling interrupts.
250  *
251  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
252  * @param[in] mask  Mask of interrupts to be disabled.
253  *                  Use @ref nrf_pdm_int_mask_t values for bit masking.
254  */
255 NRF_STATIC_INLINE void nrf_pdm_int_disable(NRF_PDM_Type * p_reg, uint32_t mask);
256 
257 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
258 /**
259  * @brief Function for setting the subscribe configuration for a given
260  *        PDM task.
261  *
262  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
263  * @param[in] task    Task for which to set the configuration.
264  * @param[in] channel Channel through which to subscribe events.
265  */
266 NRF_STATIC_INLINE void nrf_pdm_subscribe_set(NRF_PDM_Type * p_reg,
267                                              nrf_pdm_task_t task,
268                                              uint8_t        channel);
269 
270 /**
271  * @brief Function for clearing the subscribe configuration for a given
272  *        PDM task.
273  *
274  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
275  * @param[in] task  Task for which to clear the configuration.
276  */
277 NRF_STATIC_INLINE void nrf_pdm_subscribe_clear(NRF_PDM_Type * p_reg, nrf_pdm_task_t task);
278 
279 /**
280  * @brief Function for setting the publish configuration for a given
281  *        PDM event.
282  *
283  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
284  * @param[in] event   Event for which to set the configuration.
285  * @param[in] channel Channel through which to publish the event.
286  */
287 NRF_STATIC_INLINE void nrf_pdm_publish_set(NRF_PDM_Type *  p_reg,
288                                            nrf_pdm_event_t event,
289                                            uint8_t         channel);
290 
291 /**
292  * @brief Function for clearing the publish configuration for a given
293  *        PDM event.
294  *
295  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
296  * @param[in] event Event for which to clear the configuration.
297  */
298 NRF_STATIC_INLINE void nrf_pdm_publish_clear(NRF_PDM_Type * p_reg, nrf_pdm_event_t event);
299 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
300 
301 /**
302  * @brief Function for enabling the PDM peripheral.
303  *
304  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
305  *
306  * The PDM peripheral must be enabled before use.
307  */
308 NRF_STATIC_INLINE void nrf_pdm_enable(NRF_PDM_Type * p_reg);
309 
310 /**
311  * @brief Function for disabling the PDM peripheral.
312  *
313  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
314  */
315 NRF_STATIC_INLINE void nrf_pdm_disable(NRF_PDM_Type * p_reg);
316 
317 /**
318  * @brief Function for checking if the PDM peripheral is enabled.
319  *
320  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
321  *
322  * @retval true  The PDM peripheral is enabled.
323  * @retval false The PDM peripheral is not enabled.
324  */
325 NRF_STATIC_INLINE bool nrf_pdm_enable_check(NRF_PDM_Type const * p_reg);
326 
327 /**
328  * @brief Function for setting the PDM operation mode.
329  *
330  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
331  * @param[in] pdm_mode PDM operation mode.
332  * @param[in] pdm_edge PDM sampling mode.
333  */
334 NRF_STATIC_INLINE void nrf_pdm_mode_set(NRF_PDM_Type * p_reg,
335                                         nrf_pdm_mode_t pdm_mode,
336                                         nrf_pdm_edge_t pdm_edge);
337 
338 /**
339  * @brief Function for getting the PDM operation mode.
340  *
341  * @param[in]  p_reg      Pointer to the structure of registers of the peripheral.
342  * @param[out] p_pdm_mode PDM operation mode.
343  * @param[out] p_pdm_edge PDM sampling mode.
344  */
345 NRF_STATIC_INLINE void nrf_pdm_mode_get(NRF_PDM_Type const * p_reg,
346                                         nrf_pdm_mode_t *     p_pdm_mode,
347                                         nrf_pdm_edge_t *     p_pdm_edge);
348 
349 /**
350  * @brief Function for setting the PDM clock frequency.
351  *
352  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
353  * @param[in] pdm_freq PDM clock frequency.
354  */
355 NRF_STATIC_INLINE void nrf_pdm_clock_set(NRF_PDM_Type * p_reg, nrf_pdm_freq_t pdm_freq);
356 
357 /**
358  * @brief Function for getting the PDM clock frequency.
359  *
360  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
361  *
362  * @return PDM clock frequency.
363  */
364 NRF_STATIC_INLINE nrf_pdm_freq_t nrf_pdm_clock_get(NRF_PDM_Type const * p_reg);
365 
366 /**
367  * @brief Function for setting up the PDM pins.
368  *
369  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
370  * @param[in] psel_clk CLK pin number.
371  * @param[in] psel_din DIN pin number.
372  */
373 NRF_STATIC_INLINE void nrf_pdm_psel_connect(NRF_PDM_Type * p_reg,
374                                             uint32_t       psel_clk,
375                                             uint32_t       psel_din);
376 
377 /**
378  * @brief Function for getting the CLK pin selection.
379  *
380  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
381  *
382  * @return CLK pin selection;
383  */
384 NRF_STATIC_INLINE uint32_t nrf_pdm_clk_pin_get(NRF_PDM_Type const * p_reg);
385 
386 /**
387  * @brief Function for getting the DIN pin selection.
388  *
389  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
390  *
391  * @return DIN pin selection;
392  */
393 NRF_STATIC_INLINE uint32_t nrf_pdm_din_pin_get(NRF_PDM_Type const * p_reg);
394 
395 /**
396  * @brief Function for disconnecting the PDM pins.
397  *
398  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
399  */
400 NRF_STATIC_INLINE void nrf_pdm_psel_disconnect(NRF_PDM_Type * p_reg);
401 
402 /**
403  * @brief Function for setting the PDM gain.
404  *
405  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
406  * @param[in] gain_l Left channel gain.
407  * @param[in] gain_r Right channel gain.
408  */
409 NRF_STATIC_INLINE void nrf_pdm_gain_set(NRF_PDM_Type * p_reg,
410                                         nrf_pdm_gain_t gain_l,
411                                         nrf_pdm_gain_t gain_r);
412 
413 /**
414  * @brief Function for getting the PDM gain.
415  *
416  * @param[in]  p_reg    Pointer to the structure of registers of the peripheral.
417  * @param[out] p_gain_l Left channel gain.
418  * @param[out] p_gain_r Right channel gain.
419  */
420 NRF_STATIC_INLINE void nrf_pdm_gain_get(NRF_PDM_Type const * p_reg,
421                                         nrf_pdm_gain_t *     p_gain_l,
422                                         nrf_pdm_gain_t *     p_gain_r);
423 
424 /**
425  * @brief Function for setting the PDM sample buffer.
426  *
427  * The amount of allocated RAM depends on the operation mode.
428  * - For stereo mode: N 32-bit words.
429  * - For mono mode: Ceil(N/2) 32-bit words.
430  *
431  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
432  * @param[in] p_buffer Pointer to the RAM address where samples are to be written with EasyDMA.
433  * @param[in] num      Number of samples to allocate memory for in EasyDMA mode.
434  */
435 NRF_STATIC_INLINE void nrf_pdm_buffer_set(NRF_PDM_Type * p_reg, uint32_t * p_buffer, uint32_t num);
436 
437 /**
438  * @brief Function for getting the current PDM sample buffer address.
439  *
440  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
441  *
442  * @return Pointer to the current sample buffer.
443  */
444 NRF_STATIC_INLINE uint32_t * nrf_pdm_buffer_get(NRF_PDM_Type const * p_reg);
445 
446 #if NRF_PDM_HAS_RATIO_CONFIG
447 /**
448  * @brief Function for setting ratio between PDM_CLK and output sample rate.
449  *
450  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
451  * @param[in] ratio Ratio between PDM_CLK and output sample rate.
452  */
453 NRF_STATIC_INLINE void nrf_pdm_ratio_set(NRF_PDM_Type * p_reg, nrf_pdm_ratio_t ratio);
454 #endif
455 
456 #if NRF_PDM_HAS_MCLKCONFIG
457 /**
458  * @brief Function for configuring PDM master clock source.
459  *
460  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
461  * @param[in] mclksrc Master Clock source selection.
462  */
463 NRF_STATIC_INLINE void nrf_pdm_mclksrc_configure(NRF_PDM_Type * p_reg, nrf_pdm_mclksrc_t mclksrc);
464 #endif
465 
466 #ifndef NRF_DECLARE_ONLY
nrf_pdm_task_trigger(NRF_PDM_Type * p_reg,nrf_pdm_task_t task)467 NRF_STATIC_INLINE void nrf_pdm_task_trigger(NRF_PDM_Type * p_reg, nrf_pdm_task_t task)
468 {
469     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
470 }
471 
nrf_pdm_task_address_get(NRF_PDM_Type const * p_reg,nrf_pdm_task_t task)472 NRF_STATIC_INLINE uint32_t nrf_pdm_task_address_get(NRF_PDM_Type const * p_reg, nrf_pdm_task_t task)
473 {
474     return nrf_task_event_address_get(p_reg, task);
475 }
476 
nrf_pdm_event_check(NRF_PDM_Type const * p_reg,nrf_pdm_event_t event)477 NRF_STATIC_INLINE bool nrf_pdm_event_check(NRF_PDM_Type const * p_reg, nrf_pdm_event_t event)
478 {
479     return nrf_event_check(p_reg, event);
480 }
481 
nrf_pdm_event_clear(NRF_PDM_Type * p_reg,nrf_pdm_event_t event)482 NRF_STATIC_INLINE void nrf_pdm_event_clear(NRF_PDM_Type * p_reg, nrf_pdm_event_t event)
483 {
484     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
485     nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
486 }
487 
nrf_pdm_event_address_get(NRF_PDM_Type const * p_reg,nrf_pdm_event_t event)488 NRF_STATIC_INLINE uint32_t nrf_pdm_event_address_get(NRF_PDM_Type const * p_reg,
489                                                      nrf_pdm_event_t      event)
490 {
491     return nrf_task_event_address_get(p_reg, event);
492 }
493 
nrf_pdm_int_enable(NRF_PDM_Type * p_reg,uint32_t mask)494 NRF_STATIC_INLINE void nrf_pdm_int_enable(NRF_PDM_Type * p_reg, uint32_t mask)
495 {
496     p_reg->INTENSET = mask;
497 }
498 
nrf_pdm_int_enable_check(NRF_PDM_Type const * p_reg,uint32_t mask)499 NRF_STATIC_INLINE uint32_t nrf_pdm_int_enable_check(NRF_PDM_Type const * p_reg, uint32_t mask)
500 {
501     return p_reg->INTENSET & mask;
502 }
503 
nrf_pdm_int_disable(NRF_PDM_Type * p_reg,uint32_t mask)504 NRF_STATIC_INLINE void nrf_pdm_int_disable(NRF_PDM_Type * p_reg, uint32_t mask)
505 {
506     p_reg->INTENCLR = mask;
507 }
508 
509 #if defined(DPPI_PRESENT)
nrf_pdm_subscribe_set(NRF_PDM_Type * p_reg,nrf_pdm_task_t task,uint8_t channel)510 NRF_STATIC_INLINE void nrf_pdm_subscribe_set(NRF_PDM_Type * p_reg,
511                                              nrf_pdm_task_t task,
512                                              uint8_t        channel)
513 {
514     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
515             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
516 }
517 
nrf_pdm_subscribe_clear(NRF_PDM_Type * p_reg,nrf_pdm_task_t task)518 NRF_STATIC_INLINE void nrf_pdm_subscribe_clear(NRF_PDM_Type * p_reg, nrf_pdm_task_t task)
519 {
520     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
521 }
522 
nrf_pdm_publish_set(NRF_PDM_Type * p_reg,nrf_pdm_event_t event,uint8_t channel)523 NRF_STATIC_INLINE void nrf_pdm_publish_set(NRF_PDM_Type *  p_reg,
524                                            nrf_pdm_event_t event,
525                                            uint8_t         channel)
526 {
527     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
528             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
529 }
530 
nrf_pdm_publish_clear(NRF_PDM_Type * p_reg,nrf_pdm_event_t event)531 NRF_STATIC_INLINE void nrf_pdm_publish_clear(NRF_PDM_Type * p_reg, nrf_pdm_event_t event)
532 {
533     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
534 }
535 #endif // defined(DPPI_PRESENT)
536 
nrf_pdm_enable(NRF_PDM_Type * p_reg)537 NRF_STATIC_INLINE void nrf_pdm_enable(NRF_PDM_Type * p_reg)
538 {
539     p_reg->ENABLE = (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos);
540 }
541 
nrf_pdm_disable(NRF_PDM_Type * p_reg)542 NRF_STATIC_INLINE void nrf_pdm_disable(NRF_PDM_Type * p_reg)
543 {
544     p_reg->ENABLE = (PDM_ENABLE_ENABLE_Disabled << PDM_ENABLE_ENABLE_Pos);
545 }
546 
nrf_pdm_enable_check(NRF_PDM_Type const * p_reg)547 NRF_STATIC_INLINE bool nrf_pdm_enable_check(NRF_PDM_Type const * p_reg)
548 {
549     return (p_reg->ENABLE == (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos));
550 }
551 
nrf_pdm_mode_set(NRF_PDM_Type * p_reg,nrf_pdm_mode_t pdm_mode,nrf_pdm_edge_t pdm_edge)552 NRF_STATIC_INLINE void nrf_pdm_mode_set(NRF_PDM_Type * p_reg,
553                                         nrf_pdm_mode_t pdm_mode,
554                                         nrf_pdm_edge_t pdm_edge)
555 {
556     p_reg->MODE = ((pdm_mode << PDM_MODE_OPERATION_Pos) & PDM_MODE_OPERATION_Msk)
557                     | ((pdm_edge << PDM_MODE_EDGE_Pos) & PDM_MODE_EDGE_Msk);
558 }
559 
nrf_pdm_mode_get(NRF_PDM_Type const * p_reg,nrf_pdm_mode_t * p_pdm_mode,nrf_pdm_edge_t * p_pdm_edge)560 NRF_STATIC_INLINE void nrf_pdm_mode_get(NRF_PDM_Type const * p_reg,
561                                         nrf_pdm_mode_t *     p_pdm_mode,
562                                         nrf_pdm_edge_t *     p_pdm_edge)
563 {
564     uint32_t mode = p_reg->MODE;
565     *p_pdm_mode = (nrf_pdm_mode_t)((mode & PDM_MODE_OPERATION_Msk ) >> PDM_MODE_OPERATION_Pos);
566     *p_pdm_edge = (nrf_pdm_edge_t)((mode & PDM_MODE_EDGE_Msk ) >> PDM_MODE_EDGE_Pos);
567 }
568 
nrf_pdm_clock_set(NRF_PDM_Type * p_reg,nrf_pdm_freq_t pdm_freq)569 NRF_STATIC_INLINE void nrf_pdm_clock_set(NRF_PDM_Type * p_reg, nrf_pdm_freq_t pdm_freq)
570 {
571     p_reg->PDMCLKCTRL = ((pdm_freq << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk);
572 }
573 
nrf_pdm_clock_get(NRF_PDM_Type const * p_reg)574 NRF_STATIC_INLINE nrf_pdm_freq_t nrf_pdm_clock_get(NRF_PDM_Type const * p_reg)
575 {
576      return (nrf_pdm_freq_t) ((p_reg->PDMCLKCTRL << PDM_PDMCLKCTRL_FREQ_Pos) &
577                               PDM_PDMCLKCTRL_FREQ_Msk);
578 }
579 
nrf_pdm_psel_connect(NRF_PDM_Type * p_reg,uint32_t psel_clk,uint32_t psel_din)580 NRF_STATIC_INLINE void nrf_pdm_psel_connect(NRF_PDM_Type * p_reg,
581                                             uint32_t       psel_clk,
582                                             uint32_t       psel_din)
583 {
584     p_reg->PSEL.CLK = psel_clk;
585     p_reg->PSEL.DIN = psel_din;
586 }
587 
nrf_pdm_clk_pin_get(NRF_PDM_Type const * p_reg)588 NRF_STATIC_INLINE uint32_t nrf_pdm_clk_pin_get(NRF_PDM_Type const * p_reg)
589 {
590     return p_reg->PSEL.CLK;
591 }
592 
nrf_pdm_din_pin_get(NRF_PDM_Type const * p_reg)593 NRF_STATIC_INLINE uint32_t nrf_pdm_din_pin_get(NRF_PDM_Type const * p_reg)
594 {
595     return p_reg->PSEL.DIN;
596 }
597 
nrf_pdm_psel_disconnect(NRF_PDM_Type * p_reg)598 NRF_STATIC_INLINE void nrf_pdm_psel_disconnect(NRF_PDM_Type * p_reg)
599 {
600     p_reg->PSEL.CLK = ((PDM_PSEL_CLK_CONNECT_Disconnected << PDM_PSEL_CLK_CONNECT_Pos)
601                          & PDM_PSEL_CLK_CONNECT_Msk);
602     p_reg->PSEL.DIN = ((PDM_PSEL_DIN_CONNECT_Disconnected << PDM_PSEL_DIN_CONNECT_Pos)
603                          & PDM_PSEL_DIN_CONNECT_Msk);
604 }
605 
nrf_pdm_gain_set(NRF_PDM_Type * p_reg,nrf_pdm_gain_t gain_l,nrf_pdm_gain_t gain_r)606 NRF_STATIC_INLINE void nrf_pdm_gain_set(NRF_PDM_Type * p_reg,
607                                         nrf_pdm_gain_t gain_l,
608                                         nrf_pdm_gain_t gain_r)
609 {
610     p_reg->GAINL = gain_l;
611     p_reg->GAINR = gain_r;
612 }
613 
nrf_pdm_gain_get(NRF_PDM_Type const * p_reg,nrf_pdm_gain_t * p_gain_l,nrf_pdm_gain_t * p_gain_r)614 NRF_STATIC_INLINE void nrf_pdm_gain_get(NRF_PDM_Type const * p_reg,
615                                         nrf_pdm_gain_t *     p_gain_l,
616                                         nrf_pdm_gain_t *     p_gain_r)
617 {
618     *p_gain_l = (nrf_pdm_gain_t)p_reg->GAINL;
619     *p_gain_r = (nrf_pdm_gain_t)p_reg->GAINR;
620 }
621 
nrf_pdm_buffer_set(NRF_PDM_Type * p_reg,uint32_t * p_buffer,uint32_t num)622 NRF_STATIC_INLINE void nrf_pdm_buffer_set(NRF_PDM_Type * p_reg, uint32_t * p_buffer, uint32_t num)
623 {
624 #if NRF_PDM_HAS_DMA_REG
625     p_reg->DMA.PTR = (uint32_t)p_buffer;
626     p_reg->DMA.MAXCNT = num;
627 #else
628     p_reg->SAMPLE.PTR = (uint32_t)p_buffer;
629     p_reg->SAMPLE.MAXCNT = num;
630 #endif
631 }
632 
nrf_pdm_buffer_get(NRF_PDM_Type const * p_reg)633 NRF_STATIC_INLINE uint32_t * nrf_pdm_buffer_get(NRF_PDM_Type const * p_reg)
634 {
635 #if NRF_PDM_HAS_DMA_REG
636     return (uint32_t *)p_reg->DMA.PTR;
637 #else
638     return (uint32_t *)p_reg->SAMPLE.PTR;
639 #endif
640 }
641 
642 #if NRF_PDM_HAS_RATIO_CONFIG
nrf_pdm_ratio_set(NRF_PDM_Type * p_reg,nrf_pdm_ratio_t ratio)643 NRF_STATIC_INLINE void nrf_pdm_ratio_set(NRF_PDM_Type * p_reg, nrf_pdm_ratio_t ratio)
644 {
645     p_reg->RATIO = ratio;
646 }
647 #endif
648 
649 #if NRF_PDM_HAS_MCLKCONFIG
nrf_pdm_mclksrc_configure(NRF_PDM_Type * p_reg,nrf_pdm_mclksrc_t mclksrc)650 NRF_STATIC_INLINE void nrf_pdm_mclksrc_configure(NRF_PDM_Type * p_reg, nrf_pdm_mclksrc_t mclksrc)
651 {
652     p_reg->MCLKCONFIG = mclksrc;
653 }
654 #endif
655 
656 #endif // NRF_DECLARE_ONLY
657 /** @} */
658 
659 #ifdef __cplusplus
660 }
661 #endif
662 
663 #endif // NRF_PDM_H_
664