comparison gsm-fw/bsp/abb+spi/abb.c @ 148:63750f70796d

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