diff options
Diffstat (limited to 'cc3200/hal/prcm.c')
| -rw-r--r-- | cc3200/hal/prcm.c | 1953 |
1 files changed, 0 insertions, 1953 deletions
diff --git a/cc3200/hal/prcm.c b/cc3200/hal/prcm.c deleted file mode 100644 index 4b66c0ff1..000000000 --- a/cc3200/hal/prcm.c +++ /dev/null @@ -1,1953 +0,0 @@ -//***************************************************************************** -// -// 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_MSEC_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2) -#define RTC_SECS_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG3) - -//***************************************************************************** -// Register Access and Updates -// -// Tick of SCC has a resolution of 32768Hz, meaning 1 sec is equal to 32768 -// clock ticks. Ideal way of getting time in millisecond will involve floating -// point arithmetic (division by 32.768). To avoid this, we simply divide it by -// 32, which will give a range from 0 -1023(instead of 0-999). To use this -// output correctly we have to take care of this inaccuracy externally. -// following wrapper can be used to convert the value from cycles to -// millisecond: -// -// CYCLES_U16MS(cycles) ((cycles * 1000) / 1024), -// -// Similarly, before setting the value, it must be first converted (from ms to -// cycles). -// -// U16MS_CYCLES(msec) ((msec * 1024) / 1000) -// -// Note: There is a precision loss of 1 ms with the above scheme. -// -// -#define SCC_U64MSEC_GET() (RTCFastDomainCounterGet() >> 5) -#define SCC_U64MSEC_MATCH_SET(u64Msec) (MAP_PRCMSlowClkCtrMatchSet(u64Msec << 5)) -#define SCC_U64MSEC_MATCH_GET() (MAP_PRCMSlowClkCtrMatchGet() >> 5) - -//***************************************************************************** -// -// Bit: 31 is used to indicate use of RTC. If set as '1', RTC feature is used. -// Bit: 30 is used to indicate that a safe boot should be performed. -// bit: 29 is used to indicate that the last reset was caused by the WDT. -// bit: 28 is used to indicate that the board is booting for the first time after being programmed in factory. -// Bits: 27 and 26 are unused. -// 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 int uiRegValue; - - uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 31); - - PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue); -} - -//***************************************************************************** -// Clear RTC USE Bit -//***************************************************************************** -static void RTCUseClear(void) -{ - unsigned int uiRegValue; - - uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 31)); - - PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue); -} - -//***************************************************************************** -// Checks if RTC-USE bit is set -//***************************************************************************** -static tBoolean IsRTCUsed(void) -{ - return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 31)) ? true : false; -} - -//***************************************************************************** -// Read 16-bit mSecs -//***************************************************************************** -static unsigned short RTCU32MSecRegRead(void) -{ - return ((MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) >> 16) & 0x03FF); -} - -//***************************************************************************** -// Write 16-bit mSecs -//***************************************************************************** -static void RTCU32MSecRegWrite(unsigned int u32Msec) -{ - unsigned int uiRegValue; - - // read the whole register and clear the msec bits - uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(0x03FF << 16)); - - // write the msec bits only - MAP_PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue | ((u32Msec & 0x03FF) << 16)); -} - -//***************************************************************************** -// Read 32-bit Secs -//***************************************************************************** -static unsigned long RTCU32SecRegRead(void) -{ - return (MAP_PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR)); -} - -//***************************************************************************** -// Write 32-bit Secs -//***************************************************************************** -static void RTCU32SecRegWrite(unsigned long u32Msec) -{ - MAP_PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec); -} - -//***************************************************************************** -// Fast function to get the most accurate RTC counter value -//***************************************************************************** -static unsigned long long RTCFastDomainCounterGet (void) { - - #define BRK_IF_RTC_CTRS_ALIGN(c2, c1) if (c2 - c1 <= 1) { \ - itr++; \ - break; \ - } - - unsigned long long rtc_count1, rtc_count2, rtc_count3; - unsigned int itr; - - do { - rtc_count1 = PRCMSlowClkCtrFastGet(); - rtc_count2 = PRCMSlowClkCtrFastGet(); - rtc_count3 = PRCMSlowClkCtrFastGet(); - itr = 0; - - BRK_IF_RTC_CTRS_ALIGN(rtc_count2, rtc_count1); - BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count2); - BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count1); - - // Consistent values in two consecutive reads implies a correct - // value of the counter. Do note, the counter does not give the - // calendar time but a hardware that ticks upwards continuously. - // The 48-bit counter operates at 32,768 HZ. - - } while (true); - - return (1 == itr) ? rtc_count2 : rtc_count3; -} - -//***************************************************************************** -// Macros -//***************************************************************************** -#define IS_RTC_USED() IsRTCUsed() -#define RTC_USE_SET() RTCUseSet() -#define RTC_USE_CLR() RTCUseClear() - -#define RTC_U32MSEC_REG_RD() RTCU32MSecRegRead() -#define RTC_U32MSEC_REG_WR(u32Msec) RTCU32MSecRegWrite(u32Msec) - -#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 } - -}; - -//***************************************************************************** -// -//! Set a special bit -//! -//! \return None. -// -//***************************************************************************** -void PRCMSetSpecialBit(unsigned char bit) -{ - unsigned int uiRegValue; - - uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << bit); - - PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue); -} - -//***************************************************************************** -// -//! Clear a special bit -//! -//! \return None. -// -//***************************************************************************** -void PRCMClearSpecialBit(unsigned char bit) -{ - unsigned int uiRegValue; - - uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << bit)); - - PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue); -} - -//***************************************************************************** -// -//! Read a special bit -//! -//! \return Value of the bit -// -//***************************************************************************** -tBoolean PRCMGetSpecialBit(unsigned char bit) -{ - tBoolean value = (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << bit)) ? true : false; - // special bits must be cleared immediatelly after reading - PRCMClearSpecialBit(bit); - return value; -} - -//***************************************************************************** -// -//! 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(void) -{ - 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(MAP_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. -//! -//! \note The Test Power Domain is shutdown whenever the system -//! enters LPDS (by default). In order to avoid this and allow for -//! connecting back the debugger after waking up from LPDS, -//! the macro KEEP_TESTPD_ALIVE has to be defined while building the library. -//! This is recommended for development purposes only as it adds to -//! the current consumption of the system. -//! -// -//***************************************************************************** -void PRCMLPDSEnter(void) -{ -#ifndef DEBUG - // - // Disable TestPD - // - HWREG(0x4402E168) |= (1<<9); -#endif - - // - // 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(void) -{ - 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 - // - MAP_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(void) -{ - // - // 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(void) -{ - // - // 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 = MAP_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 - // - MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue); - - // - // REad the GPIO wakeup configuration register - // - ulRegValue = MAP_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 - // - MAP_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 = MAP_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 - // - MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue); - - // - // Read the GPIO wakeup configuration register - // - ulRegValue = MAP_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 - // - MAP_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(void) -{ - return ((MAP_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 - // - MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1); - - // - // Read latched values as 2 32-bit vlaues - // - ullRTCVal = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW); - ullRTCVal = ullRTCVal << 32; - ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW); - - // - // Add the interval - // - ullRTCVal = ullRTCVal + ullTicks; - - // - // Set RTC match value - // - MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF, - (unsigned long)(ullRTCVal)); - MAP_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 = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF); - ulRegValue |= (ulType << (ucLoop*2)); - MAP_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(void) -{ - - // - // Request hibernate. - // - MAP_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(void) -{ - unsigned long long ullRTCVal; - - // - // Latch the RTC vlaue - // - MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ, 0x1); - - // - // Read latched values as 2 32-bit vlaues - // - ullRTCVal = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW); - ullRTCVal = ullRTCVal << 32; - ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW); - - return ullRTCVal; -} - -//***************************************************************************** -// -//! Gets the current value of the internal slow clock counter -//! -//! This function is similar to \sa PRCMSlowClkCtrGet() but reads the counter -//! value from a relatively faster interface using an auto-latch mechainsm. -//! -//! \note Due to the nature of implemetation of auto latching, when using this -//! API, the recommendation is to read the value thrice and identify the right -//! value (as 2 out the 3 read values will always be correct and with a max. of -//! 1 LSB change) -//! -//! \return 64-bit current counter vlaue. -// -//***************************************************************************** -unsigned long long PRCMSlowClkCtrFastGet(void) -{ - unsigned long long ullRTCVal; - - // - // Read as 2 32-bit values - // - ullRTCVal = HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_MSW_1P2); - ullRTCVal = ullRTCVal << 32; - ullRTCVal |= HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_LSW_1P2); - - 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 - // - MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF, - (unsigned long)(ullValue)); - MAP_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(void) -{ - unsigned long long ullValue; - - // - // Get RTC match value - // - ullValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF); - ullValue = ullValue<<32; - ullValue |= MAP_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) -{ - MAP_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 MAP_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(void) -{ - // - // 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 = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE); - ulRegValue |= 0x1; - MAP_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 = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE); - ulRegValue &= ~0x1; - MAP_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(void) -{ - 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. -//! -//! \return None. -// -//***************************************************************************** -void PRCMRTCInUseSet(void) -{ - RTC_USE_SET(); - return; -} - -//***************************************************************************** -// -//! Clear the function of RTC as being used -//! -//! \return None. -// -//***************************************************************************** -void PRCMRTCInUseClear(void) -{ - RTC_USE_CLR(); - 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(void) -{ - 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_U32MSEC_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_U32MSEC_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_U32MSEC_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_U32MSEC_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(void) -{ - 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 masked until the device enters - // hibernate completely (analog + digital) - // - ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0); - MAP_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); -} - -//***************************************************************************** -// -//! \param ulDivider is clock frequency divider value -//! \param ulWidth is the width of the high pulse -//! -//! This function sets the input frequency for camera module. -//! -//! The frequency is calculated as follows: -//! -//! f_out = 240MHz/ulDivider; -//! -//! The parameter \e ulWidth sets the width of the high pulse. -//! -//! For e.g.: -//! -//! ulDivider = 4; -//! ulWidth = 2; -//! -//! f_out = 30 MHz and 50% duty cycle -//! -//! And, -//! -//! ulDivider = 4; -//! ulWidth = 1; -//! -//! f_out = 30 MHz and 25% duty cycle -//! -//! \return 0 on success, 1 on error -// -//***************************************************************************** -unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth) -{ - if(ulDivider > ulWidth && ulWidth != 0 ) - { - // - // Set the hifh pulse width - // - HWREG(ARCM_BASE + - APPS_RCM_O_CAMERA_CLK_GEN) = (((ulWidth & 0x07) -1) << 8); - - // - // Set the low pulse width - // - HWREG(ARCM_BASE + - APPS_RCM_O_CAMERA_CLK_GEN) = ((ulDivider - ulWidth - 1) & 0x07); - // - // Return success - // - return 0; - } - - // - // Success; - // - return 1; -} - -//***************************************************************************** -// -// Close the Doxygen group. -//! @} -// -//***************************************************************************** |
