• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_sdm_drv.h"
9 
10 #ifndef HPM_LIN_DRV_RETRY_COUNT
11 #define HPM_LIN_DRV_RETRY_COUNT (5000U)
12 #endif
13 
14 
sdm_get_default_module_control(SDM_Type * ptr,sdm_control_t * control)15 void sdm_get_default_module_control(SDM_Type *ptr, sdm_control_t *control)
16 {
17     (void) ptr;
18     control->clk_signal_sync = 0xf; /*!< configure clk sync for all channels */
19     control->data_signal_sync = 0xf; /*!< configure data sync for all channels */
20     control->interrupt_en = false;
21 }
22 
sdm_init_module(SDM_Type * ptr,sdm_control_t * control)23 void sdm_init_module(SDM_Type *ptr, sdm_control_t *control)
24 {
25     /* software reset */
26     ptr->CTRL |= SDM_CTRL_SFTRST_MASK;
27     ptr->CTRL &= ~SDM_CTRL_SFTRST_MASK;
28 
29     ptr->CTRL |= SDM_CTRL_SYNC_MCLK_SET(control->clk_signal_sync)
30                 | SDM_CTRL_SYNC_MDAT_SET(control->data_signal_sync)
31                 | SDM_CTRL_IE_SET(control->interrupt_en);
32 }
33 
sdm_get_channel_common_setting(SDM_Type * ptr,sdm_channel_common_config_t * config)34 void sdm_get_channel_common_setting(SDM_Type *ptr, sdm_channel_common_config_t *config)
35 {
36     (void) ptr;
37     config->sampling_mode = sdm_sampling_rising_clk_edge;
38     config->enable_err_interrupt = false;
39     config->enable_data_ready_interrupt = false;
40 }
41 
sdm_config_channel_common_setting(SDM_Type * ptr,uint8_t ch_index,sdm_channel_common_config_t * config)42 void sdm_config_channel_common_setting(SDM_Type *ptr, uint8_t ch_index, sdm_channel_common_config_t *config)
43 {
44     if (config->enable_err_interrupt) {
45         ptr->INT_EN |= CHN_ERR_MASK(ch_index);
46     }
47 
48     if (config->enable_data_ready_interrupt) {
49         ptr->INT_EN |= CHN_DRY_MASK(ch_index);
50     }
51 
52     ptr->CTRL &= ~CHN_SAMPLING_MODE_MASK(ch_index);
53     ptr->CTRL |= config->sampling_mode << CHN_SAMPLING_MODE_SHIFT(ch_index);
54 }
55 
sdm_get_channel_default_filter_config(SDM_Type * ptr,sdm_filter_config_t * filter_config)56 void sdm_get_channel_default_filter_config(SDM_Type *ptr, sdm_filter_config_t *filter_config)
57 {
58     (void) ptr;
59     filter_config->fifo_threshold = 8;
60     filter_config->en_fifo_threshold_int = true;
61     filter_config->manchester_threshold = 0;
62     filter_config->wdg_threshold = 255;
63     filter_config->en_af_int = 0;
64     filter_config->en_data_overflow_int = 1;
65     filter_config->en_cic_data_saturation_int = 1;
66     filter_config->en_data_ready_int = 1;
67     filter_config->sync_source = 0;
68     filter_config->fifo_clean_on_sync = 0;
69     filter_config->wtsynaclr = 0;
70     filter_config->wtsynmclr = 0;
71     filter_config->wtsyncen = 0;
72     filter_config->output_32bit = 1;
73     filter_config->data_ready_flag_by_fifo = 1;
74     filter_config->enable = 1;
75 
76     filter_config->filter_type = sdm_filter_sinc1;
77     filter_config->pwm_signal_sync = 0;
78     filter_config->output_offset = 0;
79     filter_config->oversampling_rate = 32; /**< 1- 256 */
80     filter_config->ignore_invalid_samples = 0;
81 }
82 
sdm_get_channel_default_comparator_config(SDM_Type * ptr,sdm_comparator_config_t * cmp_config)83 void sdm_get_channel_default_comparator_config(SDM_Type *ptr, sdm_comparator_config_t *cmp_config)
84 {
85     (void) ptr;
86     cmp_config->high_threshold = 0xffff;
87     cmp_config->zero_cross_threshold = 0xffff;
88     cmp_config->low_threshold = 0x0;
89 
90     cmp_config->en_zero_cross_threshold_int = false;
91     cmp_config->en_clock_invalid_int = false;
92     cmp_config->en_high_threshold_int = false;
93     cmp_config->en_low_threshold_int = false;
94     cmp_config->filter_type = sdm_filter_sinc1;
95     cmp_config->oversampling_rate = 32; /**< 1-32, when 32, write 0 into bitfield */
96     cmp_config->ignore_invalid_samples = 0;
97     cmp_config->enable = true;
98 }
99 
sdm_config_channel_filter(SDM_Type * ptr,uint8_t ch_index,sdm_filter_config_t * filter_config)100 void sdm_config_channel_filter(SDM_Type *ptr, uint8_t ch_index, sdm_filter_config_t *filter_config)
101 {
102     /* fifo setting */
103     ptr->CH[ch_index].SDFIFOCTRL = SDM_CH_SDFIFOCTRL_THRSH_SET(filter_config->fifo_threshold)
104                                 | SDM_CH_SDFIFOCTRL_D_RDY_INT_EN_SET(filter_config->en_fifo_threshold_int);
105 
106     ptr->CH[ch_index].SDCTRLE = SDM_CH_SDCTRLE_SGD_ORDR_SET(filter_config->filter_type)
107                                 | SDM_CH_SDCTRLE_PWMSYNC_SET(filter_config->pwm_signal_sync)
108                                 | SDM_CH_SDCTRLE_CIC_SCL_SET(filter_config->output_offset)
109                                 | SDM_CH_SDCTRLE_CIC_DEC_RATIO_SET(filter_config->oversampling_rate)
110                                 | SDM_CH_SDCTRLE_IGN_INI_SAMPLES_SET(filter_config->ignore_invalid_samples);
111 
112     ptr->CH[ch_index].SDCTRLP = SDM_CH_SDCTRLP_MANCH_THR_SET(filter_config->manchester_threshold)
113                                 | SDM_CH_SDCTRLP_WDOG_THR_SET(filter_config->wdg_threshold)
114                                 | SDM_CH_SDCTRLP_AF_IE_SET(filter_config->en_af_int)
115                                 | SDM_CH_SDCTRLP_DFFOVIE_SET(filter_config->en_data_overflow_int)
116                                 | SDM_CH_SDCTRLP_DSATIE_SET(filter_config->en_cic_data_saturation_int)
117                                 | SDM_CH_SDCTRLP_DRIE_SET(filter_config->en_data_ready_int)
118                                 | SDM_CH_SDCTRLP_SYNCSEL_SET(filter_config->sync_source)
119                                 | SDM_CH_SDCTRLP_FFSYNCCLREN_SET(filter_config->fifo_clean_on_sync)
120                                 | SDM_CH_SDCTRLP_WTSYNACLR_SET(filter_config->wtsynaclr)
121                                 | SDM_CH_SDCTRLP_WTSYNMCLR_SET(filter_config->wtsynmclr)
122                                 | SDM_CH_SDCTRLP_WTSYNCEN_SET(filter_config->wtsyncen)
123                                 | SDM_CH_SDCTRLP_D32_SET(filter_config->output_32bit)
124                                 | SDM_CH_SDCTRLP_DR_OPT_SET(filter_config->data_ready_flag_by_fifo);
125 
126     ptr->CH[ch_index].SDCTRLP |= SDM_CH_SDCTRLP_EN_SET(filter_config->enable);
127 }
128 
sdm_config_channel_comparator(SDM_Type * ptr,uint8_t ch_index,sdm_comparator_config_t * cmp_config)129 void sdm_config_channel_comparator(SDM_Type *ptr,  uint8_t ch_index, sdm_comparator_config_t *cmp_config)
130 {
131     ptr->CH[ch_index].SCHTL = cmp_config->high_threshold;
132     ptr->CH[ch_index].SCLLT = cmp_config->low_threshold;
133     ptr->CH[ch_index].SCHTLZ = cmp_config->zero_cross_threshold;
134 
135     ptr->CH[ch_index].SCCTRL = SDM_CH_SCCTRL_HZ_EN_SET(cmp_config->en_zero_cross_threshold_int)
136                                 | SDM_CH_SCCTRL_MF_IE_SET(cmp_config->en_clock_invalid_int)
137                                 | SDM_CH_SCCTRL_HL_IE_SET(cmp_config->en_high_threshold_int)
138                                 | SDM_CH_SCCTRL_LL_IE_SET(cmp_config->en_low_threshold_int)
139                                 | SDM_CH_SCCTRL_SGD_ORDR_SET(cmp_config->filter_type)
140                                 | SDM_CH_SCCTRL_CIC_DEC_RATIO_SET(cmp_config->oversampling_rate)
141                                 | SDM_CH_SCCTRL_IGN_INI_SAMPLES_SET(cmp_config->ignore_invalid_samples);
142 
143     ptr->CH[ch_index].SCCTRL |= SDM_CH_SCCTRL_EN_SET(cmp_config->enable);
144 }
145 
sdm_receive_one_filter_data(SDM_Type * ptr,uint8_t ch_index,bool using_fifo,int8_t * data,uint8_t data_len_in_bytes)146 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)
147 {
148     uint32_t retry = 0;
149     int32_t output;
150 
151     while (!sdm_get_channel_data_ready_status(ptr, ch_index)) {
152         if (retry > HPM_LIN_DRV_RETRY_COUNT) {
153             break;
154         }
155         retry++;
156     }
157 
158     if (retry > HPM_LIN_DRV_RETRY_COUNT) {
159         return status_timeout;
160     }
161 
162     if (using_fifo) {
163         output = ptr->CH[ch_index].SDFIFO;
164     } else {
165         output = ptr->CH[ch_index].SDATA;
166     }
167 
168     for (uint8_t i = 0; i < data_len_in_bytes; i++) {
169         *(data++) = (int8_t)(output >> (i * 8));
170     }
171 
172     return status_success;
173 }
174 
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)175 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)
176 {
177     for (uint32_t i = 0; i < count; i++) {
178         if (status_success != sdm_receive_one_filter_data(ptr, ch_index, using_fifo, data, data_len_in_bytes)) {
179             return status_fail;
180         }
181 
182         for (uint8_t i = 0; i < data_len_in_bytes; i++) {
183             data++;
184         }
185     }
186     return status_success;
187 }
188 
189