123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- //###########################################################################
- //
- // FILE: DSP2803x_SysCtrl.c
- //
- // TITLE: DSP2803x Device System Control Initialization & Support Functions.
- //
- // DESCRIPTION:
- //
- // Example initialization of system resources.
- //
- //###########################################################################
- // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V130 $
- // $Release Date: May 8, 2015 $
- // $Copyright: Copyright (C) 2009-2015 Texas Instruments Incorporated -
- // http://www.ti.com/ ALL RIGHTS RESERVED $
- //###########################################################################
- #include "DSP2803x_Device.h" // Headerfile Include File
- #include "DSP2803x_Examples.h" // Examples Include File
- // 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 "ramfuncs" 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, "ramfuncs");
- //---------------------------------------------------------------------------
- // InitSysCtrl:
- //---------------------------------------------------------------------------
- // This function initializes the System Control registers to a known state.
- // - Disables the watchdog
- // - Set the PLLCR for proper SYSCLKOUT frequency
- // - Set the pre-scaler for the high and low frequency peripheral clocks
- // - Enable the clocks to the peripherals
- void InitSysCtrl(void)
- {
- // Disable the watchdog
- DisableDog();
- // *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.
- EALLOW;
- SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // Enable ADC peripheral clock
- (*Device_cal)();
- SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0; // Return ADC clock to original state
- EDIS;
- // Select Internal Oscillator 1 as Clock Source (default), and turn off all unused clocks to
- // conserve power.
- //IntOsc1Sel();
- XtalOscSel();
- // Initialize the PLL control: PLLCR and CLKINDIV
- // DSP28_PLLCR and DSP28_CLKINDIV are defined in DSP2803x_Examples.h
- InitPll(DSP28_PLLCR,DSP28_DIVSEL);
- // Initialize the peripheral clocks
- InitPeripheralClocks();
- }
- //---------------------------------------------------------------------------
- // Example: 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
- #pragma CODE_SECTION(InitFlash,"ramfuncs");
- void InitFlash(void)
- {
- EALLOW;
- //Enable Flash Pipeline mode to improve performance
- //of code executed from Flash.
- FlashRegs.FOPT.bit.ENPIPE = 1;
- // 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.
- //Set the Paged Waitstate for the Flash
- FlashRegs.FBANKWAIT.bit.PAGEWAIT = 2;
- //Set the Random Waitstate for the Flash
- FlashRegs.FBANKWAIT.bit.RANDWAIT = 2;
- //Set the Waitstate for the OTP
- FlashRegs.FOTPWAIT.bit.OTPWAIT = 3;
- // CAUTION
- //ONLY THE DEFAULT VALUE FOR THESE 2 REGISTERS SHOULD BE USED
- FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
- FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
- EDIS;
- //Force a pipeline flush to ensure that the write to
- //the last register configured occurs before returning.
- __asm(" RPT #7 || NOP");
- }
- //---------------------------------------------------------------------------
- // Example: ServiceDog:
- //---------------------------------------------------------------------------
- // This function resets the watchdog timer.
- // Enable this function for using ServiceDog in the application
- void ServiceDog(void)
- {
- EALLOW;
- SysCtrlRegs.WDKEY = 0x0055;
- SysCtrlRegs.WDKEY = 0x00AA;
- EDIS;
- }
- //---------------------------------------------------------------------------
- // Example: DisableDog:
- //---------------------------------------------------------------------------
- // This function disables the watchdog timer.
- void DisableDog(void)
- {
- EALLOW;
- SysCtrlRegs.WDCR= 0x0068;
- EDIS;
- }
- //---------------------------------------------------------------------------
- // Example: InitPll:
- //---------------------------------------------------------------------------
- // This function initializes the PLLCR register.
- void InitPll(Uint16 val, Uint16 divsel)
- {
- volatile Uint16 iVol;
- // Make sure the PLL is not running in limp mode
- if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
- {
- EALLOW;
- // OSCCLKSRC1 failure detected. PLL running in limp mode.
- // Re-enable missing clock logic.
- SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
- EDIS;
- // Replace this line with a call to an appropriate
- // SystemShutdown(); function.
- __asm(" ESTOP0"); // Uncomment for debugging purposes
- }
- // DIVSEL MUST be 0 before PLLCR can be changed from
- // 0x0000. It is set to 0 by an external reset XRSn
- // This puts us in 1/4
- if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
- {
- EALLOW;
- SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
- EDIS;
- }
- // Change the PLLCR
- if (SysCtrlRegs.PLLCR.bit.DIV != val)
- {
- EALLOW;
- // Before setting PLLCR turn off missing clock detect logic
- SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
- SysCtrlRegs.PLLCR.bit.DIV = val;
- EDIS;
- // Optional: Wait for PLL to lock.
- // During this time the CPU will switch to OSCCLK/2 until
- // the PLL is stable. Once the PLL is stable the CPU will
- // switch to the new PLL value.
- //
- // This time-to-lock is monitored by a PLL lock counter.
- //
- // Code is not required to sit and wait for the PLL to lock.
- // However, if the code does anything that is timing critical,
- // and requires the correct clock be locked, then it is best to
- // wait until this switching has completed.
- // Wait for the PLL lock bit to be set.
- // The watchdog should be disabled before this loop, or fed within
- // the loop via ServiceDog().
- // Uncomment to disable the watchdog
- DisableDog();
- while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
- {
- // Uncomment to service the watchdog
- // ServiceDog();
- }
- EALLOW;
- SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
- EDIS;
- }
- // If switching to 1/2
- if((divsel == 1)||(divsel == 2))
- {
- EALLOW;
- SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
- EDIS;
- }
- // If switching to 1/1
- // * First go to 1/2 and let the power settle
- // The time required will depend on the system, this is only an example
- // * Then switch to 1/1
- if(divsel == 3)
- {
- EALLOW;
- SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
- DELAY_US(50L);
- SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
- EDIS;
- }
- }
- //--------------------------------------------------------------------------
- // Example: InitPeripheralClocks:
- //---------------------------------------------------------------------------
- // This function initializes the clocks to the peripheral modules.
- // First the high and low clock prescalers are set
- // Second the clocks are enabled to each peripheral.
- // To reduce power, leave clocks to unused peripherals disabled
- //
- // Note: If a peripherals clock is not enabled then you cannot
- // read or write to the registers for that peripheral
- void InitPeripheralClocks(void)
- {
- EALLOW;
- // LOSPCP prescale register settings, normally it will be set to default values
- //GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // GPIO18 = XCLKOUT
- SysCtrlRegs.LOSPCP.all = 0x0002;
- // XCLKOUT to SYSCLKOUT ratio. By default XCLKOUT = 1/4 SYSCLKOUT
- SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2;
- // Peripheral clock enables set for the selected peripherals.
- // If you are not using a peripheral leave the clock off
- // to save on power.
- //
- // Note: not all peripherals are available on all 2803x derivates.
- // Refer to the datasheet for your particular device.
- //
- // This function is not written to be an example of efficient code.
- SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
- /* SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
- SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1; // COMP1
- SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1; // COMP2
- SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 1; // COMP3
- SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
- SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1; // eCAN-A
- SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
- SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
- SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
- SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3
- SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4
- SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5
- SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
- SysCtrlRegs.PCLKCR1.bit.EPWM7ENCLK = 1; // ePWM7
- SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK = 1; // HRPWM
- SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C
- SysCtrlRegs.PCLKCR0.bit.LINAENCLK = 1; // LIN-A
- SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK = 1; // CLA1
- SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
- SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
- SysCtrlRegs.PCLKCR0.bit.SPIBENCLK = 1; // SPI-B
- SysCtrlRegs.PCLKCR2.bit.HRCAP1ENCLK = 1;
- SysCtrlRegs.PCLKCR2.bit.HRCAP2ENCLK = 1;
- SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM
- */
- EDIS;
- }
- //---------------------------------------------------------------------------
- // Example: CsmUnlock:
- //---------------------------------------------------------------------------
- // This function unlocks the CSM. User must replace 0xFFFF's with current
- // password for the DSP. Returns 1 if unlock is successful.
- #define STATUS_FAIL 0
- #define STATUS_SUCCESS 1
- Uint16 CsmUnlock()
- {
- 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;
- CsmRegs.KEY0 = 0xFFFF;
- CsmRegs.KEY1 = 0xFFFF;
- CsmRegs.KEY2 = 0xFFFF;
- CsmRegs.KEY3 = 0xFFFF;
- CsmRegs.KEY4 = 0xFFFF;
- CsmRegs.KEY5 = 0xFFFF;
- CsmRegs.KEY6 = 0xFFFF;
- CsmRegs.KEY7 = 0xFFFF;
- EDIS;
- // Perform a dummy read of the password locations
- // if they match the key values, the CSM will unlock
- temp = CsmPwl.PSWD0;
- temp = CsmPwl.PSWD1;
- temp = CsmPwl.PSWD2;
- temp = CsmPwl.PSWD3;
- temp = CsmPwl.PSWD4;
- temp = CsmPwl.PSWD5;
- temp = CsmPwl.PSWD6;
- temp = CsmPwl.PSWD7;
- // If the CSM unlocked, return succes, otherwise return
- // failure.
- if (CsmRegs.CSMSCR.bit.SECURE == 0) return STATUS_SUCCESS;
- else return STATUS_FAIL;
- }
- //---------------------------------------------------------------------------
- // Example: IntOsc1Sel:
- //---------------------------------------------------------------------------
- // This function switches to Internal Oscillator 1 and turns off all other clock
- // sources to minimize power consumption
- void IntOsc1Sel (void) {
- EALLOW;
- SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;
- SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL=0; // Clk Src = INTOSC1
- SysCtrlRegs.CLKCTL.bit.XCLKINOFF=1; // Turn off XCLKIN
- SysCtrlRegs.CLKCTL.bit.XTALOSCOFF=1; // Turn off XTALOSC
- SysCtrlRegs.CLKCTL.bit.INTOSC2OFF=1; // Turn off INTOSC2
- EDIS;
- }
- //---------------------------------------------------------------------------
- // Example: IntOsc2Sel:
- //---------------------------------------------------------------------------
- // This function switches to Internal oscillator 2 from External Oscillator
- // and turns off all other clock sources to minimize power consumption
- // NOTE: If there is no external clock connection, when switching from
- // INTOSC1 to INTOSC2, EXTOSC and XLCKIN must be turned OFF prior
- // to switching to internal oscillator 1
- void IntOsc2Sel (void) {
- EALLOW;
- SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 0; // Turn on INTOSC2
- SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 1; // Switch to INTOSC2
- SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1; // Turn off XCLKIN
- SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1; // Turn off XTALOSC
- SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1; // Switch to Internal Oscillator 2
- SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; // Clock Watchdog off of INTOSC1
- SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; // Leave INTOSC1 on
- EDIS;
- }
- //---------------------------------------------------------------------------
- // Example: XtalOscSel:
- //---------------------------------------------------------------------------
- // This function switches to External CRYSTAL oscillator and turns off all other clock
- // sources to minimize power consumption. This option may not be available on all
- // device packages
- void XtalOscSel (void) {
- EALLOW;
- SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 0; // Turn on XTALOSC
- // DELAY_US(1000L); // 1mS delay to ensure crystal
- // oscillator is up and running.
- // Adjust as needed.
- SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1; // Turn off XCLKIN
- SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0; // Switch to external clock
- SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1; // Switch from INTOSC1 to INTOSC2/ext clk
- SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; // Clock Watchdog off of INTOSC1
- SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1; // Turn off INTOSC2
- SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; // Leave INTOSC1 on
- EDIS;
- }
- //---------------------------------------------------------------------------
- // Example: ExtOscSel:
- //---------------------------------------------------------------------------
- // This function switches to External oscillator and turns off all other clock
- // sources to minimize power consumption.
- void ExtOscSel (void) {
- EALLOW;
- SysCtrlRegs.XCLK.bit.XCLKINSEL = 1; // 1-GPIO19 = XCLKIN, 0-GPIO38 = XCLKIN
- SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1; // Turn on XTALOSC
- SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 0; // Turn on XCLKIN
- SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0; // Switch to external clock
- SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1; // Switch from INTOSC1 to INTOSC2/ext clk
- SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; // Clock Watchdog off of INTOSC1
- SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1; // Turn off INTOSC2
- SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; // Leave INTOSC1 on
- EDIS;
- }
- void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr)
- {
- while(SourceAddr < SourceEndAddr)
- {
- *DestAddr++ = *SourceAddr++;
- }
- return;
- }
- //===========================================================================
- // End of file.
- //===========================================================================
|