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