1464 lines
37 KiB
C
1464 lines
37 KiB
C
//###########################################################################
|
|
//
|
|
// FILE: f2838x_sysctrl.c
|
|
//
|
|
// TITLE: F2838x Device System Control Initialization & Support Functions.
|
|
//
|
|
// DESCRIPTION:
|
|
//
|
|
// Example initialization of system resources.
|
|
//
|
|
//###########################################################################
|
|
//
|
|
//
|
|
// $Copyright:
|
|
// Copyright (C) 2022 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 "f2838x_device.h"
|
|
#include "f2838x_examples.h"
|
|
#include "math.h"
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
#pragma CODE_SECTION(InitFlash, ".TI.ramfunc");
|
|
#pragma CODE_SECTION(FlashOff, ".TI.ramfunc");
|
|
|
|
|
|
// The following values are used to validate PLL Frequency using DCC
|
|
//
|
|
#define DCC_COUNTER0_TOLERANCE 1
|
|
|
|
#ifdef USE_20MHZ_XTAL
|
|
|
|
#define OSC_FREQ 20
|
|
|
|
//
|
|
// Multipliers and dividers to configure 200MHz SYSPLL output from 20MHz XTAL
|
|
//
|
|
#define SYS_IMULT IMULT_40
|
|
#define SYS_REFDIV REFDIV_2
|
|
#define SYS_ODIV ODIV_2
|
|
#define SYS_DIV PLLCLK_BY_1
|
|
|
|
//
|
|
// Multipliers and dividers to configure 125MHz AUXPLL output from 20MHz XTAL
|
|
//
|
|
#define AUX_IMULT IMULT_50
|
|
#define AUX_REFDIV REFDIV_2
|
|
#define AUX_ODIV ODIV_4
|
|
#define AUX_DIV AUXPLLRAWCLK_BY_1
|
|
|
|
|
|
#else // USE_25MHZ_XTAL
|
|
|
|
#define OSC_FREQ 25
|
|
|
|
//
|
|
// Multipliers and dividers to configure 200MHz SYSPLL output from 25MHz XTAL
|
|
//
|
|
#define SYS_IMULT IMULT_32
|
|
#define SYS_REFDIV REFDIV_2
|
|
#define SYS_ODIV ODIV_2
|
|
#define SYS_DIV PLLCLK_BY_1
|
|
|
|
//
|
|
// Multipliers and dividers to configure 125MHz AUXPLL output from 25MHz XTAL
|
|
//
|
|
#define AUX_IMULT IMULT_40
|
|
#define AUX_REFDIV REFDIV_2
|
|
#define AUX_ODIV ODIV_4
|
|
#define AUX_DIV AUXPLLRAWCLK_BY_1
|
|
|
|
#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
|
|
//
|
|
// Enable pull-ups on unbonded IOs as soon as possible to reduce power
|
|
// consumption.
|
|
//
|
|
GPIO_EnableUnbondedIOPullups();
|
|
|
|
EALLOW;
|
|
|
|
|
|
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 *)0x5D736) == 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;
|
|
|
|
//
|
|
// Verify the crystal frequency.
|
|
// Note: This check can be removed if you are not using XTAL as the PLL
|
|
// source
|
|
//
|
|
if(!VerifyXTAL(OSC_FREQ))
|
|
{
|
|
//
|
|
// The actual XTAL frequency does not match OSC_FREQ!!
|
|
// Please check the XTAL frequency used.
|
|
//
|
|
// By default, the InitSysCtrl function assumes 25MHz XTAL.
|
|
// If a 20MHz crystal is used, please add a predefined symbol
|
|
// "USE_20MHZ_XTAL" in your CCS project.
|
|
// If a different XTAL is used, please update the PLL configuration
|
|
// below accordingly.
|
|
//
|
|
// Note that the latest F2838x controlCARDs (Rev.B and later) have been
|
|
// updated to use 25MHz XTAL by default. If you have an older 20MHz XTAL
|
|
// controlCARD (E1, E2, or Rev.A), refer to the controlCARD
|
|
// documentation on steps to reconfigure the controlCARD from 20MHz to
|
|
// 25MHz.
|
|
//
|
|
ESTOP0;
|
|
while(1);
|
|
}
|
|
|
|
//
|
|
// Initialize the SYSPLL control to generate a 200Mhz clock
|
|
//
|
|
// Defined options to be passed as arguments to this function are defined
|
|
// in f2838x_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) /(REFDIV) * (ODIV) * (PLLSYSCLKDIV)
|
|
//
|
|
InitSysPll(XTAL_OSC, SYS_IMULT, SYS_REFDIV, SYS_ODIV, SYS_DIV, SYSCTL_DCC_BASE0);
|
|
|
|
//
|
|
// Initialize the AUXPLL control to generate a 125Mhz clock:
|
|
//
|
|
// Defined options to be passed as arguments to this function are defined
|
|
// in f2838x_Examples.h.
|
|
//
|
|
// Note: The internal oscillator CANNOT be used as the PLL source if the
|
|
// AUXPLLCLK is configured to frequencies above 194 MHz.
|
|
//
|
|
// AUXPLLCLK = (XTAL_OSC) * (IMULT) /(REFDIV) * (ODIV) * (AUXPLLDIV)
|
|
//
|
|
InitAuxPll(XTAL_OSC, AUX_IMULT, AUX_REFDIV, AUX_ODIV, AUX_DIV, SYSCTL_DCC_BASE1);
|
|
|
|
//
|
|
// Set up CMCLK to use AUXPLL as the clock source and set the
|
|
// clock divider to 1.
|
|
//
|
|
EALLOW;
|
|
ClkCfgRegs.CMCLKCTL.bit.CMCLKDIV = 0; // 0 : Divide by 1
|
|
ClkCfgRegs.CMCLKCTL.bit.CMDIVSRCSEL = 0; // 0 : AuxPLL is the source for the CM clock divider.
|
|
EDIS;
|
|
|
|
#ifndef _FLASH
|
|
//
|
|
// Call Device_cal function when run using debugger
|
|
// This function is called as part of the Boot code. The function is called
|
|
// in the InitSysCtrl function since during debug time resets, the boot code
|
|
// will not be executed and the gel script will reinitialize all the
|
|
// registers and the calibrated values will be lost.
|
|
//
|
|
Device_cal();
|
|
#endif
|
|
|
|
#endif // CPU1
|
|
|
|
//
|
|
// Turn on all peripherals
|
|
//
|
|
InitPeripheralClocks();
|
|
}
|
|
|
|
//
|
|
//
|
|
// Function to verify the XTAL frequency
|
|
// freq is the XTAL frequency in MHz
|
|
// The function return true if the the actual XTAL frequency matches with the
|
|
// input value
|
|
//
|
|
//
|
|
#ifdef CPU1
|
|
bool VerifyXTAL(float freq)
|
|
{
|
|
//
|
|
// Configures XTAL as CLKSRC0 and INTOSC2 as CLKSRC1.
|
|
// Fclk0 = XTAL frequency (input parameter)
|
|
// Fclk1 = INTOSC2 frequency = 10MHz
|
|
//
|
|
// Calculating Counter0 & Valid Seed Value with +/-1% tolerance
|
|
// INTOSC can have a variance in frequency of +/-10%
|
|
//
|
|
// Since Fclk1 < Fclk0, then Async. Error (In Clock0 cycles) =
|
|
// 2*(Fclk0/Fclk1) + 2*(Fsysclk/Fclk0)
|
|
// Digitization error = 8 Clock0 cycles
|
|
// DCC Error (in Cycles) = 2*(Fclk0/Fclk1) + 2*(Fsysclk/Fclk0) + 8
|
|
// Window (in Cycles) = (Total Error) / (0.01 * Tolerance)
|
|
// Error due to variance in frequency = Window * freqVariance
|
|
// Total error = DCC Error + Error due to variance in frequency
|
|
// Counter0 = Window - Total Error
|
|
// Valid0 = 2 * Total Error
|
|
// Counter1 = Window * (Fclk1/Fclk0)
|
|
//
|
|
// Note : Update the tolerance and INTOSC2 frequency variance as necessary.
|
|
//
|
|
uint32_t total_error = ceil((2.0F * freq/10.0F) + (2.0F * 10.0F/freq) + 8.0F);
|
|
uint32_t window = total_error / 0.01F;
|
|
total_error += window * 0.1F;
|
|
|
|
uint32_t count0 = window - total_error;
|
|
uint32_t valid = 2 * total_error;
|
|
uint32_t count1 = window * 10 / freq;
|
|
|
|
EALLOW;
|
|
|
|
//
|
|
// Enable DCC0 clock
|
|
//
|
|
CpuSysRegs.PCLKCR21.bit.DCC0 = 1;
|
|
|
|
//
|
|
// Insert atleast 5 cycles delay after enabling the peripheral clock
|
|
//
|
|
asm(" RPT #5 || NOP");
|
|
|
|
//
|
|
// Clear Error & Done Flag
|
|
//
|
|
Dcc0Regs.DCCSTATUS.bit.ERR = 1;
|
|
Dcc0Regs.DCCSTATUS.bit.DONE = 1;
|
|
|
|
//
|
|
// Disable DCC
|
|
//
|
|
Dcc0Regs.DCCGCTRL.bit.DCCENA = 0x5;
|
|
|
|
//
|
|
// Disable Error Signal
|
|
//
|
|
Dcc0Regs.DCCGCTRL.bit.ERRENA = 0x5;
|
|
|
|
//
|
|
// Disable Done Signal
|
|
//
|
|
Dcc0Regs.DCCGCTRL.bit.DONEENA = 0x5;
|
|
|
|
//
|
|
// Configure Clock Source0 to XTAL
|
|
//
|
|
Dcc0Regs.DCCCLKSRC0.all = (0xA << 12) | // bits 12..15 : Key
|
|
0; // bits 0..4 : Source = XTAL(value 0)
|
|
|
|
//
|
|
// Configure Clock Source1 to INTOSC
|
|
//
|
|
Dcc0Regs.DCCCLKSRC1.all = (0xA << 12) | // bits 12..15 : Key
|
|
3; // bits 0..4 : Source = INTOS2(value 3)
|
|
|
|
//
|
|
// Configure COUNTER-0, COUNTER-1 & Valid Window
|
|
//
|
|
Dcc0Regs.DCCCNTSEED0.all = count0;
|
|
Dcc0Regs.DCCCNTSEED1.all = count1;
|
|
Dcc0Regs.DCCVALIDSEED0.all = valid;
|
|
|
|
//
|
|
// Enable Single Shot mode
|
|
//
|
|
Dcc0Regs.DCCGCTRL.bit.SINGLESHOT = 0xA;
|
|
|
|
//
|
|
// Enable Error Signal
|
|
//
|
|
Dcc0Regs.DCCGCTRL.bit.ERRENA = 0xA;
|
|
|
|
//
|
|
// Enable Done Signal
|
|
//
|
|
Dcc0Regs.DCCGCTRL.bit.DONEENA = 0xA;
|
|
|
|
//
|
|
// Enable DCC to start counting
|
|
//
|
|
Dcc0Regs.DCCGCTRL.bit.DCCENA = 0xA;
|
|
|
|
EDIS;
|
|
|
|
//
|
|
// Wait until Error or Done Flag is generated
|
|
//
|
|
while((Dcc0Regs.DCCSTATUS.bit.DONE | Dcc0Regs.DCCSTATUS.bit.ERR) == 0);
|
|
|
|
//
|
|
// Returns true if DCC completes without error
|
|
//
|
|
if (Dcc0Regs.DCCSTATUS.bit.DONE == 1U)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// 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;
|
|
CpuSysRegs.PCLKCR0.bit.CPUBGCRC = 1;
|
|
CpuSysRegs.PCLKCR0.bit.CLA1BGCRC = 1;
|
|
|
|
#ifdef CPU1
|
|
CpuSysRegs.PCLKCR0.bit.HRCAL = 1;
|
|
#endif
|
|
|
|
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
|
|
CpuSysRegs.PCLKCR0.bit.ERAD = 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.PCLKCR2.bit.EPWM13 = 1;
|
|
CpuSysRegs.PCLKCR2.bit.EPWM14 = 1;
|
|
CpuSysRegs.PCLKCR2.bit.EPWM15 = 1;
|
|
CpuSysRegs.PCLKCR2.bit.EPWM16 = 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.PCLKCR3.bit.ECAP7 = 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.PCLKCR8.bit.SPI_D = 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;
|
|
#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;
|
|
|
|
CpuSysRegs.PCLKCR18.bit.FSITX_A = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSITX_B = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_A = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_B = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_C = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_D = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_E = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_F = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_G = 1;
|
|
CpuSysRegs.PCLKCR18.bit.FSIRX_H = 1;
|
|
|
|
CpuSysRegs.PCLKCR20.bit.PMBUS_A = 1;
|
|
|
|
CpuSysRegs.PCLKCR21.bit.DCC0 = 1;
|
|
CpuSysRegs.PCLKCR21.bit.DCC1 = 1;
|
|
CpuSysRegs.PCLKCR21.bit.DCC2 = 1;
|
|
|
|
CpuSysRegs.PCLKCR23.bit.ETHERCAT = 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.PCLKCR13.all = 0;
|
|
CpuSysRegs.PCLKCR14.all = 0;
|
|
CpuSysRegs.PCLKCR16.all = 0;
|
|
CpuSysRegs.PCLKCR18.all = 0;
|
|
CpuSysRegs.PCLKCR20.all = 0;
|
|
CpuSysRegs.PCLKCR21.all = 0;
|
|
CpuSysRegs.PCLKCR22.all = 0;
|
|
CpuSysRegs.PCLKCR23.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
|
|
#pragma CODE_SECTION(".TI.ramfunc");
|
|
#endif
|
|
void InitFlash(void)
|
|
{
|
|
EALLOW;
|
|
|
|
//
|
|
// At reset bank and pump are in sleep. A Flash access will power up the
|
|
// bank and pump automatically.
|
|
//
|
|
// 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
|
|
#pragma CODE_SECTION(".TI.ramfunc");
|
|
#endif
|
|
void FlashOff(void)
|
|
{
|
|
EALLOW;
|
|
|
|
//
|
|
// Power down bank
|
|
//
|
|
Flash0CtrlRegs.FBFALLBACK.bit.BNKPWR0 = 0;
|
|
|
|
//
|
|
// Power down pump
|
|
//
|
|
Flash0CtrlRegs.FPAC1.bit.PMPPWR = 0;
|
|
|
|
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
|
|
//
|
|
// InitPll - This function initializes the PLL registers.
|
|
//
|
|
// Note: This function uses the DCC to check that the PLLRAWCLK is running at
|
|
// the expected rate. The desirable DCC can be provided as a parameter.
|
|
//
|
|
void InitSysPll(Uint16 clock_source, Uint16 imult, Uint32 refdiv, Uint32 odiv,
|
|
Uint16 divsel, Uint32 dccbase)
|
|
{
|
|
Uint32 timeout,temp_syspllmult, pllLockStatus;
|
|
bool status;
|
|
|
|
if(((clock_source & 0x3) == ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL) &&
|
|
(((clock_source & 0x4) >> 2) == ClkCfgRegs.XTALCR.bit.SE) &&
|
|
(imult == ClkCfgRegs.SYSPLLMULT.bit.IMULT) &&
|
|
(refdiv == ClkCfgRegs.SYSPLLMULT.bit.REFDIV) &&
|
|
(odiv == ClkCfgRegs.SYSPLLMULT.bit.ODIV) &&
|
|
(divsel == ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV))
|
|
{
|
|
//
|
|
// Everything is set as required, so just return
|
|
//
|
|
return;
|
|
}
|
|
|
|
EALLOW;
|
|
|
|
//
|
|
// First modify the PLL multipliers if the multipliers need an update or PLL needs
|
|
// to be powered on / enabled
|
|
//
|
|
if((imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT) ||
|
|
(refdiv != ClkCfgRegs.SYSPLLMULT.bit.REFDIV)||
|
|
(odiv != ClkCfgRegs.SYSPLLMULT.bit.ODIV) ||
|
|
(1U != ClkCfgRegs.SYSPLLCTL1.bit.PLLEN))
|
|
{
|
|
//
|
|
// Bypass PLL and set dividers to /1
|
|
//
|
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
|
|
|
|
//
|
|
// Delay of at least 120 OSCCLK cycles required post PLL bypass
|
|
//
|
|
asm(" RPT #120 || NOP");
|
|
|
|
//
|
|
// Evaluate PLL multipliers and dividers
|
|
//
|
|
temp_syspllmult = ((refdiv << 24U) | (odiv << 16U)| imult);
|
|
|
|
//
|
|
// Turnoff the PLL
|
|
//
|
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
|
|
EDIS;
|
|
|
|
//
|
|
// Delay of at least 66 OSCCLK cycles
|
|
//
|
|
asm(" RPT #66 || NOP");
|
|
|
|
if(((clock_source & 0x3) != ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL) ||
|
|
(((clock_source & 0x4) >> 2) != ClkCfgRegs.XTALCR.bit.SE))
|
|
{
|
|
switch (clock_source)
|
|
{
|
|
case INT_OSC1:
|
|
SysIntOsc1Sel();
|
|
break;
|
|
|
|
case INT_OSC2:
|
|
SysIntOsc2Sel();
|
|
break;
|
|
|
|
case XTAL_OSC:
|
|
SysXtalOscSel();
|
|
break;
|
|
|
|
case XTAL_OSC_SE:
|
|
SysXtalOscSESel();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Delay of at least 60 OSCCLK cycles
|
|
//
|
|
asm(" RPT #60 || NOP");
|
|
|
|
EALLOW;
|
|
|
|
//
|
|
// Set dividers to /1 to ensure the fastest PLL configuration
|
|
//
|
|
ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0;
|
|
|
|
//
|
|
// Program PLL multipliers
|
|
//
|
|
ClkCfgRegs.SYSPLLMULT.all = temp_syspllmult;
|
|
|
|
//
|
|
// Enable SYSPLL
|
|
//
|
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 1;
|
|
|
|
//
|
|
// Lock time is 1024 OSCCLK * (REFDIV+1)
|
|
//
|
|
timeout = (1024U * (refdiv + 1U));
|
|
pllLockStatus = ClkCfgRegs.SYSPLLSTS.bit.LOCKS;
|
|
|
|
//
|
|
// Wait for the SYSPLL lock
|
|
//
|
|
while((pllLockStatus != 1) && (timeout != 0U))
|
|
{
|
|
pllLockStatus = ClkCfgRegs.SYSPLLSTS.bit.LOCKS;
|
|
timeout--;
|
|
}
|
|
|
|
EDIS;
|
|
|
|
//
|
|
// Check PLL Frequency using DCC
|
|
//
|
|
status = IsPLLValid(dccbase, clock_source, INT_PLL_SYSPLL,
|
|
imult, odiv , refdiv);
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Re-Lock of PLL not needed since the multipliers
|
|
// are not updated
|
|
//
|
|
status = true;
|
|
}
|
|
|
|
if(status)
|
|
{
|
|
EALLOW;
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
// Enable PLLSYSCLK is fed from system PLL clock
|
|
//
|
|
ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
|
|
|
|
//
|
|
// Small 100 cycle delay
|
|
//
|
|
asm(" RPT #100 || NOP");
|
|
|
|
//
|
|
// Set the divider to user value
|
|
//
|
|
ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = divsel;
|
|
EDIS;
|
|
}
|
|
else
|
|
ESTOP0; // If the frequency is out of range, stop here.
|
|
|
|
}
|
|
|
|
//
|
|
// InitAuxPll - This function initializes the AUXPLL registers.
|
|
//
|
|
// Note: This function uses the DCC to check that the AUXPLLRAWCLK is running at
|
|
// the expected rate. The desirable DCC can be provided as a parameter.
|
|
//
|
|
void InitAuxPll(Uint16 clock_source, Uint16 imult, Uint32 refdiv, Uint32 odiv,
|
|
Uint16 divsel, Uint32 dccbase)
|
|
{
|
|
Uint16 started = 0 , status = 0;
|
|
|
|
if((clock_source == ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL) &&
|
|
(((clock_source & 0x4) >> 2) == ClkCfgRegs.XTALCR.bit.SE) &&
|
|
(imult == ClkCfgRegs.AUXPLLMULT.bit.IMULT) &&
|
|
(refdiv == ClkCfgRegs.SYSPLLMULT.bit.REFDIV) &&
|
|
(odiv == ClkCfgRegs.SYSPLLMULT.bit.ODIV) &&
|
|
(divsel == ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV))
|
|
{
|
|
//
|
|
// Everything is set as required, so just return
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// First modify the PLL multipliers
|
|
//
|
|
if((imult != ClkCfgRegs.AUXPLLMULT.bit.IMULT) ||
|
|
(refdiv != ClkCfgRegs.AUXPLLMULT.bit.REFDIV)||
|
|
(odiv != ClkCfgRegs.AUXPLLMULT.bit.ODIV) ||
|
|
(1U != ClkCfgRegs.AUXPLLCTL1.bit.PLLEN))
|
|
{
|
|
EALLOW;
|
|
|
|
//
|
|
// Bypass PLL
|
|
//
|
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0;
|
|
|
|
//
|
|
// Delay of at least 120 OSCCLK cycles required post PLL bypass
|
|
//
|
|
asm(" RPT #120 || NOP");
|
|
|
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 0; // Turn off AUXPLL
|
|
|
|
//
|
|
// Delay of at least 66 OSCCLK cycles
|
|
//
|
|
asm(" RPT #66 || NOP");
|
|
|
|
//
|
|
// Configure oscillator source
|
|
//
|
|
switch (clock_source)
|
|
{
|
|
case INT_OSC2:
|
|
AuxIntOsc2Sel();
|
|
break;
|
|
|
|
case XTAL_OSC:
|
|
AuxXtalOscSel();
|
|
break;
|
|
|
|
case XTAL_OSC_SE:
|
|
AuxXtalOscSESel();
|
|
break;
|
|
|
|
case AUXCLKIN:
|
|
AuxAuxClkSel();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Delay of at least 60 OSCCLK cycles
|
|
//
|
|
asm(" RPT #60 || NOP");
|
|
|
|
EALLOW;
|
|
//
|
|
// Set integer multiplier and dividers, which automatically turns on
|
|
// the PLL
|
|
//
|
|
ClkCfgRegs.AUXPLLMULT.all = ((refdiv << 24U) | (odiv << 16U) | 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();
|
|
}
|
|
|
|
status = IsPLLValid(dccbase, clock_source, INT_PLL_AUXPLL,
|
|
imult, odiv , refdiv);
|
|
|
|
//
|
|
// Check DCC Status
|
|
//
|
|
if(status)
|
|
{
|
|
started = 1;
|
|
}
|
|
|
|
//
|
|
// Enable AUXPLLCLK to be fed from AUX PLL
|
|
//
|
|
EALLOW;
|
|
ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;
|
|
asm(" RPT #20 || NOP");
|
|
|
|
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");
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set divider to desired value
|
|
//
|
|
EALLOW;
|
|
ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = divsel;
|
|
|
|
EDIS;
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// CsmUnlock - This function unlocks the CSM. User must replace the default
|
|
// value with the current password for the DSP.
|
|
//
|
|
Uint16 CsmUnlock(void)
|
|
{
|
|
volatile Uint16 temp;
|
|
|
|
//
|
|
// Load the key registers with the current password. These values are
|
|
// default passwords for the first ZSB. User should replace them with
|
|
// the correct password for the DSP.
|
|
//
|
|
EALLOW;
|
|
DcsmZ1Regs.Z1_CSMKEY0 = 0xFFFFFFFF;
|
|
DcsmZ1Regs.Z1_CSMKEY1 = 0x4D7FFFFF;
|
|
DcsmZ1Regs.Z1_CSMKEY2 = 0xFFFFFFFF;
|
|
DcsmZ1Regs.Z1_CSMKEY3 = 0xFFFFFFFF;
|
|
|
|
DcsmZ2Regs.Z2_CSMKEY0 = 0xFFFFFFFF;
|
|
DcsmZ2Regs.Z2_CSMKEY1 = 0x3FFFFFFF;
|
|
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
|
|
EDIS;
|
|
}
|
|
|
|
//
|
|
// SysIntOsc2Sel - This function switches to Internal oscillator 2.
|
|
//
|
|
void SysIntOsc2Sel(void)
|
|
{
|
|
EALLOW;
|
|
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // Clk Src = INTOSC2
|
|
EDIS;
|
|
}
|
|
|
|
//
|
|
// PollX1Counter - Clear the X1CNT counter and then wait for it to saturate
|
|
// four times.
|
|
//
|
|
static void
|
|
PollX1Counter(void)
|
|
{
|
|
Uint16 loopCount = 0;
|
|
|
|
//
|
|
// Delay for 1 ms while the XTAL powers up
|
|
//
|
|
// 2000 loops, 5 cycles per loop + 9 cycles overhead = 10009 cycles
|
|
//
|
|
F28x_usDelay(2000);
|
|
|
|
//
|
|
// Clear and saturate X1CNT 4 times to guarantee operation
|
|
//
|
|
do
|
|
{
|
|
//
|
|
// Keep clearing the counter until it is no longer saturated
|
|
//
|
|
while(ClkCfgRegs.X1CNT.all > 0x1FF)
|
|
{
|
|
ClkCfgRegs.X1CNT.bit.CLR = 1;
|
|
ClkCfgRegs.X1CNT.bit.CLR = 0;
|
|
}
|
|
|
|
//
|
|
// Wait for the X1 clock to saturate
|
|
//
|
|
while(ClkCfgRegs.X1CNT.all != 0x3FFU)
|
|
{
|
|
;
|
|
}
|
|
|
|
//
|
|
// Increment the counter
|
|
//
|
|
loopCount++;
|
|
}while(loopCount < 4);
|
|
}
|
|
// SysXtalOscSel - This function switches to External CRYSTAL oscillator.
|
|
//
|
|
void SysXtalOscSel(void)
|
|
{
|
|
EALLOW;
|
|
ClkCfgRegs.XTALCR.bit.OSCOFF = 0; // Turn on XTALOSC
|
|
ClkCfgRegs.XTALCR.bit.SE = 0; // Select crystal mode
|
|
EDIS;
|
|
|
|
//
|
|
// Wait for the X1 clock to saturate
|
|
//
|
|
PollX1Counter();
|
|
|
|
//
|
|
// Select XTAL as the oscillator source
|
|
//
|
|
EALLOW;
|
|
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1;
|
|
EDIS;
|
|
|
|
//
|
|
// If a missing clock failure was detected, try waiting for the X1 counter
|
|
// to saturate again. Consider modifying this code to add a 10ms timeout.
|
|
//
|
|
while(ClkCfgRegs.MCDCR.bit.MCLKSTS != 0)
|
|
{
|
|
EALLOW;
|
|
ClkCfgRegs.MCDCR.bit.MCLKCLR = 1;
|
|
EDIS;
|
|
|
|
//
|
|
// Wait for the X1 clock to saturate
|
|
//
|
|
PollX1Counter();
|
|
|
|
//
|
|
// Select XTAL as the oscillator source
|
|
//
|
|
EALLOW;
|
|
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1;
|
|
EDIS;
|
|
}
|
|
}
|
|
//
|
|
// SysXtalOscSESel - This function switches to external oscillator in
|
|
// single-ended mode and turns off all other clock sources to minimize power
|
|
// consumption. This option may not be available on all device packages
|
|
//
|
|
void
|
|
SysXtalOscSESel (void)
|
|
{
|
|
EALLOW;
|
|
ClkCfgRegs.XTALCR.bit.OSCOFF = 0; // Turn on XTALOSC
|
|
ClkCfgRegs.XTALCR.bit.SE = 1; // Select single-ended mode
|
|
EDIS;
|
|
|
|
//
|
|
// Wait for the X1 clock to saturate
|
|
//
|
|
PollX1Counter();
|
|
|
|
//
|
|
// Select XTALOSC as the oscillator source
|
|
//
|
|
EALLOW;
|
|
ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1;
|
|
EDIS;
|
|
|
|
//
|
|
// If missing clock detected, there is something wrong with the oscillator
|
|
// module.
|
|
//
|
|
if(ClkCfgRegs.MCDCR.bit.MCLKSTS != 0)
|
|
{
|
|
ESTOP0;
|
|
}
|
|
}
|
|
//
|
|
// AuxIntOsc2Sel - This function switches to Internal oscillator 2.
|
|
//
|
|
void AuxIntOsc2Sel(void)
|
|
{
|
|
EALLOW;
|
|
ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0; // Clk Src = INTOSC2
|
|
EDIS;
|
|
}
|
|
|
|
//
|
|
// AuxXtalOscSel - This function switches to External CRYSTAL oscillator in
|
|
// crystal mode.
|
|
//
|
|
void AuxXtalOscSel(void)
|
|
{
|
|
EALLOW;
|
|
ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
|
|
ClkCfgRegs.XTALCR.bit.SE = 0; // Select crystal mode
|
|
PollX1Counter(); // Wait for the X1 clock to saturate
|
|
ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1; // Clk Src = XTAL
|
|
EDIS;
|
|
}
|
|
|
|
//
|
|
// AuxXtalOscSESel - This function switches to External CRYSTAL oscillator in
|
|
// single-ended mode.
|
|
//
|
|
void AuxXtalOscSESel(void)
|
|
{
|
|
EALLOW;
|
|
ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
|
|
ClkCfgRegs.XTALCR.bit.SE = 1; // Select single-ended mode
|
|
PollX1Counter(); // Wait for the X1 clock to saturate
|
|
ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1; // Clk Src = XTAL
|
|
EDIS;
|
|
}
|
|
//
|
|
// AuxAuxClkSel - 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");
|
|
}
|
|
|
|
#ifdef CPU1
|
|
//
|
|
// IsPLLValid - This function validates PLL Raw Clock Frequency
|
|
//
|
|
bool
|
|
IsPLLValid(Uint32 base, Uint16 oscSource, Uint16 pllclk, Uint16 imult,
|
|
Uint16 odiv, Uint16 refdiv)
|
|
{
|
|
float fclk1_0ratio;
|
|
volatile struct DCC_REGS *DccRegs;
|
|
|
|
EALLOW;
|
|
|
|
//
|
|
// Assigning DCC for PLL validation
|
|
// Enable Peripheral Clock Domain PCLKCR21 for DCC
|
|
//
|
|
if(base == SYSCTL_DCC_BASE0)
|
|
{
|
|
DccRegs = &Dcc0Regs;
|
|
CpuSysRegs.PCLKCR21.bit.DCC0 = 1;
|
|
}
|
|
else if(base == SYSCTL_DCC_BASE1)
|
|
{
|
|
DccRegs = &Dcc1Regs;
|
|
CpuSysRegs.PCLKCR21.bit.DCC1 = 1;
|
|
}
|
|
else if(base == SYSCTL_DCC_BASE2)
|
|
{
|
|
DccRegs = &Dcc2Regs;
|
|
CpuSysRegs.PCLKCR21.bit.DCC2 = 1;
|
|
}
|
|
else
|
|
ESTOP0; // Invalid DCC selected
|
|
|
|
//
|
|
// Clear Error & Done Flag
|
|
//
|
|
DccRegs->DCCSTATUS.bit.ERR = 1;
|
|
DccRegs->DCCSTATUS.bit.DONE = 1;
|
|
|
|
//
|
|
// Disable DCC
|
|
//
|
|
DccRegs->DCCGCTRL.bit.DCCENA = 0x5;
|
|
|
|
//
|
|
// Disable Error Signal
|
|
//
|
|
DccRegs->DCCGCTRL.bit.ERRENA = 0x5;
|
|
|
|
//
|
|
// Disable Done Signal
|
|
//
|
|
DccRegs->DCCGCTRL.bit.DONEENA = 0x5;
|
|
|
|
//
|
|
// Configure Clock Source1 to PLL
|
|
//
|
|
// Clk Src1 Key 0xA to enable clock source selection
|
|
//
|
|
switch(pllclk)
|
|
{
|
|
case INT_PLL_SYSPLL:
|
|
DccRegs->DCCCLKSRC1.all = 0xA000; // Clk Src1 = SYSPLL
|
|
break;
|
|
|
|
case INT_PLL_AUXPLL:
|
|
DccRegs->DCCCLKSRC1.all = 0xA001; // Clk Src1 = AUXPLL
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// Code shouldn't reach here
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Configure Clock Source0 to whatever is set as a reference
|
|
// clock source for PLL
|
|
//
|
|
// Clk Src0 Key 0xA to enable clock source selection
|
|
//
|
|
switch(oscSource)
|
|
{
|
|
case INT_OSC1:
|
|
DccRegs->DCCCLKSRC0.all = 0xA001; // Clk Src0 = INTOSC1
|
|
break;
|
|
|
|
case INT_OSC2:
|
|
DccRegs->DCCCLKSRC0.all = 0xA002; // Clk Src0 = INTOSC2
|
|
break;
|
|
|
|
case XTAL_OSC:
|
|
case XTAL_OSC_SE:
|
|
DccRegs->DCCCLKSRC0.all = 0xA000; // Clk Src0 = XTAL
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// Code shouldn't reach here
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Calculating frequency ratio of output clock(f1) vs reference clock(f0)
|
|
//
|
|
fclk1_0ratio = (float)imult / ((odiv + 1U) * (refdiv + 1));
|
|
|
|
//
|
|
// Computing and configuring Counter0 , Counter1 & Valid Seed Values
|
|
// with +/-1% tolerance for the desired DCC
|
|
//
|
|
ComputeCntrSeedValue(base, fclk1_0ratio, DCC_COUNTER0_TOLERANCE);
|
|
|
|
//
|
|
// Enable Single Shot Mode
|
|
//
|
|
DccRegs->DCCGCTRL.bit.SINGLESHOT = 0xA;
|
|
|
|
//
|
|
// Enable DCC to start counting
|
|
//
|
|
DccRegs->DCCGCTRL.bit.DCCENA = 0xA;
|
|
EDIS;
|
|
|
|
//
|
|
// Wait until Error or Done Flag is generated
|
|
//
|
|
while((DccRegs->DCCSTATUS.all & 3) == 0)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Returns true if DCC completes without error
|
|
//
|
|
return((DccRegs->DCCSTATUS.all & 3) == 2);
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// ComputeCntSeedValid - Compute Counter seed values based on the frequency ratio of output
|
|
// clock vs reference clock & tolerance expected for the desired DCC
|
|
//
|
|
//*****************************************************************************
|
|
void ComputeCntrSeedValue(Uint32 base, float fclk1_0ratio, Uint32 tolerance)
|
|
{
|
|
Uint32 window, dccCounterSeed0, dccValidSeed0, dccCounterSeed1, total_error;
|
|
volatile struct DCC_REGS *DccRegs;
|
|
|
|
if(fclk1_0ratio >= 1U)
|
|
{
|
|
//
|
|
// Setting Counter0 & Valid Seed Value with expected tolerance
|
|
// Total error is 12
|
|
//
|
|
window = (12U * 100U) / tolerance;
|
|
dccCounterSeed0 = window - 12U;
|
|
dccValidSeed0 = 24U;
|
|
|
|
}
|
|
else
|
|
{
|
|
total_error = (((Uint32)2U / fclk1_0ratio) + (Uint32)10U);
|
|
|
|
window = ((total_error * 100U)/ tolerance);
|
|
|
|
//
|
|
// Setting Counter0 & Valid Seed Value with expected tolerance
|
|
//
|
|
dccCounterSeed0 = window - total_error;
|
|
dccValidSeed0 = (Uint32)2U * total_error;
|
|
|
|
}
|
|
|
|
//
|
|
// Multiplying Counter-0 window with PLL Integer Multiplier
|
|
//
|
|
dccCounterSeed1 = window * fclk1_0ratio;
|
|
|
|
//
|
|
// Assigning DCC for PLL validation
|
|
//
|
|
if(base == SYSCTL_DCC_BASE0)
|
|
DccRegs = &Dcc0Regs;
|
|
else if(base == SYSCTL_DCC_BASE1)
|
|
DccRegs = &Dcc1Regs;
|
|
else if(base == SYSCTL_DCC_BASE2)
|
|
DccRegs = &Dcc2Regs;
|
|
else
|
|
ESTOP0; // Invalid DCC selected
|
|
|
|
//
|
|
// Configure COUNTER-0, COUNTER-1 & Valid Window
|
|
//
|
|
DccRegs->DCCCNTSEED0.bit.COUNTSEED0 = dccCounterSeed0; // Loaded Counter0 Value
|
|
DccRegs->DCCVALIDSEED0.bit.VALIDSEED = dccValidSeed0; // Loaded Valid Value
|
|
DccRegs->DCCCNTSEED1.bit.COUNTSEED1 = dccCounterSeed1; // Loaded Counter1 Value
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// End of File
|
|
//
|
|
|