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