1 /*
2 * Copyright (c) 2022 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_SDM_DRV_H
9 #define HPM_SDM_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_sdm_regs.h"
13
14 /* defined channel mask macro */
15 #define SAMPLING_MODE_MASK (0x7U)
16 #define CHN_SAMPLING_MODE_SHIFT(ch) ((ch) * 3U + SDM_CTRL_CHMD_SHIFT)
17 #define CHN_SAMPLING_MODE_MASK(ch) (SAMPLING_MODE_MASK << CHN_SAMPLING_MODE_SHIFT(ch))
18
19 #define CH0_EN_MASK (0x1U << SDM_CTRL_CH_EN_SHIFT)
20 #define CHN_EN_MASK(ch) (CH0_EN_MASK << (ch))
21
22 #define CHN_ERR_MASK(ch) (SDM_INT_EN_CH0ERR_MASK << (ch))
23 #define CHN_DRY_MASK(ch) (SDM_INT_EN_CH0DRY_MASK << (ch))
24
25 typedef enum {
26 sdm_sampling_rising_clk_edge = 0,
27 sdm_sampling_every_clk_edge = 1,
28 sdm_sampling_manchester_mode = 2,
29 sdm_sampling_falling_clk_edge = 3,
30 sdm_sampling_rising_two_clk_edge = 4,
31 sdm_sampling_falling_two_clk_edge = 5
32 } sdm_sampling_mode_t;
33
34 typedef enum {
35 sdm_filter_sinc1 = 0,
36 sdm_filter_sinc2 = 1,
37 sdm_filter_sinc3 = 2,
38 sdm_filter_fast_sinc2 = 3
39 } sdm_filter_type_t;
40
41 typedef struct {
42 uint8_t clk_signal_sync; /* clk sync for channel */
43 uint8_t data_signal_sync; /* data sync for channel */
44 bool interrupt_en;
45 } sdm_control_t;
46
47 typedef struct {
48 uint8_t sampling_mode;
49 bool enable_err_interrupt;
50 bool enable_data_ready_interrupt;
51 } sdm_channel_common_config_t;
52
53 typedef struct {
54 uint16_t high_threshold;
55 uint16_t zero_cross_threshold;
56 uint16_t low_threshold;
57
58 bool en_zero_cross_threshold_int;
59 bool en_clock_invalid_int;
60 bool en_high_threshold_int;
61 bool en_low_threshold_int;
62 uint8_t filter_type; /**< sdm_filter_type_t */
63 uint8_t oversampling_rate; /**< 1 - 32 */
64 uint8_t ignore_invalid_samples;
65 bool enable;
66 } sdm_comparator_config_t;
67
68 typedef struct {
69 uint8_t fifo_threshold;
70 bool en_fifo_threshold_int;
71 uint8_t manchester_threshold :8;
72 uint8_t wdg_threshold :8;
73 uint8_t en_af_int :1;
74 uint8_t en_data_overflow_int :1;
75 uint8_t en_cic_data_saturation_int :1;
76 uint8_t en_data_ready_int :1;
77 uint8_t sync_source :6;
78 uint8_t fifo_clean_on_sync :1; /**< fifo clean by hardware when fifo interrupt occurred */
79 uint8_t wtsynaclr :1;
80 uint8_t wtsynmclr :1;
81 uint8_t wtsyncen :1;
82 uint8_t output_32bit :1;
83 uint8_t data_ready_flag_by_fifo :1;
84 uint8_t enable :1;
85
86 uint8_t filter_type; /**< sdm_filter_type_t */
87 bool pwm_signal_sync;
88 uint8_t output_offset; /**< 16bit mode need configure this */
89 uint16_t oversampling_rate; /**< 1-256 */
90 uint8_t ignore_invalid_samples;
91 } sdm_filter_config_t;
92
93 typedef struct {
94 uint32_t count;
95 uint8_t *buff;
96 uint8_t data_len_in_bytes; /* 16bit-2 32bit-4 */
97 bool using_fifo;
98 } sdm_output_config_t;
99
100 typedef enum {
101 sdm_comparator_no_event = 0,
102 sdm_comparator_event_out_high_threshold = SDM_CH_SCST_CMPH_MASK,
103 sdm_comparator_event_out_low_threshold = SDM_CH_SCST_CMPL_MASK,
104 sdm_comparator_event_hz = SDM_CH_SCST_HZ_MASK,
105 sdm_comparator_event_invalid_clk = SDM_CH_SCST_MF_MASK
106 } sdm_comparator_event_t;
107
108 typedef enum {
109 sdm_chn0_error_mask = SDM_INT_EN_CH0ERR_MASK,
110 sdm_chn1_error_mask = SDM_INT_EN_CH1ERR_MASK,
111 sdm_chn2_error_mask = SDM_INT_EN_CH2ERR_MASK,
112 sdm_chn3_error_mask = SDM_INT_EN_CH3ERR_MASK,
113 sdm_chn0_data_ready_mask = SDM_INT_EN_CH0DRY_MASK,
114 sdm_chn1_data_ready_mask = SDM_INT_EN_CH1DRY_MASK,
115 sdm_chn2_data_ready_mask = SDM_INT_EN_CH2DRY_MASK,
116 sdm_chn3_data_ready_mask = SDM_INT_EN_CH3DRY_MASK
117 } sdm_channel_int_status_mask_t;
118
119 typedef enum {
120 sdm_chn0_enable_mask = 1U << SDM_CTRL_CH_EN_SHIFT,
121 sdm_chn1_enable_mask = 1U << (SDM_CTRL_CH_EN_SHIFT + 1U),
122 sdm_chn2_enable_mask = 1U << (SDM_CTRL_CH_EN_SHIFT + 2U),
123 sdm_chn3_enable_mask = 1U << (SDM_CTRL_CH_EN_SHIFT + 3U)
124 } sdm_channel_enable_mask_t;
125
126 #ifdef __cplusplus
127 extern "C" {
128 #endif
129
130 /**
131 * @brief sdm enable module interrupt
132 *
133 * @param ptr SDM base address
134 * @param enable true for enable, false for disable
135 */
sdm_enable_module_interrupt(SDM_Type * ptr,bool enable)136 static inline void sdm_enable_module_interrupt(SDM_Type *ptr, bool enable)
137 {
138 if (enable) {
139 ptr->CTRL |= SDM_CTRL_IE_MASK;
140 } else {
141 ptr->CTRL &= ~SDM_CTRL_IE_MASK;
142 }
143 }
144
145 /**
146 * @brief sdm enable channel
147 *
148 * @param ptr SDM base address
149 * @param ch_index channel index
150 * @param enable true for enable, false for disable
151 */
sdm_enable_channel(SDM_Type * ptr,uint8_t ch_index,bool enable)152 static inline void sdm_enable_channel(SDM_Type *ptr, uint8_t ch_index, bool enable)
153 {
154 if (enable) {
155 ptr->CTRL |= CHN_EN_MASK(ch_index);
156 } else {
157 ptr->CTRL &= ~CHN_EN_MASK(ch_index);
158 }
159 }
160
161 /**
162 * @brief sdm enable channel by mask
163 *
164 * @note ch_mask supports bitwise or operation, this API could enable multiple channels at the same time
165 *
166 * @param ptr SDM base address
167 * @param ch_mask sdm_channel_enable_mask_t
168 */
sdm_enable_channel_by_mask(SDM_Type * ptr,uint32_t ch_mask)169 static inline void sdm_enable_channel_by_mask(SDM_Type *ptr, uint32_t ch_mask)
170 {
171 ptr->CTRL = (ptr->CTRL & (~SDM_CTRL_CH_EN_MASK)) | ch_mask;
172 }
173
174 /**
175 * @brief sdm set channel sampling mode
176 *
177 * @param ptr SDM base address
178 * @param ch_index channel index
179 * @param mode sdm_sampling_mode_t
180 */
sdm_set_channel_sampling_mode(SDM_Type * ptr,uint8_t ch_index,sdm_sampling_mode_t mode)181 static inline void sdm_set_channel_sampling_mode(SDM_Type *ptr, uint8_t ch_index, sdm_sampling_mode_t mode)
182 {
183 ptr->CTRL &= ~CHN_SAMPLING_MODE_MASK(ch_index);
184 ptr->CTRL |= mode << (SDM_CTRL_CHMD_SHIFT + ch_index);
185 }
186
187 /**
188 * @brief sdm enable channel interrupt
189 *
190 * @param ptr SDM base address
191 * @param mask sdm_channel_int_status_mask_t, support bitwise or operation
192 */
sdm_enable_channel_interrupt(SDM_Type * ptr,uint32_t mask)193 static inline void sdm_enable_channel_interrupt(SDM_Type *ptr, uint32_t mask)
194 {
195 ptr->INT_EN |= mask;
196 }
197
198 /**
199 * @brief sdm get status register value
200 *
201 * @param ptr SDM base address
202 * @return uint32_t sdm status register value
203 */
sdm_get_status(SDM_Type * ptr)204 static inline uint32_t sdm_get_status(SDM_Type *ptr)
205 {
206 return ptr->STATUS;
207 }
208
209 /**
210 * @brief get channel data ready status
211 *
212 * @param ptr SDM base address
213 * @param ch channel
214 * @return true data ready
215 * @return false not ready
216 */
sdm_get_channel_data_ready_status(SDM_Type * ptr,uint8_t ch)217 static inline bool sdm_get_channel_data_ready_status(SDM_Type *ptr, uint8_t ch)
218 {
219 return (((ptr->STATUS) & CHN_DRY_MASK(ch)) == CHN_DRY_MASK(ch));
220 }
221
222 /**
223 * @brief get channel error status
224 *
225 * @param ptr SDM base address
226 * @param ch channel
227 * @return true error occur
228 * @return false no error
229 */
sdm_get_channel_data_error_status(SDM_Type * ptr,uint8_t ch)230 static inline bool sdm_get_channel_data_error_status(SDM_Type *ptr, uint8_t ch)
231 {
232 return (((ptr->STATUS) & CHN_ERR_MASK(ch)) == CHN_ERR_MASK(ch));
233 }
234
235 /**
236 * @brief sdm set channel's fifo threshold
237 *
238 * @param ptr SDM base address
239 * @param ch channel index
240 * @param threshold threshold value
241 */
sdm_set_ch_fifo_threshold(SDM_Type * ptr,uint8_t ch,uint8_t threshold)242 static inline void sdm_set_ch_fifo_threshold(SDM_Type *ptr, uint8_t ch, uint8_t threshold)
243 {
244 ptr->CH[ch].SDFIFOCTRL = SDM_CH_SDFIFOCTRL_THRSH_SET(threshold);
245 }
246
247 /**
248 * @brief sdm get channel fifo threshold
249 *
250 * @param ptr SDM base address
251 * @param ch channel index
252 * @return uint8_t fifo threshold value
253 */
sdm_get_ch_fifo_threshold(SDM_Type * ptr,uint8_t ch)254 static inline uint8_t sdm_get_ch_fifo_threshold(SDM_Type *ptr, uint8_t ch)
255 {
256 return (uint8_t)(SDM_CH_SDFIFOCTRL_THRSH_GET(ptr->CH[ch].SDFIFOCTRL));
257 }
258
259 /**
260 * @brief sdm get channel filter status
261 *
262 * @param ptr SDM base address
263 * @param ch channel index
264 * @return uint32_t channel filter status register value
265 */
sdm_get_channel_filter_status(SDM_Type * ptr,uint8_t ch)266 static inline uint32_t sdm_get_channel_filter_status(SDM_Type *ptr, uint8_t ch)
267 {
268 return ptr->CH[ch].SDST;
269 }
270
271 /**
272 * @brief sdm get channel data count in fifo
273 *
274 * @param ptr SDM base address
275 * @param ch channel index
276 * @return uint8_t data count
277 */
sdm_get_channel_fifo_data_count(SDM_Type * ptr,uint8_t ch)278 static inline uint8_t sdm_get_channel_fifo_data_count(SDM_Type *ptr, uint8_t ch)
279 {
280 return (uint8_t)(SDM_CH_SDST_FILL_GET(ptr->CH[ch].SDST));
281 }
282
283 /**
284 * @brief sdm get channel filter output data in fifo
285 *
286 * @param ptr SDM base address
287 * @param ch channel index
288 * @return int32_t data
289 */
sdm_get_channel_fifo_data(SDM_Type * ptr,uint8_t ch)290 static inline int32_t sdm_get_channel_fifo_data(SDM_Type *ptr, uint8_t ch)
291 {
292 return ptr->CH[ch].SDFIFO;
293 }
294
295 /**
296 * @brief sdm get channel input clock cycle count
297 *
298 * @param ptr SDM base address
299 * @param ch channel index
300 * @return uint8_t clock cycle count
301 */
sdm_get_channel_clock_cycle_count(SDM_Type * ptr,uint8_t ch)302 static inline uint8_t sdm_get_channel_clock_cycle_count(SDM_Type *ptr, uint8_t ch)
303 {
304 return (uint8_t)(SDM_CH_SDST_PERIOD_MCLK_GET(ptr->CH[ch].SDST));
305 }
306
307 /**
308 * @brief sdm get channel comparator data
309 *
310 * @param ptr SDM base address
311 * @param ch channel index
312 * @return uint16_t comparator data
313 */
sdm_get_channel_comparator_data(SDM_Type * ptr,uint8_t ch)314 static inline uint16_t sdm_get_channel_comparator_data(SDM_Type *ptr, uint8_t ch)
315 {
316 return (uint16_t)(ptr->CH[ch].SCAMP);
317 }
318
319 /**
320 * @brief sdm set channel comparator high threshold
321 *
322 * @param ptr SDM base address
323 * @param ch channel index
324 * @param value high threshold value
325 */
sdm_set_channel_comparator_high_threshold(SDM_Type * ptr,uint8_t ch,uint16_t value)326 static inline void sdm_set_channel_comparator_high_threshold(SDM_Type *ptr, uint8_t ch, uint16_t value)
327 {
328 ptr->CH[ch].SCHTL = value;
329 }
330
331 /**
332 * @brief sdm set channel comparator zero crossing threshold
333 *
334 * @param ptr SDM base address
335 * @param ch channel index
336 * @param value zero crossing threshold value
337 */
sdm_set_channel_comparator_zero_crossing_threshold(SDM_Type * ptr,uint8_t ch,uint16_t value)338 static inline void sdm_set_channel_comparator_zero_crossing_threshold(SDM_Type *ptr, uint8_t ch, uint16_t value)
339 {
340 ptr->CH[ch].SCHTLZ = value;
341 }
342
343 /**
344 * @brief sdm set channel comparator low threshold
345 *
346 * @param ptr SDM base address
347 * @param ch channel index
348 * @param value low threshold value
349 */
sdm_set_channel_comparator_low_threshold(SDM_Type * ptr,uint8_t ch,uint16_t value)350 static inline void sdm_set_channel_comparator_low_threshold(SDM_Type *ptr, uint8_t ch, uint16_t value)
351 {
352 ptr->CH[ch].SCLLT = value;
353 }
354
355 /**
356 * @brief sdm get channel comparator status register value
357 *
358 * @param ptr SDM base address
359 * @param ch channel index
360 * @return uint32_t channel comparator status register value
361 */
sdm_get_channel_comparator_status(SDM_Type * ptr,uint8_t ch)362 static inline uint32_t sdm_get_channel_comparator_status(SDM_Type *ptr, uint8_t ch)
363 {
364 return ptr->CH[ch].SCST;
365 }
366
367 /**
368 * @brief sdm get default module control
369 *
370 * @param ptr SDM base address
371 * @param control sdm_control_t
372 */
373 void sdm_get_default_module_control(SDM_Type *ptr, sdm_control_t *control);
374
375 /**
376 * @brief sdm init module
377 *
378 * @param ptr SDM base address
379 * @param control sdm_control_t
380 */
381 void sdm_init_module(SDM_Type *ptr, sdm_control_t *control);
382
383 /**
384 * @brief sdm get channel common setting
385 *
386 * @param ptr SDM base address
387 * @param config sdm_channel_common_config_t
388 */
389 void sdm_get_channel_common_setting(SDM_Type *ptr, sdm_channel_common_config_t *config);
390
391 /**
392 * @brief sdm config channel's common setting
393 *
394 * @param ptr SDM base address
395 * @param ch_index channel index
396 * @param config sdm_channel_common_config_t
397 */
398 void sdm_config_channel_common_setting(SDM_Type *ptr, uint8_t ch_index, sdm_channel_common_config_t *config);
399
400 /**
401 * @brief sdm get channel default filter config
402 *
403 * @param ptr SDM base address
404 * @param filter_config sdm_filter_config_t
405 */
406 void sdm_get_channel_default_filter_config(SDM_Type *ptr, sdm_filter_config_t *filter_config);
407
408 /**
409 * @brief sdm config channel filter
410 *
411 * @param ptr SDM base address
412 * @param ch_index channel index
413 * @param filter_config sdm_filter_config_t
414 */
415 void sdm_config_channel_filter(SDM_Type *ptr, uint8_t ch_index, sdm_filter_config_t *filter_config);
416
417 /**
418 * @brief sdm get channel default comparator config
419 *
420 * @param ptr SDM base address
421 * @param cmp_config sdm_comparator_config_t
422 */
423 void sdm_get_channel_default_comparator_config(SDM_Type *ptr, sdm_comparator_config_t *cmp_config);
424
425 /**
426 * @brief sdm config channel comparator
427 *
428 * @param ptr SDM base address
429 * @param ch_index channel index
430 * @param cmp_config sdm_comparator_config_t
431 */
432 void sdm_config_channel_comparator(SDM_Type *ptr, uint8_t ch_index, sdm_comparator_config_t *cmp_config);
433
434 /**
435 * @brief sdm receive one filter data
436 *
437 * @param ptr SDM base address
438 * @param ch_index channel index
439 * @param using_fifo true for getting data from fifo, false for getting data from register
440 * @param data data buff
441 * @param data_len_in_bytes output data len in bytes
442 * @retval hpm_stat_t status_success only if it succeeds
443 */
444 hpm_stat_t sdm_receive_one_filter_data(SDM_Type *ptr, uint8_t ch_index, bool using_fifo, int8_t *data, uint8_t data_len_in_bytes);
445
446 /**
447 * @brief sdm receive filter data
448 *
449 * @param ptr SDM base address
450 * @param ch_index channel index
451 * @param using_fifo true for getting data from fifo, false for getting data from register
452 * @param data data buff
453 * @param count data count
454 * @param data_len_in_bytes output data len in bytes
455 * @retval hpm_stat_t status_success only if it succeeds
456 */
457 hpm_stat_t sdm_receive_filter_data(SDM_Type *ptr, uint8_t ch_index, bool using_fifo, int8_t *data, uint32_t count, uint8_t data_len_in_bytes);
458
459 /**
460 * @}
461 */
462
463 #ifdef __cplusplus
464 }
465 #endif
466
467 #endif /* HPM_SDM_DRV_H */
468
469