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