/**************************************************************************//** * @file system_TM4C123GH6PM.c * @brief CMSIS Device System Source File for * Texas Instruments TIVA TM4C123 Device Series * @version V1.00 * @date 27. March 2013 * * @note * modified by Keil ******************************************************************************/ #include #include "TM4C123GH6PM.h" /*---------------------------------------------------------------------------- DEFINES *----------------------------------------------------------------------------*/ //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ // // This file can be used by the Keil uVision configuration wizard to set // the following system clock configuration values. Or the value of the // macros can be directly edited below if not using the uVision configuration // wizard. // //--------------------- Clock Configuration ---------------------------------- // // Clock Configuration // Uncheck this box to skip the clock configuration. // // The following controls whether the system clock is configured in the // SystemInit() function. If it is defined to be 1 then the system clock // will be configured according to the macros in the rest of this file. // If it is defined to be 0, then the system clock configuration is bypassed. // #define CLOCK_SETUP 1 //********************************* RCC *************************************** // // Run-Mode Clock Configuration (RCC) // SYSDIV: System Clock Divisor <2-16> // Specifies the divisor used to generate the system clock from // either the PLL output of 200 MHz, or the chosen oscillator. // // The following value is the system clock divisor. This will be applied if // USESYSDIV (see below) is enabled. The valid range of dividers is 2-16. // #define CFG_RCC_SYSDIV 4 // USESYSDIV: Enable System Clock Divider // Check this box to use the System Clock Divider // // The following controls whether the system clock divider is used. If the // value is 1, then the system clock divider is used, and the value of the // system divider is defined by SYSDIV (see above). If the value is 0, then // the system clock divider is not used. // #define CFG_RCC_USESYSDIV 1 // USEPWMDIV: Enable PWM Clock Divider // Check this box to use the PWM Clock Divider // // The following controls whether the PWM clock divider is used. If the // value is 1, then the PWM clock divider is used, and the value of the // PWM divider is defined by PWMDIV (see below). If the value is 0, then // the PWM clock divider is not used. // #define CFG_RCC_USEPWMDIV 1 // PWMDIV: PWM Unit Clock Divisor // <0=> 0: SysClk / 2 // <1=> 1: SysClk / 4 // <2=> 2: SysClk / 8 // <3=> 3: SysClk / 16 // <4=> 4: SysClk / 32 // <5=> 5: SysClk / 64 // <6=> 6: SysClk / 64 // <7=> 7: SysClk / 64 (default) // Specifies the divisor used to generate the PWM time base, // from the System Clock // // The following value determines the PWM clock divider. It is used if // USEPWMDIV is enabled (see above). Otherwise the PWM clock is the same as // the system clock. The value of the divider is determined by the table // above. // #define CFG_RCC_PWMDIV 7 // PWRDN: PLL Power Down // Check this box to disable the PLL. You must also choose // PLL Bypass. // // If the following value is 1, then the PLL is powered down. Keep this value // as 1 if you do not need to use the PLL. In this case, BYPASS (see below) // must also be set to 1. If you are using the PLL, then this value must be // set to 0. // #define CFG_RCC_PWRDN 0 // BYPASS: PLL Bypass // Check this box to not use the PLL for the System Clock // // Set the following value to 1 to bypass the PLL and not use it for the // system clock. You must set this to 1 if PWRDN (above) is set to 1. Set // this to 0 if you are using the PLL. // #define CFG_RCC_BYPASS 0 // XTAL: Crystal Value // < 0=> 0: 1.0000 MHz (can not be used with PLL) // < 1=> 1: 1.8432 MHz (can not be used with PLL) // < 2=> 2: 2.0000 MHz (can not be used with PLL) // < 3=> 3: 2.4576 MHz (can not be used with PLL) // < 4=> 4: 3.579545 MHz // < 5=> 5: 3.6864 MHz // < 6=> 6: 4.0000 MHz // < 7=> 7: 4.096 MHz // < 8=> 8: 4.9152 MHz // < 9=> 9: 5.0000 MHz // <10=> 10: 5.12 MHz // <11=> 11: 6.0000 MHz (default) // <12=> 12: 6.144 MHz // <13=> 13: 7.3728 MHz // <14=> 14: 8.0000 MHz // <15=> 15: 8.192 MHz // <16=> 16: 10.0 MHz // <17=> 17: 12.0 MHz // <18=> 18: 12.288 MHz // <19=> 19: 13.56 MHz // <20=> 20: 14.31818 MHz // <21=> 21: 16.0 MHz // <22=> 22: 16.384 MHz // This is the crystal frequency used for the main oscillator // // This value defines the crystal frequency for the main oscillator, according // to the table in the comments above. If an external crystal is used, then // this value must be set to match the value of the crystal. // #define CFG_RCC_XTAL 21 // OSCSRC: Oscillator Source // <0=> 0: MOSC Main oscillator // <1=> 1: IOSC Internal oscillator (default) // <2=> 2: IOSC/4 Internal oscillator / 4 (this is necessary if used as input to PLL) // <3=> 3: 30kHz 30-KHz internal oscillator // Chooses the oscillator that is used for the system clock, // or the PLL input. // // The following value chooses the oscillator source according to the table in // the comments above. // #define CFG_RCC_OSCSRC 0 // IOSCDIS: Internal Oscillator Disable // Check this box to turn off the internal oscillator // // Set the following value to 1 to turn off the internal oscillator. This // value can be set to 1 if you are not using the internal oscillator. // #define CFG_RCC_IOSCDIS 1 // MOSCDIS: Main Oscillator Disable // Check this box to turn off the main oscillator // // Set the following value to 1 to turn off the main oscillator. This // value can be set to 1 if you are not using the main oscillator. // #define CFG_RCC_MOSCDIS 0 // //********************************* RCC2 ************************************** // // Run-Mode Clock Configuration 2 (RCC2) // USERCC2: Use RCC2 // Check this box to override some fields in RCC. RCC2 provides // more bits for the system clock divider, and provides an // additional oscillator source. If you do not need these // additional features, then leave this box unchecked. // // Set the following value to 1 to use the RCC2 register. The RCC2 register // overrides some of the fields in the RCC register if it is used. // #define CFG_RCC2_USERCC2 0 // SYSDIV2: System Clock Divisor <2-64> // Specifies the divisor used to generate the system clock from // either the PLL output of 200 MHz, or the oscillator. // // The following value is the system clock divisor. This will be applied if // USESYSDIV in RCC is enabled. The valid range of dividers is 2-64. // #define CFG_RCC_SYSDIV2 4 // PWRDN2: Power Down PLL // Check this box to disable the PLL. You must also choose // PLL Bypass. // // If the following value is 1, then the PLL is powered down. Keep this value // as 1 if you do not need to use the PLL. In this case, BYPASS2 (see below) // must also be set to 1. If you are using the PLL, then this value must be // set to 0. // #define CFG_RCC_PWRDN2 0 // BYPASS2: Bypass PLL // Check this box to not use the PLL for the System Clock // // Set the following value to 1 to bypass the PLL and not use it for the // system clock. You must set this to 1 if PWRDN2 (above) is set to 1. Set // this to 0 if you are using the PLL. // #define CFG_RCC_BYPASS2 0 // OSCSRC2: Oscillator Source // <0=> 0: MOSC Main oscillator // <1=> 1: IOSC Internal oscillator (default) // <2=> 2: IOSC/4 Internal oscillator / 4 (this is necessary if used as input to PLL) // <3=> 3: 30kHz 30-kHz internal oscillator // <7=> 7: 32kHz 32.768-kHz external oscillator // The oscillator that is used for the system clock, or the PLL input. // // The following value chooses the oscillator source according to the table in // the comments above. // #define CFG_RCC_OSCSRC2 0 // // // //-------- <<< end of configuration section >>> ------------------------------ // // The following macros are used to program the RCC and RCC2 registers in // the SystemInit() function. Edit the macros above to change these values. // #define RCC_Val \ ( \ ((CFG_RCC_SYSDIV - 1) << 23) | \ (CFG_RCC_USESYSDIV << 22) | \ (CFG_RCC_USEPWMDIV << 20) | \ (CFG_RCC_PWMDIV << 17) | \ (CFG_RCC_PWRDN << 13) | \ (CFG_RCC_BYPASS << 11) | \ (CFG_RCC_XTAL << 6) | \ (CFG_RCC_OSCSRC << 4) | \ (CFG_RCC_IOSCDIS << 1) | \ (CFG_RCC_MOSCDIS << 1)\ ) #define RCC2_Val \ ( \ (CFG_RCC2_USERCC2 << 31) | \ ((CFG_RCC_SYSDIV2 - 1) << 23) | \ (CFG_RCC_PWRDN2 << 13) | \ (CFG_RCC_BYPASS2 << 11) | \ (CFG_RCC_OSCSRC2 << 4)\ ) /*---------------------------------------------------------------------------- Define clocks *----------------------------------------------------------------------------*/ #define XTALM (16000000UL) /* Main oscillator freq */ #define XTALI (12000000UL) /* Internal oscillator freq */ #define XTAL30K ( 30000UL) /* Internal 30K oscillator freq */ #define XTAL32K ( 32768UL) /* external 32K oscillator freq */ #define PLL_CLK (400000000UL) #define ADC_CLK (PLL_CLK/25) #define CAN_CLK (PLL_CLK/50) /* Determine clock frequency according to clock register values */ #if (RCC2_Val & (1UL<<31)) /* is rcc2 used ? */ #if (RCC2_Val & (1UL<<11)) /* check BYPASS */ #if (((RCC2_Val>>4) & 0x07) == 0x0) #if (((RCC_Val>>6) & 0x1F) == 0x0) #define __CORE_CLK_PRE 1000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x1) #define __CORE_CLK_PRE 1843200UL #elif (((RCC_Val>>6) & 0x1F) == 0x2) #define __CORE_CLK_PRE 2000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x3) #define __CORE_CLK_PRE 2457600UL #elif (((RCC_Val>>6) & 0x1F) == 0x4) #define __CORE_CLK_PRE 3579545UL #elif (((RCC_Val>>6) & 0x1F) == 0x5) #define __CORE_CLK_PRE 3686400UL #elif (((RCC_Val>>6) & 0x1F) == 0x6) #define __CORE_CLK_PRE 4000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x7) #define __CORE_CLK_PRE 4096000UL #elif (((RCC_Val>>6) & 0x1F) == 0x8) #define __CORE_CLK_PRE 4915200UL #elif (((RCC_Val>>6) & 0x1F) == 0x9) #define __CORE_CLK_PRE 5000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xA) #define __CORE_CLK_PRE 5120000UL #elif (((RCC_Val>>6) & 0x1F) == 0xB) #define __CORE_CLK_PRE 6000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xC) #define __CORE_CLK_PRE 6144000UL #elif (((RCC_Val>>6) & 0x1F) == 0xD) #define __CORE_CLK_PRE 7372800UL #elif (((RCC_Val>>6) & 0x1F) == 0xE) #define __CORE_CLK_PRE 8000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xF) #define __CORE_CLK_PRE 8192000UL #elif (((RCC_Val>>6) & 0x1F) == 0x10) #define __CORE_CLK_PRE 10000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x11) #define __CORE_CLK_PRE 12000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x12) #define __CORE_CLK_PRE 12288000UL #elif (((RCC_Val>>6) & 0x1F) == 0x13) #define __CORE_CLK_PRE 13560000UL #elif (((RCC_Val>>6) & 0x1F) == 0x14) #define __CORE_CLK_PRE 14318180UL #elif (((RCC_Val>>6) & 0x1F) == 0x15) #define __CORE_CLK_PRE 16000000UL #else #define __CORE_CLK_PRE 16384000UL #endif #elif (((RCC2_Val>>4) & 0x07) == 0x1) #define __CORE_CLK_PRE XTALI #elif (((RCC2_Val>>4) & 0x07) == 0x2) #define __CORE_CLK_PRE (XTALI/4) #else #define __CORE_CLK_PRE XTAL30K #endif #else #define __CORE_CLK_PRE PLL_CLK #endif #if (RCC_Val & (1UL<<22)) /* check USESYSDIV */ #if (RCC2_Val & (1UL<<11)) #define __CORE_CLK (__CORE_CLK_PRE / (((RCC2_Val>>23) & (0x3F)) + 1)) #else #define __CORE_CLK (__CORE_CLK_PRE / (((RCC2_Val>>23) & (0x3F)) + 1) / 2) #endif #else #define __CORE_CLK __CORE_CLK_PRE #endif #else #if (RCC_Val & (1UL<<11)) /* check BYPASS */ #if (((RCC_Val>>4) & 0x03) == 0x0) #if (((RCC_Val>>6) & 0x1F) == 0x0) #define __CORE_CLK_PRE 1000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x1) #define __CORE_CLK_PRE 1843200UL #elif (((RCC_Val>>6) & 0x1F) == 0x2) #define __CORE_CLK_PRE 2000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x3) #define __CORE_CLK_PRE 2457600UL #elif (((RCC_Val>>6) & 0x1F) == 0x4) #define __CORE_CLK_PRE 3579545UL #elif (((RCC_Val>>6) & 0x1F) == 0x5) #define __CORE_CLK_PRE 3686400UL #elif (((RCC_Val>>6) & 0x1F) == 0x6) #define __CORE_CLK_PRE 4000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x7) #define __CORE_CLK_PRE 4096000UL #elif (((RCC_Val>>6) & 0x1F) == 0x8) #define __CORE_CLK_PRE 4915200UL #elif (((RCC_Val>>6) & 0x1F) == 0x9) #define __CORE_CLK_PRE 5000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xA) #define __CORE_CLK_PRE 5120000UL #elif (((RCC_Val>>6) & 0x1F) == 0xB) #define __CORE_CLK_PRE 6000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xC) #define __CORE_CLK_PRE 6144000UL #elif (((RCC_Val>>6) & 0x1F) == 0xD) #define __CORE_CLK_PRE 7372800UL #elif (((RCC_Val>>6) & 0x1F) == 0xE) #define __CORE_CLK_PRE 8000000UL #elif (((RCC_Val>>6) & 0x1F) == 0xF) #define __CORE_CLK_PRE 8192000UL #elif (((RCC_Val>>6) & 0x1F) == 0x10) #define __CORE_CLK_PRE 10000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x11) #define __CORE_CLK_PRE 12000000UL #elif (((RCC_Val>>6) & 0x1F) == 0x12) #define __CORE_CLK_PRE 12288000UL #elif (((RCC_Val>>6) & 0x1F) == 0x13) #define __CORE_CLK_PRE 13560000UL #elif (((RCC_Val>>6) & 0x1F) == 0x14) #define __CORE_CLK_PRE 14318180UL #elif (((RCC_Val>>6) & 0x1F) == 0x15) #define __CORE_CLK_PRE 16000000UL #else #define __CORE_CLK_PRE 16384000UL #endif #elif (((RCC_Val>>4) & 0x03) == 0x1) #define __CORE_CLK_PRE XTALI #elif (((RCC_Val>>4) & 0x03) == 0x2) #define __CORE_CLK_PRE (XTALI/4) #else #define __CORE_CLK_PRE XTAL30K #endif #else #define __CORE_CLK_PRE PLL_CLK #endif #if (RCC_Val & (1UL<<22)) /* check USESYSDIV */ #if (RCC_Val & (1UL<<11)) /* check BYPASS */ #define __CORE_CLK (__CORE_CLK_PRE / (((RCC_Val>>23) & (0x0F)) + 1)) #else #define __CORE_CLK (__CORE_CLK_PRE / (((RCC_Val>>23) & (0x0F)) + 1) / 2) #endif #else #define __CORE_CLK __CORE_CLK_PRE #endif #endif /*---------------------------------------------------------------------------- Clock Variable definitions *----------------------------------------------------------------------------*/ uint32_t SystemCoreClock = __CORE_CLK; /*!< System Clock Frequency (Core Clock)*/ /*---------------------------------------------------------------------------- Clock functions *----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- Get the OSC clock *----------------------------------------------------------------------------*/ __INLINE static uint32_t getOscClk (uint32_t xtal, uint32_t oscSrc) { uint32_t oscClk = XTALI; switch (oscSrc) { /* switch OSCSRC */ case 0: /* MOSC Main oscillator */ switch (xtal) { /* switch XTAL */ case 0x0: oscClk = 1000000UL; break; case 0x1: oscClk = 1843200UL; break; case 0x2: oscClk = 2000000UL; break; case 0x3: oscClk = 2457600UL; break; case 0x4: oscClk = 3579545UL; break; case 0x5: oscClk = 3686400UL; break; case 0x6: oscClk = 4000000UL; break; case 0x7: oscClk = 4096000UL; break; case 0x8: oscClk = 4915200UL; break; case 0x9: oscClk = 5000000UL; break; case 0xA: oscClk = 5120000UL; break; case 0xB: oscClk = 6000000UL; break; case 0xC: oscClk = 6144000UL; break; case 0xD: oscClk = 7372800UL; break; case 0xE: oscClk = 8000000UL; break; case 0xF: oscClk = 8192000UL; break; case 0x10: oscClk = 10000000UL; break; case 0x11: oscClk = 12000000UL; break; case 0x12: oscClk = 12288000UL; break; case 0x13: oscClk = 13560000UL; break; case 0x14: oscClk = 14318180UL; break; case 0x15: oscClk = 16000000UL; break; case 0x16: oscClk = 16384000UL; break; } break; case 1: /* IOSC Internal oscillator */ oscClk = XTALI; break; case 2: /* IOSC/4 Internal oscillator/4 */ oscClk = XTALI/4; break; case 3: /* 30kHz internal oscillator */ oscClk = XTAL30K; break; } return oscClk; } void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ { uint32_t rcc, rcc2; /* Determine clock frequency according to clock register values */ rcc = SYSCTL->RCC; rcc2 = SYSCTL->RCC2; //if (rcc2 & SYSCTL_RCC2_USERCC2) if (rcc2 & (1UL<<31)) { /* is rcc2 is used ? */ // if (rcc2 & SYSCTL_RCC2_BYPASS2) if (rcc2 & (1UL<<11)) { /* check BYPASS */ SystemCoreClock = getOscClk (((rcc>>6) & 0x0F),((rcc2>>4) & 0x07)); } else { SystemCoreClock = PLL_CLK; } if (rcc & (1UL<<22)) { /* check USESYSDIV */ if (rcc2 & (1UL<<11)) { SystemCoreClock = SystemCoreClock / (((rcc2>>23) & (0x3F)) + 1); } else { SystemCoreClock = SystemCoreClock / (((rcc2>>23) & (0x3F)) + 1) / 2; } } } else { // if (RCC_Val & (1UL<<11)) { /* check BYPASS */ if (rcc & (1UL<<11)) { /* check BYPASS */ /* Simulation does not work at this point */ SystemCoreClock = getOscClk (((rcc>>6) & 0x1F),((rcc>>4) & 0x03)); } else { SystemCoreClock = PLL_CLK; } // if (rcc & SYSCTL_RCC_USE_SYSDIV) if (rcc & (1UL<<22)) { /* check USESYSDIV */ // if (rcc2 & SYSCTL_RCC_BYPASS) if (rcc & (1UL<<11)) { /* check BYPASS */ /* Simulation does not work at this point */ // if (RCC_Val & (1UL<<11)) { /* check BYPASS */ SystemCoreClock = SystemCoreClock / (((rcc>>23) & (0x0F)) + 1); } else { SystemCoreClock = SystemCoreClock / (((rcc>>23) & (0x0F)) + 1) / 2; } } } } /** * Initialize the system * * @param none * @return none * * @brief Setup the microcontroller system. * Initialize the System. */ void SystemInit (void) { #if(CLOCK_SETUP) uint32_t i; #endif /* FPU settings ------------------------------------------------------------*/ #if (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ (3UL << 11*2) ); /* set CP11 Full Access */ #endif #if(CLOCK_SETUP) SYSCTL->RCC2 = 0x07802810; /* set default value */ SYSCTL->RCC = 0x078E3AD1; /* set default value */ SYSCTL->RCC = (RCC_Val | (1UL<<11) | (1UL<<13)) & ~(1UL<<22); /* set value with BYPASS, PWRDN set, USESYSDIV reset */ SYSCTL->RCC2 = (RCC2_Val | (1UL<<11) | (1UL<<13)); /* set value with BYPASS, PWRDN set */ for (i = 0; i < 1000; i++); /* wait a while */ SYSCTL->RCC = (RCC_Val | (1UL<<11)) & ~(1UL<<22); /* set value with BYPASS, USESYSDIV reset */ SYSCTL->RCC2 = (RCC2_Val | (1UL<<11)); /* set value with BYPASS */ for (i = 0; i < 1000; i++); /* wait a while */ SYSCTL->RCC = (RCC_Val | (1<<11)); /* set value with BYPASS */ if ( (((RCC_Val & (1UL<<13)) == 0) && ((RCC2_Val & (1UL<<31)) == 0)) || (((RCC2_Val & (1UL<<13)) == 0) && ((RCC2_Val & (1UL<<31)) != 0)) ) { while ((SYSCTL->RIS & (1UL<<6)) != (1UL<<6)); /* wait until PLL is locked */ } SYSCTL->RCC = (RCC_Val); /* set value */ SYSCTL->RCC2 = (RCC2_Val); /* set value */ for (i = 0; i < 10000; i++); /* wait a while */ #endif }