1277 lines
36 KiB
C
1277 lines
36 KiB
C
|
//###########################################################################
|
||
|
//
|
||
|
// FILE: F2837xD_SysCtrl.c
|
||
|
//
|
||
|
// TITLE: F2837xD Device System Control Initialization & Support Functions.
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
//
|
||
|
// Example initialization of system resources.
|
||
|
//
|
||
|
//###########################################################################
|
||
|
// $TI Release: F2837xD Support Library v3.05.00.00 $
|
||
|
// $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
|
||
|
// $Copyright:
|
||
|
// Copyright (C) 2013-2018 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.
|
||
|
// $
|
||
|
//###########################################################################
|
||
|
|
||
|
//
|
||
|
// Included Files
|
||
|
//
|
||
|
#include "F2837xD_device.h"
|
||
|
#include "F2837xD_Examples.h"
|
||
|
#ifdef __cplusplus
|
||
|
using std::memcpy;
|
||
|
#endif
|
||
|
|
||
|
#define STATUS_FAIL 0
|
||
|
#define STATUS_SUCCESS 1
|
||
|
#define TMR1SYSCLKCTR 0xF0000000
|
||
|
#define TMR2INPCLKCTR 0x800
|
||
|
|
||
|
//
|
||
|
// Functions that will be run from RAM need to be assigned to a different
|
||
|
// section. This section will then be mapped to a load and run address using
|
||
|
// the linker cmd file.
|
||
|
//
|
||
|
// *IMPORTANT*
|
||
|
//
|
||
|
// IF RUNNING FROM FLASH, PLEASE COPY OVER THE SECTION ".TI.ramfunc" FROM
|
||
|
// FLASH TO RAM PRIOR TO CALLING InitSysCtrl(). THIS PREVENTS THE MCU FROM
|
||
|
// THROWING AN EXCEPTION WHEN A CALL TO DELAY_US() IS MADE.
|
||
|
//
|
||
|
#ifndef __cplusplus
|
||
|
#ifdef __TI_COMPILER_VERSION__
|
||
|
#if __TI_COMPILER_VERSION__ >= 15009000
|
||
|
#pragma CODE_SECTION(InitFlash, ".TI.ramfunc");
|
||
|
#pragma CODE_SECTION(FlashOff, ".TI.ramfunc");
|
||
|
#else
|
||
|
#pragma CODE_SECTION(InitFlash, "ramfuncs");
|
||
|
#pragma CODE_SECTION(FlashOff, "ramfuncs");
|
||
|
#endif
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// InitSysCtrl - Initialization of system resources.
|
||
|
//
|
||
|
void InitSysCtrl(void)
|
||
|
{
|
||
|
//
|
||
|
// Disable the watchdog
|
||
|
//
|
||
|
DisableDog();
|
||
|
|
||
|
#ifdef _FLASH
|
||
|
//
|
||
|
// Copy time critical code and Flash setup code to RAM. This includes the
|
||
|
// following functions: InitFlash()
|
||
|
//
|
||
|
// The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
|
||
|
// symbols are created by the linker. Refer to the device .cmd file.
|
||
|
//
|
||
|
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
|
||
|
|
||
|
//
|
||
|
// Call Flash Initialization to setup flash waitstates. This function must
|
||
|
// reside in RAM.
|
||
|
//
|
||
|
InitFlash();
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// *IMPORTANT*
|
||
|
//
|
||
|
// The Device_cal function, which copies the ADC & oscillator calibration
|
||
|
// values from TI reserved OTP into the appropriate trim registers, occurs
|
||
|
// automatically in the Boot ROM. If the boot ROM code is bypassed during
|
||
|
// the debug process, the following function MUST be called for the ADC and
|
||
|
// oscillators to function according to specification. The clocks to the
|
||
|
// ADC MUST be enabled before calling this function.
|
||
|
//
|
||
|
// See the device data manual and/or the ADC Reference Manual for more
|
||
|
// information.
|
||
|
//
|
||
|
#ifdef CPU1
|
||
|
EALLOW;
|
||
|
|
||
|
//
|
||
|
// Enable pull-ups on unbonded IOs as soon as possible to reduce power
|
||
|
// consumption.
|
||
|
//
|
||
|
GPIO_EnableUnbondedIOPullups();
|
||
|
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
|
||
|
|
||
|
//
|
||
|
// Check if device is trimmed
|
||
|
//
|
||
|
if(*((Uint16 *)0x5D1B6) == 0x0000){
|
||
|
//
|
||
|
// Device is not trimmed--apply static calibration values
|
||
|
//
|
||
|
AnalogSubsysRegs.ANAREFTRIMA.all = 31709;
|
||
|
AnalogSubsysRegs.ANAREFTRIMB.all = 31709;
|
||
|
AnalogSubsysRegs.ANAREFTRIMC.all = 31709;
|
||
|
AnalogSubsysRegs.ANAREFTRIMD.all = 31709;
|
||
|
}
|
||
|
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_A = 0;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_B = 0;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_C = 0;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_D = 0;
|
||
|
EDIS;
|
||
|
|
||
|
//
|
||
|
// Initialize the PLL control: SYSPLLMULT and SYSCLKDIVSEL.
|
||
|
//
|
||
|
// Defined options to be passed as arguments to this function are defined
|
||
|
// in F2837xD_Examples.h.
|
||
|
//
|
||
|
// Note: The internal oscillator CANNOT be used as the PLL source if the
|
||
|
// PLLSYSCLK is configured to frequencies above 194 MHz.
|
||
|
//
|
||
|
// PLLSYSCLK = (XTAL_OSC) * (IMULT + FMULT) / (PLLSYSCLKDIV)
|
||
|
//
|
||
|
#ifdef _LAUNCHXL_F28379D
|
||
|
InitSysPll(XTAL_OSC,IMULT_40,FMULT_0,PLLCLK_BY_2);
|
||
|
#else
|
||
|
InitSysPll(XTAL_OSC, IMULT_20, FMULT_0, PLLCLK_BY_2);
|
||
|
#endif // _LAUNCHXL_F28379D
|
||
|
|
||
|
#endif // CPU1
|
||
|
|
||
|
//
|
||
|
// Turn on all peripherals
|
||
|
//
|
||
|
InitPeripheralClocks();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// InitPeripheralClocks - Initializes the clocks for the peripherals.
|
||
|
//
|
||
|
// Note: In order to reduce power consumption, turn off the clocks to any
|
||
|
// peripheral that is not specified for your part-number or is not used in the
|
||
|
// application
|
||
|
//
|
||
|
void InitPeripheralClocks(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
|
||
|
CpuSysRegs.PCLKCR0.bit.CLA1 = 1;
|
||
|
CpuSysRegs.PCLKCR0.bit.DMA = 1;
|
||
|
CpuSysRegs.PCLKCR0.bit.CPUTIMER0 = 1;
|
||
|
CpuSysRegs.PCLKCR0.bit.CPUTIMER1 = 1;
|
||
|
CpuSysRegs.PCLKCR0.bit.CPUTIMER2 = 1;
|
||
|
|
||
|
#ifdef CPU1
|
||
|
CpuSysRegs.PCLKCR0.bit.HRPWM = 1;
|
||
|
#endif
|
||
|
|
||
|
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
|
||
|
|
||
|
#ifdef CPU1
|
||
|
CpuSysRegs.PCLKCR1.bit.EMIF1 = 1;
|
||
|
CpuSysRegs.PCLKCR1.bit.EMIF2 = 1;
|
||
|
#endif
|
||
|
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM4 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM5 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM6 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM7 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM8 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM9 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM10 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM11 = 1;
|
||
|
CpuSysRegs.PCLKCR2.bit.EPWM12 = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR3.bit.ECAP1 = 1;
|
||
|
CpuSysRegs.PCLKCR3.bit.ECAP2 = 1;
|
||
|
CpuSysRegs.PCLKCR3.bit.ECAP3 = 1;
|
||
|
CpuSysRegs.PCLKCR3.bit.ECAP4 = 1;
|
||
|
CpuSysRegs.PCLKCR3.bit.ECAP5 = 1;
|
||
|
CpuSysRegs.PCLKCR3.bit.ECAP6 = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR4.bit.EQEP1 = 1;
|
||
|
CpuSysRegs.PCLKCR4.bit.EQEP2 = 1;
|
||
|
CpuSysRegs.PCLKCR4.bit.EQEP3 = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR6.bit.SD1 = 1;
|
||
|
CpuSysRegs.PCLKCR6.bit.SD2 = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR7.bit.SCI_A = 1;
|
||
|
CpuSysRegs.PCLKCR7.bit.SCI_B = 1;
|
||
|
CpuSysRegs.PCLKCR7.bit.SCI_C = 1;
|
||
|
CpuSysRegs.PCLKCR7.bit.SCI_D = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR8.bit.SPI_A = 1;
|
||
|
CpuSysRegs.PCLKCR8.bit.SPI_B = 1;
|
||
|
CpuSysRegs.PCLKCR8.bit.SPI_C = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR9.bit.I2C_A = 1;
|
||
|
CpuSysRegs.PCLKCR9.bit.I2C_B = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR10.bit.CAN_A = 1;
|
||
|
CpuSysRegs.PCLKCR10.bit.CAN_B = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR11.bit.McBSP_A = 1;
|
||
|
CpuSysRegs.PCLKCR11.bit.McBSP_B = 1;
|
||
|
|
||
|
#ifdef CPU1
|
||
|
CpuSysRegs.PCLKCR11.bit.USB_A = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR12.bit.uPP_A = 1;
|
||
|
#endif
|
||
|
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_B = 1;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
|
||
|
CpuSysRegs.PCLKCR13.bit.ADC_D = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS1 = 1;
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS2 = 1;
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS3 = 1;
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS4 = 1;
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS5 = 1;
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS6 = 1;
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS7 = 1;
|
||
|
CpuSysRegs.PCLKCR14.bit.CMPSS8 = 1;
|
||
|
|
||
|
CpuSysRegs.PCLKCR16.bit.DAC_A = 1;
|
||
|
CpuSysRegs.PCLKCR16.bit.DAC_B = 1;
|
||
|
CpuSysRegs.PCLKCR16.bit.DAC_C = 1;
|
||
|
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// DisablePeripheralClocks - Gates-off all peripheral clocks.
|
||
|
//
|
||
|
void DisablePeripheralClocks(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
|
||
|
CpuSysRegs.PCLKCR0.all = 0;
|
||
|
CpuSysRegs.PCLKCR1.all = 0;
|
||
|
CpuSysRegs.PCLKCR2.all = 0;
|
||
|
CpuSysRegs.PCLKCR3.all = 0;
|
||
|
CpuSysRegs.PCLKCR4.all = 0;
|
||
|
CpuSysRegs.PCLKCR6.all = 0;
|
||
|
CpuSysRegs.PCLKCR7.all = 0;
|
||
|
CpuSysRegs.PCLKCR8.all = 0;
|
||
|
CpuSysRegs.PCLKCR9.all = 0;
|
||
|
CpuSysRegs.PCLKCR10.all = 0;
|
||
|
CpuSysRegs.PCLKCR11.all = 0;
|
||
|
CpuSysRegs.PCLKCR12.all = 0;
|
||
|
CpuSysRegs.PCLKCR13.all = 0;
|
||
|
CpuSysRegs.PCLKCR14.all = 0;
|
||
|
CpuSysRegs.PCLKCR16.all = 0;
|
||
|
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// InitFlash - This function initializes the Flash Control registers.
|
||
|
//
|
||
|
// *CAUTION*
|
||
|
// This function MUST be executed out of RAM. Executing it out of OTP/Flash
|
||
|
// will yield unpredictable results.
|
||
|
//
|
||
|
#ifdef __cplusplus
|
||
|
#ifdef __TI_COMPILER_VERSION__
|
||
|
#if __TI_COMPILER_VERSION__ >= 15009000
|
||
|
#pragma CODE_SECTION(".TI.ramfunc");
|
||
|
#else
|
||
|
#pragma CODE_SECTION("ramfuncs");
|
||
|
#endif
|
||
|
#endif
|
||
|
#endif
|
||
|
void InitFlash(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
|
||
|
//
|
||
|
// The default value of VREADST is good enough for the flash to power up
|
||
|
// properly at the INTOSC frequency. Below VREADST configuration covers up
|
||
|
// to the max frequency possible for this device. This is required for
|
||
|
// proper flash wake up at the higher frequencies if users put it to sleep
|
||
|
// for power saving reason.
|
||
|
//
|
||
|
Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
|
||
|
|
||
|
//
|
||
|
// At reset bank and pump are in sleep. A Flash access will power up the
|
||
|
// bank and pump automatically.
|
||
|
//
|
||
|
// After a Flash access, bank and pump go to low power mode (configurable
|
||
|
// in FBFALLBACK/FPAC1 registers) if there is no further access to flash.
|
||
|
//
|
||
|
// Power up Flash bank and pump. This also sets the fall back mode of
|
||
|
// flash and pump as active.
|
||
|
//
|
||
|
Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0x1;
|
||
|
Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0x3;
|
||
|
|
||
|
//
|
||
|
// Disable Cache and prefetch mechanism before changing wait states
|
||
|
//
|
||
|
Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 0;
|
||
|
Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 0;
|
||
|
|
||
|
//
|
||
|
// Set waitstates according to frequency
|
||
|
//
|
||
|
// *CAUTION*
|
||
|
// Minimum waitstates required for the flash operating at a given CPU rate
|
||
|
// must be characterized by TI. Refer to the datasheet for the latest
|
||
|
// information.
|
||
|
//
|
||
|
#if CPU_FRQ_200MHZ
|
||
|
Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x3;
|
||
|
#endif
|
||
|
|
||
|
#if CPU_FRQ_150MHZ
|
||
|
Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
|
||
|
#endif
|
||
|
|
||
|
#if CPU_FRQ_120MHZ
|
||
|
Flash0CtrlRegs.FRDCNTL.bit.RWAIT = 0x2;
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// Enable Cache and prefetch mechanism to improve performance of code
|
||
|
// executed from Flash.
|
||
|
//
|
||
|
Flash0CtrlRegs.FRD_INTF_CTRL.bit.DATA_CACHE_EN = 1;
|
||
|
Flash0CtrlRegs.FRD_INTF_CTRL.bit.PREFETCH_EN = 1;
|
||
|
|
||
|
//
|
||
|
// At reset, ECC is enabled. If it is disabled by application software and
|
||
|
// if application again wants to enable ECC.
|
||
|
//
|
||
|
Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;
|
||
|
|
||
|
EDIS;
|
||
|
|
||
|
//
|
||
|
// Force a pipeline flush to ensure that the write to the last register
|
||
|
// configured occurs before returning.
|
||
|
//
|
||
|
__asm(" RPT #7 || NOP");
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// FlashOff - This function powers down the flash
|
||
|
//
|
||
|
// *CAUTION*
|
||
|
// This function MUST be executed out of RAM. Executing it out of OTP/Flash
|
||
|
// will yield unpredictable results. Also you must seize the flash pump in
|
||
|
// order to power it down.
|
||
|
//
|
||
|
#ifdef __cplusplus
|
||
|
#ifdef __TI_COMPILER_VERSION__
|
||
|
#if __TI_COMPILER_VERSION__ >= 15009000
|
||
|
#pragma CODE_SECTION(".TI.ramfunc");
|
||
|
#else
|
||
|
#pragma CODE_SECTION("ramfuncs");
|
||
|
#endif
|
||
|
#endif
|
||
|
#endif
|
||
|
void FlashOff(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
|
||
|
//
|
||
|
// Set VREADST to the proper value for the flash banks to power up properly
|
||
|
//
|
||
|
Flash0CtrlRegs.FBAC.bit.VREADST = 0x14;
|
||
|
|
||
|
//
|
||
|
// Power down bank
|
||
|
//
|
||
|
Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0;
|
||
|
|
||
|
//
|
||
|
// Power down pump
|
||
|
//
|
||
|
Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0;
|
||
|
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// SeizeFlashPump - Wait until the flash pump is available. Then take control
|
||
|
// of it using the flash pump Semaphore.
|
||
|
//
|
||
|
void SeizeFlashPump(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
#ifdef CPU1
|
||
|
while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x2)
|
||
|
{
|
||
|
FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x2;
|
||
|
}
|
||
|
#elif defined(CPU2)
|
||
|
while (FlashPumpSemaphoreRegs.PUMPREQUEST.bit.PUMP_OWNERSHIP != 0x1)
|
||
|
{
|
||
|
FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x1;
|
||
|
}
|
||
|
#endif
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// ReleaseFlashPump - Release control of the flash pump using the flash pump
|
||
|
// semaphore.
|
||
|
//
|
||
|
void ReleaseFlashPump(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
FlashPumpSemaphoreRegs.PUMPREQUEST.all = IPC_PUMP_KEY | 0x0;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// ServiceDog - This function resets the watchdog timer.
|
||
|
//
|
||
|
// Enable this function for using ServiceDog in the application.
|
||
|
//
|
||
|
void ServiceDog(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
WdRegs.WDKEY.bit.WDKEY = 0x0055;
|
||
|
WdRegs.WDKEY.bit.WDKEY = 0x00AA;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// DisableDog - This function disables the watchdog timer.
|
||
|
//
|
||
|
void DisableDog(void)
|
||
|
{
|
||
|
volatile Uint16 temp;
|
||
|
|
||
|
//
|
||
|
// Grab the clock config first so we don't clobber it
|
||
|
//
|
||
|
EALLOW;
|
||
|
temp = WdRegs.WDCR.all & 0x0007;
|
||
|
WdRegs.WDCR.all = 0x0068 | temp;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
#ifdef CPU1
|
||
|
//
|
||
|
// InitSysPll()
|
||
|
// This function initializes the PLL registers.
|
||
|
// Note:
|
||
|
// - The internal oscillator CANNOT be used as the PLL source if the
|
||
|
// PLLSYSCLK is configured to frequencies above 194 MHz.
|
||
|
//
|
||
|
// - This function uses the Watchdog as a monitor for the PLL. The user
|
||
|
// watchdog settings will be modified and restored upon completion. Function
|
||
|
// allows for a minimum re lock attempt for 5 tries. Re lock attempt is carried
|
||
|
// out if either SLIP condition occurs or SYSCLK to Input Clock ratio is off by 10%
|
||
|
//
|
||
|
// - This function uses the following resources to support PLL initialization:
|
||
|
// o Watchdog
|
||
|
// o CPU Timer 1
|
||
|
// o CPU Timer 2
|
||
|
//
|
||
|
void InitSysPll(Uint16 clock_source, Uint16 imult, Uint16 fmult, Uint16 divsel)
|
||
|
{
|
||
|
Uint16 SCSR, WDCR, WDWCR, intStatus, t1TCR, t1TPR, t1TPRH;
|
||
|
Uint16 t2TCR, t2TPR, t2TPRH, t2SRC, t2Prescale;
|
||
|
Uint32 t1PRD, t2PRD, ctr1;
|
||
|
float sysclkToInClkError, mult, div;
|
||
|
bool sysclkInvalidFreq=true;
|
||
|
|
||
|
if((clock_source == ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL) &&
|
||
|
(imult == ClkCfgRegs.SYSPLLMULT.bit.IMULT) &&
|
||
|
(fmult == ClkCfgRegs.SYSPLLMULT.bit.FMULT) &&
|
||
|
(divsel == ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV))
|
||
|
{
|
||
|
//
|
||
|
// Everything is set as required, so just return
|
||
|
//
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(clock_source != ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL)
|
||
|
{
|
||
|
switch (clock_source)
|
||
|
{
|
||
|
case INT_OSC1:
|
||
|
SysIntOsc1Sel();
|
||
|
break;
|
||
|
|
||
|
case INT_OSC2:
|
||
|
SysIntOsc2Sel();
|
||
|
break;
|
||
|
|
||
|
case XTAL_OSC:
|
||
|
SysXtalOscSel();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EALLOW;
|
||
|
if(imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT ||
|
||
|
fmult != ClkCfgRegs.SYSPLLMULT.bit.FMULT)
|
||
|
{
|
||
|
Uint16 i;
|
||
|
|
||
|
//
|
||
|
// This bit is reset only by POR
|
||
|
//
|
||
|
if(DevCfgRegs.SYSDBGCTL.bit.BIT_0 == 1)
|
||
|
{
|
||
|
//
|
||
|
// The user can optionally insert handler code here. This will only
|
||
|
// be executed if a watchdog reset occurred after a failed system
|
||
|
// PLL initialization. See your device user's guide for more
|
||
|
// information.
|
||
|
//
|
||
|
// If the application has a watchdog reset handler, this bit should
|
||
|
// be checked to determine if the watchdog reset occurred because
|
||
|
// of the PLL.
|
||
|
//
|
||
|
// No action here will continue with retrying the PLL as normal.
|
||
|
//
|
||
|
// Failed PLL initialization is due to any of the following:
|
||
|
// - No PLL clock
|
||
|
// - SLIP condition
|
||
|
// - Wrong Frequency
|
||
|
//
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Bypass PLL and set dividers to /1
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0;
|
||
|
|
||
|
//
|
||
|
// Lock the PLL five times. This helps ensure a successful start.
|
||
|
// Five is the minimum recommended number. The user can increase this
|
||
|
// number according to allotted system initialization time.
|
||
|
//
|
||
|
for(i = 0; i < 5; i++)
|
||
|
{
|
||
|
//
|
||
|
// Turn off PLL
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
//
|
||
|
// Write multiplier, which automatically turns on the PLL
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLMULT.all = ((fmult << 8U) | imult);
|
||
|
|
||
|
//
|
||
|
// Wait for the SYSPLL lock counter
|
||
|
//
|
||
|
while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1)
|
||
|
{
|
||
|
//
|
||
|
// Uncomment to service the watchdog
|
||
|
//
|
||
|
// ServiceDog();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set divider to produce slower output frequency to limit current increase
|
||
|
//
|
||
|
if(divsel != PLLCLK_BY_126)
|
||
|
{
|
||
|
ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// *CAUTION*
|
||
|
// It is recommended to use the following watchdog code to monitor the PLL
|
||
|
// startup sequence. If your application has already cleared the watchdog
|
||
|
// SCRS[WDOVERRIDE] bit this cannot be done. It is recommended not to clear
|
||
|
// this bit until after the PLL has been initiated.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Backup User Watchdog
|
||
|
//
|
||
|
SCSR = WdRegs.SCSR.all;
|
||
|
WDCR = WdRegs.WDCR.all;
|
||
|
WDWCR = WdRegs.WDWCR.all;
|
||
|
|
||
|
//
|
||
|
// Disable windowed functionality, reset counter
|
||
|
//
|
||
|
EALLOW;
|
||
|
WdRegs.WDWCR.all = 0x0;
|
||
|
WdRegs.WDKEY.bit.WDKEY = 0x55;
|
||
|
WdRegs.WDKEY.bit.WDKEY = 0xAA;
|
||
|
|
||
|
//
|
||
|
// Disable global interrupts
|
||
|
//
|
||
|
intStatus = __disable_interrupts();
|
||
|
|
||
|
//
|
||
|
// Configure for watchdog reset and to run at max frequency
|
||
|
//
|
||
|
WdRegs.SCSR.all = 0x0;
|
||
|
WdRegs.WDCR.all = 0x28;
|
||
|
|
||
|
//
|
||
|
// This bit is reset only by power-on-reset (POR) and will not be cleared
|
||
|
// by a WD reset
|
||
|
//
|
||
|
DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 1;
|
||
|
|
||
|
//
|
||
|
// Enable PLLSYSCLK is fed from system PLL clock
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
|
||
|
|
||
|
//
|
||
|
// Delay to ensure system is clocking from PLL prior to clearing status bit
|
||
|
//
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
//
|
||
|
// Service watchdog
|
||
|
//
|
||
|
ServiceDog();
|
||
|
|
||
|
//
|
||
|
// Slip Bit Monitor and SYSCLK Frequency Check using timers
|
||
|
// Re-lock routine for SLIP condition or if SYSCLK and CLKSRC timer counts
|
||
|
// are off by +/- 10%.
|
||
|
// At a minimum, SYSCLK check is performed. Re lock attempt is carried out
|
||
|
// if SLIPS bit is set. This while loop is monitored by watchdog.
|
||
|
// In the event that the PLL does not successfully lock, the loop will be
|
||
|
// aborted by watchdog reset.
|
||
|
//
|
||
|
EALLOW;
|
||
|
while(sysclkInvalidFreq == true)
|
||
|
{
|
||
|
if(ClkCfgRegs.SYSPLLSTS.bit.SLIPS == 1)
|
||
|
{
|
||
|
//
|
||
|
// Bypass PLL
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
//
|
||
|
// Turn off PLL
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
//
|
||
|
// Write multipliers, which automatically turns on the PLL
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLMULT.all = ((fmult << 8U) | imult);
|
||
|
|
||
|
//
|
||
|
// Wait for the SYSPLL lock counter to expire
|
||
|
//
|
||
|
while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1);
|
||
|
|
||
|
//
|
||
|
// Enable PLLSYSCLK is fed from system PLL clock
|
||
|
//
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
|
||
|
|
||
|
//
|
||
|
// Delay to ensure system is clocking from PLL
|
||
|
//
|
||
|
asm(" RPT #20 || NOP");
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Backup timer1 and timer2 settings
|
||
|
//
|
||
|
t1TCR = CpuTimer1Regs.TCR.all;
|
||
|
t1PRD = CpuTimer1Regs.PRD.all;
|
||
|
t1TPR = CpuTimer1Regs.TPR.all;
|
||
|
t1TPRH = CpuTimer1Regs.TPRH.all;
|
||
|
t2SRC = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL;
|
||
|
t2Prescale = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE;
|
||
|
t2TCR = CpuTimer2Regs.TCR.all;
|
||
|
t2PRD = CpuTimer2Regs.PRD.all;
|
||
|
t2TPR = CpuTimer2Regs.TPR.all;
|
||
|
t2TPRH = CpuTimer2Regs.TPRH.all;
|
||
|
|
||
|
//
|
||
|
// Set up timers 1 and 2
|
||
|
// Configure timer1 to count SYSCLK cycles
|
||
|
//
|
||
|
CpuTimer1Regs.TCR.bit.TSS = 1; // stop timer1
|
||
|
CpuTimer1Regs.PRD.all = TMR1SYSCLKCTR; // seed timer1 counter
|
||
|
CpuTimer1Regs.TPR.bit.TDDR = 0x0; // sysclock divider
|
||
|
CpuTimer1Regs.TCR.bit.TRB = 1; // reload timer with value in PRD
|
||
|
CpuTimer1Regs.TCR.bit.TIF = 1; // clear interrupt flag
|
||
|
CpuTimer1Regs.TCR.bit.TIE = 1; // enable interrupt
|
||
|
|
||
|
//
|
||
|
// Configure timer2 to count Input clock cycles
|
||
|
//
|
||
|
switch(clock_source)
|
||
|
{
|
||
|
case INT_OSC1:
|
||
|
// Clk Src = INT_OSC1
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x1;
|
||
|
break;
|
||
|
case INT_OSC2:
|
||
|
// Clk Src = INT_OSC2
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x2;
|
||
|
break;
|
||
|
case XTAL_OSC:
|
||
|
// Clk Src = XTAL
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x3;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
CpuTimer2Regs.TCR.bit.TIF = 1; // clear interrupt flag
|
||
|
CpuTimer2Regs.TCR.bit.TIE = 1; // enable interrupt
|
||
|
CpuTimer2Regs.TCR.bit.TSS = 1; // stop timer2
|
||
|
CpuTimer2Regs.PRD.all = TMR2INPCLKCTR; // seed timer2 counter
|
||
|
CpuTimer2Regs.TPR.bit.TDDR = 0x0; // sysclock divider
|
||
|
CpuTimer2Regs.TCR.bit.TRB = 1; // reload timer with value in PRD
|
||
|
|
||
|
//
|
||
|
// Stop/Start timer counters
|
||
|
//
|
||
|
CpuTimer1Regs.TCR.bit.TSS = 1; // stop timer1
|
||
|
CpuTimer2Regs.TCR.bit.TSS = 1; // stop timer2
|
||
|
CpuTimer1Regs.TCR.bit.TRB = 1; // reload timer1 with value in PRD
|
||
|
CpuTimer2Regs.TCR.bit.TRB = 1; // reload timer2 with value in PRD
|
||
|
CpuTimer2Regs.TCR.bit.TIF = 1; // clear timer2 interrupt flag
|
||
|
CpuTimer2Regs.TCR.bit.TSS = 0; // start timer2
|
||
|
CpuTimer1Regs.TCR.bit.TSS = 0; // start timer1
|
||
|
|
||
|
//
|
||
|
// Stop timers if either timer1 or timer2 counters overflow
|
||
|
//
|
||
|
while((CpuTimer2Regs.TCR.bit.TIF == 0) && (CpuTimer1Regs.TCR.bit.TIF == 0));
|
||
|
|
||
|
CpuTimer1Regs.TCR.bit.TSS = 1; // stop timer1
|
||
|
CpuTimer2Regs.TCR.bit.TSS = 1; // stop timer2
|
||
|
|
||
|
//
|
||
|
// Calculate elapsed counts on timer1
|
||
|
//
|
||
|
ctr1 = TMR1SYSCLKCTR - CpuTimer1Regs.TIM.all;
|
||
|
|
||
|
//
|
||
|
// Restore timer settings
|
||
|
//
|
||
|
CpuTimer1Regs.TCR.all = t1TCR;
|
||
|
CpuTimer1Regs.PRD.all = t1PRD;
|
||
|
CpuTimer1Regs.TPR.all = t1TPR;
|
||
|
CpuTimer1Regs.TPRH.all = t1TPRH;
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = t2SRC;
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = t2Prescale;
|
||
|
CpuTimer2Regs.TCR.all = t2TCR;
|
||
|
CpuTimer2Regs.PRD.all = t2PRD;
|
||
|
CpuTimer2Regs.TPR.all = t2TPR;
|
||
|
CpuTimer2Regs.TPRH.all = t2TPRH;
|
||
|
|
||
|
//
|
||
|
// Calculate Clock Error:
|
||
|
// Error = (mult/div) - (timer1 count/timer2 count)
|
||
|
//
|
||
|
mult = (float)(imult) + (float)(fmult)/4;
|
||
|
div = (float)((!ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV) ? 1 : (ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV << 1));
|
||
|
|
||
|
sysclkToInClkError = (mult/div) - ((float)ctr1/(float)TMR2INPCLKCTR);
|
||
|
|
||
|
//
|
||
|
// sysclkInvalidFreq will be set to true if sysclkToInClkError is off by 10%
|
||
|
//
|
||
|
sysclkInvalidFreq = ((sysclkToInClkError > 0.10) || (sysclkToInClkError < -0.10));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Clear bit
|
||
|
//
|
||
|
DevCfgRegs.SYSDBGCTL.bit.BIT_0 = 0;
|
||
|
|
||
|
//
|
||
|
// Restore user watchdog, first resetting counter
|
||
|
//
|
||
|
WdRegs.WDKEY.bit.WDKEY = 0x55;
|
||
|
WdRegs.WDKEY.bit.WDKEY = 0xAA;
|
||
|
|
||
|
WDCR |= 0x28; // Setup WD key--KEY bits always read 0
|
||
|
WdRegs.WDCR.all = WDCR;
|
||
|
WdRegs.WDWCR.all = WDWCR;
|
||
|
WdRegs.SCSR.all = SCSR & 0xFFFE; // Mask write to bit 0 (W1toClr)
|
||
|
|
||
|
//
|
||
|
// Restore state of ST1[INTM]. This was set by the __disable_interrupts()
|
||
|
// intrinsic previously.
|
||
|
//
|
||
|
if(!(intStatus & 0x1))
|
||
|
{
|
||
|
EINT;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Restore state of ST1[DBGM]. This was set by the __disable_interrupts()
|
||
|
// intrinsic previously.
|
||
|
//
|
||
|
if(!(intStatus & 0x2))
|
||
|
{
|
||
|
asm(" CLRC DBGM");
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// 200 PLLSYSCLK delay to allow voltage regulator to stabilize prior
|
||
|
// to increasing entire system clock frequency.
|
||
|
//
|
||
|
asm(" RPT #200 || NOP");
|
||
|
|
||
|
//
|
||
|
// Set the divider to user value
|
||
|
//
|
||
|
ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
|
||
|
|
||
|
EDIS;
|
||
|
}
|
||
|
#endif // CPU1
|
||
|
|
||
|
//
|
||
|
// InitAuxPll - This function initializes the AUXPLL registers.
|
||
|
//
|
||
|
// Note: For this function to properly detect PLL startup,
|
||
|
// SYSCLK >= 2*AUXPLLCLK after the AUXPLL is selected as the clocking source.
|
||
|
//
|
||
|
// This function will use CPU Timer 2 to monitor a successful lock of the
|
||
|
// AUXPLL.
|
||
|
//
|
||
|
void InitAuxPll(Uint16 clock_source, Uint16 imult, Uint16 fmult, Uint16 divsel)
|
||
|
{
|
||
|
Uint16 i;
|
||
|
Uint16 counter = 0;
|
||
|
Uint16 started = 0;
|
||
|
Uint16 t2TCR, t2TPR, t2TPRH, t2SRC, t2Prescale, attempts;
|
||
|
Uint32 t2PRD;
|
||
|
|
||
|
if((clock_source == ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL) &&
|
||
|
(imult == ClkCfgRegs.AUXPLLMULT.bit.IMULT) &&
|
||
|
(fmult == ClkCfgRegs.AUXPLLMULT.bit.FMULT) &&
|
||
|
(divsel == ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV))
|
||
|
{
|
||
|
//
|
||
|
// Everything is set as required, so just return
|
||
|
//
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
switch (clock_source)
|
||
|
{
|
||
|
case INT_OSC2:
|
||
|
AuxIntOsc2Sel();
|
||
|
break;
|
||
|
|
||
|
case XTAL_OSC:
|
||
|
AuxXtalOscSel();
|
||
|
break;
|
||
|
|
||
|
case AUXCLKIN:
|
||
|
AuxAuxClkSel();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Backup Timer 2 settings
|
||
|
//
|
||
|
t2SRC = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL;
|
||
|
t2Prescale = CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE;
|
||
|
t2TCR = CpuTimer2Regs.TCR.all;
|
||
|
t2PRD = CpuTimer2Regs.PRD.all;
|
||
|
t2TPR = CpuTimer2Regs.TPR.all;
|
||
|
t2TPRH = CpuTimer2Regs.TPRH.all;
|
||
|
|
||
|
//
|
||
|
// Configure Timer 2 for AUXPLL as source in known configuration
|
||
|
//
|
||
|
EALLOW;
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = 0x6;
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = 0x0; // Divide by 1
|
||
|
|
||
|
CpuTimer2Regs.TCR.bit.TSS = 1; // Stop timer
|
||
|
CpuTimer2Regs.PRD.all = 10; // Small PRD value to detect overflow
|
||
|
CpuTimer2Regs.TPR.all = 0;
|
||
|
CpuTimer2Regs.TPRH.all = 0;
|
||
|
CpuTimer2Regs.TCR.bit.TIE = 0; // Disable timer interrupts
|
||
|
|
||
|
//
|
||
|
// Set AUX Divide by 8 to ensure that AUXPLLCLK <= SYSCLK/2 while using
|
||
|
// Timer 2
|
||
|
//
|
||
|
ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = 0x3;
|
||
|
EDIS;
|
||
|
|
||
|
while((counter < 5) && (started == 0))
|
||
|
{
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 0; // Turn off AUXPLL
|
||
|
asm(" RPT #20 || NOP"); // Small delay for power down
|
||
|
|
||
|
//
|
||
|
// Set integer and fractional multiplier, which automatically turns on
|
||
|
// the PLL
|
||
|
//
|
||
|
ClkCfgRegs.AUXPLLMULT.all = ((fmult << 8U) | imult);
|
||
|
|
||
|
//
|
||
|
// Enable AUXPLL
|
||
|
//
|
||
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 1;
|
||
|
EDIS;
|
||
|
|
||
|
//
|
||
|
// Wait for the AUXPLL lock counter
|
||
|
//
|
||
|
while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1)
|
||
|
{
|
||
|
//
|
||
|
// Uncomment to service the watchdog
|
||
|
//
|
||
|
// ServiceDog();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Enable AUXPLLCLK to be fed from AUX PLL
|
||
|
//
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
//
|
||
|
// CPU Timer 2 will now be setup to be clocked from AUXPLLCLK. This is
|
||
|
// used to test that the PLL has successfully started.
|
||
|
//
|
||
|
CpuTimer2Regs.TCR.bit.TRB = 1; // Reload period value
|
||
|
CpuTimer2Regs.TCR.bit.TSS = 0; // Start Timer
|
||
|
|
||
|
//
|
||
|
// Check to see timer is counting properly
|
||
|
//
|
||
|
for(i = 0; i < 1000; i++)
|
||
|
{
|
||
|
//
|
||
|
// Check overflow flag
|
||
|
//
|
||
|
if(CpuTimer2Regs.TCR.bit.TIF)
|
||
|
{
|
||
|
//
|
||
|
// Clear overflow flag
|
||
|
//
|
||
|
CpuTimer2Regs.TCR.bit.TIF = 1;
|
||
|
|
||
|
//
|
||
|
// Set flag to indicate PLL started and break out of for-loop
|
||
|
//
|
||
|
started = 1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Stop timer
|
||
|
//
|
||
|
CpuTimer2Regs.TCR.bit.TSS = 1;
|
||
|
counter++;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
if(started == 0)
|
||
|
{
|
||
|
//
|
||
|
// AUX PLL may not have started. Reset multiplier to 0 (bypass PLL).
|
||
|
//
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.AUXPLLMULT.all = 0;
|
||
|
EDIS;
|
||
|
|
||
|
//
|
||
|
// The user should put some handler code here based on how this
|
||
|
// condition should be handled in their application.
|
||
|
//
|
||
|
asm(" ESTOP0");
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Slip Bit Monitor
|
||
|
// Re-lock routine for SLIP condition
|
||
|
//
|
||
|
attempts = 0;
|
||
|
while(ClkCfgRegs.AUXPLLSTS.bit.SLIPS && (attempts < 10))
|
||
|
{
|
||
|
EALLOW;
|
||
|
//
|
||
|
// Bypass AUXPLL
|
||
|
//
|
||
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
//
|
||
|
// Turn off AUXPLL
|
||
|
//
|
||
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 0;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
//
|
||
|
// Set integer and fractional multiplier, which automatically turns
|
||
|
// on the PLL
|
||
|
//
|
||
|
ClkCfgRegs.AUXPLLMULT.all = ((fmult << 8U) | imult);
|
||
|
|
||
|
//
|
||
|
// Wait for the AUXPLL lock counter
|
||
|
//
|
||
|
while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1);
|
||
|
|
||
|
//
|
||
|
// Enable AUXPLLCLK to be fed from AUXPLL
|
||
|
//
|
||
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
|
||
|
asm(" RPT #20 || NOP");
|
||
|
|
||
|
attempts++;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set divider to desired value
|
||
|
//
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = divsel;
|
||
|
|
||
|
//
|
||
|
// Restore Timer 2 configuration
|
||
|
//
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKSRCSEL = t2SRC;
|
||
|
CpuSysRegs.TMR2CLKCTL.bit.TMR2CLKPRESCALE = t2Prescale;
|
||
|
CpuTimer2Regs.TCR.all = t2TCR;
|
||
|
CpuTimer2Regs.PRD.all = t2PRD;
|
||
|
CpuTimer2Regs.TPR.all = t2TPR;
|
||
|
CpuTimer2Regs.TPRH.all = t2TPRH;
|
||
|
|
||
|
//
|
||
|
// Reload period value
|
||
|
//
|
||
|
CpuTimer2Regs.TCR.bit.TRB = 1;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// CsmUnlock - This function unlocks the CSM. User must replace 0xFFFF's with
|
||
|
// current password for the DSP. Returns 1 if unlock is successful.
|
||
|
//
|
||
|
Uint16 CsmUnlock(void)
|
||
|
{
|
||
|
volatile Uint16 temp;
|
||
|
|
||
|
//
|
||
|
// Load the key registers with the current password. The 0xFFFF's are dummy
|
||
|
// passwords. User should replace them with the correct password for the
|
||
|
// DSP.
|
||
|
//
|
||
|
EALLOW;
|
||
|
DcsmZ1Regs.Z1_CSMKEY0 = 0xFFFFFFFF;
|
||
|
DcsmZ1Regs.Z1_CSMKEY1 = 0xFFFFFFFF;
|
||
|
DcsmZ1Regs.Z1_CSMKEY2 = 0xFFFFFFFF;
|
||
|
DcsmZ1Regs.Z1_CSMKEY3 = 0xFFFFFFFF;
|
||
|
|
||
|
DcsmZ2Regs.Z2_CSMKEY0 = 0xFFFFFFFF;
|
||
|
DcsmZ2Regs.Z2_CSMKEY1 = 0xFFFFFFFF;
|
||
|
DcsmZ2Regs.Z2_CSMKEY2 = 0xFFFFFFFF;
|
||
|
DcsmZ2Regs.Z2_CSMKEY3 = 0xFFFFFFFF;
|
||
|
EDIS;
|
||
|
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// SysIntOsc1Sel - This function switches to Internal Oscillator 1.
|
||
|
//
|
||
|
void SysIntOsc1Sel(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 2; // Clk Src = INTOSC1
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// SysIntOsc2Sel - This function switches to Internal oscillator 2.
|
||
|
//
|
||
|
void SysIntOsc2Sel(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // Turn on INTOSC2
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // Clk Src = INTOSC2
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// SysXtalOscSel - This function switches to External CRYSTAL oscillator.
|
||
|
//
|
||
|
void SysXtalOscSel(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // Clk Src = XTAL
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// AuxIntOsc2Sel - This function switches to Internal oscillator 2.
|
||
|
//
|
||
|
void AuxIntOsc2Sel(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // Turn on INTOSC2
|
||
|
ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0; // Clk Src = INTOSC2
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// AuxXtalOscSel - This function switches to External CRYSTAL oscillator.
|
||
|
//
|
||
|
void AuxXtalOscSel(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
|
||
|
ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1; // Clk Src = XTAL
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// AuxAUXCLKOscSel - This function switches to AUXCLKIN (from a GPIO).
|
||
|
//
|
||
|
void AuxAuxClkSel(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 2; // Clk Src = XTAL
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// IDLE - Enter IDLE mode (single CPU).
|
||
|
//
|
||
|
void IDLE(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
CpuSysRegs.LPMCR.bit.LPM = LPM_IDLE;
|
||
|
EDIS;
|
||
|
asm(" IDLE");
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// STANDBY - Enter STANDBY mode (single CPU).
|
||
|
//
|
||
|
void STANDBY(void)
|
||
|
{
|
||
|
EALLOW;
|
||
|
CpuSysRegs.LPMCR.bit.LPM = LPM_STANDBY;
|
||
|
EDIS;
|
||
|
asm(" IDLE");
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// HALT - Enter HALT mode (dual CPU). Puts CPU2 in IDLE mode first.
|
||
|
//
|
||
|
void HALT(void)
|
||
|
{
|
||
|
#if defined(CPU2)
|
||
|
IDLE();
|
||
|
#elif defined(CPU1)
|
||
|
EALLOW;
|
||
|
CpuSysRegs.LPMCR.bit.LPM = LPM_HALT;
|
||
|
EDIS;
|
||
|
|
||
|
while(DevCfgRegs.LPMSTAT.bit.CPU2LPMSTAT != 0x1);
|
||
|
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
|
||
|
EDIS;
|
||
|
asm(" IDLE");
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// HIB - Enter HIB mode (dual CPU). Puts CPU2 in STANDBY first. Alternately,
|
||
|
// CPU2 may be in reset.
|
||
|
void HIB(void)
|
||
|
{
|
||
|
#if defined(CPU2)
|
||
|
STANDBY();
|
||
|
#elif defined(CPU1)
|
||
|
EALLOW;
|
||
|
CpuSysRegs.LPMCR.bit.LPM = LPM_HIB;
|
||
|
EDIS;
|
||
|
|
||
|
while((DevCfgRegs.LPMSTAT.bit.CPU2LPMSTAT == 0x0) &&
|
||
|
(DevCfgRegs.RSTSTAT.bit.CPU2RES == 1));
|
||
|
|
||
|
DisablePeripheralClocks();
|
||
|
EALLOW;
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
|
||
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
|
||
|
EDIS;
|
||
|
asm(" IDLE");
|
||
|
#endif
|
||
|
}
|
||
|
|