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