//########################################################################### // // FILE: sysctl.c // // TITLE: Stellaris style wrapper driver for F2837x system control. // //########################################################################### // $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. // $ //########################################################################### //***************************************************************************** // //! \addtogroup sysctl_api //! @{ // //***************************************************************************** #include "F28x_Project.h" #include #include #include "inc/hw_types.h" #include "driverlib/debug.h" #include "driverlib/sysctl.h" //***************************************************************************** // //! \internal //! Checks a peripheral identifier. //! //! \param ui32Peripheral is the peripheral identifier. //! //! This function determines if a peripheral identifier is valid. //! //! \return Returns \b true if the peripheral identifier is valid and \b false //! otherwise. // //***************************************************************************** #ifdef DEBUG static bool _SysCtlPeripheralValid(uint32_t ui32Peripheral) { return((ui32Peripheral == SYSCTL_PERIPH_CLA1) || (ui32Peripheral == SYSCTL_PERIPH_DMA) || (ui32Peripheral == SYSCTL_PERIPH_TIMER0) || (ui32Peripheral == SYSCTL_PERIPH_TIMER1) || (ui32Peripheral == SYSCTL_PERIPH_TIMER2) || (ui32Peripheral == SYSCTL_PERIPH_HRPWM) || (ui32Peripheral == SYSCTL_PERIPH_TBCLKSYNC) || (ui32Peripheral == SYSCTL_PERIPH_GTBCLKSYNC) || (ui32Peripheral == SYSCTL_PERIPH_EMIF1) || (ui32Peripheral == SYSCTL_PERIPH_EMIF2) || (ui32Peripheral == SYSCTL_PERIPH_EPWM1) || (ui32Peripheral == SYSCTL_PERIPH_EPWM2) || (ui32Peripheral == SYSCTL_PERIPH_EPWM3) || (ui32Peripheral == SYSCTL_PERIPH_EPWM4) || (ui32Peripheral == SYSCTL_PERIPH_EPWM5) || (ui32Peripheral == SYSCTL_PERIPH_EPWM6) || (ui32Peripheral == SYSCTL_PERIPH_EPWM7) || (ui32Peripheral == SYSCTL_PERIPH_EPWM8) || (ui32Peripheral == SYSCTL_PERIPH_EPWM9) || (ui32Peripheral == SYSCTL_PERIPH_EPWM10) || (ui32Peripheral == SYSCTL_PERIPH_EPWM11) || (ui32Peripheral == SYSCTL_PERIPH_EPWM12) || (ui32Peripheral == SYSCTL_PERIPH_ECAP1) || (ui32Peripheral == SYSCTL_PERIPH_ECAP2) || (ui32Peripheral == SYSCTL_PERIPH_ECAP3) || (ui32Peripheral == SYSCTL_PERIPH_ECAP4) || (ui32Peripheral == SYSCTL_PERIPH_ECAP5) || (ui32Peripheral == SYSCTL_PERIPH_ECAP6) || (ui32Peripheral == SYSCTL_PERIPH_EQEP1) || (ui32Peripheral == SYSCTL_PERIPH_EQEP2) || (ui32Peripheral == SYSCTL_PERIPH_EQEP3) || (ui32Peripheral == SYSCTL_PERIPH_SD1) || (ui32Peripheral == SYSCTL_PERIPH_SD2) || (ui32Peripheral == SYSCTL_PERIPH_SCI1) || (ui32Peripheral == SYSCTL_PERIPH_SCI2) || (ui32Peripheral == SYSCTL_PERIPH_SCI3) || (ui32Peripheral == SYSCTL_PERIPH_SCI4) || (ui32Peripheral == SYSCTL_PERIPH_SPI1) || (ui32Peripheral == SYSCTL_PERIPH_SPI2) || (ui32Peripheral == SYSCTL_PERIPH_SPI3) || (ui32Peripheral == SYSCTL_PERIPH_I2C1) || (ui32Peripheral == SYSCTL_PERIPH_I2C2) || (ui32Peripheral == SYSCTL_PERIPH_CAN1) || (ui32Peripheral == SYSCTL_PERIPH_CAN2) || (ui32Peripheral == SYSCTL_PERIPH_MCBSP1) || (ui32Peripheral == SYSCTL_PERIPH_MCBSP2) || (ui32Peripheral == SYSCTL_PERIPH_UPP1) || (ui32Peripheral == SYSCTL_PERIPH_ADC1) || (ui32Peripheral == SYSCTL_PERIPH_ADC2) || (ui32Peripheral == SYSCTL_PERIPH_ADC3) || (ui32Peripheral == SYSCTL_PERIPH_ADC4) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS1) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS2) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS3) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS4) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS5) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS6) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS7) || (ui32Peripheral == SYSCTL_PERIPH_CMPSS8) || (ui32Peripheral == SYSCTL_PERIPH_BUFFDAC1) || (ui32Peripheral == SYSCTL_PERIPH_BUFFDAC2) || (ui32Peripheral == SYSCTL_PERIPH_BUFFDAC3)); } #endif //***************************************************************************** // //! Determines if a peripheral is present. //! //! \param ui32Peripheral is the peripheral in question. //! //! This function determines if a particular peripheral is present in the //! device. Each member of the family has a different peripheral //! set; this function determines which peripherals are present on this device. //! //! \return Returns \b true if the specified peripheral is present and \b false //! if it is not. // //***************************************************************************** bool SysCtlPeripheralPresent(uint32_t ui32Peripheral) { uint16_t regIndex; uint16_t bitIndex; // // Check the arguments. // ASSERT(_SysCtlPeripheralValid(ui32Peripheral)); regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M; bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S; if(HWREG(&(DevCfgRegs.DC0.all) + (2 * regIndex)) & (1 << bitIndex)){ return true; }else{ return false; } } //***************************************************************************** // //! Determines if a peripheral is ready. //! //! \param ui32Peripheral is the peripheral in question. //! //! This function determines if a particular peripheral is ready to be //! accessed. The peripheral may be in a non-ready state if it is not enabled, //! is being held in reset, or is in the process of becoming ready after being //! enabled or taken out of reset. //! //! \note The ability to check for a peripheral being ready varies based on the //! part in use. Please consult the data sheet for the part you are //! using to determine if this feature is available. //! //! \return Returns \b true if the specified peripheral is ready and \b false //! if it is not. // //***************************************************************************** bool SysCtlPeripheralReady(uint32_t ui32Peripheral) { uint16_t regIndex; uint16_t bitIndex; // // Check the arguments. // ASSERT(_SysCtlPeripheralValid(ui32Peripheral)); regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M; bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S; // Is the peripheral there? if(HWREG((uint32_t)&(DevCfgRegs.DC0.all) + (2 * regIndex)) & ((uint32_t)1 << bitIndex)){ // Is the peripheral enabled? if(HWREG((uint32_t)&(CpuSysRegs.PCLKCR0.all) + (2 * regIndex)) & ((uint32_t)1 << bitIndex)){ // Is the peripheral in reset? if((HWREG((uint32_t)&(DevCfgRegs.SOFTPRES0.all) + (2 * regIndex)) & ((uint32_t)1 << bitIndex)) == 0){ // No? Ok cool return true; } } }else{ return false; } return false; } //***************************************************************************** // //! Resets a peripheral //! //! \param ui32Peripheral is the peripheral to reset. //! //! The f2837x devices do not have a means of resetting peripherals via //! via software. This is a dummy function that does nothing. //! //! //! \return None. // //***************************************************************************** void SysCtlPeripheralReset(uint32_t ui32Peripheral) { uint16_t regIndex; uint16_t bitIndex; regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M; bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S; EALLOW; HWREG((uint32_t)&(DevCfgRegs.SOFTPRES0.all) + (2 * regIndex)) |= ((uint32_t)1 << bitIndex); asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop"); HWREG((uint32_t)&(DevCfgRegs.SOFTPRES0.all) + (2 * regIndex)) &= ~((uint32_t)1 << bitIndex); EDIS; } //***************************************************************************** // //! Enables a peripheral. //! //! \param ui32Peripheral is the peripheral to enable. //! //! Peripherals are enabled with this function. At power-up, all peripherals //! are disabled; they must be enabled in order to operate or respond to //! register reads/writes. //! //! The \e ui32Peripheral parameter must be only one of the following values: //! \b SYSCTL_PERIPH_UART_A, \b SYSCTL_PERIPH_UART_B, \b SYSCTL_PERIPH_UART_C, //! \b SYSCTL_PERIPH_UART_D, \b SYSCTL_PERIPH_SPI_A, \b SYSCTL_PERIPH_SPI_B, //! \b SYSCTL_PERIPH_SPI_C, \b SYSCTL_PERIPH_MCBSP_A, \b SYSCTL_PERIPH_MCBSP_B, //! \b SYSCTL_PERIPH_DMA, \b SYSCTL_PERIPH_USB_A //! //! \return None. // //***************************************************************************** void SysCtlPeripheralEnable(uint32_t ui32Peripheral) { uint16_t regIndex; uint16_t bitIndex; volatile uint32_t test1, test2, test3, test4; regIndex = (ui32Peripheral & SYSCTL_PERIPH_REG_M); bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S; EALLOW; HWREG((uint32_t)&(CpuSysRegs.PCLKCR0.all) + (2 * regIndex)) |= ((uint32_t)1 << bitIndex); EDIS; } //***************************************************************************** // //! Disables a peripheral. //! //! \param ui32Peripheral is the peripheral to disable. //! //! Peripherals are disabled with this function. Once disabled, they will not //! operate or respond to register reads/writes. //! //! The \e ui32Peripheral parameter must be only one of the following values: //! \b SYSCTL_PERIPH_UART_A, \b SYSCTL_PERIPH_UART_B, \b SYSCTL_PERIPH_UART_C, //! \b SYSCTL_PERIPH_UART_D, \b SYSCTL_PERIPH_SPI_A, \b SYSCTL_PERIPH_SPI_B, //! \b SYSCTL_PERIPH_SPI_C, \b SYSCTL_PERIPH_MCBSP_A, \b SYSCTL_PERIPH_MCBSP_B, //! \b SYSCTL_PERIPH_DMA, \b SYSCTL_PERIPH_USB_A //! //! \return None. // //***************************************************************************** void SysCtlPeripheralDisable(uint32_t ui32Peripheral) { uint16_t regIndex; uint16_t bitIndex; regIndex = ui32Peripheral & SYSCTL_PERIPH_REG_M; bitIndex = (ui32Peripheral & SYSCTL_PERIPH_BIT_M) >> SYSCTL_PERIPH_BIT_S; EALLOW; HWREG((uint32_t)&(CpuSysRegs.PCLKCR0.all) + (2 * regIndex)) &= ~((uint32_t)1 << bitIndex); EDIS; } //***************************************************************************** // //! Resets the device. //! //! This function performs a software reset of the entire device. The //! processor and all peripherals are reset and all device registers are //! returned to their default values (with the exception of the reset cause //! register, which maintains its current value but has the software reset //! bit set as well). //! //! \return This function does not return. // //***************************************************************************** void SysCtlReset(void) { // // Write an incorrect check value to the watchdog control register // This will cause a device reset // EALLOW; // Enable the watchdog HWREG(&(WdRegs.WDCR.all)) = 0x0028; // Write a bad check value HWREG(&(WdRegs.WDCR.all)) = 0xFFFF; EDIS; // // The device should have reset, so this should never be reached. Just in // case, loop forever. // while(1) { } } //***************************************************************************** // //! Provides a small delay. //! //! \param ulCount is the number of delay loop iterations to perform. //! //! This function provides a means of generating a constant length delay. It //! is written in assembly to keep the delay consistent across tool chains, //! avoiding the need to tune the delay based on the tool chain in use. //! //! The loop takes 5 cycles/loop + 9. //! //! \return None. // //***************************************************************************** #ifdef __TI_COMPILER_VERSION__ #if __TI_COMPILER_VERSION__ >= 15009000 __asm(" .def _SysCtlDelay\n" " .sect \".TI.ramfunc\"\n" " .global _SysCtlDelay\n" "_SysCtlDelay:\n" " SUB ACC,#1\n" " BF _SysCtlDelay,GEQ\n" " LRETR\n"); #else __asm(" .def _SysCtlDelay\n" " .sect \"ramfuncs\"\n" " .global _SysCtlDelay\n" "_SysCtlDelay:\n" " SUB ACC,#1\n" " BF _SysCtlDelay,GEQ\n" " LRETR\n"); #endif #endif //***************************************************************************** // //! Gets the processor clock rate. //! //! This function determines the clock rate of the processor clock. //! //! \note Because of the many different clocking options available, this //! function cannot determine the clock speed of the processor. This function //! should be modified to return the actual clock speed of the processor in //! your specific application. //! //! \return The processor clock rate. // //***************************************************************************** uint32_t SysCtlClockGet(uint32_t u32ClockIn) { if((ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL == 0) || (ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL == 2)){ //10MHz Internal Clock u32ClockIn = 10000000; } //If the pll is enabled calculate its effect on the clock // if((HWREG(SYSCTL_SYSPLLCTL) & // (SYSCTL_SYSPLLCTL_SPLLEN | SYSCTL_SYSPLLCTL_SPLLCLKEN)) == 3) if(ClkCfgRegs.SYSPLLCTL1.bit.PLLEN && ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN) { //Calculate integer multiplier and fixed divide by 2 // ulClockIn = ulClockIn * // (HWREG(SYSCTL_SYSPLLMULT) & SYSCTL_SYSPLLMULT_SPLLIMULT_M); u32ClockIn = u32ClockIn * ClkCfgRegs.SYSPLLMULT.bit.IMULT; //Calculate fractional multiplier // switch((HWREG(SYSCTL_SYSPLLMULT) & SYSCTL_SYSPLLMULT_SPLLFMULT_M) >> // SYSCTL_SYSPLLMULT_SPLLFMULT_S) switch(ClkCfgRegs.SYSPLLMULT.bit.FMULT) { default: case 0: break; case 1: u32ClockIn += u32ClockIn / 4; break; case 2: u32ClockIn += u32ClockIn / 2; break; case 3: u32ClockIn += (u32ClockIn * 3) / 4; break; } } if(ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV != 0){ u32ClockIn /= (2 * ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV); } return u32ClockIn; } //***************************************************************************** // //! Gets the low speed peripheral clock rate. //! //! This function determines the clock rate of the low speed peripherals. //! //! \note Because of the many different clocking options available, this //! function cannot determine the clock speed of the processor. This function //! should be modified to return the actual clock speed of the processor in //! your specific application. //! //! \return The low speed peripheral clock rate. // //***************************************************************************** uint32_t SysCtlLowSpeedClockGet(uint32_t u32ClockIn) { // Get the main system clock u32ClockIn = SysCtlClockGet(u32ClockIn); // Apply the divider to the main clock if(ClkCfgRegs.LOSPCP.bit.LSPCLKDIV != 0){ u32ClockIn /= (2 * ClkCfgRegs.LOSPCP.bit.LSPCLKDIV); } return u32ClockIn; } //***************************************************************************** // //! Sets the clocking of the device. //! //! \param ui32Config is the required configuration of the device clocking. //! //! This function configures the clocking of the device. The oscillator to be //! used, SYSPLL fractional and integer multiplier, and the system clock //! divider are all configured with this function. //! //! The \e ui32Config parameter is the logical OR of four values: //! Clock divider, Integer multiplier, Fractional multiplier, and oscillator //! source. //! //! The system clock divider is chosen with using the following macro: //! \b SYSCTL_SYSDIV(x) - "x" is an integer of value 1 or any even value //! up to 126 //! //! The System PLL fractional multiplier is chosen with one of the following //! values: //! \b SYSCTL_FMULT_0, \b SYSCTL_FMULT_1_4, \b SYSCTL_FMULT_1_2, //! \b SYSCTL_FMULT_3_4 //! //! The System PLL integer multiplier is chosen with using the following macro: //! \b SYSCTL_IMULT(x) - "x" is an integer from 0 to 127 //! //! The oscillator source is chosen with one of the following values: //! \b SYSCTL_OSCSRC_OSC2, \b SYSCTL_OSCSRC_XTAL, \b SYSCTL_OSCSRC_OSC1 //! //! \note The external oscillator must be enabled in order to use an external //! clock source. Note that attempts to disable the oscillator used to clock //! the device is prevented by the hardware. //! //! \return None. // //***************************************************************************** void SysCtlClockSet(uint32_t ui32Config) { uint32_t clock_source = (ui32Config & SYSCTL_OSCSRC_M) >> SYSCTL_OSCSRC_S; uint32_t imult = (ui32Config & SYSCTL_IMULT_M); uint32_t fmult = (ui32Config & SYSCTL_FMULT_M) >> SYSCTL_FMULT_S; uint32_t divsel = (ui32Config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S; 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) { //Configure Oscillator EALLOW; switch (clock_source) { case ((uint32_t)SYSCTL_OSCSRC_OSC2 >> SYSCTL_OSCSRC_S): ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // Turn on INTOSC2 ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // Clk Src = INTOSC2 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC break; case ((uint32_t)SYSCTL_OSCSRC_XTAL >> SYSCTL_OSCSRC_S): ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // Clk Src = XTAL break; case ((uint32_t)SYSCTL_OSCSRC_OSC1 >> SYSCTL_OSCSRC_S): ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 2; // Clk Src = INTOSC1 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC break; } EDIS; } EALLOW; // first modify the PLL multipliers if(imult != ClkCfgRegs.SYSPLLMULT.bit.IMULT || fmult != ClkCfgRegs.SYSPLLMULT.bit.FMULT) { // Bypass PLL and set dividers to /1 ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0; ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0; // Program PLL multipliers uint32_t temp_syspllmult = ClkCfgRegs.SYSPLLMULT.all; ClkCfgRegs.SYSPLLMULT.all = ((temp_syspllmult & ~(0x37FU)) | ((fmult << 8U) | imult)); ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 1; // Enable SYSPLL // Wait for the SYSPLL lock while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1) { // Uncomment to service the watchdog //WdRegs.WDKEY.bit.WDKEY = 0x0055; //WdRegs.WDKEY.bit.WDKEY = 0x00AA; } // Write a multiplier again to ensure proper PLL initialization // This will force the PLL to lock a second time ClkCfgRegs.SYSPLLMULT.bit.IMULT = imult; // Setting integer multiplier // Wait for the SYSPLL re-lock while(ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1) { // Uncomment to service the watchdog //WdRegs.WDKEY.bit.WDKEY = 0x0055; //WdRegs.WDKEY.bit.WDKEY = 0x00AA; } } // Set divider to produce slower output frequency to limit current increase if(divsel != (126/2)) { 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; } //***************************************************************************** // //! Sets the clocking of the device. //! //! \param ui32Config is the required configuration of the device clocking. //! //! This function configures the clocking of the device. The input crystal //! frequency, oscillator to be used, use of the PLL, and the system clock //! divider are all configured with this function. //! //! The \e ui32Config parameter is the logical OR of several different values, //! many of which are grouped into sets where only one can be chosen. //! //! The system clock divider is chosen with one of the following values: //! \b SYSCTL_SYSDIV_1, \b SYSCTL_SYSDIV_2, \b SYSCTL_SYSDIV_3, ... //! \b SYSCTL_SYSDIV_64. //! //! The use of the PLL is chosen with either \b SYSCTL_USE_PLL or //! \b SYSCTL_USE_OSC. //! //! The external crystal frequency is chosen with one of the following values: //! \b SYSCTL_XTAL_4MHZ, \b SYSCTL_XTAL_4_09MHZ, \b SYSCTL_XTAL_4_91MHZ, //! \b SYSCTL_XTAL_5MHZ, \b SYSCTL_XTAL_5_12MHZ, \b SYSCTL_XTAL_6MHZ, //! \b SYSCTL_XTAL_6_14MHZ, \b SYSCTL_XTAL_7_37MHZ, \b SYSCTL_XTAL_8MHZ, //! \b SYSCTL_XTAL_8_19MHZ, \b SYSCTL_XTAL_10MHZ, \b SYSCTL_XTAL_12MHZ, //! \b SYSCTL_XTAL_12_2MHZ, \b SYSCTL_XTAL_13_5MHZ, \b SYSCTL_XTAL_14_3MHZ, //! \b SYSCTL_XTAL_16MHZ, \b SYSCTL_XTAL_16_3MHZ, \b SYSCTL_XTAL_18MHZ, //! \b SYSCTL_XTAL_20MHZ, \b SYSCTL_XTAL_24MHZ, or \b SYSCTL_XTAL_25MHz. //! Values below \b SYSCTL_XTAL_5MHZ are not valid when the PLL is in //! operation. //! //! The oscillator source is chosen with one of the following values: //! \b SYSCTL_OSC_MAIN, \b SYSCTL_OSC_INT, \b SYSCTL_OSC_INT4, //! \b SYSCTL_OSC_INT30, or \b SYSCTL_OSC_EXT32. \b SYSCTL_OSC_EXT32 is only //! available on devices with the hibernate module, and then only when the //! hibernate module has been enabled. //! //! The internal and main oscillators are disabled with the //! \b SYSCTL_INT_OSC_DIS and \b SYSCTL_MAIN_OSC_DIS flags, respectively. //! The external oscillator must be enabled in order to use an external clock //! source. Note that attempts to disable the oscillator used to clock the //! device is prevented by the hardware. //! //! To clock the system from an external source (such as an external crystal //! oscillator), use \b SYSCTL_USE_OSC \b | \b SYSCTL_OSC_MAIN. To clock the //! system from the main oscillator, use \b SYSCTL_USE_OSC \b | //! \b SYSCTL_OSC_MAIN. To clock the system from the PLL, use //! \b SYSCTL_USE_PLL \b | \b SYSCTL_OSC_MAIN, and select the appropriate //! crystal with one of the \b SYSCTL_XTAL_xxx values. //! //! \note If selecting the PLL as the system clock source (that is, via //! \b SYSCTL_USE_PLL), this function polls the PLL lock interrupt to //! determine when the PLL has locked. If an interrupt handler for the //! system control interrupt is in place, and it responds to and clears the //! PLL lock interrupt, this function delays until its timeout has occurred //! instead of completing as soon as PLL lock is achieved. //! //! \return None. // //***************************************************************************** void SysCtlAuxClockSet(uint32_t ui32Config) { uint16_t ui16TempDivsel; //Bypass PLL //Ensure the PLL is out of our clock tree EALLOW; ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0; EDIS; __asm( " RPT #255 || NOP"); //Configure Oscillator EALLOW; switch (ui32Config & SYSCTL_OSCSRC_M) { default: case SYSCTL_OSCSRC_OSC2: ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // Turn on INTOSC2 ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0; // Clk Src = INTOSC2 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC break; case SYSCTL_OSCSRC_XTAL: ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 1; // Clk Src = XTAL break; case SYSCTL_OSCSRC_OSC1: ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 2; // Clk Src = INTOSC1 ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=1; // Turn off XTALOSC break; } EDIS; __asm( " RPT #255 || NOP"); //Configure PLL if enabled if(ui32Config & SYSCTL_PLL_ENABLE) { EALLOW; //modify dividers to maximum to reduce the inrush current //set the integer fractional multipliers in one single write ClkCfgRegs.AUXPLLMULT.all = ((ui32Config & SYSCTL_IMULT_M) >> SYSCTL_IMULT_S) | (((ui32Config & SYSCTL_FMULT_M) >> SYSCTL_FMULT_S) << 8); EDIS; __asm( " RPT #255 || NOP"); //Wait for the SYSPLL lock while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1) { // Uncomment to service the watchdog // ServiceDog(); } } //Configure Dividers //increase the freq. of operation in steps to avoid any VDD fluctuations ui16TempDivsel = 3; while(ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV != ((ui32Config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S)) { EALLOW; ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = ui16TempDivsel; EDIS; ui16TempDivsel -= 1; if(ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV != ((ui32Config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S)) { SysCtlDelay(15); } } //Enable PLLSYSCLK is fed from system PLL clock EALLOW; ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1; EDIS; } //***************************************************************************** // //! Powers up the USB PLL. //! //! This function will enable the USB controller's PLL. //! //! \note Because every application is different, the user will likely have to //! modify this function to ensure the PLL multiplier is set correctly to //! achieve the 60 MHz required by the USB controller. //! //! \return None. // //***************************************************************************** void SysCtlUSBPLLEnable(void) { // // Turn on INTOSC2 // ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // //Select INTOSC2 as USB PLL Clk In // ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0; // // Set Aux PLL divider // ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = 1; // // Set Aux PLL multiplier // ClkCfgRegs.AUXPLLMULT.bit.IMULT = 12; // // Set Aux PLL fractional multiplier to 0.0 // ClkCfgRegs.AUXPLLMULT.bit.FMULT = 0; // //Enable AUXPLL // ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 1; // // //Wait for the AUXPLL lock // while(ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1) // { // // Uncomment to service the watchdog // // ServiceDog(); // } // // AUXPLLCLK is fed from the AUXPLL // ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1; } //***************************************************************************** // //! Powers down the USB PLL. //! //! This function will disable the USB controller's PLL. The USB registers //! are still accessible, but the physical layer will no longer function. //! //! \return None. // //***************************************************************************** void SysCtlUSBPLLDisable(void) { //Disable the PLL // ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0; } //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************