summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/lm3s69xx/startup
diff options
context:
space:
mode:
authorKarel Gardas <karel.gardas@centrum.cz>2013-08-29 22:20:03 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-09-02 09:06:20 +0200
commit0c47440c6a8bc6bab476bf787fb784490377a326 (patch)
tree85dace74d0f6196d15578a447cbc1163d624d9de /c/src/lib/libbsp/arm/lm3s69xx/startup
parentsmptests/smpatomic08: Avoid copy and paste (diff)
downloadrtems-0c47440c6a8bc6bab476bf787fb784490377a326.tar.bz2
bsp/lm4f120: new BSP to support TI LM4F120 XL LaunchPad board
Diffstat (limited to 'c/src/lib/libbsp/arm/lm3s69xx/startup')
-rw-r--r--c/src/lib/libbsp/arm/lm3s69xx/startup/bspstart.c59
-rw-r--r--c/src/lib/libbsp/arm/lm3s69xx/startup/linkcmds.lm4f12028
-rw-r--r--c/src/lib/libbsp/arm/lm3s69xx/startup/syscon.c9
3 files changed, 89 insertions, 7 deletions
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,10 +128,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/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;