1 | /* |
---|
2 | * This routine does the bulk of the system initialization. |
---|
3 | */ |
---|
4 | |
---|
5 | /* |
---|
6 | * Copyright (c) 2013 Eugeniy Meshcheryakov <eugen@debian.org> |
---|
7 | * |
---|
8 | * The license and distribution terms for this file may be |
---|
9 | * found in the file LICENSE in this distribution or at |
---|
10 | * http://www.rtems.org/license/LICENSE. |
---|
11 | */ |
---|
12 | |
---|
13 | #include <bsp.h> |
---|
14 | #include <bspopts.h> |
---|
15 | #include <bsp/bootcard.h> |
---|
16 | #include <bsp/irq-generic.h> |
---|
17 | #include <bsp/lm3s69xx.h> |
---|
18 | #include <bsp/io.h> |
---|
19 | #include <bsp/syscon.h> |
---|
20 | #include <assert.h> |
---|
21 | |
---|
22 | static void init_main_osc(void) |
---|
23 | { |
---|
24 | volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; |
---|
25 | |
---|
26 | uint32_t sysdiv_val = LM3S69XX_PLL_FREQUENCY / LM3S69XX_SYSTEM_CLOCK; |
---|
27 | #if defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM3S3749) |
---|
28 | assert(sysdiv_val * LM3S69XX_SYSTEM_CLOCK == LM3S69XX_PLL_FREQUENCY); |
---|
29 | #endif |
---|
30 | assert((sysdiv_val >= 4) && (sysdiv_val <= 16)); |
---|
31 | |
---|
32 | uint32_t rcc = syscon->rcc; |
---|
33 | uint32_t rcc2 = syscon->rcc2; |
---|
34 | |
---|
35 | rcc = (rcc & ~SYSCONRCC_USESYSDIV) | SYSCONRCC_BYPASS; |
---|
36 | rcc2 |= SYSCONRCC2_BYPASS2; |
---|
37 | |
---|
38 | syscon->rcc = rcc; |
---|
39 | syscon->rcc2 = rcc2; |
---|
40 | |
---|
41 | /* |
---|
42 | As per a note in Stellaris® LM4F120H5QR Microcontroller Data |
---|
43 | Sheet on page 219: "When transitioning the system clock |
---|
44 | configuration to use the MOSC as the fundamental clock source, the |
---|
45 | MOSCDIS bit must be set prior to reselecting the MOSC or an |
---|
46 | undefined system clock configuration can sporadically occur." |
---|
47 | */ |
---|
48 | |
---|
49 | rcc |= SYSCONRCC_MOSCDIS; |
---|
50 | syscon->rcc = rcc; |
---|
51 | |
---|
52 | rcc = (rcc & ~(SYSCONRCC_XTAL_MSK)) |
---|
53 | | SYSCONRCC_XTAL(LM3S69XX_XTAL_CONFIG); |
---|
54 | rcc2 = (rcc2 & ~(SYSCONRCC2_PWRDN2 | SYSCONRCC2_OSCSRC2_MSK)) |
---|
55 | | SYSCONRCC2_USERCC2 | SYSCONRCC2_OSCSRC2(0x0); |
---|
56 | |
---|
57 | /* clear PLL lock interrupt */ |
---|
58 | syscon->misc &= (SYSCONMISC_PLLLMIS); |
---|
59 | |
---|
60 | syscon->rcc = rcc; |
---|
61 | syscon->rcc2 = rcc2; |
---|
62 | lm3s69xx_syscon_delay_3x_clocks(16); |
---|
63 | |
---|
64 | /* since now, we'll use only RCC2 as SYSCONRCC2_USERCC2 and XTAL |
---|
65 | (only available in RCC) are already set */ |
---|
66 | |
---|
67 | if (sysdiv_val % 2 == 0) { |
---|
68 | rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2_MSK) | SYSCONRCC2_SYSDIV2(sysdiv_val / 2 - 1); |
---|
69 | |
---|
70 | rcc2 &= ~(SYSCONRCC2_DIV400); |
---|
71 | } |
---|
72 | else { |
---|
73 | /* need to use DIV400 */ |
---|
74 | rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2EXT_MSK) | SYSCONRCC2_SYSDIV2EXT(sysdiv_val - 1) |
---|
75 | | SYSCONRCC2_DIV400; |
---|
76 | } |
---|
77 | syscon->rcc2 = rcc2; |
---|
78 | |
---|
79 | while ((syscon->ris & SYSCONRIS_PLLLRIS) == 0) |
---|
80 | /* Wait for PLL lock */; |
---|
81 | |
---|
82 | rcc2 &= ~(SYSCONRCC2_BYPASS2); |
---|
83 | |
---|
84 | syscon->rcc2 = rcc2; |
---|
85 | lm3s69xx_syscon_delay_3x_clocks(16); |
---|
86 | } |
---|
87 | |
---|
88 | static const lm3s69xx_gpio_config start_config_gpio[] = { |
---|
89 | #ifdef LM3S69XX_ENABLE_UART_0 |
---|
90 | #if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM4F120) |
---|
91 | LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_A, 0), |
---|
92 | LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_A, 1), |
---|
93 | #else |
---|
94 | #error No GPIO pin configuration for UART 0 |
---|
95 | #endif |
---|
96 | #endif /* LM3S69XX_ENABLE_UART_0 */ |
---|
97 | |
---|
98 | #ifdef LM3S69XX_ENABLE_UART_1 |
---|
99 | #if defined(LM3S69XX_MCU_LM3S3749) |
---|
100 | LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0), |
---|
101 | LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1), |
---|
102 | #elif defined(LM3S69XX_MCU_LM3S6965) |
---|
103 | LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 2), |
---|
104 | LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 3), |
---|
105 | #elif defined(LM3S69XX_MCU_LM4F120) |
---|
106 | LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0), |
---|
107 | LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1), |
---|
108 | LM3S69XX_PIN_UART_RTS(LM3S69XX_PORT_C, 4), |
---|
109 | LM3S69XX_PIN_UART_CTS(LM3S69XX_PORT_C, 5), |
---|
110 | #else |
---|
111 | #error No GPIO pin configuration for UART 1 |
---|
112 | #endif |
---|
113 | #endif /* LM3S69XX_ENABLE_UART_1 */ |
---|
114 | |
---|
115 | #ifdef LM3S69XX_ENABLE_UART_2 |
---|
116 | #if defined(LM3S69XX_MCU_LM3S3749) |
---|
117 | LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 0), |
---|
118 | LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 1), |
---|
119 | #elif defined(LM3S69XX_MCU_LM3S6965) |
---|
120 | LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_G, 0), |
---|
121 | LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_G, 1), |
---|
122 | #else |
---|
123 | #error No GPIO pin configuration for UART 2 |
---|
124 | #endif |
---|
125 | #endif /* LM3S69XX_ENABLE_UART_2 */ |
---|
126 | }; |
---|
127 | |
---|
128 | static void init_gpio(void) |
---|
129 | { |
---|
130 | #if LM3S69XX_USE_AHB_FOR_GPIO |
---|
131 | volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; |
---|
132 | |
---|
133 | syscon->gpiohbctl |= SYSCONGPIOHBCTL_PORTA | SYSCONGPIOHBCTL_PORTB |
---|
134 | | SYSCONGPIOHBCTL_PORTC | SYSCONGPIOHBCTL_PORTD |
---|
135 | | SYSCONGPIOHBCTL_PORTE | SYSCONGPIOHBCTL_PORTF |
---|
136 | #if LM3S69XX_NUM_GPIO_BLOCKS > 6 |
---|
137 | | SYSCONGPIOHBCTL_PORTG |
---|
138 | #if LM3S69XX_NUM_GPIO_BLOCKS > 7 |
---|
139 | | SYSCONGPIOHBCTL_PORTH |
---|
140 | #endif |
---|
141 | #endif |
---|
142 | ; |
---|
143 | |
---|
144 | #endif /* LM3S69XX_USE_AHB_FOR_GPIO */ |
---|
145 | |
---|
146 | lm3s69xx_gpio_set_config_array(start_config_gpio, |
---|
147 | sizeof(start_config_gpio) / sizeof(start_config_gpio[0])); |
---|
148 | } |
---|
149 | |
---|
150 | void bsp_start(void) |
---|
151 | { |
---|
152 | init_main_osc(); |
---|
153 | init_gpio(); |
---|
154 | bsp_interrupt_initialize(); |
---|
155 | } |
---|