comparison src/cs/drivers/drv_app/lcc/lcc_task.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 * Power Task (pwr)
3 * Design and coding by Svend Kristian Lindholm, skl@ti.com
4 *
5 * Main PWR Task
6 *
7 * $Id: pwr_task.c 1.1 Wed, 20 Aug 2003 10:22:37 +0200 skl $
8 *
9 ******************************************************************************/
10
11 #include "lcc/lcc.h"
12 #include "lcc/lcc_task.h"
13 #include "lcc/lcc_handle_message.h"
14 #include "lcc/lcc_tm_i.h"
15 #include "lcc/lcc_trace.h"
16
17 #include "rv/rv_defined_swe.h"
18
19 #include "ffs/ffs.h"
20
21 #include <string.h>
22 /******************************************************************************
23 * Globals and function prototypes
24 ******************************************************************************/
25
26 extern T_PWR_CTRL_BLOCK *pwr_ctrl;
27 extern T_PWR_CFG_BLOCK *pwr_cfg;
28
29 // Event handling functions
30 T_RV_RET process_spi_adc_indication (T_PWR_REQ *request);
31
32 // Timer event handling functions
33 T_RV_RET process_pwr_handle_T1_expiration (T_PWR_REQ *request);
34 T_RV_RET process_pwr_handle_T2_expiration (T_PWR_REQ *request);
35 T_RV_RET process_pwr_handle_T3_expiration (T_PWR_REQ *request);
36 T_RV_RET process_pwr_handle_T4_expiration (T_PWR_REQ *request);
37 T_RV_RET process_pwr_handle_mod_cycle_expiration(T_PWR_REQ *request);
38 T_RV_RET process_pwr_handle_mmi_info_expiration (T_PWR_REQ *request);
39
40 // Interrupt event handling functions
41 T_RV_RET process_abb_chg_unplugged_ind (T_PWR_REQ *request);
42
43
44 T_RVM_RETURN pwr_check_files(void);
45 T_RVM_RETURN pwr_read_files(void);
46 T_RVM_RETURN pwr_read_chg_files(void);
47 T_RVM_RETURN pwr_read_cal_files(void);
48
49 void build_name(const char *ch_pre, char *cfg_id , UINT8 index, const char * ch_post, char * name);
50
51 // FFS function prototypes
52 effs_t ffs_stat(const char *name, struct stat_s *stat);
53 int ffs_fread(const char *name, void *addr, int size);
54
55 void ttr(unsigned trmask, char *format, ...);
56 void str(unsigned mask, char *string);
57
58
59 /******************************************************************************
60 * PWR Task
61 ******************************************************************************/
62
63 // This function checks the existance of FFS directories and files related
64 // to the PWR module - See RD818
65 // If the existance of the object is MANDATORY pwr_check_files returns an
66 // error and the PWR configuration is stopped
67 // If the existance of the object is OPTIONAL pwr_check_files a
68 // warning is given and the PWR configuration proceeds
69
70 T_RVM_RETURN pwr_check_files()
71 {
72 T_FFS_SIZE error;
73 T_FFS_STAT stat;
74
75 ttw(ttr(TTrInit, "pwr_check_files(%d)" NL, 0));
76
77 // Check directories:
78 // /pwr MANDATORY
79 // /pwr/bat MANDATORY
80 // /pwr/chg OPTIONAL
81 // /mmi OPTIONAL
82 // /mmi/pwr OPTIONAL
83
84 // MANDATORY directories
85 if ((error = ffs_stat("/pwr", &stat)) == EFFS_OK) {
86 if (stat.type != OT_DIR) {
87 ttr(TTrFatal, "pwr exists but is not a directory %d" NL, 0);
88 return EFFS_NOTADIR;
89 }
90 } else {
91 ttr(TTrFatal, "no /pwr directory %d" NL, 0);
92 return error;
93 }
94 if ((error = ffs_stat("/pwr/bat", &stat)) == EFFS_OK) {
95 if (stat.type != OT_DIR) {
96 ttr(TTrFatal, "/pwr/bat exists but is not a directory %d" NL, 0);
97 return EFFS_NOTADIR;
98 }
99 } else {
100 ttr(TTrFatal, "no /pwr/bat directory %d" NL, 0);
101 return error;
102 }
103
104
105 // OPTIONAL directories
106 if ((error = ffs_stat("/pwr/chg", &stat)) == EFFS_OK) {
107 if (stat.type != OT_DIR) {
108 ttr(TTrWarning, "/pwr/chg exists but is not a directory %d" NL, 0);
109 }
110 } else {
111 ttr(TTrWarning, "no /pwr/chg directory %d" NL, 0);
112 }
113 if ((error = ffs_stat("/mmi", &stat)) == EFFS_OK) {
114 if (stat.type != OT_DIR) {
115 ttr(TTrWarning, "/mmi exists but is not a directory %d" NL, 0);
116 }
117 } else {
118 ttr(TTrWarning, "no /mmi directory %d" NL, 0);
119 }
120 if ((error = ffs_stat("/mmi/pwr", &stat)) == EFFS_OK) {
121 if (stat.type != OT_DIR) {
122 ttr(TTrWarning, "/mmi/pwr exists but is not a directory %d" NL, 0);
123 }
124 } else {
125 ttr(TTrWarning, "no /mmi/pwr directory %d" NL, 0);
126 }
127
128 // Check calibration files:
129 // /pwr/vbat.cal MANDATORY
130 // NOT checked - it MUST be present - else we will have no Vbat measurements
131
132 // Check configuration files:
133 // /pwr/common.cfg MANDATORY
134 // /pwr/bat/bat<N>.cfg MANDATORY
135 // /pwr/bat/temp<N>.cfg OPTIONAL
136 // /pwr/chg/chg<N>.cfg OPTIONAL
137
138
139 // MANDATORY files
140 if ((error = ffs_stat("/pwr/common.cfg", &stat)) == EFFS_OK) {
141 if (stat.type != OT_FILE) {
142 ttr(TTrFatal, "/pwr/common.cfg exists but is not a file %d" NL, 0);
143 return EFFS_NOTADIR;
144 }
145 } else {
146 ttr(TTrFatal, "no /pwr/common.cfg file %d" NL, 0);
147 return error;
148 }
149
150 ttw(ttr(TTrInit, "pwr_check_files(%d)" NL, 0xFF));
151 return RV_OK;
152 }
153
154 // This function reads the FFS pwr configuration files
155 // /pwr/vbat.cal MANDATORY
156 // /mmi/pwr/bsie OPTIONAL
157 // /pwr/common.cfg MANDATORY
158 // /pwr/bat/bat<n>.cfg MANDATORY
159 // /pwr/bat/temp<n>.cfg MANDATORY
160 //
161 // Precondition: Files have been checked with pwr_check_files()
162 // Therefore we know they exist. Charger files are read later.
163 //
164
165 T_RVM_RETURN pwr_read_files()
166 {
167 T_FFS_SIZE error;
168 T_FFS_STAT stat;
169 char name[20];
170 uint8 i;
171 char cfg_id;
172
173 ttw(ttr(TTrInit, "pwr_read_files(%d)" NL, 0));
174
175
176 // Brute force of charger configuration ? /pwr/chg/force
177 if ((error = ffs_stat("/pwr/chg/force", &stat)) == EFFS_OK) {
178 error = ffs_fread("/pwr/chg/force", &pwr_cfg->data.cforce, 1);
179 ttw(ttr(TTrInitLow, "Read /pwr/chg/force(%d)" NL, error));
180 pwr_cfg->data.chg_cfg_id = pwr_cfg->data.cforce + '0';
181 pwr_ctrl->chg_cfg_id = pwr_cfg->data.cforce;
182 } else {
183 // Use 'normal' 'plug & play' configuration
184 pwr_cfg->data.cforce = 0;
185 pwr_cfg->data.chg_cfg_id = 1 + '0'; // Default
186 pwr_ctrl->chg_cfg_id = 1; // Default
187 }
188
189 // Brute force of battery configuration ? /pwr/bat/force
190 if ((error = ffs_stat("/pwr/bat/force", &stat)) == EFFS_OK) {
191 error = ffs_fread("/pwr/bat/force", &pwr_cfg->data.bforce, 1);
192 ttw(ttr(TTrInitLow, "Read /pwr/bat/force(%d)" NL, error));
193 pwr_ctrl->cfg_id = pwr_cfg->data.bforce;
194 pwr_cfg->data.cfg_id = pwr_cfg->data.bforce + '0';
195 } else {
196 // Use 'normal' 'plug & play' configuration
197 // Precondition: We have a reliable battery id measurement
198 pwr_cfg->data.bforce = 0;
199 ttw(ttr(TTrInitLow, "Plug & play bat_id=%d" NL, pwr_cfg->data.bat_id));
200 }
201
202 // Read /pwr/common.cfg
203 error = ffs_fread("/pwr/common.cfg", &pwr_cfg->common, PWR_COMMON_CFG_SIZE);
204 ttw(ttr(TTrInitLow, "Read /pwr/common.cfg(%d)" NL, error));
205
206 // Read /mmi/pwr/bsie
207 // Apply defaults if file doesn't exist
208 if ((error = ffs_stat("/mmi/pwr/bsie.cfg", &stat)) == EFFS_OK) {
209 if (stat.type != OT_FILE) {
210 ttr(TTrWarning, "/mmi/pwr/bsie.cfg exists but is not a file %d" NL, 0);
211 return EFFS_NOTAFILE;
212 } else {
213 error = ffs_fread("/mmi/pwr/bsie.cfg", &pwr_cfg->mmi, sizeof(pwr_cfg->mmi));
214 ttw(ttr(TTrInitLow, "Read /mmi/pwr/bsie.cfg(%d)" NL, error));
215 }
216 } else {
217 ttr(TTrWarning, "no /mmi/pwr/bsie file %d" NL, 0);
218 // Apply defaults
219 pwr_cfg->mmi.repetition = PWR_MMI_REP_THR;
220 }
221
222 if (pwr_cfg->data.bforce > 0) {
223 // Brute force battery configuration
224 build_name("/pwr/bat/bat", &pwr_cfg->data.cfg_id, 12, ".cfg", name);
225 error = ffs_fread(name, &pwr_cfg->bat, PWR_BAT_CFG_SIZE);
226 build_name("/pwr/bat/temp", &pwr_cfg->data.cfg_id, 13, ".cfg", name);
227 error = ffs_fread(name, &pwr_cfg->temp, PWR_TEMP_CFG_SIZE);
228 } else {
229 // Find out which <n> and read /pwr/bat/bat<n>.cfg
230 // We know that at least one battery configuration file exists
231 // Pick the file that matches the bat_id measured earlier
232
233 for (i = 1; i <= 5; i++) {
234 cfg_id = i + '0';
235 build_name("/pwr/bat/bat", &cfg_id, 12, ".cfg", name);
236 error = ffs_fread(name, &pwr_cfg->bat, PWR_BAT_CFG_SIZE);
237 // Found the right battery id??
238 if ((pwr_cfg->data.bat_id >= pwr_cfg->bat.id_low) &&
239 (pwr_cfg->data.bat_id <= pwr_cfg->bat.id_high)) {
240 ttw(ttr(TTrInitLow, "Chose %s" NL, name));
241 // Save the configuration number in the name
242 pwr_ctrl->cfg_id = i;
243 pwr_cfg->data.cfg_id = cfg_id;
244 pwr_ctrl->flag_bat_unknown = 0;
245
246 // Read the corresponding temperature configuration
247 build_name("/pwr/bat/temp", &pwr_cfg->data.cfg_id, 13, ".cfg", name);
248 error = ffs_fread(name, &pwr_cfg->temp, PWR_TEMP_CFG_SIZE);
249 break;
250 }
251 }
252
253 // Check if a matching battery configuration was found
254 if ((pwr_cfg->data.cfg_id < '1') || (pwr_cfg->data.cfg_id > '5')) {
255 pwr_cfg->data.cfg_id = '1';
256 pwr_ctrl->cfg_id = 1;
257 ttr(TTrWarning, "No matching battery configuration id - Defaults to %d" NL, pwr_ctrl->cfg_id);
258
259 // Flag that battery configuration was unknown
260 // Inform the MMI later when it has registered
261 pwr_ctrl->flag_bat_unknown = 1;
262 }
263 }
264
265 ttw(ttr(TTrInit, "pwr_read_files(%d)" NL, 0xFF));
266 return RV_OK;
267 }
268
269
270 // Read calibration files only
271 T_RVM_RETURN pwr_read_cal_files()
272 {
273 T_FFS_SIZE error;
274
275 // Read /pwr/vbat.cal
276 error = ffs_fread("/pwr/vbat.cal", &pwr_cfg->cal.vbat, sizeof(pwr_cfg->cal.vbat));
277 if ( error < EFFS_OK )
278 return RVM_INTERNAL_ERR;
279 ttw(ttr(TTrInitLow, "Read /pwr/vbat.cal(%d)" NL, error));
280 ttw(ttr(TTrInitLow, "pwr_cfg->cal.vbat.alfa_num=%d" NL, pwr_cfg->cal.vbat.alfa_num));
281 ttw(ttr(TTrInitLow, "pwr_cfg->cal.vbat.alfa_denom=%d" NL, pwr_cfg->cal.vbat.alfa_denom));
282 ttw(ttr(TTrInitLow, "pwr_cfg->cal.vbat.beta=%d" NL, pwr_cfg->cal.vbat.beta));
283 return RVM_OK;
284
285 }
286
287 // This function reads the FFS pwr configuration file
288 // It is invoked when a charger is plugged
289 // /pwr/chg/chg<n>.cfg MANDATORY
290 T_RVM_RETURN pwr_read_chg_files()
291 {
292 T_FFS_SIZE error;
293 char name[20];
294 uint8 i;
295 char chg_id;
296
297 ttw(ttr(TTrInit, "pwr_read_chg_files(%d)" NL, 0));
298
299 if (pwr_cfg->data.cforce > 0) {
300 // Brute force charger configuration
301 build_name("/pwr/chg/chg", &pwr_cfg->data.chg_cfg_id, 12, ".cfg", name);
302 error = ffs_fread(name, &pwr_cfg->chg, PWR_CHG_CFG_SIZE);
303 ttw(ttr(TTrInitLow,"error = %d" NL, error));
304
305 // Readout /pwr/chg/chg<N>.cfg
306 ttw(ttr(TTrInitLow,"chg.cfg: type: %d" NL, pwr_cfg->chg.type));
307 ttw(ttr(TTrInitLow,"ichg_max: %d" NL, pwr_cfg->chg.ichg_max));
308 ttw(ttr(TTrInitLow,"vchg_low: %d" NL, pwr_cfg->chg.vchg_low));
309 ttw(ttr(TTrInitLow,"vchg_high: %d" NL, pwr_cfg->chg.vchg_high));
310 } else {
311 // Find out which <n> and read /pwr/chg/chg<n>.cfg
312 // We know that at least one charger configuration file exists
313 // Pick the file that matches the chg_id measured earlier
314
315 for (i = 1; i <= 5; i++) {
316 chg_id = i + '0';
317 build_name("/pwr/chg/chg", &chg_id, 12, ".cfg", name);
318 error = ffs_fread(name, &pwr_cfg->chg, PWR_CHG_CFG_SIZE);
319 ttw(ttr(TTrInitLow,"error = %d" NL, error));
320
321 // Readout /pwr/chg/chg<N>.cfg
322 ttw(ttr(TTrInitLow,"chg.cfg: type: %d" NL, pwr_cfg->chg.type));
323 ttw(ttr(TTrInitLow,"ichg_max: %d" NL, pwr_cfg->chg.ichg_max));
324 ttw(ttr(TTrInitLow,"vchg_low: %d" NL, pwr_cfg->chg.vchg_low));
325 ttw(ttr(TTrInitLow,"vchg_high: %d" NL, pwr_cfg->chg.vchg_high));
326
327 // Found the right charger id??
328 if ((pwr_cfg->data.chg_id > pwr_cfg->chg.vchg_low) &&
329 (pwr_cfg->data.chg_id < pwr_cfg->chg.vchg_high)) {
330 ttw(ttr(TTrInitLow, "Chose %s" NL, name));
331 // Save the configuration number in the name
332 pwr_ctrl->chg_cfg_id = i;
333 pwr_cfg->data.chg_cfg_id = chg_id;
334 pwr_ctrl->flag_chg_unknown = 0;
335
336 break;
337 }
338 }
339
340 // Check if a matching charger configuration was found
341 if ((pwr_cfg->data.chg_cfg_id < '1') || (pwr_cfg->data.chg_cfg_id > '5')) {
342 pwr_cfg->data.chg_cfg_id = '1';
343 pwr_ctrl->chg_cfg_id = 1;
344 ttr(TTrWarning, "No matching charger configuration id - Defaults to %d" NL, pwr_ctrl->chg_cfg_id);
345
346 // Flag that charger configuration was unknown
347 // Inform the MMI later when it has registered
348 pwr_ctrl->flag_chg_unknown = 1;
349 }
350 }
351 ttw(ttr(TTrInit, "pwr_read_chg_files(%d)" NL, 0xFF));
352 }
353
354 void *pwr_malloc(int size)
355 {
356 void *addr;
357
358 if (rvf_get_buf(pwr_ctrl->prim_id, size, &addr) == RVF_RED) {
359 ttr(TTrFatal, "PWR FATAL: No Memory (%d)" NL, pwr_ctrl->state);
360 return NULL;
361 }
362
363 return addr;
364 }
365
366 void pwr_free(void *addr)
367 {
368 int error;
369
370 ttw(ttr(TTrEvent, "pwr_free (%d)" NL, 0));
371 if ((error = rvf_free_buf(addr)) != RV_OK) {
372 ttr(TTrFatal, "PWR FATAL: pwr_free (%d)" NL, error);
373 }
374 }
375
376
377 void pwr_task()
378 {
379 void *request;
380 struct pwr_req_s *pwr_request;
381 int error;
382
383 ttw(ttr(TTrEnv, "pwr_task(%d)" NL, 0));
384
385 while (1) {
386 rvf_wait(RVF_TASK_MBOX_0_EVT_MASK,0);
387 request = rvf_read_mbox(RVF_TASK_MBOX_0);
388 pwr_request = (struct pwr_req_s *)request;
389
390 if (request != NULL) {
391
392 ttw(ttr(TTrEvent, "Received Event(%d)" NL, pwr_request->header.msg_id));
393 ttw(ttr(TTrEventLow, "src_addr_id(%d)" NL, pwr_request->header.src_addr_id));
394 ttw(ttr(TTrEventLow, "dest_addr_id(%d)" NL, pwr_request->header.dest_addr_id));
395
396 switch (pwr_request->header.msg_id) {
397 case PWR_CHARGER_PLUGGED_IND:
398 // Sometimes (low voltage - init) receiving a ghost charger plug although interrupts are disabled
399 pwr_free(request);
400 break;
401 case PWR_CHARGER_UNPLUGGED_IND:
402 error = process_abb_chg_unplugged_ind(pwr_request);
403 break;
404 case PWR_ADC_IND :
405 error = process_spi_adc_indication(request);
406 break;
407
408 // Timers
409
410 case TIMER_T1_EXPIRED:
411 error = process_pwr_handle_T1_expiration(request);
412 break;
413 case TIMER_T2_EXPIRED:
414 error = process_pwr_handle_T2_expiration(request);
415 break;
416 case TIMER_T3_EXPIRED:
417 error = process_pwr_handle_T3_expiration(request);
418 break;
419 case TIMER_T4_EXPIRED:
420 error = process_pwr_handle_T4_expiration(request);
421 break;
422 case TIMER_MOD_CYCLE_EXPIRED:
423 error = process_pwr_handle_mod_cycle_expiration(request);
424 break;
425 case TIMER_MMI_INFO_EXPIRED:
426 error = process_pwr_handle_mmi_info_expiration(request);
427 break;
428 default :
429 {
430 ttr(TTrFatal, "PWR FATAL: Unknown Event: %d" NL, pwr_request->header.msg_id);
431 ttr(TTrFatal, " State: %d" NL, pwr_ctrl->state);
432 // Exception Handling - Unknown Event
433 }
434 }
435 } else {
436 // Exception Handling - NULL pointer
437 ttr(TTrFatal, "PWR FATAL: NULL pointer (%d)" NL, pwr_ctrl->state);
438 }
439 }
440 ttw(ttr(TTrEnv, "pwr_task(%d)" NL, 0xFF));
441 }
442