comparison src/cs/drivers/drv_app/fchg/fchg_process.c @ 362:4c3d05866531

FCHG: beginning of the new version
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 29 Dec 2017 07:06:06 +0000
parents ce6d71349af0
children cce24b9de6db
comparison
equal deleted inserted replaced
361:9e0608dc9170 362:4c3d05866531
11 #include "abb/abb.h" 11 #include "abb/abb.h"
12 #include <string.h> 12 #include <string.h>
13 #include <stdio.h> 13 #include <stdio.h>
14 14
15 extern UINT16 madc_vbat_2_physical(UINT16 adc_val); 15 extern UINT16 madc_vbat_2_physical(UINT16 adc_val);
16 extern UINT16 madc_vbat_inverse(UINT16 mv);
16 17
17 void pwr_init_discharge(void) 18 void pwr_init_discharge(void)
18 { 19 {
19 pwr_ctrl->curr_disch_thresh = 0; 20 pwr_ctrl->curr_disch_thresh = 0;
20 } 21 }
41 pwr_ctrl->curr_disch_thresh = i; 42 pwr_ctrl->curr_disch_thresh = i;
42 sprintf(trace, "Battery fell through %u%% mark", 43 sprintf(trace, "Battery fell through %u%% mark",
43 pwr_ctrl->batt_thresholds[i].remain_capa); 44 pwr_ctrl->batt_thresholds[i].remain_capa);
44 rvf_send_trace(trace, strlen(trace), NULL_PARAM, 45 rvf_send_trace(trace, strlen(trace), NULL_PARAM,
45 RV_TRACE_LEVEL_WARNING, FCHG_USE_ID); 46 RV_TRACE_LEVEL_WARNING, FCHG_USE_ID);
46 }
47
48 static void charge_progress_trace(char *mode, UINT16 ichg)
49 {
50 char trace[64];
51
52 sprintf(trace, "%s charging: Vbat=%u Ichg=%u i2v=%u", mode,
53 pwr_ctrl->batt_mv, ichg, pwr_ctrl->i2v_offset);
54 rvf_send_trace(trace, strlen(trace), NULL_PARAM,
55 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID);
56 } 47 }
57 48
58 static void start_i2v_cal(void) 49 static void start_i2v_cal(void)
59 { 50 {
60 UINT16 bciconf; 51 UINT16 bciconf;
86 pwr_ctrl->config.ci_current + pwr_ctrl->i2v_offset); 77 pwr_ctrl->config.ci_current + pwr_ctrl->i2v_offset);
87 /* Enable the charger */ 78 /* Enable the charger */
88 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0003); 79 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0003);
89 } 80 }
90 81
91 static void start_cv_charging(UINT16 code) 82 static void start_cv_charging(void)
92 { 83 {
84 UINT16 code;
85
93 rvf_send_trace("Start CV charging", 17, NULL_PARAM, 86 rvf_send_trace("Start CV charging", 17, NULL_PARAM,
94 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); 87 RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID);
95 pwr_ctrl->state = FCHG_STATE_CV_CHARGING; 88 pwr_ctrl->state = FCHG_STATE_CV_CHARGING;
96 /* Select constant voltage charging. The charger is disabled */ 89 /* Select constant voltage charging. The charger is disabled */
97 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); 90 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0);
98 /* figure out the DAC code */ 91 /* figure out the DAC code */
99 while (code && 92 code = madc_vbat_inverse(pwr_ctrl->config.cv_init_set);
100 madc_vbat_2_physical(code) >= pwr_ctrl->config.cv_init_set)
101 code--;
102 code++;
103 rvf_send_trace("Voltage (DAC code) ", 19, code, 93 rvf_send_trace("Voltage (DAC code) ", 19, code,
104 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID); 94 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID);
105 /* Program the DAC with the constant voltage value */ 95 /* Program the DAC with the constant voltage value */
106 ABB_Write_Register_on_page(PAGE0, CHGREG, code); 96 ABB_Write_Register_on_page(PAGE0, CHGREG, code);
107 /* Enable the charger */ 97 /* Enable the charger */
108 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0001); 98 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0x0001);
99 /* CV control loop state init */
100 pwr_ctrl->cv_dac_init = code;
101 pwr_ctrl->cv_dac_curr = code;
102 pwr_ctrl->cv_high_vbat_count = 0;
103 pwr_ctrl->cv_low_vbat_count = 0;
104 /* Ichg averaging state init */
105 pwr_ctrl->ichg_fill_level = 0;
106 pwr_ctrl->ichg_ring_ptr = 0;
107 pwr_ctrl->ichg_low_count = 0;
109 } 108 }
110 109
111 static void start_charge_condition_met(void) 110 static void start_charge_condition_met(void)
112 { 111 {
113 rvf_send_trace("Charge start condition met", 26, NULL_PARAM, 112 rvf_send_trace("Charge start condition met", 26, NULL_PARAM,
118 pwr_ctrl->i2v_offset = 0; 117 pwr_ctrl->i2v_offset = 0;
119 start_ci_charging(); 118 start_ci_charging();
120 } 119 }
121 } 120 }
122 121
122 static void ci_progress_trace(UINT16 ichg)
123 {
124 char trace[64];
125
126 sprintf(trace, "CI charging: Vbat=%u Ichg=%u i2v=%u",
127 pwr_ctrl->batt_mv, ichg, pwr_ctrl->i2v_offset);
128 rvf_send_trace(trace, strlen(trace), NULL_PARAM,
129 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID);
130 }
131
132 static int cv_ichg_process(UINT16 ichg_new)
133 {
134 UINT16 ichg_clip, ichg_entry;
135 UINT32 ichg_accum;
136 UINT16 i;
137 char trace[64];
138
139 if (pwr_ctrl->ichg_fill_level < ICHG_AVG_WINDOW)
140 pwr_ctrl->ichg_avg_buf[pwr_ctrl->ichg_fill_level++] = ichg_new;
141 else {
142 ichg_clip = pwr_ctrl->ichg_average +
143 pwr_ctrl->config.ichg_max_spike;
144 if (ichg_new > ichg_clip)
145 ichg_entry = ichg_clip;
146 else
147 ichg_entry = ichg_new;
148 pwr_ctrl->ichg_avg_buf[pwr_ctrl->ichg_ring_ptr++] = ichg_entry;
149 if (pwr_ctrl->ichg_ring_ptr >= ICHG_AVG_WINDOW)
150 pwr_ctrl->ichg_ring_ptr = 0;
151 }
152 ichg_accum = 0;
153 for (i = 0; i < pwr_ctrl->ichg_fill_level; i++)
154 ichg_accum += pwr_ctrl->ichg_avg_buf[i];
155 pwr_ctrl->ichg_average = ichg_accum / pwr_ctrl->ichg_fill_level;
156 sprintf(trace, "CV charging: Vbat=%u Ichg=%u Ichg_avg=%u i2v=%u",
157 pwr_ctrl->batt_mv, ichg_new, pwr_ctrl->ichg_average,
158 pwr_ctrl->i2v_offset);
159 rvf_send_trace(trace, strlen(trace), NULL_PARAM,
160 RV_TRACE_LEVEL_DEBUG_LOW, FCHG_USE_ID);
161 if (pwr_ctrl->ichg_average >
162 (pwr_ctrl->config.end_current + pwr_ctrl->i2v_offset)) {
163 pwr_ctrl->ichg_low_count = 0;
164 return 0;
165 }
166 pwr_ctrl->ichg_low_count++;
167 if (pwr_ctrl->ichg_low_count < pwr_ctrl->config.ichg_samples_needed)
168 return 0;
169 rvf_send_trace("Stopping charge by low current condition", 40,
170 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID);
171 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0);
172 pwr_init_discharge();
173 pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE;
174 return 1;
175 }
176
123 static int overvoltage_end_charge_check(void) 177 static int overvoltage_end_charge_check(void)
124 { 178 {
125 if (pwr_ctrl->batt_mv < pwr_ctrl->config.overvoltage) 179 if (pwr_ctrl->batt_mv < pwr_ctrl->config.overvoltage)
180 return 0;
181 if (pwr_ctrl->cv_dac_curr >= pwr_ctrl->cv_dac_init)
182 return 0;
183 if ((pwr_ctrl->cv_dac_init - pwr_ctrl->cv_dac_curr) <
184 pwr_ctrl->config.cv_dac_max_decr)
126 return 0; 185 return 0;
127 rvf_send_trace("Stopping charge by overvoltage condition", 40, 186 rvf_send_trace("Stopping charge by overvoltage condition", 40,
128 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID); 187 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, FCHG_USE_ID);
129 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); 188 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0);
130 pwr_init_discharge(); 189 pwr_init_discharge();
183 return; 242 return;
184 } 243 }
185 start_ci_charging(); 244 start_ci_charging();
186 return; 245 return;
187 case FCHG_STATE_CI_CHARGING: 246 case FCHG_STATE_CI_CHARGING:
188 charge_progress_trace("CI", msg->data[2]); 247 ci_progress_trace(msg->data[2]);
189 if (!(msg->data[9] & CHGPRES)) { 248 if (!(msg->data[9] & CHGPRES)) {
190 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0); 249 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0);
191 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR; 250 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR;
192 return; 251 return;
193 } 252 }
253 if (pwr_ctrl->batt_mv >= pwr_ctrl->config.ci2cv_thresh)
254 start_cv_charging();
255 return;
256 case FCHG_STATE_CV_CHARGING:
257 if (!(msg->data[9] & CHGPRES)) {
258 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0);
259 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR;
260 return;
261 }
262 if (cv_ichg_process(msg->data[2]))
263 return;
194 if (overvoltage_end_charge_check()) 264 if (overvoltage_end_charge_check())
195 return; 265 return;
196 if (pwr_ctrl->batt_mv >= pwr_ctrl->config.ci2cv_thresh) 266 /* DAC control loop will go here */
197 start_cv_charging(msg->data[0]);
198 return;
199 case FCHG_STATE_CV_CHARGING:
200 charge_progress_trace("CV", msg->data[2]);
201 if (!(msg->data[9] & CHGPRES)) {
202 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0);
203 pwr_ctrl->state = FCHG_STATE_NO_EXT_PWR;
204 return;
205 }
206 if (overvoltage_end_charge_check())
207 return;
208 if (msg->data[2] >=
209 pwr_ctrl->config.end_current + pwr_ctrl->i2v_offset)
210 return;
211 rvf_send_trace("Stopping charge by low current condition", 40,
212 NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH,
213 FCHG_USE_ID);
214 ABB_Write_Register_on_page(PAGE0, BCICTL2, 0);
215 pwr_init_discharge();
216 pwr_ctrl->state = FCHG_STATE_READY_TO_RECHARGE;
217 return; 267 return;
218 default: 268 default:
219 rvf_send_trace("Invalid state in pwr_process_adc()", 32, 269 rvf_send_trace("Invalid state in pwr_process_adc()", 32,
220 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR, 270 pwr_ctrl->state, RV_TRACE_LEVEL_ERROR,
221 FCHG_USE_ID); 271 FCHG_USE_ID);