1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7 #include "hpm_mcl_analog.h"
8
hpm_mcl_analog_init(mcl_analog_t * analog,mcl_analog_cfg_t * cfg,mcl_cfg_t * mcl_cfg)9 hpm_mcl_stat_t hpm_mcl_analog_init(mcl_analog_t *analog, mcl_analog_cfg_t *cfg, mcl_cfg_t *mcl_cfg)
10 {
11 uint8_t current_num = 0;
12
13 analog->status = analog_status_init;
14 MCL_ASSERT(analog != NULL, mcl_invalid_pointer);
15 analog->status = analog_status_null;
16 MCL_ASSERT(cfg != NULL, mcl_invalid_pointer);
17 MCL_ASSERT(mcl_cfg != NULL, mcl_invalid_pointer);
18 MCL_ASSERT(cfg->callback.get_value != NULL, mcl_invalid_pointer);
19 MCL_ASSERT(cfg->callback.init != NULL, mcl_invalid_pointer);
20 MCL_ASSERT(cfg->callback.update_sample_location != NULL, mcl_invalid_pointer);
21 MCL_ASSERT(((cfg->enable_process_by_user == false) || (cfg->callback.process_by_user != NULL)), mcl_invalid_pointer);
22 analog->cfg = cfg;
23 analog->board_parameter = &mcl_cfg->physical.board.analog[0];
24 analog->num_current_sample_res = &mcl_cfg->physical.board.num_current_sample_res;
25 MCL_ASSERT(cfg->callback.init() == mcl_success, mcl_analog_init_error);
26 if (analog->cfg->enable_a_current) {
27 current_num++;
28 MCL_ASSERT(cfg->callback.update_sample_location(analog_a_current, 0) == mcl_success, mcl_analog_update_location_error);
29 }
30 if (analog->cfg->enable_b_current) {
31 current_num++;
32 MCL_ASSERT(cfg->callback.update_sample_location(analog_b_current, 0) == mcl_success, mcl_analog_update_location_error);
33 }
34 if (analog->cfg->enable_c_current) {
35 current_num++;
36 MCL_ASSERT(cfg->callback.update_sample_location(analog_c_current, 0) == mcl_success, mcl_analog_update_location_error);
37 }
38 if (analog->cfg->enable_a_voltage) {
39 MCL_ASSERT(cfg->callback.update_sample_location(analog_a_voltage, 0) == mcl_success, mcl_analog_update_location_error);
40 }
41 if (analog->cfg->enable_b_voltage) {
42 MCL_ASSERT(cfg->callback.update_sample_location(analog_b_voltage, 0) == mcl_success, mcl_analog_update_location_error);
43 }
44 if (analog->cfg->enable_c_voltage) {
45 MCL_ASSERT(cfg->callback.update_sample_location(analog_c_voltage, 0) == mcl_success, mcl_analog_update_location_error);
46 }
47 if (analog->cfg->enable_vbus) {
48 MCL_ASSERT(cfg->callback.update_sample_location(analog_vbus, 0) == mcl_success, mcl_analog_update_location_error);
49 }
50
51 MCL_ASSERT(*analog->num_current_sample_res == current_num, mcl_invalid_argument);
52 /**
53 * @brief @todo only two res sample
54 *
55 */
56 MCL_ASSERT(*analog->num_current_sample_res == 2, mcl_in_development);
57
58 analog->status = analog_status_run;
59
60 return mcl_success;
61 }
62
hpm_mcl_analog_get_value(mcl_analog_t * analog,mcl_analog_chn_t chn,float * value)63 hpm_mcl_stat_t hpm_mcl_analog_get_value(mcl_analog_t *analog, mcl_analog_chn_t chn, float *value)
64 {
65 int32_t adc_val;
66 float val0;
67
68 MCL_ASSERT_OPT(analog != NULL, mcl_invalid_pointer);
69 MCL_ASSERT_OPT(value != NULL, mcl_invalid_pointer);
70 MCL_ASSERT(analog->status == analog_status_run, mcl_analog_not_ready);
71 MCL_ASSERT_EXEC_CODE_AND_RETURN(analog->cfg->callback.get_value(chn, &adc_val) == mcl_success,
72 analog->status = analog_status_fail, mcl_analog_get_value_error);
73 if (analog->cfg->enable_process_by_user) {
74 MCL_ASSERT(analog->cfg->callback.process_by_user(chn, adc_val, &val0) == mcl_success, mcl_fail);
75 } else {
76 val0 = adc_val;
77 val0 = (val0 * analog->board_parameter[chn].adc_reference_vol / analog->board_parameter[chn].sample_precision) /
78 analog->board_parameter[chn].opamp_gain / analog->board_parameter[chn].sample_res;
79 if (analog->cfg->enable_filter[chn]) {
80 val0 = hpm_mcl_filter_iir_df1(analog->iir[chn], val0);
81 }
82 }
83 *value = val0;
84
85 return mcl_success;
86 }
87
hpm_mcl_analog_iir_filter_init(mcl_analog_t * analog,mcl_analog_chn_t chn,mcl_filter_iir_df1_t * iir)88 hpm_mcl_stat_t hpm_mcl_analog_iir_filter_init(mcl_analog_t *analog, mcl_analog_chn_t chn, mcl_filter_iir_df1_t *iir)
89 {
90 MCL_ASSERT(analog != NULL, mcl_invalid_pointer);
91 MCL_ASSERT(iir != NULL, mcl_invalid_pointer);
92 analog->iir[chn] = iir;
93 analog->cfg->enable_filter[chn] = true;
94 memset(iir->mem, 0, iir->cfg->section * sizeof(mcl_filter_iir_df1_memory_t));
95
96 return mcl_success;
97 }
98
hpm_mcl_analog_disable_iir_filter(mcl_analog_t * analog,mcl_analog_chn_t chn)99 hpm_mcl_stat_t hpm_mcl_analog_disable_iir_filter(mcl_analog_t *analog, mcl_analog_chn_t chn)
100 {
101 MCL_ASSERT(analog != NULL, mcl_invalid_pointer);
102 analog->cfg->enable_filter[chn] = false;
103 memset(analog->iir[chn]->mem, 0, analog->iir[chn]->cfg->section * sizeof(mcl_filter_iir_df1_memory_t));
104
105 return mcl_success;
106 }
107
hpm_mcl_analog_step_convert(mcl_analog_t * analog,float value,mcl_analog_chn_t chn,float angle,float * output)108 hpm_mcl_stat_t hpm_mcl_analog_step_convert(mcl_analog_t *analog, float value, mcl_analog_chn_t chn, float angle, float *output)
109 {
110 (void)analog;
111 MCL_ASSERT_OPT(output != NULL, mcl_invalid_pointer);
112 switch (chn) {
113 case analog_a_current:
114 if ((angle >= (0.75 * MCL_PI)) && (angle <= (1.75 * MCL_PI))) {
115 *output = -value;
116 } else {
117 *output = value;
118 }
119 break;
120 case analog_b_current:
121 if ((angle <= (0.25 * MCL_PI)) || (angle >= (1.25 * MCL_PI))) {
122 *output = -value;
123 } else {
124 *output = value;
125 }
126 break;
127 default:
128 return mcl_invalid_argument;
129 }
130 return mcl_success;
131 }
132