comparison src/cs/drivers/drv_app/pwr/pwr_cust.c @ 0:b6a5e36de839

src/cs: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:39:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:b6a5e36de839
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/rv_defined_swe.h" // for RVM_PWR_SWE
16
17 #ifdef RVM_PWR_SWE
18
19 #include "abb/abb.h"
20 #include "rvm/rvm_use_id_list.h"
21 #include "pwr/pwr_messages.h"
22 #include "rvf/rvf_api.h"
23 #include "pwr/pwr_cust.h"
24 #include "pwr/pwr_env.h"
25 #include "pwr/pwr_analog_dev.h"
26 #include "spi/spi_env.h"
27 #include "spi/spi_task.h"
28 #include "pwr/pwr_liion_cha.h"
29 #include "pwr/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 (ANLG_FAM == 1)
358 ABB_Write_Register_on_page(PAGE0, VRPCCTL2, 0x00EE);
359 #elif (ANLG_FAM == 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 (ANLG_FAM == 1)
494 ABB_Write_Register_on_page(PAGE0, VRPCCTL2, 0x00EE);
495 #elif (ANLG_FAM == 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 */