1 //*****************************************************************************
2 //
3 //  prcm.c
4 //
5 //  Driver for the Power, Reset and Clock Module (PRCM)
6 //
7 //  Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
8 //
9 //
10 //  Redistribution and use in source and binary forms, with or without
11 //  modification, are permitted provided that the following conditions
12 //  are met:
13 //
14 //    Redistributions of source code must retain the above copyright
15 //    notice, this list of conditions and the following disclaimer.
16 //
17 //    Redistributions in binary form must reproduce the above copyright
18 //    notice, this list of conditions and the following disclaimer in the
19 //    documentation and/or other materials provided with the
20 //    distribution.
21 //
22 //    Neither the name of Texas Instruments Incorporated nor the names of
23 //    its contributors may be used to endorse or promote products derived
24 //    from this software without specific prior written permission.
25 //
26 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 //  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 //  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 //  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 //  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 //  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 //  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 //  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 //*****************************************************************************
39 
40 //*****************************************************************************
41 //
42 //! \addtogroup PRCM_Power_Reset_Clock_Module_api
43 //! @{
44 //
45 //*****************************************************************************
46 
47 #include "inc/hw_types.h"
48 #include "inc/hw_ints.h"
49 #include "inc/hw_memmap.h"
50 #include "inc/hw_apps_rcm.h"
51 #include "inc/hw_gprcm.h"
52 #include "inc/hw_hib1p2.h"
53 #include "inc/hw_hib3p3.h"
54 #include "prcm.h"
55 #include "interrupt.h"
56 #include "cpu.h"
57 #include "utils.h"
58 #include "rom_map.h"
59 
60 
61 //*****************************************************************************
62 // Macro definition
63 //*****************************************************************************
64 #define PRCM_SOFT_RESET           0x00000001
65 #define PRCM_ENABLE_STATUS        0x00000002
66 #define SYS_CLK                   80000000
67 #define XTAL_CLK                  40000000
68 
69 
70 //*****************************************************************************
71 //    CC3200 does not have a true RTC capability. However, API(s) in this file
72 //    provide an effective mechanism to support RTC feature in the device.
73 //
74 //    The implementation to support RTC has been kept very simple. A set of
75 //    HIB Memory Registers in conjunction with Slow Clock Counter are used
76 //    to render RTC information to users. Core principle of design involves
77 //    two steps (a) establish an association between user provided wall-clock
78 //    and slow clock counter. (b) store reference value of this associattion
79 //    in HIB Registers. This reference value and SCC value are then combined
80 //    to create real-world calendar time.
81 //
82 //    Across HIB cycles, value stored in HIB Registers is retained and slow
83 //    clock counter continues to tick, thereby, this arragement is relevant
84 //    and valid as long as device has a (tickle) battery power.
85 //
86 //    Further, provision also has been made to set an alarm. When it RTC value
87 //    matches that of set for alarm, an interrupt is generated.
88 //
89 //    HIB MEM REG0 and REG1 are reserved for TI.
90 //
91 //    If RTC feature is not used, then HIB REG2 & REG3 are available to user.
92 //
93 //    Lower half of REG0 is used for TI HW ECO.
94 //*****************************************************************************
95 #define RTC_U64MSEC_MK(u32Secs, u16Msec) (((unsigned long long)u32Secs << 10)|\
96                                           (u16Msec & 0x3FF))
97 
98 #define RTC_SECS_IN_U64MSEC(u64Msec)     ((unsigned long)(u64Msec  >>   10))
99 #define RTC_MSEC_IN_U64MSEC(u64Msec)     ((unsigned short)(u64Msec & 0x3FF))
100 
101 #define RTC_MSEC_U32_REG_ADDR            (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2)
102 #define RTC_SECS_U32_REG_ADDR            (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG3)
103 
104 //*****************************************************************************
105 // Register Access and Updates
106 //
107 // Tick of SCC has a resolution of 32768Hz, meaning 1 sec is equal to 32768
108 // clock ticks. Ideal way of getting time in millisecond will involve floating
109 // point arithmetic (division by 32.768). To avoid this, we simply divide it by
110 // 32, which will give a range from 0 -1023(instead of 0-999). To use this
111 // output correctly we have to take care of this inaccuracy externally.
112 // following wrapper can be used to convert the value from cycles to
113 // millisecond:
114 //
115 // CYCLES_U16MS(cycles) ((cycles * 1000) / 1024),
116 //
117 // Similarly, before setting the value, it must be first converted (from ms to
118 // cycles).
119 //
120 // U16MS_CYCLES(msec)   ((msec * 1024) / 1000)
121 //
122 // Note: There is a precision loss of 1 ms with the above scheme.
123 //
124 //
125 #define SCC_U64MSEC_GET()                (RTCFastDomainCounterGet() >> 5)
126 #define SCC_U64MSEC_MATCH_SET(u64Msec)   (MAP_PRCMSlowClkCtrMatchSet(u64Msec << 5))
127 #define SCC_U64MSEC_MATCH_GET()          (MAP_PRCMSlowClkCtrMatchGet() >> 5)
128 
129 //*****************************************************************************
130 //
131 // Bit:  31 is used to indicate use of RTC. If set as '1', RTC feature is used.
132 // Bit:  30 is used to indicate that a safe boot should be performed.
133 // bit:  29 is used to indicate that the last reset was caused by the WDT.
134 // bit:  28 is used to indicate that the board is booting for the first time after being programmed in factory.
135 // Bits: 27 and 26 are unused.
136 // Bits: 25 to 16 are used to save millisecond part of RTC reference.
137 // Bits: 15 to 0 are being used for HW Changes / ECO.
138 //
139 //*****************************************************************************
140 
141 //*****************************************************************************
142 // Set RTC USE Bit
143 //*****************************************************************************
RTCUseSet(void)144 static void RTCUseSet(void)
145 {
146   unsigned int uiRegValue;
147 
148   uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 31);
149 
150   PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
151 }
152 
153 //*****************************************************************************
154 // Clear RTC USE Bit
155 //*****************************************************************************
RTCUseClear(void)156 static void RTCUseClear(void)
157 {
158   unsigned int uiRegValue;
159 
160   uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 31));
161 
162   PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
163 }
164 
165 //*****************************************************************************
166 // Checks if RTC-USE bit is set
167 //*****************************************************************************
IsRTCUsed(void)168 static tBoolean IsRTCUsed(void)
169 {
170   return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 31)) ? true : false;
171 }
172 
173 //*****************************************************************************
174 // Read 16-bit mSecs
175 //*****************************************************************************
RTCU32MSecRegRead(void)176 static unsigned short RTCU32MSecRegRead(void)
177 {
178   return ((MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) >> 16) & 0x03FF);
179 }
180 
181 //*****************************************************************************
182 // Write 16-bit mSecs
183 //*****************************************************************************
RTCU32MSecRegWrite(unsigned int u32Msec)184 static void RTCU32MSecRegWrite(unsigned int u32Msec)
185 {
186    unsigned int uiRegValue;
187 
188    // read the whole register and clear the msec bits
189    uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(0x03FF << 16));
190 
191    // write the msec bits only
192    MAP_PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue | ((u32Msec & 0x03FF) << 16));
193 }
194 
195 //*****************************************************************************
196 // Read 32-bit Secs
197 //*****************************************************************************
RTCU32SecRegRead(void)198 static unsigned long RTCU32SecRegRead(void)
199 {
200   return (MAP_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   MAP_PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec);
209 }
210 
211 //*****************************************************************************
212 // Fast function to get the most accurate RTC counter value
213 //*****************************************************************************
RTCFastDomainCounterGet(void)214 static unsigned long long RTCFastDomainCounterGet (void) {
215 
216     #define BRK_IF_RTC_CTRS_ALIGN(c2, c1)       if (c2 - c1 <= 1) {     \
217                                                     itr++;              \
218                                                     break;              \
219                                                 }
220 
221     unsigned long long rtc_count1, rtc_count2, rtc_count3;
222     unsigned int itr;
223 
224     do {
225         rtc_count1 = PRCMSlowClkCtrFastGet();
226         rtc_count2 = PRCMSlowClkCtrFastGet();
227         rtc_count3 = PRCMSlowClkCtrFastGet();
228         itr = 0;
229 
230         BRK_IF_RTC_CTRS_ALIGN(rtc_count2, rtc_count1);
231         BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count2);
232         BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count1);
233 
234         // Consistent values in two consecutive reads implies a correct
235         // value of the counter. Do note, the counter does not give the
236         // calendar time but a hardware that ticks upwards continuously.
237         // The 48-bit counter operates at 32,768 HZ.
238 
239     } while (true);
240 
241     return (1 == itr) ? rtc_count2 : rtc_count3;
242 }
243 
244 //*****************************************************************************
245 // Macros
246 //*****************************************************************************
247 #define IS_RTC_USED()                   IsRTCUsed()
248 #define RTC_USE_SET()                   RTCUseSet()
249 #define RTC_USE_CLR()                   RTCUseClear()
250 
251 #define RTC_U32MSEC_REG_RD()            RTCU32MSecRegRead()
252 #define RTC_U32MSEC_REG_WR(u32Msec)     RTCU32MSecRegWrite(u32Msec)
253 
254 #define RTC_U32SECS_REG_RD()            RTCU32SecRegRead()
255 #define RTC_U32SECS_REG_WR(u32Secs)     RTCU32SecRegWrite(u32Secs)
256 
257 #define SELECT_SCC_U42BITS(u64Msec)     (u64Msec & 0x3ffffffffff)
258 
259 //*****************************************************************************
260 // Global Peripheral clock and rest Registers
261 //*****************************************************************************
262 static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] =
263 {
264 
265 	{APPS_RCM_O_CAMERA_CLK_GATING,   APPS_RCM_O_CAMERA_SOFT_RESET   },
266 	{APPS_RCM_O_MCASP_CLK_GATING,    APPS_RCM_O_MCASP_SOFT_RESET    },
267 	{APPS_RCM_O_MMCHS_CLK_GATING,    APPS_RCM_O_MMCHS_SOFT_RESET    },
268 	{APPS_RCM_O_MCSPI_A1_CLK_GATING, APPS_RCM_O_MCSPI_A1_SOFT_RESET },
269 	{APPS_RCM_O_MCSPI_A2_CLK_GATING, APPS_RCM_O_MCSPI_A2_SOFT_RESET },
270 	{APPS_RCM_O_UDMA_A_CLK_GATING,   APPS_RCM_O_UDMA_A_SOFT_RESET   },
271 	{APPS_RCM_O_GPIO_A_CLK_GATING,   APPS_RCM_O_GPIO_A_SOFT_RESET   },
272 	{APPS_RCM_O_GPIO_B_CLK_GATING,   APPS_RCM_O_GPIO_B_SOFT_RESET   },
273 	{APPS_RCM_O_GPIO_C_CLK_GATING,   APPS_RCM_O_GPIO_C_SOFT_RESET   },
274 	{APPS_RCM_O_GPIO_D_CLK_GATING,   APPS_RCM_O_GPIO_D_SOFT_RESET   },
275 	{APPS_RCM_O_GPIO_E_CLK_GATING,   APPS_RCM_O_GPIO_E_SOFT_RESET   },
276 	{APPS_RCM_O_WDOG_A_CLK_GATING,   APPS_RCM_O_WDOG_A_SOFT_RESET   },
277 	{APPS_RCM_O_UART_A0_CLK_GATING,  APPS_RCM_O_UART_A0_SOFT_RESET  },
278 	{APPS_RCM_O_UART_A1_CLK_GATING,  APPS_RCM_O_UART_A1_SOFT_RESET  },
279 	{APPS_RCM_O_GPT_A0_CLK_GATING ,  APPS_RCM_O_GPT_A0_SOFT_RESET   },
280 	{APPS_RCM_O_GPT_A1_CLK_GATING,   APPS_RCM_O_GPT_A1_SOFT_RESET   },
281 	{APPS_RCM_O_GPT_A2_CLK_GATING,   APPS_RCM_O_GPT_A2_SOFT_RESET   },
282 	{APPS_RCM_O_GPT_A3_CLK_GATING,   APPS_RCM_O_GPT_A3_SOFT_RESET   },
283 	{APPS_RCM_O_CRYPTO_CLK_GATING,   APPS_RCM_O_CRYPTO_SOFT_RESET   },
284 	{APPS_RCM_O_MCSPI_S0_CLK_GATING, APPS_RCM_O_MCSPI_S0_SOFT_RESET },
285 	{APPS_RCM_O_I2C_CLK_GATING,      APPS_RCM_O_I2C_SOFT_RESET      }
286 
287 };
288 
289 //*****************************************************************************
290 //
291 //! Set a special bit
292 //!
293 //! \return None.
294 //
295 //*****************************************************************************
PRCMSetSpecialBit(unsigned char bit)296 void PRCMSetSpecialBit(unsigned char bit)
297 {
298     unsigned int uiRegValue;
299 
300     uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << bit);
301 
302     PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
303 }
304 
305 //*****************************************************************************
306 //
307 //! Clear a special bit
308 //!
309 //! \return None.
310 //
311 //*****************************************************************************
PRCMClearSpecialBit(unsigned char bit)312 void PRCMClearSpecialBit(unsigned char bit)
313 {
314     unsigned int uiRegValue;
315 
316     uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << bit));
317 
318     PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
319 }
320 
321 //*****************************************************************************
322 //
323 //! Read a special bit
324 //!
325 //! \return Value of the bit
326 //
327 //*****************************************************************************
PRCMGetSpecialBit(unsigned char bit)328 tBoolean PRCMGetSpecialBit(unsigned char bit)
329 {
330     tBoolean value = (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << bit)) ? true : false;
331     // special bits must be cleared immediatelly after reading
332     PRCMClearSpecialBit(bit);
333     return value;
334 }
335 
336 //*****************************************************************************
337 //
338 //! Performs a software reset of a SOC
339 //!
340 //! This function performs a software reset of a SOC
341 //!
342 //! \return None.
343 //
344 //*****************************************************************************
PRCMSOCReset(void)345 void PRCMSOCReset(void)
346 {
347   //
348   // Reset MCU
349   //
350   HWREG(GPRCM_BASE+ GPRCM_O_MCU_GLOBAL_SOFT_RESET) |= 0x1;
351 
352 }
353 
354 //*****************************************************************************
355 //
356 //! Performs a software reset of a MCU and associated peripherals
357 //!
358 //! \param bIncludeSubsystem is \b true to reset associated peripherals.
359 //!
360 //! This function performs a software reset of a MCU and associated peripherals.
361 //! To reset the associated peripheral, the parameter \e bIncludeSubsystem
362 //! should be set to \b true.
363 //!
364 //! \return None.
365 //
366 //*****************************************************************************
PRCMMCUReset(tBoolean bIncludeSubsystem)367 void PRCMMCUReset(tBoolean bIncludeSubsystem)
368 {
369   if(bIncludeSubsystem)
370   {
371     //
372     // Reset Apps processor and associated peripheral
373     //
374     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x2;
375   }
376   else
377   {
378     //
379     // Reset Apps processor only
380     //
381     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x1;
382   }
383 }
384 
385 //*****************************************************************************
386 //
387 //! Gets the reason for a reset.
388 //!
389 //! This function returns the reason(s) for a reset. The reset reason are:-
390 //! -\b PRCM_POWER_ON  - Device is powering up.
391 //! -\b PRCM_LPDS_EXIT - Device is exiting from LPDS.
392 //! -\b PRCM_CORE_RESET - Device is exiting soft core only reset
393 //! -\b PRCM_MCU_RESET - Device is exiting soft subsystem reset.
394 //! -\b PRCM_WDT_RESET - Device was reset by watchdog.
395 //! -\b PRCM_SOC_RESET - Device is exting SOC reset.
396 //! -\b PRCM_HIB_EXIT - Device is exiting hibernate.
397 //!
398 //! \return Returns one of the cause defined above.
399 //
400 //*****************************************************************************
PRCMSysResetCauseGet(void)401 unsigned long PRCMSysResetCauseGet(void)
402 {
403   unsigned long ulWakeupStatus;
404 
405   //
406   // Read the Reset status
407   //
408   ulWakeupStatus = (HWREG(GPRCM_BASE+ GPRCM_O_APPS_RESET_CAUSE) & 0xFF);
409 
410   //
411   // For hibernate do additional chaeck.
412   //
413   if(ulWakeupStatus == PRCM_POWER_ON)
414   {
415     if(MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1)
416     {
417       ulWakeupStatus = PRCM_HIB_EXIT;
418     }
419   }
420 
421   //
422   // Return status.
423   //
424   return ulWakeupStatus;
425 }
426 
427 //*****************************************************************************
428 //
429 //! Enable clock(s) to peripheral.
430 //!
431 //! \param ulPeripheral is one of the valid peripherals
432 //! \param ulClkFlags are bitmask of clock(s) to be enabled.
433 //!
434 //! This function enables the clock for the specified peripheral. Peripherals
435 //! are by default clock gated (disabled) and generates a bus fault if
436 //! accessed.
437 //!
438 //! The parameter \e ulClkFlags can be logical OR of the following:
439 //! -\b PRCM_RUN_MODE_CLK - Ungates clock to the peripheral
440 //! -\b PRCM_SLP_MODE_CLK - Keeps the clocks ungated in sleep.
441 //! -\b PRCM_DSLP_MODE_CLK - Keeps the clock ungated in deepsleep.
442 //!
443 //! \return None.
444 //
445 //*****************************************************************************
PRCMPeripheralClkEnable(unsigned long ulPeripheral,unsigned long ulClkFlags)446 void PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags)
447 {
448   //
449   // Enable the specified peripheral clocks, Nothing to be done for PRCM_ADC
450   // as it is a dummy define for pinmux utility code generation
451   //
452   if(ulPeripheral != PRCM_ADC)
453   {
454     HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) |= ulClkFlags;
455   }
456   //
457   // Set the default clock for camera
458   //
459   if(ulPeripheral == PRCM_CAMERA)
460   {
461     HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) = 0x0404;
462   }
463 }
464 
465 //*****************************************************************************
466 //
467 //! Disables clock(s) to peripheral.
468 //!
469 //! \param ulPeripheral is one of the valid peripherals
470 //! \param ulClkFlags are bitmask of clock(s) to be enabled.
471 //!
472 //! This function disable the clock for the specified peripheral. Peripherals
473 //! are by default clock gated (disabled) and generated a bus fault if
474 //! accessed.
475 //!
476 //! The parameter \e ulClkFlags can be logical OR bit fields as defined in
477 //! PRCMEnablePeripheral().
478 //!
479 //! \return None.
480 //
481 //*****************************************************************************
PRCMPeripheralClkDisable(unsigned long ulPeripheral,unsigned long ulClkFlags)482 void PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags)
483 {
484   //
485   // Disable the specified peripheral clocks
486   //
487   HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) &= ~ulClkFlags;
488 }
489 
490 //*****************************************************************************
491 //
492 //! Gets the input clock for the specified peripheral.
493 //!
494 //! \param ulPeripheral is one of the valid peripherals.
495 //!
496 //! This function gets the input clock for the specified peripheral.
497 //!
498 //! The parameter \e ulPeripheral has the same definition as that in
499 //! PRCMPeripheralClkEnable();
500 //!
501 //! \return Returns input clock frequency for specified peripheral.
502 //
503 //*****************************************************************************
PRCMPeripheralClockGet(unsigned long ulPeripheral)504 unsigned long PRCMPeripheralClockGet(unsigned long ulPeripheral)
505 {
506   unsigned long ulClockFreq;
507   unsigned long ulHiPulseDiv;
508   unsigned long ulLoPulseDiv;
509 
510   //
511   // Get the clock based on specified peripheral.
512   //
513   if(((ulPeripheral == PRCM_SSPI) | (ulPeripheral == PRCM_LSPI)
514             | (ulPeripheral == PRCM_GSPI)))
515   {
516     return XTAL_CLK;
517   }
518   else if(ulPeripheral == PRCM_CAMERA)
519   {
520     ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) >> 8) & 0x07);
521     ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN)& 0xFF);
522   }
523   else if(ulPeripheral == PRCM_SDHOST)
524   {
525     ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN) >> 8) & 0x07);
526     ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN)& 0xFF);
527   }
528   else
529   {
530     return SYS_CLK;
531   }
532 
533   //
534   // Compute the clock freq. from the divider value
535   //
536   ulClockFreq = (240000000/((ulHiPulseDiv + 1) + (ulLoPulseDiv + 1)));
537 
538   //
539   // Return the clock rate.
540   //
541   return ulClockFreq;
542 }
543 
544 //*****************************************************************************
545 //
546 //! Performs a software reset of a peripheral.
547 //!
548 //! \param ulPeripheral is one of the valid peripheral.
549 //!
550 //! This assert or deassert reset to the specified peripheral based of the
551 //! \e bAssert parameter.
552 //!
553 //! \return None.
554 //
555 //*****************************************************************************
PRCMPeripheralReset(unsigned long ulPeripheral)556 void PRCMPeripheralReset(unsigned long ulPeripheral)
557 {
558   volatile unsigned long ulDelay;
559 
560   if( ulPeripheral != PRCM_DTHE)
561   {
562     //
563     // Assert the reset
564     //
565     HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg)
566                                                          |= PRCM_SOFT_RESET;
567     //
568     // Delay for a little bit.
569     //
570     for(ulDelay = 0; ulDelay < 16; ulDelay++)
571     {
572     }
573 
574     //
575     // Deassert the reset
576     //
577     HWREG(ARCM_BASE+PRCM_PeriphRegsList[ulPeripheral].ulRstReg)
578                                                           &= ~PRCM_SOFT_RESET;
579   }
580 }
581 
582 //*****************************************************************************
583 //
584 //! Determines if a peripheral is ready.
585 //!
586 //! \param ulPeripheral is one of the valid modules
587 //!
588 //! This function determines if a particular peripheral is ready to be
589 //! accessed. The peripheral may be in a non-ready state if it is not enabled,
590 //! is being held in reset, or is in the process of becoming ready after being
591 //! enabled or taken out of reset.
592 //!
593 //! \return Returns \b true if the  peripheral is ready, \b false otherwise.
594 //
595 //*****************************************************************************
PRCMPeripheralStatusGet(unsigned long ulPeripheral)596 tBoolean PRCMPeripheralStatusGet(unsigned long ulPeripheral)
597 {
598   unsigned long ReadyBit;
599 
600   //
601   // Read the ready bit status
602   //
603   ReadyBit = HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg);
604   ReadyBit = ReadyBit & PRCM_ENABLE_STATUS;
605 
606   if (ReadyBit)
607   {
608     //
609     // Module is ready
610     //
611     return(true);
612   }
613   else
614   {
615     //
616     // Module is not ready
617     //
618     return(false);
619   }
620 }
621 
622 //*****************************************************************************
623 //
624 //! Configure I2S fracactional divider
625 //!
626 //! \param ulI2CClkFreq is the required input clock for McAPS module
627 //!
628 //! This function configures I2S fractional divider. By default this
629 //! divider is set to output 24 Mhz clock to I2S module.
630 //!
631 //! The minimum frequency that can be obtained by configuring this divider is
632 //!
633 //! (240000KHz/1023.99) =  234.377 KHz
634 //!
635 //! \return None.
636 //
637 //*****************************************************************************
PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)638 void PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)
639 {
640  unsigned long long ullDiv;
641   unsigned short usInteger;
642   unsigned short usFrac;
643 
644   ullDiv = (((unsigned long long)240000000 * 65536)/ulI2CClkFreq);
645 
646   usInteger = (ullDiv/65536);
647   usFrac    = (ullDiv%65536);
648 
649   HWREG(ARCM_BASE + APPS_RCM_O_MCASP_FRAC_CLK_CONFIG0) =
650     ((usInteger & 0x3FF) << 16 | usFrac);
651 }
652 
653 //*****************************************************************************
654 //
655 //! Sets the LPDS exit PC and SP restore vlaues.
656 //!
657 //! \param ulStackPtr is the SP restore value.
658 //! \param ulProgCntr is the PC restore value
659 //!
660 //! This function sets the LPDS exit PC and SP restore vlaues. Setting
661 //! \e ulProgCntr to a non-zero value, forces bootloader to jump to that
662 //! address with Stack Pointer initialized to \e ulStackPtr on LPDS exit,
663 //! otherwise the application's vector table entries are used.
664 //!
665 //! \return None.
666 //
667 //*****************************************************************************
PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr,unsigned long ulProgCntr)668 void PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr)
669 {
670   //
671   // Set The SP Value
672   //
673   HWREG(0x4402E18C) = ulStackPtr;
674 
675   //
676   // Set The PC Value
677   //
678   HWREG(0x4402E190) = ulProgCntr;
679 }
680 
681 //*****************************************************************************
682 //
683 //! Puts the system into Low Power Deel Sleep (LPDS) power mode.
684 //!
685 //! This function puts the system into Low Power Deel Sleep (LPDS) power mode.
686 //! A call to this function never returns and the execution starts from Reset.
687 //! \sa PRCMLPDSRestoreInfoSet().
688 //!
689 //! \return None.
690 //!
691 //! \note The Test Power Domain is shutdown whenever the system
692 //!  enters LPDS (by default). In order to avoid this and allow for
693 //!  connecting back the debugger after waking up from LPDS,
694 //!  the macro KEEP_TESTPD_ALIVE has to be defined while building the library.
695 //!  This is recommended for development purposes only as it adds to
696 //!  the current consumption of the system.
697 //!
698 //
699 //*****************************************************************************
PRCMLPDSEnter(void)700 void PRCMLPDSEnter(void)
701 {
702 #ifndef DEBUG
703   //
704   // Disable TestPD
705   //
706   HWREG(0x4402E168) |= (1<<9);
707 #endif
708 
709   //
710   // Set bandgap duty cycle to 1
711   //
712   HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
713 
714   //
715   // Request LPDS
716   //
717   HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ) = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ;
718 
719   __asm("    nop\n"
720         "    nop\n"
721         "    nop\n"
722         "    nop\n");
723 }
724 
725 //*****************************************************************************
726 //
727 //! Enable the individual LPDS wakeup source(s).
728 //!
729 //! \param ulLpdsWakeupSrc is logical OR of wakeup sources.
730 //!
731 //! This function enable the individual LPDS wakeup source(s) and following
732 //! three wakeup sources (\e ulLpdsWakeupSrc ) are supported by the device.
733 //! -\b PRCM_LPDS_HOST_IRQ
734 //! -\b PRCM_LPDS_GPIO
735 //! -\b PRCM_LPDS_TIMER
736 //!
737 //! \return None.
738 //
739 //*****************************************************************************
PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)740 void PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
741 {
742   unsigned long ulRegVal;
743 
744   //
745   // Read the current wakup sources
746   //
747   ulRegVal = HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG);
748 
749   //
750   // Enable individual wakeup source
751   //
752   ulRegVal = ((ulRegVal | ulLpdsWakeupSrc) & 0x91);
753 
754   //
755   // Set the configuration in the register
756   //
757   HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) = ulRegVal;
758 }
759 
760 //*****************************************************************************
761 //
762 //! Disable the individual LPDS wakeup source(s).
763 //!
764 //! \param ulLpdsWakeupSrc is logical OR of wakeup sources.
765 //!
766 //! This function enable the individual LPDS wakeup source(s) and following
767 //! three wake up sources (\e ulLpdsWakeupSrc ) are supported by the device.
768 //! -\b PRCM_LPDS_HOST_IRQ
769 //! -\b PRCM_LPDS_GPIO
770 //! -\b PRCM_LPDS_TIMER
771 //!
772 //! \return None.
773 //
774 //*****************************************************************************
PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)775 void PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)
776 {
777   HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) &= ~ulLpdsWakeupSrc;
778 }
779 
780 
781 //*****************************************************************************
782 //
783 //! Get LPDS wakeup cause
784 //!
785 //! This function gets LPDS wakeup caouse
786 //!
787 //! \return Returns values enumerated as described in
788 //! PRCMLPDSWakeupSourceEnable().
789 //
790 //*****************************************************************************
PRCMLPDSWakeupCauseGet(void)791 unsigned long PRCMLPDSWakeupCauseGet(void)
792 {
793   return (HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_SRC));
794 }
795 
796 //*****************************************************************************
797 //
798 //! Sets LPDS wakeup Timer
799 //!
800 //! \param ulTicks is number of 32.768 KHz clocks
801 //!
802 //! This function sets internal LPDS wakeup timer running at 32.768 KHz. The
803 //! timer is only configured if the parameter \e ulTicks is in valid range i.e.
804 //! from 21 to 2^32.
805 //!
806 //! \return Returns \b true on success, \b false otherwise.
807 //
808 //*****************************************************************************
PRCMLPDSIntervalSet(unsigned long ulTicks)809 void PRCMLPDSIntervalSet(unsigned long ulTicks)
810 {
811   //
812   // Check sleep is atleast for 21 cycles
813   // If not set the sleep time to 21 cycles
814   //
815   if( ulTicks < 21)
816   {
817       ulTicks = 21;
818   }
819 
820   HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_WAKE_CFG) = ulTicks;
821   HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_OPP_CFG) = ulTicks-20;
822 }
823 
824 //*****************************************************************************
825 //
826 //! Selects the GPIO for LPDS wakeup
827 //!
828 //! \param ulGPIOPin is one of the valid GPIO fro LPDS wakeup.
829 //! \param ulType is the wakeup trigger type.
830 //!
831 //! This function setects the wakeup GPIO for LPDS wakeup and can be
832 //! used to select one out of 7 pre-defined GPIO(s).
833 //!
834 //! The parameter \e ulLpdsGPIOSel should be one of the following:-
835 //! -\b PRCM_LPDS_GPIO2
836 //! -\b PRCM_LPDS_GPIO4
837 //! -\b PRCM_LPDS_GPIO13
838 //! -\b PRCM_LPDS_GPIO17
839 //! -\b PRCM_LPDS_GPIO11
840 //! -\b PRCM_LPDS_GPIO24
841 //! -\b PRCM_LPDS_GPIO26
842 //!
843 //! The parameter \e ulType sets the trigger type and can be one of the
844 //! following:
845 //! - \b PRCM_LPDS_LOW_LEVEL
846 //! - \b PRCM_LPDS_HIGH_LEVEL
847 //! - \b PRCM_LPDS_FALL_EDGE
848 //! - \b PRCM_LPDS_RISE_EDGE
849 //!
850 //! \return None.
851 //
852 //*****************************************************************************
PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin,unsigned long ulType)853 void PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)
854 {
855   //
856   // Set the wakeup GPIO
857   //
858   MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin);
859 
860   //
861   // Set the trigger type.
862   //
863   HWREG(GPRCM_BASE + GPRCM_O_APPS_GPIO_WAKE_CONF) = (ulType & 0x3);
864 }
865 
866 //*****************************************************************************
867 //
868 //! Puts the system into Sleep.
869 //!
870 //! This function puts the system into sleep power mode. System exits the power
871 //! state on any one of the available interrupt. On exit from sleep mode the
872 //! function returns to the calling function with all the processor core
873 //! registers retained.
874 //!
875 //! \return None.
876 //
877 //*****************************************************************************
PRCMSleepEnter(void)878 void PRCMSleepEnter(void)
879 {
880   //
881   // Request Sleep
882   //
883   CPUwfi();
884 }
885 
886 //*****************************************************************************
887 //
888 //! Puts the system into Deep Sleep power mode.
889 //!
890 //! This function puts the system into Deep Sleep power mode. System exits the
891 //! power state on any one of the available interrupt. On exit from deep
892 //! sleep the function returns to the calling function with all the processor
893 //! core registers retained.
894 //!
895 //! \return None.
896 //
897 //*****************************************************************************
PRCMDeepSleepEnter(void)898 void PRCMDeepSleepEnter(void)
899 {
900   //
901   // Set bandgap duty cycle to 1
902   //
903   HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
904 
905   //
906   // Enable DSLP in cortex
907   //
908   HWREG(0xE000ED10)|=1<<2;
909 
910   //
911   // Request Deep Sleep
912   //
913   CPUwfi();
914 
915   //
916   // Disable DSLP in cortex before
917   // returning to the caller
918   //
919   HWREG(0xE000ED10) &= ~(1<<2);
920 
921 }
922 
923 //*****************************************************************************
924 //
925 //! Enable SRAM column retention during Deep Sleep and/or LPDS Power mode(s)
926 //!
927 //! \param ulSramColSel is bit mask of valid SRAM columns.
928 //! \param ulModeFlags is the bit mask of power modes.
929 //!
930 //! This functions enables the SRAM retention. The device supports configurable
931 //! SRAM column retention in Low Power Deep Sleep (LPDS) and Deep Sleep power
932 //! modes. Each column is of 64 KB size.
933 //!
934 //! The parameter \e ulSramColSel should be logical OR of the following:-
935 //! -\b PRCM_SRAM_COL_1
936 //! -\b PRCM_SRAM_COL_2
937 //! -\b PRCM_SRAM_COL_3
938 //! -\b PRCM_SRAM_COL_4
939 //!
940 //! The parameter \e ulModeFlags selects the power modes and sholud be logical
941 //! OR of one or more of the following
942 //! -\b PRCM_SRAM_DSLP_RET
943 //! -\b PRCM_SRAM_LPDS_RET
944 //!
945 //! \return None.
946 //
947 //****************************************************************************
PRCMSRAMRetentionEnable(unsigned long ulSramColSel,unsigned long ulModeFlags)948 void PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags)
949 {
950   if(ulModeFlags & PRCM_SRAM_DSLP_RET)
951   {
952     //
953     // Configure deep sleep SRAM retention register
954     //
955     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_DSLP_CFG) = (ulSramColSel & 0xF);
956   }
957 
958   if(ulModeFlags & PRCM_SRAM_LPDS_RET)
959   {
960     //
961     // Configure LPDS SRAM retention register
962     //
963     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) = (ulSramColSel & 0xF);
964   }
965 }
966 
967 //*****************************************************************************
968 //
969 //! Disable SRAM column retention during Deep Sleep and/or LPDS Power mode(s).
970 //!
971 //! \param ulSramColSel is bit mask of valid SRAM columns.
972 //! \param ulFlags is the bit mask of power modes.
973 //!
974 //! This functions disable the SRAM retention. The device supports configurable
975 //! SRAM column retention in Low Power Deep Sleep (LPDS) and Deep Sleep power
976 //! modes. Each column is of 64 KB size.
977 //!
978 //! The parameter \e ulSramColSel should be logical OR of the following:-
979 //! -\b PRCM_SRAM_COL_1
980 //! -\b PRCM_SRAM_COL_2
981 //! -\b PRCM_SRAM_COL_3
982 //! -\b PRCM_SRAM_COL_4
983 //!
984 //! The parameter \e ulFlags selects the power modes and sholud be logical OR
985 //! of one or more of the following
986 //! -\b PRCM_SRAM_DSLP_RET
987 //! -\b PRCM_SRAM_LPDS_RET
988 //!
989 //! \return None.
990 //
991 //****************************************************************************
PRCMSRAMRetentionDisable(unsigned long ulSramColSel,unsigned long ulFlags)992 void PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags)
993 {
994   if(ulFlags & PRCM_SRAM_DSLP_RET)
995   {
996     //
997     // Configure deep sleep SRAM retention register
998     //
999     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_DSLP_CFG) &= ~(ulSramColSel & 0xF);
1000   }
1001 
1002   if(ulFlags & PRCM_SRAM_LPDS_RET)
1003   {
1004     //
1005     // Configure LPDS SRAM retention register
1006     //
1007     HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) &= ~(ulSramColSel & 0xF);
1008   }
1009 }
1010 
1011 
1012 //*****************************************************************************
1013 //
1014 //! Enables individual HIB wakeup source(s).
1015 //!
1016 //! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.
1017 //!
1018 //! This function enables individual HIB wakeup source(s). The paramter
1019 //! \e ulHIBWakupSrc is the bit mask of HIB wakeup sources and should be
1020 //! logical OR of one or more of the follwoing :-
1021 //! -\b PRCM_HIB_SLOW_CLK_CTR
1022 //! -\b PRCM_HIB_GPIO2
1023 //! -\b PRCM_HIB_GPIO4
1024 //! -\b PRCM_HIB_GPIO13
1025 //! -\b PRCM_HIB_GPIO17
1026 //! -\b PRCM_HIB_GPIO11
1027 //! -\b PRCM_HIB_GPIO24
1028 //! -\b PRCM_HIB_GPIO26
1029 //!
1030 //! \return None.
1031 //
1032 //*****************************************************************************
PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)1033 void PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
1034 {
1035   unsigned long ulRegValue;
1036 
1037   //
1038   // Read the RTC register
1039   //
1040   ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
1041 
1042   //
1043   // Enable the RTC as wakeup source if specified
1044   //
1045   ulRegValue |= (ulHIBWakupSrc & 0x1);
1046 
1047   //
1048   // Enable HIB wakeup sources
1049   //
1050   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
1051 
1052   //
1053   // REad the GPIO wakeup configuration register
1054   //
1055   ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
1056 
1057   //
1058   // Enable the specified GPIOs a wakeup sources
1059   //
1060   ulRegValue |= ((ulHIBWakupSrc>>16)&0xFF);
1061 
1062   //
1063   // Write the new register configuration
1064   //
1065   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
1066 }
1067 
1068 //*****************************************************************************
1069 //
1070 //! Disable individual HIB wakeup source(s).
1071 //!
1072 //! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.
1073 //!
1074 //! This function disable individual HIB wakeup source(s). The paramter
1075 //! \e ulHIBWakupSrc is same as bit fileds defined in
1076 //! PRCMEnableHibernateWakeupSource()
1077 //!
1078 //! \return None.
1079 //
1080 //*****************************************************************************
PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)1081 void PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
1082 {
1083   unsigned long ulRegValue;
1084 
1085   //
1086   // Read the RTC register
1087   //
1088   ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
1089 
1090   //
1091   // Disable the RTC as wakeup source if specified
1092   //
1093   ulRegValue &= ~(ulHIBWakupSrc & 0x1);
1094 
1095   //
1096   // Disable HIB wakeup sources
1097   //
1098   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
1099 
1100   //
1101   // Read the GPIO wakeup configuration register
1102   //
1103   ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
1104 
1105   //
1106   // Enable the specified GPIOs a wakeup sources
1107   //
1108   ulRegValue &= ~((ulHIBWakupSrc>>16)&0xFF);
1109 
1110   //
1111   // Write the new register configuration
1112   //
1113   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
1114 }
1115 
1116 
1117 //*****************************************************************************
1118 //
1119 //! Get hibernate wakeup cause
1120 //!
1121 //! This function gets the hibernate wakeup cause.
1122 //!
1123 //! \return Returns \b PRCM_HIB_WAKEUP_CAUSE_SLOW_CLOCK or
1124 //! \b PRCM_HIB_WAKEUP_CAUSE_GPIO
1125 //
1126 //*****************************************************************************
PRCMHibernateWakeupCauseGet(void)1127 unsigned long PRCMHibernateWakeupCauseGet(void)
1128 {
1129   return ((MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS)>>1)&0xF);
1130 }
1131 
1132 //*****************************************************************************
1133 //
1134 //! Sets Hibernate wakeup Timer
1135 //!
1136 //! \param ullTicks is number of 32.768 KHz clocks
1137 //!
1138 //! This function sets internal hibernate wakeup timer running at 32.768 KHz.
1139 //!
1140 //! \return Returns \b true on success, \b false otherwise.
1141 //
1142 //*****************************************************************************
PRCMHibernateIntervalSet(unsigned long long ullTicks)1143 void PRCMHibernateIntervalSet(unsigned long long ullTicks)
1144 {
1145   unsigned long long ullRTCVal;
1146 
1147   //
1148   // Latch the RTC vlaue
1149   //
1150   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1);
1151 
1152   //
1153   // Read latched values as 2 32-bit vlaues
1154   //
1155   ullRTCVal  = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
1156   ullRTCVal  = ullRTCVal << 32;
1157   ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
1158 
1159   //
1160   // Add the interval
1161   //
1162   ullRTCVal = ullRTCVal + ullTicks;
1163 
1164   //
1165   // Set RTC match value
1166   //
1167   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF,
1168                                             (unsigned long)(ullRTCVal));
1169   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF,
1170                                            (unsigned long)(ullRTCVal>>32));
1171 }
1172 
1173 
1174 //*****************************************************************************
1175 //
1176 //! Selects the GPIO(s) for hibernate wakeup
1177 //!
1178 //! \param ulGPIOBitMap is the bit-map of valid hibernate wakeup GPIO.
1179 //! \param ulType is the wakeup trigger type.
1180 //!
1181 //! This function setects the wakeup GPIO for hibernate and can be
1182 //! used to select any combination of 7 pre-defined GPIO(s).
1183 //!
1184 //! This function enables individual HIB wakeup source(s). The paramter
1185 //! \e ulGPIOBitMap should be one of the follwoing :-
1186 //! -\b PRCM_HIB_GPIO2
1187 //! -\b PRCM_HIB_GPIO4
1188 //! -\b PRCM_HIB_GPIO13
1189 //! -\b PRCM_HIB_GPIO17
1190 //! -\b PRCM_HIB_GPIO11
1191 //! -\b PRCM_HIB_GPIO24
1192 //! -\b PRCM_HIB_GPIO26
1193 //!
1194 //! The parameter \e ulType sets the trigger type and can be one of the
1195 //! following:
1196 //! - \b PRCM_HIB_LOW_LEVEL
1197 //! - \b PRCM_HIB_HIGH_LEVEL
1198 //! - \b PRCM_HIB_FALL_EDGE
1199 //! - \b PRCM_HIB_RISE_EDGE
1200 //!
1201 //! \return None.
1202 //
1203 //*****************************************************************************
PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap,unsigned long ulType)1204 void PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)
1205 {
1206   unsigned char ucLoop;
1207   unsigned long ulRegValue;
1208 
1209   //
1210   // Shift the bits to extract the GPIO selection
1211   //
1212   ulGPIOBitMap >>= 16;
1213 
1214   //
1215   // Set the configuration for each GPIO
1216   //
1217   for(ucLoop=0; ucLoop < 7; ucLoop++)
1218   {
1219     if(ulGPIOBitMap & (1<<ucLoop))
1220     {
1221       ulRegValue  = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF);
1222       ulRegValue |= (ulType << (ucLoop*2));
1223       MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF, ulRegValue);
1224     }
1225   }
1226 }
1227 
1228 //*****************************************************************************
1229 //
1230 //! Puts the system into Hibernate
1231 //!
1232 //! This function puts the system into Hibernate. The device enters HIB
1233 //! immediately and on exit from HIB device core starts its execution from
1234 //! reset thus the function never returns.
1235 //!
1236 //! \return None.
1237 //
1238 //*****************************************************************************
PRCMHibernateEnter(void)1239 void PRCMHibernateEnter(void)
1240 {
1241 
1242   //
1243   // Request hibernate.
1244   //
1245   MAP_PRCMHIBRegWrite((HIB3P3_BASE+HIB3P3_O_MEM_HIB_REQ),0x1);
1246 
1247   __asm("    nop\n"
1248         "    nop\n"
1249         "    nop\n"
1250         "    nop\n");
1251 }
1252 
1253 //*****************************************************************************
1254 //
1255 //! Gets the current value of the internal slow clock counter
1256 //!
1257 //! This function latches and reads the internal RTC running at 32.768 Khz
1258 //!
1259 //! \return 64-bit current counter vlaue.
1260 //
1261 //*****************************************************************************
PRCMSlowClkCtrGet(void)1262 unsigned long long PRCMSlowClkCtrGet(void)
1263 {
1264   unsigned long long ullRTCVal;
1265 
1266   //
1267   // Latch the RTC vlaue
1268   //
1269   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ, 0x1);
1270 
1271   //
1272   // Read latched values as 2 32-bit vlaues
1273   //
1274   ullRTCVal  = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
1275   ullRTCVal  = ullRTCVal << 32;
1276   ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
1277 
1278   return ullRTCVal;
1279 }
1280 
1281 //*****************************************************************************
1282 //
1283 //! Gets the current value of the internal slow clock counter
1284 //!
1285 //! This function is similar to \sa PRCMSlowClkCtrGet() but reads the counter
1286 //! value from a relatively faster interface using an auto-latch mechainsm.
1287 //!
1288 //! \note Due to the nature of implemetation of auto latching, when using this
1289 //! API, the recommendation is to read the value thrice and identify the right
1290 //! value (as 2 out the 3 read values will always be correct and with a max. of
1291 //! 1 LSB change)
1292 //!
1293 //! \return 64-bit current counter vlaue.
1294 //
1295 //*****************************************************************************
PRCMSlowClkCtrFastGet(void)1296 unsigned long long PRCMSlowClkCtrFastGet(void)
1297 {
1298   unsigned long long ullRTCVal;
1299 
1300   //
1301   // Read as 2 32-bit values
1302   //
1303   ullRTCVal = HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_MSW_1P2);
1304   ullRTCVal = ullRTCVal << 32;
1305   ullRTCVal |= HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_LSW_1P2);
1306 
1307   return ullRTCVal;
1308 
1309 }
1310 
1311 //*****************************************************************************
1312 //
1313 //! Sets slow clock counter match value to interrupt the processor.
1314 //!
1315 //! \param ullValue is the match value.
1316 //!
1317 //! This function sets the match value for  slow clock counter. This is use
1318 //! to interrupt the processor when RTC counts to the specified value.
1319 //!
1320 //! \return None.
1321 //
1322 //*****************************************************************************
PRCMSlowClkCtrMatchSet(unsigned long long ullValue)1323 void PRCMSlowClkCtrMatchSet(unsigned long long ullValue)
1324 {
1325   //
1326   // Set RTC match value
1327   //
1328   MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF,
1329                                            (unsigned long)(ullValue));
1330   MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF,
1331                                            (unsigned long)(ullValue>>32));
1332 }
1333 
1334 //*****************************************************************************
1335 //
1336 //! Gets slow clock counter match value.
1337 //!
1338 //! This function gets the match value for  slow clock counter. This is use
1339 //! to interrupt the processor when RTC counts to the specified value.
1340 //!
1341 //! \return None.
1342 //
1343 //*****************************************************************************
PRCMSlowClkCtrMatchGet(void)1344 unsigned long long PRCMSlowClkCtrMatchGet(void)
1345 {
1346   unsigned long long ullValue;
1347 
1348   //
1349   // Get RTC match value
1350   //
1351   ullValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF);
1352   ullValue = ullValue<<32;
1353   ullValue |= MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF);
1354 
1355   //
1356   // Return the value
1357   //
1358   return ullValue;
1359 }
1360 
1361 
1362 //*****************************************************************************
1363 //
1364 //! Write to On-Chip Retention (OCR) register.
1365 //!
1366 //! This function writes to On-Chip retention register. The device supports two
1367 //! 4-byte OCR register which are retained across all power mode.
1368 //!
1369 //! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.
1370 //!
1371 //! \return None.
1372 //
1373 //*****************************************************************************
PRCMOCRRegisterWrite(unsigned char ucIndex,unsigned long ulRegValue)1374 void PRCMOCRRegisterWrite(unsigned char ucIndex, unsigned long ulRegValue)
1375 {
1376   MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2+(ucIndex << 2),ulRegValue);
1377 }
1378 
1379 //*****************************************************************************
1380 //
1381 //! Read from On-Chip Retention (OCR) register.
1382 //!
1383 //! This function reads from On-Chip retention register. The device supports two
1384 //! 4-byte OCR register which are retained across all power mode.
1385 //!
1386 //! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.
1387 //!
1388 //! \return None.
1389 //
1390 //*****************************************************************************
PRCMOCRRegisterRead(unsigned char ucIndex)1391 unsigned long PRCMOCRRegisterRead(unsigned char ucIndex)
1392 {
1393   //
1394   // Return the read value.
1395   //
1396   return MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2));
1397 }
1398 
1399 //*****************************************************************************
1400 //
1401 //! Registers an interrupt handler for the PRCM.
1402 //!
1403 //! \param pfnHandler is a pointer to the function to be called when the
1404 //! interrupt is activated.
1405 //!
1406 //! This function does the actual registering of the interrupt handler.  This
1407 //! function enables the global interrupt in the interrupt controller;
1408 //!
1409 //! \return None.
1410 //
1411 //*****************************************************************************
PRCMIntRegister(void (* pfnHandler)(void))1412 void PRCMIntRegister(void (*pfnHandler)(void))
1413 {
1414   //
1415   // Register the interrupt handler.
1416   //
1417   IntRegister(INT_PRCM, pfnHandler);
1418 
1419   //
1420   // Enable the PRCM interrupt.
1421   //
1422   IntEnable(INT_PRCM);
1423 }
1424 
1425 //*****************************************************************************
1426 //
1427 //! Unregisters an interrupt handler for the PRCM.
1428 //!
1429 //! This function does the actual unregistering of the interrupt handler.  It
1430 //! clears the handler to be called when a PRCM interrupt occurs.  This
1431 //! function also masks off the interrupt in the interrupt controller so that
1432 //! the interrupt handler no longer is called.
1433 //!
1434 //! \return None.
1435 //
1436 //*****************************************************************************
PRCMIntUnregister(void)1437 void PRCMIntUnregister(void)
1438 {
1439   //
1440   // Enable the UART interrupt.
1441   //
1442   IntDisable(INT_PRCM);
1443 
1444   //
1445   // Register the interrupt handler.
1446   //
1447   IntUnregister(INT_PRCM);
1448 }
1449 
1450 //*****************************************************************************
1451 //
1452 //! Enables individual PRCM interrupt sources.
1453 //!
1454 //! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
1455 //!
1456 //! This function enables the indicated ARCM interrupt sources.  Only the
1457 //! sources that are enabled can be reflected to the processor interrupt;
1458 //! disabled sources have no effect on the processor.
1459 //!
1460 //! The \e ulIntFlags parameter is the logical OR of any of the following:
1461 //! -\b PRCM_INT_SLOW_CLK_CTR
1462 //!
1463 //
1464 //*****************************************************************************
PRCMIntEnable(unsigned long ulIntFlags)1465 void PRCMIntEnable(unsigned long ulIntFlags)
1466 {
1467   unsigned long ulRegValue;
1468 
1469   if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )
1470   {
1471     //
1472     // Enable PRCM interrupt
1473     //
1474     HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) |= 0x4;
1475 
1476     //
1477     // Enable RTC interrupt
1478     //
1479     ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
1480     ulRegValue |= 0x1;
1481     MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
1482   }
1483 }
1484 
1485 //*****************************************************************************
1486 //
1487 //! Disables individual PRCM interrupt sources.
1488 //!
1489 //! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
1490 //!
1491 //! This function disables the indicated ARCM interrupt sources.  Only the
1492 //! sources that are enabled can be reflected to the processor interrupt;
1493 //! disabled sources have no effect on the processor.
1494 //!
1495 //! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
1496 //! parameter to PRCMEnableInterrupt().
1497 //!
1498 //! \return None.
1499 //
1500 //*****************************************************************************
PRCMIntDisable(unsigned long ulIntFlags)1501 void PRCMIntDisable(unsigned long ulIntFlags)
1502 {
1503   unsigned long ulRegValue;
1504 
1505   if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )
1506   {
1507     //
1508     // Disable PRCM interrupt
1509     //
1510     HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) &= ~0x4;
1511 
1512     //
1513     // Disable RTC interrupt
1514     //
1515     ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
1516     ulRegValue &= ~0x1;
1517     MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
1518   }
1519 }
1520 
1521 //*****************************************************************************
1522 //
1523 //! Gets the current interrupt status.
1524 //!
1525 //! This function returns the PRCM interrupt status of interrupts that are
1526 //! allowed to reflect to the processor. The interrupts are cleared on read.
1527 //!
1528 //! \return Returns the current interrupt status.
1529 //
1530 //*****************************************************************************
PRCMIntStatus(void)1531 unsigned long PRCMIntStatus(void)
1532 {
1533     return HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_STATUS);
1534 }
1535 
1536 //*****************************************************************************
1537 //
1538 //! Mark the function of RTC as being used
1539 //!
1540 //! This function marks in HW that feature to maintain calendar time in device
1541 //! is being used.
1542 //!
1543 //! Specifically, this feature reserves user's HIB Register-1 accessed through
1544 //! PRCMOCRRegisterWrite(1) for internal work / purpose, therefore, the stated
1545 //! register is not available to user. Also, users must not excercise the Slow
1546 //! Clock Counter API(s), if RTC has been set for use.
1547 //!
1548 //! \return None.
1549 //
1550 //*****************************************************************************
PRCMRTCInUseSet(void)1551 void PRCMRTCInUseSet(void)
1552 {
1553         RTC_USE_SET();
1554         return;
1555 }
1556 
1557 //*****************************************************************************
1558 //
1559 //! Clear the function of RTC as being used
1560 //!
1561 //! \return None.
1562 //
1563 //*****************************************************************************
PRCMRTCInUseClear(void)1564 void PRCMRTCInUseClear(void)
1565 {
1566         RTC_USE_CLR();
1567         return;
1568 }
1569 
1570 //*****************************************************************************
1571 //
1572 //! Ascertain whether function of RTC is being used
1573 //!
1574 //! This function indicates whether function of RTC is being used on the device
1575 //! or not.
1576 //!
1577 //! This routine should be utilized by the application software, when returning
1578 //! from low-power, to confirm that RTC has been put to use and may not need to
1579 //! set the value of the RTC.
1580 //!
1581 //! The RTC feature, if set or marked, can be only reset either through reboot
1582 //! or power cycle.
1583 //!
1584 //! \return None.
1585 //
1586 //*****************************************************************************
PRCMRTCInUseGet(void)1587 tBoolean PRCMRTCInUseGet(void)
1588 {
1589         return IS_RTC_USED()? true : false;
1590 }
1591 
1592 //*****************************************************************************
1593 //
1594 //! Set the calendar time in the device.
1595 //!
1596 //! \param ulSecs refers to the seconds part of the  calendar time
1597 //! \param usMsec refers to the fractional (ms) part of the second
1598 //!
1599 //! This function sets the specified calendar time in the device. The calendar
1600 //! time is outlined in terms of seconds and milliseconds. However, the device
1601 //! makes no assumption about the origin or reference of the calendar time.
1602 //!
1603 //! The device uses the indicated calendar value to update and maintain the
1604 //! wall-clock time across active and low power states.
1605 //!
1606 //! The function PRCMRTCInUseSet() must be invoked prior to use of this feature.
1607 //!
1608 //! \return None.
1609 //
1610 //*****************************************************************************
PRCMRTCSet(unsigned long ulSecs,unsigned short usMsec)1611 void PRCMRTCSet(unsigned long ulSecs, unsigned short usMsec)
1612 {
1613         unsigned long long ullMsec = 0;
1614 
1615         if(IS_RTC_USED()) {
1616                 ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec) - SCC_U64MSEC_GET();
1617 
1618                  RTC_U32SECS_REG_WR(RTC_SECS_IN_U64MSEC(ullMsec));
1619                  RTC_U32MSEC_REG_WR(RTC_MSEC_IN_U64MSEC(ullMsec));
1620         }
1621 
1622         return;
1623 }
1624 
1625 //*****************************************************************************
1626 //
1627 //! Get the instantaneous calendar time from the device.
1628 //!
1629 //! \param ulSecs refers to the seconds part of the  calendar time
1630 //! \param usMsec refers to the fractional (ms) part of the second
1631 //!
1632 //! This function fetches the instantaneous value of the ticking calendar time
1633 //! from the device. The calendar time is outlined in terms of seconds and
1634 //! milliseconds.
1635 //!
1636 //! The device provides the calendar value that has been maintained across
1637 //! active and low power states.
1638 //!
1639 //! The function PRCMRTCSet() must have been invoked once to set a reference.
1640 //!
1641 //! \return None.
1642 //
1643 //*****************************************************************************
PRCMRTCGet(unsigned long * ulSecs,unsigned short * usMsec)1644 void PRCMRTCGet(unsigned long *ulSecs, unsigned short *usMsec)
1645 {
1646         unsigned long long ullMsec = 0;
1647 
1648         if(IS_RTC_USED()) {
1649                 ullMsec  = RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
1650                                           RTC_U32MSEC_REG_RD());
1651                 ullMsec += SCC_U64MSEC_GET();
1652         }
1653 
1654         *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);
1655         *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);
1656 
1657         return;
1658 }
1659 
1660 //*****************************************************************************
1661 //
1662 //! Set a calendar time alarm.
1663 //!
1664 //! \param ulSecs refers to the seconds part of the  calendar time
1665 //! \param usMsec refers to the fractional (ms) part of the second
1666 //!
1667 //! This function sets an wall-clock alarm in the device to be reported for  a
1668 //! futuristic calendar time. The calendar time is outlined in terms of seconds
1669 //! and milliseconds.
1670 //!
1671 //! The device provides uses the calendar value that has been maintained across
1672 //! active and low power states to report attainment of alarm time.
1673 //!
1674 //! The function PRCMRTCSet() must have been invoked once to set a reference.
1675 //!
1676 //! \return None.
1677 //
1678 //*****************************************************************************
PRCMRTCMatchSet(unsigned long ulSecs,unsigned short usMsec)1679 void PRCMRTCMatchSet(unsigned long ulSecs, unsigned short usMsec)
1680 {
1681         unsigned long long ullMsec = 0;
1682 
1683         if(IS_RTC_USED()) {
1684                 ullMsec  = RTC_U64MSEC_MK(ulSecs, usMsec);
1685                 ullMsec -= RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
1686                                           RTC_U32MSEC_REG_RD());
1687                 SCC_U64MSEC_MATCH_SET(SELECT_SCC_U42BITS(ullMsec));
1688         }
1689 
1690         return;
1691 }
1692 
1693 //*****************************************************************************
1694 //
1695 //! Get a previously set calendar time alarm.
1696 //!
1697 //! \param ulSecs refers to the seconds part of the  calendar time
1698 //! \param usMsec refers to the fractional (ms) part of the second
1699 //!
1700 //! This function fetches from the device a wall-clock alarm that would  have
1701 //! been previously set in the device. The calendar time is outlined in terms
1702 //! of seconds and milliseconds.
1703 //!
1704 //! If no alarm was set in the past, then this function would fetch a random
1705 //! information.
1706 //!
1707 //! The function PRCMRTCMatchSet() must have been invoked once to set an alarm.
1708 //!
1709 //! \return None.
1710 //
1711 //*****************************************************************************
PRCMRTCMatchGet(unsigned long * ulSecs,unsigned short * usMsec)1712 void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec)
1713 {
1714         unsigned long long ullMsec = 0;
1715 
1716         if(IS_RTC_USED()) {
1717                 ullMsec  = SCC_U64MSEC_MATCH_GET();
1718                 ullMsec += RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
1719                                           RTC_U32MSEC_REG_RD());
1720         }
1721 
1722         *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);
1723         *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);
1724 
1725         return;
1726 }
1727 
1728 //*****************************************************************************
1729 //
1730 //! MCU Initialization Routine
1731 //!
1732 //! This function sets mandatory configurations for the MCU
1733 //!
1734 //! \return None
1735 //
1736 //*****************************************************************************
PRCMCC3200MCUInit(void)1737 void PRCMCC3200MCUInit(void)
1738 {
1739     unsigned long ulRegValue;
1740 
1741     //
1742     // DIG DCDC LPDS ECO Enable
1743     //
1744     HWREG(0x4402F064) |= 0x800000;
1745 
1746     //
1747     // Enable hibernate ECO for PG 1.32 devices only. With this ECO enabled,
1748     // any hibernate wakeup source will be kept masked until the device enters
1749     // hibernate completely (analog + digital)
1750     //
1751     ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE  + HIB3P3_O_MEM_HIB_REG0);
1752     MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4));
1753 
1754     //
1755     // Handling the clock switching (for 1.32 only)
1756     //
1757     HWREG(0x4402E16C) |= 0x3C;
1758 
1759     //
1760     // Enable uDMA
1761     //
1762     MAP_PRCMPeripheralClkEnable(PRCM_UDMA,PRCM_RUN_MODE_CLK);
1763 
1764     //
1765     // Reset uDMA
1766     //
1767     MAP_PRCMPeripheralReset(PRCM_UDMA);
1768 
1769     //
1770     // Disable uDMA
1771     //
1772     MAP_PRCMPeripheralClkDisable(PRCM_UDMA,PRCM_RUN_MODE_CLK);
1773 
1774     //
1775     // Enable RTC
1776     //
1777     if(MAP_PRCMSysResetCauseGet()== PRCM_POWER_ON)
1778     {
1779         MAP_PRCMHIBRegWrite(0x4402F804,0x1);
1780     }
1781 
1782     //
1783     // SWD mode
1784     //
1785     if (((HWREG(0x4402F0C8) & 0xFF) == 0x2))
1786     {
1787         HWREG(0x4402E110) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);
1788         HWREG(0x4402E114) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);
1789     }
1790 
1791     //
1792     // Override JTAG mux
1793     //
1794     HWREG(0x4402E184) |= 0x2;
1795 
1796     //
1797     // Change UART pins(55,57) mode to PIN_MODE_0 if they are in PIN_MODE_1
1798     //
1799     if ((HWREG(0x4402E0A4) & 0xF) == 0x1)
1800     {
1801         HWREG(0x4402E0A4) = ((HWREG(0x4402E0A4) & ~0xF));
1802     }
1803 
1804     if ((HWREG(0x4402E0A8) & 0xF) == 0x1)
1805     {
1806         HWREG(0x4402E0A8) = ((HWREG(0x4402E0A8) & ~0xF));
1807     }
1808 
1809     //
1810     // DIG DCDC VOUT trim settings based on PROCESS INDICATOR
1811     //
1812     if (((HWREG(0x4402DC78) >> 22) & 0xF) == 0xE)
1813     {
1814         HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x32 << 18));
1815     }
1816     else
1817     {
1818         HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x29 << 18));
1819     }
1820 
1821     //
1822     // Enable SOFT RESTART in case of DIG DCDC collapse
1823     //
1824     HWREG(0x4402FC74) &= ~(0x10000000);
1825 
1826 
1827     //
1828     // Disable the sleep for ANA DCDC
1829     //
1830     HWREG(0x4402F0A8) |= 0x00000004 ;
1831 }
1832 
1833 //*****************************************************************************
1834 //
1835 //! Reads 32-bit value from register at specified address
1836 //!
1837 //! \param ulRegAddr is the address of register to be read.
1838 //!
1839 //! This function reads 32-bit value from the register as specified by
1840 //! \e ulRegAddr.
1841 //!
1842 //! \return Return the value of the register.
1843 //
1844 //*****************************************************************************
PRCMHIBRegRead(unsigned long ulRegAddr)1845 unsigned long PRCMHIBRegRead(unsigned long ulRegAddr)
1846 {
1847   unsigned long ulValue;
1848 
1849   //
1850   // Read the Reg value
1851   //
1852   ulValue = HWREG(ulRegAddr);
1853 
1854   //
1855   // Wait for 200 uSec
1856   //
1857   UtilsDelay((80*200)/3);
1858 
1859   //
1860   // Return the value
1861   //
1862   return ulValue;
1863 }
1864 
1865 //*****************************************************************************
1866 //
1867 //! Writes 32-bit value to register at specified address
1868 //!
1869 //! \param ulRegAddr is the address of register to be read.
1870 //! \param ulValue is the 32-bit value to be written.
1871 //!
1872 //! This function writes 32-bit value passed as \e ulValue to the register as
1873 //! specified by \e ulRegAddr
1874 //!
1875 //! \return None
1876 //
1877 //*****************************************************************************
PRCMHIBRegWrite(unsigned long ulRegAddr,unsigned long ulValue)1878 void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue)
1879 {
1880   //
1881   // Read the Reg value
1882   //
1883   HWREG(ulRegAddr) = ulValue;
1884 
1885   //
1886   // Wait for 200 uSec
1887   //
1888   UtilsDelay((80*200)/3);
1889 }
1890 
1891 //*****************************************************************************
1892 //
1893 //! \param ulDivider is clock frequency divider value
1894 //! \param ulWidth is the width of the high pulse
1895 //!
1896 //! This function sets the input frequency for camera module.
1897 //!
1898 //! The frequency is calculated as follows:
1899 //!
1900 //!        f_out = 240MHz/ulDivider;
1901 //!
1902 //! The parameter \e ulWidth sets the width of the high pulse.
1903 //!
1904 //! For e.g.:
1905 //!
1906 //!     ulDivider = 4;
1907 //!     ulWidth   = 2;
1908 //!
1909 //!     f_out = 30 MHz and 50% duty cycle
1910 //!
1911 //! And,
1912 //!
1913 //!     ulDivider = 4;
1914 //!     ulWidth   = 1;
1915 //!
1916 //!     f_out = 30 MHz and 25% duty cycle
1917 //!
1918 //! \return 0 on success, 1 on error
1919 //
1920 //*****************************************************************************
PRCMCameraFreqSet(unsigned char ulDivider,unsigned char ulWidth)1921 unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth)
1922 {
1923     if(ulDivider > ulWidth && ulWidth != 0 )
1924     {
1925       //
1926       // Set  the hifh pulse width
1927       //
1928       HWREG(ARCM_BASE +
1929             APPS_RCM_O_CAMERA_CLK_GEN) = (((ulWidth & 0x07) -1) << 8);
1930 
1931       //
1932       // Set the low pulse width
1933       //
1934       HWREG(ARCM_BASE +
1935             APPS_RCM_O_CAMERA_CLK_GEN) = ((ulDivider - ulWidth - 1) & 0x07);
1936       //
1937       // Return success
1938       //
1939       return 0;
1940     }
1941 
1942     //
1943     // Success;
1944     //
1945     return 1;
1946 }
1947 
1948 //*****************************************************************************
1949 //
1950 // Close the Doxygen group.
1951 //! @}
1952 //
1953 //*****************************************************************************
1954