1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8
9 #ifndef HPM_DAO_DRV_H
10 #define HPM_DAO_DRV_H
11
12 #include "hpm_common.h"
13 #include "hpm_dao_regs.h"
14 #include "hpm_i2s_common.h"
15 #include "hpm_soc_feature.h"
16
17 /**
18 * @brief DAO driver APIs
19 * @defgroup dao_interface DAO driver APIs
20 * @ingroup io_interfaces
21 * @{
22 */
23
24 /**
25 * @brief DAO channel selection
26 */
27 #define DAO_CHANNEL_LEFT_ONLY DAO_CTRL_LEFT_EN_MASK
28 #define DAO_CHANNEL_RIGHT_ONLY DAO_CTRL_RIGHT_EN_MASK
29 #define DAO_CHANNEL_BOTH \
30 (DAO_CTRL_RIGHT_EN_MASK | DAO_CTRL_LEFT_EN_MASK)
31
32 /**
33 * @brief DAO default output
34 */
35 #define DAO_DEFAULT_OUTPUT_ALL_LOW (0U)
36 #define DAO_DEFAULT_OUTPUT_ALL_HIGH (1U)
37 #define DAO_DEFAULT_OUTPUT_P_HIGH_N_LOW (2U)
38 #define DAO_DEFAULT_OUTPUT_DISABLED (3U)
39
40 /**
41 * @brief DAO config
42 */
43 typedef struct dao_config {
44 bool enable_mono_output;
45 uint8_t default_output_level;
46 uint8_t channel_count;
47 #if defined(DAO_SOC_SUPPORT_DATA_FORMAT_CONFIG) && (DAO_SOC_SUPPORT_DATA_FORMAT_CONFIG == 1)
48 bool enable_tdm_mode;
49 bool frame_start_at_rising_edge;
50 uint8_t protocol;
51 uint8_t channel_length;
52 uint8_t audio_depth;
53 #endif
54 uint8_t channel_slot_mask;
55 } dao_config_t;
56
57 typedef enum {
58 dao_right_channel = DAO_CTRL_RIGHT_EN_MASK,
59 dao_left_channel = DAO_CTRL_LEFT_EN_MASK,
60 } dao_channel_t;
61
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65
66 /**
67 * @brief config high pass filter
68 *
69 * @param [in] ptr DAO base address
70 * @param [in] hpf_coef_ma high pass filter a coefficient's complement
71 * @param [in] hpf_coef_b high pass filter b coefficient
72 * @param [in] enable
73 * @arg true: enable
74 * @arg false: disable
75 */
dao_config_hpf(DAO_Type * ptr,uint32_t hpf_coef_ma,uint32_t hpf_coef_b,bool enable)76 static inline void dao_config_hpf(DAO_Type *ptr,
77 uint32_t hpf_coef_ma,
78 uint32_t hpf_coef_b,
79 bool enable)
80 {
81 ptr->HPF_MA = DAO_HPF_MA_COEF_SET(hpf_coef_ma);
82 ptr->HPF_B = DAO_HPF_B_COEF_SET(hpf_coef_b);
83 ptr->CTRL = (ptr->CTRL & ~DAO_CTRL_HPF_EN_MASK)
84 | (enable ? DAO_CTRL_HPF_EN_MASK : 0);
85 }
86
87 /**
88 * @brief enable high pass filter
89 *
90 * @param [in] ptr DAO base address
91 */
dao_enable_hpf(DAO_Type * ptr)92 static inline void dao_enable_hpf(DAO_Type *ptr)
93 {
94 ptr->CTRL |= DAO_CTRL_HPF_EN_MASK;
95 }
96
97 /**
98 * @brief disable high pass filter
99 *
100 * @param [in] ptr DAO base address
101 */
dao_disable_hpf(DAO_Type * ptr)102 static inline void dao_disable_hpf(DAO_Type *ptr)
103 {
104 ptr->CTRL &= ~DAO_CTRL_HPF_EN_MASK;
105 }
106
107 /**
108 * @brief enable channel
109 *
110 * @param [in] ptr DAO base address
111 * @param [in] ch channel defined in dao_channel_t
112 */
dao_enable_channel(DAO_Type * ptr,uint32_t ch)113 static inline void dao_enable_channel(DAO_Type *ptr, uint32_t ch)
114 {
115 ptr->CTRL |= ch;
116 }
117
118 /**
119 * @brief disable channel
120 *
121 * @param [in] ptr DAO base address
122 * @param [in] ch channel defined in dao_channel_t
123 */
dao_disable_channel(DAO_Type * ptr,uint32_t ch)124 static inline void dao_disable_channel(DAO_Type *ptr, uint32_t ch)
125 {
126 ptr->CTRL &= ~ch;
127 }
128
129 /**
130 * @brief enable mono output
131 *
132 * @param [in] ptr DAO base address
133 */
dao_enable_mono_output(DAO_Type * ptr)134 static inline void dao_enable_mono_output(DAO_Type *ptr)
135 {
136 ptr->CTRL |= DAO_CTRL_MONO_MASK;
137 }
138
139 /**
140 * @brief disable mono output
141 *
142 * @param [in] ptr DAO base address
143 */
dao_disable_mono_output(DAO_Type * ptr)144 static inline void dao_disable_mono_output(DAO_Type *ptr)
145 {
146 ptr->CTRL &= ~DAO_CTRL_MONO_MASK;
147 }
148
149 /**
150 * @brief enable remap
151 *
152 * @param [in] ptr DAO base address
153 */
dao_enable_remap(DAO_Type * ptr)154 static inline void dao_enable_remap(DAO_Type *ptr)
155 {
156 ptr->CTRL |= DAO_CTRL_REMAP_MASK;
157 }
158
159 /**
160 * @brief disable remap
161 *
162 * @param [in] ptr DAO base address
163 */
dao_disable_remap(DAO_Type * ptr)164 static inline void dao_disable_remap(DAO_Type *ptr)
165 {
166 ptr->CTRL &= ~DAO_CTRL_REMAP_MASK;
167 }
168
169 /**
170 * @brief invert output
171 *
172 * @param [in] ptr DAO base address
173 * @param [in] invert
174 * @arg true: invert output
175 * @arg false: not invert output
176 */
dao_invert_output(DAO_Type * ptr,bool invert)177 static inline void dao_invert_output(DAO_Type *ptr, bool invert)
178 {
179 ptr->CTRL = (ptr->CTRL & DAO_CTRL_INVERT_MASK)
180 | DAO_CTRL_INVERT_SET(invert);
181 }
182
183 /**
184 * @brief force pads output with certain level
185 *
186 * @param [in] ptr DAO base address
187 * @param [in] output output level
188 */
dao_force_output(DAO_Type * ptr,uint8_t output)189 static inline void dao_force_output(DAO_Type *ptr, uint8_t output)
190 {
191 ptr->CTRL = (ptr->CTRL & DAO_CTRL_FALSE_LEVEL_MASK)
192 | DAO_CTRL_FALSE_LEVEL_SET(output);
193 }
194
195 /**
196 * @brief enable false run
197 * when false run mode is enabled, the module continues to consume data, no actual output on pads.
198 * @param [in] ptr DAO base address
199 * @param [in] enable
200 * @arg true: enable
201 * @arg false: disable
202 */
dao_enable_false_run(DAO_Type * ptr,bool enable)203 static inline void dao_enable_false_run(DAO_Type *ptr, bool enable)
204 {
205 ptr->CTRL = (ptr->CTRL & DAO_CTRL_FALSE_RUN_MASK)
206 | DAO_CTRL_FALSE_RUN_SET(enable);
207 }
208
209 /**
210 * @brief software reset
211 *
212 * @param [in] ptr DAO base address
213 */
dao_software_reset(DAO_Type * ptr)214 static inline void dao_software_reset(DAO_Type *ptr)
215 {
216 ptr->CMD |= DAO_CMD_SFTRST_MASK;
217 ptr->CMD &= ~DAO_CMD_SFTRST_MASK;
218 }
219
220 /**
221 * @brief check whether DAO is running
222 *
223 * @param [in] ptr DAO base address
224 * @retval true if dao is running
225 */
dao_is_running(DAO_Type * ptr)226 static inline bool dao_is_running(DAO_Type *ptr)
227 {
228 return ptr->CMD & DAO_CMD_RUN_MASK;
229 }
230
231 /**
232 * @brief start
233 *
234 * @param [in] ptr DAO base address
235 */
dao_start(DAO_Type * ptr)236 static inline void dao_start(DAO_Type *ptr)
237 {
238 ptr->CMD |= DAO_CMD_RUN_MASK;
239 }
240
241 /**
242 * @brief stop
243 *
244 * @param [in] ptr DAO base address
245 */
dao_stop(DAO_Type * ptr)246 static inline void dao_stop(DAO_Type *ptr)
247 {
248 ptr->CMD &= ~DAO_CMD_RUN_MASK;
249 }
250
251 /**
252 * @brief initlization
253 *
254 * @param [in] ptr DAO base address
255 * @param [in] config dao_config_t
256 * @retval hpm_stat_t status_invalid_argument or status_success
257 */
258 hpm_stat_t dao_init(DAO_Type *ptr, dao_config_t *config);
259
260 /**
261 * @brief get default config
262 *
263 * @param [in] ptr DAO base address
264 * @param [out] config dao_config_t
265 */
266 void dao_get_default_config(DAO_Type *ptr, dao_config_t *config);
267
268 /**
269 * @}
270 */
271
272 #ifdef __cplusplus
273 }
274 #endif
275
276 #endif /* HPM_DAO_DRV_H */
277