FreeCalypso > hg > fc-tourmaline
comparison src/cs/layer1/cfile/l1_pwmgr.c @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4e78acac3d88 |
---|---|
1 /************* Revision Controle System Header ************* | |
2 * GSM Layer 1 software | |
3 * L1_PWMGR.C | |
4 * | |
5 * Filename l1_pwmgr.c | |
6 * Copyright 2003 (C) Texas Instruments | |
7 * | |
8 ************* Revision Controle System Header *************/ | |
9 | |
10 #define L1_PWMGR_C | |
11 //#pragma DUPLICATE_FOR_INTERNAL_RAM_START | |
12 | |
13 #include "timer/timer2.h" | |
14 #include "armio/armio.h" | |
15 | |
16 //omaps00090550 #include "l1_macro.h" | |
17 #include "l1_confg.h" | |
18 | |
19 #if (OP_L1_STANDALONE == 1) | |
20 #include "uart/serialswitch_core.h" | |
21 #else | |
22 #include "uart/serialswitch.h" | |
23 #endif | |
24 | |
25 #if (OP_L1_STANDALONE == 0) | |
26 #include "sim/sim.h" | |
27 #include "rv_swe.h" | |
28 #endif | |
29 | |
30 | |
31 #if (CODE_VERSION == SIMULATION) | |
32 #include "l1_types.h" | |
33 #include "l1_const.h" | |
34 | |
35 #if (CHIPSET == 12) || (CHIPSET == 15) | |
36 #include "inth/sys_inth.h" | |
37 #include "sys_dma.h" | |
38 #include "ulpd.h" | |
39 #include "clkm.h" | |
40 | |
41 // typedef volatile unsigned short REG_UWORD16; //omaps00090550 | |
42 #define REG16(A) (*(REG_UWORD16*)(A)) | |
43 | |
44 #else | |
45 #include "inth/iq.h" | |
46 #endif | |
47 | |
48 #if TESTMODE | |
49 #include "l1tm_defty.h" | |
50 #endif // TESTMODE | |
51 | |
52 #if (AUDIO_TASK == 1) | |
53 #include "l1audio_const.h" | |
54 #include "l1audio_cust.h" | |
55 #include "l1audio_defty.h" | |
56 #endif // AUDIO_TASK | |
57 | |
58 #if (L1_GTT == 1) | |
59 #include "l1gtt_const.h" | |
60 #include "l1gtt_defty.h" | |
61 #endif | |
62 | |
63 #if (L1_MP3 == 1) | |
64 #include "l1mp3_defty.h" | |
65 #endif | |
66 | |
67 #if (L1_MIDI == 1) | |
68 #include "l1midi_defty.h" | |
69 #endif | |
70 //ADDED FOR AAC | |
71 #if (L1_AAC == 1) | |
72 #include "l1aac_defty.h" | |
73 #endif | |
74 #include "l1_defty.h" | |
75 #include "l1_varex.h" | |
76 #include "l1_tabs.h" | |
77 #include "cust_os.h" | |
78 #include "l1_msgty.h" | |
79 #include "l1_proto.h" | |
80 #include "ulpd.h" | |
81 #include "l1_trace.h" | |
82 | |
83 #if L1_GPRS | |
84 #include "l1p_cons.h" | |
85 #include "l1p_msgt.h" | |
86 #include "l1p_deft.h" | |
87 #include "l1p_vare.h" | |
88 #endif // L1_GPRS | |
89 | |
90 #include <stdio.h> | |
91 #include "sim_cfg.h" | |
92 #include "sim_cons.h" | |
93 #include "sim_def.h" | |
94 #include "sim_var.h" | |
95 //omaps00090550 | |
96 #include "nucleus.h" | |
97 | |
98 extern NU_TASK L1S_task; | |
99 STATUS status; | |
100 | |
101 | |
102 | |
103 #else // NO SIMULATION | |
104 | |
105 | |
106 | |
107 #include "l1_types.h" | |
108 #include "l1_const.h" | |
109 | |
110 #include "abb/abb.h" | |
111 #include "dma/sys_dma.h" | |
112 | |
113 #if (OP_BT == 1) | |
114 #include "hci_ll_simul.h" | |
115 #endif | |
116 | |
117 #if TESTMODE | |
118 #include "l1tm_defty.h" | |
119 #endif // TESTMODE | |
120 | |
121 #if (AUDIO_TASK == 1) | |
122 #include "l1audio_const.h" | |
123 #include "l1audio_cust.h" | |
124 #include "l1audio_defty.h" | |
125 #endif // AUDIO_TASK | |
126 | |
127 #if (L1_GTT == 1) | |
128 #include "l1gtt_const.h" | |
129 #include "l1gtt_defty.h" | |
130 #endif | |
131 | |
132 #if (L1_MP3 == 1) | |
133 #include "l1mp3_defty.h" | |
134 #endif | |
135 | |
136 #if (L1_MIDI == 1) | |
137 #include "l1midi_defty.h" | |
138 #endif | |
139 //ADDED FOR AAC | |
140 #if (L1_AAC == 1) | |
141 #include "l1aac_defty.h" | |
142 #endif | |
143 #include "l1_defty.h" | |
144 #include "l1_varex.h" | |
145 #include "l1_tabs.h" | |
146 #include "sys_types.h" | |
147 #include "tpudrv.h" | |
148 #include "cust_os.h" | |
149 #include "l1_msgty.h" | |
150 #include "l1_proto.h" | |
151 #include "l1_trace.h" | |
152 #include "timer/timer.h" | |
153 | |
154 #if (CHIPSET == 12) || (CHIPSET == 15) | |
155 #include "timer/timer_sec.h" | |
156 #include "inth/sys_inth.h" | |
157 | |
158 /* FreeCalypso: massive #if (CHIPSET == 15) chunk removed */ | |
159 | |
160 #else //(CHIPSET == 12) || (CHIPSET == 15) | |
161 #include "inth/iq.h" | |
162 #include "inth/inth.h" | |
163 #endif | |
164 // #include "timer1.h" | |
165 #include "ulpd/ulpd.h" | |
166 #include "clkm/clkm.h" | |
167 #include "memif/mem.h" | |
168 #if L2_L3_SIMUL | |
169 #include "hw_debug.h" | |
170 #endif | |
171 | |
172 #if (OP_WCP == 1) && (OP_L1_STANDALONE != 1) | |
173 #include "csmi/sleep.h" | |
174 #endif // OP_WCP | |
175 #if (W_A_CALYPSO_PLUS_SPR_19599 == 1) | |
176 #include "sys_memif.h" | |
177 #endif | |
178 | |
179 #if (GSM_IDLE_RAM != 0) | |
180 #if (OP_L1_STANDALONE == 1) | |
181 #include "csmi_simul.h" | |
182 #else | |
183 #include "csmi/csmi.h" | |
184 #endif | |
185 #endif | |
186 | |
187 #if (CHIPSET == 15) | |
188 #include "drp_api.h" | |
189 #endif | |
190 | |
191 #endif // NO SIMULATION | |
192 | |
193 #if (CODE_VERSION != SIMULATION) | |
194 // for PTOOL compatibility | |
195 extern void INT_DisableIRQ(void); | |
196 extern void INT_EnableIRQ(void); | |
197 extern void l1dmacro_RF_sleep(void); | |
198 extern void l1dmacro_RF_wakeup(void); | |
199 WORD32 l1s_get_HWTimers_ticks(void); | |
200 | |
201 // file timer1.h | |
202 SYS_UWORD16 Dtimer1_Get_cntlreg(void); | |
203 void Dtimer1_AR(unsigned short Ar); | |
204 void Dtimer1_PTV(unsigned short Ptv); | |
205 void Dtimer1_Clken(unsigned short En); | |
206 void Dtimer1_Start (unsigned short startStop); | |
207 void Dtimer1_Init_cntl (SYS_UWORD16 St, SYS_UWORD16 Reload, SYS_UWORD16 clockScale, SYS_UWORD16 clkon); | |
208 SYS_UWORD16 Dtimer1_WriteValue (SYS_UWORD16 value); | |
209 SYS_UWORD16 Dtimer1_ReadValue (void); | |
210 #endif | |
211 | |
212 void l1s_wakeup(void); | |
213 BOOL l1s_compute_wakeup_ticks(void); | |
214 void l1s_recover_Frame(void); | |
215 UWORD8 Cust_recover_Os(void); | |
216 void l1s_recover_HWTimers(void); | |
217 UWORD8 Cust_check_system(void); | |
218 void f_arm_sleep_cmd(UWORD8 d_sleep_mode); | |
219 | |
220 //#if (TRACE_TYPE == 2) || (TRACE_TYPE == 3) | |
221 extern void L1_trace_string(char *s); | |
222 extern void L1_trace_char (char s); | |
223 //#endif | |
224 extern UWORD16 slp_debug_flag; | |
225 | |
226 #if (GSM_IDLE_RAM != 0) | |
227 extern void l1s_trace_mftab(void); | |
228 #endif | |
229 | |
230 #if (CODE_VERSION != SIMULATION) && (CHIPSET == 15) | |
231 extern T_DRP_REGS_STR *drp_regs; | |
232 #endif | |
233 | |
234 #if L1_GPRS | |
235 WORD32 l1s_get_next_gauging_in_Packet_Idle(void); | |
236 #endif | |
237 //#pragma DUPLICATE_FOR_INTERNAL_RAM_END | |
238 | |
239 #if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0)) // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled | |
240 //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START // KEEP IN EXTERNAL MEM otherwise | |
241 | |
242 /************************************************************/ | |
243 /* Macros for power management */ | |
244 /************************************************************/ | |
245 #define MIN(min, operand1) \ | |
246 if (operand1 <= min) min = operand1; | |
247 | |
248 // ex: RATIO T32khz/T4.33Mhz = 132.2428385417 | |
249 // => root = integer part of the ratio | |
250 // = 132 | |
251 // => frac = fractionnal part of the ratio multiplied by 65536 rounded to make it integer | |
252 // = 0.2428385417 * 65536 (Cf. ULPD specification) | |
253 // = 0.2428385417 * 2^16 | |
254 // = 15914.66666689 = 15914 | |
255 | |
256 #define RATIO(HF,LF, root, frac) \ | |
257 root = (UWORD32)(HF/LF); \ | |
258 frac = (UWORD32)(((HF - (root*LF)) << 16) / LF); | |
259 | |
260 // previous ratio with frac + 0.5 | |
261 #if 0 /* original LoCosto code */ | |
262 #define RATIO2(HF,LF, root, frac) \ | |
263 if(LF){ \ | |
264 root = (UWORD32)(HF/LF); \ | |
265 frac = (UWORD32)((((HF - (root*LF)) << 16) + 0.5*LF) / LF);} | |
266 #else /* FreeCalypso TCS211 reconstruction */ | |
267 #define RATIO2(HF,LF, root, frac) \ | |
268 { \ | |
269 root = (UWORD32)(HF/LF); \ | |
270 frac = (UWORD32)((((HF - (root*LF)) << 16) + 0.5*LF) / LF);} | |
271 #endif | |
272 | |
273 #define HFTHEO(LF, root, frac, hftheo) \ | |
274 hftheo = root*LF + ((frac*LF) >>16); | |
275 | |
276 #define SUM(HF, LF, nb, ind) \ | |
277 LF=HF=0; \ | |
278 for(ind=0; ind<nb; ind++) \ | |
279 { \ | |
280 LF = LF +l1s.pw_mgr.histo[ind][0]; \ | |
281 HF = HF +l1s.pw_mgr.histo[ind][1]; \ | |
282 } | |
283 | |
284 | |
285 #if 0 /* FreeCalypso TCS211 reconstruction */ | |
286 T_PWMGR_DEBUG l1_pwmgr_debug; | |
287 #endif | |
288 | |
289 | |
290 /* FreeCalypso: massive #if (CHIPSET == 15) chunk removed */ | |
291 | |
292 | |
293 // l1ctl_pgm_clk32() | |
294 // convert ratio in 4.33Mhz and pgm INC_FRAC,INC_SIXTEEN. | |
295 | |
296 void l1ctl_pgm_clk32(UWORD32 nb_hf, UWORD32 nb_32khz) | |
297 { | |
298 #if (CODE_VERSION != SIMULATION) | |
299 if (l1_config.pwr_mngt == PWR_MNGT) | |
300 { | |
301 UWORD32 inc_sixteen= 0, inc_frac=0, lf; | |
302 | |
303 // REM: nb_hf is the real value of the high frequency (ex in nbr of 65Mhz clock) | |
304 // To compute the ratio, nb_hf must be expressed in nbr of clock 4.33 Mhz | |
305 // that's why nb_hf is divided by 3*l1_config.dpll | |
306 // RATIO2(nb_hf/(3*l1_config.dpll),nb_32khz,inc_sixteen,inc_frac); | |
307 // this line above is equal to the ligne below: | |
308 lf=(UWORD32)(3*l1_config.dpll*nb_32khz); | |
309 RATIO2(nb_hf,lf,inc_sixteen,inc_frac); | |
310 | |
311 // integer part | |
312 ULDP_INCSIXTEEN_UPDATE(inc_sixteen); | |
313 | |
314 // fractional part | |
315 ULDP_INCFRAC_UPDATE(inc_frac); | |
316 } | |
317 #endif | |
318 } | |
319 | |
320 | |
321 // l1ctl_gauging() | |
322 // Description: management of the gauging results | |
323 // At RESET state reset histogram and then go to INIT. | |
324 // At INIT state, go back to RESET on each */ | |
325 // gauging > +- 100 ppm. If NB_INIT good gauging go to ACQUIS state. | |
326 // At ACQUIS state, go back to RESET on each gauging > (+- 20ppm +- 1us). If NB_ACQU good gauging */ | |
327 // go to UPDATE state. Allow deep sleep feature. | |
328 // At UPDATE state, count consecutive gauging >+- 1 us. | |
329 // If MAX_BAD_GAUGING results go back to RESET. | |
330 // Otherwise re-enable deep sleep feature and reset bad results counter. | |
331 | |
332 void l1ctl_gauging ( UWORD32 nb_32khz, UWORD32 nb_hf) | |
333 { | |
334 if (l1_config.pwr_mngt == PWR_MNGT) | |
335 { | |
336 enum states | |
337 { | |
338 RESET = 0, | |
339 INIT = 1, | |
340 ACQUIS = 2, | |
341 UPDATE = 3 | |
342 }; | |
343 | |
344 static UWORD8 bad_count; // bad gauging values | |
345 static UWORD8 gauging_state= RESET; // RESET,INIT, ACQUIS, UPDATE | |
346 static UWORD8 nb_gaug; // number of gauging in ACQUIS | |
347 static UWORD8 idx,i; // index | |
348 static UWORD32 root, frac; // ratio of HF and LF average | |
349 UWORD32 sumLF, sumHF; // sum of HF and LF counts | |
350 double nbHF_theo; | |
351 | |
352 | |
353 // AFC or TEMPERATURE variation | |
354 | |
355 //if ( (ABS( (WORD32)(l1s.pw_mgr.previous_afc-l1s.afc) ) > AFC_VARIATION) || | |
356 // (ABS( (WORD32)(l1s.pw_mgr.previous_temp-l1s.afc) > TEMP_VARIATION) ) | |
357 // gauging_state = RESET; | |
358 | |
359 // reset state machine if not in IDLE mode | |
360 #if L1_GPRS | |
361 if ((l1a_l1s_com.l1s_en_task[NP] != TASK_ENABLED) && (l1a_l1s_com.l1s_en_task[PNP] != TASK_ENABLED)) | |
362 gauging_state = RESET; | |
363 #else | |
364 if ((l1a_l1s_com.l1s_en_task[NP] != TASK_ENABLED) ) | |
365 gauging_state = RESET; | |
366 | |
367 #endif | |
368 | |
369 switch (gauging_state) | |
370 { | |
371 | |
372 case RESET: | |
373 { | |
374 UWORD8 i; | |
375 | |
376 // Reset Histogram | |
377 for (i=0; i < SIZE_HIST; i++) | |
378 { | |
379 l1s.pw_mgr.histo[i][0] = 0; | |
380 l1s.pw_mgr.histo[i][1] = 0; | |
381 } | |
382 idx = 0; | |
383 l1s.pw_mgr.enough_gaug= FALSE; // forbid Deep sleep | |
384 gauging_state = INIT; | |
385 nb_gaug = NB_INIT; // counter for ACQUIS state | |
386 bad_count = 0; // reset count of BAD gauging | |
387 | |
388 #if (TRACE_TYPE != 0) | |
389 l1_trace_gauging_reset(); | |
390 #endif | |
391 } | |
392 | |
393 | |
394 case INIT: | |
395 { | |
396 | |
397 // Acquire NB_INIT gauging wtw +- 100 ppm | |
398 | |
399 if (l1a_l1s_com.mode != I_MODE) return; | |
400 | |
401 // compute clocks ratio from measurements. | |
402 RATIO(nb_hf,nb_32khz,root,frac) | |
403 | |
404 | |
405 // allow [-500ppm,+100ppm] derive on 32Khz at startup. | |
406 #if 0 /* really old code, apparently */ | |
407 if ( | |
408 (root > l1s.pw_mgr.c_clk_min || | |
409 (root == l1s.pw_mgr.c_clk_min && | |
410 frac >= l1s.pw_mgr.c_clk_init_min) ) && | |
411 (root < l1s.pw_mgr.c_clk_max || | |
412 (root == l1s.pw_mgr.c_clk_max && | |
413 frac <= l1s.pw_mgr.c_clk_init_max ) ) | |
414 #elif 1 /* TCS211 reconstruction */ | |
415 if ( | |
416 (root == l1s.pw_mgr.c_clk_min && | |
417 frac >= l1s.pw_mgr.c_clk_init_min ) || | |
418 (root == l1s.pw_mgr.c_clk_max && | |
419 frac <= l1s.pw_mgr.c_clk_init_max ) | |
420 #else /* LoCosto code */ | |
421 if ( | |
422 ( l1s.pw_mgr.c_clk_min == l1s.pw_mgr.c_clk_max && | |
423 frac >= l1s.pw_mgr.c_clk_init_min && | |
424 frac <= l1s.pw_mgr.c_clk_init_max ) | |
425 || | |
426 ( l1s.pw_mgr.c_clk_min != l1s.pw_mgr.c_clk_max && | |
427 ( (root == l1s.pw_mgr.c_clk_min && | |
428 frac >= l1s.pw_mgr.c_clk_init_min ) || | |
429 (root > l1s.pw_mgr.c_clk_min && | |
430 root < l1s.pw_mgr.c_clk_max ) || | |
431 (root == l1s.pw_mgr.c_clk_max && | |
432 frac <= l1s.pw_mgr.c_clk_init_max ) ) ) | |
433 #endif | |
434 ) | |
435 { | |
436 l1s.pw_mgr.histo[idx ][0] = nb_32khz; // init histo with the number of 32kHz | |
437 l1s.pw_mgr.histo[idx++][1] = nb_hf; // init histo with the number of hf (13Mhz) | |
438 | |
439 #if (CODE_VERSION == SIMULATION) | |
440 #if (TRACE_TYPE==5) | |
441 trace_ULPD("Gauging INIT Case ", l1s.actual_time.fn); | |
442 #endif | |
443 #endif | |
444 | |
445 } | |
446 else | |
447 { | |
448 // out of the allowed derive -> reset | |
449 idx=0; | |
450 #if (TRACE_TYPE != 0) | |
451 l1_trace_gauging_reset(); | |
452 #endif | |
453 } | |
454 | |
455 if (idx == NB_INIT) | |
456 { | |
457 // enough measurement -> ACQUIS state | |
458 gauging_state = ACQUIS; | |
459 // compute clk ratio on count average | |
460 SUM(sumHF,sumLF, NB_INIT,i) // returns sumHF and sumLF | |
461 RATIO(sumHF,sumLF,root, frac) // returns root and frac*2E16, computed on the average | |
462 } | |
463 } | |
464 break; | |
465 | |
466 | |
467 case ACQUIS: | |
468 { | |
469 // Acquire NB_ACQU gauging at +-25ppm | |
470 // with jitter +- 1 us | |
471 UWORD8 n; | |
472 | |
473 // from nb_32khz "measured" | |
474 // compute nbHF_theo | |
475 HFTHEO(nb_32khz,root,frac,nbHF_theo) | |
476 | |
477 if ( (nb_hf >= (nbHF_theo - l1s.pw_mgr.c_delta_hf_acquis)) && | |
478 (nb_hf <= (nbHF_theo + l1s.pw_mgr.c_delta_hf_acquis)) ) | |
479 { | |
480 l1s.pw_mgr.histo[idx][0] = nb_32khz; | |
481 l1s.pw_mgr.histo[idx++][1] = nb_hf; | |
482 idx = idx % SIZE_HIST; | |
483 | |
484 // compute clk ratio on count average | |
485 if(++nb_gaug >= SIZE_HIST) n=SIZE_HIST; | |
486 else n= nb_gaug; | |
487 SUM(sumHF,sumLF, n,i) | |
488 RATIO(sumHF,sumLF,root, frac) | |
489 | |
490 #if (CODE_VERSION == SIMULATION) | |
491 #if (TRACE_TYPE==5) | |
492 trace_ULPD("Gauging ACQUIS Case ", l1s.actual_time.fn); | |
493 #endif | |
494 #endif | |
495 | |
496 if ( nb_gaug == (NB_INIT+NB_ACQU)) // NB_ACQU good gauging | |
497 { | |
498 gauging_state = UPDATE; // UPDATE state | |
499 l1s.pw_mgr.enough_gaug = TRUE; // allow Deep sleep | |
500 l1ctl_pgm_clk32(sumHF,sumLF); // clocks ratio in 4.33Mhz | |
501 } | |
502 } | |
503 else | |
504 { | |
505 gauging_state = RESET; | |
506 } | |
507 } | |
508 break; | |
509 | |
510 case UPDATE: | |
511 { | |
512 | |
513 // Update gauging histogram | |
514 // compute nbHF theoric for ratio_avg | |
515 HFTHEO(nb_32khz,root,frac,nbHF_theo) | |
516 | |
517 if ( (nb_hf >= (nbHF_theo-l1s.pw_mgr.c_delta_hf_update)) && | |
518 (nb_hf <= (nbHF_theo+l1s.pw_mgr.c_delta_hf_update)) ) | |
519 { | |
520 l1s.pw_mgr.histo[idx][0] = nb_32khz; | |
521 l1s.pw_mgr.histo[idx++][1] = nb_hf; | |
522 | |
523 // compute clk ratio on count average | |
524 SUM(sumHF,sumLF, SIZE_HIST,i) | |
525 l1ctl_pgm_clk32(sumHF,sumLF); // clocks ratio in 4.33Mhz | |
526 | |
527 l1s.pw_mgr.enough_gaug = TRUE; // allow Deep sleep | |
528 bad_count = 0; // reset count of BAD gauging | |
529 | |
530 #if (CODE_VERSION == SIMULATION) | |
531 #if (TRACE_TYPE==5) | |
532 trace_ULPD("Gauging UPDATE Case ", l1s.actual_time.fn); | |
533 #endif | |
534 #endif | |
535 | |
536 } | |
537 else | |
538 { | |
539 bad_count ++; | |
540 if (bad_count >= MAX_BAD_GAUGING) gauging_state = RESET; | |
541 l1s.pw_mgr.enough_gaug= FALSE; // forbid Deep sleep | |
542 } | |
543 idx = idx % SIZE_HIST; | |
544 } | |
545 break; | |
546 } | |
547 #if (TRACE_TYPE != 0) // Trace gauging | |
548 // save parameters in the corresponding structure | |
549 l1s.pw_mgr.state = gauging_state; | |
550 l1s.pw_mgr.lf = nb_32khz ; | |
551 // WARNING WARNING, this case gauging_state == UPDATE modify the algo. | |
552 // In case of trace the parameter root and frac are refresh. | |
553 // it is not the case if no trace and it seems there is mistake | |
554 #if 0 /* FreeCalypso TCS211 reconstruction */ | |
555 if (gauging_state == UPDATE) | |
556 { | |
557 RATIO2(sumHF,sumLF,root,frac); | |
558 } | |
559 #endif | |
560 //End of Warning. | |
561 l1s.pw_mgr.hf = nb_hf ; | |
562 l1s.pw_mgr.root = root ; | |
563 l1s.pw_mgr.frac = frac ; | |
564 #endif // End Trace gauging | |
565 } | |
566 } | |
567 | |
568 | |
569 /* GAUGING_Handler() */ | |
570 /* Description: update increment counter for 32Khz */ | |
571 /* This interrupt function computes the ratio between */ | |
572 /* HF/32Khz gauging counters and program ULPD increment */ | |
573 /* values. */ | |
574 | |
575 void GAUGING_Handler(void) | |
576 { | |
577 #if (CODE_VERSION != SIMULATION) | |
578 if (l1_config.pwr_mngt == PWR_MNGT) | |
579 { | |
580 UWORD32 nb_32khz, nb_hf; | |
581 | |
582 // Gauging task is ended | |
583 l1s.pw_mgr.gauging_task = INACTIVE; | |
584 #if (CHIPSET == 12) || (CHIPSET == 15) | |
585 F_INTH_DISABLE_ONE_IT(C_INTH_ULPD_GAUGING_IT); // Mask ULPD GAUGING int. | |
586 #else | |
587 INTH_DISABLEONEIT(IQ_ULPD_GAUGING); // Mask ULPD GAUGING int. | |
588 #endif | |
589 | |
590 // Number of 32 Khz clock at the end of the gauging | |
591 nb_32khz = ((*( UWORD16 *)ULDP_COUNTER_32_MSB_REG) * 65536) + | |
592 (*( UWORD16 *)ULDP_COUNTER_32_LSB_REG); | |
593 | |
594 // Number of high frequency clock at the end of the gauging | |
595 // Convert it in nbr of 13 Mhz clocks (5*13=65Mhz) | |
596 nb_hf = ( ((*( UWORD16 *)ULDP_COUNTER_HI_FREQ_MSB_REG) * 65536) + | |
597 (*( UWORD16 *)ULDP_COUNTER_HI_FREQ_LSB_REG) ); // Divide by PLL ratio | |
598 | |
599 l1ctl_gauging(nb_32khz, nb_hf); | |
600 } | |
601 #else //Simulation part | |
602 | |
603 // Gauging task is ended | |
604 l1s.pw_mgr.gauging_task = INACTIVE; | |
605 | |
606 l1ctl_gauging(DEFAULT_32KHZ_VALUE,DEFAULT_HFMHZ_VALUE); | |
607 #endif | |
608 } | |
609 | |
610 | |
611 // l1s_get_HWTimers_ticks() | |
612 // Description: | |
613 // evaluate the loading of the HW Timers for dep sleep | |
614 // BIG SLEEP: timers CLK may be stopped (user dependant) | |
615 // DEEP SLEEP:timers CLK and WTCHDOG CLK are stopped | |
616 // CLKS are enabled after VTCX0+SLICER+13MHZ | |
617 // setup time | |
618 | |
619 WORD32 l1s_get_HWTimers_ticks(void) | |
620 { | |
621 #if (CODE_VERSION != SIMULATION) | |
622 WORD32 timer1,timer2,watchdog,HWTimer; | |
623 #if (CHIPSET == 12) || (CHIPSET == 15) | |
624 WORD32 watchdog_sec; | |
625 #endif | |
626 UWORD16 cntlreg; | |
627 UWORD16 modereg; | |
628 WORD32 old = 0; | |
629 | |
630 // read Hercules Timers & Watchdog | |
631 //================================================= | |
632 // Tint = Tclk * (LOAD_TIM+1) * 2^(PTV+1) | |
633 // Tclk = 1.2308us for Fclk=13Mhz | |
634 // PTV = X (pre-scaler field) | |
635 //------------------------------------------------- | |
636 timer1 = timer2 = watchdog = HWTimer = -1; | |
637 #if (CHIPSET == 12) || (CHIPSET == 15) | |
638 watchdog_sec = -1; | |
639 #endif | |
640 | |
641 cntlreg = Dtimer1_Get_cntlreg(); // AND 0x1F | |
642 if ( (cntlreg & D_TIMER_RUN) == D_TIMER_RUN) | |
643 { | |
644 #if 0 /* match TCS211 object */ | |
645 cntlreg = cntlreg&0x1F; | |
646 #endif | |
647 cntlreg >>= 2; // take PTV | |
648 cntlreg = 1 << (cntlreg+1); | |
649 timer1 = (WORD32) ( ((Dtimer1_ReadValue()+1) * cntlreg * 0.0012308) / 4.615 ); | |
650 if (timer1 <= MIN_SLEEP_TIME) return(0); | |
651 old = Dtimer1_ReadValue(); | |
652 HWTimer = timer1; | |
653 } | |
654 | |
655 cntlreg = Dtimer2_Get_cntlreg(); | |
656 if ( (cntlreg & D_TIMER_RUN) == D_TIMER_RUN) | |
657 { | |
658 #if 0 /* match TCS211 object */ | |
659 cntlreg = cntlreg&0x1F; | |
660 #endif | |
661 cntlreg >>= 2; // take PTV | |
662 cntlreg = 1 << (cntlreg+1); | |
663 timer2 = (WORD32) ( ((Dtimer2_ReadValue()+1) * cntlreg * 0.0012308) / 4.615 ); | |
664 if (timer2 <= MIN_SLEEP_TIME) return(0); | |
665 if (HWTimer == -1) HWTimer = timer2; | |
666 else MIN(HWTimer,timer2) | |
667 } | |
668 | |
669 cntlreg = TIMER_Read(0); // AND 0x0f80 | |
670 modereg = TIMER_Read(2); | |
671 | |
672 if ( (cntlreg & TIMER_ST) || (modereg & TIMER_WDOG)) | |
673 { | |
674 // in watchdog mode PTV is forced to 7 | |
675 if ( modereg & TIMER_WDOG ) | |
676 cntlreg |= TIMER_PTV; | |
677 | |
678 cntlreg = (cntlreg & TIMER_PTV) >> 9; // take PTV | |
679 cntlreg = 1 << (cntlreg+1); | |
680 watchdog = (WORD32) ( ((TIMER_ReadValue()+1) * cntlreg * 0.001078) / 4.615 ); | |
681 if (watchdog <= MIN_SLEEP_TIME) return(0); | |
682 if (HWTimer == -1) HWTimer = watchdog; | |
683 else MIN(HWTimer,watchdog) | |
684 } | |
685 | |
686 #if (CHIPSET == 12) || (CHIPSET == 15) | |
687 /* | |
688 * Secure Watchdog Timer management | |
689 */ | |
690 cntlreg = TIMER_SEC_Read(0); // AND 0x0f80 | |
691 modereg = TIMER_SEC_Read(2); | |
692 if ( (cntlreg & TIMER_ST) || (modereg & TIMER_WDOG)) | |
693 { | |
694 // in watchdog mode PTV is forced to 7 | |
695 if ( modereg & TIMER_WDOG ) | |
696 cntlreg |= TIMER_PTV; | |
697 | |
698 cntlreg = (cntlreg & TIMER_PTV) >> 9; // take PTV | |
699 cntlreg = 1 << (cntlreg+1); | |
700 watchdog_sec = (WORD32) ( ((TIMER_SEC_ReadValue()+1) * cntlreg * 0.001078) / 4.615 ); | |
701 if (watchdog_sec <= MIN_SLEEP_TIME) return(0); | |
702 if (HWTimer == -1) HWTimer = watchdog_sec; | |
703 else MIN(HWTimer,watchdog_sec) | |
704 } | |
705 | |
706 #endif | |
707 | |
708 return (HWTimer); | |
709 #else // simulation part | |
710 return (-1); // no HW timer in simulation | |
711 #endif | |
712 } | |
713 | |
714 #if (GSM_IDLE_RAM != 0) // Compile only if GSM_IDLE_RAM enabled | |
715 | |
716 void l1s_adapt_traffic_controller(void) | |
717 { | |
718 BOOL l1s_extram; | |
719 UWORD8 nb_bitmap; | |
720 T_L1S_GSM_IDLE_INTRAM * gsm_idle_ram_ctl; | |
721 | |
722 gsm_idle_ram_ctl = &(l1s.gsm_idle_ram_ctl); | |
723 | |
724 l1s_extram = FALSE; | |
725 | |
726 for(nb_bitmap=0; ((nb_bitmap < SIZE_TAB_L1S_MONITOR) && (l1s_extram == FALSE)); nb_bitmap++) | |
727 { | |
728 if (nb_bitmap == 1) | |
729 { | |
730 l1s_extram |= (((INT_RAM_GSM_IDLE_L1S_PROCESSES1 ^ gsm_idle_ram_ctl->task_bitmap_idle_ram[nb_bitmap]) & gsm_idle_ram_ctl->task_bitmap_idle_ram[nb_bitmap]) != 0); | |
731 }else | |
732 { | |
733 l1s_extram |= (gsm_idle_ram_ctl->task_bitmap_idle_ram[nb_bitmap] != 0); | |
734 } | |
735 } | |
736 | |
737 if ((l1s_extram != FALSE) && (!READ_TRAFFIC_CONT_STATE)) | |
738 { | |
739 CSMI_TrafficControllerOn(); | |
740 #if (TRACE_TYPE==1) || (TRACE_TYPE==4) | |
741 { | |
742 l1s_trace_mftab(); | |
743 } | |
744 #endif | |
745 } | |
746 } | |
747 #endif | |
748 | |
749 UWORD32 last_wakeup = 0; | |
750 UWORD8 wakeup_type; // Type of the interrupt | |
751 UWORD8 why_big_sleep; // Type of the big sleep | |
752 | |
753 extern UWORD16 int_id; | |
754 | |
755 // l1s_sleep_manager() | |
756 // Description: | |
757 // evaluate the loading of the system | |
758 // - SIM, UART, LCD .... | |
759 // - Nucleus tasks, Hisrs, timers | |
760 // - Timer1, Timer2, Watchdog | |
761 // program Big or Deep sleep | |
762 | |
763 void l1s_sleep_manager() | |
764 { | |
765 //UWORD8 temp=0; OMAPS00090550 | |
766 | |
767 UWORD16 temp_clear_intr; | |
768 | |
769 // fn when l1s_sleep_manager function is called | |
770 #if (CODE_VERSION != SIMULATION) | |
771 UWORD32 sleep_time = l1s.actual_time.fn_mod42432; | |
772 #else | |
773 UWORD32 sleep_time = l1s.actual_time.fn; | |
774 #endif | |
775 | |
776 if (l1_config.pwr_mngt == PWR_MNGT) | |
777 { | |
778 // Power management is enabled | |
779 WORD32 min_time, HWtimer,wake_up_time,min_time_gauging; | |
780 WORD32 afc_fix; | |
781 static UWORD32 previous_sleep = CLOCK_STOP; | |
782 #if (W_A_CALYPSO_PLUS_SPR_19599 == 1) | |
783 BOOL extended_page_mode_state = 0; //Store state of extended page mode | |
784 #endif | |
785 WORD32 time_from_last_wakeup, min_time_from_last_wakeup; | |
786 UWORD32 sleep_mode; | |
787 | |
788 #if (OP_BT == 1) | |
789 WORD32 hci_ll_status; | |
790 #endif | |
791 | |
792 // init for trace and debug | |
793 why_big_sleep = BIG_SLEEP_DUE_TO_UNDEFINED; | |
794 wakeup_type = WAKEUP_FOR_UNDEFINED; | |
795 | |
796 /* | |
797 * FreeCalypso change: TI's original code implemented logic to | |
798 * suppress both big and deep sleep (i.e., retry on the next frame) | |
799 * if less than 7 frames have elapsed since the last wakeup and | |
800 * if the previous sleep cycle was CLOCK_STOP. We are changing | |
801 * this logic in two ways: the check has been moved up here | |
802 * (originally the check code was way down, wasting work on other | |
803 * logic if there will be no sleep anyway), and we additionally | |
804 * suppress both big and deep sleep (effecting retry on the next | |
805 * frame) if the previous sleep cycle was FRAME_STOP and less than | |
806 * 5 frames have elapsed since wakeup. The reason for the latter | |
807 * addition is that we now allow big sleep while UART and/or SIM | |
808 * activity timers are running (suppressing deep sleep), and | |
809 * holding off for 5 frames before going into another big sleep | |
810 * keeps us from fluttering in and out of big sleep as the external | |
811 * host or the SIM is trying to talk to us. | |
812 */ | |
813 time_from_last_wakeup = (sleep_time - last_wakeup + 42432) % 42432; | |
814 | |
815 if (previous_sleep == CLOCK_STOP) | |
816 min_time_from_last_wakeup = 7; | |
817 else | |
818 min_time_from_last_wakeup = 5; | |
819 | |
820 if (time_from_last_wakeup < min_time_from_last_wakeup) | |
821 return; | |
822 | |
823 //================================================= | |
824 // check System (SIM, UART, LDC ..... ) | |
825 //================================================= | |
826 sleep_mode = Cust_check_system(); | |
827 | |
828 if (sleep_mode == DO_NOT_SLEEP) | |
829 return; | |
830 | |
831 #if (CODE_VERSION != SIMULATION) | |
832 //================================================= | |
833 // Protect System structures | |
834 // must be called BEFORE INT_DisableIRQ() while | |
835 // Nucleus does not restore IRQ/FIQ bits !!!! | |
836 //================================================= | |
837 OS_system_protect(); | |
838 //================================================= | |
839 // Disable IRQ | |
840 //================================================= | |
841 INT_DisableIRQ(); | |
842 #endif // NOT SIMULATION | |
843 | |
844 //================================================= | |
845 // check OS loading | |
846 //================================================= | |
847 min_time = OS_get_inactivity_ticks(); | |
848 | |
849 //================================================= | |
850 // check HW Timers loading | |
851 //================================================= | |
852 HWtimer= l1s_get_HWTimers_ticks(); | |
853 | |
854 //================================================= | |
855 // check next gauging task for Packet Idle | |
856 //================================================= | |
857 #if L1_GPRS | |
858 min_time_gauging = l1s_get_next_gauging_in_Packet_Idle(); | |
859 #else | |
860 min_time_gauging = -1; // not used | |
861 #endif | |
862 | |
863 #if (OP_BT == 1) | |
864 hci_ll_status = hci_ll_ok_for_sleep(); | |
865 #endif | |
866 // check if immediate activity planned | |
867 // 0 means immediate activity | |
868 // in case big sleep is choosen (sleep mode == FRAME_STOP) because of UART or SIM, | |
869 // return and wait end of this activity (few TDMA frames) then check on next TDMA frames | |
870 // if MS can go in deep sleep | |
871 /* | |
872 * FreeCalypso change: we no longer abstain from big sleep because of UART | |
873 * and SIM activity timers, i.e., when deep sleep is suppressed because of | |
874 * either of those, we go into big sleep instead. We also do big sleep | |
875 * if deep sleep is disallowed because of the backlight or charging. | |
876 * However, if the UART issue is not the running activity timer, but some | |
877 * output being drained from the Tx FIFO, for that case our new code in | |
878 * Cust_check_system() will return DO_NOT_SLEEP (checked above), causing | |
879 * us to retry on the next frame and hopefully go into deep sleep after | |
880 * another frame or two. | |
881 */ | |
882 if ( !min_time | |
883 || !HWtimer | |
884 || !min_time_gauging | |
885 #if 0 /* FreeCalypso change */ | |
886 || (sleep_mode != CLOCK_STOP) | |
887 #endif | |
888 #if (OP_BT == 1) | |
889 || !hci_ll_status | |
890 #endif | |
891 ) | |
892 { | |
893 | |
894 | |
895 #if (CODE_VERSION != SIMULATION) | |
896 OS_system_Unprotect(); | |
897 // free System structure | |
898 // Enable all IRQ | |
899 INT_EnableIRQ(); | |
900 // Wake up UART | |
901 | |
902 SER_WakeUpUarts(); // Wake up Uarts | |
903 | |
904 #endif | |
905 return; | |
906 } | |
907 //================================================= | |
908 // Select sleep duration .... | |
909 //================================================= | |
910 // remember: -1 means no activity planned | |
911 //l1a_l1s_com.time_to_next_l1s_task is UW32, min_time is W32. Max value of l1a_l1s_com.time_to_next_l1s_task will be 2p31 | |
912 //and ,min_time max value will be 2p30. If min_time > l1a_l1s_com.time_to_next_l1s_task, | |
913 //means MSB of l1a_l1s_com.time_to_next_l1s_task is zero. so, we can use- uw32_store_next_time & 0x7FFFFFFF | |
914 | |
915 if (min_time == -1) min_time = l1a_l1s_com.time_to_next_l1s_task; | |
916 else MIN(min_time, l1a_l1s_com.time_to_next_l1s_task) | |
917 if (HWtimer != -1) MIN(min_time, HWtimer) | |
918 if (min_time_gauging != -1) MIN(min_time, min_time_gauging) | |
919 | |
920 #if (TRACE_TYPE !=0 ) && (TRACE_TYPE != 2) && (TRACE_TYPE != 3) | |
921 // to trace the Wake up source | |
922 // depending of min_time choose the wakeup_type | |
923 wakeup_type = WAKEUP_FOR_OS_TASK; | |
924 if (min_time == l1a_l1s_com.time_to_next_l1s_task) wakeup_type = WAKEUP_FOR_L1_TASK; | |
925 if (min_time == HWtimer) wakeup_type = WAKEUP_FOR_HW_TIMER_TASK; | |
926 if (min_time == min_time_gauging) wakeup_type = WAKEUP_FOR_GAUGING_TASK; | |
927 #endif | |
928 | |
929 //================================================= | |
930 // Choose DEEP or BIG SLEEP | |
931 //================================================= | |
932 if ( ((l1s.pw_mgr.mode_authorized == DEEP_SLEEP) && (sleep_mode == CLOCK_STOP)) || | |
933 ((l1s.pw_mgr.mode_authorized == ALL_SLEEP) && (sleep_mode == CLOCK_STOP)) ) | |
934 { | |
935 // Check now gauging histogramme or if in inactive period of cell selection | |
936 #if (W_A_DSP_IDLE3 == 1) && (CODE_VERSION!=SIMULATION) | |
937 if (((l1s.pw_mgr.enough_gaug == TRUE) || (l1a_l1s_com.mode == CS_MODE0)) && | |
938 ( l1s_dsp_com.dsp_ndb_ptr->d_dsp_state == C_DSP_IDLE3)) | |
939 #else | |
940 #if (CHIPSET == 12) || (CHIPSET == 15) | |
941 if (((l1s.pw_mgr.enough_gaug == TRUE) || (l1a_l1s_com.mode == CS_MODE0)) && | |
942 !CLKM_READ_nIDLE3) | |
943 #else | |
944 if ((l1s.pw_mgr.enough_gaug == TRUE) || (l1a_l1s_com.mode == CS_MODE0)) | |
945 #endif | |
946 #endif | |
947 l1s.pw_mgr.sleep_performed = CLOCK_STOP; | |
948 else | |
949 { | |
950 // BIG SLEEP is chosen : check the reason | |
951 l1s.pw_mgr.sleep_performed = FRAME_STOP; | |
952 if (l1s.pw_mgr.enough_gaug != TRUE) | |
953 why_big_sleep = BIG_SLEEP_DUE_TO_GAUGING; | |
954 else | |
955 why_big_sleep = BIG_SLEEP_DUE_TO_DSP_TRACES; | |
956 } | |
957 } | |
958 if (l1s.pw_mgr.mode_authorized == BIG_SLEEP || | |
959 l1s.pw_mgr.mode_authorized == BIG_SMALL_SLEEP) | |
960 why_big_sleep = BIG_SLEEP_DUE_TO_SLEEP_MODE; | |
961 | |
962 if ( ((l1s.pw_mgr.mode_authorized == BIG_SLEEP) && (sleep_mode >= FRAME_STOP)) || | |
963 ((l1s.pw_mgr.mode_authorized == BIG_SMALL_SLEEP) && (sleep_mode >= FRAME_STOP)) || | |
964 ((l1s.pw_mgr.mode_authorized >= DEEP_SLEEP) && (sleep_mode == FRAME_STOP)) ) | |
965 l1s.pw_mgr.sleep_performed = FRAME_STOP; | |
966 | |
967 | |
968 /* FreeCalypso change: check moved up and extended */ | |
969 #if 0 | |
970 if ((previous_sleep == CLOCK_STOP) && (time_from_last_wakeup < 7)) | |
971 { | |
972 #if (CODE_VERSION != SIMULATION) | |
973 OS_system_Unprotect(); // free System structure | |
974 INT_EnableIRQ(); // Enable all IRQ | |
975 | |
976 SER_WakeUpUarts(); // Wake up Uarts | |
977 | |
978 #endif // NOT SIMULATION | |
979 return; | |
980 } | |
981 #endif | |
982 | |
983 // update previous sleep | |
984 previous_sleep = l1s.pw_mgr.sleep_performed; | |
985 | |
986 | |
987 #if (CODE_VERSION != SIMULATION) | |
988 | |
989 #if (CHIPSET == 12) || (CHIPSET == 15) | |
990 F_INTH_DISABLE_ONE_IT(C_INTH_FRAME_IT); // mask Frame int. | |
991 #else | |
992 INTH_DISABLEONEIT(IQ_FRAME); // mask Frame int. | |
993 #endif | |
994 #endif | |
995 | |
996 //===================================================== | |
997 // if CLOCK_STOP : stop RF, TPU, asleep Omega, DPLL, SPI | |
998 // if FRAME_STOP : asleep Omega, SPI | |
999 //===================================================== | |
1000 #if (CODE_VERSION != SIMULATION) | |
1001 if ( l1s.pw_mgr.sleep_performed == CLOCK_STOP ) | |
1002 { | |
1003 // ==== STop RF and TPU..... =================== | |
1004 | |
1005 //L1_trace_string("Proceeding to Deep Sleep\n"); | |
1006 | |
1007 | |
1008 l1dmacro_RF_sleep(); | |
1009 | |
1010 // (*(volatile UWORD16 *)l1s_tpu_com.reg_cmd) =TPU_CTRL_RESET | | |
1011 // TSP_CTRL_RESET |TPU_CTRL_CLK_EN; | |
1012 // (*(volatile UWORD16 *)l1s_tpu_com.reg_cmd) =0; | |
1013 | |
1014 //===== SET default value for gauging ========= | |
1015 // If we have come in here during the inactive period of cell | |
1016 // selection, then load the ULPD timers with default values | |
1017 // (used when the MS lost the network: in this case the deep sleep may be used) | |
1018 if (l1a_l1s_com.mode == CS_MODE0) | |
1019 { | |
1020 l1ctl_pgm_clk32(DEFAULT_HFMHZ_VALUE, DEFAULT_32KHZ_VALUE); | |
1021 } | |
1022 } | |
1023 | |
1024 | |
1025 //============================================== | |
1026 // disable DPLL (do not provide clk to DSP & RIF (RIF)) | |
1027 //============================================== | |
1028 #if ((CHIPSET ==4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12) || (CHIPSET == 15)) | |
1029 // disable DPLL (do not provide clk to DSP & RIF (Bridge)) | |
1030 ( * (volatile SYS_UWORD16 *) CLKM_CNTL_CLK) |= CLKM_DPLL_DIS | CLKM_BRIDGE_DIS; | |
1031 #endif | |
1032 | |
1033 //============================================== | |
1034 // if CLOCK_STOP or FRAME-STOP : Asleep OMEGA (ABB) | |
1035 //============================================== | |
1036 afc_fix = ABB_sleep(l1s.pw_mgr.sleep_performed, l1s.afc); | |
1037 | |
1038 #if (OP_BT == 1) | |
1039 hci_ll_go_to_sleep(); | |
1040 #endif | |
1041 //================================================= | |
1042 // STop SPI ..... | |
1043 //================================================= | |
1044 | |
1045 *((volatile UWORD16 *)MEM_SPI)&=0xFFFE; // SPI CLK DISABLED | |
1046 #endif // NOT SIMULATION | |
1047 | |
1048 | |
1049 //================================================= | |
1050 // CQ19599: For Calypso+ chipset, extended page mode | |
1051 // shall be disabled before entering deep sleep and | |
1052 // restored at wake up | |
1053 //================================================= | |
1054 #if (W_A_CALYPSO_PLUS_SPR_19599 == 1) | |
1055 extended_page_mode_state = (BOOL) f_memif_extended_page_mode_read_bit(); | |
1056 f_memif_extended_page_mode_disable(); | |
1057 #endif | |
1058 | |
1059 //================================================= | |
1060 // Init the timer : | |
1061 // | |
1062 // a margin of 4 frames (>MIN_SLEEP_TIME) is taken | |
1063 // when evaluating system loading, because 1 frame | |
1064 // is lost for wakeup only, and because sleep | |
1065 // duration less than 1 frame is not worth .... | |
1066 // | |
1067 // 1 2 3 4 5 6 7 8 | |
1068 // SLEEP_CTRL SLEEP WAKEUP TASK (RF,Timer, ...) | |
1069 // | |
1070 //================================================= | |
1071 //ULPD Timer can be loaded up to MAX_GSM_TIMER (possible in CS_MODE0) | |
1072 if ( l1s.pw_mgr.sleep_performed == CLOCK_STOP ) | |
1073 { | |
1074 // DEEP SLEEP -> need time to setup afc and rf | |
1075 wake_up_time = min_time - l1_config.params.setup_afc_and_rf; | |
1076 } | |
1077 else | |
1078 // BIG SLEEP | |
1079 wake_up_time = min_time - 1; | |
1080 | |
1081 | |
1082 | |
1083 #if (CODE_VERSION != SIMULATION) | |
1084 if ( wake_up_time >= MAX_GSM_TIMER) | |
1085 ULDP_TIMER_INIT(MAX_GSM_TIMER); | |
1086 else | |
1087 ULDP_TIMER_INIT(wake_up_time); | |
1088 | |
1089 ULDP_TIMER_LD; // Load the timer | |
1090 | |
1091 // BUG3060. Clear pending IQ_TGSM from ULPD. This could happen in case ULPD was frozen | |
1092 // with zero into its GSM counter. In that case, the interrupt is still pending | |
1093 // and if it is not cleared, it wakes the board up just after switching the clock. | |
1094 // Clear it into the ULPD... | |
1095 // The ULDP_GSM_TIMER_IT_REG is a read only register and is cleared on | |
1096 //reading the register. | |
1097 temp_clear_intr =(* (volatile UWORD16 *) ULDP_GSM_TIMER_IT_REG) & ULPD_IT_TIMER_GSM; | |
1098 // ... and next into the INTH. (must be done in this order | |
1099 | |
1100 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1101 F_INTH_RESET_ONE_IT(C_INTH_TGSM_IT); | |
1102 F_INTH_ENABLE_ONE_IT(C_INTH_TGSM_IT); | |
1103 #else | |
1104 INTH_RESETONEIT(IQ_TGSM); // clear TDMA IRQ | |
1105 INTH_ENABLEONEIT(IQ_TGSM); // Unmask ULPD GSM int. | |
1106 #endif | |
1107 | |
1108 #if (GSM_IDLE_RAM != 0) | |
1109 if (READ_TRAFFIC_CONT_STATE) | |
1110 { | |
1111 CSMI_TrafficControllerOff(); | |
1112 } | |
1113 #endif | |
1114 | |
1115 ULDP_TIMER_START; // start count down | |
1116 | |
1117 | |
1118 #if (GSM_IDLE_RAM_DEBUG == 1) | |
1119 (*( volatile unsigned short* )(0xFFFE4802)) &= ~ (1 << 2); // GPIO-2=0 | |
1120 #endif | |
1121 | |
1122 if ( l1s.pw_mgr.sleep_performed == CLOCK_STOP ) | |
1123 // DEEP SLEEP | |
1124 { | |
1125 #if (OP_WCP == 1) && (OP_L1_STANDALONE != 1) | |
1126 // specific sleep for WCP | |
1127 arm7_deep_sleep(); | |
1128 #else // NO OP_WCP | |
1129 #if (W_A_CALYPSO_BUG_01435 == 1) | |
1130 f_arm_sleep_cmd(DEEP_SLEEP); | |
1131 #else | |
1132 *((volatile UWORD16 *)CLKM_ARM_CLK) &= ~(CLKM_DEEP_SLEEP); // set deep sleep mode | |
1133 #endif | |
1134 #endif // OP_WCP | |
1135 } | |
1136 else | |
1137 { | |
1138 // BIG SLEEP / l1s.pw_mgr.sleep_performed == FRAME_STOP | |
1139 | |
1140 //========================================================== | |
1141 //Shut down PERIPHERALS clocks UWIRE and ARMIO if authorized | |
1142 //========================================================== | |
1143 | |
1144 UWORD16 clocks_stopped; //OMAPS90550- new | |
1145 clocks_stopped = (l1s.pw_mgr.clocks & l1s.pw_mgr.modules_status); | |
1146 if((clocks_stopped & ARMIO_CLK_CUT) == ARMIO_CLK_CUT) | |
1147 *((volatile UWORD16 *)ARMIO_CNTL_REG) &= ~(ARMIO_CLOCKEN); | |
1148 if((clocks_stopped & UWIRE_CLK_CUT) == UWIRE_CLK_CUT) | |
1149 *((volatile UWORD16 *)(MEM_UWIRE + 0x8)) &= ~(0x0001); | |
1150 | |
1151 #if (W_A_CALYPSO_BUG_01435 == 1) | |
1152 f_arm_sleep_cmd(BIG_SLEEP); | |
1153 #else | |
1154 | |
1155 *((volatile UWORD16 *)CLKM_ARM_CLK) &= ~(CLKM_MCLK_EN); // set big sleep mode | |
1156 #endif | |
1157 } | |
1158 #else // Simulation part | |
1159 l1s.pw_mgr.sleep_duration = wake_up_time; | |
1160 hw.deep_sleep_en = 1; | |
1161 status = NU_Suspend_Task(&L1S_task); | |
1162 // check status value... | |
1163 if (status) | |
1164 { | |
1165 #if (TRACE_TYPE==5) | |
1166 sprintf(errormsg,"Error somewhere in the L1S application to suspend : deep sleep\n"); | |
1167 log_sim_error(ERR); | |
1168 #endif | |
1169 EXIT; | |
1170 } | |
1171 #endif // SIMULATION | |
1172 | |
1173 //================================================= | |
1174 // Wake-up procedure | |
1175 //================================================= | |
1176 // Restore L1 data base, Nucleus, HW Timers .... | |
1177 //================================================= | |
1178 | |
1179 #if (GSM_IDLE_RAM_DEBUG == 1) | |
1180 (*( volatile unsigned short* )(0xFFFE4802)) |= (1 << 2); // GPIO-2=1 | |
1181 #endif | |
1182 | |
1183 | |
1184 l1s_wakeup(); | |
1185 | |
1186 last_wakeup = l1s.actual_time.fn_mod42432; | |
1187 | |
1188 if (last_wakeup == sleep_time) | |
1189 // sleep duration == 0 -> wakeup in the same frame as sleep | |
1190 wakeup_type = WAKEUP_ASYNCHRONOUS_SLEEP_DURATION_0; | |
1191 | |
1192 #if (GSM_IDLE_RAM != 0) | |
1193 // Update counters with sleep duration -> will be used case expiration in next wake up phase before traffic controller is enabled by msg sending | |
1194 gsm_idle_ram_ctl->os_load -= (l1s.pw_mgr.sleep_duration); | |
1195 gsm_idle_ram_ctl->hw_timer -= (l1s.pw_mgr.sleep_duration); | |
1196 | |
1197 if (l1s.pw_mgr.wakeup_type != WAKEUP_FOR_L1_TASK) | |
1198 { | |
1199 if (!READ_TRAFFIC_CONT_STATE) | |
1200 { | |
1201 CSMI_TrafficControllerOn(); | |
1202 } | |
1203 } | |
1204 #endif | |
1205 //================================================= | |
1206 //if CLOCK_STOP : restart TPU and RF.... | |
1207 //================================================= | |
1208 #if (CODE_VERSION != SIMULATION) | |
1209 if ( l1s.pw_mgr.sleep_performed == CLOCK_STOP ) | |
1210 { | |
1211 // (*(volatile UWORD16 *)l1s_tpu_com.reg_cmd) = TPU_CTRL_CLK_EN; | |
1212 UWORD8 local_sleep_status; | |
1213 | |
1214 l1dmacro_RF_wakeup(); | |
1215 | |
1216 } | |
1217 | |
1218 #if ((CHIPSET ==4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11)) | |
1219 // enable DPLL (provide clk to DSP & RIF(Bridge) in small/big sleep) | |
1220 // On CALYPSO, BRIDGE clock can be cut according to the ARM sleep mode even during DMA transfer | |
1221 ( * (volatile SYS_UWORD16 *) CLKM_CNTL_CLK) &= ~(CLKM_DPLL_DIS | CLKM_BRIDGE_DIS); | |
1222 #elif (CHIPSET == 12) | |
1223 // Nothing to be done because if DSP wants clock, it will exit from IDLE3 mode, which wakes up the DPLL | |
1224 #elif (CHIPSET == 15) | |
1225 ( * (volatile SYS_UWORD16 *) CLKM_CNTL_CLK) &= ~(CLKM_DPLL_DIS); | |
1226 #endif | |
1227 | |
1228 //================================================= | |
1229 //if CLOCK_STOP or FRAME-STOP : ReStart SPI | |
1230 //================================================= | |
1231 *((volatile UWORD16 *)MEM_SPI)|=0x0001; // SPI CLK ENABLED | |
1232 | |
1233 //================================================= | |
1234 // Wake up ABB | |
1235 //================================================= | |
1236 ABB_wakeup(l1s.pw_mgr.sleep_performed, l1s.afc); | |
1237 | |
1238 #if (OP_BT == 1) | |
1239 hci_ll_wake_up(); | |
1240 #endif | |
1241 #endif //CODE VERSION | |
1242 | |
1243 //================================================= | |
1244 // CQ19599: For Calypso+ chipset, restore the extended | |
1245 // page mode if it was enabled before entering in sleep | |
1246 //================================================= | |
1247 #if (W_A_CALYPSO_PLUS_SPR_19599 == 1) | |
1248 if ( extended_page_mode_state != 0 ) | |
1249 f_memif_extended_page_mode_enable(); | |
1250 #endif | |
1251 | |
1252 #if (OP_L1_STANDALONE == 0) | |
1253 /*GC_Wakeup(); OMAPS00134004*/ | |
1254 #endif | |
1255 | |
1256 #if (CODE_VERSION != SIMULATION) | |
1257 //================================================= | |
1258 // enable IRQ | |
1259 //================================================= | |
1260 OS_system_Unprotect(); | |
1261 #endif | |
1262 | |
1263 #if (TRACE_TYPE != 0) | |
1264 if (l1a_l1s_com.mode != CS_MODE0) // in this mode the trace prevent from going to deep sleep due to UART activity | |
1265 { | |
1266 #if (GSM_IDLE_RAM == 0) | |
1267 l1_trace_sleep(sleep_time, l1s.actual_time.fn_mod42432, l1s.pw_mgr.sleep_performed, wakeup_type, why_big_sleep); | |
1268 #else | |
1269 l1_trace_sleep_intram(sleep_time, l1s.actual_time.fn_mod42432, l1s.pw_mgr.sleep_performed, wakeup_type, why_big_sleep); | |
1270 #if (TRACE_TYPE==1) || (TRACE_TYPE==4) | |
1271 l1s_trace_mftab(); | |
1272 #endif | |
1273 #endif | |
1274 } | |
1275 #endif | |
1276 | |
1277 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4) | |
1278 trace_info.sleep_performed = TRUE; | |
1279 #endif | |
1280 | |
1281 #if (CODE_VERSION != SIMULATION) | |
1282 | |
1283 //================================================= | |
1284 // enable IRQ | |
1285 //================================================= | |
1286 INT_EnableIRQ(); | |
1287 | |
1288 //================================================= | |
1289 // Be careful:in case of asynchronous wake-up after sleep | |
1290 // an IT_TDMA may be unmasked and executed just after OS_system_Unprotect(). | |
1291 // As we already are inside an hisr(), it implies the execution of an another hisr(). | |
1292 // In order to avoid issues with the execution of an hisr() inside the hisr() | |
1293 // do not add code here after !!! | |
1294 // if possible respect this rule ! | |
1295 //================================================= | |
1296 | |
1297 //================================================= | |
1298 // wake-up UARTs | |
1299 //this function must be call after the UART interrupt, | |
1300 //it means after the function INT_EnableIRQ() | |
1301 //================================================= | |
1302 { | |
1303 #if (GSM_IDLE_RAM != 0) | |
1304 // Traffic controller has to be enabled before calling SER_WakeUpUarts | |
1305 // as this function can access the external RAM. | |
1306 // Reset the flag that will indicates if an interrup will put the traffic | |
1307 // controller ON during that time. | |
1308 l1s.gsm_idle_ram_ctl.trff_ctrl_enable_cause_int = FALSE; | |
1309 if (!READ_TRAFFIC_CONT_STATE) | |
1310 { | |
1311 flag_traffic_controller_state = 1; | |
1312 CSMI_TrafficControllerOn(); | |
1313 } | |
1314 #endif | |
1315 | |
1316 | |
1317 SER_WakeUpUarts(); // Wake up Uarts | |
1318 | |
1319 | |
1320 #if (GSM_IDLE_RAM != 0) | |
1321 // The traffic controller state shall be restored as it was before | |
1322 // calling SER_WakeUpUarts. Do not disable it if an interrup occured | |
1323 // in between and activated the traffic controller. | |
1324 if ((flag_traffic_controller_state == 1) && (l1s.gsm_idle_ram_ctl.trff_ctrl_enable_cause_int == FALSE)) | |
1325 { | |
1326 CSMI_TrafficControllerOff(); | |
1327 } | |
1328 flag_traffic_controller_state = 0; | |
1329 #endif | |
1330 } | |
1331 #endif // NOT SIMULATION | |
1332 } | |
1333 } | |
1334 | |
1335 // l1s_wakeup() */ | |
1336 // Description: wake-up of the MCU from GSM Timer it OR unscheduled wake-up | |
1337 // This function read the TPU timer and fix the : | |
1338 // - system clock | |
1339 // - Nucleus timers | |
1340 // - L1 frame counter | |
1341 // - L1 next task counter | |
1342 // - Hardware timers | |
1343 | |
1344 void l1s_wakeup(void) | |
1345 { | |
1346 #if (CODE_VERSION != SIMULATION) | |
1347 if (l1_config.pwr_mngt == PWR_MNGT) | |
1348 { | |
1349 // Restore interrupts .... | |
1350 | |
1351 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1352 // mask TGSM int. | |
1353 F_INTH_DISABLE_ONE_IT(C_INTH_TGSM_IT); | |
1354 #else | |
1355 INTH_DISABLEONEIT(IQ_TGSM); // mask TGSM int. | |
1356 #endif | |
1357 | |
1358 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1359 int_id = ((* (SYS_UWORD16 *) C_INTH_B_IRQ_REG) & C_INTH_SRC_NUM);// For debug: Save IRQ that causes the waking up | |
1360 if ( int_id >= 256 ) | |
1361 int_id = ((* (SYS_UWORD16 *) C_INTH_B_FIQ_REG) & C_INTH_SRC_NUM)+100; | |
1362 #else | |
1363 int_id = ((* (SYS_UWORD16 *) INTH_B_IRQ_REG) & INTH_SRC_NUM);// For debug: Save IRQ that causes the waking up | |
1364 if ( int_id >= 256 ) | |
1365 int_id = ((* (SYS_UWORD16 *) INTH_B_FIQ_REG) & INTH_SRC_NUM)+100; | |
1366 #endif | |
1367 | |
1368 // clear pending IQ_FRAME it and unmask it | |
1369 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1370 F_INTH_RESET_ONE_IT(C_INTH_FRAME_IT); | |
1371 F_INTH_ENABLE_ONE_IT(C_INTH_FRAME_IT); // Unmask FRAME int. | |
1372 #else | |
1373 INTH_RESETONEIT(IQ_FRAME); // clear TDMA IRQ | |
1374 INTH_ENABLEONEIT(IQ_FRAME); // Unmask FRAME int. | |
1375 #endif | |
1376 | |
1377 #if (CHIPSET == 8) | |
1378 // if deep sleep | |
1379 if ( l1s.pw_mgr.sleep_performed == CLOCK_STOP ) | |
1380 { | |
1381 UWORD8 i; | |
1382 | |
1383 // Loop with check whether DPLL is locked: 100 us max. | |
1384 for (i=0;i<16;i++) | |
1385 { | |
1386 if (DPLL_READ_DPLL_LOCK) | |
1387 break; | |
1388 } | |
1389 wait_ARM_cycles(convert_nanosec_to_cycles(50000)); // 50us | |
1390 | |
1391 // Enable DPLL | |
1392 //-------------------------------------------------- | |
1393 DPLL_SET_PLL_ENABLE; | |
1394 | |
1395 // Loop with check whether DPLL is locked: 100 us max. | |
1396 for (i=0;i<16;i++) | |
1397 { | |
1398 if (DPLL_READ_DPLL_LOCK) | |
1399 break; | |
1400 } | |
1401 wait_ARM_cycles(convert_nanosec_to_cycles(50000)); // 50us | |
1402 } // if deep sleep | |
1403 | |
1404 #endif // CHIPSET == 8 | |
1405 | |
1406 //================================================= | |
1407 //Restart PERIPHERALS clocks if necessary after a big sleep period | |
1408 // WARNING: restart other clocks modules!!! | |
1409 //================================================= | |
1410 | |
1411 | |
1412 #if(CHIPSET == 15) | |
1413 if(l1s.pw_mgr.sleep_performed == FRAME_STOP ) | |
1414 { | |
1415 | |
1416 //ABB_Wakeup_BS(); //Not Used | |
1417 //DBB_Wakeup_BS(); //Not Used | |
1418 } | |
1419 #else | |
1420 // if big sleep | |
1421 if ( l1s.pw_mgr.sleep_performed == FRAME_STOP ) | |
1422 { | |
1423 | |
1424 UWORD16 clocks_stopped; | |
1425 clocks_stopped = (l1s.pw_mgr.clocks & l1s.pw_mgr.modules_status); | |
1426 if((clocks_stopped & ARMIO_CLK_CUT) == ARMIO_CLK_CUT) | |
1427 *((volatile UWORD16 *)ARMIO_CNTL_REG) |= ARMIO_CLOCKEN; | |
1428 if((clocks_stopped & UWIRE_CLK_CUT) == UWIRE_CLK_CUT) | |
1429 *((volatile UWORD16 *)(MEM_UWIRE + 0x8)) |= 0x0001; | |
1430 | |
1431 } | |
1432 #endif | |
1433 | |
1434 | |
1435 /***************************************************/ | |
1436 /* Compute effective sleeping time .... */ | |
1437 /* */ | |
1438 /* sleep duration is */ | |
1439 /* - TIMER_INIT */ | |
1440 /* - or TIMER_INIT - TIMER_VALUE */ | |
1441 /* */ | |
1442 /* "frame_adjust" = TRUE for unschedules wake-up */ | |
1443 /* FALSE for scheduled wake-up */ | |
1444 /***************************************************/ | |
1445 l1s.pw_mgr.frame_adjust = l1s_compute_wakeup_ticks(); | |
1446 | |
1447 #if (TRACE_TYPE !=0 ) && (TRACE_TYPE != 2) && (TRACE_TYPE != 3) | |
1448 if ((l1s.pw_mgr.frame_adjust == TRUE)) | |
1449 wakeup_type = WAKEUP_BY_ASYNC_INTERRUPT; | |
1450 #endif | |
1451 | |
1452 | |
1453 /* Fix Frame */ | |
1454 | |
1455 l1s_recover_Frame(); | |
1456 | |
1457 | |
1458 /* Fix Hardware Timers */ | |
1459 /* */ | |
1460 /* GSM 1.0 : ntd - timer clock not cut */ | |
1461 /* */ | |
1462 /* GSM 1.5 : deep sleep - need to fix timers */ | |
1463 | |
1464 if (l1s.pw_mgr.sleep_performed == CLOCK_STOP) | |
1465 l1s_recover_HWTimers(); | |
1466 | |
1467 | |
1468 /* Fix Os */ | |
1469 | |
1470 if (Cust_recover_Os()) l1s.pw_mgr.Os_ticks_required = TRUE; | |
1471 } | |
1472 #else // SIMULATION part | |
1473 // update L1 timers (FN,...) | |
1474 l1s_recover_Frame(); | |
1475 #endif | |
1476 } | |
1477 | |
1478 | |
1479 | |
1480 /* l1s_wakeup_adjust() */ | |
1481 /* Description: 1 frame adjust a fter unscheduled wake-up */ | |
1482 /* This function fix the : */ | |
1483 /* - system clock */ | |
1484 /* - Nucleus timers */ | |
1485 /* - L1 frame counter */ | |
1486 /* - L1 next task counter */ | |
1487 /* - Hardware timers */ | |
1488 | |
1489 | |
1490 void l1s_wakeup_adjust () | |
1491 { | |
1492 #if (CODE_VERSION != SIMULATION) | |
1493 if (l1_config.pwr_mngt == PWR_MNGT) | |
1494 { | |
1495 | |
1496 UWORD32 previous_sleep_time; | |
1497 | |
1498 /***************************************************/ | |
1499 // Freeze GSM Timer .... */ | |
1500 /***************************************************/ | |
1501 ULDP_TIMER_FREEZE; | |
1502 | |
1503 /***************************************************/ | |
1504 // Compute effective sleeping time .... | |
1505 // | |
1506 // compute sleep duration | |
1507 // - TIMER_INIT | |
1508 // - or TIMER_INIT - TIMER_VALUE | |
1509 /***************************************************/ | |
1510 // save sleep duration that was computed at "unscheduled wakeup" | |
1511 previous_sleep_time = l1s.pw_mgr.sleep_duration; | |
1512 | |
1513 l1s_compute_wakeup_ticks(); | |
1514 | |
1515 // reset flag for adjustment request .... | |
1516 l1s.pw_mgr.frame_adjust = FALSE; | |
1517 | |
1518 // fix sleep duration | |
1519 // => compute difference with duration computed at | |
1520 // "unscheduled wakeup" | |
1521 l1s.pw_mgr.sleep_duration -= previous_sleep_time; | |
1522 | |
1523 // adjust system with 1 frame IF NECESSARY .... | |
1524 if (l1s.pw_mgr.sleep_duration) | |
1525 { | |
1526 /***************************************************/ | |
1527 /* Fix Frame */ | |
1528 /***************************************************/ | |
1529 l1s_recover_Frame(); | |
1530 | |
1531 /***************************************************/ | |
1532 /* Fix Os */ | |
1533 /***************************************************/ | |
1534 if (Cust_recover_Os()) l1s.pw_mgr.Os_ticks_required = TRUE; | |
1535 } | |
1536 } | |
1537 #endif | |
1538 } | |
1539 | |
1540 | |
1541 /*-------------------------------------------------------*/ | |
1542 /* l1s_compute_wakeup_Ticks() */ | |
1543 /*-------------------------------------------------------*/ | |
1544 /* */ | |
1545 /* Description: wake-up */ | |
1546 /* ------------ */ | |
1547 /* This function compute the sleep duration according to */ | |
1548 /* current value of count down counter. */ | |
1549 /* - if TIMER_VALUE = 0 it returns TIMER_INIT */ | |
1550 /* - else it returns TIMER_INIT-TIMER_VALUE*/ | |
1551 /* */ | |
1552 /*-------------------------------------------------------*/ | |
1553 BOOL l1s_compute_wakeup_ticks(void) | |
1554 { | |
1555 UWORD16 temp_clear_intr; | |
1556 #if (CODE_VERSION != SIMULATION) | |
1557 // read current value of count down counter | |
1558 l1s.pw_mgr.sleep_duration = READ_ULDP_TIMER_VALUE; | |
1559 | |
1560 // if count down=0 it's a scheduled wake-up.... | |
1561 if (l1s.pw_mgr.sleep_duration == 0) | |
1562 { | |
1563 // read sleeping planned value in TPU INIT register | |
1564 l1s.pw_mgr.sleep_duration = READ_ULDP_TIMER_INIT; | |
1565 // INTH is different from the ULPD interrupt -> aynchronous wakeup | |
1566 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1567 if (int_id != C_INTH_TGSM_IT) | |
1568 #else | |
1569 if (int_id != IQ_TGSM) | |
1570 #endif | |
1571 { | |
1572 wakeup_type = WAKEUP_ASYNCHRONOUS_ULPD_0; | |
1573 // RESET IT_ULPD in ULPD module | |
1574 // The ULDP_GSM_TIMER_IT_REG is a read only register and is cleared on reading the register | |
1575 temp_clear_intr =(* (volatile UWORD16 *) ULDP_GSM_TIMER_IT_REG) & ULPD_IT_TIMER_GSM; | |
1576 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1577 // RESET IQ_TGSM (IT_ULPD) in IT register | |
1578 F_INTH_RESET_ONE_IT(C_INTH_TGSM_IT); | |
1579 // RESET IQ_FRAME in IT register | |
1580 F_INTH_RESET_ONE_IT(C_INTH_FRAME_IT); | |
1581 int_id = C_INTH_TGSM_IT; | |
1582 #else | |
1583 // RESET IQ_TGSM (IT_ULPD) in IT register | |
1584 INTH_RESETONEIT(IQ_TGSM); | |
1585 // RESET IQ_FRAME in IT register | |
1586 INTH_RESETONEIT(IQ_FRAME); | |
1587 int_id = IQ_TGSM; | |
1588 #endif | |
1589 return(FALSE); | |
1590 } | |
1591 else | |
1592 return(FALSE); | |
1593 } | |
1594 else // Unscheduled wakeup | |
1595 { | |
1596 // read sleeping planned value in TPU INIT register & compute time elapsed | |
1597 l1s.pw_mgr.sleep_duration = READ_ULDP_TIMER_INIT - l1s.pw_mgr.sleep_duration; | |
1598 return(TRUE); | |
1599 } | |
1600 #else | |
1601 return(FALSE);//omaps00090550 | |
1602 #endif | |
1603 } | |
1604 | |
1605 /*-------------------------------------------------------*/ | |
1606 /* l1s_recover_Frame() */ | |
1607 /*-------------------------------------------------------*/ | |
1608 /* */ | |
1609 /* Description: adjust layer1 data from sleep duration */ | |
1610 /* ------------ */ | |
1611 /*-------------------------------------------------------*/ | |
1612 void l1s_recover_Frame(void) | |
1613 { | |
1614 if (l1_config.pwr_mngt == PWR_MNGT) | |
1615 { | |
1616 /***************************************************/ | |
1617 /* Fix Frame counters . */ | |
1618 /***************************************************/ | |
1619 l1s.debug_time += l1s.pw_mgr.sleep_duration; // used for debug and by L3 scenario. | |
1620 | |
1621 // Time... | |
1622 // Update "actual time". | |
1623 l1s_increment_time(&(l1s.actual_time), l1s.pw_mgr.sleep_duration); | |
1624 | |
1625 // Update "next time". | |
1626 l1s.next_time = l1s.actual_time; | |
1627 l1s_increment_time(&(l1s.next_time), 1); // Next time is actual_time + 1 | |
1628 | |
1629 #if L1_GPRS | |
1630 // Update "next plus time". | |
1631 l1s.next_plus_time = l1s.next_time; | |
1632 l1s_increment_time(&(l1s.next_plus_time), 1); // Next_plus time is next_time + 1 | |
1633 #endif | |
1634 | |
1635 #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4) | |
1636 trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1)); | |
1637 #endif | |
1638 | |
1639 // Multiframe table... | |
1640 // Increment active frame % mftab size. | |
1641 l1s.afrm = (l1s.afrm + l1s.pw_mgr.sleep_duration) % MFTAB_SIZE; | |
1642 | |
1643 // Control function counters... | |
1644 // Increment frame count from last AFC update. | |
1645 l1s.afc_frame_count+= l1s.pw_mgr.sleep_duration; | |
1646 // reset counter to mask SNR/TOA results for 2 fr. | |
1647 #if (TOA_ALGO == 2) | |
1648 l1s.toa_var.toa_snr_mask=0; | |
1649 #else | |
1650 l1s.toa_snr_mask=0; | |
1651 #endif | |
1652 | |
1653 /***************************************************/ | |
1654 /* Fix next L1S task counter */ | |
1655 /***************************************************/ | |
1656 // Decrement time to next L1S task. | |
1657 if((l1a_l1s_com.time_to_next_l1s_task > 0) && | |
1658 (l1a_l1s_com.time_to_next_l1s_task < MAX_FN)) | |
1659 l1a_l1s_com.time_to_next_l1s_task -= l1s.pw_mgr.sleep_duration; | |
1660 } // l1_config.pwr_mngt == PWR_MNGT | |
1661 } | |
1662 | |
1663 | |
1664 /*-------------------------------------------------------*/ | |
1665 /* l1s_recover_HWTimers() */ | |
1666 /*-------------------------------------------------------*/ | |
1667 /* */ | |
1668 /* Description: adjust hardware timers from sleep */ | |
1669 /* ------------ duration */ | |
1670 /* */ | |
1671 /* Timers clocks are enabled after VTCX0+SLICER+13MHZ */ | |
1672 /* setup times. So sleep duration is : */ | |
1673 /* GSM TIMER - SETUP_FRAME + SETUP_SLICER + SETUP_VTCXO */ | |
1674 /* + SETUP_CLK13 */ | |
1675 /*-------------------------------------------------------*/ | |
1676 | |
1677 void l1s_recover_HWTimers(void) | |
1678 { | |
1679 #if (CODE_VERSION != SIMULATION) | |
1680 | |
1681 #define SETUP_FRAME_IN_CLK32 (SETUP_FRAME*4.615*32.768) | |
1682 #if (CHIPSET == 15) | |
1683 #define DELTA_TIME (0) | |
1684 #else | |
1685 #define DELTA_TIME (SETUP_FRAME_IN_CLK32 -SETUP_SLICER - SETUP_VTCXO) | |
1686 #endif | |
1687 | |
1688 | |
1689 if (l1_config.pwr_mngt == PWR_MNGT) | |
1690 { | |
1691 WORD32 timer1,timer2,timer; | |
1692 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1693 WORD32 timer_sec; | |
1694 #endif | |
1695 UWORD16 cntlreg; | |
1696 UWORD16 modereg; | |
1697 double duration; | |
1698 | |
1699 | |
1700 //WORD32 old;- OMAPS 90550 new | |
1701 | |
1702 // read Hercules Timers & Watchdog | |
1703 //================================================= | |
1704 // Tint = Tclk * (LOAD_TIM+1) * 2^(PTV+1) | |
1705 // Tclk = 1.2308us for Fclk=13Mhz | |
1706 // PTV = 7 (pre-scaler field) | |
1707 //------------------------------------------------- | |
1708 | |
1709 cntlreg = Dtimer1_Get_cntlreg(); | |
1710 if ( (cntlreg & D_TIMER_RUN) == D_TIMER_RUN) | |
1711 { | |
1712 #if 0 /* match TCS211 object */ | |
1713 cntlreg = cntlreg&0x1F; | |
1714 #endif | |
1715 cntlreg >>= 2; // take PTV | |
1716 cntlreg = 1 << (cntlreg+1); // compute 2^(PTV+1) | |
1717 // convert sleep duration in HWTimers ticks.... | |
1718 duration = (l1s.pw_mgr.sleep_duration * 4.615 - (DELTA_TIME/32.768)) / (cntlreg * 0.0012308); | |
1719 #if 0 /* match TCS211 object */ | |
1720 if (duration < 0.0){ | |
1721 duration = 0.0; // This needs to be done for all the timers | |
1722 } | |
1723 #endif | |
1724 timer1 = Dtimer1_ReadValue() - (UWORD16) duration; | |
1725 | |
1726 Dtimer1_Start(0); | |
1727 Dtimer1_WriteValue(timer1); | |
1728 Dtimer1_Start(1); | |
1729 } | |
1730 | |
1731 cntlreg = Dtimer2_Get_cntlreg(); | |
1732 if ( (cntlreg & D_TIMER_RUN) == D_TIMER_RUN) | |
1733 { | |
1734 #if 0 /* match TCS211 object */ | |
1735 cntlreg = cntlreg&0x1F; | |
1736 #endif | |
1737 cntlreg >>= 2; // take PTV | |
1738 cntlreg = 1 << (cntlreg+1); | |
1739 // convert sleep duration in HWTimers ticks.... | |
1740 duration = (l1s.pw_mgr.sleep_duration * 4.615 - (DELTA_TIME/32.768)) / (cntlreg * 0.0012308); | |
1741 #if 0 /* match TCS211 object */ | |
1742 if (duration < 0.0){ | |
1743 duration = 0.0; // This needs to be done for all the timers | |
1744 } | |
1745 #endif | |
1746 timer2 = Dtimer2_ReadValue() - (UWORD16) duration; | |
1747 Dtimer2_Start(0); | |
1748 Dtimer2_WriteValue(timer2); | |
1749 Dtimer2_Start(1); | |
1750 } | |
1751 | |
1752 cntlreg = TIMER_Read(0); | |
1753 modereg = TIMER_Read(2); | |
1754 if ( (cntlreg & TIMER_ST) || (modereg & TIMER_WDOG)) | |
1755 { | |
1756 // in watchdog mode PTV is forced to 7 | |
1757 if ( modereg & TIMER_WDOG ) | |
1758 cntlreg |= TIMER_PTV; | |
1759 | |
1760 cntlreg = (cntlreg & TIMER_PTV) >> 9; // take PTV | |
1761 cntlreg = 1 << (cntlreg+1); | |
1762 // convert sleep duration in HWTimers ticks.... | |
1763 duration = (l1s.pw_mgr.sleep_duration * 4.615 - (DELTA_TIME/32.768)) / (cntlreg * 0.001078); | |
1764 | |
1765 timer = TIMER_ReadValue() - (UWORD16) duration; | |
1766 TIMER_START_STOP(0); | |
1767 TIMER_WriteValue(timer); | |
1768 TIMER_START_STOP(1); | |
1769 } | |
1770 | |
1771 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1772 cntlreg = TIMER_SEC_Read(0); | |
1773 modereg = TIMER_SEC_Read(2); | |
1774 if ( (cntlreg & TIMER_ST) || (modereg & TIMER_WDOG)) | |
1775 { | |
1776 // in watchdog mode PTV is forced to 7 | |
1777 if ( modereg & TIMER_WDOG ) | |
1778 cntlreg |= TIMER_PTV; | |
1779 | |
1780 cntlreg = (cntlreg & TIMER_PTV) >> 9; // take PTV | |
1781 cntlreg = 1 << (cntlreg+1); | |
1782 // convert sleep duration in HWTimers ticks.... | |
1783 duration = (l1s.pw_mgr.sleep_duration * 4.615 - (DELTA_TIME/32.768)) / (cntlreg * 0.001078); | |
1784 | |
1785 timer_sec = TIMER_SEC_ReadValue() - (UWORD16) duration; | |
1786 TIMER_SEC_START_STOP(0); | |
1787 TIMER_SEC_WriteValue(timer_sec); | |
1788 TIMER_SEC_START_STOP(1); | |
1789 } | |
1790 #endif | |
1791 | |
1792 } | |
1793 #endif | |
1794 } | |
1795 /*-------------------------------------------------------*/ | |
1796 /* l1s_get_next_gauging_in_Packet_Idle() */ | |
1797 /*-------------------------------------------------------*/ | |
1798 /* */ | |
1799 /* Description: */ | |
1800 /* ------------ */ | |
1801 /* return the nbr of frames before the next gauging */ | |
1802 /* return -1 means no activity planned */ | |
1803 /*-------------------------------------------------------*/ | |
1804 #if L1_GPRS | |
1805 UWORD32 next_gauging_scheduled_for_PNP; // gauging for Packet Idle | |
1806 | |
1807 WORD32 l1s_get_next_gauging_in_Packet_Idle(void) | |
1808 { | |
1809 WORD32 next_gauging; | |
1810 | |
1811 // gauging performed with Normal Paging (we are in Idle mode) | |
1812 if (l1a_l1s_com.l1s_en_task[NP] == TASK_ENABLED) | |
1813 return (-1); // no activity planned | |
1814 | |
1815 // we are not in Packet Idle Mode | |
1816 if (l1a_l1s_com.l1s_en_task[PNP] != TASK_ENABLED) | |
1817 return (-1); // no activity planned | |
1818 | |
1819 next_gauging = next_gauging_scheduled_for_PNP - l1s.actual_time.fn ; | |
1820 if (next_gauging < 0) | |
1821 next_gauging+=MAX_FN; | |
1822 | |
1823 if (next_gauging <= MIN_SLEEP_TIME) | |
1824 return(0); | |
1825 | |
1826 return (next_gauging); | |
1827 } | |
1828 #endif | |
1829 /*-------------------------------------------------------*/ | |
1830 /* l1s_gauging_decision_with_PNP() */ | |
1831 /*-------------------------------------------------------*/ | |
1832 /* */ | |
1833 /* Description: */ | |
1834 /* ------------ */ | |
1835 /* */ | |
1836 /*-------------------------------------------------------*/ | |
1837 #if L1_GPRS | |
1838 BOOL l1s_gauging_decision_with_PNP(void) | |
1839 { | |
1840 #define TWO_SECONDS_IN_FRAME (UWORD16)(2000/4.615) | |
1841 | |
1842 /* reconstructed TCS211 code */ | |
1843 if (l1s.actual_time.fn >= next_gauging_scheduled_for_PNP) | |
1844 { | |
1845 next_gauging_scheduled_for_PNP = l1s.actual_time.fn + TWO_SECONDS_IN_FRAME; | |
1846 if (next_gauging_scheduled_for_PNP >= MAX_FN) next_gauging_scheduled_for_PNP -= MAX_FN; | |
1847 return (TRUE); | |
1848 } | |
1849 | |
1850 return (FALSE); // do not perform gauging | |
1851 } | |
1852 #endif | |
1853 /*-------------------------------------------------------*/ | |
1854 /* l1s_gauging_decision_with_NP() */ | |
1855 /*-------------------------------------------------------*/ | |
1856 /* */ | |
1857 /* Description: */ | |
1858 /* ------------ */ | |
1859 /* */ | |
1860 /*-------------------------------------------------------*/ | |
1861 BOOL l1s_gauging_decision_with_NP(void) | |
1862 { | |
1863 | |
1864 static UWORD8 time_to_gaug; | |
1865 | |
1866 // a paging is scheduled or , was scheduled but discarded by a higher priority task | |
1867 if (l1s.pw_mgr.paging_scheduled == TRUE) | |
1868 { | |
1869 l1s.pw_mgr.paging_scheduled = FALSE; // reset Flag. | |
1870 | |
1871 // A gauging session is needed : start gauging session with this paging bloc ! | |
1872 | |
1873 //Nina modify to save power, not forbid deep sleep, only force gauging in next paging | |
1874 // FreeCalypso TCS211 reconstruction: Nina's change reverted | |
1875 #if 1 | |
1876 if (l1s.pw_mgr.enough_gaug != TRUE) | |
1877 time_to_gaug = 0; | |
1878 #else | |
1879 if ((l1s.pw_mgr.enough_gaug != TRUE)||(l1s.force_gauging_next_paging_due_to_CCHR == 1)) | |
1880 { | |
1881 time_to_gaug = 0; | |
1882 l1s.force_gauging_next_paging_due_to_CCHR = 0; | |
1883 } | |
1884 #endif | |
1885 if (time_to_gaug > 0) | |
1886 { | |
1887 time_to_gaug--; // perform the gauging with an another paging. | |
1888 } | |
1889 else // perform the gauging with this paging | |
1890 { | |
1891 if (l1s.task_status[NP].current_status == ACTIVE ) | |
1892 { | |
1893 time_to_gaug = GAUG_VS_PAGING_RATE[l1a_l1s_com.bs_pa_mfrms-2]-1; | |
1894 | |
1895 return (TRUE); // gauging allowed | |
1896 } | |
1897 else // a gauging is scheduled to be perform here but the paging is missing | |
1898 { // (paging discarded by a higher priority task ?) | |
1899 l1s.pw_mgr.enough_gaug= FALSE; // forbid Deep sleep until next gauging | |
1900 } | |
1901 } | |
1902 } | |
1903 return (FALSE); // gauging not allowed | |
1904 } | |
1905 | |
1906 /*************************************************************/ | |
1907 /* Gauging task management : */ | |
1908 /* */ | |
1909 /* CALYPSO */ | |
1910 /* */ | |
1911 /* 9 8 7 6 5 4 3 2 1 0 */ | |
1912 /* C0 C1 C2 C3 C4 W R - - - */ | |
1913 /* | | */ | |
1914 /* | | */ | |
1915 /* |_ start gauging |_ stop gauging */ | |
1916 /* */ | |
1917 /*OTHERS: */ | |
1918 /* */ | |
1919 /* 11 10 9 8 7 6 5 4 3 2 1 0 */ | |
1920 /* C0 C1 C2 C3 C4 W R - - - - - */ | |
1921 /* | | | | | */ | |
1922 /* | | |_ start gauging |_ stop gauging */ | |
1923 /* | | | | */ | |
1924 /* | |_ (ITCOM) | |(ITCOM) */ | |
1925 /* | | */ | |
1926 /* |_ pgm PLL |_restore PLL */ | |
1927 /* */ | |
1928 /* */ | |
1929 /*************************************************************/ | |
1930 void l1s_gauging_task(void) | |
1931 { | |
1932 if (l1_config.pwr_mngt == PWR_MNGT) | |
1933 { | |
1934 /*************************************************************/ | |
1935 if (l1s.pw_mgr.gauging_task == ACTIVE) | |
1936 { | |
1937 /*************************************************************/ | |
1938 // COUNT = 10 ==> PLL is at 65 Mhz, start the gauging | |
1939 /*************************************************************/ | |
1940 #if (CHIPSET==7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12) || (CHIPSET == 15) | |
1941 // the gauging was started with the begining of the paging | |
1942 #else | |
1943 if (l1s.pw_mgr.gaug_count == (l1s.pw_mgr.gaug_duration-1)) | |
1944 { | |
1945 #if (CODE_VERSION != SIMULATION) | |
1946 ULDP_GAUGING_START; // start gauging | |
1947 #endif | |
1948 | |
1949 #if (TRACE_TYPE != 0) | |
1950 #if (GSM_IDLE_RAM != 0) | |
1951 l1_trace_gauging_intram(); | |
1952 #else | |
1953 l1_trace_gauging(); | |
1954 #endif | |
1955 #endif | |
1956 } | |
1957 #endif | |
1958 | |
1959 l1s.pw_mgr.gaug_count--; // decrement counter | |
1960 | |
1961 | |
1962 // When a MISC task is enabled L1S must be ran every frame | |
1963 // to be able to enable the frame interrupt for DSP | |
1964 l1a_l1s_com.time_to_next_l1s_task = 0; | |
1965 } | |
1966 | |
1967 /*************************************************************/ | |
1968 // REQUEST A GAUGING PROCESS ON EACH PAGING BLOCK | |
1969 // IN IDLE MODE ..... | |
1970 /*************************************************************/ | |
1971 | |
1972 else if (l1s.pw_mgr.gauging_task == INACTIVE ) | |
1973 { | |
1974 BOOL decision = FALSE; | |
1975 | |
1976 if (l1a_l1s_com.l1s_en_task[NP] == TASK_ENABLED) | |
1977 decision = l1s_gauging_decision_with_NP(); | |
1978 #if L1_GPRS | |
1979 else | |
1980 if (l1a_l1s_com.l1s_en_task[PNP] == TASK_ENABLED) | |
1981 decision = l1s_gauging_decision_with_PNP(); | |
1982 #endif | |
1983 | |
1984 if (decision == TRUE) | |
1985 { | |
1986 // gauging duration | |
1987 l1s.pw_mgr.gaug_count = l1s.pw_mgr.gaug_duration; | |
1988 | |
1989 #if (CHIPSET==7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12) || (CHIPSET == 15) | |
1990 // start ULPD gauging immediately with Calypso because we needn't IT_COM. | |
1991 #if (CODE_VERSION != SIMULATION) | |
1992 ULDP_GAUGING_START; | |
1993 #if (CHIPSET == 12) || (CHIPSET == 15) | |
1994 // Force the DPLL to be active | |
1995 ( * (volatile SYS_UWORD16 *) CLKM_CNTL_CLK) &= ~(CLKM_DPLL_DIS); | |
1996 #endif | |
1997 #endif | |
1998 | |
1999 #if (TRACE_TYPE != 0) | |
2000 #if (GSM_IDLE_RAM != 0) | |
2001 l1_trace_gauging_intram(); | |
2002 #else | |
2003 l1_trace_gauging(); | |
2004 #endif | |
2005 #endif | |
2006 #endif | |
2007 | |
2008 // DSP programmation ....... | |
2009 #if (DSP >= 33) | |
2010 #if (CHIPSET==4) | |
2011 l1s_dsp_com.dsp_ndb_ptr->d_pll_config |= B_32KHZ_CALIB; | |
2012 #endif | |
2013 #else | |
2014 l1s_dsp_com.dsp_ndb_ptr->d_pll_clkmod1 = CLKMOD2; // IDLE1 only for DSP | |
2015 #endif | |
2016 | |
2017 l1s.pw_mgr.gauging_task = ACTIVE; | |
2018 } | |
2019 } | |
2020 } | |
2021 } | |
2022 /*-------------------------------------------------------*/ | |
2023 /* l1s_gauging_task_end() */ | |
2024 /*-------------------------------------------------------*/ | |
2025 /* */ | |
2026 /* Description: */ | |
2027 /* ------------ */ | |
2028 /* stop the gauging activity */ | |
2029 /*-------------------------------------------------------*/ | |
2030 void l1s_gauging_task_end(void) | |
2031 { | |
2032 if (l1_config.pwr_mngt == PWR_MNGT) | |
2033 { | |
2034 /*************************************************************/ | |
2035 if (l1s.pw_mgr.gauging_task == ACTIVE) | |
2036 { | |
2037 /*************************************************************/ | |
2038 // COUNT = 1 ==> stop the gauging and free DSP idle modes.... | |
2039 /*************************************************************/ | |
2040 if (l1s.pw_mgr.gaug_count == 1) | |
2041 { | |
2042 // wait for end of gauging interrupt ... | |
2043 l1s.pw_mgr.gauging_task = WAIT_IQ; | |
2044 | |
2045 // Unmask ULPD GAUGING int. | |
2046 #if (CODE_VERSION != SIMULATION) | |
2047 #if (CHIPSET == 12) || (CHIPSET == 15) | |
2048 F_INTH_ENABLE_ONE_IT(C_INTH_ULPD_GAUGING_IT); | |
2049 #else | |
2050 INTH_ENABLEONEIT(IQ_ULPD_GAUGING); | |
2051 #endif | |
2052 ULDP_GAUGING_STOP; // stop ULPD gauging | |
2053 #if (CHIPSET == 12) || (CHIPSET == 15) | |
2054 // Allow the DPLL to be cut according to ARM sleep mode | |
2055 //( * (volatile SYS_UWORD16 *) CLKM_CNTL_CLK) |= (CLKM_DPLL_DIS); | |
2056 #endif | |
2057 #endif | |
2058 | |
2059 // DSP programmation : free IDLE modes... | |
2060 #if (DSP >= 33) | |
2061 #if (CHIPSET==4) | |
2062 l1s_dsp_com.dsp_ndb_ptr->d_pll_config &= ~B_32KHZ_CALIB; | |
2063 #endif | |
2064 #else | |
2065 l1s_dsp_com.dsp_ndb_ptr->d_pll_clkmod1 = CLKMOD1; | |
2066 #endif | |
2067 | |
2068 | |
2069 #if (CODE_VERSION == SIMULATION) | |
2070 // in order to simulate the Gauging interrupt | |
2071 GAUGING_Handler(); | |
2072 | |
2073 #if (TRACE_TYPE==5) | |
2074 trace_ULPD("Stop Gauging", l1s.actual_time.fn); | |
2075 #endif | |
2076 #endif | |
2077 } | |
2078 } | |
2079 } | |
2080 } | |
2081 | |
2082 //#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END | |
2083 #endif |