FreeCalypso > hg > fc-magnetite
comparison src/cs/drivers/drv_app/fchg/fchg_process.c @ 331:8166b0afcf8c
FCHG: main ADC process implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 14 Dec 2017 16:22:30 +0000 |
parents | |
children | 8a90038c0173 |
comparison
equal
deleted
inserted
replaced
330:dd3c89e9ca2e | 331:8166b0afcf8c |
---|---|
1 /* | |
2 * In this module we are going to implement the main process functions | |
3 * for FCHG. | |
4 */ | |
5 | |
6 #include "fchg/fchg_env.h" | |
7 #include "fchg/fchg_func_i.h" | |
8 #include "rv/rv_general.h" | |
9 #include "rvf/rvf_api.h" | |
10 #include "rvm/rvm_use_id_list.h" | |
11 #include "abb/abb.h" | |
12 #include <string.h> | |
13 #include <stdio.h> | |
14 | |
15 extern UINT16 madc_vbat_2_physical(UINT16 adc_val); | |
16 | |
17 void pwr_init_discharge(void) | |
18 { | |
19 pwr_ctrl->curr_percent = pwr_ctrl->batt_thresholds[0].remain_capa; | |
20 } | |
21 | |
22 static void handle_discharge(void) | |
23 { | |
24 UINT16 i; | |
25 char trace[64]; | |
26 | |
27 /* first we need to find the current threshold we are at */ | |
28 for (i = 0; i < pwr_ctrl->nb_thresholds; i++) | |
29 if (pwr_ctrl->batt_thresholds[i].remain_capa == | |
30 pwr_ctrl->curr_percent) | |
31 break; | |
32 /* is there one below? */ | |
33 if (++i == pwr_ctrl->nb_thresholds) | |
34 return; | |
35 /* are we crossing it? */ | |
36 if (pwr_ctrl->batt_mv >= pwr_ctrl->batt_thresholds[i].bat_voltage) | |
37 return; | |
38 /* yes, we crossed it - see if we fell even further down */ | |
39 while (i < pwr_ctrl->nb_thresholds && | |
40 pwr_ctrl->batt_mv < pwr_ctrl->batt_thresholds[i].bat_voltage) | |
41 i++; | |
42 /* the last one was it */ | |
43 i--; | |
44 pwr_ctrl->curr_percent = pwr_ctrl->batt_thresholds[i].remain_capa; | |
45 sprintf(trace, "Battery fell through %u%% mark", | |
46 pwr_ctrl->curr_percent); | |
47 rvf_send_trace(trace, strlen(trace), NULL_PARAM, | |
48 RV_TRACE_LEVEL_WARNING, FCHG_USE_ID); | |
49 } | |
50 | |
51 static void charge_progress_trace(char *mode, UINT16 ichg) | |
52 { | |
53 char trace[64]; | |
54 | |
55 sprintf(trace, "%s charging: Vbat=%u Ichg=%u i2v=%u", mode, | |
56 pwr_ctrl->batt_mv, ichg, pwr_ctrl->i2v_offset); | |
57 rvf_send_trace(trace, strlen(trace), NULL_PARAM, | |
58 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
59 } | |
60 | |
61 static void start_i2v_cal(void) | |
62 { | |
63 UINT16 bciconf; | |
64 | |
65 rvf_send_trace("Calibrating i2v offset", 22, NULL_PARAM, | |
66 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
67 pwr_ctrl->state = FCHG_STATE_I2V_CAL_2; | |
68 bciconf = ABB_Read_Register_on_page(PAGE1, BCICONF); | |
69 bciconf &= 0x3E0; | |
70 bciconf |= pwr_ctrl->config.bciconf; | |
71 ABB_Write_Register_on_page(PAGE1, BCICONF, bciconf); | |
72 /* | |
73 * Set the CHDISPA bit and start the zero calibration routine | |
74 * of the I to V converter | |
75 */ | |
76 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0010); | |
77 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0019); | |
78 } | |
79 | |
80 static void start_ci_charging(void) | |
81 { | |
82 rvf_send_trace("Start CI charging", 17, NULL_PARAM, | |
83 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
84 pwr_ctrl->state = FCHG_STATE_CI_CHARGING; | |
85 /* Select constant current charging. The charger is disabled */ | |
86 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0002); | |
87 /* Program the DAC with the constant current value */ | |
88 ABB_Write_Register_on_page(PAGE0, CHGREG, | |
89 pwr_ctrl->config.ci_current + pwr_ctrl->i2v_offset); | |
90 /* Enable the charger */ | |
91 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0003); | |
92 } | |
93 | |
94 static void start_cv_charging(UINT16 code) | |
95 { | |
96 rvf_send_trace("Start CV charging", 17, NULL_PARAM, | |
97 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
98 pwr_ctrl->state = FCHG_STATE_CV_CHARGING; | |
99 /* Select constant voltage charging. The charger is disabled */ | |
100 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
101 /* figure out the DAC code */ | |
102 while (code && | |
103 madc_vbat_2_physical(code) >= pwr_ctrl->config.charge_to_mv) | |
104 code--; | |
105 code++; | |
106 rvf_send_trace("Voltage (DAC code) ", 19, code, | |
107 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
108 /* Program the DAC with the constant voltage value */ | |
109 ABB_Write_Register_on_page(PAGE0, CHGREG, code); | |
110 /* Enable the charger */ | |
111 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0001); | |
112 } | |
113 | |
114 static void start_charge_condition_met(void) | |
115 { | |
116 rvf_send_trace("Charge start condition met", 26, NULL_PARAM, | |
117 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
118 if (pwr_ctrl->config.bciconf) | |
119 start_i2v_cal(); | |
120 else { | |
121 pwr_ctrl->i2v_offset = 0; | |
122 start_ci_charging(); | |
123 } | |
124 } | |
125 | |
126 static int overvoltage_end_charge_check(void) | |
127 { | |
128 if (pwr_ctrl->batt_mv < pwr_ctrl->config.overvoltage) | |
129 return 0; | |
130 rvf_send_trace("Stopping charge by overvoltage condition", 40, | |
131 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); | |
132 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
133 pwr_init_discharge(); | |
134 pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE; | |
135 return 1; | |
136 } | |
137 | |
138 void pwr_process_adc(struct pwr_adc_ind_s *msg) | |
139 { | |
140 pwr_ctrl->batt_mv = madc_vbat_2_physical(msg->data[0]); | |
141 | |
142 switch (pwr_ctrl->state) { | |
143 case FCHG_STATE_NO_EXT_PWR: | |
144 case FCHG_STATE_PWR_PLUG_TIMER: | |
145 case FCHG_STATE_NO_CHARGING: | |
146 handle_discharge(); | |
147 return; | |
148 case FCHG_STATE_READY_TO_CHARGE: | |
149 handle_discharge(); | |
150 if (!(msg->data[9] & CHGPRES)) { | |
151 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
152 return; | |
153 } | |
154 if (pwr_ctrl->batt_mv >= pwr_ctrl->config.start_thresh) | |
155 start_charge_condition_met(); | |
156 return; | |
157 case FCHG_STATE_READY_TO_RECHARGE: | |
158 handle_discharge(); | |
159 if (!(msg->data[9] & CHGPRES)) { | |
160 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
161 return; | |
162 } | |
163 if (pwr_ctrl->batt_mv >= pwr_ctrl->config.restart_thresh) | |
164 start_charge_condition_met(); | |
165 return; | |
166 case FCHG_STATE_I2V_CAL_1: | |
167 if (!(msg->data[9] & CHGPRES)) { | |
168 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
169 return; | |
170 } | |
171 if (pwr_ctrl->config.bciconf) | |
172 start_i2v_cal(); | |
173 else { | |
174 pwr_ctrl->i2v_offset = 0; | |
175 start_ci_charging(); | |
176 } | |
177 return; | |
178 case FCHG_STATE_I2V_CAL_2: | |
179 pwr_ctrl->i2v_offset = msg->data[2]; | |
180 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
181 rvf_send_trace("i2v offset (MADC code) ", 23, | |
182 pwr_ctrl->i2v_offset, | |
183 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); | |
184 if (!(msg->data[9] & CHGPRES)) { | |
185 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
186 return; | |
187 } | |
188 start_ci_charging(); | |
189 return; | |
190 case FCHG_STATE_CI_CHARGING: | |
191 charge_progress_trace("CI", msg->data[2]); | |
192 if (!(msg->data[9] & CHGPRES)) { | |
193 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
194 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
195 return; | |
196 } | |
197 if (overvoltage_end_charge_check()) | |
198 return; | |
199 if (pwr_ctrl->batt_mv >= pwr_ctrl->config.charge_to_mv) | |
200 start_cv_charging(msg->data[0]); | |
201 return; | |
202 case FCHG_STATE_CV_CHARGING: | |
203 charge_progress_trace("CV", msg->data[2]); | |
204 if (!(msg->data[9] & CHGPRES)) { | |
205 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
206 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; | |
207 return; | |
208 } | |
209 if (overvoltage_end_charge_check()) | |
210 return; | |
211 if (msg->data[2] >= | |
212 pwr_ctrl->config.end_current + pwr_ctrl->i2v_offset) | |
213 return; | |
214 rvf_send_trace("Stopping charge by low current condition", 40, | |
215 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, | |
216 FCHG_USE_ID); | |
217 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); | |
218 pwr_init_discharge(); | |
219 pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE; | |
220 return; | |
221 default: | |
222 rvf_send_trace("Invalid state in pwr_process_adc()", 32, | |
223 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR, | |
224 FCHG_USE_ID); | |
225 } | |
226 } |