diff --git a/arch/arm/src/xmc4/chip/xmc4_scu.h b/arch/arm/src/xmc4/chip/xmc4_scu.h index 2d22084252d..afa4d0f8a7f 100644 --- a/arch/arm/src/xmc4/chip/xmc4_scu.h +++ b/arch/arm/src/xmc4/chip/xmc4_scu.h @@ -938,7 +938,7 @@ #define SCU_SLEEPCR_SYSSEL (1 << 0) /* Bit 0: System Clock Selection Value */ # define SCU_SLEEPCR_SYSSEL_OFI (0) /* 0=fOFI */ -# define SCU_SLEEPCR_SYSSEL_ PLL (1 << 0) /* 1=fPLL */ +# define SCU_SLEEPCR_SYSSEL_FPLL (1 << 0) /* 1=fPLL */ #define SCU_SLEEPCR_USBCR (1 << 16) /* Bit 6: USB Clock Control in Sleep Mode */ #define SCU_SLEEPCR_MMCCR (1 << 17) /* Bit 17: MMC Clock Control in Sleep Mode */ #define SCU_SLEEPCR_ETH0CR (1 << 18) /* Bit 18: Ethernet Clock Control in Sleep Mode */ diff --git a/arch/arm/src/xmc4/xmc4_clockconfig.c b/arch/arm/src/xmc4/xmc4_clockconfig.c index eeb71dbe0b4..9d6cc0621eb 100644 --- a/arch/arm/src/xmc4/xmc4_clockconfig.c +++ b/arch/arm/src/xmc4/xmc4_clockconfig.c @@ -58,6 +58,7 @@ #include "up_arch.h" #include "chip/xmc4_scu.h" #include "xmc4_clockconfig.h" +#include "chip/xmc4_ports.h" #include @@ -105,7 +106,7 @@ #define CLKSET_VALUE (0x00000000) #define USBCLKCR_VALUE (0x00010000) -#if BOARD_PBDIV == 1 +#if BOARD_PLL_PBDIV == 1 # define PBCLKCR_VALUE SCU_PBCLKCR_PBDIV_FCPU #else /* BOARD_PBDIV == 2 */ # define PBCLKCR_VALUE SCU_PBCLKCR_PBDIV_DIV2 @@ -387,8 +388,8 @@ void xmc4_clock_configure(void) /* Setup fSYS clock */ - regval = (BOARD_ENABLE_PLL << SCU_SYSCLKCR_SYSSEL); - regval |= SCU_SYSCLKCR_SYSDIV(BOARD_SYSDIV); + regval = (BOARD_ENABLE_PLL ? SCU_SYSCLKCR_SYSSEL : 0); + regval |= SCU_SYSCLKCR_SYSDIV(BOARD_PLL_SYSDIV); putreg32(regval, XMC4_SCU_SYSCLKCR); /* Setup peripheral clock divider */ @@ -411,7 +412,7 @@ void xmc4_clock_configure(void) /* Setup EBU clock */ - regval = SCU_EBUCLKCR_EBUDIV(BOARD_EBUDIV); + regval = SCU_EBUCLKCR_EBUDIV(BOARD_PLL_EBUDIV); putreg32(regval, XMC4_SCU_EBUCLKCR); #ifdef BOARD_ENABLE_USBPLL @@ -423,7 +424,7 @@ void xmc4_clock_configure(void) /* Setup EXT */ regval = (BOARD_EXT_SOURCE << SCU_EXTCLKCR_ECKSEL_SHIFT); - regval |= SCU_EXTCLKCR_ECKDIV(BOARD_EXTDIV); + regval |= SCU_EXTCLKCR_ECKDIV(BOARD_PLL_ECKDIV); putreg32(regval, XMC4_SCU_EXTCLKCR); #if BOARD_ENABLE_PLL @@ -561,4 +562,30 @@ void xmc4_clock_configure(void) /* Enable selected clocks */ putreg32(CLKSET_VALUE, XMC4_SCU_CLKSET); + +#if BOARD_PLL_CLOCKSRC_XTAL == 1 + regval = SCU_SLEEPCR_SYSSEL_FPLL; + putreg32(regval, XMC4_SCU_SLEEPCR); +#endif /* BOARD_PLL_CLOCKSRC_XTAL == 1 */ + +#if BOARD_EXTCKL_ENABLE +#if BOARD_EXTCLK_PIN == EXTCLK_PIN_P0_8 + /* enable EXTCLK output on P0.8 */ + regval = getreg32(XMC4_PORT0_HWSEL); + regval &= ~PORT_HWSEL_HW8_MASK; + putreg32(regval, XMC4_PORT0_HWSEL); + + regval = getreg32(XMC4_PORT0_PDR1); + regval &= ~PORT_PDR1_PD8_MASK; + putreg32(regval, XMC4_PORT0_PDR1); + + regval = getreg32(XMC4_PORT0_IOCR8); + regval &= ~PORT_IOCR8_PC8_MASK; + regval |= PORT_IOCR8_PC8(0x11); /* push-pull output, alt func 1 */ + putreg32(regval, XMC4_PORT0_IOCR8); +#else + /* enable EXTCLK output on P1.15 */ +# warn "Not yet implemented" +#endif +#endif } diff --git a/arch/arm/src/xmc4/xmc4_start.c b/arch/arm/src/xmc4/xmc4_start.c index d1a1b4a1c3f..5e65aecaac7 100644 --- a/arch/arm/src/xmc4/xmc4_start.c +++ b/arch/arm/src/xmc4/xmc4_start.c @@ -396,9 +396,17 @@ void __start(void) /* Then start NuttX */ +#ifdef CONFIG_STACK_COLORATION + /* Set the IDLE stack to the coloration value and jump into os_start() */ + + go_os_start((FAR void *)&_ebss, CONFIG_IDLETHREAD_STACKSIZE); +#else + /* Call os_start() */ + os_start(); /* Shouldn't get here */ for (; ; ); +#endif } diff --git a/configs/xmc4500-relax/include/board.h b/configs/xmc4500-relax/include/board.h index 7190d1c9394..0dfd182eb6c 100644 --- a/configs/xmc4500-relax/include/board.h +++ b/configs/xmc4500-relax/include/board.h @@ -82,99 +82,8 @@ #define BOARD_XTAL_FREQUENCY 12000000 /* 12MHz XTAL */ #undef BOARD_RTC_XTAL_FRQUENCY /* 32.768KHz RTC XTAL not available on the Relax Lite */ - -#if defined(BOARD_FCPU_144MHZ) -/* Default clock initialization - * - * fXTAL = 12Mhz - * -> fPLL = (fXTAL / (2 * 1) * 48) = 288MHz - * -> fSYS = (fPLL / 1) = 288MHz - * -> fCPU = (fSYS / 2) = 144MHz - * -> fPERIPH = (fCPU / 1) = 144MHz - * -> fCCU = (fSYS / 2) = 144MHz - * -> fETH = 72MHz (REVISIT) - * -> fUSB = 48MHz (REVISIT) - * -> fEBU = 72MHz (REVISIT) - * - * fUSBPLL Disabled, only enabled if SCU_CLK_USBCLKCR_USBSEL_USBPLL is selected - * - * fOFI = 24MHz - * -> fWDT = 24MHz (REVISIT) - */ - -/* Select the external crystal as the PLL clock source */ - -# define BOARD_PLL_CLOCKSRC_XTAL 1 /* PLL Clock source == external crystal */ -# undef BOARD_PLL_CLOCKSRC_OFI /* PLL Clock source != internal fast oscillator */ - -/* PLL Configuration: - * - * fPLL = (fPLLSRC / (pdiv * k2div) * ndiv - * - * fPLL = (12000000 / (2 * 1)) * 48 - * = 288MHz - */ - -# define BOARD_ENABLE_PLL 1 -# define BOARD_PLL_PDIV 2 -# define BOARD_PLL_NDIV 48 -# define BOARD_PLL_K2DIV 1 -# define BOARD_PLL_FREQUENCY 288000000 - -/* System frequency, fSYS, is divided down from PLL output */ - -# define BOARD_SYSDIV 1 /* PLL Output divider to get fSYS */ -# define BOARD_SYS_FREQUENCY 288000000 - -/* CPU frequency, fCPU, may be divided down from system frequency */ - -# define BOARD_CPUDIV_ENABLE 1 /* Enable PLL divide by 2 for fCPU */ -# define BOARD_CPU_FREQUENCY 144000000 - -/* CCU frequency may be divided down from system frequency */ - -# define BOARD_CCUDIV_ENABLE 1 /* Enable PLL div by 2 */ -# define BOARD_CCU_FREQUENCY 144000000 - -/* Watchdog clock settings */ - -# define BOARD_WDT_SOURCE WDT_CLKSRC_FOFI -# define BOARD_WDTDIV 1 -# define BOARD_WDT_FREQUENCY 24000000 - -/* EBU frequency may be divided down from system frequency */ - -# define BOARD_EBUDIV 2 /* fSYS / 2 */ -# define BOARD_EBU_FREQUENCY 72000000 - -/* EXT clock settings */ - -# define BOARD_EXT_SOURCE EXT_CLKSRC_FPLL -# define BOARD_EXTDIV 289 /* REVISIT */ -# define BOARD_EXT_FREQUENCY 498270 /* REVISIT */ - -/* The peripheral clock, fPERIPH, derives from fCPU with no division */ - -# define BOARD_PBDIV 1 /* No division */ -# define BOARD_PERIPH_FREQUENCY 144000000 - -#elif defined(BOARD_FCPU_120MHZ) -/* Default clock initialization - * - * fXTAL = 12Mhz - * -> fPLL = (fXTAL / (2 * 4) * 80) = 120 - * -> fSYS = (fPLL / 1) = 120MHz - * -> fCPU = (fSYS / 1) = 120MHz - * -> fPERIPH = (fCPU / 1) = 120MHz - * -> fCCU = (fSYS / 1) = 120MHz - * -> fETH = 60MHz (REVISIT) - * -> fUSB = 48MHz (REVISIT) - * -> fEBU = 60MHz (REVISIT) - * - * fUSBPLL Disabled, only enabled if SCU_CLK_USBCLKCR_USBSEL_USBPLL is selected - * - * fOFI = 24MHz - * -> fWDT = 24MHz (REVISIT) +/* + * TODO: enable the RTC osc, use RTC for time/date */ /* Select the external crystal as the PLL clock source */ @@ -184,56 +93,142 @@ /* PLL Configuration: * - * fPLL = (fPLLSRC / (pdiv * k2div) * ndiv + * fXTAL = 12Mhz + * 260 MHz <= fVCO <= 520 MHz * - * fPLL = (12000000 / (2 * 4)) * 80 - * = 120MHz + * fVCO = fXTAL * ndiv / pdiv + * fPLL = fVCO / k2div + * fSYS = fPLL / sysdiv + * fETH = fSYS / 2 (fixed div by 2) + * fCCU = fSYS / ccudiv (div by 1 or 2) + * fCPU = fSYS / cpudiv (div by 1 or 2) + * fPERIPH = fCPU / pbdiv (div by 1 or 2) */ -# define BOARD_ENABLE_PLL 1 -# define BOARD_PLL_PDIV 2 -# define BOARD_PLL_NDIV 80 +# define BOARD_ENABLE_PLL 1 /* enable the PLL */ +# define CPU_FREQ 120 /* MHz */ + +/* TODO: Automate PLL calculations */ + +#if CPU_FREQ == 120 +/* + * 120 MHz + * + * fVCO = 12MHz * 40 / 2 = 480MHz + * fPLL = 480MHz / 2 = 240MHz + * fSYS = fPLL / 2 = 120MHz + * fCCU = fSYS / 2 = 60MHz + * fCPU = fSYS / 1 = 120MHz + * fPB = fCPU / 2 = 60MHz + * fETH = fSYS / 2 = 60MHz + */ + +# define BOARD_PLL_NDIV 40 +# define BOARD_PLL_PDIV 1 # define BOARD_PLL_K2DIV 4 -# define BOARD_PLL_FREQUENCY 120000000 +# define BOARD_PLL_SYSDIV 1 +# define BOARD_PLL_CPUDIV 1 +# define BOARD_PLL_PBDIV 2 +# define BOARD_PLL_CCUDIV 2 +# define BOARD_PLL_EBUDIV 4 -/* System frequency, fSYS, is divided down from PLL output */ +#elif CPU_FREQ == 144 +/* + * 144 MHz + * + * fVCO = 12MHz * 36 / 1 = 432MHz + * fPLL = 432MHz / 3 = 144MHz + * fSYS = fPLL / 1 = 144MHz + * fCCU = fSYS / 2 = 72MHz + * fCPU = fSYS / 1 = 144MHz + * fPB = fCPU / 2 = 72MHz + * fETH = fSYS / 2 = 72MHz + */ -# define BOARD_SYSDIV 1 /* No division */ -# define BOARD_SYS_FREQUENCY 120000000 +# define BOARD_PLL_NDIV 36 +# define BOARD_PLL_PDIV 1 +# define BOARD_PLL_K2DIV 3 +# define BOARD_PLL_SYSDIV 1 +# define BOARD_PLL_CPUDIV 1 +# define BOARD_PLL_PBDIV 2 +# define BOARD_PLL_CCUDIV 2 +# define BOARD_PLL_EBUDIV 2 -/* CPU frequency, fCPU, may be divided down from system frequency */ +#else +# error "Illegal or Unsupported CPU Frequency" +#endif -# define BOARD_CPUDIV_ENABLE 0 /* No divison */ -# define BOARD_CPU_FREQUENCY 120000000 -/* CCU frequency may be divided down from system frequency */ +# define BOARD_CCUDIV_ENABLE (BOARD_PLL_CCUDIV - 1) +# define BOARD_CPUDIV_ENABLE (BOARD_PLL_CPUDIV - 1) -# define BOARD_CCUDIV_ENABLE 0 /* No divison */ -# define BOARD_CCU_FREQUENCY 120000000 - -/* Watchdog clock setting */ +# define BOARD_VCO_FREQUENCY (BOARD_XTAL_FREQUENCY * BOARD_PLL_NDIV / BOARD_PLL_PDIV) +# define BOARD_PLL_FREQUENCY (BOARD_VCO_FREQUENCY / BOARD_PLL_K2DIV) +# define BOARD_SYS_FREQUENCY (BOARD_PLL_FREQUENCY / BOARD_PLL_SYSDIV) +# define BOARD_CCU_FREQUENCY (BOARD_SYS_FREQUENCY / BOARD_PLL_CCUDIV) +# define BOARD_CPU_FREQUENCY (BOARD_SYS_FREQUENCY / BOARD_PLL_CPUDIV) +# define BOARD_PERIPH_FREQUENCY (BOARD_CPU_FREQUENCY / BOARD_PLL_PBDIV) +# define BOARD_ETH_FREQUENCY (BOARD_SYS_FREQUENCY / 2) # define BOARD_WDT_SOURCE WDT_CLKSRC_FOFI # define BOARD_WDTDIV 1 # define BOARD_WDT_FREQUENCY 24000000 -/* EBU frequency may be divided down from system frequency */ +# define BOARD_EXT_SOURCE EXT_CLKSRC_FPLL +# define BOARD_PLL_ECKDIV 480 /* [1,512] */ + +# define kHz_1 1000 +# define MHz_1 (kHz_1 * kHz_1) +# define MHz_50 ( 50 * MHz_1) +# define MHz_260 (260 * MHz_1) +# define MHz_520 (520 * MHz_1) + + /* range check VCO frequency */ +# if (BOARD_VCO_FREQUENCY < MHz_260) +# error "VCO freq must be >= 260 MHz" +# endif + +# if (BOARD_VCO_FREQUENCY > MHz_520) +# error "VCO freq must be <= 520 MHz" +# endif + + /* range check Ethernet MAC frequency */ +# if (BOARD_ETH_FREQUENCY <= MHz_50) +# error "ETH freq must be > 50 MHz" +# endif + + + +/* check ccudiv cpudiv pbdiv against Table 11-5 + * of XMC4500 User Manual + */ +#define CLKDIV_INDEX (4 * (BOARD_PLL_CCUDIV-1) + \ + 2 * (BOARD_PLL_CPUDIV-1) + \ + (BOARD_PLL_PBDIV-1) ) + +#if (CLKDIV_INDEX == 3) || (CLKDIV_INDEX == 4) || (CLKDIV_INDEX > 6) +# error "Illegal combination of dividers! Ref: Table 11-5 of UM" +#endif -# define BOARD_EBUDIV 2 /* fSYS/2 */ -# define BOARD_EBU_FREQUENCY 60000000 /* EXT clock settings */ +#define BOARD_EXTCKL_ENABLE 1 /* 0 disables output */ +#if BOARD_EXTCKL_ENABLE +# define EXTCLK_PIN_P0_8 8 +# define EXTCLK_PIN_P1_15 15 +# define BOARD_EXTCLK_PIN EXTCLK_PIN_P0_8 # define BOARD_EXT_SOURCE EXT_CLKSRC_FPLL -# define BOARD_EXTDIV 289 /* REVISIT */ -# define BOARD_EXT_FREQUENCY 415225 /* REVISIT */ +# define BOARD_EXT_FREQUENCY (250 * kHz_1) /* Desired output freq */ +# define BOARD_EXTDIV (BOARD_PLL_FREQUENCY / BOARD_EXT_FREQUENCY) -/* The peripheral clock, fPERIPH, derives from fCPU with no division */ - -# define BOARD_PBDIV 1 /* No division */ -# define BOARD_PERIPH_FREQUENCY 120000000 +/* range check EXTDIV */ +# if BOARD_EXTDIV > 512 +# error "EXTCLK Divisor out of range!" +# endif #endif + /* Standby clock source selection * * BOARD_STDBY_CLOCKSRC_OSI - Internal 32.768KHz slow oscillator