1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276 |
- //###########################################################################
- //
- // 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
- }
|