comparison src/cs/drivers/drv_core/abb/abb.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 4f40ae165be4
comparison
equal deleted inserted replaced
-1:000000000000 0:b6a5e36de839
1 /**********************************************************************************/
2 /* TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION */
3 /* */
4 /* Property of Texas Instruments -- For Unrestricted Internal Use Only */
5 /* Unauthorized reproduction and/or distribution is strictly prohibited. This */
6 /* product is protected under copyright law and trade secret law as an */
7 /* unpublished work. Created 1987, (C) Copyright 1997 Texas Instruments. All */
8 /* rights reserved. */
9 /* */
10 /* */
11 /* Filename : abb.c */
12 /* */
13 /* Description : Functions to drive the ABB device. */
14 /* The Serial Port Interface is used to connect the TI */
15 /* Analog BaseBand (ABB). */
16 /* It is assumed that the ABB is connected as the SPI */
17 /* device 0. */
18 /* */
19 /* Author : Pascal PUEL */
20 /* */
21 /* Version number : 1.3 */
22 /* */
23 /* Date and time : 08/22/03 */
24 /* */
25 /* Previous delta : Creation */
26 /* */
27 /**********************************************************************************/
28
29 #include "l1sw.cfg"
30
31 #include "chipset.cfg"
32 #include "board.cfg"
33 #include "rf.cfg"
34 #include "swconfig.cfg"
35 #include "sys.cfg"
36 #include "abb.h"
37 #include "l1_macro.h"
38 #include "l1_confg.h"
39 #include "clkm/clkm.h" // for wait_ARM_cycles function
40 #include "abb_inline.h"
41 #include "ulpd/ulpd.h" // for FRAME_STOP definition
42 #include "nucleus.h" // for NUCLEUS functions and types
43 #include "l1_types.h"
44
45 #if (OP_L1_STANDALONE == 0)
46 #include "main/sys_types.h"
47 #include "rv/general.h"
48 #include "buzzer/buzzer.h" // for BZ_KeyBeep_OFF function
49 #else
50 #include "sys_types.h"
51 #endif
52
53 #if (VCXO_ALGO == 1)
54 #include "l1_ctl.h"
55 #endif
56
57 #if (RF_FAM == 35)
58 #include "l1_rf35.h"
59 #endif
60
61 #if (RF_FAM == 12)
62 #include "tpudrv12.h"
63 #include "l1_rf12.h"
64 #endif
65
66 #if (RF_FAM == 10)
67 #include "l1_rf10.h"
68 #endif
69
70 #if (RF_FAM == 8)
71 #include "l1_rf8.h"
72 #endif
73
74 #if (RF_FAM == 2)
75 #include "l1_rf2.h"
76 #endif
77
78 /*
79 * The following conditional compilation control is a FreeCalypso addition.
80 * TI's original code always configured the BCICONF register with
81 * MESBB and BBCHGEN bits set, enabling both charging and the measurement
82 * resistive divider for the backup battery. However, on our primary
83 * hw targets (Openmoko GTA02 and our own FCDEV3B) Iota's VBACKUP pin
84 * is unconnected, whereas on Mot C139 and Pirelli DP-L10 "alien" hw
85 * the VBACKUP situation is unclear. But at least on our known hw
86 * with VBACKUP unconnected, it is better to leave backup battery charging
87 * and measurement OFF - TI's original config seems to be a drain on
88 * the main battery. Therefore, we are going to leave MESBB and BBCHGEN
89 * off until and unless we have a hw target where backup battery charging
90 * and measurement are appropriate.
91 */
92
93 #define ENABLE_BACKUP_BATTERY 0
94
95 #if (ABB_SEMAPHORE_PROTECTION)
96
97 static NU_SEMAPHORE abb_sem;
98
99 /*-----------------------------------------------------------------------*/
100 /* ABB_Sem_Create() */
101 /* */
102 /* This function creates the Nucleus semaphore to protect ABB accesses */
103 /* against preemption. */
104 /* No check on the result. */
105 /* */
106 /*-----------------------------------------------------------------------*/
107 void ABB_Sem_Create(void)
108 {
109 // create a semaphore with an initial count of 1 and with FIFO type suspension.
110 NU_Create_Semaphore(&abb_sem, "ABB_SEM", 1, NU_FIFO);
111 }
112
113 #endif // ABB_SEMAPHORE_PROTECTION
114
115 /*-----------------------------------------------------------------------*/
116 /* ABB_Wait_IBIC_Access() */
117 /* */
118 /* This function waits for the first IBIC access. */
119 /* */
120 /*-----------------------------------------------------------------------*/
121 void ABB_Wait_IBIC_Access(void)
122 {
123 #if (ANLG_FAM ==1)
124 // Wait 6 OSCAS cycles (100 KHz) for first IBIC access
125 // (i.e wait 60us + 10% security marge = 66us)
126 wait_ARM_cycles(convert_nanosec_to_cycles(66000));
127 #elif ((ANLG_FAM ==2) || (ANLG_FAM == 3))
128 // Wait 6 x 32 KHz clock cycles for first IBIC access
129 // (i.e wait 187us + 10% security marge = 210us)
130 wait_ARM_cycles(convert_nanosec_to_cycles(210000));
131 #endif
132 }
133
134
135
136 /*-----------------------------------------------------------------------*/
137 /* ABB_Write_Register_on_page() */
138 /* */
139 /* This function manages all the spi serial transfer to write to an */
140 /* ABB register on a specified page. */
141 /* */
142 /*-----------------------------------------------------------------------*/
143 void ABB_Write_Register_on_page(SYS_UWORD16 page, SYS_UWORD16 reg_id, SYS_UWORD16 value)
144 {
145 volatile SYS_UWORD16 status;
146
147 // Start spi clock, mask IT for WR and read SPI_REG_STATUS to reset the RE and WE flags.
148 SPI_Ready_for_WR
149 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
150
151 #if ((ABB_SEMAPHORE_PROTECTION == 1) || (ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
152
153 // check if the semaphore has been correctly created and try to obtain it.
154 // if the semaphore cannot be obtained, the task is suspended and then resumed
155 // as soon as the semaphore is released.
156 if(&abb_sem != 0)
157 {
158 NU_Obtain_Semaphore(&abb_sem, NU_SUSPEND);
159 }
160 #endif // ABB_SEMAPHORE_PROTECTION
161
162 // set the ABB page for register access
163 ABB_SetPage(page);
164
165 // Write value in reg_id
166 ABB_WriteRegister(reg_id, value);
167
168 // set the ABB page for register access at page 0
169 ABB_SetPage(PAGE0);
170
171 #if ((ABB_SEMAPHORE_PROTECTION == 1) || (ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
172 // release the semaphore only if it has correctly been created.
173 if(&abb_sem != 0)
174 {
175 NU_Release_Semaphore(&abb_sem);
176 }
177 #endif // ABB_SEMAPHORE_PROTECTION
178
179 // Stop the SPI clock
180 #ifdef SPI_CLK_LOW_POWER
181 SPI_CLK_DISABLE
182 #endif
183 }
184
185
186 /*-----------------------------------------------------------------------*/
187 /* ABB_Read_Register_on_page() */
188 /* */
189 /* This function manages all the spi serial transfer to read one */
190 /* ABB register on a specified page. */
191 /* */
192 /* Returns the real data value of the register. */
193 /* */
194 /*-----------------------------------------------------------------------*/
195 SYS_UWORD16 ABB_Read_Register_on_page(SYS_UWORD16 page, SYS_UWORD16 reg_id)
196 {
197 volatile SYS_UWORD16 status;
198 SYS_UWORD16 reg_val;
199
200 // Start spi clock, mask IT for RD and WR and read SPI_REG_STATUS to reset the RE and WE flags.
201 SPI_Ready_for_RDWR
202 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
203
204 #if ((ABB_SEMAPHORE_PROTECTION == 1) || (ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
205
206 // check if the semaphore has been correctly created and try to obtain it.
207 // if the semaphore cannot be obtained, the task is suspended and then resumed
208 // as soon as the semaphore is released.
209 if(&abb_sem != 0)
210 {
211 NU_Obtain_Semaphore(&abb_sem, NU_SUSPEND);
212 }
213 #endif // ABB_SEMAPHORE_PROTECTION
214
215 /* set the ABB page for register access */
216 ABB_SetPage(page);
217
218 /* Read selected ABB register */
219 reg_val = ABB_ReadRegister(reg_id);
220
221 /* set the ABB page for register access at page 0 */
222 ABB_SetPage(PAGE0);
223
224 #if ((ABB_SEMAPHORE_PROTECTION == 1) || (ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
225 // release the semaphore only if it has correctly been created.
226 if(&abb_sem != 0)
227 {
228 NU_Release_Semaphore(&abb_sem);
229 }
230 #endif // ABB_SEMAPHORE_PROTECTION
231
232 // Stop the SPI clock
233 #ifdef SPI_CLK_LOW_POWER
234 SPI_CLK_DISABLE
235 #endif
236
237 return (reg_val); // Return result
238 }
239
240 /*------------------------------------------------------------------------*/
241 /* ABB_free_13M() */
242 /* */
243 /* This function sets the 13M clock working in ABB. A wait loop */
244 /* is required to allow first slow access to ABB clock register. */
245 /* */
246 /* WARNING !! : this function must not be protected by semaphore !! */
247 /* */
248 /*------------------------------------------------------------------------*/
249 void ABB_free_13M(void)
250 {
251 volatile SYS_UWORD16 status;
252
253 // Start spi clock, mask IT for WR and read SPI_REG_STATUS to reset the RE and WE flags.
254 SPI_Ready_for_WR
255 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
256
257 ABB_SetPage(PAGE0);
258
259 // This transmission frees the CLK13 in ABB.
260 ABB_WriteRegister(TOGBR2, 0x08);
261
262 // Wait for first IBIC access
263 ABB_Wait_IBIC_Access();
264
265 // SW Workaround : This transmission has to be done twice.
266 ABB_WriteRegister(TOGBR2, 0x08);
267
268 // Wait for first IBIC access
269 ABB_Wait_IBIC_Access();
270
271 // Stop the SPI clock
272 #ifdef SPI_CLK_LOW_POWER
273 SPI_CLK_DISABLE
274 #endif
275 }
276
277
278
279 /*------------------------------------------------------------------------*/
280 /* ABB_stop_13M() */
281 /* */
282 /* This function stops the 13M clock in ABB. */
283 /* */
284 /*------------------------------------------------------------------------*/
285 void ABB_stop_13M(void)
286 {
287 volatile SYS_UWORD16 status;
288
289 // Start spi clock, mask IT for WR and read SPI_REG_STATUS to reset the RE and WE flags.
290 SPI_Ready_for_WR
291 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
292
293 ABB_SetPage(PAGE0);
294
295 // Set ACTIVMCLK = 0.
296 ABB_WriteRegister(TOGBR2, 0x04);
297
298 // Wait for first IBIC access
299 ABB_Wait_IBIC_Access();
300
301 // Stop the SPI clock
302 #ifdef SPI_CLK_LOW_POWER
303 SPI_CLK_DISABLE
304 #endif
305 }
306
307
308
309 /*------------------------------------------------------------------------*/
310 /* ABB_Read_Status() */
311 /* */
312 /* This function reads and returns the value of VRPCSTS ABB register. */
313 /* */
314 /*------------------------------------------------------------------------*/
315 SYS_UWORD16 ABB_Read_Status(void)
316 {
317 volatile SYS_UWORD16 status;
318 SYS_UWORD16 reg_val;
319
320 // Start spi clock, mask IT for WR and read SPI_REG_STATUS to reset the RE and WE flags.
321 SPI_Ready_for_WR
322 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
323
324 #if ((ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
325
326 // check if the semaphore has been correctly created and try to obtain it.
327 // if the semaphore cannot be obtained, the task is suspended and then resumed
328 // as soon as the semaphore is released.
329 if(&abb_sem != 0)
330 {
331 NU_Obtain_Semaphore(&abb_sem, NU_SUSPEND);
332 }
333 #endif // ABB_SEMAPHORE_PROTECTION
334
335 ABB_SetPage(PAGE0);
336
337 #if (ANLG_FAM == 1) || (ANLG_FAM == 2)
338 ABB_SetPage(PAGE0);
339 reg_val = ABB_ReadRegister(VRPCSTS);
340 #elif (ANLG_FAM == 3)
341 ABB_SetPage(PAGE1);
342 reg_val = ABB_ReadRegister(VRPCCFG);
343 #endif
344
345 #if ((ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
346 // release the semaphore only if it has correctly been created.
347 if(&abb_sem != 0)
348 {
349 NU_Release_Semaphore(&abb_sem);
350 }
351 #endif // ABB_SEMAPHORE_PROTECTION
352
353 // Stop the SPI clock
354 #ifdef SPI_CLK_LOW_POWER
355 SPI_CLK_DISABLE
356 #endif
357
358 return (reg_val);
359 }
360
361 /*------------------------------------------------------------------------*/
362 /* ABB_on() */
363 /* */
364 /* This function configures ABB registers to work in ON condition */
365 /* */
366 /*------------------------------------------------------------------------*/
367 void ABB_on(SYS_UWORD16 modules, SYS_UWORD8 bRecoveryFlag)
368 {
369 volatile SYS_UWORD16 status;
370 #if ((ANLG_FAM ==2) || (ANLG_FAM == 3))
371 SYS_UWORD32 reg;
372 #endif
373
374 // a possible cause of the recovery is that ABB is on Oscas => switch from Oscas to CLK13
375 if (bRecoveryFlag)
376 {
377 // RESTITUTE 13MHZ CLOCK TO ABB
378 //---------------------------------------------------
379 ABB_free_13M();
380
381 // RESTITUTE 13MHZ CLOCK TO ABB AGAIN (C.F. BUG1719)
382 //---------------------------------------------------
383 ABB_free_13M();
384 }
385
386 // Start spi clock, mask IT for RD and WR and read SPI_REG_STATUS to reset the RE and WE flags.
387 SPI_Ready_for_RDWR
388 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
389
390 #if (ABB_SEMAPHORE_PROTECTION == 3)
391
392 // check if the semaphore has been correctly created and try to obtain it.
393 // if the semaphore cannot be obtained, the task is suspended and then resumed
394 // as soon as the semaphore is released.
395 if(&abb_sem != 0)
396 {
397 NU_Obtain_Semaphore(&abb_sem, NU_SUSPEND);
398 }
399 #endif // ABB_SEMAPHORE_PROTECTION
400
401 ABB_SetPage(PAGE0);
402
403 // This transmission disables MADC,AFC,VDL,VUL modules.
404 ABB_WriteRegister(TOGBR1, 0x0155);
405
406 #if (ANLG_FAM == 1)
407 // This transmission disables Band gap fast mode Enable BB charge.
408 ABB_WriteRegister(VRPCCTL2, 0x1fc);
409
410 /* *********** DC/DC enabling selection ************************************************************** */
411 // This transmission changes the register page in OMEGA for usp to pg1.
412 ABB_SetPage(PAGE1);
413
414 /* Insert here accesses to modify DC/DC parameters. Default is a switching frequency of 240 Khz */
415 {
416 SYS_UWORD8 vrpcctrl3_data;
417
418 #if (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11)
419 vrpcctrl3_data = 0x007d; // core voltage 1.4V for C035
420 #else
421 vrpcctrl3_data = 0x00bd; // core voltage 1.8V for C05
422 #endif
423
424 if(modules & DCDC) // check if the DCDC is enabled
425 {
426 vrpcctrl3_data |= 0x0002; // set DCDCEN
427 }
428
429 // This access disables the DCDC.
430 ABB_WriteRegister(VRPCCTRL3, vrpcctrl3_data);
431 }
432
433 /* ************************ SELECTION OF TEST MODE FOR ABB **************************************** */
434 /* This test configuration allows visibility on BULENA,BULON,BDLON,BDLENA on test pins */
435 /* ***************************************************************************************************/
436 #if (BOARD==6)&& (ANLG_FAM==1) //BUG01967 to remove access to TAPCTRL (EVA4 board and Nausica)
437 // This transmission enables Omega test register.
438 ABB_WriteRegister(TAPCTRL, 0x01);
439
440 // This transmission select Omega test instruction.
441 ABB_WriteRegister(TAPREG, TSPTEST1);
442
443 // This transmission disables Omega test register.
444 ABB_WriteRegister(TAPCTRL, 0x00);
445 #endif
446 /* *************************************************************************************************** */
447
448 if (!bRecoveryFlag) // Check recovery status from L1, prevent G23 SIM issue
449 {
450 // This transmission changes SIM power supply to 3 volts.
451 ABB_WriteRegister(VRPCCTRL1, 0x45);
452 }
453
454 ABB_SetPage(PAGE0);
455
456 // This transmission enables selected OMEGA modules.
457 ABB_WriteRegister(TOGBR1, (modules & ~DCDC) >> 6);
458
459 if(modules & MADC) // check if the ADC is enabled
460 {
461 // This transmission connects the resistive divider to MB and BB.
462 ABB_WriteRegister(BCICTL1, 0x0005);
463 }
464 #elif ((ANLG_FAM == 2) || (ANLG_FAM == 3))
465 // Restore the ABB checks and debouncing if start on TESTRESETZ
466
467 // This transmission changes the register page in the ABB for usp to pg1.
468 ABB_SetPage(PAGE1);
469
470 // This transmission sets the AFCCK to CKIN/2.
471 ABB_WriteRegister(AFCCTLADD, 0x01);
472
473 // This transmission enables the tapreg.
474 ABB_WriteRegister(TAPCTRL, 0x01);
475
476 // This transmission enables access to page 2.
477 ABB_WriteRegister(TAPREG, 0x01b);
478
479 // This transmission changes the register page in the ABB for usp to pg2.
480 ABB_SetPage(PAGE2);
481
482 #if (ANLG_FAM == 2)
483 // Restore push button environment
484 ABB_WriteRegister(0x3C, 0x07);
485
486 #elif (ANLG_FAM == 3)
487
488 // Restore push button environment
489 ABB_WriteRegister(0x3C, 0xBF);
490
491 /* ************************ SELECTION OF BBCFG CONFIG FOR ABB 3 PG1_0 *******************************/
492 #if (ANLG_PG == S_PG_10) // SYREN PG1.0 ON ESAMPLE
493 ABB_WriteRegister(BBCFG, C_BBCFG); // Initialize transmit register
494 #endif
495 // This transmission enables access to page 0.
496 ABB_SetPage(PAGE0);
497
498 // reset bit MSKINT1 , if set by TESTRESET
499 reg=ABB_ReadRegister(VRPCSTS) & 0xffe;
500
501 ABB_WriteRegister(VRPCSTS, reg);
502
503 ABB_SetPage(PAGE2);
504
505 // Restore default for BG behavior in sleep mode
506 ABB_WriteRegister(VRPCAUX, 0xBF);
507
508 // Restore default for deboucing length
509 ABB_WriteRegister(VRPCLDO, 0x00F);
510
511 // Restore default for INT1 generation, wait time in switch on, checks in switch on
512 ABB_WriteRegister(VRPCABBTST, 0x0002);
513
514 #endif
515
516 // This transmission changes the register page in the ABB for usp to pg1.
517 ABB_SetPage(PAGE1);
518
519 // This transmission sets tapinst to id code.
520 ABB_WriteRegister(TAPREG, 0x0001);
521
522 // This transmission disables TAPREG access.
523 ABB_WriteRegister(TAPCTRL, 0x00);
524
525 // enable BB battery charge BCICONF register, enable test mode to track BDLEN and BULEN windows
526 // This transmission enables BB charge and BB bridge connection for BB measurements.
527 #if ENABLE_BACKUP_BATTERY
528 ABB_WriteRegister(BCICONF, 0x060);
529 #else
530 ABB_WriteRegister(BCICONF, 0x000);
531 #endif
532
533 /* ************************ SELECTION OF BBCFG CONFIG FOR ABB 3 PG2_0 *******************************/
534 #if (ANLG_FAM == 3)
535 #if (ANLG_PG == S_PG_20) // SYREN PG2.0 ON EVACONSO
536 ABB_WriteRegister(BBCFG, C_BBCFG); // Initialize transmit register
537 #endif
538 #endif
539
540 /* ************************ SELECTION OF TEST MODE FOR ABB ******************************************/
541 /* This test configuration allows visibility on test pins TAPCTRL has not to be reset */
542 /* ****************************************************************************************************/
543
544 // This transmission enables the tapreg.
545 ABB_WriteRegister(TAPCTRL, 0x01);
546
547 // This transmission select ABB test instruction.
548 ABB_WriteRegister(TAPREG, TSPEN);
549
550 // This transmission changes the register page in ABB for usp to pg0.
551 ABB_SetPage(PAGE0);
552
553 // This transmission enables selected ABB modules.
554 ABB_WriteRegister(TOGBR1, modules >> 6);
555
556 // enable MB & BB resistive bridges for measurements
557 if(modules & MADC) // check if the ADC is enabled
558 {
559 // This transmission connects the resistive divider to MB and BB.
560 ABB_WriteRegister(BCICTL1, 0x0001);
561 }
562
563 /********* Sleep definition part ******************/
564 // This transmission changes the register page in the ABB for usp to pg1.
565 #if (ANLG_FAM == 2)
566 ABB_SetPage(PAGE1);
567
568 // update the Delay needed by the ABB before going in deep sleep, and clear previous delay value.
569 reg = ABB_ReadRegister(VRPCCFG) & 0x1e0;
570
571 ABB_WriteRegister(VRPCCFG, (SLPDLY | reg));
572
573 // update the ABB mask sleep register (regulator disabled in deep sleep), and clear previous mask value.
574 reg = ABB_ReadRegister(VRPCMSK) & 0x1e0;
575 ABB_WriteRegister(VRPCMSK, (MASK_SLEEP_MODE | reg));
576 #elif (ANLG_FAM == 3)
577 Syren_Sleep_Config(NORMAL_SLEEP,SLEEP_BG,SLPDLY);
578 #endif
579 // This transmission changes the register page in the ABB for usp to pg0.
580 ABB_SetPage(PAGE0);
581 #endif
582
583 // SW workaround for initialization of the audio parts of the ABB to avoid white noise
584 // C.f. BUG1941
585 // Set VDLR and VULR bits
586 // Write TOGBR1 register
587 // This transmission enables selected ABB modules.
588 ABB_WriteRegister(TOGBR1, 0x0A);
589
590 // wait for 1 ms
591 wait_ARM_cycles(convert_nanosec_to_cycles(1000000));
592
593 // Reset VDLS and VULS bits
594 // Write TOGBR1 register
595 // This transmission enables selected ABB modules.
596 ABB_WriteRegister(TOGBR1, 0x05);
597
598 #if (ABB_SEMAPHORE_PROTECTION == 3)
599 // release the semaphore only if it has correctly been created.
600 if(&abb_sem != 0)
601 {
602 NU_Release_Semaphore(&abb_sem);
603 }
604 #endif // ABB_SEMAPHORE_PROTECTION
605
606 // Stop the SPI clock
607 #ifdef SPI_CLK_LOW_POWER
608 SPI_CLK_DISABLE
609 #endif
610 }
611
612
613
614 /*-----------------------------------------------------------------------*/
615 /* ABB_Read_ADC() */
616 /* */
617 /* This function manages all the spi serial transfer to read all the */
618 /* ABB ADC conversion channels. */
619 /* Stores the result in Buff parameter. */
620 /* */
621 /*-----------------------------------------------------------------------*/
622 void ABB_Read_ADC(SYS_UWORD16 *Buff)
623 {
624 volatile SYS_UWORD16 status;
625
626 // Start spi clock, mask IT for RD and WR and read SPI_REG_STATUS to reset the RE and WE flags.
627 SPI_Ready_for_RDWR
628 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
629
630 #if (ABB_SEMAPHORE_PROTECTION == 3)
631
632 // check if the semaphore has been correctly created and try to obtain it.
633 // if the semaphore cannot be obtained, the task is suspended and then resumed
634 // as soon as the semaphore is released.
635 if(&abb_sem != 0)
636 {
637 NU_Obtain_Semaphore(&abb_sem, NU_SUSPEND);
638 }
639 #endif // ABB_SEMAPHORE_PROTECTION
640
641 // This transmission changes the register page in the ABB for usp to pg0.
642 ABB_SetPage(PAGE0);
643
644 /* Read all ABB ADC registers */
645 *Buff++ = ABB_ReadRegister(VBATREG);
646 *Buff++ = ABB_ReadRegister(VCHGREG);
647 *Buff++ = ABB_ReadRegister(ICHGREG);
648 *Buff++ = ABB_ReadRegister(VBKPREG);
649 *Buff++ = ABB_ReadRegister(ADIN1REG);
650 *Buff++ = ABB_ReadRegister(ADIN2REG);
651 *Buff++ = ABB_ReadRegister(ADIN3REG);
652
653 #if (ANLG_FAM ==1)
654 *Buff++ = ABB_ReadRegister(ADIN4XREG);
655 *Buff++ = ABB_ReadRegister(ADIN5YREG);
656 #elif (ANLG_FAM ==2)
657 *Buff++ = ABB_ReadRegister(ADIN4REG);
658 #elif (ANLG_FAM == 3)
659 *Buff++ = ABB_ReadRegister(ADIN4REG);
660 *Buff++ = ABB_ReadRegister(ADIN5REG);
661 #endif // ANLG_FAM
662
663 #if (ABB_SEMAPHORE_PROTECTION == 3)
664 // release the semaphore only if it has correctly been created.
665 if(&abb_sem != 0)
666 {
667 NU_Release_Semaphore(&abb_sem);
668 }
669 #endif // ABB_SEMAPHORE_PROTECTION
670
671 // Stop the SPI clock
672 #ifdef SPI_CLK_LOW_POWER
673 SPI_CLK_DISABLE
674 #endif
675 }
676
677
678
679 /*-----------------------------------------------------------------------*/
680 /* ABB_Conf_ADC() */
681 /* */
682 /* This function manages all the spi serial transfer to: */
683 /* - select the ABB ADC channels to be converted */
684 /* - enable/disable EOC interrupt */
685 /* */
686 /*-----------------------------------------------------------------------*/
687 void ABB_Conf_ADC(SYS_UWORD16 Channels, SYS_UWORD16 ItVal)
688 {
689 volatile SYS_UWORD16 status;
690 SYS_UWORD16 reg_val;
691
692 // Start spi clock, mask IT for RD and WR and read SPI_REG_STATUS to reset the RE and WE flags.
693 SPI_Ready_for_RDWR
694 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
695
696 #if (ABB_SEMAPHORE_PROTECTION == 3)
697
698 // check if the semaphore has been correctly created and try to obtain it.
699 // if the semaphore cannot be obtained, the task is suspended and then resumed
700 // as soon as the semaphore is released.
701 if(&abb_sem != 0)
702 {
703 NU_Obtain_Semaphore(&abb_sem, NU_SUSPEND);
704 }
705 #endif // ABB_SEMAPHORE_PROTECTION
706
707 // This transmission changes the register page in the ABB for usp to pg0.
708 ABB_SetPage(PAGE0);
709
710 /* select ADC channels to be converted */
711 #if (ANLG_FAM == 1)
712 ABB_WriteRegister(MADCCTRL1, Channels);
713 #elif ((ANLG_FAM == 2) || (ANLG_FAM == 3))
714 ABB_WriteRegister(MADCCTRL, Channels);
715 #endif
716
717 reg_val = ABB_ReadRegister(ITMASK);
718
719 // This transmission configure the End Of Conversion IT without modifying other bits in the same register.
720 if(ItVal == EOC_INTENA)
721 ABB_WriteRegister(ITMASK, reg_val & EOC_INTENA);
722 else if(ItVal == EOC_INTMASK)
723 ABB_WriteRegister(ITMASK, reg_val | EOC_INTMASK);
724
725 #if (ABB_SEMAPHORE_PROTECTION == 3)
726 // release the semaphore only if it has correctly been created.
727 if(&abb_sem != 0)
728 {
729 NU_Release_Semaphore(&abb_sem);
730 }
731 #endif // ABB_SEMAPHORE_PROTECTION
732
733 // Stop the SPI clock
734 #ifdef SPI_CLK_LOW_POWER
735 SPI_CLK_DISABLE
736 #endif
737 }
738
739
740
741
742 /*------------------------------------------------------------------------*/
743 /* ABB_sleep() */
744 /* */
745 /* This function disables the DCDC and returns to PAGE 0. It stops then */
746 /* the 13MHz clock in ABB. A wait loop s required to allow */
747 /* first slow access to ABB clock register. */
748 /* */
749 /* WARNING !! : this function must not be protected by semaphore !! */
750 /* */
751 /* Returns AFC value. */
752 /* */
753 /*------------------------------------------------------------------------*/
754 SYS_UWORD32 ABB_sleep(SYS_UWORD8 sleep_performed, SYS_WORD16 afc)
755 {
756 volatile SYS_UWORD16 status;
757 SYS_UWORD32 afcout_index;
758 volatile SYS_UWORD16 nb_it;
759 SYS_UWORD16 reg_val;
760
761 // table for AFC allowed values during Sleep mode. First 5th elements
762 // are related to positive AFC values, last 5th to negative ones.
763 SYS_UWORD32 Afcout_T[10]= {0x0f,0x1f,0x3f,0x7f,0xff,0x00,0x01,0x03,0x07,0x0f};
764
765 // Start spi clock, mask IT for RD and WR and read SPI_REG_STATUS to reset the RE and WE flags.
766 SPI_Ready_for_RDWR
767 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
768
769 // COMPUTATION AND PROGRAMMING OF AFC VALUE
770 //---------------------------------------------------
771 if(afc & 0x1000)
772 afcout_index = ((afc + 512)>>10) + 1;
773 else
774 afcout_index = (afc + 512)>>10;
775
776 if (sleep_performed == FRAME_STOP) // Big sleep
777 {
778 #if ((ANLG_FAM == 2) || (ANLG_FAM == 3))
779 //////////// ADD HERE IOTA or SYREN CONFIGURATION FOR BIG SLEEP ////////////////////////////
780 #endif
781
782 }
783 else // Deep sleep
784 {
785 #if(ANLG_FAM == 1)
786 // SELECTION OF AFC TEST MODE FOR OMEGA
787 //---------------------------------------------------
788 // This test configuration allows access on the AFCOUT register
789 ABB_SetPage(PAGE1);
790
791 // This transmission enables OMEGA test register.
792 ABB_WriteRegister(TAPCTRL, 0x01);
793
794 // This transmission selects OMEGA test instruction.
795 ABB_WriteRegister(TAPREG, AFCTEST);
796
797 // Set AFCOUT to 0.
798 ABB_WriteRegister(AFCOUT, 0x00 >> 6);
799
800 ABB_SetPage(PAGE0);
801
802 #elif (ANLG_FAM == 2)
803 // This configuration allows access on the AFCOUT register
804 ABB_SetPage(PAGE1);
805
806 // Read AFCCTLADD value and enable USP access to AFCOUT register
807 reg_val = (ABB_ReadRegister(AFCCTLADD) | 0x04);
808
809 ABB_WriteRegister(AFCCTLADD, reg_val);
810
811 // Set AFCOUT to 0.
812 ABB_WriteRegister(AFCOUT, 0x00);
813
814 #if ENABLE_BACKUP_BATTERY
815 // Read BCICONF value and cut the measurement bridge of BB cut the BB charge.
816 reg_val = ABB_ReadRegister(BCICONF) & 0x039f;
817
818 ABB_WriteRegister(BCICONF, reg_val);
819 #endif
820
821 // Disable the ABB test mode
822 ABB_WriteRegister(TAPCTRL, 0x00);
823
824 ABB_SetPage(PAGE0);
825
826 // Read BCICTL1 value and cut the measurement bridge of MB.
827 reg_val = ABB_ReadRegister(BCICTL1) & 0x03fe;
828
829 ABB_WriteRegister(BCICTL1, reg_val);
830 #endif
831
832 #if (ANLG_FAM == 3) // Nothing to be done as MB and BB measurement bridges are automatically disconnected
833 // in Syren during sleep mode. BB charge stays enabled
834 ABB_SetPage(PAGE1); // Initialize transmit reg_num. This transmission
835 // change the register page in IOTA for usp to pg1
836
837 ABB_WriteRegister(TAPCTRL, 0x00); // Disable Syren test mode
838
839 ABB_SetPage(PAGE0);
840 #endif
841
842 // switch off MADC, AFC, AUXDAC, VOICE.
843 ABB_WriteRegister(TOGBR1, 0x155);
844
845 // Switch off Analog supply LDO
846 //-----------------------------
847 #if (ANLG_FAM == 1)
848 ABB_SetPage(PAGE1);
849
850 // Read VRPCCTL3 register value and switch off VR3.
851 reg_val = ABB_ReadRegister(VRPCCTRL3) & 0x3df;
852
853 ABB_WriteRegister(VRPCCTRL3, reg_val);
854
855 #elif (ANLG_FAM == 2)
856 // Read VRPCSTS register value and extract status of meaningfull inputs.
857 reg_val = ABB_ReadRegister(VRPCSTS) & 0x0070;
858
859 if (reg_val == 0x30)
860 {
861 // start the SLPDLY counter in order to switch the ABB in sleep mode. This transmission sets IOTA sleep bit.
862 ABB_WriteRegister(VRPCDEV, 0x02);
863 }
864
865 // Dummy transmission to clean of ABB bus. This transmission accesses IOTA address 0 in "read".
866 ABB_WriteRegister(0x0000 | 0x0001, 0x0000);
867
868 #elif (ANLG_FAM == 3)
869 // In Syren there is no need to check for VRPCCFG as wake up prioritys are changed
870 // start the SLPDLY counter in order to switch the ABB in sleep mode
871 ABB_WriteRegister(VRPCDEV,0x02); // Initialize transmit reg_num. This transmission
872 // set Syren sleep bit
873 /*
874 // Dummy transmission to clean of ABB bus. This transmission accesses SYREN address 0 in "read".
875 ABB_WriteRegister(0x0000 | 0x0001, 0x0000);
876 */
877 #endif
878
879 // Switch to low frequency clock
880 ABB_stop_13M();
881 }
882
883 // Stop the SPI clock
884 #ifdef SPI_CLK_LOW_POWER
885 SPI_CLK_DISABLE
886 #endif
887
888 #if (OP_L1_STANDALONE == 1)
889 #if (CHIPSET == 12)
890 // GPIO_InitAllPull(ALL_ONE); // enable all GPIO internal pull
891 // workaround to set APLL_DIV_CLK( internal PU) at high level
892 // by default APLL_DIV_CLK is low pulling 80uA on VRIO
893 // *(SYS_UWORD16*) (0xFFFFFD90)= 0x01;//CNTL_APLL_DIV_CLK -> APLL_CLK_DIV != 0
894 // *(SYS_UWORD16*) (0xFFFEF030)= 0x10;// DPLL mode
895 #endif
896 #endif
897 return(Afcout_T[afcout_index]);
898 }
899
900
901 /*------------------------------------------------------------------------*/
902 /* ABB_wakeup() */
903 /* */
904 /* This function sets the 13MHz clock working in ABB. A wait loop */
905 /* is required to allow first slow access to ABB clock register. */
906 /* Then it re-enables DCDC and returns to PAGE 0. */
907 /* */
908 /* WARNING !! : this function must not be protected by semaphore !! */
909 /* */
910 /*------------------------------------------------------------------------*/
911 void ABB_wakeup(SYS_UWORD8 sleep_performed, SYS_WORD16 afc)
912 {
913 volatile SYS_UWORD16 status;
914 SYS_UWORD16 reg_val;
915
916 // Start spi clock, mask IT for RD and WR and read SPI_REG_STATUS to reset the RE and WE flags.
917 SPI_Ready_for_RDWR
918 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
919
920 if (sleep_performed == FRAME_STOP) // Big sleep
921 {
922 #if ((ANLG_FAM == 2) || (ANLG_FAM == 3))
923 //////////// ADD HERE IOTA or SYREN CONFIGURATION FOR BIG SLEEP WAKEUP ////////////////////////////
924 #endif
925 }
926 else // Deep sleep
927 {
928 #if (OP_L1_STANDALONE == 1)
929 #if (CHIPSET == 12)
930 // restore context from
931 // workaround to set APLL_DIV_CLK( internal PU) at high level
932 // by default APLL_DIV_CLK is low pulling 80uA on VRIO
933 // *(SYS_UWORD16*) (0xFFFFFD90)= 0x00;//CNTL_APLL_DIV_CLK -> APLL_DIV_CLK != 0
934 // *(SYS_UWORD16*) (0xFFFEF030)= 0x00;// DPLL mode
935 #endif
936 #endif
937
938 // Restitutes 13MHZ Clock to ABB
939 ABB_free_13M();
940
941 // Switch ON Analog supply LDO
942 #if (ANLG_FAM == 1)
943 ABB_SetPage(PAGE1);
944
945 // Read VRPCCTL3 register value and switch on VR3.
946 reg_val = ABB_ReadRegister(VRPCCTRL3) | 0x020;
947
948 ABB_WriteRegister(VRPCCTRL3, reg_val);
949 ABB_SetPage(PAGE0);
950 #endif
951
952 // This transmission switches on MADC, AFC.
953 ABB_WriteRegister(TOGBR1, 0x280);
954
955 // This transmission sets the AUXAFC2.
956 ABB_WriteRegister(AUXAFC2, ((afc>>10) & 0x7));
957
958 // This transmission sets the AUXAFC1.
959 ABB_WriteRegister(AUXAFC1, (afc & 0x3ff));
960
961 #if (ANLG_FAM == 1)
962 // Remove AFC test mode
963 ABB_SetPage(PAGE1);
964
965 // This transmission select Omega test instruction.
966 ABB_WriteRegister(TAPREG, TSPTEST1);
967
968 // Disable test mode selection
969 // This transmission disables Omega test register.
970 ABB_WriteRegister(TAPCTRL, 0x00 >> 6);
971
972 ABB_SetPage(PAGE0);
973
974 #elif (ANLG_FAM == 2)
975 ABB_SetPage(PAGE1);
976
977 // Read AFCCTLADD register value and disable USP access to AFCOUT register.
978 reg_val = ABB_ReadRegister(AFCCTLADD) & ~0x04;
979
980 ABB_WriteRegister(AFCCTLADD, reg_val);
981
982 #if ENABLE_BACKUP_BATTERY
983 // Read BCICONF register value and enable BB measurement bridge enable BB charge.
984 reg_val = ABB_ReadRegister(BCICONF) | 0x0060;
985
986 ABB_WriteRegister(BCICONF, reg_val);
987 #endif
988
989
990 /* *************************************************************************************************** */
991 // update the Delay needed by the ABB before going in deep sleep, and clear previous delay value.
992 reg_val = ABB_ReadRegister(VRPCCFG) & 0x1e0;
993 ABB_WriteRegister(VRPCCFG, (SLPDLY | reg_val));
994
995 // Enable the ABB test mode
996 ABB_WriteRegister(TAPCTRL, 0x01);
997 ABB_WriteRegister(TAPREG, TSPEN);
998 ABB_SetPage(PAGE0);
999
1000 // Read BCICTL1 register value and enable MB measurement bridge and cut the measurement bridge of MB.
1001 reg_val = ABB_ReadRegister(BCICTL1) | 0x0001;
1002
1003 ABB_WriteRegister(BCICTL1, reg_val);
1004 #endif
1005
1006 #if (ANLG_FAM == 3)
1007
1008 ABB_SetPage(PAGE1);
1009
1010 /* *************************************************************************************************** */
1011 // update the Delay needed by the ABB before going in deep sleep, and clear previous delay value.
1012 reg_val = ABB_ReadRegister(VRPCCFG) & 0x1e0;
1013 ABB_WriteRegister(VRPCCFG, (SLPDLY | reg_val));
1014
1015 /* ************************ SELECTION OF TEST MODE FOR ABB=3 *****************************************/
1016 /* This test configuration allows visibility on test pins TAPCTRL has not to be reset */
1017 /* ****************************************************************************************************/
1018
1019 ABB_WriteRegister(TAPCTRL, 0x01); // Initialize the transmit register
1020 // This transmission enables IOTA test register
1021
1022 ABB_WriteRegister(TAPREG, TSPEN);
1023 // This transmission select IOTA test instruction
1024 // This transmission select IOTA test instruction
1025 /**************************************************************************************************** */
1026
1027 ABB_SetPage(PAGE0); // Initialize transmit reg_num. This transmission
1028 #endif
1029 }
1030
1031 // Stop the SPI clock
1032 #ifdef SPI_CLK_LOW_POWER
1033 SPI_CLK_DISABLE
1034 #endif
1035 }
1036
1037 /*------------------------------------------------------------------------*/
1038 /* ABB_wa_VRPC() */
1039 /* */
1040 /* This function initializes the VRPCCTRL1 or VRPCSIM register */
1041 /* according to the ABB used. */
1042 /* */
1043 /*------------------------------------------------------------------------*/
1044 void ABB_wa_VRPC(SYS_UWORD16 value)
1045 {
1046 volatile SYS_UWORD16 status;
1047
1048 // Start spi clock, mask IT for WR and read SPI_REG_STATUS to reset the RE and WE flags.
1049 SPI_Ready_for_WR
1050 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
1051
1052 #if ((ABB_SEMAPHORE_PROTECTION == 1) || (ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
1053
1054 // check if the semaphore has been correctly created and try to obtain it.
1055 // if the semaphore cannot be obtained, the task is suspended and then resumed
1056 // as soon as the semaphore is released.
1057 if(&abb_sem != 0)
1058 {
1059 NU_Obtain_Semaphore(&abb_sem, NU_SUSPEND);
1060 }
1061 #endif // ABB_SEMAPHORE_PROTECTION
1062
1063 ABB_SetPage(PAGE1);
1064
1065 #if (ANLG_FAM == 1)
1066 // This transmission initializes the VRPCCTL1 register.
1067 ABB_WriteRegister(VRPCCTRL1, value);
1068
1069 #elif (ANLG_FAM == 2)
1070 // This transmission initializes the VRPCSIM register.
1071 ABB_WriteRegister(VRPCSIM, value);
1072
1073 #elif (ANLG_FAM == 3)
1074 // This transmission initializes the VRPCSIMR register.
1075 ABB_WriteRegister(VRPCSIMR, value);
1076
1077 #endif
1078
1079 ABB_SetPage(PAGE0);
1080
1081 #if ((ABB_SEMAPHORE_PROTECTION == 1) || (ABB_SEMAPHORE_PROTECTION == 2) || (ABB_SEMAPHORE_PROTECTION == 3))
1082 // release the semaphore only if it has correctly been created.
1083 if(&abb_sem != 0)
1084 {
1085 NU_Release_Semaphore(&abb_sem);
1086 }
1087 #endif // ABB_SEMAPHORE_PROTECTION
1088
1089 // Stop the SPI clock
1090 #ifdef SPI_CLK_LOW_POWER
1091 SPI_CLK_DISABLE
1092 #endif
1093 }
1094
1095
1096 /*-----------------------------------------------------------------------*/
1097 /* ABB_Write_Uplink_Data() */
1098 /* */
1099 /* This function uses the SPI to write to ABB uplink buffer. */
1100 /* */
1101 /*-----------------------------------------------------------------------*/
1102 void ABB_Write_Uplink_Data(SYS_UWORD16 *TM_ul_data)
1103 {
1104 SYS_UWORD8 i;
1105 volatile SYS_UWORD16 status;
1106
1107 // Start spi clock, mask IT for WR and read SPI_REG_STATUS to reset the RE and WE flags.
1108 SPI_Ready_for_WR
1109 status = * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
1110
1111 // Select Page 0 for TOGBR2
1112 ABB_SetPage(PAGE0);
1113
1114 // Initialize pointer of burst buffer 1 : IBUFPTR is bit 10 of TOGBR2
1115 ABB_WriteRegister(TOGBR2, 0x10);
1116
1117 // Clear, assuming that it works like IBUFPTR of Vega
1118 ABB_WriteRegister(TOGBR2, 0x0);
1119
1120 // Write the ramp data
1121 for (i=0;i<16;i++)
1122 ABB_WriteRegister(BULDATA1_2, TM_ul_data[i]>>6);
1123
1124 // Stop the SPI clock
1125 #ifdef SPI_CLK_LOW_POWER
1126 SPI_CLK_DISABLE
1127 #endif
1128 }
1129
1130 //////////////////////// IDEV-INLO integration of sleep mode for Syren ///////////////////////////////////////
1131
1132 #if (ANLG_FAM == 3)
1133
1134 // Syren Sleep configuration function --------------------------
1135 void Syren_Sleep_Config(SYS_UWORD16 sleep_type,SYS_UWORD16 bg_select, SYS_UWORD16 sleep_delay)
1136 {
1137 volatile SYS_UWORD16 status,sl_ldo_stat;
1138
1139 ABB_SetPage(PAGE1); // Initialize transmit register. This transmission
1140 // change the register page in ABB for usp to pg1
1141
1142 ABB_WriteRegister(VRPCCFG, sleep_delay); // write delay value
1143
1144 sl_ldo_stat = ((sleep_type<<9|bg_select<<8) & 0x0374);
1145
1146 ABB_WriteRegister(VRPCMSKSLP, sl_ldo_stat); // write sleep ldo configuration
1147
1148 ABB_SetPage(PAGE0); // Initialize transmit register. This transmission
1149 // change the register page in ABB for usp to pg0
1150 }
1151 #endif
1152
1153
1154 #if (OP_L1_STANDALONE == 0)
1155 /*-----------------------------------------------------------------------*/
1156 /* ABB_Power_Off() */
1157 /* */
1158 /* This function uses the SPI to switch off the ABB. */
1159 /* */
1160 /*-----------------------------------------------------------------------*/
1161 void ABB_Power_Off(void)
1162 {
1163 // Wait until all necessary actions are performed (write in FFS, etc...) to power-off the board (empirical value - 30 ticks).
1164 NU_Sleep (30);
1165
1166 // Wait also until <ON/OFF> key is released.
1167 // This is needed to avoid, if the power key is pressed for a long time, to switch
1168 // ON-switch OFF the mobile, until the power key is released.
1169 #if((ANLG_FAM == 1) || (ANLG_FAM == 2))
1170 while ((ABB_Read_Status() & ONREFLT) == PWR_OFF_KEY_PRESSED) {
1171 #elif(ANLG_FAM == 3)
1172 while ((ABB_Read_Register_on_page(PAGE1, VRPCCFG) & PWOND) == PWR_OFF_KEY_PRESSED) {
1173 #endif
1174
1175 NU_Sleep (1); }
1176
1177 BZ_KeyBeep_OFF();
1178
1179 #if(ANLG_FAM == 1)
1180 ABB_Write_Register_on_page(PAGE0, VRPCCTL2, 0x00EE);
1181 #elif((ANLG_FAM == 2) || (ANLG_FAM == 3))
1182 ABB_Write_Register_on_page(PAGE0, VRPCDEV, 0x0001);
1183 #endif
1184 }
1185 #endif
1186
1187
1188