[PATCH] bsp/lm4f120: new BSP to support TI LM4F120 XL LaunchPad board
Karel Gardas
karel.gardas at centrum.cz
Tue Aug 20 16:51:01 UTC 2013
---
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 | 61 +++++++++++++++++--
c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c | 9 +++
7 files changed, 95 insertions(+), 11 deletions(-)
create mode 100644 c/src/lib/libbsp/arm/lm3s69xx/make/custom/lm4f120.cfg
diff --git a/c/src/lib/libbsp/arm/lm3s69xx/configure.ac b/c/src/lib/libbsp/arm/lm3s69xx/configure.ac
index 833c56d..c9d40cf 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 7402624..2b38d93 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 0f3dc3b..78af4a7 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 0000000..aa7961e
--- /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 d5f3d17..9e5b2b5 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 442c713..2c2228e 100644
--- a/c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c
+++ b/c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c
@@ -19,32 +19,72 @@ 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;
+ lm3s69xx_syscon_delay_3x_clocks(524288);
+
+ rcc = (rcc & ~(SYSCONRCC_XTAL_MSK))
+ | SYSCONRCC_XTAL(LM3S69XX_XTAL_CONFIG);
+ rcc2 = (rcc2 & ~(SYSCONRCC2_PWRDN2 | SYSCONRCC2_USERCC2 | SYSCONRCC2_OSCSRC2_MSK))
+ | SYSCONRCC2_USERCC2 | SYSCONRCC2_OSCSRC2_MSK;
+
+ /* 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 +99,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,10 +130,12 @@ 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
;
#endif /* LM3S69XX_USE_AHB_FOR_GPIO */
diff --git a/c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c b/c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c
index 463bfd7..09b7a80 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;
--
1.7.3.2
More information about the devel
mailing list