]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4_SimpleLink_CC3220SF_CCS/ti/devices/cc32xx/driverlib/prcm.c
Add SimpleLink CC3220SF demo.
[freertos] / FreeRTOS / Demo / CORTEX_M4_SimpleLink_CC3220SF_CCS / ti / devices / cc32xx / driverlib / prcm.c
1 /*\r
2  * -------------------------------------------\r
3  *    CC3220 SDK - v0.10.00.00 \r
4  * -------------------------------------------\r
5  *\r
6  *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ \r
7  *  \r
8  *  Redistribution and use in source and binary forms, with or without \r
9  *  modification, are permitted provided that the following conditions \r
10  *  are met:\r
11  *\r
12  *    Redistributions of source code must retain the above copyright \r
13  *    notice, this list of conditions and the following disclaimer.\r
14  *\r
15  *    Redistributions in binary form must reproduce the above copyright\r
16  *    notice, this list of conditions and the following disclaimer in the \r
17  *    documentation and/or other materials provided with the   \r
18  *    distribution.\r
19  *\r
20  *    Neither the name of Texas Instruments Incorporated nor the names of\r
21  *    its contributors may be used to endorse or promote products derived\r
22  *    from this software without specific prior written permission.\r
23  *\r
24  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
25  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
26  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
27  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
28  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
29  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
30  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
31  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
32  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
33  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
34  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
35  *  \r
36  */\r
37 \r
38 //*****************************************************************************\r
39 //\r
40 //! \addtogroup PRCM_Power_Reset_Clock_Module_api\r
41 //! @{\r
42 //\r
43 //*****************************************************************************\r
44 \r
45 #include "inc/hw_types.h"\r
46 #include "inc/hw_ints.h"\r
47 #include "inc/hw_memmap.h"\r
48 #include "inc/hw_apps_rcm.h"\r
49 #include "inc/hw_gprcm.h"\r
50 #include "inc/hw_hib1p2.h"\r
51 #include "inc/hw_hib3p3.h"\r
52 #include "inc/hw_ocp_shared.h"\r
53 #include "inc/hw_common_reg.h"\r
54 #include "prcm.h"\r
55 #include "interrupt.h"\r
56 #include "cpu.h"\r
57 #include "flash.h"\r
58 #include "utils.h"\r
59 \r
60 \r
61 //*****************************************************************************\r
62 // Macro definition\r
63 //*****************************************************************************\r
64 #define PRCM_SOFT_RESET           0x00000001\r
65 #define PRCM_ENABLE_STATUS        0x00000002\r
66 #define SYS_CLK                   80000000\r
67 #define XTAL_CLK                  40000000\r
68 \r
69 \r
70 //*****************************************************************************\r
71 //    CC3200 does not have a true RTC capability. However, API(s) in this file\r
72 //    provide an effective mechanism to support RTC feature in the device.\r
73 //\r
74 //    The implementation to support RTC has been kept very simple. A set of\r
75 //    HIB Memory Registers in conjunction with Slow Clock Counter are used\r
76 //    to render RTC information to users. Core principle of design involves\r
77 //    two steps (a) establish an association between user provided wall-clock\r
78 //    and slow clock counter. (b) store reference value of this associattion\r
79 //    in HIB Registers. This reference value and SCC value are then combined\r
80 //    to create real-world calendar time.\r
81 //\r
82 //    Across HIB cycles, value stored in HIB Registers is retained and slow\r
83 //    clock counter continues to tick, thereby, this arragement is relevant\r
84 //    and valid as long as device has a (tickle) battery power.\r
85 //\r
86 //    Further, provision also has been made to set an alarm. When it RTC value\r
87 //    matches that of set for alarm, an interrupt is generated.\r
88 //\r
89 //    HIB MEM REG0 and REG1 are reserved for TI.\r
90 //\r
91 //    If RTC feature is not used, then HIB REG2 & REG3 are available to user.\r
92 //\r
93 //    Lower half of REG0 is used for TI HW ECO.\r
94 //*****************************************************************************\r
95 #define RTC_U64MSEC_MK(u32Secs, u16Msec) (((unsigned long long)u32Secs << 10)|\\r
96                                           (u16Msec & 0x3FF))\r
97 \r
98 #define RTC_SECS_IN_U64MSEC(u64Msec)     ((unsigned long)(u64Msec  >>   10))\r
99 #define RTC_MSEC_IN_U64MSEC(u64Msec)     ((unsigned short)(u64Msec & 0x3FF))\r
100 \r
101 #define RTC_SECS_U32_REG_ADDR            (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG3)\r
102 #define RTC_MSEC_U16_REG_ADDR            (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2+2)\r
103 \r
104 #define RTC_U32SECS_REG                 (HWREG(RTC_SECS_U32_REG_ADDR))\r
105 #define RTC_U16MSEC_REG                 (*(unsigned short*)RTC_MSEC_U16_REG_ADDR)\r
106 \r
107 //*****************************************************************************\r
108 // Register Access and Updates\r
109 //\r
110 // Tick of SCC has a resolution of 32768Hz, meaning 1 sec is equal to 32768\r
111 // clock ticks. Ideal way of getting time in millisecond will involve floating\r
112 // point arithmetic (division by 32.768). To avoid this, we simply divide it by\r
113 // 32, which will give a range from 0 -1023(instead of 0-999). To use this\r
114 // output correctly we have to take care of this inaccuracy externally.\r
115 // following wrapper can be used to convert the value from cycles to\r
116 // millisecond:\r
117 //\r
118 // CYCLES_U16MS(cycles) ((cycles *1000)/ 1024),\r
119 //\r
120 // Similarly, before setting the value, it must be first converted (from ms to\r
121 // cycles).\r
122 //\r
123 // U16MS_CYCLES(msec)   ((msec *1024)/1000)\r
124 //\r
125 // Note: There is a precision loss of 1 ms with the above scheme.\r
126 //\r
127 //*****************************************************************************\r
128 #define SCC_U64MSEC_GET()                (PRCMSlowClkCtrGet() >> 5)\r
129 #define SCC_U64MSEC_MATCH_SET(u64Msec)   (PRCMSlowClkCtrMatchSet(u64Msec << 5))\r
130 #define SCC_U64MSEC_MATCH_GET()          (PRCMSlowClkCtrMatchGet() >> 5)\r
131 \r
132 //*****************************************************************************\r
133 //\r
134 // Bit:  31 is used to indicate use of RTC. If set as '1', RTC feature is used.\r
135 // Bits: 30 to 26 are reserved, available to software for use\r
136 // Bits: 25 to 16 are used to save millisecond part of RTC reference.\r
137 // Bits: 15 to 0 are being used for HW Changes / ECO\r
138 //\r
139 //*****************************************************************************\r
140 \r
141 //*****************************************************************************\r
142 // Set RTC USE Bit\r
143 //*****************************************************************************\r
144 static void RTCUseSet(void)\r
145 {\r
146   unsigned short usRegValue;\r
147 \r
148   usRegValue = RTC_U16MSEC_REG |  (1 << 15);\r
149 \r
150   UtilsDelay((80*200)/3);\r
151 \r
152   RTC_U16MSEC_REG = usRegValue;\r
153 }\r
154 \r
155 //*****************************************************************************\r
156 // Checks if RTC-USE bit is set\r
157 //*****************************************************************************\r
158 static tBoolean IsRTCUsed(void)\r
159 {\r
160   unsigned short usRegValue;\r
161 \r
162   usRegValue = RTC_U16MSEC_REG;\r
163 \r
164   UtilsDelay((80*200)/3);\r
165 \r
166   return ((usRegValue & (1 << 15))? true : false);\r
167 }\r
168 \r
169 //*****************************************************************************\r
170 // Read 16-bit mSecs\r
171 //*****************************************************************************\r
172 static unsigned short RTCU16MSecRegRead(void)\r
173 {\r
174   unsigned short usRegValue;\r
175 \r
176   usRegValue = RTC_U16MSEC_REG;\r
177 \r
178   UtilsDelay((80*200)/3);\r
179 \r
180   return (usRegValue & 0x3FF);\r
181 }\r
182 \r
183 //*****************************************************************************\r
184 // Write 16-bit mSecs\r
185 //*****************************************************************************\r
186 static void RTCU16MSecRegWrite(unsigned short u16Msec)\r
187 {\r
188    unsigned short usRegValue;\r
189 \r
190    usRegValue = RTC_U16MSEC_REG;\r
191 \r
192    UtilsDelay((80*200)/3);\r
193 \r
194    RTC_U16MSEC_REG = ((usRegValue & ~0x3FF) |u16Msec);\r
195 }\r
196 \r
197 //*****************************************************************************\r
198 // Read 32-bit Secs\r
199 //*****************************************************************************\r
200 static unsigned long RTCU32SecRegRead(void)\r
201 {\r
202   return (PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR));\r
203 }\r
204 \r
205 //*****************************************************************************\r
206 // Write 32-bit Secs\r
207 //*****************************************************************************\r
208 static void RTCU32SecRegWrite(unsigned long u32Msec)\r
209 {\r
210    PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec);\r
211 }\r
212 \r
213 //*****************************************************************************\r
214 // Macros\r
215 //*****************************************************************************\r
216 #define IS_RTC_USED()                   IsRTCUsed()\r
217 #define RTC_USE_SET()                   RTCUseSet()\r
218 \r
219 #define RTC_U16MSEC_REG_RD()            RTCU16MSecRegRead()\r
220 #define RTC_U16MSEC_REG_WR(u16Msec)     RTCU16MSecRegWrite(u16Msec)\r
221 \r
222 #define RTC_U32SECS_REG_RD()            RTCU32SecRegRead()\r
223 #define RTC_U32SECS_REG_WR(u32Secs)     RTCU32SecRegWrite(u32Secs)\r
224 \r
225 #define SELECT_SCC_U42BITS(u64Msec)     (u64Msec & 0x3ffffffffff)\r
226 \r
227 //*****************************************************************************\r
228 // Global Peripheral clock and rest Registers\r
229 //*****************************************************************************\r
230 static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] =\r
231 {\r
232 \r
233         {APPS_RCM_O_CAMERA_CLK_GATING,   APPS_RCM_O_CAMERA_SOFT_RESET   },\r
234         {APPS_RCM_O_MCASP_CLK_GATING,    APPS_RCM_O_MCASP_SOFT_RESET    },\r
235         {APPS_RCM_O_MMCHS_CLK_GATING,    APPS_RCM_O_MMCHS_SOFT_RESET    },\r
236         {APPS_RCM_O_MCSPI_A1_CLK_GATING, APPS_RCM_O_MCSPI_A1_SOFT_RESET },\r
237         {APPS_RCM_O_MCSPI_A2_CLK_GATING, APPS_RCM_O_MCSPI_A2_SOFT_RESET },\r
238         {APPS_RCM_O_UDMA_A_CLK_GATING,   APPS_RCM_O_UDMA_A_SOFT_RESET   },\r
239         {APPS_RCM_O_GPIO_A_CLK_GATING,   APPS_RCM_O_GPIO_A_SOFT_RESET   },\r
240         {APPS_RCM_O_GPIO_B_CLK_GATING,   APPS_RCM_O_GPIO_B_SOFT_RESET   },\r
241         {APPS_RCM_O_GPIO_C_CLK_GATING,   APPS_RCM_O_GPIO_C_SOFT_RESET   },\r
242         {APPS_RCM_O_GPIO_D_CLK_GATING,   APPS_RCM_O_GPIO_D_SOFT_RESET   },\r
243         {APPS_RCM_O_GPIO_E_CLK_GATING,   APPS_RCM_O_GPIO_E_SOFT_RESET   },\r
244         {APPS_RCM_O_WDOG_A_CLK_GATING,   APPS_RCM_O_WDOG_A_SOFT_RESET   },\r
245         {APPS_RCM_O_UART_A0_CLK_GATING,  APPS_RCM_O_UART_A0_SOFT_RESET  },\r
246         {APPS_RCM_O_UART_A1_CLK_GATING,  APPS_RCM_O_UART_A1_SOFT_RESET  },\r
247         {APPS_RCM_O_GPT_A0_CLK_GATING ,  APPS_RCM_O_GPT_A0_SOFT_RESET   },\r
248         {APPS_RCM_O_GPT_A1_CLK_GATING,   APPS_RCM_O_GPT_A1_SOFT_RESET   },\r
249         {APPS_RCM_O_GPT_A2_CLK_GATING,   APPS_RCM_O_GPT_A2_SOFT_RESET   },\r
250         {APPS_RCM_O_GPT_A3_CLK_GATING,   APPS_RCM_O_GPT_A3_SOFT_RESET   },\r
251         {APPS_RCM_O_CRYPTO_CLK_GATING,   APPS_RCM_O_CRYPTO_SOFT_RESET   },\r
252         {APPS_RCM_O_MCSPI_S0_CLK_GATING, APPS_RCM_O_MCSPI_S0_SOFT_RESET },\r
253         {APPS_RCM_O_I2C_CLK_GATING,      APPS_RCM_O_I2C_SOFT_RESET      }\r
254 \r
255 };\r
256 \r
257 //*****************************************************************************\r
258 //\r
259 //! Performs a software reset of a MCU and associated peripherals\r
260 //!\r
261 //! \param bIncludeSubsystem is \b true to reset associated peripherals.\r
262 //!\r
263 //! This function performs a software reset of a MCU and associated peripherals.\r
264 //! To reset the associated peripheral, the parameter \e bIncludeSubsystem\r
265 //! should be set to \b true.\r
266 //!\r
267 //! \return None.\r
268 //\r
269 //*****************************************************************************\r
270 void PRCMMCUReset(tBoolean bIncludeSubsystem)\r
271 {\r
272   if(bIncludeSubsystem)\r
273   {\r
274     //\r
275     // Reset Apps processor and associated peripheral\r
276     //\r
277     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x2;\r
278   }\r
279   else\r
280   {\r
281     //\r
282     // Reset Apps processor only\r
283     //\r
284     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x1;\r
285   }\r
286 \r
287   //\r
288   // Wait for system to enter hibernate\r
289   //\r
290   __asm("    wfi\n");\r
291 \r
292   //\r
293   // Infinite loop\r
294   //\r
295   while(1)\r
296   {\r
297 \r
298   }\r
299 }\r
300 \r
301 //*****************************************************************************\r
302 //\r
303 //! Gets the reason for a reset.\r
304 //!\r
305 //! This function returns the reason(s) for a reset. The reset reason are:-\r
306 //! -\b PRCM_POWER_ON  - Device is powering up.\r
307 //! -\b PRCM_LPDS_EXIT - Device is exiting from LPDS.\r
308 //! -\b PRCM_CORE_RESET - Device is exiting soft core only reset\r
309 //! -\b PRCM_MCU_RESET - Device is exiting soft subsystem reset.\r
310 //! -\b PRCM_WDT_RESET - Device was reset by watchdog.\r
311 //! -\b PRCM_SOC_RESET - Device is exting SOC reset.\r
312 //! -\b PRCM_HIB_EXIT - Device is exiting hibernate.\r
313 //!\r
314 //! \return Returns one of the cause defined above.\r
315 //\r
316 //*****************************************************************************\r
317 unsigned long PRCMSysResetCauseGet()\r
318 {\r
319   unsigned long ulWakeupStatus;\r
320 \r
321   //\r
322   // Read the Reset status\r
323   //\r
324   ulWakeupStatus = (HWREG(GPRCM_BASE+ GPRCM_O_APPS_RESET_CAUSE) & 0xFF);\r
325 \r
326   //\r
327   // For hibernate do additional check.\r
328   //\r
329   if(ulWakeupStatus == PRCM_POWER_ON)\r
330   {\r
331     if(PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1)\r
332     {\r
333       ulWakeupStatus = PRCM_HIB_EXIT;\r
334 \r
335       if( (HWREG(OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_8) & (0x00000280)) == 0x00000280  )\r
336       {\r
337         ulWakeupStatus = PRCM_WDT_RESET;\r
338       }\r
339     }\r
340   }\r
341   else if((ulWakeupStatus == PRCM_LPDS_EXIT) &&\r
342           !(HWREG(GPRCM_BASE + GPRCM_O_GPRCM_EFUSE_READ_REG1) & (1 <<2)) )\r
343   {\r
344     if(HWREG(OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_8) & (0x1<<8))\r
345     {\r
346       ulWakeupStatus = PRCM_POWER_ON;\r
347     }\r
348   }\r
349 \r
350   //\r
351   // Return status.\r
352   //\r
353   return ulWakeupStatus;\r
354 }\r
355 \r
356 //*****************************************************************************\r
357 //\r
358 //! Enable clock(s) to peripheral.\r
359 //!\r
360 //! \param ulPeripheral is one of the valid peripherals\r
361 //! \param ulClkFlags are bitmask of clock(s) to be enabled.\r
362 //!\r
363 //! This function enables the clock for the specified peripheral. Peripherals\r
364 //! are by default clock gated (disabled) and generates a bus fault if\r
365 //! accessed.\r
366 //!\r
367 //! The parameter \e ulClkFlags can be logical OR of the following:\r
368 //! -\b PRCM_RUN_MODE_CLK - Ungates clock to the peripheral\r
369 //! -\b PRCM_SLP_MODE_CLK - Keeps the clocks ungated in sleep.\r
370 //!\r
371 //! \return None.\r
372 //\r
373 //*****************************************************************************\r
374 void\r
375 PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags)\r
376 {\r
377   //\r
378   // Enable the specified peripheral clocks, Nothing to be done for PRCM_ADC\r
379   // as it is a dummy define for pinmux utility code generation\r
380   //\r
381   if(ulPeripheral != PRCM_ADC)\r
382   {\r
383     HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) |= ulClkFlags;\r
384   }\r
385   \r
386   //\r
387   // Checking ROM Version less than 2.x.x. \r
388   // Only for driverlib backward compatibility\r
389   //\r
390   if( (HWREG(0x00000400) & 0xFFFF) < 2 )\r
391   {\r
392     //\r
393     // Set the default clock for camera\r
394     //\r
395     if(ulPeripheral == PRCM_CAMERA)\r
396     {\r
397       HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) = 0x0404;\r
398     }\r
399   }\r
400 }\r
401 \r
402 //*****************************************************************************\r
403 //\r
404 //! Disables clock(s) to peripheral.\r
405 //!\r
406 //! \param ulPeripheral is one of the valid peripherals\r
407 //! \param ulClkFlags are bitmask of clock(s) to be enabled.\r
408 //!\r
409 //! This function disable the clock for the specified peripheral. Peripherals\r
410 //! are by default clock gated (disabled) and generated a bus fault if\r
411 //! accessed.\r
412 //!\r
413 //! The parameter \e ulClkFlags can be logical OR bit fields as defined in\r
414 //! PRCMEnablePeripheral().\r
415 //!\r
416 //! \return None.\r
417 //\r
418 //*****************************************************************************\r
419 void\r
420 PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags)\r
421 {\r
422   //\r
423   // Disable the specified peripheral clocks\r
424   //\r
425   HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) &= ~ulClkFlags;\r
426 }\r
427 \r
428 //*****************************************************************************\r
429 //\r
430 //! Gets the input clock for the specified peripheral.\r
431 //!\r
432 //! \param ulPeripheral is one of the valid peripherals.\r
433 //!\r
434 //! This function gets the input clock for the specified peripheral.\r
435 //!\r
436 //! The parameter \e ulPeripheral has the same definition as that in\r
437 //! PRCMPeripheralClkEnable();\r
438 //!\r
439 //! \return Returns input clock frequency for specified peripheral.\r
440 //\r
441 //*****************************************************************************\r
442 unsigned long\r
443 PRCMPeripheralClockGet(unsigned long ulPeripheral)\r
444 {\r
445   unsigned long ulClockFreq;\r
446   unsigned long ulHiPulseDiv;\r
447   unsigned long ulLoPulseDiv;\r
448 \r
449   //\r
450   // Get the clock based on specified peripheral.\r
451   //\r
452   if(((ulPeripheral == PRCM_SSPI) | (ulPeripheral == PRCM_LSPI)\r
453             | (ulPeripheral == PRCM_GSPI)))\r
454   {\r
455     return XTAL_CLK;\r
456   }\r
457   else if(ulPeripheral == PRCM_CAMERA)\r
458   {\r
459     ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) >> 8) & 0x07);\r
460     ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN)& 0xFF);\r
461   }\r
462   else if(ulPeripheral == PRCM_SDHOST)\r
463   {\r
464     ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN) >> 8) & 0x07);\r
465     ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN)& 0xFF);\r
466   }\r
467   else\r
468   {\r
469     return SYS_CLK;\r
470   }\r
471 \r
472   //\r
473   // Compute the clock freq. from the divider value\r
474   //\r
475   ulClockFreq = (240000000/((ulHiPulseDiv + 1) + (ulLoPulseDiv + 1)));\r
476 \r
477   //\r
478   // Return the clock rate.\r
479   //\r
480   return ulClockFreq;\r
481 }\r
482 \r
483 //*****************************************************************************\r
484 //\r
485 //! Performs a software reset of a peripheral.\r
486 //!\r
487 //! \param ulPeripheral is one of the valid peripheral.\r
488 //!\r
489 //! This function does soft reset of the specified peripheral\r
490 //!\r
491 //! \return None.\r
492 //\r
493 //*****************************************************************************\r
494 void\r
495 PRCMPeripheralReset(unsigned long ulPeripheral)\r
496 {\r
497   volatile unsigned long ulDelay;\r
498 \r
499   if( ulPeripheral != PRCM_DTHE)\r
500   {\r
501     //\r
502     // Assert the reset\r
503     //\r
504     HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg)\r
505                                                          |= PRCM_SOFT_RESET;\r
506     //\r
507     // Delay a little bit.\r
508     //\r
509     for(ulDelay = 0; ulDelay < 16; ulDelay++)\r
510     {\r
511     }\r
512 \r
513     //\r
514     // Deassert the reset\r
515     //\r
516     HWREG(ARCM_BASE+PRCM_PeriphRegsList[ulPeripheral].ulRstReg)\r
517                                                           &= ~PRCM_SOFT_RESET;\r
518   }\r
519 }\r
520 \r
521 //*****************************************************************************\r
522 //\r
523 //! Determines if a peripheral is ready.\r
524 //!\r
525 //! \param ulPeripheral is one of the valid modules\r
526 //!\r
527 //! This function determines if a particular peripheral is ready to be\r
528 //! accessed. The peripheral may be in a non-ready state if it is not enabled,\r
529 //! is being held in reset, or is in the process of becoming ready after being\r
530 //! enabled or taken out of reset.\r
531 //!\r
532 //! \return Returns \b true if the  peripheral is ready, \b false otherwise.\r
533 //\r
534 //*****************************************************************************\r
535 tBoolean\r
536 PRCMPeripheralStatusGet(unsigned long ulPeripheral)\r
537 {\r
538   unsigned long ReadyBit;\r
539 \r
540   //\r
541   // Read the ready bit status\r
542   //\r
543   ReadyBit = HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg);\r
544   ReadyBit = ReadyBit & PRCM_ENABLE_STATUS;\r
545 \r
546   if (ReadyBit)\r
547   {\r
548     //\r
549     // Module is ready\r
550     //\r
551     return(true);\r
552   }\r
553   else\r
554   {\r
555     //\r
556     // Module is not ready\r
557     //\r
558     return(false);\r
559   }\r
560 }\r
561 \r
562 //*****************************************************************************\r
563 //\r
564 //! Configure I2S fracactional divider\r
565 //!\r
566 //! \param ulI2CClkFreq is the required input clock for McAPS module\r
567 //!\r
568 //! This function configures I2S fractional divider. By default this\r
569 //! divider is set to output 24 Mhz clock to I2S module.\r
570 //!\r
571 //! The minimum frequency that can be obtained by configuring this divider is\r
572 //!\r
573 //! (240000KHz/1023.99) =  234.377 KHz\r
574 //!\r
575 //! \return None.\r
576 //\r
577 //*****************************************************************************\r
578 void\r
579 PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)\r
580 {\r
581   unsigned long long ullDiv;\r
582   unsigned short usInteger;\r
583   unsigned short usFrac;\r
584 \r
585   ullDiv = (((unsigned long long)240000000 * 65536)/ulI2CClkFreq);\r
586 \r
587   usInteger = (ullDiv/65536);\r
588   usFrac    = (ullDiv%65536);\r
589 \r
590   HWREG(ARCM_BASE + APPS_RCM_O_MCASP_FRAC_CLK_CONFIG0) =\r
591     ((usInteger & 0x3FF) << 16 | usFrac);\r
592 }\r
593 \r
594 //*****************************************************************************\r
595 //\r
596 //! Sets the LPDS exit PC and SP restore vlaues.\r
597 //!\r
598 //! \param ulStackPtr is the SP restore value.\r
599 //! \param ulProgCntr is the PC restore value\r
600 //!\r
601 //! This function sets the LPDS exit PC and SP restore vlaues. Setting\r
602 //! \e ulProgCntr to a non-zero value, forces bootloader to jump to that\r
603 //! address with Stack Pointer initialized to \e ulStackPtr on LPDS exit,\r
604 //! otherwise the application's vector table entries are used.\r
605 //!\r
606 //! \return None.\r
607 //\r
608 //*****************************************************************************\r
609 void\r
610 PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr)\r
611 {\r
612   //\r
613   // ROM Version 2.x.x or greater\r
614   //\r
615   if( (HWREG(0x00000400) & 0xFFFF) >= 2 )\r
616   {\r
617     //\r
618     // Set The SP Value\r
619     //\r
620     HWREG(0x4402E160) = ulStackPtr;\r
621 \r
622     //\r
623     // Set The PC Value\r
624     //\r
625     HWREG(0x4402E198) = ulProgCntr;\r
626 \r
627   }\r
628   else\r
629   {\r
630     //\r
631     // Set The SP Value\r
632     //\r
633     HWREG(0x4402E18C) = ulStackPtr;\r
634 \r
635     //\r
636     // Set The PC Value\r
637     //\r
638     HWREG(0x4402E190) = ulProgCntr;\r
639   }\r
640 }\r
641 \r
642 //*****************************************************************************\r
643 //\r
644 //! Puts the system into Low Power Deel Sleep (LPDS) power mode.\r
645 //!\r
646 //! This function puts the system into Low Power Deel Sleep (LPDS) power mode.\r
647 //! A call to this function never returns and the execution starts from Reset.\r
648 //! \sa PRCMLPDSRestoreInfoSet().\r
649 //!\r
650 //! \return None.\r
651 //!\r
652 //! \note  External debugger will always disconnect whenever the system\r
653 //!  enters LPDS and debug interface is shutdown until next POR reset. In order\r
654 //!  to avoid this and allow for connecting back the debugger after waking up\r
655 //!  from LPDS \sa PRCMLPDSEnterKeepDebugIf().\r
656 //!\r
657 //\r
658 //*****************************************************************************\r
659 void\r
660 PRCMLPDSEnter()\r
661 {\r
662   unsigned long ulChipId;\r
663 \r
664   //\r
665   // Read the Chip ID\r
666   //\r
667   ulChipId = ((HWREG(GPRCM_BASE + GPRCM_O_GPRCM_EFUSE_READ_REG2) >> 16) & 0x1F);\r
668 \r
669   //\r
670   // Check if flash exists\r
671   //\r
672   if( (0x11 == ulChipId) || (0x19 == ulChipId))\r
673   {\r
674 \r
675     //\r
676     // Disable the flash\r
677     //\r
678     FlashDisable();\r
679   }\r
680 \r
681 #ifndef KEEP_TESTPD_ALIVE\r
682 \r
683   //\r
684   // Disable TestPD\r
685   //\r
686   HWREG(0x4402E168) |= (1<<9);\r
687 #endif\r
688 \r
689   //\r
690   // Set bandgap duty cycle to 1\r
691   //\r
692   HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;\r
693 \r
694   //\r
695   // Request LPDS\r
696   //\r
697   HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ)\r
698           = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ;\r
699 \r
700   //\r
701   // Wait for system to enter LPDS\r
702   //\r
703   __asm("    wfi\n");\r
704 \r
705   //\r
706   // Infinite loop\r
707   //\r
708   while(1)\r
709   {\r
710 \r
711   }\r
712 \r
713 }\r
714 \r
715 \r
716 //*****************************************************************************\r
717 //\r
718 //! Puts the system into Low Power Deel Sleep (LPDS) power mode keeping\r
719 //! debug interface alive.\r
720 //!\r
721 //! This function puts the system into Low Power Deel Sleep (LPDS) power mode\r
722 //! keeping debug interface alive. A call to this function never returns and the\r
723 //! execution starts from Reset \sa PRCMLPDSRestoreInfoSet().\r
724 //!\r
725 //! \return None.\r
726 //!\r
727 //! \note External debugger will always disconnect whenever the system\r
728 //!  enters LPDS, using this API will allow connecting back the debugger after\r
729 //!  waking up from LPDS. This API is recommended for development purposes\r
730 //!  only as it adds to the current consumption of the system.\r
731 //!\r
732 //\r
733 //*****************************************************************************\r
734 void\r
735 PRCMLPDSEnterKeepDebugIf()\r
736 {\r
737   unsigned long ulChipId;\r
738 \r
739   //\r
740   // Read the Chip ID\r
741   //\r
742   ulChipId = ((HWREG(GPRCM_BASE + GPRCM_O_GPRCM_EFUSE_READ_REG2) >> 16) & 0x1F);\r
743 \r
744   //\r
745   // Check if flash exists\r
746   //\r
747   if( (0x11 == ulChipId) || (0x19 == ulChipId))\r
748   {\r
749 \r
750     //\r
751     // Disable the flash\r
752     //\r
753     FlashDisable();\r
754   }\r
755 \r
756   //\r
757   // Set bandgap duty cycle to 1\r
758   //\r
759   HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;\r
760 \r
761   //\r
762   // Request LPDS\r
763   //\r
764   HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ)\r
765           = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ;\r
766 \r
767   //\r
768   // Wait for system to enter LPDS\r
769   //\r
770   __asm("    wfi\n");\r
771 \r
772   //\r
773   // Infinite loop\r
774   //\r
775   while(1)\r
776   {\r
777 \r
778   }\r
779 \r
780 }\r
781 \r
782 //*****************************************************************************\r
783 //\r
784 //! Enable the individual LPDS wakeup source(s).\r
785 //!\r
786 //! \param ulLpdsWakeupSrc is logical OR of wakeup sources.\r
787 //!\r
788 //! This function enable the individual LPDS wakeup source(s) and following\r
789 //! three wakeup sources (\e ulLpdsWakeupSrc ) are supported by the device.\r
790 //! -\b PRCM_LPDS_HOST_IRQ\r
791 //! -\b PRCM_LPDS_GPIO\r
792 //! -\b PRCM_LPDS_TIMER\r
793 //!\r
794 //! \return None.\r
795 //\r
796 //*****************************************************************************\r
797 void\r
798 PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)\r
799 {\r
800   unsigned long ulRegVal;\r
801 \r
802   //\r
803   // Read the current wakup sources\r
804   //\r
805   ulRegVal = HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG);\r
806 \r
807   //\r
808   // Enable individual wakeup source\r
809   //\r
810   ulRegVal = ((ulRegVal | ulLpdsWakeupSrc) & 0x91);\r
811 \r
812   //\r
813   // Set the configuration in the register\r
814   //\r
815   HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) = ulRegVal;\r
816 }\r
817 \r
818 //*****************************************************************************\r
819 //\r
820 //! Disable the individual LPDS wakeup source(s).\r
821 //!\r
822 //! \param ulLpdsWakeupSrc is logical OR of wakeup sources.\r
823 //!\r
824 //! This function enable the individual LPDS wakeup source(s) and following\r
825 //! three wake up sources (\e ulLpdsWakeupSrc ) are supported by the device.\r
826 //! -\b PRCM_LPDS_HOST_IRQ\r
827 //! -\b PRCM_LPDS_GPIO\r
828 //! -\b PRCM_LPDS_TIMER\r
829 //!\r
830 //! \return None.\r
831 //\r
832 //*****************************************************************************\r
833 void\r
834 PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)\r
835 {\r
836   HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) &= ~ulLpdsWakeupSrc;\r
837 }\r
838 \r
839 \r
840 //*****************************************************************************\r
841 //\r
842 //! Get LPDS wakeup cause\r
843 //!\r
844 //! This function gets LPDS wakeup caouse\r
845 //!\r
846 //! \return Returns values enumerated as described in\r
847 //! PRCMLPDSWakeupSourceEnable().\r
848 //\r
849 //*****************************************************************************\r
850 unsigned long\r
851 PRCMLPDSWakeupCauseGet()\r
852 {\r
853   return (HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_SRC));\r
854 }\r
855 \r
856 //*****************************************************************************\r
857 //\r
858 //! Sets LPDS wakeup Timer\r
859 //!\r
860 //! \param ulTicks is number of 32.768 KHz clocks\r
861 //!\r
862 //! This function sets internal LPDS wakeup timer running at 32.768 KHz. The\r
863 //! timer is only configured if the parameter \e ulTicks is in valid range i.e.\r
864 //! from 21 to 2^32.\r
865 //!\r
866 //! \return Returns \b true on success, \b false otherwise.\r
867 //\r
868 //*****************************************************************************\r
869 void\r
870 PRCMLPDSIntervalSet(unsigned long ulTicks)\r
871 {\r
872   //\r
873   // Check sleep is atleast for 21 cycles\r
874   // If not set the sleep time to 21 cycles\r
875   //\r
876   if( ulTicks < 21)\r
877   {\r
878       ulTicks = 21;\r
879   }\r
880 \r
881   HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_WAKE_CFG) = ulTicks;\r
882   HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_OPP_CFG) = ulTicks-20;\r
883 }\r
884 \r
885 //*****************************************************************************\r
886 //\r
887 //! Selects the GPIO for LPDS wakeup\r
888 //!\r
889 //! \param ulGPIOPin is one of the valid GPIO fro LPDS wakeup.\r
890 //! \param ulType is the wakeup trigger type.\r
891 //!\r
892 //! This function setects the wakeup GPIO for LPDS wakeup and can be\r
893 //! used to select one out of 7 pre-defined GPIO(s).\r
894 //!\r
895 //! The parameter \e ulLpdsGPIOSel should be one of the following:-\r
896 //! -\b PRCM_LPDS_GPIO2\r
897 //! -\b PRCM_LPDS_GPIO4\r
898 //! -\b PRCM_LPDS_GPIO13\r
899 //! -\b PRCM_LPDS_GPIO17\r
900 //! -\b PRCM_LPDS_GPIO11\r
901 //! -\b PRCM_LPDS_GPIO24\r
902 //! -\b PRCM_LPDS_GPIO26\r
903 //!\r
904 //! The parameter \e ulType sets the trigger type and can be one of the\r
905 //! following:\r
906 //! - \b PRCM_LPDS_LOW_LEVEL\r
907 //! - \b PRCM_LPDS_HIGH_LEVEL\r
908 //! - \b PRCM_LPDS_FALL_EDGE\r
909 //! - \b PRCM_LPDS_RISE_EDGE\r
910 //!\r
911 //! \return None.\r
912 //\r
913 //*****************************************************************************\r
914 void\r
915 PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)\r
916 {\r
917   //\r
918   // Set the wakeup GPIO\r
919   //\r
920   PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin);\r
921 \r
922   //\r
923   // Set the trigger type.\r
924   //\r
925   HWREG(GPRCM_BASE + GPRCM_O_APPS_GPIO_WAKE_CONF) = (ulType & 0x3);\r
926 }\r
927 \r
928 //*****************************************************************************\r
929 //\r
930 //! Puts the system into Sleep.\r
931 //!\r
932 //! This function puts the system into sleep power mode. System exits the power\r
933 //! state on any one of the available interrupt. On exit from sleep mode the\r
934 //! function returns to the calling function with all the processor core\r
935 //! registers retained.\r
936 //!\r
937 //! \return None.\r
938 //\r
939 //*****************************************************************************\r
940 void\r
941 PRCMSleepEnter()\r
942 {\r
943   //\r
944   // Request Sleep\r
945   //\r
946   CPUwfi();\r
947 }\r
948 \r
949 //*****************************************************************************\r
950 //\r
951 //! Enable SRAM column retention during LPDS Power mode(s)\r
952 //!\r
953 //! \param ulSramColSel is bit mask of valid SRAM columns.\r
954 //! \param ulModeFlags is the bit mask of power modes.\r
955 //!\r
956 //! This functions enables the SRAM retention. The device supports configurable\r
957 //! SRAM column retention in Low Power Deep Sleep (LPDS). Each column is of\r
958 //! 64 KB size.\r
959 //!\r
960 //! The parameter \e ulSramColSel should be logical OR of the following:-\r
961 //! -\b PRCM_SRAM_COL_1\r
962 //! -\b PRCM_SRAM_COL_2\r
963 //! -\b PRCM_SRAM_COL_3\r
964 //! -\b PRCM_SRAM_COL_4\r
965 //!\r
966 //! The parameter \e ulModeFlags selects the power modes and sholud be logical\r
967 //! OR of one or more of the following\r
968 //! -\b PRCM_SRAM_LPDS_RET\r
969 //!\r
970 //! \return None.\r
971 //\r
972 //****************************************************************************\r
973 void\r
974 PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags)\r
975 {\r
976   if(ulModeFlags & PRCM_SRAM_LPDS_RET)\r
977   {\r
978     //\r
979     // Configure LPDS SRAM retention register\r
980     //\r
981     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) = (ulSramColSel & 0xF);\r
982   }\r
983 }\r
984 \r
985 //*****************************************************************************\r
986 //\r
987 //! Disable SRAM column retention during LPDS Power mode(s).\r
988 //!\r
989 //! \param ulSramColSel is bit mask of valid SRAM columns.\r
990 //! \param ulFlags is the bit mask of power modes.\r
991 //!\r
992 //! This functions disable the SRAM retention. The device supports configurable\r
993 //! SRAM column retention in Low Power Deep Sleep (LPDS). Each column is\r
994 //! of 64 KB size.\r
995 //!\r
996 //! The parameter \e ulSramColSel should be logical OR of the following:-\r
997 //! -\b PRCM_SRAM_COL_1\r
998 //! -\b PRCM_SRAM_COL_2\r
999 //! -\b PRCM_SRAM_COL_3\r
1000 //! -\b PRCM_SRAM_COL_4\r
1001 //!\r
1002 //! The parameter \e ulFlags selects the power modes and sholud be logical OR\r
1003 //! of one or more of the following\r
1004 //! -\b PRCM_SRAM_LPDS_RET\r
1005 //!\r
1006 //! \return None.\r
1007 //\r
1008 //****************************************************************************\r
1009 void\r
1010 PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags)\r
1011 {\r
1012   if(ulFlags & PRCM_SRAM_LPDS_RET)\r
1013   {\r
1014     //\r
1015     // Configure LPDS SRAM retention register\r
1016     //\r
1017     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) &= ~(ulSramColSel & 0xF);\r
1018   }\r
1019 }\r
1020 \r
1021 \r
1022 //*****************************************************************************\r
1023 //\r
1024 //! Enables individual HIB wakeup source(s).\r
1025 //!\r
1026 //! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.\r
1027 //!\r
1028 //! This function enables individual HIB wakeup source(s). The paramter\r
1029 //! \e ulHIBWakupSrc is the bit mask of HIB wakeup sources and should be\r
1030 //! logical OR of one or more of the follwoing :-\r
1031 //! -\b PRCM_HIB_SLOW_CLK_CTR\r
1032 //! -\b PRCM_HIB_GPIO2\r
1033 //! -\b PRCM_HIB_GPIO4\r
1034 //! -\b PRCM_HIB_GPIO13\r
1035 //! -\b PRCM_HIB_GPIO17\r
1036 //! -\b PRCM_HIB_GPIO11\r
1037 //! -\b PRCM_HIB_GPIO24\r
1038 //! -\b PRCM_HIB_GPIO26\r
1039 //!\r
1040 //! \return None.\r
1041 //\r
1042 //*****************************************************************************\r
1043 void\r
1044 PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)\r
1045 {\r
1046   unsigned long ulRegValue;\r
1047 \r
1048   //\r
1049   // Read the RTC register\r
1050   //\r
1051   ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);\r
1052 \r
1053   //\r
1054   // Enable the RTC as wakeup source if specified\r
1055   //\r
1056   ulRegValue |= (ulHIBWakupSrc & 0x1);\r
1057 \r
1058   //\r
1059   // Enable HIB wakeup sources\r
1060   //\r
1061   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);\r
1062 \r
1063   //\r
1064   // REad the GPIO wakeup configuration register\r
1065   //\r
1066   ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);\r
1067 \r
1068   //\r
1069   // Enable the specified GPIOs a wakeup sources\r
1070   //\r
1071   ulRegValue |= ((ulHIBWakupSrc>>16)&0xFF);\r
1072 \r
1073   //\r
1074   // Write the new register configuration\r
1075   //\r
1076   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);\r
1077 }\r
1078 \r
1079 //*****************************************************************************\r
1080 //\r
1081 //! Disable individual HIB wakeup source(s).\r
1082 //!\r
1083 //! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.\r
1084 //!\r
1085 //! This function disable individual HIB wakeup source(s). The paramter\r
1086 //! \e ulHIBWakupSrc is same as bit fileds defined in\r
1087 //! PRCMEnableHibernateWakeupSource()\r
1088 //!\r
1089 //! \return None.\r
1090 //\r
1091 //*****************************************************************************\r
1092 void\r
1093 PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)\r
1094 {\r
1095   unsigned long ulRegValue;\r
1096 \r
1097   //\r
1098   // Read the RTC register\r
1099   //\r
1100   ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);\r
1101 \r
1102   //\r
1103   // Disable the RTC as wakeup source if specified\r
1104   //\r
1105   ulRegValue &= ~(ulHIBWakupSrc & 0x1);\r
1106 \r
1107   //\r
1108   // Disable HIB wakeup sources\r
1109   //\r
1110   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);\r
1111 \r
1112   //\r
1113   // Read the GPIO wakeup configuration register\r
1114   //\r
1115   ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);\r
1116 \r
1117   //\r
1118   // Enable the specified GPIOs a wakeup sources\r
1119   //\r
1120   ulRegValue &= ~((ulHIBWakupSrc>>16)&0xFF);\r
1121 \r
1122   //\r
1123   // Write the new register configuration\r
1124   //\r
1125   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);\r
1126 }\r
1127 \r
1128 \r
1129 //*****************************************************************************\r
1130 //\r
1131 //! Get hibernate wakeup cause\r
1132 //!\r
1133 //! This function gets the hibernate wakeup cause.\r
1134 //!\r
1135 //! \return Returns \b PRCM_HIB_WAKEUP_CAUSE_SLOW_CLOCK or\r
1136 //! \b PRCM_HIB_WAKEUP_CAUSE_GPIO\r
1137 //\r
1138 //*****************************************************************************\r
1139 unsigned long\r
1140 PRCMHibernateWakeupCauseGet()\r
1141 {\r
1142   //\r
1143   // Supported only in ES2.00 and Later devices i.e. ROM Version 2.x.x or greater\r
1144   //\r
1145   if( (HWREG(0x00000400) & 0xFFFF) >= 2 )\r
1146   {\r
1147       return ((PRCMHIBRegRead((OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_8))>>2)&0xF);\r
1148   }\r
1149   else\r
1150   {\r
1151       return(0);\r
1152   }\r
1153 }\r
1154 \r
1155 //*****************************************************************************\r
1156 //\r
1157 //! Sets Hibernate wakeup Timer\r
1158 //!\r
1159 //! \param ullTicks is number of 32.768 KHz clocks\r
1160 //!\r
1161 //! This function sets internal hibernate wakeup timer running at 32.768 KHz.\r
1162 //!\r
1163 //! \return Returns \b true on success, \b false otherwise.\r
1164 //\r
1165 //*****************************************************************************\r
1166 void\r
1167 PRCMHibernateIntervalSet(unsigned long long ullTicks)\r
1168 {\r
1169   unsigned long long ullRTCVal;\r
1170 \r
1171   //\r
1172   // Latch the RTC vlaue\r
1173   //\r
1174   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1);\r
1175 \r
1176   //\r
1177   // Read latched values as 2 32-bit vlaues\r
1178   //\r
1179   ullRTCVal  = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);\r
1180   ullRTCVal  = ullRTCVal << 32;\r
1181   ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);\r
1182 \r
1183   //\r
1184   // Add the interval\r
1185   //\r
1186   ullRTCVal = ullRTCVal + ullTicks;\r
1187 \r
1188   //\r
1189   // Set RTC match value\r
1190   //\r
1191   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF,\r
1192                                             (unsigned long)(ullRTCVal));\r
1193   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF,\r
1194                                            (unsigned long)(ullRTCVal>>32));\r
1195 }\r
1196 \r
1197 \r
1198 //*****************************************************************************\r
1199 //\r
1200 //! Selects the GPIO(s) for hibernate wakeup\r
1201 //!\r
1202 //! \param ulGPIOBitMap is the bit-map of valid hibernate wakeup GPIO.\r
1203 //! \param ulType is the wakeup trigger type.\r
1204 //!\r
1205 //! This function setects the wakeup GPIO for hibernate and can be\r
1206 //! used to select any combination of 7 pre-defined GPIO(s).\r
1207 //!\r
1208 //! This function enables individual HIB wakeup source(s). The paramter\r
1209 //! \e ulGPIOBitMap should be one of the follwoing :-\r
1210 //! -\b PRCM_HIB_GPIO2\r
1211 //! -\b PRCM_HIB_GPIO4\r
1212 //! -\b PRCM_HIB_GPIO13\r
1213 //! -\b PRCM_HIB_GPIO17\r
1214 //! -\b PRCM_HIB_GPIO11\r
1215 //! -\b PRCM_HIB_GPIO24\r
1216 //! -\b PRCM_HIB_GPIO26\r
1217 //!\r
1218 //! The parameter \e ulType sets the trigger type and can be one of the\r
1219 //! following:\r
1220 //! - \b PRCM_HIB_LOW_LEVEL\r
1221 //! - \b PRCM_HIB_HIGH_LEVEL\r
1222 //! - \b PRCM_HIB_FALL_EDGE\r
1223 //! - \b PRCM_HIB_RISE_EDGE\r
1224 //!\r
1225 //! \return None.\r
1226 //\r
1227 //*****************************************************************************\r
1228 void\r
1229 PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)\r
1230 {\r
1231   unsigned char ucLoop;\r
1232   unsigned long ulRegValue;\r
1233 \r
1234   //\r
1235   // Shift the bits to extract the GPIO selection\r
1236   //\r
1237   ulGPIOBitMap >>= 16;\r
1238 \r
1239   //\r
1240   // Set the configuration for each GPIO\r
1241   //\r
1242   for(ucLoop=0; ucLoop < 7; ucLoop++)\r
1243   {\r
1244     if(ulGPIOBitMap & (1<<ucLoop))\r
1245     {\r
1246       ulRegValue  = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF);\r
1247       ulRegValue = (ulRegValue & (~(0x3 << (ucLoop*2)))) | (ulType <<(ucLoop*2));\r
1248       PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF, ulRegValue);\r
1249     }\r
1250   }\r
1251 }\r
1252 \r
1253 //*****************************************************************************\r
1254 //\r
1255 //! Puts the system into Hibernate\r
1256 //!\r
1257 //! This function puts the system into Hibernate. The device enters HIB\r
1258 //! immediately and on exit from HIB device core starts its execution from\r
1259 //! reset thus the function never returns.\r
1260 //!\r
1261 //! \return None.\r
1262 //\r
1263 //*****************************************************************************\r
1264 void\r
1265 PRCMHibernateEnter()\r
1266 {\r
1267 \r
1268   //\r
1269   // Request hibernate.\r
1270   //\r
1271   PRCMHIBRegWrite((HIB3P3_BASE+HIB3P3_O_MEM_HIB_REQ),0x1);\r
1272 \r
1273   //\r
1274   // Wait for system to enter hibernate\r
1275   //\r
1276   __asm("    wfi\n");\r
1277 \r
1278   //\r
1279   // Infinite loop\r
1280   //\r
1281   while(1)\r
1282   {\r
1283 \r
1284   }\r
1285 }\r
1286 \r
1287 //*****************************************************************************\r
1288 //\r
1289 //! Gets the current value of the internal slow clock counter\r
1290 //!\r
1291 //! This function latches and reads the internal RTC running at 32.768 Khz\r
1292 //!\r
1293 //! \return 64-bit current counter vlaue.\r
1294 //\r
1295 //*****************************************************************************\r
1296 unsigned long long\r
1297 PRCMSlowClkCtrGet()\r
1298 {\r
1299   unsigned long long ullRTCVal;\r
1300 \r
1301   //\r
1302   // Latch the RTC vlaue\r
1303   //\r
1304   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ, 0x1);\r
1305 \r
1306   //\r
1307   // Read latched values as 2 32-bit vlaues\r
1308   //\r
1309   ullRTCVal  = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);\r
1310   ullRTCVal  = ullRTCVal << 32;\r
1311   ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);\r
1312 \r
1313   return ullRTCVal;\r
1314 }\r
1315 \r
1316 //*****************************************************************************\r
1317 //\r
1318 //! Gets the current value of the internal slow clock counter\r
1319 //!\r
1320 //! This function is similar to \sa PRCMSlowClkCtrGet() but reads the counter\r
1321 //! value from a relatively faster interface using an auto-latch mechainsm.\r
1322 //!\r
1323 //! \note Due to the nature of implemetation of auto latching, when using this\r
1324 //! API, the recommendation is to read the value thrice and identify the right\r
1325 //! value (as 2 out the 3 read values will always be correct and with a max. of\r
1326 //! 1 LSB change)\r
1327 //!\r
1328 //! \return 64-bit current counter vlaue.\r
1329 //\r
1330 //*****************************************************************************\r
1331 unsigned long long PRCMSlowClkCtrFastGet(void)\r
1332 {\r
1333   unsigned long long ullRTCVal;\r
1334 \r
1335   //\r
1336   // Read as 2 32-bit values\r
1337   //\r
1338   ullRTCVal = HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_MSW_1P2);\r
1339   ullRTCVal = ullRTCVal << 32;\r
1340   ullRTCVal |= HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_LSW_1P2);\r
1341 \r
1342   return ullRTCVal;\r
1343 \r
1344 }\r
1345 \r
1346 //*****************************************************************************\r
1347 //\r
1348 //! Sets slow clock counter match value to interrupt the processor.\r
1349 //!\r
1350 //! \param ullValue is the match value.\r
1351 //!\r
1352 //! This function sets the match value for  slow clock counter. This is use\r
1353 //! to interrupt the processor when RTC counts to the specified value.\r
1354 //!\r
1355 //! \return None.\r
1356 //\r
1357 //*****************************************************************************\r
1358 void PRCMSlowClkCtrMatchSet(unsigned long long ullValue)\r
1359 {\r
1360   //\r
1361   // Set RTC match value\r
1362   //\r
1363   PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF,\r
1364                                            (unsigned long)(ullValue));\r
1365   PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF,\r
1366                                            (unsigned long)(ullValue>>32));\r
1367 }\r
1368 \r
1369 //*****************************************************************************\r
1370 //\r
1371 //! Gets slow clock counter match value.\r
1372 //!\r
1373 //! This function gets the match value for  slow clock counter. This is use\r
1374 //! to interrupt the processor when RTC counts to the specified value.\r
1375 //!\r
1376 //! \return None.\r
1377 //\r
1378 //*****************************************************************************\r
1379 unsigned long long PRCMSlowClkCtrMatchGet()\r
1380 {\r
1381   unsigned long long ullValue;\r
1382 \r
1383   //\r
1384   // Get RTC match value\r
1385   //\r
1386   ullValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF);\r
1387   ullValue = ullValue<<32;\r
1388   ullValue |= PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF);\r
1389 \r
1390   //\r
1391   // Return the value\r
1392   //\r
1393   return ullValue;\r
1394 }\r
1395 \r
1396 \r
1397 //*****************************************************************************\r
1398 //\r
1399 //! Write to On-Chip Retention (OCR) register.\r
1400 //!\r
1401 //! This function writes to On-Chip retention register. The device supports two\r
1402 //! 4-byte OCR register which are retained across all power mode.\r
1403 //!\r
1404 //! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.\r
1405 //!\r
1406 //! These registers are shared by the RTC implementation (if Driverlib RTC\r
1407 //! APIs are used), ROM, and user application.\r
1408 //!\r
1409 //! When RTC APIs in use:\r
1410 //!\r
1411 //!     |-----------------------------------------------|\r
1412 //!     |                  INDEX 1                      |\r
1413 //!     |-----------------------------------------------|\r
1414 //!     |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|\r
1415 //!     |-----------------------------------------------|\r
1416 //!     |           Reserved by RTC APIs - YY           |\r
1417 //!     |-----------------------------------------------|\r
1418 //!     |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|\r
1419 //!     |-----------------------------------------------|\r
1420 //!     |           Reserved by RTC APIs - YY           |\r
1421 //!     |-----------------------------------------------|\r
1422 //!\r
1423 //!\r
1424 //!     |-----------------------------------------------|\r
1425 //!     |                  INDEX 0                      |\r
1426 //!     |-----------------------------------------------|\r
1427 //!     |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|\r
1428 //!     |-----------------------------------------------|\r
1429 //!     |           Reserved by RTC APIs - YY           |\r
1430 //!     |-----------------------------------------------|\r
1431 //!     |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|\r
1432 //!     |-----------------------------------------------|\r
1433 //!     |YY|        For User Application             |XX|\r
1434 //!     |-----------------------------------------------|\r
1435 //!\r
1436 //!     YY => Reserved by RTC APIs. If Driverlib RTC APIs are used\r
1437 //!     XX => Reserved by ROM\r
1438 //!\r
1439 //!\r
1440 //! When RTC APIs are not in use:\r
1441 //!\r
1442 //!     |-----------------------------------------------|\r
1443 //!     |                  INDEX 1                      |\r
1444 //!     |-----------------------------------------------|\r
1445 //!     |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|\r
1446 //!     |-----------------------------------------------|\r
1447 //!     |            For User Application               |\r
1448 //!     |-----------------------------------------------|\r
1449 //!     |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|\r
1450 //!     |-----------------------------------------------|\r
1451 //!     |            For User Application               |\r
1452 //!     |-----------------------------------------------|\r
1453 //!\r
1454 //!\r
1455 //!     |-----------------------------------------------|\r
1456 //!     |                  INDEX 0                      |\r
1457 //!     |-----------------------------------------------|\r
1458 //!     |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|\r
1459 //!     |-----------------------------------------------|\r
1460 //!     |            For User Application               |\r
1461 //!     |-----------------------------------------------|\r
1462 //!     |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|\r
1463 //!     |-----------------------------------------------|\r
1464 //!     |           For User Application             |XX|\r
1465 //!     |-----------------------------------------------|\r
1466 //!\r
1467 //!     XX => Reserved by ROM\r
1468 //!\r
1469 //!\r
1470 //!\r
1471 //! \return None.\r
1472 //\r
1473 //*****************************************************************************\r
1474 void PRCMOCRRegisterWrite(unsigned char ucIndex, unsigned long ulRegValue)\r
1475 {\r
1476   unsigned long ulVal;\r
1477 \r
1478   //\r
1479   // Compuitr the offset\r
1480   //\r
1481   ucIndex = ucIndex << 2;\r
1482 \r
1483   //\r
1484   // If bit 0 is reserved\r
1485   //\r
1486   if( (HWREG(OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_8) & (0x00000080)) &&\r
1487       (ucIndex == 0) )\r
1488   {\r
1489     ulVal = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2 + ucIndex);\r
1490     ulRegValue = ((ulRegValue << 0x1) | (ulVal & (0x1)));\r
1491   }\r
1492 \r
1493   //\r
1494   // Write thr value\r
1495   //\r
1496   PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2 + ucIndex,ulRegValue);\r
1497 \r
1498 }\r
1499 \r
1500 //*****************************************************************************\r
1501 //\r
1502 //! Read from On-Chip Retention (OCR) register.\r
1503 //!\r
1504 //! This function reads from On-Chip retention register. The device supports two\r
1505 //! 4-byte OCR register which are retained across all power mode.\r
1506 //!\r
1507 //! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.\r
1508 //!\r
1509 //! \sa PRCMOCRRegisterWrite() for the register usage details.\r
1510 //!\r
1511 //! \return None.\r
1512 //\r
1513 //*****************************************************************************\r
1514 unsigned long PRCMOCRRegisterRead(unsigned char ucIndex)\r
1515 {\r
1516   unsigned long ulRet;\r
1517 \r
1518   //\r
1519   // Read the OCR register\r
1520   //\r
1521   ulRet = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2));\r
1522 \r
1523   //\r
1524   // If bit 0 is reserved\r
1525   //\r
1526   if( (HWREG(OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_8) & (0x00000080)) &&\r
1527       (ucIndex == 0) )\r
1528   {\r
1529      ulRet = ulRet >> 0x1;\r
1530   }\r
1531 \r
1532   //\r
1533   // Return the read value.\r
1534   //\r
1535   return ulRet;\r
1536 }\r
1537 \r
1538 //*****************************************************************************\r
1539 //\r
1540 //! Registers an interrupt handler for the PRCM.\r
1541 //!\r
1542 //! \param pfnHandler is a pointer to the function to be called when the\r
1543 //! interrupt is activated.\r
1544 //!\r
1545 //! This function does the actual registering of the interrupt handler.  This\r
1546 //! function enables the global interrupt in the interrupt controller;\r
1547 //!\r
1548 //! \return None.\r
1549 //\r
1550 //*****************************************************************************\r
1551 void PRCMIntRegister(void (*pfnHandler)(void))\r
1552 {\r
1553   //\r
1554   // Register the interrupt handler.\r
1555   //\r
1556   IntRegister(INT_PRCM, pfnHandler);\r
1557 \r
1558   //\r
1559   // Enable the PRCM interrupt.\r
1560   //\r
1561   IntEnable(INT_PRCM);\r
1562 }\r
1563 \r
1564 //*****************************************************************************\r
1565 //\r
1566 //! Unregisters an interrupt handler for the PRCM.\r
1567 //!\r
1568 //! This function does the actual unregistering of the interrupt handler.  It\r
1569 //! clears the handler to be called when a PRCM interrupt occurs.  This\r
1570 //! function also masks off the interrupt in the interrupt controller so that\r
1571 //! the interrupt handler no longer is called.\r
1572 //!\r
1573 //! \return None.\r
1574 //\r
1575 //*****************************************************************************\r
1576 void PRCMIntUnregister()\r
1577 {\r
1578   //\r
1579   // Enable the UART interrupt.\r
1580   //\r
1581   IntDisable(INT_PRCM);\r
1582 \r
1583   //\r
1584   // Register the interrupt handler.\r
1585   //\r
1586   IntUnregister(INT_PRCM);\r
1587 }\r
1588 \r
1589 //*****************************************************************************\r
1590 //\r
1591 //! Enables individual PRCM interrupt sources.\r
1592 //!\r
1593 //! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.\r
1594 //!\r
1595 //! This function enables the indicated ARCM interrupt sources.  Only the\r
1596 //! sources that are enabled can be reflected to the processor interrupt;\r
1597 //! disabled sources have no effect on the processor.\r
1598 //!\r
1599 //! The \e ulIntFlags parameter is the logical OR of any of the following:\r
1600 //! -\b PRCM_INT_SLOW_CLK_CTR\r
1601 //!\r
1602 //\r
1603 //*****************************************************************************\r
1604 void PRCMIntEnable(unsigned long ulIntFlags)\r
1605 {\r
1606   unsigned long ulRegValue;\r
1607 \r
1608   if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )\r
1609   {\r
1610     //\r
1611     // Enable PRCM interrupt\r
1612     //\r
1613     HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) |= 0x4;\r
1614 \r
1615     //\r
1616     // Enable RTC interrupt\r
1617     //\r
1618     ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);\r
1619     ulRegValue |= 0x1;\r
1620     PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);\r
1621   }\r
1622 }\r
1623 \r
1624 //*****************************************************************************\r
1625 //\r
1626 //! Disables individual PRCM interrupt sources.\r
1627 //!\r
1628 //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.\r
1629 //!\r
1630 //! This function disables the indicated ARCM interrupt sources.  Only the\r
1631 //! sources that are enabled can be reflected to the processor interrupt;\r
1632 //! disabled sources have no effect on the processor.\r
1633 //!\r
1634 //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags\r
1635 //! parameter to PRCMEnableInterrupt().\r
1636 //!\r
1637 //! \return None.\r
1638 //\r
1639 //*****************************************************************************\r
1640 void PRCMIntDisable(unsigned long ulIntFlags)\r
1641 {\r
1642   unsigned long ulRegValue;\r
1643 \r
1644   if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )\r
1645   {\r
1646     //\r
1647     // Disable PRCM interrupt\r
1648     //\r
1649     HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) &= ~0x4;\r
1650 \r
1651     //\r
1652     // Disable RTC interrupt\r
1653     //\r
1654     ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);\r
1655     ulRegValue &= ~0x1;\r
1656     PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);\r
1657   }\r
1658 }\r
1659 \r
1660 //*****************************************************************************\r
1661 //\r
1662 //! Gets the current interrupt status.\r
1663 //!\r
1664 //! This function returns the PRCM interrupt status of interrupts that are\r
1665 //! allowed to reflect to the processor. The interrupts are cleared on read.\r
1666 //!\r
1667 //! \return Returns the current interrupt status.\r
1668 //\r
1669 //*****************************************************************************\r
1670 unsigned long PRCMIntStatus()\r
1671 {\r
1672     return HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_STATUS);\r
1673 }\r
1674 \r
1675 //*****************************************************************************\r
1676 //\r
1677 //! Mark the function of RTC as being used\r
1678 //!\r
1679 //! This function marks in HW that feature to maintain calendar time in device\r
1680 //! is being used.\r
1681 //!\r
1682 //! Specifically, this feature reserves user's HIB Register-1 accessed through\r
1683 //! PRCMOCRRegisterWrite(1) for internal work / purpose, therefore, the stated\r
1684 //! register is not available to user. Also, users must not excercise the Slow\r
1685 //! Clock Counter API(s), if RTC has been set for use.\r
1686 //!\r
1687 //! The RTC feature, if set or marked, can be only reset either through reboot\r
1688 //! or power cycle.\r
1689 //!\r
1690 //! \return None.\r
1691 //\r
1692 //*****************************************************************************\r
1693 void PRCMRTCInUseSet()\r
1694 {\r
1695         RTC_USE_SET();\r
1696         return;\r
1697 }\r
1698 \r
1699 //*****************************************************************************\r
1700 //\r
1701 //! Ascertain whether function of RTC is being used\r
1702 //!\r
1703 //! This function indicates whether function of RTC is being used on the device\r
1704 //! or not.\r
1705 //!\r
1706 //! This routine should be utilized by the application software, when returning\r
1707 //! from low-power, to confirm that RTC has been put to use and may not need to\r
1708 //! set the value of the RTC.\r
1709 //!\r
1710 //! The RTC feature, if set or marked, can be only reset either through reboot\r
1711 //! or power cycle.\r
1712 //!\r
1713 //! \return None.\r
1714 //\r
1715 //*****************************************************************************\r
1716 tBoolean PRCMRTCInUseGet()\r
1717 {\r
1718         return IS_RTC_USED()? true : false;\r
1719 }\r
1720 \r
1721 //*****************************************************************************\r
1722 //\r
1723 //! Set the calendar time in the device.\r
1724 //!\r
1725 //! \param ulSecs refers to the seconds part of the  calendar time\r
1726 //! \param usMsec refers to the fractional (ms) part of the second\r
1727 //!\r
1728 //! This function sets the specified calendar time in the device. The calendar\r
1729 //! time is outlined in terms of seconds and milliseconds. However, the device\r
1730 //! makes no assumption about the origin or reference of the calendar time.\r
1731 //!\r
1732 //! The device uses the indicated calendar value to update and maintain the\r
1733 //! wall-clock time across active and low power states.\r
1734 //!\r
1735 //! The function PRCMRTCInUseSet() must be invoked prior to use of this feature.\r
1736 //!\r
1737 //! \return None.\r
1738 //\r
1739 //*****************************************************************************\r
1740 void PRCMRTCSet(unsigned long ulSecs, unsigned short usMsec)\r
1741 {\r
1742         unsigned long long ullMsec = 0;\r
1743 \r
1744         if(IS_RTC_USED()) {\r
1745                 ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec) - SCC_U64MSEC_GET();\r
1746 \r
1747                  RTC_U32SECS_REG_WR(RTC_SECS_IN_U64MSEC(ullMsec));\r
1748                  RTC_U16MSEC_REG_WR(RTC_MSEC_IN_U64MSEC(ullMsec));\r
1749         }\r
1750 \r
1751         return;\r
1752 }\r
1753 \r
1754 //*****************************************************************************\r
1755 //\r
1756 //! Get the instantaneous calendar time from the device.\r
1757 //!\r
1758 //! \param ulSecs refers to the seconds part of the  calendar time\r
1759 //! \param usMsec refers to the fractional (ms) part of the second\r
1760 //!\r
1761 //! This function fetches the instantaneous value of the ticking calendar time\r
1762 //! from the device. The calendar time is outlined in terms of seconds and\r
1763 //! milliseconds.\r
1764 //!\r
1765 //! The device provides the calendar value that has been maintained across\r
1766 //! active and low power states.\r
1767 //!\r
1768 //! The function PRCMRTCSet() must have been invoked once to set a reference.\r
1769 //!\r
1770 //! \return None.\r
1771 //\r
1772 //*****************************************************************************\r
1773 void PRCMRTCGet(unsigned long *ulSecs, unsigned short *usMsec)\r
1774 {\r
1775         unsigned long long ullMsec = 0;\r
1776 \r
1777         if(IS_RTC_USED()) {\r
1778                 ullMsec  = RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),\r
1779                                           RTC_U16MSEC_REG_RD());\r
1780                 ullMsec += SCC_U64MSEC_GET();\r
1781         }\r
1782 \r
1783         *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);\r
1784         *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);\r
1785 \r
1786         return;\r
1787 }\r
1788 \r
1789 //*****************************************************************************\r
1790 //\r
1791 //! Set a calendar time alarm.\r
1792 //!\r
1793 //! \param ulSecs refers to the seconds part of the  calendar time\r
1794 //! \param usMsec refers to the fractional (ms) part of the second\r
1795 //!\r
1796 //! This function sets an wall-clock alarm in the device to be reported for  a\r
1797 //! futuristic calendar time. The calendar time is outlined in terms of seconds\r
1798 //! and milliseconds.\r
1799 //!\r
1800 //! The device provides uses the calendar value that has been maintained across\r
1801 //! active and low power states to report attainment of alarm time.\r
1802 //!\r
1803 //! The function PRCMRTCSet() must have been invoked once to set a reference.\r
1804 //!\r
1805 //! \return None.\r
1806 //\r
1807 //*****************************************************************************\r
1808 void PRCMRTCMatchSet(unsigned long ulSecs, unsigned short usMsec)\r
1809 {\r
1810         unsigned long long ullMsec = 0;\r
1811 \r
1812         if(IS_RTC_USED()) {\r
1813                 ullMsec  = RTC_U64MSEC_MK(ulSecs, usMsec);\r
1814                 ullMsec -= RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),\r
1815                                           RTC_U16MSEC_REG_RD());\r
1816                 SCC_U64MSEC_MATCH_SET(SELECT_SCC_U42BITS(ullMsec));\r
1817         }\r
1818 \r
1819         return;\r
1820 }\r
1821 \r
1822 //*****************************************************************************\r
1823 //\r
1824 //! Get a previously set calendar time alarm.\r
1825 //!\r
1826 //! \param ulSecs refers to the seconds part of the  calendar time\r
1827 //! \param usMsec refers to the fractional (ms) part of the second\r
1828 //!\r
1829 //! This function fetches from the device a wall-clock alarm that would  have\r
1830 //! been previously set in the device. The calendar time is outlined in terms\r
1831 //! of seconds and milliseconds.\r
1832 //!\r
1833 //! If no alarm was set in the past, then this function would fetch a random\r
1834 //! information.\r
1835 //!\r
1836 //! The function PRCMRTCMatchSet() must have been invoked once to set an alarm.\r
1837 //!\r
1838 //! \return None.\r
1839 //\r
1840 //*****************************************************************************\r
1841 void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec)\r
1842 {\r
1843         unsigned long long ullMsec = 0;\r
1844 \r
1845         if(IS_RTC_USED()) {\r
1846                 ullMsec  = SCC_U64MSEC_MATCH_GET();\r
1847                 ullMsec += RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),\r
1848                                           RTC_U16MSEC_REG_RD());\r
1849         }\r
1850 \r
1851         *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);\r
1852         *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);\r
1853 \r
1854         return;\r
1855 }\r
1856 \r
1857 //*****************************************************************************\r
1858 //\r
1859 //! MCU Initialization Routine\r
1860 //!\r
1861 //! This function contains all the mandatory bug fixes, ECO enables,\r
1862 //! initializations for both CC3200 and CC3220.\r
1863 //!\r
1864 //! \note \b ###IMPORTANT### : This is a routine which should be one of the\r
1865 //! first things to be executed after control comes to MCU Application code.\r
1866 //!\r
1867 //! \return None\r
1868 //\r
1869 //*****************************************************************************\r
1870 void PRCMCC3200MCUInit()\r
1871 {\r
1872 \r
1873   if( PRCMSysResetCauseGet() != PRCM_LPDS_EXIT )\r
1874   {\r
1875     if( 0x00010001 == HWREG(0x00000400) )\r
1876     {\r
1877 \r
1878 #ifndef REMOVE_CC3200_ES_1_2_1_CODE\r
1879 \r
1880       unsigned long ulRegVal;\r
1881 \r
1882       //\r
1883       // DIG DCDC NFET SEL and COT mode disable\r
1884       //\r
1885       HWREG(0x4402F010) = 0x30031820;\r
1886       HWREG(0x4402F00C) = 0x04000000;\r
1887 \r
1888       UtilsDelay(32000);\r
1889 \r
1890       //\r
1891       // ANA DCDC clock config\r
1892       //\r
1893       HWREG(0x4402F11C) = 0x099;\r
1894       HWREG(0x4402F11C) = 0x0AA;\r
1895       HWREG(0x4402F11C) = 0x1AA;\r
1896 \r
1897       //\r
1898       // PA DCDC clock config\r
1899       //\r
1900       HWREG(0x4402F124) = 0x099;\r
1901       HWREG(0x4402F124) = 0x0AA;\r
1902       HWREG(0x4402F124) = 0x1AA;\r
1903 \r
1904       //\r
1905       // TD Flash timing configurations in case of MCU WDT reset\r
1906       //\r
1907       if((HWREG(0x4402D00C) & 0xFF) == 0x00000005)\r
1908       {\r
1909           HWREG(0x400F707C) |= 0x01840082;\r
1910           HWREG(0x400F70C4)= 0x1;\r
1911           HWREG(0x400F70C4)= 0x0;\r
1912       }\r
1913 \r
1914       //\r
1915       // Take I2C semaphore\r
1916       //\r
1917       ulRegVal = HWREG(0x400F7000);\r
1918       ulRegVal = (ulRegVal & ~0x3) | 0x1;\r
1919       HWREG(0x400F7000) = ulRegVal;\r
1920 \r
1921       //\r
1922       // Take GPIO semaphore\r
1923       //\r
1924       ulRegVal = HWREG(0x400F703C);\r
1925       ulRegVal = (ulRegVal & ~0x3FF) | 0x155;\r
1926       HWREG(0x400F703C) = ulRegVal;\r
1927 \r
1928       //\r
1929       // Enable 32KHz internal RC oscillator\r
1930       //\r
1931       PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_INT_OSC_CONF, 0x00000101);\r
1932 \r
1933       //\r
1934       // Delay for a little bit.\r
1935       //\r
1936       UtilsDelay(8000);\r
1937 \r
1938       //\r
1939       // Enable 16MHz clock\r
1940       //\r
1941       HWREG(HIB1P2_BASE+HIB1P2_O_CM_OSC_16M_CONFIG) = 0x00010008;\r
1942 \r
1943       //\r
1944       // Delay for a little bit.\r
1945       //\r
1946       UtilsDelay(8000);\r
1947 \r
1948 #endif // REMOVE_CC3200_ES_1_2_1_CODE\r
1949 \r
1950     }\r
1951     else\r
1952     {\r
1953 \r
1954       unsigned long ulRegValue;\r
1955 \r
1956       //\r
1957       // DIG DCDC LPDS ECO Enable\r
1958       //\r
1959       HWREG(0x4402F064) |= 0x800000;\r
1960 \r
1961       //\r
1962       // Enable hibernate ECO for PG 1.32 devices only. With this ECO enabled,\r
1963       // any hibernate wakeup source will be kept maked until the device enters\r
1964       // hibernate completely (analog + digital)\r
1965       //\r
1966       ulRegValue = PRCMHIBRegRead(HIB3P3_BASE  + HIB3P3_O_MEM_HIB_REG0);\r
1967       PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4));\r
1968 \r
1969       //\r
1970       // Handling the clock switching (for 1.32 only)\r
1971       //\r
1972       HWREG(0x4402E16C) |= 0x3C;\r
1973     }\r
1974 \r
1975 \r
1976     //\r
1977     // Enable uDMA\r
1978     //\r
1979     PRCMPeripheralClkEnable(PRCM_UDMA,PRCM_RUN_MODE_CLK);\r
1980 \r
1981     //\r
1982     // Reset uDMA\r
1983     //\r
1984     PRCMPeripheralReset(PRCM_UDMA);\r
1985 \r
1986     //\r
1987     // Disable uDMA\r
1988     //\r
1989     PRCMPeripheralClkDisable(PRCM_UDMA,PRCM_RUN_MODE_CLK);\r
1990 \r
1991     //\r
1992     // Enable RTC\r
1993     //\r
1994     if(PRCMSysResetCauseGet()== PRCM_POWER_ON)\r
1995     {\r
1996         PRCMHIBRegWrite(0x4402F804,0x1);\r
1997     }\r
1998 \r
1999     //\r
2000     // SWD mode\r
2001     //\r
2002     if(((HWREG(0x4402F0C8) & 0xFF) == 0x2))\r
2003     {\r
2004         HWREG(0x4402E110) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);\r
2005         HWREG(0x4402E114) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);\r
2006     }\r
2007 \r
2008     //\r
2009     // Override JTAG mux\r
2010     //\r
2011     HWREG(0x4402E184) |= 0x2;\r
2012 \r
2013     //\r
2014     // Change UART pins(55,57) mode to PIN_MODE_0 if they are in PIN_MODE_1\r
2015     //\r
2016     if( (HWREG(0x4402E0A4) & 0xF) == 0x1)\r
2017     {\r
2018         HWREG(0x4402E0A4) = ((HWREG(0x4402E0A4) & ~0xF));\r
2019     }\r
2020 \r
2021     if( (HWREG(0x4402E0A8) & 0xF) == 0x1)\r
2022     {\r
2023         HWREG(0x4402E0A8) = ((HWREG(0x4402E0A8) & ~0xF));\r
2024     }\r
2025 \r
2026     //\r
2027     // DIG DCDC VOUT trim settings based on PROCESS INDICATOR\r
2028     //\r
2029     if(((HWREG(0x4402DC78) >> 22) & 0xF) == 0xE)\r
2030     {\r
2031         HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x32 << 18));\r
2032     }\r
2033     else\r
2034     {\r
2035         HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x29 << 18));\r
2036     }\r
2037 \r
2038     //\r
2039     // Enable SOFT RESTART in case of DIG DCDC collapse\r
2040     //\r
2041     HWREG(0x4402FC74) &= ~(0x10000000);\r
2042 \r
2043     //\r
2044     // Required only if ROM version is lower than 2.x.x\r
2045     //\r
2046     if( (HWREG(0x00000400) & 0xFFFF) < 2 )\r
2047     {\r
2048       //\r
2049       // Disable the sleep for ANA DCDC\r
2050       //\r
2051       HWREG(0x4402F0A8) |= 0x00000004 ;\r
2052     }\r
2053     else if( (HWREG(0x00000400) >> 16)  >= 1 )\r
2054     {\r
2055       //\r
2056       // Enable NWP force reset and HIB on WDT reset\r
2057       // Enable direct boot path for flash\r
2058       //\r
2059       HWREG(OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_8) |= ((7<<5) | 0x1);\r
2060       if((HWREG(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2) & 0x1) )\r
2061       {\r
2062           HWREG(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2) &= ~0x1;\r
2063           HWREG(OCP_SHARED_BASE + OCP_SHARED_O_SPARE_REG_8) |= (1<<9);\r
2064 \r
2065           //\r
2066           // Clear the RTC hib wake up source\r
2067           //\r
2068           HWREG(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN) &= ~0x1;\r
2069 \r
2070           //\r
2071           // Reset RTC match value\r
2072           //\r
2073           HWREG(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF) = 0;\r
2074           HWREG(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF) = 0;\r
2075 \r
2076       }\r
2077     }\r
2078     \r
2079     unsigned long efuse_reg2;\r
2080     unsigned long ulDevMajorVer, ulDevMinorVer;\r
2081     //\r
2082     // Read the device identification register\r
2083     //\r
2084     efuse_reg2= HWREG(GPRCM_BASE + GPRCM_O_GPRCM_EFUSE_READ_REG2);\r
2085     \r
2086     //\r
2087     // Read the ROM mojor and minor version\r
2088     //\r
2089     ulDevMajorVer = ((efuse_reg2 >> 28) & 0xF);\r
2090     ulDevMinorVer = ((efuse_reg2 >> 24) & 0xF);\r
2091   \r
2092     if(((ulDevMajorVer == 0x3) && (ulDevMinorVer == 0)) || (ulDevMajorVer < 0x3))\r
2093     {\r
2094       unsigned int Scratch, PreRegulatedMode;\r
2095 \r
2096       // 0x4402F840 => 6th bit \931\94 indicates device is in pre-regulated mode.\r
2097       PreRegulatedMode = (HWREG(0x4402F840) >> 6) & 1;\r
2098     \r
2099       if( PreRegulatedMode)\r
2100       {\r
2101         Scratch = HWREG(0x4402F028);\r
2102         Scratch &= 0xFFFFFF7F; // <7:7> = 0\r
2103         HWREG(0x4402F028) = Scratch;\r
2104         \r
2105         Scratch = HWREG(0x4402F010);\r
2106         Scratch &= 0x0FFFFFFF; // <31:28> = 0\r
2107         Scratch |= 0x10000000; // <31:28> = 1\r
2108         HWREG(0x4402F010) = Scratch;\r
2109       }\r
2110       else\r
2111       {\r
2112         Scratch = HWREG(0x4402F024);\r
2113 \r
2114         Scratch &= 0xFFFFFFF0; // <3:0> = 0\r
2115         Scratch |= 0x00000001; // <3:0> = 1\r
2116         Scratch &= 0xFFFFF0FF; // <11:8> = 0000\r
2117         Scratch |= 0x00000500; // <11:8> = 0101\r
2118         Scratch &= 0xFFFE7FFF; // <16:15> = 0000\r
2119         Scratch |= 0x00010000; // <16:15> = 10\r
2120 \r
2121         HWREG(0x4402F024) = Scratch;\r
2122 \r
2123         Scratch = HWREG(0x4402F028);\r
2124 \r
2125         Scratch &= 0xFFFFFF7F; // <7:7> = 0\r
2126         Scratch &= 0x0FFFFFFF; // <31:28> = 0\r
2127         Scratch &= 0xFF0FFFFF; // <23:20> = 0\r
2128         Scratch |= 0x00300000; // <23:20> = 0011\r
2129         Scratch &= 0xFFF0FFFF; // <19:16> = 0\r
2130         Scratch |= 0x00030000; // <19:16> = 0011\r
2131 \r
2132         HWREG(0x4402F028) = Scratch;\r
2133         HWREG(0x4402F010) &= 0x0FFFFFFF; // <31:28> = 0\r
2134       }\r
2135     }\r
2136     else\r
2137     {\r
2138       unsigned int Scratch, PreRegulatedMode;\r
2139 \r
2140       // 0x4402F840 => 6th bit \931\94 indicates device is in pre-regulated mode.\r
2141       PreRegulatedMode = (HWREG(0x4402F840) >> 6) & 1;\r
2142     \r
2143       Scratch = HWREG(0x4402F028);\r
2144       Scratch &= 0xFFFFFF7F; // <7:7> = 0\r
2145       HWREG(0x4402F028) = Scratch;\r
2146     \r
2147       HWREG(0x4402F010) &= 0x0FFFFFFF; // <31:28> = 0\r
2148       if( PreRegulatedMode)\r
2149       {\r
2150         HWREG(0x4402F010) |= 0x10000000; // <31:28> = 1\r
2151       }  \r
2152     }\r
2153   }\r
2154   else\r
2155   {\r
2156     unsigned long ulRegVal;\r
2157 \r
2158     //\r
2159     // I2C Configuration\r
2160     //\r
2161     ulRegVal = HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register);\r
2162     ulRegVal = (ulRegVal & ~0x3) | 0x1;\r
2163     HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register) = ulRegVal;\r
2164 \r
2165     //\r
2166     // GPIO configuration\r
2167     //\r
2168     ulRegVal = HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register);\r
2169     ulRegVal = (ulRegVal & ~0x3FF) | 0x155;\r
2170     HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register) = ulRegVal;\r
2171 \r
2172   }\r
2173 }\r
2174 \r
2175 //*****************************************************************************\r
2176 //\r
2177 //! Reads 32-bit value from register at specified address\r
2178 //!\r
2179 //! \param ulRegAddr is the address of register to be read.\r
2180 //!\r
2181 //! This function reads 32-bit value from the register as specified by\r
2182 //! \e ulRegAddr.\r
2183 //!\r
2184 //! \return Return the value of the register.\r
2185 //\r
2186 //*****************************************************************************\r
2187 unsigned long PRCMHIBRegRead(unsigned long ulRegAddr)\r
2188 {\r
2189   unsigned long ulValue;\r
2190 \r
2191   //\r
2192   // Read the Reg value\r
2193   //\r
2194   ulValue = HWREG(ulRegAddr);\r
2195 \r
2196   //\r
2197   // Wait for 200 uSec\r
2198   //\r
2199   UtilsDelay((80*200)/3);\r
2200 \r
2201   //\r
2202   // Return the value\r
2203   //\r
2204   return ulValue;\r
2205 }\r
2206 \r
2207 //*****************************************************************************\r
2208 //\r
2209 //! Writes 32-bit value to register at specified address\r
2210 //!\r
2211 //! \param ulRegAddr is the address of register to be read.\r
2212 //! \param ulValue is the 32-bit value to be written.\r
2213 //!\r
2214 //! This function writes 32-bit value passed as \e ulValue to the register as\r
2215 //! specified by \e ulRegAddr\r
2216 //!\r
2217 //! \return None\r
2218 //\r
2219 //*****************************************************************************\r
2220 void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue)\r
2221 {\r
2222   //\r
2223   // Read the Reg value\r
2224   //\r
2225   HWREG(ulRegAddr) = ulValue;\r
2226 \r
2227   //\r
2228   // Wait for 200 uSec\r
2229   //\r
2230   UtilsDelay((80*200)/3);\r
2231 }\r
2232 \r
2233 //*****************************************************************************\r
2234 //\r
2235 //! \param ulDivider is clock frequency divider value\r
2236 //! \param ulWidth is the width of the high pulse\r
2237 //!\r
2238 //! This function sets the input frequency for camera module.\r
2239 //!\r
2240 //! The frequency is calculated as follows:\r
2241 //!\r
2242 //!        f_out = 240MHz/ulDivider;\r
2243 //!\r
2244 //! The parameter \e ulWidth sets the width of the high pulse.\r
2245 //!\r
2246 //! For e.g.:\r
2247 //!\r
2248 //!     ulDivider = 4;\r
2249 //!     ulWidth   = 2;\r
2250 //!\r
2251 //!     f_out = 30 MHz and 50% duty cycle\r
2252 //!\r
2253 //! And,\r
2254 //!\r
2255 //!     ulDivider = 4;\r
2256 //!     ulWidth   = 1;\r
2257 //!\r
2258 //!     f_out = 30 MHz and 25% duty cycle\r
2259 //!\r
2260 //! \return 0 on success, 1 on error\r
2261 //\r
2262 //*****************************************************************************\r
2263 unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth)\r
2264 {\r
2265     if(ulDivider > ulWidth && ulWidth != 0 )\r
2266     {\r
2267       //\r
2268       // Set  the hifh pulse width\r
2269       //\r
2270       HWREG(ARCM_BASE +\r
2271             APPS_RCM_O_CAMERA_CLK_GEN) = (((ulWidth & 0x07) -1) << 8);\r
2272 \r
2273       //\r
2274       // Set the low pulse width\r
2275       //\r
2276       HWREG(ARCM_BASE +\r
2277             APPS_RCM_O_CAMERA_CLK_GEN) = ((ulDivider - ulWidth - 1) & 0x07);\r
2278       //\r
2279       // Return success\r
2280       //\r
2281       return 0;\r
2282     }\r
2283 \r
2284     //\r
2285     // Success;\r
2286     //\r
2287     return 1;\r
2288 }\r
2289 \r
2290 //*****************************************************************************\r
2291 //\r
2292 //! Enable the IO value retention\r
2293 //!\r
2294 //! \param ulIORetGrpFlags is one of the valid IO groups.\r
2295 //!\r
2296 //! This function enables the IO retention for group of pins as specified by\r
2297 //! \e ulIORetGrpFlags parameter. Enabling retention will immediately lock the\r
2298 //! digital pins, in the specified group, to their current state (0 or 1).\r
2299 //! Output pins can only be driven when retention is disabled.\r
2300 //!\r
2301 //! The parameter \e ulIORetGrpFlags can be logical OR of one or\r
2302 //! more of the following:\r
2303 //! -\b PRCM_IO_RET_GRP_0 - All the pins except sFlash and JTAG interface\r
2304 //! -\b PRCM_IO_RET_GRP_1 - sFlash interface pins 11,12,13,14\r
2305 //! -\b PRCM_IO_RET_GRP_2 - JTAG TDI and TDO interface pins 16,17\r
2306 //! -\b PRCM_IO_RET_GRP_3 - JTAG TCK and TMS interface pins 19,20\r
2307 //!\r
2308 //! \note Use case is to park the pins when entering HIB.\r
2309 //!\r
2310 //! \return None.\r
2311 //\r
2312 //*****************************************************************************\r
2313 void PRCMIORetentionEnable(unsigned long ulIORetGrpFlags)\r
2314 {\r
2315 \r
2316   //\r
2317   // Supported only in ES2.00 and Later devices i.e. ROM Version 2.x.x or greater\r
2318   //\r
2319   if( (HWREG(0x00000400) & 0xFFFF) >= 2 )\r
2320   {\r
2321     //\r
2322     // Disable IO Pad to ODI Path\r
2323     //\r
2324     HWREG(OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CMN_CONFIG) |= 0x00001F00;\r
2325 \r
2326     //\r
2327     // 0b'0 in bit 5 for JTAG PADS\r
2328     // 0b'0 in bit 0 for all other IOs\r
2329     //\r
2330     HWREG(OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CMN_CONFIG) &= ~(0x00000023);\r
2331 \r
2332     //\r
2333     // Enable retention for GRP0\r
2334     //\r
2335     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_0 )\r
2336     {\r
2337       HWREG(HIB3P3_BASE+HIB3P3_O_MEM_PAD_OEN_RET33_CONF) |= 0x5;\r
2338     }\r
2339 \r
2340     //\r
2341     // Enable retention for GRP1\r
2342     //\r
2343     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_1 )\r
2344     {\r
2345       HWREG(HIB3P3_BASE  + HIB3P3_O_MEM_HIB_REG0) |= ((0x3<<5));\r
2346     }\r
2347 \r
2348     //\r
2349     // Enable retention for GRP2\r
2350     //\r
2351     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_2 )\r
2352     {\r
2353       HWREG(HIB3P3_BASE  + HIB3P3_O_MEM_JTAG_CONF) |= 0x00000101;\r
2354     }\r
2355 \r
2356     //\r
2357     // Enable retention for GRP3\r
2358     //\r
2359     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_3 )\r
2360     {\r
2361       HWREG(HIB3P3_BASE  + HIB3P3_O_MEM_JTAG_CONF) |= 0x00000204;\r
2362     }\r
2363   }\r
2364 }\r
2365 \r
2366 //*****************************************************************************\r
2367 //\r
2368 //! Disable the IO value retention\r
2369 //!\r
2370 //! \param ulIORetGrpFlags is one of the valid IO groups.\r
2371 //!\r
2372 //! This function disable the IO retention for group of pins as specified by\r
2373 //! \e ulIORetGrpFlags parameter. Disabling retention will unlock the\r
2374 //! digital pins in the specified group. Output pins can only be driven when\r
2375 //! retention is disabled.\r
2376 //!\r
2377 //! The parameter \e ulIORetGrpFlags can be logical OR of one or\r
2378 //! more of the following:\r
2379 //! -\b PRCM_IO_RET_GRP_0 - All the pins except sFlash and JTAG interface\r
2380 //! -\b PRCM_IO_RET_GRP_1 - sFlash interface pins 11,12,13,14\r
2381 //! -\b PRCM_IO_RET_GRP_2 - JTAG TDI and TDO interface pins 16,17\r
2382 //! -\b PRCM_IO_RET_GRP_3 - JTAG TCK and TMS interface pins 19,20\r
2383 //!\r
2384 //! \note Use case is to un-park the pins when exiting HIB\r
2385 //!\r
2386 //! \return None.\r
2387 //\r
2388 //*****************************************************************************\r
2389 void PRCMIORetentionDisable(unsigned long ulIORetGrpFlags)\r
2390 {\r
2391   //\r
2392   // Supported only in ES2.00 and Later devices i.e. ROM Version 2.x.x or greater\r
2393   //\r
2394   if( (HWREG(0x00000400) & 0xFFFF) >= 2 )\r
2395   {\r
2396 \r
2397     //\r
2398     // Enable IO Pad to ODI Path\r
2399     //\r
2400     HWREG(OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CMN_CONFIG) &= ~(0x00001F00);\r
2401 \r
2402     //\r
2403     // 0b'1 in bit 5 for JTAG PADS\r
2404     // 0b'1 in bit 0 for all other IOs\r
2405     //\r
2406     HWREG(OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CMN_CONFIG) |= 0x00000023;\r
2407 \r
2408     //\r
2409     // Disable retention for GRP0\r
2410     //\r
2411     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_0 )\r
2412     {\r
2413       HWREG(HIB3P3_BASE+HIB3P3_O_MEM_PAD_OEN_RET33_CONF) &= ~0x5;\r
2414     }\r
2415 \r
2416     //\r
2417     // Disable retention for GRP1\r
2418     //\r
2419     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_1 )\r
2420     {\r
2421       HWREG(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0) &= ~((0x3<<5));\r
2422     }\r
2423 \r
2424     //\r
2425     // Disable retention for GRP2\r
2426     //\r
2427     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_2 )\r
2428     {\r
2429       HWREG(HIB3P3_BASE  + HIB3P3_O_MEM_JTAG_CONF) &= ~0x00000101;\r
2430     }\r
2431 \r
2432     //\r
2433     // Disable retention for GRP3\r
2434     //\r
2435     if( ulIORetGrpFlags & PRCM_IO_RET_GRP_3 )\r
2436     {\r
2437       HWREG(HIB3P3_BASE  + HIB3P3_O_MEM_JTAG_CONF) &= ~0x00000204;\r
2438     }\r
2439 \r
2440   }\r
2441 }\r
2442 \r
2443 //*****************************************************************************\r
2444 //\r
2445 //! Gets the device type\r
2446 //!\r
2447 //! This function returns bit-packed value representing the device type\r
2448 //!\r
2449 //! The returned value is logical OR of one or more of the following:-\r
2450 //!\r
2451 //! -\b PRCM_DEV_TYPE_FLAG_R        - R variant\r
2452 //! -\b PRCM_DEV_TYPE_FLAG_F        - F variant\r
2453 //! -\b PRCM_DEV_TYPE_FLAG_Z        - Z variant\r
2454 //! -\b PRCM_DEV_TYPE_FLAG_SECURE   - Device is secure\r
2455 //! -\b PRCM_DEV_TYPE_FLAG_PRE_PROD - Device is a pre-production part\r
2456 //! -\b PRCM_DEV_TYPE_FLAG_3200     - Device is CC3200\r
2457 //! -\b PRCM_DEV_TYPE_FLAG_3220     - Device is CC3220\r
2458 //! -\b PRCM_DEV_TYPE_FLAG_REV1     - Device Rev 1\r
2459 //! -\b PRCM_DEV_TYPE_FLAG_REV2     - Device Rev 2\r
2460 //!\r
2461 //! Pre-defined helper macros:-\r
2462 //!\r
2463 //! -\b PRCM_DEV_TYPE_PRE_CC3200R   - Pre-Production CC3200R\r
2464 //! -\b PRCM_DEV_TYPE_PRE_CC3200F   - Pre-Production CC3200F\r
2465 //! -\b PRCM_DEV_TYPE_PRE_CC3200Z   - Pre-Production CC3200Z\r
2466 //! -\b PRCM_DEV_TYPE_CC3200R       - Production CC3200R\r
2467 //! -\b PRCM_DEV_TYPE_PRE_CC3220R   - Pre-Production CC3220R\r
2468 //! -\b PRCM_DEV_TYPE_PRE_CC3220F   - Pre-Production CC3220F\r
2469 //! -\b PRCM_DEV_TYPE_PRE_CC3220Z   - Pre-Production CC3220Z\r
2470 //! -\b PRCM_DEV_TYPE_CC3220R       - Production CC3220R\r
2471 //! -\b PRCM_DEV_TYPE_PRE_CC3220RS  - Pre-Production CC3220RS\r
2472 //! -\b PRCM_DEV_TYPE_PRE_CC3220FS  - Pre-Production CC3220FS\r
2473 //! -\b PRCM_DEV_TYPE_PRE_CC3220ZS  - Pre-Production CC3220ZS\r
2474 //! -\b PRCM_DEV_TYPE_CC3220RS      - Production CC3220RS\r
2475 //! -\b PRCM_DEV_TYPE_CC3220FS      - Production CC3220FS\r
2476 //!\r
2477 //! \return  Returns, bit-packed value representing the device type,\r
2478 //! or 0 if device is unknown\r
2479 //\r
2480 //*****************************************************************************\r
2481 unsigned long PRCMDeviceTypeGet()\r
2482 {\r
2483   unsigned long ulDevType;\r
2484   unsigned long ulChipId;\r
2485   unsigned long ulDevMajorVer;\r
2486   unsigned long ulDevMinorVer;\r
2487 \r
2488   //\r
2489   // Read the device identification register\r
2490   //\r
2491   ulChipId = HWREG(GPRCM_BASE + GPRCM_O_GPRCM_EFUSE_READ_REG2);\r
2492 \r
2493   //\r
2494   // Read the ROM mojor and minor version\r
2495   //\r
2496   ulDevMajorVer = ((ulChipId >> 28) & 0xF);\r
2497   ulDevMinorVer = ((ulChipId >> 24) & 0xF);\r
2498 \r
2499   \r
2500   ulChipId = ((HWREG(GPRCM_BASE + GPRCM_O_GPRCM_EFUSE_READ_REG2) >> 16) & 0x1F);\r
2501    \r
2502   //\r
2503   // Get the device variant from the chip id\r
2504   //\r
2505   switch((ulChipId & 0xF))\r
2506   {\r
2507     //\r
2508     // It is R variant\r
2509     //\r
2510     case 0x0:\r
2511       ulDevType = PRCM_DEV_TYPE_FLAG_R;\r
2512       break;\r
2513 \r
2514     //\r
2515     // It is F variant, non secure F variant is always Pre-Production\r
2516     //\r
2517     case 0x1:\r
2518       ulDevType = PRCM_DEV_TYPE_FLAG_F|PRCM_DEV_TYPE_FLAG_PRE_PROD;\r
2519       break;\r
2520 \r
2521     //\r
2522     // It is Z variant and is always Pre-Production\r
2523     //\r
2524     case 0x3:\r
2525       ulDevType = PRCM_DEV_TYPE_FLAG_Z|PRCM_DEV_TYPE_FLAG_PRE_PROD;\r
2526       break;\r
2527 \r
2528     //\r
2529     // It is Secure R\r
2530     //\r
2531     case 0x8:\r
2532       ulDevType = PRCM_DEV_TYPE_FLAG_R|PRCM_DEV_TYPE_FLAG_SECURE;\r
2533       break;\r
2534 \r
2535     //\r
2536     // It is Secure F\r
2537     //\r
2538     case 0x9:\r
2539       ulDevType = PRCM_DEV_TYPE_FLAG_F|PRCM_DEV_TYPE_FLAG_SECURE;\r
2540       break;\r
2541 \r
2542     //\r
2543     // It is secure Z variant and variant is always Pre-Production\r
2544     //\r
2545     case 0xB:\r
2546       ulDevType = PRCM_DEV_TYPE_FLAG_Z|PRCM_DEV_TYPE_FLAG_SECURE|\r
2547                   PRCM_DEV_TYPE_FLAG_PRE_PROD;\r
2548       break;\r
2549 \r
2550     //\r
2551     // Undefined variant\r
2552     //\r
2553     default:\r
2554       ulDevType = 0x0;\r
2555   }\r
2556   \r
2557   if( ulDevType != 0 )\r
2558   {\r
2559     if( ulDevMajorVer == 0x3 )\r
2560     {\r
2561       ulDevType |= PRCM_DEV_TYPE_FLAG_3220;\r
2562     }\r
2563     else if( ulDevMajorVer == 0x2 )\r
2564     {\r
2565       ulDevType  |= (PRCM_DEV_TYPE_FLAG_PRE_PROD|PRCM_DEV_TYPE_FLAG_3220);\r
2566       \r
2567       if( ((ulDevType & PRCM_DEV_TYPE_FLAG_Z) != 0) )\r
2568       {\r
2569         if((ulDevMinorVer == 0x0))\r
2570         {\r
2571           ulDevType |= PRCM_DEV_TYPE_FLAG_REV1; \r
2572         }\r
2573         else\r
2574         {\r
2575           ulDevType |= PRCM_DEV_TYPE_FLAG_REV2;\r
2576         }\r
2577       }\r
2578       else\r
2579       {\r
2580         if((ulDevMinorVer == 0x1))\r
2581         {\r
2582           ulDevType |= PRCM_DEV_TYPE_FLAG_REV1;\r
2583         }\r
2584       }     \r
2585     }\r
2586     else\r
2587     {\r
2588       if( (ulDevMinorVer == 0x4))\r
2589       {\r
2590         if( ((ulDevType & PRCM_DEV_TYPE_FLAG_Z) != 0))\r
2591         {\r
2592           ulDevType |= (PRCM_DEV_TYPE_FLAG_PRE_PROD|PRCM_DEV_TYPE_FLAG_3220);\r
2593         }\r
2594         else\r
2595         {\r
2596           ulDevType |= PRCM_DEV_TYPE_FLAG_3200;\r
2597         }\r
2598       }\r
2599       else\r
2600       {\r
2601         ulDevType |= (PRCM_DEV_TYPE_FLAG_PRE_PROD|PRCM_DEV_TYPE_FLAG_3200);\r
2602       }\r
2603     }     \r
2604   }\r
2605  \r
2606 \r
2607   return ulDevType;\r
2608 }\r
2609 \r
2610 \r
2611 \r
2612 //****************************************************************************\r
2613 //\r
2614 //! Used to trigger a hibernate cycle for the device using RTC\r
2615 //!\r
2616 //! This API can be used to do a clean reboot of device.\r
2617 //!\r
2618 //! \note This routine should only be exercised after all the network processing\r
2619 //! has been stopped. To stop network processing use \b sl_stop API from\r
2620 //! simplelink library.\r
2621 //!\r
2622 //! \return None\r
2623 //\r
2624 //****************************************************************************\r
2625 void PRCMHibernateCycleTrigger()\r
2626 {\r
2627   unsigned long ulRegValue;\r
2628   unsigned long long ullRTCVal;\r
2629 \r
2630   //\r
2631   // Read the RTC register\r
2632   //\r
2633   ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);\r
2634 \r
2635   //\r
2636   // Enable the RTC as wakeup source if specified\r
2637   //\r
2638   ulRegValue |= (PRCM_HIB_SLOW_CLK_CTR & 0x1);\r
2639 \r
2640   //\r
2641   // Enable HIB wakeup sources\r
2642   //\r
2643   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);\r
2644 \r
2645   //\r
2646   // Latch the RTC vlaue\r
2647   //\r
2648   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1);\r
2649 \r
2650   //\r
2651   // Read latched values as 2 32-bit vlaues\r
2652   //\r
2653   ullRTCVal  = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);\r
2654   ullRTCVal  = ullRTCVal << 32;\r
2655   ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);\r
2656 \r
2657   //\r
2658   //Considering worst case execution times of ROM,RAM,Flash value of 160 is used\r
2659   //\r
2660   ullRTCVal = ullRTCVal + 160;\r
2661 \r
2662   //\r
2663   // Set RTC match value\r
2664   //\r
2665   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF,\r
2666                                             (unsigned long)(ullRTCVal));\r
2667   PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF,\r
2668                                            (unsigned long)(ullRTCVal>>32));\r
2669   //\r
2670   // Note : Any addition of code after this line would need a change in\r
2671   // ullTicks Interval currently set to 160\r
2672   //\r
2673 \r
2674   //\r
2675   // Request hibernate.\r
2676   //\r
2677   PRCMHIBRegWrite((HIB3P3_BASE+HIB3P3_O_MEM_HIB_REQ),0x1);\r
2678 \r
2679   //\r
2680   // Wait for system to enter hibernate\r
2681   //\r
2682   __asm("    wfi\n");\r
2683 \r
2684   //\r
2685   // Infinite loop\r
2686   //\r
2687   while(1)\r
2688   {\r
2689 \r
2690   }\r
2691 }\r
2692 \r
2693 \r
2694 //*****************************************************************************\r
2695 //\r
2696 // Close the Doxygen group.\r
2697 //! @}\r
2698 //\r
2699 //*****************************************************************************\r