FreeCalypso > hg > fc-magnetite
comparison src/cs/drivers/drv_app/pwr/pwr_cust.c @ 145:246f4a7dd92b
src/cs/drivers/drv_app/pwr: import from MV100 source
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 09 Oct 2016 05:59:14 +0000 |
parents | |
children | fb95e3f83dc5 |
comparison
equal
deleted
inserted
replaced
144:fd8227e3047d | 145:246f4a7dd92b |
---|---|
1 /******************************************************************************* | |
2 * | |
3 * pwr_cust.c | |
4 * | |
5 * Purpose: This file contains functions for battery management. | |
6 * These functions can be modified by the customer. | |
7 * | |
8 * Author Candice Bazanegue (c-brille@ti.com) | |
9 * | |
10 * | |
11 * (C) Texas Instruments 2001 | |
12 * | |
13 ******************************************************************************/ | |
14 | |
15 #include "rv_defined_swe.h" // for RVM_PWR_SWE | |
16 | |
17 #ifdef RVM_PWR_SWE | |
18 | |
19 #include "abb.h" | |
20 #include "rvm_use_id_list.h" | |
21 #include "pwr_messages.h" | |
22 #include "rvf_api.h" | |
23 #include "pwr_cust.h" | |
24 #include "pwr_env.h" | |
25 #include "pwr_analog_dev.h" | |
26 #include "spi_env.h" | |
27 #include "spi_task.h" | |
28 #include "pwr_liion_cha.h" | |
29 #include "pwr_disch.h" | |
30 | |
31 /* Caution: keep ascending order in the temperature arrays !!! */ | |
32 | |
33 const INT16 BAT_Celsius_temp_10uA[4]= | |
34 { | |
35 -10, -5, 0, 5 | |
36 }; | |
37 const UINT16 BAT_MADC_temp_10uA[4]= | |
38 { | |
39 0x13F, 0x103, 0xCB, 0x9C | |
40 }; | |
41 const INT16 BAT_Celsius_temp_50uA[13]= | |
42 { | |
43 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 | |
44 }; | |
45 const UINT16 BAT_MADC_temp_50uA[13]= | |
46 { | |
47 0x351, 0x2AD, 0x22E, 0x1C4, 0x169, 0x128, 0xF9, 0xCB, 0x96, 0x83, 0x68, 0x58, 0x4A | |
48 }; | |
49 | |
50 | |
51 /* Correpondence between the battery voltage and the remaining capacity in the battery */ | |
52 /* The voltages have to be expressed in mV units */ | |
53 /* The capacities are percentages of the total capacity */ | |
54 /* Caution: keep this order in the array !!!! (in voltage (or capacity) descending order) */ | |
55 | |
56 const T_PWR_THRESHOLDS a_pwr_thresholds[NB_THRESHOLDS]= | |
57 {{4200,100}, {4000,75}, {3970,50}, {3950,25}, {3900,15}, {3870,10}}; | |
58 | |
59 | |
60 | |
61 /* Global variable */ | |
62 extern T_SPI_GBL_INFO *SPI_GBL_INFO_PTR; | |
63 | |
64 | |
65 | |
66 /******************************************************************************* | |
67 ** Function pwr_adc_to_mvolt | |
68 ** | |
69 ** Description Converts the MADC voltage reading into voltage in mVolt | |
70 ** | |
71 ** Warning: The offsets are not taken into account !!! | |
72 ** | |
73 *******************************************************************************/ | |
74 UINT16 pwr_adc_to_mvolt(UINT16 voltage_madc) | |
75 { | |
76 UINT16 voltage_mvolt; | |
77 | |
78 /* Note: /1000 because MADC_VOLTAGE_STEP is expressed in uV */ | |
79 voltage_mvolt = (voltage_madc * MADC_VOLTAGE_STEP * 4) / 1000; | |
80 | |
81 /* return voltage in mVolt */ | |
82 return (voltage_mvolt); | |
83 } | |
84 | |
85 | |
86 /******************************************************************************* | |
87 ** Function pwr_adc_to_mA | |
88 ** | |
89 ** Description Converts the MADC current reading into current in mA | |
90 ** | |
91 ** Warning: The offsets are not taken into account !!! | |
92 ** | |
93 *******************************************************************************/ | |
94 UINT16 pwr_adc_to_mA(UINT16 current_madc) | |
95 { | |
96 UINT16 current_mA; | |
97 | |
98 /* Note: /1000 because MADC_VOLTAGE_STEP is expressed in uA */ | |
99 current_mA = (current_madc * MADC_CURRENT_STEP) / 1000; | |
100 | |
101 /* return current in mA */ | |
102 return (current_mA); | |
103 } | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 /******************************************************************************* | |
110 ** Function pwr_bat_temp_within_limits | |
111 ** | |
112 ** Description Check if the battery temperature is within limits | |
113 ** | |
114 ** Parameter battery_temperature : battery temperature un Celsius degrees | |
115 ** | |
116 *******************************************************************************/ | |
117 UINT8 pwr_bat_temp_within_limits(INT16 battery_temperature) | |
118 { | |
119 rvf_send_trace("Battery temperature (Celsius degrees) ", 38, battery_temperature, RV_TRACE_LEVEL_DEBUG_LOW, PWR_USE_ID); | |
120 if ((battery_temperature < BAT_TEMPERATURE_MAX) && | |
121 (battery_temperature > BAT_TEMPERATURE_MIN)) | |
122 { | |
123 rvf_send_trace("Battery temperature within limits",33, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_LOW, PWR_USE_ID); | |
124 return (TRUE); | |
125 } | |
126 | |
127 rvf_send_trace("Battery temperature outside limits",34, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_MEDIUM, PWR_USE_ID); | |
128 return (FALSE); | |
129 } | |
130 | |
131 | |
132 | |
133 /******************************************************************************* | |
134 ** Function pwr_madc_to_Celius_conv | |
135 ** | |
136 ** Description Find the temperature in Celsius degrees corresponding | |
137 ** to the value given by the MADC | |
138 ** | |
139 *******************************************************************************/ | |
140 UINT8 pwr_madc_to_Celsius_conv(UINT8 bias_current, UINT16 madc_temp, INT16 *celsius_temp) | |
141 { | |
142 UINT8 last_index, i; | |
143 const UINT16 *MADC_temp_array; | |
144 const INT16 *celsius_temp_array; | |
145 UINT16 madc_diff; | |
146 UINT16 madc_inc; | |
147 UINT16 celsius_inc; | |
148 | |
149 /* choose the table */ | |
150 switch(bias_current) | |
151 { | |
152 case THEN_10uA: | |
153 MADC_temp_array = BAT_MADC_temp_10uA; | |
154 celsius_temp_array = BAT_Celsius_temp_10uA; | |
155 /* get last index of the lookup table array(s) */ | |
156 last_index = sizeof(BAT_MADC_temp_10uA)/sizeof(BAT_MADC_temp_10uA[0]); | |
157 break; | |
158 | |
159 case THEN_50uA: | |
160 MADC_temp_array = BAT_MADC_temp_50uA; | |
161 celsius_temp_array = BAT_Celsius_temp_50uA; | |
162 /* get last index of the lookup table array(s) */ | |
163 last_index = sizeof(BAT_MADC_temp_50uA)/sizeof(BAT_MADC_temp_50uA[0]); | |
164 break; | |
165 | |
166 default: return (FALSE); | |
167 } | |
168 | |
169 /* check the limits */ | |
170 if((madc_temp > MADC_temp_array[0]) || (madc_temp < MADC_temp_array[last_index-1])) | |
171 { | |
172 return (FALSE); | |
173 } | |
174 | |
175 | |
176 /* find the two points between which the given point lies */ | |
177 for(i=0; i<last_index; i++) | |
178 { | |
179 if(madc_temp >= MADC_temp_array[i]) | |
180 { | |
181 if(i==0) | |
182 { | |
183 *celsius_temp = celsius_temp_array[0]; | |
184 return (TRUE); | |
185 } | |
186 | |
187 /* the value is between MADC_temp_array[i] and MADC_temp_array[i-1] */ | |
188 /* interpolate to get a more precise value */ | |
189 | |
190 madc_inc = MADC_temp_array[i-1] - MADC_temp_array[i]; | |
191 celsius_inc = celsius_temp_array[1] - celsius_temp_array[0]; /* positive value */ | |
192 | |
193 /* difference between the given point and the first madc value below this point */ | |
194 madc_diff = madc_temp - MADC_temp_array[i]; | |
195 | |
196 *celsius_temp = celsius_temp_array[i] - (madc_diff*celsius_inc)/madc_inc; | |
197 | |
198 return (TRUE); | |
199 } | |
200 | |
201 /* else, try a smaller value */ | |
202 } | |
203 | |
204 return (FALSE); | |
205 } | |
206 | |
207 | |
208 | |
209 /******************************************************************************* | |
210 ** Function pwr_get_battery_temperature | |
211 ** | |
212 ** Description Start MADC temperature reading | |
213 ** | |
214 ** Note If the used battery does not allow to make a temperature | |
215 ** measurement, the body of this function can be replaced | |
216 ** by just a "return" with a temperature (in Celsius degrees) | |
217 ** between BAT_TEMPERATURE_MIN and BAT_TEMPERATURE_MAX. | |
218 *******************************************************************************/ | |
219 void pwr_get_battery_temperature(void) | |
220 { | |
221 | |
222 /* set the bias current to 50uA */ | |
223 ABB_Write_Register_on_page(PAGE0, BCICTL1, THEN_50uA); | |
224 rvf_delay(RVF_MS_TO_TICKS(5)); | |
225 | |
226 pwr_env_ctrl_blk->timer0_state = BATTERY_50UA_TEMP_TEST; | |
227 | |
228 if (SPI_GBL_INFO_PTR->is_adc_on == FALSE) | |
229 { | |
230 /* start ADIN2REG channel conversion by writing in the result register */ | |
231 ABB_Write_Register_on_page(PAGE0, ADIN2REG, 0x0000); | |
232 rvf_start_timer (SPI_TIMER0, | |
233 RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_1), | |
234 FALSE); | |
235 } | |
236 else /* The L1 asks for ADC conversions */ | |
237 { | |
238 /* Let time for the L1 to ask for new AD conversions */ | |
239 rvf_start_timer (SPI_TIMER0, | |
240 RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_2), | |
241 FALSE); | |
242 } | |
243 } | |
244 | |
245 | |
246 | |
247 /******************************************************************************* | |
248 ** Function pwr_bat_50uA_temp_test_timer_process | |
249 ** | |
250 ** Description | |
251 ** | |
252 ** | |
253 *******************************************************************************/ | |
254 void pwr_bat_50uA_temp_test_timer_process(void) | |
255 { | |
256 UINT16 bat_madc_temp; | |
257 | |
258 rvf_send_trace("TIMER0: Battery 50uA temp test",30, NULL_PARAM, RV_TRACE_LEVEL_WARNING, PWR_USE_ID); | |
259 | |
260 pwr_env_ctrl_blk->bat_celsius_temp = (INT16)(0xFFFF); | |
261 | |
262 /* Read ADC result */ | |
263 bat_madc_temp = ABB_Read_Register_on_page(PAGE0, ADIN2REG); | |
264 | |
265 /* MADC value to Celsius degrees conversion */ | |
266 if (!pwr_madc_to_Celsius_conv(THEN_50uA, bat_madc_temp, &(pwr_env_ctrl_blk->bat_celsius_temp))) | |
267 { | |
268 /* outside the 50uA temp range */ | |
269 /* set the bias current to 10uA */ | |
270 | |
271 pwr_env_ctrl_blk->timer0_state = BATTERY_10UA_TEMP_TEST; | |
272 | |
273 ABB_Write_Register_on_page(PAGE0, BCICTL1, THEN_10uA); | |
274 rvf_delay(RVF_MS_TO_TICKS(5)); | |
275 | |
276 if (SPI_GBL_INFO_PTR->is_adc_on == FALSE) | |
277 { | |
278 /* start ADIN2REG channel conversion by writing in the result register */ | |
279 ABB_Write_Register_on_page(PAGE0, ADIN2REG, 0x0000); | |
280 rvf_start_timer (SPI_TIMER0, | |
281 RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_1), | |
282 FALSE); | |
283 } | |
284 else /* The L1 asks for ADC conversions */ | |
285 { | |
286 /* Let time for the L1 to ask for new AD conversions */ | |
287 rvf_start_timer (SPI_TIMER0, | |
288 RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_2), | |
289 FALSE); | |
290 } | |
291 } | |
292 | |
293 else | |
294 { | |
295 /* The battery temp is inside the 50uA temp range */ | |
296 /* Turn OFF the current source */ | |
297 ABB_Write_Register_on_page(PAGE0, BCICTL1, MESBAT); | |
298 | |
299 /* Go ahead */ | |
300 if (pwr_env_ctrl_blk->charging_state == CI_CHARGE_STARTED) | |
301 { | |
302 /* temperature measurement during CI charge */ | |
303 pwr_CI_charge_process(); | |
304 } | |
305 else if (pwr_env_ctrl_blk->charging_state == CV_CHARGE_STARTED) | |
306 { | |
307 /* temperature measurement during CV charge */ | |
308 pwr_CV_charge_process(); | |
309 } | |
310 else if (pwr_env_ctrl_blk->charging_state == TESTING_BATTERY) | |
311 { | |
312 /* temperature measurement before calibration */ | |
313 pwr_calibration_process(); | |
314 } | |
315 else | |
316 { | |
317 /* temperature measurement for battery information */ | |
318 pwr_get_bat_info(); | |
319 } | |
320 } | |
321 } | |
322 | |
323 | |
324 /******************************************************************************* | |
325 ** Function pwr_bat_10uA_temp_test_timer_process | |
326 ** | |
327 ** Description | |
328 ** | |
329 ** | |
330 *******************************************************************************/ | |
331 void pwr_bat_10uA_temp_test_timer_process(void) | |
332 { | |
333 UINT16 bat_madc_temp; | |
334 | |
335 rvf_send_trace("TIMER0: Battery 10uA temp test",30, NULL_PARAM, RV_TRACE_LEVEL_WARNING, PWR_USE_ID); | |
336 | |
337 pwr_env_ctrl_blk->bat_celsius_temp = (INT16)(0xFFFF); | |
338 | |
339 bat_madc_temp = ABB_Read_Register_on_page(PAGE0, ADIN2REG); | |
340 | |
341 /* MADC value to Celsius degrees conversion */ | |
342 if (!pwr_madc_to_Celsius_conv(THEN_10uA, bat_madc_temp, &(pwr_env_ctrl_blk->bat_celsius_temp))) | |
343 { | |
344 /* ERROR: Reading out of limits */ | |
345 rvf_send_trace("Battery temperature reading out of limits", 41, NULL_PARAM, RV_TRACE_LEVEL_WARNING, PWR_USE_ID); | |
346 | |
347 /* turn OFF the current source */ | |
348 ABB_Write_Register_on_page(PAGE0, BCICTL1, MESBAT); | |
349 | |
350 pwr_stop_charging(); | |
351 | |
352 /* informs the upper layer that the battery temperature is not correct */ | |
353 pwr_send_charge_not_possible_event(BAT_TEMP_OUTSIDE_LIMITS); | |
354 | |
355 if (SPI_GBL_INFO_PTR->is_gsm_on == FALSE) /* GSM OFF */ | |
356 { | |
357 #if (ANALOG == 1) | |
358 ABB_Write_Register_on_page(PAGE0, VRPCCTL2, 0x00EE); | |
359 #elif (ANALOG == 2) | |
360 ABB_Write_Register_on_page(PAGE0, VRPCDEV, 0x0001); | |
361 #endif | |
362 } | |
363 else | |
364 { | |
365 pwr_handle_discharge(); | |
366 } | |
367 } | |
368 | |
369 else | |
370 { | |
371 /* The battery temperature is inside the 10uA temp range */ | |
372 /* turn OFF the current source */ | |
373 ABB_Write_Register_on_page(PAGE0, BCICTL1, MESBAT); | |
374 | |
375 /* Go ahead */ | |
376 if (pwr_env_ctrl_blk->charging_state == CI_CHARGE_STARTED) | |
377 { | |
378 /* temperature measurement during CI charge */ | |
379 pwr_CI_charge_process(); | |
380 } | |
381 else if (pwr_env_ctrl_blk->charging_state == CV_CHARGE_STARTED) | |
382 { | |
383 /* temperature measurement during CV charge */ | |
384 pwr_CV_charge_process(); | |
385 } | |
386 else if (pwr_env_ctrl_blk->charging_state == TESTING_BATTERY) | |
387 { | |
388 /* temperature measurement before calibration */ | |
389 pwr_calibration_process(); | |
390 } | |
391 else | |
392 { | |
393 /* temperature measurement for battery information */ | |
394 pwr_get_bat_info(); | |
395 } | |
396 } | |
397 } | |
398 | |
399 | |
400 | |
401 | |
402 /******************************************************************************* | |
403 ** Function pwr_get_battery_type | |
404 ** | |
405 ** Description Return the type of the battery | |
406 ** | |
407 ** Note If the used battery does not allow to make a battery type | |
408 ** SW detection, the body of this function can be replaced | |
409 ** by the last 2 lines | |
410 ** | |
411 *******************************************************************************/ | |
412 void pwr_get_battery_type(void) | |
413 { | |
414 | |
415 /* enable bias current for main battery type reading | |
416 ABB_Write_Register_on_page(PAGE0, BCICTL1, 0x0081); | |
417 rvf_delay(RVF_MS_TO_TICKS(5)); | |
418 | |
419 pwr_env_ctrl_blk->timer0_state = BATTERY_TYPE_TEST; | |
420 | |
421 if (SPI_GBL_INFO_PTR->is_adc_on == FALSE) | |
422 { | |
423 /* start ADIN1REG channel conversion by writing in the result register | |
424 ABB_Write_Register_on_page(PAGE0, ADIN1REG, 0x0000); | |
425 rvf_start_timer (SPI_TIMER0, | |
426 RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_1), | |
427 FALSE); | |
428 } | |
429 else /* The L1 asks for ADC conversions | |
430 { | |
431 /* Let time for the L1 to ask for new AD conversions | |
432 rvf_start_timer (SPI_TIMER0, | |
433 RVF_MS_TO_TICKS (SPI_TIMER0_INTERVAL_2), | |
434 FALSE); | |
435 } | |
436 */ | |
437 | |
438 | |
439 | |
440 /****************************************/ | |
441 /* If the battery can not be detected, */ | |
442 /* the code above has to be replaced by */ | |
443 /* those 2 lines (with the type of the */ | |
444 /* used battery). */ | |
445 /****************************************/ | |
446 | |
447 pwr_env_ctrl_blk->bat_type = LI_ION; | |
448 | |
449 /* Check if the battery is OK */ | |
450 pwr_battery_qualification(); | |
451 | |
452 | |
453 } | |
454 | |
455 | |
456 | |
457 /******************************************************************************* | |
458 ** Function pwr_type_test_timer_process | |
459 ** | |
460 ** Description | |
461 ** | |
462 ** | |
463 *******************************************************************************/ | |
464 void pwr_type_test_timer_process(void) | |
465 { | |
466 UINT16 bat_type_voltage; | |
467 | |
468 rvf_send_trace("TIMER0: Battery type test",25, NULL_PARAM, RV_TRACE_LEVEL_WARNING, PWR_USE_ID); | |
469 | |
470 bat_type_voltage = ABB_Read_Register_on_page(PAGE0, ADIN1REG); | |
471 | |
472 /* turn OFF the current source */ | |
473 ABB_Write_Register_on_page(PAGE0, BCICTL1, MESBAT); | |
474 | |
475 if ((bat_type_voltage >= BAT_TYPE_LI_ION_MIN) && | |
476 (bat_type_voltage <= BAT_TYPE_LI_ION_MAX)) /* Li-ion batteries */ | |
477 { | |
478 pwr_env_ctrl_blk->bat_type = LI_ION; | |
479 | |
480 /* Check if the battery is OK */ | |
481 pwr_battery_qualification(); | |
482 | |
483 } | |
484 | |
485 else /* battery type unknown */ | |
486 { | |
487 pwr_env_ctrl_blk->bat_type = UNKNOWN; | |
488 | |
489 /* informs the upper layer that the battery type is unknown */ | |
490 pwr_send_charge_not_possible_event(BAT_TYPE_UNKNOWN); | |
491 if (SPI_GBL_INFO_PTR->is_gsm_on == FALSE) /* GSM OFF */ | |
492 { | |
493 #if (ANALOG == 1) | |
494 ABB_Write_Register_on_page(PAGE0, VRPCCTL2, 0x00EE); | |
495 #elif (ANALOG == 2) | |
496 ABB_Write_Register_on_page(PAGE0, VRPCDEV, 0x0001); | |
497 #endif | |
498 } | |
499 else | |
500 { | |
501 pwr_handle_discharge(); | |
502 } | |
503 } | |
504 } | |
505 | |
506 | |
507 | |
508 /******************************************************************************* | |
509 ** Function pwr_get_capacity_vs_voltage | |
510 ** | |
511 ** Description Compares the battery voltage with the thresholds given in the | |
512 ** a_pwr_thresholds array and returns the remaining capacity | |
513 ** corresponding to the threshold above this voltage. | |
514 ** | |
515 ** Parameters: UINT16 bat_voltage: battery voltage in mV !!! | |
516 ** | |
517 *******************************************************************************/ | |
518 T_PWR_PERCENT pwr_get_capacity_vs_voltage(UINT16 bat_voltage) | |
519 { | |
520 volatile UINT16 i; | |
521 T_PWR_PERCENT remaining_capacity; | |
522 | |
523 for(i=0; i<NB_THRESHOLDS; i++) | |
524 { | |
525 if(bat_voltage > a_pwr_thresholds[i].bat_voltage) | |
526 { | |
527 if(i==0) | |
528 { | |
529 remaining_capacity = a_pwr_thresholds[0].remain_capa; | |
530 } | |
531 else | |
532 { | |
533 remaining_capacity = a_pwr_thresholds[i-1].remain_capa; | |
534 } | |
535 | |
536 return (remaining_capacity); | |
537 } | |
538 /* else, try the next threshold */ | |
539 } | |
540 | |
541 if(i==NB_THRESHOLDS) | |
542 { | |
543 /* battery voltage below the last threshold */ | |
544 remaining_capacity = a_pwr_thresholds[i-1].remain_capa; | |
545 return (remaining_capacity); | |
546 } | |
547 | |
548 return 0; /* dummy return */ | |
549 } | |
550 | |
551 #endif /* #ifdef RVM_PWR_SWE */ |