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