aboutsummaryrefslogtreecommitdiff
path: root/cc3200/hal/prcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'cc3200/hal/prcm.c')
-rw-r--r--cc3200/hal/prcm.c1778
1 files changed, 1778 insertions, 0 deletions
diff --git a/cc3200/hal/prcm.c b/cc3200/hal/prcm.c
new file mode 100644
index 000000000..78b8d8276
--- /dev/null
+++ b/cc3200/hal/prcm.c
@@ -0,0 +1,1778 @@
+//*****************************************************************************
+//
+// prcm.c
+//
+// Driver for the Power, Reset and Clock Module (PRCM)
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+//! \addtogroup PRCM_Power_Reset_Clock_Module_api
+//! @{
+//
+//*****************************************************************************
+
+#include "inc/hw_types.h"
+#include "inc/hw_ints.h"
+#include "inc/hw_memmap.h"
+#include "inc/hw_apps_rcm.h"
+#include "inc/hw_gprcm.h"
+#include "inc/hw_hib1p2.h"
+#include "inc/hw_hib3p3.h"
+#include "prcm.h"
+#include "interrupt.h"
+#include "cpu.h"
+#include "utils.h"
+#include "rom_map.h"
+
+
+//*****************************************************************************
+// Macro definition
+//*****************************************************************************
+#define PRCM_SOFT_RESET 0x00000001
+#define PRCM_ENABLE_STATUS 0x00000002
+#define SYS_CLK 80000000
+#define XTAL_CLK 40000000
+
+
+//*****************************************************************************
+// CC3200 does not have a true RTC capability. However, API(s) in this file
+// provide an effective mechanism to support RTC feature in the device.
+//
+// The implementation to support RTC has been kept very simple. A set of
+// HIB Memory Registers in conjunction with Slow Clock Counter are used
+// to render RTC information to users. Core principle of design involves
+// two steps (a) establish an association between user provided wall-clock
+// and slow clock counter. (b) store reference value of this associattion
+// in HIB Registers. This reference value and SCC value are then combined
+// to create real-world calendar time.
+//
+// Across HIB cycles, value stored in HIB Registers is retained and slow
+// clock counter continues to tick, thereby, this arragement is relevant
+// and valid as long as device has a (tickle) battery power.
+//
+// Further, provision also has been made to set an alarm. When it RTC value
+// matches that of set for alarm, an interrupt is generated.
+//
+// HIB MEM REG0 and REG1 are reserved for TI.
+//
+// If RTC feature is not used, then HIB REG2 & REG3 are available to user.
+//
+// Lower half of REG0 is used for TI HW ECO.
+//*****************************************************************************
+#define RTC_U64MSEC_MK(u32Secs, u16Msec) (((unsigned long long)u32Secs << 10)|\
+ (u16Msec & 0x3FF))
+
+#define RTC_SECS_IN_U64MSEC(u64Msec) ((unsigned long)(u64Msec >> 10))
+#define RTC_MSEC_IN_U64MSEC(u64Msec) ((unsigned short)(u64Msec & 0x3FF))
+
+#define RTC_SECS_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG3)
+#define RTC_MSEC_U16_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2+2)
+
+#define RTC_U32SECS_REG (HWREG(RTC_SECS_U32_REG_ADDR))
+#define RTC_U16MSEC_REG (*(unsigned short*)RTC_MSEC_U16_REG_ADDR)
+
+//*****************************************************************************
+// Register Access and Updates
+//
+// Tick of SCC has a resolution of 32768Hz. Therefore, scaling SCC value by 32
+// yields ~1 msec resolution. All operations of SCC in RTC context use ms unit.
+//*****************************************************************************
+#define SCC_U64MSEC_GET() (PRCMSlowClkCtrGet() >> 5)
+#define SCC_U64MSEC_MATCH_SET(u64Msec) (PRCMSlowClkCtrMatchSet(u64Msec << 5))
+#define SCC_U64MSEC_MATCH_GET() (PRCMSlowClkCtrMatchGet() >> 5)
+
+//*****************************************************************************
+//
+// Bit: 31 is used to indicate use of RTC. If set as '1', RTC feature is used.
+// Bits: 30 to 26 are reserved, available to software for use
+// Bits: 25 to 16 are used to save millisecond part of RTC reference.
+// Bits: 15 to 0 are being used for HW Changes / ECO
+//
+//*****************************************************************************
+
+//*****************************************************************************
+// Set RTC USE Bit
+//*****************************************************************************
+static void RTCUseSet(void)
+{
+ unsigned short usRegValue;
+
+ usRegValue = RTC_U16MSEC_REG | (1 << 15);
+
+ UtilsDelay((80*200)/3);
+
+ RTC_U16MSEC_REG = usRegValue;
+}
+
+//*****************************************************************************
+// Checks if RTC-USE bit is set
+//*****************************************************************************
+static tBoolean IsRTCUsed(void)
+{
+ unsigned short usRegValue;
+
+ usRegValue = RTC_U16MSEC_REG;
+
+ UtilsDelay((80*200)/3);
+
+ return ((usRegValue & (1 << 15))? true : false);
+}
+
+//*****************************************************************************
+// Read 16-bit mSecs
+//*****************************************************************************
+static unsigned short RTCU16MSecRegRead(void)
+{
+ unsigned short usRegValue;
+
+ usRegValue = RTC_U16MSEC_REG;
+
+ UtilsDelay((80*200)/3);
+
+ return (usRegValue & 0x3FF);
+}
+
+//*****************************************************************************
+// Write 16-bit mSecs
+//*****************************************************************************
+static void RTCU16MSecRegWrite(unsigned short u16Msec)
+{
+ unsigned short usRegValue;
+
+ usRegValue = RTC_U16MSEC_REG;
+
+ UtilsDelay((80*200)/3);
+
+ RTC_U16MSEC_REG = ((usRegValue & ~0x3FF) |u16Msec);
+}
+
+//*****************************************************************************
+// Read 32-bit Secs
+//*****************************************************************************
+static unsigned long RTCU32SecRegRead(void)
+{
+ return (PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR));
+}
+
+//*****************************************************************************
+// Write 32-bit Secs
+//*****************************************************************************
+static void RTCU32SecRegWrite(unsigned long u32Msec)
+{
+ PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec);
+}
+
+//*****************************************************************************
+// Macros
+//*****************************************************************************
+#define IS_RTC_USED() IsRTCUsed()
+#define RTC_USE_SET() RTCUseSet()
+
+#define RTC_U16MSEC_REG_RD() RTCU16MSecRegRead()
+#define RTC_U16MSEC_REG_WR(u16Msec) RTCU16MSecRegWrite(u16Msec)
+
+#define RTC_U32SECS_REG_RD() RTCU32SecRegRead()
+#define RTC_U32SECS_REG_WR(u32Secs) RTCU32SecRegWrite(u32Secs)
+
+#define SELECT_SCC_U42BITS(u64Msec) (u64Msec & 0x3ffffffffff)
+
+//*****************************************************************************
+// Global Peripheral clock and rest Registers
+//*****************************************************************************
+static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] =
+{
+
+ {APPS_RCM_O_CAMERA_CLK_GATING, APPS_RCM_O_CAMERA_SOFT_RESET },
+ {APPS_RCM_O_MCASP_CLK_GATING, APPS_RCM_O_MCASP_SOFT_RESET },
+ {APPS_RCM_O_MMCHS_CLK_GATING, APPS_RCM_O_MMCHS_SOFT_RESET },
+ {APPS_RCM_O_MCSPI_A1_CLK_GATING, APPS_RCM_O_MCSPI_A1_SOFT_RESET },
+ {APPS_RCM_O_MCSPI_A2_CLK_GATING, APPS_RCM_O_MCSPI_A2_SOFT_RESET },
+ {APPS_RCM_O_UDMA_A_CLK_GATING, APPS_RCM_O_UDMA_A_SOFT_RESET },
+ {APPS_RCM_O_GPIO_A_CLK_GATING, APPS_RCM_O_GPIO_A_SOFT_RESET },
+ {APPS_RCM_O_GPIO_B_CLK_GATING, APPS_RCM_O_GPIO_B_SOFT_RESET },
+ {APPS_RCM_O_GPIO_C_CLK_GATING, APPS_RCM_O_GPIO_C_SOFT_RESET },
+ {APPS_RCM_O_GPIO_D_CLK_GATING, APPS_RCM_O_GPIO_D_SOFT_RESET },
+ {APPS_RCM_O_GPIO_E_CLK_GATING, APPS_RCM_O_GPIO_E_SOFT_RESET },
+ {APPS_RCM_O_WDOG_A_CLK_GATING, APPS_RCM_O_WDOG_A_SOFT_RESET },
+ {APPS_RCM_O_UART_A0_CLK_GATING, APPS_RCM_O_UART_A0_SOFT_RESET },
+ {APPS_RCM_O_UART_A1_CLK_GATING, APPS_RCM_O_UART_A1_SOFT_RESET },
+ {APPS_RCM_O_GPT_A0_CLK_GATING , APPS_RCM_O_GPT_A0_SOFT_RESET },
+ {APPS_RCM_O_GPT_A1_CLK_GATING, APPS_RCM_O_GPT_A1_SOFT_RESET },
+ {APPS_RCM_O_GPT_A2_CLK_GATING, APPS_RCM_O_GPT_A2_SOFT_RESET },
+ {APPS_RCM_O_GPT_A3_CLK_GATING, APPS_RCM_O_GPT_A3_SOFT_RESET },
+ {APPS_RCM_O_CRYPTO_CLK_GATING, APPS_RCM_O_CRYPTO_SOFT_RESET },
+ {APPS_RCM_O_MCSPI_S0_CLK_GATING, APPS_RCM_O_MCSPI_S0_SOFT_RESET },
+ {APPS_RCM_O_I2C_CLK_GATING, APPS_RCM_O_I2C_SOFT_RESET }
+
+};
+
+//*****************************************************************************
+//
+//! Performs a software reset of a SOC
+//!
+//! This function performs a software reset of a SOC
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMSOCReset(void)
+{
+ //
+ // Reset MCU
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_MCU_GLOBAL_SOFT_RESET) |= 0x1;
+
+}
+
+//*****************************************************************************
+//
+//! Performs a software reset of a MCU and associated peripherals
+//!
+//! \param bIncludeSubsystem is \b true to reset associated peripherals.
+//!
+//! This function performs a software reset of a MCU and associated peripherals.
+//! To reset the associated peripheral, the parameter \e bIncludeSubsystem
+//! should be set to \b true.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMMCUReset(tBoolean bIncludeSubsystem)
+{
+ if(bIncludeSubsystem)
+ {
+ //
+ // Reset Apps processor and associated peripheral
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x2;
+ }
+ else
+ {
+ //
+ // Reset Apps processor only
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_SOFT_RESET) = 0x1;
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the reason for a reset.
+//!
+//! This function returns the reason(s) for a reset. The reset reason are:-
+//! -\b PRCM_POWER_ON - Device is powering up.
+//! -\b PRCM_LPDS_EXIT - Device is exiting from LPDS.
+//! -\b PRCM_CORE_RESET - Device is exiting soft core only reset
+//! -\b PRCM_MCU_RESET - Device is exiting soft subsystem reset.
+//! -\b PRCM_WDT_RESET - Device was reset by watchdog.
+//! -\b PRCM_SOC_RESET - Device is exting SOC reset.
+//! -\b PRCM_HIB_EXIT - Device is exiting hibernate.
+//!
+//! \return Returns one of the cause defined above.
+//
+//*****************************************************************************
+unsigned long PRCMSysResetCauseGet()
+{
+ unsigned long ulWakeupStatus;
+
+ //
+ // Read the Reset status
+ //
+ ulWakeupStatus = (HWREG(GPRCM_BASE+ GPRCM_O_APPS_RESET_CAUSE) & 0xFF);
+
+ //
+ // For hibernate do additional chaeck.
+ //
+ if(ulWakeupStatus == PRCM_POWER_ON)
+ {
+ if(PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1)
+ {
+ ulWakeupStatus = PRCM_HIB_EXIT;
+ }
+ }
+
+ //
+ // Return status.
+ //
+ return ulWakeupStatus;
+}
+
+//*****************************************************************************
+//
+//! Enable clock(s) to peripheral.
+//!
+//! \param ulPeripheral is one of the valid peripherals
+//! \param ulClkFlags are bitmask of clock(s) to be enabled.
+//!
+//! This function enables the clock for the specified peripheral. Peripherals
+//! are by default clock gated (disabled) and generates a bus fault if
+//! accessed.
+//!
+//! The parameter \e ulClkFlags can be logical OR of the following:
+//! -\b PRCM_RUN_MODE_CLK - Ungates clock to the peripheral
+//! -\b PRCM_SLP_MODE_CLK - Keeps the clocks ungated in sleep.
+//! -\b PRCM_DSLP_MODE_CLK - Keeps the clock ungated in deepsleep.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags)
+{
+ //
+ // Enable the specified peripheral clocks, Nothing to be done for PRCM_ADC
+ // as it is a dummy define for pinmux utility code generation
+ //
+ if(ulPeripheral != PRCM_ADC)
+ {
+ HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) |= ulClkFlags;
+ }
+ //
+ // Set the default clock for camera
+ //
+ if(ulPeripheral == PRCM_CAMERA)
+ {
+ HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) = 0x0404;
+ }
+}
+
+//*****************************************************************************
+//
+//! Disables clock(s) to peripheral.
+//!
+//! \param ulPeripheral is one of the valid peripherals
+//! \param ulClkFlags are bitmask of clock(s) to be enabled.
+//!
+//! This function disable the clock for the specified peripheral. Peripherals
+//! are by default clock gated (disabled) and generated a bus fault if
+//! accessed.
+//!
+//! The parameter \e ulClkFlags can be logical OR bit fields as defined in
+//! PRCMEnablePeripheral().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags)
+{
+ //
+ // Disable the specified peripheral clocks
+ //
+ HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulClkReg) &= ~ulClkFlags;
+}
+
+//*****************************************************************************
+//
+//! Gets the input clock for the specified peripheral.
+//!
+//! \param ulPeripheral is one of the valid peripherals.
+//!
+//! This function gets the input clock for the specified peripheral.
+//!
+//! The parameter \e ulPeripheral has the same definition as that in
+//! PRCMPeripheralClkEnable();
+//!
+//! \return Returns input clock frequency for specified peripheral.
+//
+//*****************************************************************************
+unsigned long
+PRCMPeripheralClockGet(unsigned long ulPeripheral)
+{
+ unsigned long ulClockFreq;
+ unsigned long ulHiPulseDiv;
+ unsigned long ulLoPulseDiv;
+
+ //
+ // Get the clock based on specified peripheral.
+ //
+ if(((ulPeripheral == PRCM_SSPI) | (ulPeripheral == PRCM_LSPI)
+ | (ulPeripheral == PRCM_GSPI)))
+ {
+ return XTAL_CLK;
+ }
+ else if(ulPeripheral == PRCM_CAMERA)
+ {
+ ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN) >> 8) & 0x07);
+ ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_CAMERA_CLK_GEN)& 0xFF);
+ }
+ else if(ulPeripheral == PRCM_SDHOST)
+ {
+ ulHiPulseDiv = ((HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN) >> 8) & 0x07);
+ ulLoPulseDiv = (HWREG(ARCM_BASE + APPS_RCM_O_MMCHS_CLK_GEN)& 0xFF);
+ }
+ else
+ {
+ return SYS_CLK;
+ }
+
+ //
+ // Compute the clock freq. from the divider value
+ //
+ ulClockFreq = (240000000/((ulHiPulseDiv + 1) + (ulLoPulseDiv + 1)));
+
+ //
+ // Return the clock rate.
+ //
+ return ulClockFreq;
+}
+
+//*****************************************************************************
+//
+//! Performs a software reset of a peripheral.
+//!
+//! \param ulPeripheral is one of the valid peripheral.
+//!
+//! This assert or deassert reset to the specified peripheral based of the
+//! \e bAssert parameter.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMPeripheralReset(unsigned long ulPeripheral)
+{
+ volatile unsigned long ulDelay;
+
+ if( ulPeripheral != PRCM_DTHE)
+ {
+ //
+ // Assert the reset
+ //
+ HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg)
+ |= PRCM_SOFT_RESET;
+ //
+ // Delay for a little bit.
+ //
+ for(ulDelay = 0; ulDelay < 16; ulDelay++)
+ {
+ }
+
+ //
+ // Deassert the reset
+ //
+ HWREG(ARCM_BASE+PRCM_PeriphRegsList[ulPeripheral].ulRstReg)
+ &= ~PRCM_SOFT_RESET;
+ }
+}
+
+//*****************************************************************************
+//
+//! Determines if a peripheral is ready.
+//!
+//! \param ulPeripheral is one of the valid modules
+//!
+//! This function determines if a particular peripheral is ready to be
+//! accessed. The peripheral may be in a non-ready state if it is not enabled,
+//! is being held in reset, or is in the process of becoming ready after being
+//! enabled or taken out of reset.
+//!
+//! \return Returns \b true if the peripheral is ready, \b false otherwise.
+//
+//*****************************************************************************
+tBoolean
+PRCMPeripheralStatusGet(unsigned long ulPeripheral)
+{
+ unsigned long ReadyBit;
+
+ //
+ // Read the ready bit status
+ //
+ ReadyBit = HWREG(ARCM_BASE + PRCM_PeriphRegsList[ulPeripheral].ulRstReg);
+ ReadyBit = ReadyBit & PRCM_ENABLE_STATUS;
+
+ if (ReadyBit)
+ {
+ //
+ // Module is ready
+ //
+ return(true);
+ }
+ else
+ {
+ //
+ // Module is not ready
+ //
+ return(false);
+ }
+}
+
+//*****************************************************************************
+//
+//! Configure I2S fracactional divider
+//!
+//! \param ulI2CClkFreq is the required input clock for McAPS module
+//!
+//! This function configures I2S fractional divider. By default this
+//! divider is set to output 24 Mhz clock to I2S module.
+//!
+//! The minimum frequency that can be obtained by configuring this divider is
+//!
+//! (240000KHz/1023.99) = 234.377 KHz
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)
+{
+ unsigned long long ullDiv;
+ unsigned short usInteger;
+ unsigned short usFrac;
+
+ ullDiv = (((unsigned long long)240000000 * 65536)/ulI2CClkFreq);
+
+ usInteger = (ullDiv/65536);
+ usFrac = (ullDiv%65536);
+
+ HWREG(ARCM_BASE + APPS_RCM_O_MCASP_FRAC_CLK_CONFIG0) =
+ ((usInteger & 0x3FF) << 16 | usFrac);
+}
+
+//*****************************************************************************
+//
+//! Sets the LPDS exit PC and SP restore vlaues.
+//!
+//! \param ulStackPtr is the SP restore value.
+//! \param ulProgCntr is the PC restore value
+//!
+//! This function sets the LPDS exit PC and SP restore vlaues. Setting
+//! \e ulProgCntr to a non-zero value, forces bootloader to jump to that
+//! address with Stack Pointer initialized to \e ulStackPtr on LPDS exit,
+//! otherwise the application's vector table entries are used.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr)
+{
+ //
+ // Set The SP Value
+ //
+ HWREG(0x4402E18C) = ulStackPtr;
+
+ //
+ // Set The PC Value
+ //
+ HWREG(0x4402E190) = ulProgCntr;
+}
+
+//*****************************************************************************
+//
+//! Puts the system into Low Power Deel Sleep (LPDS) power mode.
+//!
+//! This function puts the system into Low Power Deel Sleep (LPDS) power mode.
+//! A call to this function never returns and the execution starts from Reset.
+//! \sa PRCMLPDSRestoreInfoSet().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMLPDSEnter()
+{
+ //
+ // Disable TestPD
+ //
+ HWREG(0x4402E168) |= (1<<9);
+
+ //
+ // Set bandgap duty cycle to 1
+ //
+ HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
+
+ //
+ // Request LPDS
+ //
+ HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ)
+ = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ;
+
+ __asm(" nop\n"
+ " nop\n"
+ " nop\n"
+ " nop\n");
+}
+
+//*****************************************************************************
+//
+//! Enable the individual LPDS wakeup source(s).
+//!
+//! \param ulLpdsWakeupSrc is logical OR of wakeup sources.
+//!
+//! This function enable the individual LPDS wakeup source(s) and following
+//! three wakeup sources (\e ulLpdsWakeupSrc ) are supported by the device.
+//! -\b PRCM_LPDS_HOST_IRQ
+//! -\b PRCM_LPDS_GPIO
+//! -\b PRCM_LPDS_TIMER
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
+{
+ unsigned long ulRegVal;
+
+ //
+ // Read the current wakup sources
+ //
+ ulRegVal = HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG);
+
+ //
+ // Enable individual wakeup source
+ //
+ ulRegVal = ((ulRegVal | ulLpdsWakeupSrc) & 0x91);
+
+ //
+ // Set the configuration in the register
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) = ulRegVal;
+}
+
+//*****************************************************************************
+//
+//! Disable the individual LPDS wakeup source(s).
+//!
+//! \param ulLpdsWakeupSrc is logical OR of wakeup sources.
+//!
+//! This function enable the individual LPDS wakeup source(s) and following
+//! three wake up sources (\e ulLpdsWakeupSrc ) are supported by the device.
+//! -\b PRCM_LPDS_HOST_IRQ
+//! -\b PRCM_LPDS_GPIO
+//! -\b PRCM_LPDS_TIMER
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)
+{
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) &= ~ulLpdsWakeupSrc;
+}
+
+
+//*****************************************************************************
+//
+//! Get LPDS wakeup cause
+//!
+//! This function gets LPDS wakeup caouse
+//!
+//! \return Returns values enumerated as described in
+//! PRCMLPDSWakeupSourceEnable().
+//
+//*****************************************************************************
+unsigned long
+PRCMLPDSWakeupCauseGet()
+{
+ return (HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_SRC));
+}
+
+//*****************************************************************************
+//
+//! Sets LPDS wakeup Timer
+//!
+//! \param ulTicks is number of 32.768 KHz clocks
+//!
+//! This function sets internal LPDS wakeup timer running at 32.768 KHz. The
+//! timer is only configured if the parameter \e ulTicks is in valid range i.e.
+//! from 21 to 2^32.
+//!
+//! \return Returns \b true on success, \b false otherwise.
+//
+//*****************************************************************************
+void
+PRCMLPDSIntervalSet(unsigned long ulTicks)
+{
+ //
+ // Check sleep is atleast for 21 cycles
+ // If not set the sleep time to 21 cycles
+ //
+ if( ulTicks < 21)
+ {
+ ulTicks = 21;
+ }
+
+ HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_WAKE_CFG) = ulTicks;
+ HWREG(GPRCM_BASE + GPRCM_O_APPS_LPDS_WAKETIME_OPP_CFG) = ulTicks-20;
+}
+
+//*****************************************************************************
+//
+//! Selects the GPIO for LPDS wakeup
+//!
+//! \param ulGPIOPin is one of the valid GPIO fro LPDS wakeup.
+//! \param ulType is the wakeup trigger type.
+//!
+//! This function setects the wakeup GPIO for LPDS wakeup and can be
+//! used to select one out of 7 pre-defined GPIO(s).
+//!
+//! The parameter \e ulLpdsGPIOSel should be one of the following:-
+//! -\b PRCM_LPDS_GPIO2
+//! -\b PRCM_LPDS_GPIO4
+//! -\b PRCM_LPDS_GPIO13
+//! -\b PRCM_LPDS_GPIO17
+//! -\b PRCM_LPDS_GPIO11
+//! -\b PRCM_LPDS_GPIO24
+//! -\b PRCM_LPDS_GPIO26
+//!
+//! The parameter \e ulType sets the trigger type and can be one of the
+//! following:
+//! - \b PRCM_LPDS_LOW_LEVEL
+//! - \b PRCM_LPDS_HIGH_LEVEL
+//! - \b PRCM_LPDS_FALL_EDGE
+//! - \b PRCM_LPDS_RISE_EDGE
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)
+{
+ //
+ // Set the wakeup GPIO
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin);
+
+ //
+ // Set the trigger type.
+ //
+ HWREG(GPRCM_BASE + GPRCM_O_APPS_GPIO_WAKE_CONF) = (ulType & 0x3);
+}
+
+//*****************************************************************************
+//
+//! Puts the system into Sleep.
+//!
+//! This function puts the system into sleep power mode. System exits the power
+//! state on any one of the available interrupt. On exit from sleep mode the
+//! function returns to the calling function with all the processor core
+//! registers retained.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMSleepEnter()
+{
+ //
+ // Request Sleep
+ //
+ CPUwfi();
+}
+
+//*****************************************************************************
+//
+//! Puts the system into Deep Sleep power mode.
+//!
+//! This function puts the system into Deep Sleep power mode. System exits the
+//! power state on any one of the available interrupt. On exit from deep
+//! sleep the function returns to the calling function with all the processor
+//! core registers retained.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMDeepSleepEnter()
+{
+ //
+ // Set bandgap duty cycle to 1
+ //
+ HWREG(HIB1P2_BASE + HIB1P2_O_BGAP_DUTY_CYCLING_EXIT_CFG) = 0x1;
+
+ //
+ // Enable DSLP in cortex
+ //
+ HWREG(0xE000ED10)|=1<<2;
+
+ //
+ // Request Deep Sleep
+ //
+ CPUwfi();
+
+ //
+ // Disable DSLP in cortex before
+ // returning to the caller
+ //
+ HWREG(0xE000ED10) &= ~(1<<2);
+
+}
+
+//*****************************************************************************
+//
+//! Enable SRAM column retention during Deep Sleep and/or LPDS Power mode(s)
+//!
+//! \param ulSramColSel is bit mask of valid SRAM columns.
+//! \param ulModeFlags is the bit mask of power modes.
+//!
+//! This functions enables the SRAM retention. The device supports configurable
+//! SRAM column retention in Low Power Deep Sleep (LPDS) and Deep Sleep power
+//! modes. Each column is of 64 KB size.
+//!
+//! The parameter \e ulSramColSel should be logical OR of the following:-
+//! -\b PRCM_SRAM_COL_1
+//! -\b PRCM_SRAM_COL_2
+//! -\b PRCM_SRAM_COL_3
+//! -\b PRCM_SRAM_COL_4
+//!
+//! The parameter \e ulModeFlags selects the power modes and sholud be logical
+//! OR of one or more of the following
+//! -\b PRCM_SRAM_DSLP_RET
+//! -\b PRCM_SRAM_LPDS_RET
+//!
+//! \return None.
+//
+//****************************************************************************
+void
+PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags)
+{
+ if(ulModeFlags & PRCM_SRAM_DSLP_RET)
+ {
+ //
+ // Configure deep sleep SRAM retention register
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_DSLP_CFG) = (ulSramColSel & 0xF);
+ }
+
+ if(ulModeFlags & PRCM_SRAM_LPDS_RET)
+ {
+ //
+ // Configure LPDS SRAM retention register
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) = (ulSramColSel & 0xF);
+ }
+}
+
+//*****************************************************************************
+//
+//! Disable SRAM column retention during Deep Sleep and/or LPDS Power mode(s).
+//!
+//! \param ulSramColSel is bit mask of valid SRAM columns.
+//! \param ulFlags is the bit mask of power modes.
+//!
+//! This functions disable the SRAM retention. The device supports configurable
+//! SRAM column retention in Low Power Deep Sleep (LPDS) and Deep Sleep power
+//! modes. Each column is of 64 KB size.
+//!
+//! The parameter \e ulSramColSel should be logical OR of the following:-
+//! -\b PRCM_SRAM_COL_1
+//! -\b PRCM_SRAM_COL_2
+//! -\b PRCM_SRAM_COL_3
+//! -\b PRCM_SRAM_COL_4
+//!
+//! The parameter \e ulFlags selects the power modes and sholud be logical OR
+//! of one or more of the following
+//! -\b PRCM_SRAM_DSLP_RET
+//! -\b PRCM_SRAM_LPDS_RET
+//!
+//! \return None.
+//
+//****************************************************************************
+void
+PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags)
+{
+ if(ulFlags & PRCM_SRAM_DSLP_RET)
+ {
+ //
+ // Configure deep sleep SRAM retention register
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_DSLP_CFG) &= ~(ulSramColSel & 0xF);
+ }
+
+ if(ulFlags & PRCM_SRAM_LPDS_RET)
+ {
+ //
+ // Configure LPDS SRAM retention register
+ //
+ HWREG(GPRCM_BASE+ GPRCM_O_APPS_SRAM_LPDS_CFG) &= ~(ulSramColSel & 0xF);
+ }
+}
+
+
+//*****************************************************************************
+//
+//! Enables individual HIB wakeup source(s).
+//!
+//! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.
+//!
+//! This function enables individual HIB wakeup source(s). The paramter
+//! \e ulHIBWakupSrc is the bit mask of HIB wakeup sources and should be
+//! logical OR of one or more of the follwoing :-
+//! -\b PRCM_HIB_SLOW_CLK_CTR
+//! -\b PRCM_HIB_GPIO2
+//! -\b PRCM_HIB_GPIO4
+//! -\b PRCM_HIB_GPIO13
+//! -\b PRCM_HIB_GPIO17
+//! -\b PRCM_HIB_GPIO11
+//! -\b PRCM_HIB_GPIO24
+//! -\b PRCM_HIB_GPIO26
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
+{
+ unsigned long ulRegValue;
+
+ //
+ // Read the RTC register
+ //
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
+
+ //
+ // Enable the RTC as wakeup source if specified
+ //
+ ulRegValue |= (ulHIBWakupSrc & 0x1);
+
+ //
+ // Enable HIB wakeup sources
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
+
+ //
+ // REad the GPIO wakeup configuration register
+ //
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
+
+ //
+ // Enable the specified GPIOs a wakeup sources
+ //
+ ulRegValue |= ((ulHIBWakupSrc>>16)&0xFF);
+
+ //
+ // Write the new register configuration
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
+}
+
+//*****************************************************************************
+//
+//! Disable individual HIB wakeup source(s).
+//!
+//! \param ulHIBWakupSrc is logical OR of valid HIB wakeup sources.
+//!
+//! This function disable individual HIB wakeup source(s). The paramter
+//! \e ulHIBWakupSrc is same as bit fileds defined in
+//! PRCMEnableHibernateWakeupSource()
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
+{
+ unsigned long ulRegValue;
+
+ //
+ // Read the RTC register
+ //
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
+
+ //
+ // Disable the RTC as wakeup source if specified
+ //
+ ulRegValue &= ~(ulHIBWakupSrc & 0x1);
+
+ //
+ // Disable HIB wakeup sources
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
+
+ //
+ // Read the GPIO wakeup configuration register
+ //
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
+
+ //
+ // Enable the specified GPIOs a wakeup sources
+ //
+ ulRegValue &= ~((ulHIBWakupSrc>>16)&0xFF);
+
+ //
+ // Write the new register configuration
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
+}
+
+
+//*****************************************************************************
+//
+//! Get hibernate wakeup cause
+//!
+//! This function gets the hibernate wakeup cause.
+//!
+//! \return Returns \b PRCM_HIB_WAKEUP_CAUSE_SLOW_CLOCK or
+//! \b PRCM_HIB_WAKEUP_CAUSE_GPIO
+//
+//*****************************************************************************
+unsigned long
+PRCMHibernateWakeupCauseGet()
+{
+ return ((PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS)>>1)&0xF);
+}
+
+//*****************************************************************************
+//
+//! Sets Hibernate wakeup Timer
+//!
+//! \param ullTicks is number of 32.768 KHz clocks
+//!
+//! This function sets internal hibernate wakeup timer running at 32.768 KHz.
+//!
+//! \return Returns \b true on success, \b false otherwise.
+//
+//*****************************************************************************
+void
+PRCMHibernateIntervalSet(unsigned long long ullTicks)
+{
+ unsigned long long ullRTCVal;
+
+ //
+ // Latch the RTC vlaue
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1);
+
+ //
+ // Read latched values as 2 32-bit vlaues
+ //
+ ullRTCVal = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
+ ullRTCVal = ullRTCVal << 32;
+ ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
+
+ //
+ // Add the interval
+ //
+ ullRTCVal = ullRTCVal + ullTicks;
+
+ //
+ // Set RTC match value
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF,
+ (unsigned long)(ullRTCVal));
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF,
+ (unsigned long)(ullRTCVal>>32));
+}
+
+
+//*****************************************************************************
+//
+//! Selects the GPIO(s) for hibernate wakeup
+//!
+//! \param ulGPIOBitMap is the bit-map of valid hibernate wakeup GPIO.
+//! \param ulType is the wakeup trigger type.
+//!
+//! This function setects the wakeup GPIO for hibernate and can be
+//! used to select any combination of 7 pre-defined GPIO(s).
+//!
+//! This function enables individual HIB wakeup source(s). The paramter
+//! \e ulGPIOBitMap should be one of the follwoing :-
+//! -\b PRCM_HIB_GPIO2
+//! -\b PRCM_HIB_GPIO4
+//! -\b PRCM_HIB_GPIO13
+//! -\b PRCM_HIB_GPIO17
+//! -\b PRCM_HIB_GPIO11
+//! -\b PRCM_HIB_GPIO24
+//! -\b PRCM_HIB_GPIO26
+//!
+//! The parameter \e ulType sets the trigger type and can be one of the
+//! following:
+//! - \b PRCM_HIB_LOW_LEVEL
+//! - \b PRCM_HIB_HIGH_LEVEL
+//! - \b PRCM_HIB_FALL_EDGE
+//! - \b PRCM_HIB_RISE_EDGE
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)
+{
+ unsigned char ucLoop;
+ unsigned long ulRegValue;
+
+ //
+ // Shift the bits to extract the GPIO selection
+ //
+ ulGPIOBitMap >>= 16;
+
+ //
+ // Set the configuration for each GPIO
+ //
+ for(ucLoop=0; ucLoop < 7; ucLoop++)
+ {
+ if(ulGPIOBitMap & (1<<ucLoop))
+ {
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF);
+ ulRegValue |= (ulType << (ucLoop*2));
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF, ulRegValue);
+ }
+ }
+}
+
+//*****************************************************************************
+//
+//! Puts the system into Hibernate
+//!
+//! This function puts the system into Hibernate. The device enters HIB
+//! immediately and on exit from HIB device core starts its execution from
+//! reset thus the function never returns.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+PRCMHibernateEnter()
+{
+
+ //
+ // Request hibernate.
+ //
+ PRCMHIBRegWrite((HIB3P3_BASE+HIB3P3_O_MEM_HIB_REQ),0x1);
+
+ __asm(" nop\n"
+ " nop\n"
+ " nop\n"
+ " nop\n");
+}
+
+//*****************************************************************************
+//
+//! Gets the current value of the internal slow clock counter
+//!
+//! This function latches and reads the internal RTC running at 32.768 Khz
+//!
+//! \return 64-bit current counter vlaue.
+//
+//*****************************************************************************
+unsigned long long
+PRCMSlowClkCtrGet()
+{
+ unsigned long long ullRTCVal;
+
+ //
+ // Latch the RTC vlaue
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ, 0x1);
+
+ //
+ // Read latched values as 2 32-bit vlaues
+ //
+ ullRTCVal = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
+ ullRTCVal = ullRTCVal << 32;
+ ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
+
+ return ullRTCVal;
+}
+
+
+//*****************************************************************************
+//
+//! Sets slow clock counter match value to interrupt the processor.
+//!
+//! \param ullValue is the match value.
+//!
+//! This function sets the match value for slow clock counter. This is use
+//! to interrupt the processor when RTC counts to the specified value.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMSlowClkCtrMatchSet(unsigned long long ullValue)
+{
+ //
+ // Set RTC match value
+ //
+ PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF,
+ (unsigned long)(ullValue));
+ PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF,
+ (unsigned long)(ullValue>>32));
+}
+
+//*****************************************************************************
+//
+//! Gets slow clock counter match value.
+//!
+//! This function gets the match value for slow clock counter. This is use
+//! to interrupt the processor when RTC counts to the specified value.
+//!
+//! \return None.
+//
+//*****************************************************************************
+unsigned long long PRCMSlowClkCtrMatchGet()
+{
+ unsigned long long ullValue;
+
+ //
+ // Get RTC match value
+ //
+ ullValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF);
+ ullValue = ullValue<<32;
+ ullValue |= PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF);
+
+ //
+ // Return the value
+ //
+ return ullValue;
+}
+
+
+//*****************************************************************************
+//
+//! Write to On-Chip Retention (OCR) register.
+//!
+//! This function writes to On-Chip retention register. The device supports two
+//! 4-byte OCR register which are retained across all power mode.
+//!
+//! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMOCRRegisterWrite(unsigned char ucIndex, unsigned long ulRegValue)
+{
+ PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2+(ucIndex << 2),ulRegValue);
+}
+
+//*****************************************************************************
+//
+//! Read from On-Chip Retention (OCR) register.
+//!
+//! This function reads from On-Chip retention register. The device supports two
+//! 4-byte OCR register which are retained across all power mode.
+//!
+//! The parameter \e ucIndex is an index of the OCR and can be \b 0 or \b 1.
+//!
+//! \return None.
+//
+//*****************************************************************************
+unsigned long PRCMOCRRegisterRead(unsigned char ucIndex)
+{
+ //
+ // Return the read value.
+ //
+ return PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2));
+}
+
+//*****************************************************************************
+//
+//! Registers an interrupt handler for the PRCM.
+//!
+//! \param pfnHandler is a pointer to the function to be called when the
+//! interrupt is activated.
+//!
+//! This function does the actual registering of the interrupt handler. This
+//! function enables the global interrupt in the interrupt controller;
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMIntRegister(void (*pfnHandler)(void))
+{
+ //
+ // Register the interrupt handler.
+ //
+ IntRegister(INT_PRCM, pfnHandler);
+
+ //
+ // Enable the PRCM interrupt.
+ //
+ IntEnable(INT_PRCM);
+}
+
+//*****************************************************************************
+//
+//! Unregisters an interrupt handler for the PRCM.
+//!
+//! This function does the actual unregistering of the interrupt handler. It
+//! clears the handler to be called when a PRCM interrupt occurs. This
+//! function also masks off the interrupt in the interrupt controller so that
+//! the interrupt handler no longer is called.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMIntUnregister()
+{
+ //
+ // Enable the UART interrupt.
+ //
+ IntDisable(INT_PRCM);
+
+ //
+ // Register the interrupt handler.
+ //
+ IntUnregister(INT_PRCM);
+}
+
+//*****************************************************************************
+//
+//! Enables individual PRCM interrupt sources.
+//!
+//! \param ulIntFlags is the bit mask of the interrupt sources to be enabled.
+//!
+//! This function enables the indicated ARCM interrupt sources. Only the
+//! sources that are enabled can be reflected to the processor interrupt;
+//! disabled sources have no effect on the processor.
+//!
+//! The \e ulIntFlags parameter is the logical OR of any of the following:
+//! -\b PRCM_INT_SLOW_CLK_CTR
+//!
+//
+//*****************************************************************************
+void PRCMIntEnable(unsigned long ulIntFlags)
+{
+ unsigned long ulRegValue;
+
+ if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )
+ {
+ //
+ // Enable PRCM interrupt
+ //
+ HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) |= 0x4;
+
+ //
+ // Enable RTC interrupt
+ //
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
+ ulRegValue |= 0x1;
+ PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
+ }
+}
+
+//*****************************************************************************
+//
+//! Disables individual PRCM interrupt sources.
+//!
+//! \param ulIntFlags is the bit mask of the interrupt sources to be disabled.
+//!
+//! This function disables the indicated ARCM interrupt sources. Only the
+//! sources that are enabled can be reflected to the processor interrupt;
+//! disabled sources have no effect on the processor.
+//!
+//! The \e ulIntFlags parameter has the same definition as the \e ulIntFlags
+//! parameter to PRCMEnableInterrupt().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMIntDisable(unsigned long ulIntFlags)
+{
+ unsigned long ulRegValue;
+
+ if(ulIntFlags & PRCM_INT_SLOW_CLK_CTR )
+ {
+ //
+ // Disable PRCM interrupt
+ //
+ HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_ENABLE) &= ~0x4;
+
+ //
+ // Disable RTC interrupt
+ //
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
+ ulRegValue &= ~0x1;
+ PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
+ }
+}
+
+//*****************************************************************************
+//
+//! Gets the current interrupt status.
+//!
+//! This function returns the PRCM interrupt status of interrupts that are
+//! allowed to reflect to the processor. The interrupts are cleared on read.
+//!
+//! \return Returns the current interrupt status.
+//
+//*****************************************************************************
+unsigned long PRCMIntStatus()
+{
+ return HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_STATUS);
+}
+
+//*****************************************************************************
+//
+//! Mark the function of RTC as being used
+//!
+//! This function marks in HW that feature to maintain calendar time in device
+//! is being used.
+//!
+//! Specifically, this feature reserves user's HIB Register-1 accessed through
+//! PRCMOCRRegisterWrite(1) for internal work / purpose, therefore, the stated
+//! register is not available to user. Also, users must not excercise the Slow
+//! Clock Counter API(s), if RTC has been set for use.
+//!
+//! The RTC feature, if set or marked, can be only reset either through reboot
+//! or power cycle.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMRTCInUseSet()
+{
+ RTC_USE_SET();
+ return;
+}
+
+//*****************************************************************************
+//
+//! Ascertain whether function of RTC is being used
+//!
+//! This function indicates whether function of RTC is being used on the device
+//! or not.
+//!
+//! This routine should be utilized by the application software, when returning
+//! from low-power, to confirm that RTC has been put to use and may not need to
+//! set the value of the RTC.
+//!
+//! The RTC feature, if set or marked, can be only reset either through reboot
+//! or power cycle.
+//!
+//! \return None.
+//
+//*****************************************************************************
+tBoolean PRCMRTCInUseGet()
+{
+ return IS_RTC_USED()? true : false;
+}
+
+//*****************************************************************************
+//
+//! Set the calendar time in the device.
+//!
+//! \param ulSecs refers to the seconds part of the calendar time
+//! \param usMsec refers to the fractional (ms) part of the second
+//!
+//! This function sets the specified calendar time in the device. The calendar
+//! time is outlined in terms of seconds and milliseconds. However, the device
+//! makes no assumption about the origin or reference of the calendar time.
+//!
+//! The device uses the indicated calendar value to update and maintain the
+//! wall-clock time across active and low power states.
+//!
+//! The function PRCMRTCInUseSet() must be invoked prior to use of this feature.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMRTCSet(unsigned long ulSecs, unsigned short usMsec)
+{
+ unsigned long long ullMsec = 0;
+
+ if(IS_RTC_USED()) {
+ ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec) - SCC_U64MSEC_GET();
+
+ RTC_U32SECS_REG_WR(RTC_SECS_IN_U64MSEC(ullMsec));
+ RTC_U16MSEC_REG_WR(RTC_MSEC_IN_U64MSEC(ullMsec));
+ }
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! Get the instantaneous calendar time from the device.
+//!
+//! \param ulSecs refers to the seconds part of the calendar time
+//! \param usMsec refers to the fractional (ms) part of the second
+//!
+//! This function fetches the instantaneous value of the ticking calendar time
+//! from the device. The calendar time is outlined in terms of seconds and
+//! milliseconds.
+//!
+//! The device provides the calendar value that has been maintained across
+//! active and low power states.
+//!
+//! The function PRCMRTCSet() must have been invoked once to set a reference.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMRTCGet(unsigned long *ulSecs, unsigned short *usMsec)
+{
+ unsigned long long ullMsec = 0;
+
+ if(IS_RTC_USED()) {
+ ullMsec = RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
+ RTC_U16MSEC_REG_RD());
+ ullMsec += SCC_U64MSEC_GET();
+ }
+
+ *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);
+ *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! Set a calendar time alarm.
+//!
+//! \param ulSecs refers to the seconds part of the calendar time
+//! \param usMsec refers to the fractional (ms) part of the second
+//!
+//! This function sets an wall-clock alarm in the device to be reported for a
+//! futuristic calendar time. The calendar time is outlined in terms of seconds
+//! and milliseconds.
+//!
+//! The device provides uses the calendar value that has been maintained across
+//! active and low power states to report attainment of alarm time.
+//!
+//! The function PRCMRTCSet() must have been invoked once to set a reference.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMRTCMatchSet(unsigned long ulSecs, unsigned short usMsec)
+{
+ unsigned long long ullMsec = 0;
+
+ if(IS_RTC_USED()) {
+ ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec);
+ ullMsec -= RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
+ RTC_U16MSEC_REG_RD());
+ SCC_U64MSEC_MATCH_SET(SELECT_SCC_U42BITS(ullMsec));
+ }
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! Get a previously set calendar time alarm.
+//!
+//! \param ulSecs refers to the seconds part of the calendar time
+//! \param usMsec refers to the fractional (ms) part of the second
+//!
+//! This function fetches from the device a wall-clock alarm that would have
+//! been previously set in the device. The calendar time is outlined in terms
+//! of seconds and milliseconds.
+//!
+//! If no alarm was set in the past, then this function would fetch a random
+//! information.
+//!
+//! The function PRCMRTCMatchSet() must have been invoked once to set an alarm.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec)
+{
+ unsigned long long ullMsec = 0;
+
+ if(IS_RTC_USED()) {
+ ullMsec = SCC_U64MSEC_MATCH_GET();
+ ullMsec += RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
+ RTC_U16MSEC_REG_RD());
+ }
+
+ *ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);
+ *usMsec = RTC_MSEC_IN_U64MSEC(ullMsec);
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! MCU Initialization Routine
+//!
+//! This function sets mandatory configurations for the MCU
+//!
+//! \return None
+//
+//*****************************************************************************
+void PRCMCC3200MCUInit()
+{
+ unsigned long ulRegValue;
+
+ //
+ // DIG DCDC LPDS ECO Enable
+ //
+ HWREG(0x4402F064) |= 0x800000;
+
+ //
+ // Enable hibernate ECO for PG 1.32 devices only. With this ECO enabled,
+ // any hibernate wakeup source will be kept maked until the device enters
+ // hibernate completely (analog + digital)
+ //
+ ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0);
+ PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4));
+
+ //
+ // Handling the clock switching (for 1.32 only)
+ //
+ HWREG(0x4402E16C) |= 0x3C;
+
+ //
+ // Enable uDMA
+ //
+ MAP_PRCMPeripheralClkEnable(PRCM_UDMA,PRCM_RUN_MODE_CLK);
+
+ //
+ // Reset uDMA
+ //
+ MAP_PRCMPeripheralReset(PRCM_UDMA);
+
+ //
+ // Disable uDMA
+ //
+ MAP_PRCMPeripheralClkDisable(PRCM_UDMA,PRCM_RUN_MODE_CLK);
+
+ //
+ // Enable RTC
+ //
+ if(MAP_PRCMSysResetCauseGet()== PRCM_POWER_ON)
+ {
+ MAP_PRCMHIBRegWrite(0x4402F804,0x1);
+ }
+
+ //
+ // SWD mode
+ //
+ if (((HWREG(0x4402F0C8) & 0xFF) == 0x2))
+ {
+ HWREG(0x4402E110) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);
+ HWREG(0x4402E114) = ((HWREG(0x4402E110) & ~0xC0F) | 0x2);
+ }
+
+ //
+ // Override JTAG mux
+ //
+ HWREG(0x4402E184) |= 0x2;
+
+ //
+ // Change UART pins(55,57) mode to PIN_MODE_0 if they are in PIN_MODE_1
+ //
+ if ((HWREG(0x4402E0A4) & 0xF) == 0x1)
+ {
+ HWREG(0x4402E0A4) = ((HWREG(0x4402E0A4) & ~0xF));
+ }
+
+ if ((HWREG(0x4402E0A8) & 0xF) == 0x1)
+ {
+ HWREG(0x4402E0A8) = ((HWREG(0x4402E0A8) & ~0xF));
+ }
+
+ //
+ // DIG DCDC VOUT trim settings based on PROCESS INDICATOR
+ //
+ if (((HWREG(0x4402DC78) >> 22) & 0xF) == 0xE)
+ {
+ HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x32 << 18));
+ }
+ else
+ {
+ HWREG(0x4402F0B0) = ((HWREG(0x4402F0B0) & ~(0x00FC0000))|(0x29 << 18));
+ }
+
+ //
+ // Enable SOFT RESTART in case of DIG DCDC collapse
+ //
+ HWREG(0x4402FC74) &= ~(0x10000000);
+
+
+ //
+ // Disable the sleep for ANA DCDC
+ //
+ HWREG(0x4402F0A8) |= 0x00000004 ;
+}
+
+//*****************************************************************************
+//
+//! Reads 32-bit value from register at specified address
+//!
+//! \param ulRegAddr is the address of register to be read.
+//!
+//! This function reads 32-bit value from the register as specified by
+//! \e ulRegAddr.
+//!
+//! \return Return the value of the register.
+//
+//*****************************************************************************
+unsigned long PRCMHIBRegRead(unsigned long ulRegAddr)
+{
+ unsigned long ulValue;
+
+ //
+ // Read the Reg value
+ //
+ ulValue = HWREG(ulRegAddr);
+
+ //
+ // Wait for 200 uSec
+ //
+ UtilsDelay((80*200)/3);
+
+ //
+ // Return the value
+ //
+ return ulValue;
+}
+
+//*****************************************************************************
+//
+//! Writes 32-bit value to register at specified address
+//!
+//! \param ulRegAddr is the address of register to be read.
+//! \param ulValue is the 32-bit value to be written.
+//!
+//! This function writes 32-bit value passed as \e ulValue to the register as
+//! specified by \e ulRegAddr
+//!
+//! \return None
+//
+//*****************************************************************************
+void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue)
+{
+ //
+ // Read the Reg value
+ //
+ HWREG(ulRegAddr) = ulValue;
+
+ //
+ // Wait for 200 uSec
+ //
+ UtilsDelay((80*200)/3);
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************