1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_PDM_DRV_H
9 #define HPM_PDM_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_pdm_regs.h"
13
14 /**
15 * @brief PDM driver APIs
16 * @defgroup pdm_interface PDM driver APIs
17 * @ingroup io_interfaces
18 * @{
19 */
20
21 /**
22 * @brief PDM event
23 */
24 #define PDM_EVENT_FILT_CRX_ERROR (PDM_ST_FILT_CRX_ERR_MASK)
25 #define PDM_EVENT_OFIFO_OVERFLOW_ERROR (PDM_ST_OFIFO_OVFL_ERR_MASK)
26 #define PDM_EVENT_CIC_OVERLOAD_ERROR (PDM_ST_CIC_OVLD_ERR_MASK)
27 #define PDM_EVENT_CIC_SAT_ERROR (PDM_ST_CIC_SAT_ERR_MASK)
28
29 /**
30 * @brief PDM CIC sidma-delta filter order
31 */
32 #define PDM_CIC_SIGMA_DELTA_ORDER_5 (2U)
33 #define PDM_CIC_SIGMA_DELTA_ORDER_6 (1U)
34 #define PDM_CIC_SIGMA_DELTA_ORDER_7 (0U)
35
36 /**
37 * @brief PDM config
38 */
39 typedef struct pdm_config {
40 bool sof_at_ref_clk_falling_edge;
41 bool bypass_pdm_clk_div;
42 bool enable_pdm_clk_out;
43 bool enable_hpf;
44 uint8_t pdm_clk_div;
45 uint8_t capture_delay;
46 uint8_t dec_after_cic;
47 uint8_t post_scale;
48 uint8_t sigma_delta_order;
49 uint8_t cic_dec_ratio;
50 } pdm_config_t;
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56 /**
57 * @brief config high pass filter
58 *
59 * @param [in] ptr PDM base address
60 * @param [in] hpf_coef_ma high pass filter a coefficient's complement
61 * @param [in] hpf_coef_b high pass filter b coefficient
62 */
pdm_config_hpf(PDM_Type * ptr,uint32_t hpf_coef_ma,uint32_t hpf_coef_b)63 static inline void pdm_config_hpf(PDM_Type *ptr,
64 uint32_t hpf_coef_ma,
65 uint32_t hpf_coef_b)
66 {
67 ptr->HPF_MA = PDM_HPF_MA_COEF_SET(hpf_coef_ma);
68 ptr->HPF_B = PDM_HPF_B_COEF_SET(hpf_coef_b);
69 }
70
71 /**
72 * @brief enable high pass filter
73 *
74 * @param [in] ptr PDM base address
75 */
pdm_enable_hpf(PDM_Type * ptr)76 static inline void pdm_enable_hpf(PDM_Type *ptr)
77 {
78 ptr->CTRL |= PDM_CTRL_HPF_EN_MASK;
79 }
80
81 /**
82 * @brief disable high pass filter
83 *
84 * @param [in] ptr PDM base address
85 */
pdm_disable_hpf(PDM_Type * ptr)86 static inline void pdm_disable_hpf(PDM_Type *ptr)
87 {
88 ptr->CTRL &= ~PDM_CTRL_HPF_EN_MASK;
89 }
90
91 /**
92 * @brief check whether PDM is running
93 *
94 * @param [in] ptr PDM base address
95 * @retval true in PDM is running
96 */
pdm_is_running(PDM_Type * ptr)97 static inline bool pdm_is_running(PDM_Type *ptr)
98 {
99 return ptr->RUN & PDM_RUN_PDM_EN_MASK;
100 }
101
102 /**
103 * @brief stop pdm
104 *
105 * @param [in] ptr PDM base address
106 */
pdm_stop(PDM_Type * ptr)107 static inline void pdm_stop(PDM_Type *ptr)
108 {
109 ptr->RUN &= ~PDM_RUN_PDM_EN_MASK;
110 }
111
112 /**
113 * @brief start pdm
114 *
115 * @param [in] ptr PDM base address
116 */
pdm_start(PDM_Type * ptr)117 static inline void pdm_start(PDM_Type *ptr)
118 {
119 ptr->RUN |= PDM_RUN_PDM_EN_MASK;
120 }
121
122 /**
123 * @brief disable channel
124 *
125 * @param [in] ptr PDM base address
126 * @param [in] channel_disable_mask channel mask
127 */
pdm_disable_channel(PDM_Type * ptr,uint16_t channel_disable_mask)128 static inline void pdm_disable_channel(PDM_Type *ptr,
129 uint16_t channel_disable_mask)
130 {
131 ptr->CH_CTRL &= ~PDM_CH_CTRL_CH_EN_SET(channel_disable_mask);
132 }
133
134 /**
135 * @brief enable channel
136 *
137 * @param [in] ptr PDM base address
138 * @param [in] capture_high_level_mask capture when PDM_CLK is high
139 * @param [in] channel_enable_mask channel mask
140 */
pdm_enable_channel(PDM_Type * ptr,uint16_t capture_high_level_mask,uint16_t channel_enable_mask)141 static inline void pdm_enable_channel(PDM_Type *ptr,
142 uint16_t capture_high_level_mask,
143 uint16_t channel_enable_mask)
144 {
145 ptr->CH_CTRL |= PDM_CH_CTRL_CH_POL_SET(capture_high_level_mask)
146 | PDM_CH_CTRL_CH_EN_SET(channel_enable_mask);
147 }
148
149 /**
150 * @brief disable pdm clock out
151 *
152 * @param [in] ptr PDM base address
153 */
pdm_disable_pdm_clock_out(PDM_Type * ptr)154 static inline void pdm_disable_pdm_clock_out(PDM_Type *ptr)
155 {
156 ptr->CTRL &= ~PDM_CTRL_PDM_CLK_OE_MASK;
157 }
158
159 /**
160 * @brief enable pdm clock out
161 *
162 * @param [in] ptr PDM base address
163 */
pdm_enable_pdm_clock_out(PDM_Type * ptr)164 static inline void pdm_enable_pdm_clock_out(PDM_Type *ptr)
165 {
166 ptr->CTRL |= PDM_CTRL_PDM_CLK_OE_MASK;
167 }
168
169 /**
170 * @brief pdm config cic
171 *
172 * @param [in] ptr PDM base address
173 * @param [in] sigma_delta_order sidma-delta filter order
174 * @param [in] div Rate of down sampling
175 * @param [in] post_scale output value post scale
176 */
pdm_config_cic(PDM_Type * ptr,uint8_t sigma_delta_order,uint8_t div,uint8_t post_scale)177 static inline void pdm_config_cic(PDM_Type *ptr,
178 uint8_t sigma_delta_order,
179 uint8_t div,
180 uint8_t post_scale)
181 {
182 ptr->CIC_CFG = PDM_CIC_CFG_POST_SCALE_SET(post_scale)
183 | PDM_CIC_CFG_SGD_SET(sigma_delta_order)
184 | PDM_CIC_CFG_CIC_DEC_RATIO_SET(div);
185 }
186
187 /**
188 * @brief pdm software reset
189 *
190 * @param [in] ptr PDM base address
191 */
pdm_software_reset(PDM_Type * ptr)192 static inline void pdm_software_reset(PDM_Type *ptr)
193 {
194 ptr->CTRL |= PDM_CTRL_SFTRST_MASK;
195 ptr->CTRL &= ~PDM_CTRL_SFTRST_MASK;
196 }
197
198 /**
199 * @brief pdm enable irq
200 *
201 * @param [in] ptr PDM base address
202 * @param [in] mask pdm irq mask in ST register
203 */
pdm_enable_irq(PDM_Type * ptr,uint8_t mask)204 static inline void pdm_enable_irq(PDM_Type *ptr, uint8_t mask)
205 {
206 ptr->CTRL |= mask << (PDM_CTRL_CIC_SAT_ERR_IE_SHIFT - PDM_ST_CIC_SAT_ERR_SHIFT);
207 }
208
209 /**
210 * @brief pdm disable irq
211 *
212 * @param [in] ptr PDM base address
213 * @param [in] mask pdm irq mask in ST register
214 */
pdm_disable_irq(PDM_Type * ptr,uint8_t mask)215 static inline void pdm_disable_irq(PDM_Type *ptr, uint8_t mask)
216 {
217 ptr->CTRL &= ~(mask << (PDM_CTRL_CIC_SAT_ERR_IE_SHIFT - PDM_ST_CIC_SAT_ERR_SHIFT));
218 }
219
220 /**
221 * @brief pdm initialization
222 *
223 * @param [in] ptr PDM base address
224 * @param [in] config pdm_config_t
225 * @retval hpm_stat_t status_invalid_argument or status_success
226 */
227 hpm_stat_t pdm_init(PDM_Type *ptr, pdm_config_t *config);
228
229 /**
230 * @brief pdm get default config
231 *
232 * @param [in] ptr PDM base address
233 * @param [out] config pdm_config_t
234 */
235 void pdm_get_default_config(PDM_Type *ptr, pdm_config_t *config);
236
237 /**
238 * @}
239 */
240
241 #ifdef __cplusplus
242 }
243 #endif
244
245 #endif /* HPM_PDM_DRV_H */
246
247