Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:03

0001 /*
0002  *  This routine does the bulk of the system initialization.
0003  */
0004 
0005 /*
0006  * Copyright (c) 2013 Eugeniy Meshcheryakov <eugen@debian.org>
0007  *
0008  * The license and distribution terms for this file may be
0009  * found in the file LICENSE in this distribution or at
0010  * http://www.rtems.org/license/LICENSE.
0011  */
0012 
0013 #include <bsp.h>
0014 #include <bspopts.h>
0015 #include <bsp/bootcard.h>
0016 #include <bsp/irq-generic.h>
0017 #include <bsp/lm3s69xx.h>
0018 #include <bsp/io.h>
0019 #include <bsp/syscon.h>
0020 #include <assert.h>
0021 
0022 static void init_main_osc(void)
0023 {
0024   volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
0025 
0026   uint32_t sysdiv_val = LM3S69XX_PLL_FREQUENCY / LM3S69XX_SYSTEM_CLOCK;
0027 #if defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM3S3749)
0028   assert(sysdiv_val * LM3S69XX_SYSTEM_CLOCK == LM3S69XX_PLL_FREQUENCY);
0029 #endif
0030   assert((sysdiv_val >= 4) && (sysdiv_val <= 16));
0031 
0032   uint32_t rcc = syscon->rcc;
0033   uint32_t rcc2 = syscon->rcc2;
0034 
0035   rcc = (rcc & ~SYSCONRCC_USESYSDIV) | SYSCONRCC_BYPASS;
0036   rcc2 |= SYSCONRCC2_BYPASS2;
0037 
0038   syscon->rcc = rcc;
0039   syscon->rcc2 = rcc2;
0040 
0041   /*
0042    As per a note in Stellaris(R) LM4F120H5QR Microcontroller Data
0043    Sheet on page 219: "When transitioning the system clock
0044    configuration to use the MOSC as the fundamental clock source, the
0045    MOSCDIS bit must be set prior to reselecting the MOSC or an
0046    undefined system clock configuration can sporadically occur."
0047   */
0048 
0049   rcc |= SYSCONRCC_MOSCDIS;
0050   syscon->rcc = rcc;
0051 
0052   rcc = (rcc & ~(SYSCONRCC_XTAL_MSK))
0053       | SYSCONRCC_XTAL(LM3S69XX_XTAL_CONFIG);
0054   rcc2 = (rcc2 & ~(SYSCONRCC2_PWRDN2 | SYSCONRCC2_OSCSRC2_MSK))
0055       | SYSCONRCC2_USERCC2 | SYSCONRCC2_OSCSRC2(0x0);
0056 
0057   /* clear PLL lock interrupt */
0058   syscon->misc &= (SYSCONMISC_PLLLMIS);
0059 
0060   syscon->rcc = rcc;
0061   syscon->rcc2 = rcc2;
0062   lm3s69xx_syscon_delay_3x_clocks(16);
0063 
0064   /* since now, we'll use only RCC2 as SYSCONRCC2_USERCC2 and XTAL
0065      (only available in RCC) are already set */
0066 
0067   if (sysdiv_val % 2 == 0) {
0068       rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2_MSK) | SYSCONRCC2_SYSDIV2(sysdiv_val / 2 - 1);
0069 
0070       rcc2 &= ~(SYSCONRCC2_DIV400);
0071   }
0072   else {
0073       /* need to use DIV400 */
0074       rcc2 = (rcc2 & ~SYSCONRCC2_SYSDIV2EXT_MSK) | SYSCONRCC2_SYSDIV2EXT(sysdiv_val - 1)
0075           | SYSCONRCC2_DIV400;
0076   }
0077   syscon->rcc2 = rcc2;
0078 
0079   while ((syscon->ris & SYSCONRIS_PLLLRIS) == 0)
0080       /* Wait for PLL lock */;
0081 
0082   rcc2 &= ~(SYSCONRCC2_BYPASS2);
0083 
0084   syscon->rcc2 = rcc2;
0085   lm3s69xx_syscon_delay_3x_clocks(16);
0086 }
0087 
0088 static const lm3s69xx_gpio_config start_config_gpio[] = {
0089 #ifdef LM3S69XX_ENABLE_UART_0
0090 #if defined(LM3S69XX_MCU_LM3S3749) || defined(LM3S69XX_MCU_LM3S6965) || defined(LM3S69XX_MCU_LM4F120)
0091   LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_A, 0),
0092   LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_A, 1),
0093 #else
0094 #error No GPIO pin configuration for UART 0
0095 #endif
0096 #endif /* LM3S69XX_ENABLE_UART_0 */
0097 
0098 #ifdef LM3S69XX_ENABLE_UART_1
0099 #if defined(LM3S69XX_MCU_LM3S3749)
0100   LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0),
0101   LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1),
0102 #elif defined(LM3S69XX_MCU_LM3S6965)
0103   LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 2),
0104   LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 3),
0105 #elif defined(LM3S69XX_MCU_LM4F120)
0106   LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0),
0107   LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1),
0108   LM3S69XX_PIN_UART_RTS(LM3S69XX_PORT_C, 4),
0109   LM3S69XX_PIN_UART_CTS(LM3S69XX_PORT_C, 5),
0110 #else
0111 #error No GPIO pin configuration for UART 1
0112 #endif
0113 #endif /* LM3S69XX_ENABLE_UART_1 */
0114 
0115 #ifdef LM3S69XX_ENABLE_UART_2
0116 #if defined(LM3S69XX_MCU_LM3S3749)
0117   LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 0),
0118   LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 1),
0119 #elif defined(LM3S69XX_MCU_LM3S6965)
0120   LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_G, 0),
0121   LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_G, 1),
0122 #else
0123 #error No GPIO pin configuration for UART 2
0124 #endif
0125 #endif /* LM3S69XX_ENABLE_UART_2 */
0126 };
0127 
0128 static void init_gpio(void)
0129 {
0130 #if LM3S69XX_USE_AHB_FOR_GPIO
0131   volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON;
0132 
0133   syscon->gpiohbctl |= SYSCONGPIOHBCTL_PORTA | SYSCONGPIOHBCTL_PORTB
0134       | SYSCONGPIOHBCTL_PORTC | SYSCONGPIOHBCTL_PORTD
0135       | SYSCONGPIOHBCTL_PORTE | SYSCONGPIOHBCTL_PORTF
0136 #if LM3S69XX_NUM_GPIO_BLOCKS > 6
0137       | SYSCONGPIOHBCTL_PORTG
0138 #if LM3S69XX_NUM_GPIO_BLOCKS > 7
0139       | SYSCONGPIOHBCTL_PORTH
0140 #endif
0141 #endif
0142       ;
0143 
0144 #endif /* LM3S69XX_USE_AHB_FOR_GPIO */
0145 
0146   lm3s69xx_gpio_set_config_array(start_config_gpio,
0147       sizeof(start_config_gpio) / sizeof(start_config_gpio[0]));
0148 }
0149 
0150 void bsp_start(void)
0151 {
0152   init_main_osc();
0153   init_gpio();
0154   bsp_interrupt_initialize();
0155 }