• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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