From 0c47440c6a8bc6bab476bf787fb784490377a326 Mon Sep 17 00:00:00 2001 From: Karel Gardas Date: Thu, 29 Aug 2013 22:20:03 +0200 Subject: bsp/lm4f120: new BSP to support TI LM4F120 XL LaunchPad board --- c/src/lib/libbsp/arm/lm3s69xx/configure.ac | 11 +++- c/src/lib/libbsp/arm/lm3s69xx/include/lm3s69xx.h | 15 +++++- c/src/lib/libbsp/arm/lm3s69xx/include/syscon.h | 1 + .../libbsp/arm/lm3s69xx/make/custom/lm4f120.cfg | 5 ++ c/src/lib/libbsp/arm/lm3s69xx/ssi/ssi.c | 4 +- c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c | 59 +++++++++++++++++++--- .../libbsp/arm/lm3s69xx/startup/linkcmds.lm4f120 | 28 ++++++++++ c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c | 9 ++++ 8 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 c/src/lib/libbsp/arm/lm3s69xx/make/custom/lm4f120.cfg create mode 100644 c/src/lib/libbsp/arm/lm3s69xx/startup/linkcmds.lm4f120 diff --git a/c/src/lib/libbsp/arm/lm3s69xx/configure.ac b/c/src/lib/libbsp/arm/lm3s69xx/configure.ac index 833c56d3f9..c9d40cf907 100644 --- a/c/src/lib/libbsp/arm/lm3s69xx/configure.ac +++ b/c/src/lib/libbsp/arm/lm3s69xx/configure.ac @@ -25,11 +25,13 @@ RTEMS_BSPOPTS_SET([BSP_SMALL_MEMORY],[*_qemu],[]) RTEMS_BSPOPTS_SET([BSP_SMALL_MEMORY],[*],[1]) RTEMS_BSPOPTS_HELP([BSP_SMALL_MEMORY],[disable testsuite samples with high memory demands]) -RTEMS_BSPOPTS_SET([LM3S69XX_SYSTEM_CLOCK],[*],[50000000U]) +RTEMS_BSPOPTS_SET([LM3S69XX_SYSTEM_CLOCK],[lm3s*],[50000000U]) +RTEMS_BSPOPTS_SET([LM3S69XX_SYSTEM_CLOCK],[lm4f*],[80000000U]) RTEMS_BSPOPTS_HELP([LM3S69XX_SYSTEM_CLOCK],[system clock in Hz]) RTEMS_BSPOPTS_SET([LM3S69XX_XTAL_CONFIG],[lm3s6965*],[0xE]) dnl 8MHz XTAL RTEMS_BSPOPTS_SET([LM3S69XX_XTAL_CONFIG],[lm3s3749*],[0x10]) dnl 10MHz XTAL +RTEMS_BSPOPTS_SET([LM3S69XX_XTAL_CONFIG],[lm4f120*],[0x15]) dnl 16MHz XTAL RTEMS_BSPOPTS_HELP([LM3S69XX_XTAL_CONFIG],[crystal configuration for RCC register]) RTEMS_BSPOPTS_SET([LM3S69XX_SSI_CLOCK],[*],[1000000U]) @@ -49,17 +51,21 @@ RTEMS_BSPOPTS_HELP([LM3S69XX_ENABLE_UART_2],[enable UART 2]) RTEMS_BSPOPTS_SET([LM3S69XX_NUM_GPIO_BLOCKS],[lm3s3749*],[8]) RTEMS_BSPOPTS_SET([LM3S69XX_NUM_GPIO_BLOCKS],[lm3s6965*],[7]) +RTEMS_BSPOPTS_SET([LM3S69XX_NUM_GPIO_BLOCKS],[lm4f120*],[6]) RTEMS_BSPOPTS_HELP([LM3S69XX_NUM_GPIO_BLOCKS],[number of GPIO blocks supported by MCU]) RTEMS_BSPOPTS_SET([LM3S69XX_NUM_SSI_BLOCKS],[lm3s3749*],[2]) RTEMS_BSPOPTS_SET([LM3S69XX_NUM_SSI_BLOCKS],[lm3s6965*],[1]) +RTEMS_BSPOPTS_SET([LM3S69XX_NUM_SSI_BLOCKS],[lm4f120*],[4]) RTEMS_BSPOPTS_HELP([LM3S69XX_NUM_SSI_BLOCKS],[number of SSI blocks supported by MCU]) RTEMS_BSPOPTS_SET([LM3S69XX_HAS_UDMA],[lm3s3749*],[1]) +RTEMS_BSPOPTS_SET([LM3S69XX_HAS_UDMA],[lm4f*],[1]) RTEMS_BSPOPTS_SET([LM3S69XX_HAS_UDMA],[*],[0]) RTEMS_BSPOPTS_HELP([LM3S69XX_HAS_UDMA],[defined if MCU supports UDMA]) RTEMS_BSPOPTS_SET([LM3S69XX_USE_AHB_FOR_GPIO],[lm3s3749*],[1]) +RTEMS_BSPOPTS_SET([LM3S69XX_USE_AHB_FOR_GPIO],[lm4f*],[1]) RTEMS_BSPOPTS_SET([LM3S69XX_USE_AHB_FOR_GPIO],[*],[0]) RTEMS_BSPOPTS_HELP([LM3S69XX_USE_AHB_FOR_GPIO],[use AHB apperture to access GPIO registers]) @@ -69,6 +75,9 @@ RTEMS_BSPOPTS_HELP([LM3S69XX_MCU_LM3S3749],[board has LM3S3749 MCU]) RTEMS_BSPOPTS_SET([LM3S69XX_MCU_LM3S6965],[lm3s6965*],[1]) RTEMS_BSPOPTS_HELP([LM3S69XX_MCU_LM3S6965],[board has LM3S6965 MCU]) +RTEMS_BSPOPTS_SET([LM3S69XX_MCU_LM4F120],[lm4f120*],[1]) +RTEMS_BSPOPTS_HELP([LM3S69XX_MCU_LM4F120],[board has LM4F120xxx MCU]) + RTEMS_BSP_CLEANUP_OPTIONS(0, 0) RTEMS_BSP_LINKCMDS diff --git a/c/src/lib/libbsp/arm/lm3s69xx/include/lm3s69xx.h b/c/src/lib/libbsp/arm/lm3s69xx/include/lm3s69xx.h index 74026248ad..2b38d936cb 100644 --- a/c/src/lib/libbsp/arm/lm3s69xx/include/lm3s69xx.h +++ b/c/src/lib/libbsp/arm/lm3s69xx/include/lm3s69xx.h @@ -32,10 +32,12 @@ #define LM3S69XX_GPIO_D_BASE 0x4005b000 #define LM3S69XX_GPIO_E_BASE 0x4005c000 #define LM3S69XX_GPIO_F_BASE 0x4005d000 +#if LM3S69XX_NUM_GPIO_BLOCKS > 6 #define LM3S69XX_GPIO_G_BASE 0x4005e000 #if LM3S69XX_NUM_GPIO_BLOCKS > 7 #define LM3S69XX_GPIO_H_BASE 0x4005f000 #endif +#endif #define LM3S69XX_GPIO(port) ((volatile lm3s69xx_gpio *)(LM3S69XX_GPIO_A_BASE + (port) * 0x1000)) #else /* LM3S69XX_USE_AHB_FOR_GPIO */ @@ -45,10 +47,12 @@ #define LM3S69XX_GPIO_D_BASE 0x40007000 #define LM3S69XX_GPIO_E_BASE 0x40024000 #define LM3S69XX_GPIO_F_BASE 0x40025000 +#if LM3S69XX_NUM_GPIO_BLOCKS > 6 #define LM3S69XX_GPIO_G_BASE 0x40026000 #if LM3S69XX_NUM_GPIO_BLOCKS > 7 #define LM3S69XX_GPIO_H_BASE 0x40027000 #endif +#endif #define LM3S69XX_GPIO(port) ((volatile lm3s69xx_gpio *)(((port) < 4) ? \ (LM3S69XX_GPIO_A_BASE + (port) * 0x1000) : \ @@ -58,6 +62,12 @@ #define LM3S69XX_SSI_0_BASE 0x40008000 #if LM3S69XX_NUM_SSI_BLOCKS > 1 #define LM3S69XX_SSI_1_BASE 0x40009000 +#if LM3S69XX_NUM_SSI_BLOCKS > 2 +#define LM3S69XX_SSI_2_BASE 0x4000A000 +#if LM3S69XX_NUM_SSI_BLOCKS > 3 +#define LM3S69XX_SSI_3_BASE 0x4000B000 +#endif +#endif #endif #define LM3S69XX_SYSCON ((volatile lm3s69xx_syscon *)LM3S69XX_SYSCON_BASE) @@ -194,8 +204,11 @@ typedef struct { uint32_t gpiohbctl; #define SYSCONRCC2_USERCC2 BSP_BIT32(31) +#define SYSCONRCC2_DIV400 BSP_BIT32(30) #define SYSCONRCC2_SYSDIV2(val) BSP_FLD32(val, 23, 28) -#define SYSCONRCC2_SYSDIV2_MSK(val) BSP_MSK32(23, 28) +#define SYSCONRCC2_SYSDIV2_MSK BSP_MSK32(23, 28) +#define SYSCONRCC2_SYSDIV2EXT(val) BSP_FLD32(val, 22, 28) +#define SYSCONRCC2_SYSDIV2EXT_MSK BSP_MSK32(22, 28) #define SYSCONRCC2_USBPWRDN BSP_BIT32(14) #define SYSCONRCC2_PWRDN2 BSP_BIT32(13) #define SYSCONRCC2_BYPASS2 BSP_BIT32(11) diff --git a/c/src/lib/libbsp/arm/lm3s69xx/include/syscon.h b/c/src/lib/libbsp/arm/lm3s69xx/include/syscon.h index 0f3dc3b0cf..78af4a757e 100644 --- a/c/src/lib/libbsp/arm/lm3s69xx/include/syscon.h +++ b/c/src/lib/libbsp/arm/lm3s69xx/include/syscon.h @@ -18,6 +18,7 @@ void lm3s69xx_syscon_enable_uart_clock(unsigned int port, bool enable); void lm3s69xx_syscon_enable_ssi_clock(unsigned int port, bool enable); void lm3s69xx_syscon_enable_pwm_clock(bool enable); void lm3s69xx_syscon_set_pwmdiv(unsigned int div); +void lm3s69xx_syscon_delay_3x_clocks(unsigned long x_count); #ifdef __cplusplus } diff --git a/c/src/lib/libbsp/arm/lm3s69xx/make/custom/lm4f120.cfg b/c/src/lib/libbsp/arm/lm3s69xx/make/custom/lm4f120.cfg new file mode 100644 index 0000000000..aa7961e6c7 --- /dev/null +++ b/c/src/lib/libbsp/arm/lm3s69xx/make/custom/lm4f120.cfg @@ -0,0 +1,5 @@ +# +# Config file for LM4F120XL. +# + +include $(RTEMS_ROOT)/make/custom/lm3s69xx.inc diff --git a/c/src/lib/libbsp/arm/lm3s69xx/ssi/ssi.c b/c/src/lib/libbsp/arm/lm3s69xx/ssi/ssi.c index d5f3d17eb3..9e5b2b5338 100644 --- a/c/src/lib/libbsp/arm/lm3s69xx/ssi/ssi.c +++ b/c/src/lib/libbsp/arm/lm3s69xx/ssi/ssi.c @@ -134,7 +134,7 @@ static lm3s69xx_ssi_bus_entry ssi_0_bus = { .bus_number = 0, .idle_char = 0xffff, .io_configs = { -#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) +#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM4F120) LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_A, 2), /* CLK */ LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_A, 5), /* TX */ LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_A, 4) /* RX */ @@ -156,7 +156,7 @@ static lm3s69xx_ssi_bus_entry ssi_1_bus = { .bus_number = 1, .idle_char = 0xffff, .io_configs = { -#if defined(LM3S69XX_MCU_LM3S3749) +#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM4F120) LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_E, 0), /* CLK */ LM3S69XX_PIN_SSI_TX(LM3S69XX_PORT_E, 3), /* TX */ LM3S69XX_PIN_SSI_RX(LM3S69XX_PORT_E, 2) /* RX */ diff --git a/c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c b/c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c index 442c713892..a8329b613d 100644 --- a/c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c +++ b/c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c @@ -19,32 +19,70 @@ static void init_main_osc(void) volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; uint32_t sysdiv_val = LM3S69XX_PLL_FREQUENCY / LM3S69XX_SYSTEM_CLOCK; +#if defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM3S3749) assert(sysdiv_val * LM3S69XX_SYSTEM_CLOCK == LM3S69XX_PLL_FREQUENCY); +#endif assert((sysdiv_val >= 4) && (sysdiv_val <= 16)); uint32_t rcc = syscon->rcc; + uint32_t rcc2 = syscon->rcc2; rcc = (rcc & ~SYSCONRCC_USESYSDIV) | SYSCONRCC_BYPASS; + rcc2 |= SYSCONRCC2_BYPASS2; + syscon->rcc = rcc; + syscon->rcc2 = rcc2; - rcc = (rcc & ~(SYSCONRCC_PWRDN | SYSCONRCC_XTAL_MSK | SYSCONRCC_OSCSRC_MSK)) - | SYSCONRCC_XTAL(LM3S69XX_XTAL_CONFIG) | SYSCONRCC_OSCSRC_MOSC; + /* + As per a note in Stellaris® LM4F120H5QR Microcontroller Data + Sheet on page 219: "When transitioning the system clock + configuration to use the MOSC as the fundamental clock source, the + MOSCDIS bit must be set prior to reselecting the MOSC or an + undefined system clock configuration can sporadically occur." + */ + + rcc |= SYSCONRCC_MOSCDIS; syscon->rcc = rcc; - rcc = (rcc & ~SYSCONRCC_SYSDIV_MSK) | SYSCONRCC_SYSDIV(sysdiv_val / 2 - 1) - | SYSCONRCC_USESYSDIV; + rcc = (rcc & ~(SYSCONRCC_XTAL_MSK)) + | SYSCONRCC_XTAL(LM3S69XX_XTAL_CONFIG); + rcc2 = (rcc2 & ~(SYSCONRCC2_PWRDN2 | SYSCONRCC2_OSCSRC2_MSK)) + | SYSCONRCC2_USERCC2 | SYSCONRCC2_OSCSRC2(0x0); + + /* clear PLL lock interrupt */ + syscon->misc &= (SYSCONMISC_PLLLMIS); + syscon->rcc = rcc; + syscon->rcc2 = rcc2; + lm3s69xx_syscon_delay_3x_clocks(16); + + /* since now, we'll use only RCC2 as SYSCONRCC2_USERCC2 and XTAL + (only available in RCC) are already set */ + + if (sysdiv_val % 2 == 0) { + rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2_MSK) | SYSCONRCC2_SYSDIV2(sysdiv_val / 2 - 1); + + rcc2 &= ~(SYSCONRCC2_DIV400); + } + else { + /* need to use DIV400 */ + rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2EXT_MSK) | SYSCONRCC2_SYSDIV2EXT(sysdiv_val - 1) + | SYSCONRCC2_DIV400; + } + syscon->rcc2 = rcc2; while ((syscon->ris & SYSCONRIS_PLLLRIS) == 0) /* Wait for PLL lock */; - rcc &= ~SYSCONRCC_BYPASS; - syscon->rcc = rcc; + rcc2 &= ~(SYSCONRCC2_BYPASS2); + + syscon->rcc2 = rcc2; + lm3s69xx_syscon_delay_3x_clocks(16); } static const lm3s69xx_gpio_config start_config_gpio[] = { #ifdef LM3S69XX_ENABLE_UART_0 -#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) +#if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM4F120) LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_A, 0), LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_A, 1), #else @@ -59,6 +97,11 @@ static const lm3s69xx_gpio_config start_config_gpio[] = { #elif defined(LM3S69XX_MCU_LM3S6965) LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 2), LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 3), +#elif defined(LM3S69XX_MCU_LM4F120) + LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0), + LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1), + LM3S69XX_PIN_UART_RTS(LM3S69XX_PORT_C, 4), + LM3S69XX_PIN_UART_CTS(LM3S69XX_PORT_C, 5), #else #error No GPIO pin configuration for UART 1 #endif @@ -85,9 +128,11 @@ static void init_gpio(void) syscon->gpiohbctl |= SYSCONGPIOHBCTL_PORTA | SYSCONGPIOHBCTL_PORTB | SYSCONGPIOHBCTL_PORTC | SYSCONGPIOHBCTL_PORTD | SYSCONGPIOHBCTL_PORTE | SYSCONGPIOHBCTL_PORTF +#if LM3S69XX_NUM_GPIO_BLOCKS > 6 | SYSCONGPIOHBCTL_PORTG #if LM3S69XX_NUM_GPIO_BLOCKS > 7 | SYSCONGPIOHBCTL_PORTH +#endif #endif ; diff --git a/c/src/lib/libbsp/arm/lm3s69xx/startup/linkcmds.lm4f120 b/c/src/lib/libbsp/arm/lm3s69xx/startup/linkcmds.lm4f120 new file mode 100644 index 0000000000..fe19ff33fd --- /dev/null +++ b/c/src/lib/libbsp/arm/lm3s69xx/startup/linkcmds.lm4f120 @@ -0,0 +1,28 @@ +/** + * @file + * + * @brief Memory map. + */ + +MEMORY { + RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 32K + ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 256K +} + +REGION_ALIAS ("REGION_START", ROM_INT); +REGION_ALIAS ("REGION_VECTOR", RAM_INT); +REGION_ALIAS ("REGION_TEXT", ROM_INT); +REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT); +REGION_ALIAS ("REGION_RODATA", ROM_INT); +REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_DATA", RAM_INT); +REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT); +REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT); +REGION_ALIAS ("REGION_FAST_DATA", RAM_INT); +REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_BSS", RAM_INT); +REGION_ALIAS ("REGION_WORK", RAM_INT); +REGION_ALIAS ("REGION_STACK", RAM_INT); + +INCLUDE linkcmds.armv7m diff --git a/c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c b/c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c index 463bfd7d51..09b7a8008c 100644 --- a/c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c +++ b/c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c @@ -18,6 +18,15 @@ static void delay_3_clocks(void) "nop"); } +void __attribute__((naked)) lm3s69xx_syscon_delay_3x_clocks(unsigned long x_count) +{ + asm volatile( + "subs r0, #1\n\t" + "bne lm3s69xx_syscon_delay_3x_clocks\n\t" + "bx lr" + ); +} + void lm3s69xx_syscon_enable_gpio_clock(unsigned int port, bool enable) { volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; -- cgit v1.2.3