diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 10:35:35 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-20 13:52:14 +0200 |
commit | 99648958668d3a33ee57974479b36201fe303f34 (patch) | |
tree | 6f27ea790e2823c6156e71219a4f54680263fac6 /bsps/arm/lm3s69xx | |
parent | bsps: Move start files to bsps (diff) | |
download | rtems-99648958668d3a33ee57974479b36201fe303f34.tar.bz2 |
bsps: Move startup files to bsps
Adjust build support files to new directory layout.
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'bsps/arm/lm3s69xx')
-rw-r--r-- | bsps/arm/lm3s69xx/start/bsp_specs | 9 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/bspstart.c | 155 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/bspstarthook.c | 29 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/io.c | 144 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/linkcmds.lm3s3749 | 30 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/linkcmds.lm3s6965 | 30 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu | 30 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/linkcmds.lm4f120 | 30 | ||||
-rw-r--r-- | bsps/arm/lm3s69xx/start/syscon.c | 115 |
9 files changed, 572 insertions, 0 deletions
diff --git a/bsps/arm/lm3s69xx/start/bsp_specs b/bsps/arm/lm3s69xx/start/bsp_specs new file mode 100644 index 0000000000..47dd31d46b --- /dev/null +++ b/bsps/arm/lm3s69xx/start/bsp_specs @@ -0,0 +1,9 @@ +%rename endfile old_endfile +%rename startfile old_startfile + +*startfile: +%{!qrtems: %(old_startfile)} \ +%{!nostdlib: %{qrtems: crti.o%s crtbegin.o%s}} + +*endfile: +%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s} diff --git a/bsps/arm/lm3s69xx/start/bspstart.c b/bsps/arm/lm3s69xx/start/bspstart.c new file mode 100644 index 0000000000..da3029e58c --- /dev/null +++ b/bsps/arm/lm3s69xx/start/bspstart.c @@ -0,0 +1,155 @@ +/* + * This routine does the bulk of the system initialization. + */ + +/* + * Copyright © 2013 Eugeniy Meshcheryakov <eugen@debian.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bspopts.h> +#include <bsp/bootcard.h> +#include <bsp/irq-generic.h> +#include <bsp/lm3s69xx.h> +#include <bsp/io.h> +#include <bsp/syscon.h> +#include <assert.h> + +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; + + /* + 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_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 */; + + 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) || defined(LM3S69XX_MCU_LM4F120) + LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_A, 0), + LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_A, 1), +#else +#error No GPIO pin configuration for UART 0 +#endif +#endif /* LM3S69XX_ENABLE_UART_0 */ + +#ifdef LM3S69XX_ENABLE_UART_1 +#if defined(LM3S69XX_MCU_LM3S3749) + LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_B, 0), + LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_B, 1), +#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 +#endif /* LM3S69XX_ENABLE_UART_1 */ + +#ifdef LM3S69XX_ENABLE_UART_2 +#if defined(LM3S69XX_MCU_LM3S3749) + LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_D, 0), + LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_D, 1), +#elif defined(LM3S69XX_MCU_LM3S6965) + LM3S69XX_PIN_UART_RX(LM3S69XX_PORT_G, 0), + LM3S69XX_PIN_UART_TX(LM3S69XX_PORT_G, 1), +#else +#error No GPIO pin configuration for UART 2 +#endif +#endif /* LM3S69XX_ENABLE_UART_2 */ +}; + +static void init_gpio(void) +{ +#if LM3S69XX_USE_AHB_FOR_GPIO + volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; + + 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 */ + + lm3s69xx_gpio_set_config_array(start_config_gpio, + sizeof(start_config_gpio) / sizeof(start_config_gpio[0])); +} + +void bsp_start(void) +{ + init_main_osc(); + init_gpio(); + bsp_interrupt_initialize(); +} diff --git a/bsps/arm/lm3s69xx/start/bspstarthook.c b/bsps/arm/lm3s69xx/start/bspstarthook.c new file mode 100644 index 0000000000..0524577ea7 --- /dev/null +++ b/bsps/arm/lm3s69xx/start/bspstarthook.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2011-2012 Sebastian Huber. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bsp/start.h> + +void BSP_START_TEXT_SECTION bsp_start_hook_0(void) +{ + /* Do nothing */ +} + +void BSP_START_TEXT_SECTION bsp_start_hook_1(void) +{ + bsp_start_copy_sections(); + bsp_start_clear_bss(); + + /* At this point we can use objects outside the .start section */ +} diff --git a/bsps/arm/lm3s69xx/start/io.c b/bsps/arm/lm3s69xx/start/io.c new file mode 100644 index 0000000000..b476e7b6dd --- /dev/null +++ b/bsps/arm/lm3s69xx/start/io.c @@ -0,0 +1,144 @@ +/* + * Copyright © 2013 Eugeniy Meshcheryakov <eugen@debian.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp/io.h> +#include <bsp/lm3s69xx.h> +#include <bsp/syscon.h> +#include <rtems.h> + +static void set_bit(volatile uint32_t *reg, unsigned index, uint32_t set) +{ + uint32_t mask = 1U; + uint32_t val = *reg; + + val &= ~(mask << index); + val |= set << index; + + *reg = val; +} + +static void set_config(unsigned int pin, const lm3s69xx_gpio_config *config) +{ + unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin); + volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port); + unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin); + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + lm3s69xx_syscon_enable_gpio_clock(port, true); + + /* Disable digital and analog functions before reconfiguration. */ + set_bit(&gpio->den, index, 0); + set_bit(&gpio->amsel, index, 0); + + set_bit(&gpio->afsel, index, config->alternate); + set_bit(&gpio->dir, index, config->dir); + set_bit(&gpio->odr, index, config->otype); + + switch (config->drive) { + case LM3S69XX_GPIO_DRIVE_4MA: + gpio->dr4r |= 1 << index; + break; + case LM3S69XX_GPIO_DRIVE_8MA: + gpio->dr8r |= 1 << index; + break; + default: + gpio->dr2r |= 1 << index; + break; + } + + switch (config->pull) { + case LM3S69XX_GPIO_PULL_UP: + gpio->pur |= 1 << index; + break; + case LM3S69XX_GPIO_PULL_DOWN: + gpio->pdr |= 1 << index; + break; + default: + set_bit(&gpio->pdr, index, 0); + set_bit(&gpio->pur, index, 0); + break; + } + + set_bit(&gpio->slr, index, config->slr); + + set_bit(&gpio->den, index, config->digital); + set_bit(&gpio->amsel, index, config->analog); + + rtems_interrupt_enable(level); +} + +void lm3s69xx_gpio_set_config(const lm3s69xx_gpio_config *config) +{ + unsigned int current = config->pin_first; + unsigned int last = config->pin_last; + + while (current <= last) { + set_config(current, config); + current++; + } +} + +void lm3s69xx_gpio_set_config_array(const lm3s69xx_gpio_config *configs, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) + lm3s69xx_gpio_set_config(&configs[i]); +} + +/** + * Enables/disables digital function on the specified pin. + */ +void lm3s69xx_gpio_digital_enable(unsigned int pin, bool enable) +{ + unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin); + volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port); + unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin); + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + set_bit(&gpio->den, index, enable); + rtems_interrupt_enable(level); +} + +/** + * Enables/disables analog mode on the specified pin. + */ +void lm3s69xx_gpio_analog_mode_select(unsigned int pin, bool enable) +{ + unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin); + volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port); + unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin); + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + set_bit(&gpio->amsel, index, enable); + rtems_interrupt_enable(level); +} + +void lm3s69xx_gpio_set_pin(unsigned int pin, bool set) +{ + unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin); + volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port); + unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin); + uint32_t mask = 1U << index; + + gpio->data[mask] = set ? mask : 0; +} + +bool lm3s69xx_gpio_get_pin(unsigned int pin) +{ + unsigned int port = LM3S69XX_GPIO_PORT_OF_PIN(pin); + volatile lm3s69xx_gpio *gpio = LM3S69XX_GPIO(port); + unsigned int index = LM3S69XX_GPIO_INDEX_OF_PIN(pin); + uint32_t mask = 1U << index; + + return gpio->data[mask] != 0; +} diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm3s3749 b/bsps/arm/lm3s69xx/start/linkcmds.lm3s3749 new file mode 100644 index 0000000000..ff165c7835 --- /dev/null +++ b/bsps/arm/lm3s69xx/start/linkcmds.lm3s3749 @@ -0,0 +1,30 @@ +/** + * @file + * + * @brief Memory map. + */ + +MEMORY { + RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 64K + ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 128K +} + +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); +REGION_ALIAS ("REGION_NOCACHE", RAM_INT); +REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT); + +INCLUDE linkcmds.armv7m diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965 b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965 new file mode 100644 index 0000000000..02d2487dc9 --- /dev/null +++ b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965 @@ -0,0 +1,30 @@ +/** + * @file + * + * @brief Memory map. + */ + +MEMORY { + RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 64K + 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); +REGION_ALIAS ("REGION_NOCACHE", RAM_INT); +REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT); + +INCLUDE linkcmds.armv7m diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu new file mode 100644 index 0000000000..a4d3a1972d --- /dev/null +++ b/bsps/arm/lm3s69xx/start/linkcmds.lm3s6965_qemu @@ -0,0 +1,30 @@ +/** + * @file + * + * @brief Memory map. + */ + +MEMORY { + RAM_INT (AIW) : ORIGIN = 0x20000000, LENGTH = 16M + ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 64M +} + +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); +REGION_ALIAS ("REGION_NOCACHE", RAM_INT); +REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT); + +INCLUDE linkcmds.armv7m diff --git a/bsps/arm/lm3s69xx/start/linkcmds.lm4f120 b/bsps/arm/lm3s69xx/start/linkcmds.lm4f120 new file mode 100644 index 0000000000..e995a3ddbf --- /dev/null +++ b/bsps/arm/lm3s69xx/start/linkcmds.lm4f120 @@ -0,0 +1,30 @@ +/** + * @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); +REGION_ALIAS ("REGION_NOCACHE", RAM_INT); +REGION_ALIAS ("REGION_NOCACHE_LOAD", RAM_INT); + +INCLUDE linkcmds.armv7m diff --git a/bsps/arm/lm3s69xx/start/syscon.c b/bsps/arm/lm3s69xx/start/syscon.c new file mode 100644 index 0000000000..1f5a1a3596 --- /dev/null +++ b/bsps/arm/lm3s69xx/start/syscon.c @@ -0,0 +1,115 @@ +/* + * Copyright © 2013 Eugeniy Meshcheryakov <eugen@debian.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp/syscon.h> +#include <bsp/lm3s69xx.h> +#include <rtems.h> + +static void delay_3_clocks(void) +{ + asm volatile( + "nop\n\t" + "nop\n\t" + "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; + uint32_t mask = 1 << port; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + if (enable) + syscon->rcgc2 |= mask; + else + syscon->rcgc2 &= ~mask; + + delay_3_clocks(); + + rtems_interrupt_enable(level); +} + +void lm3s69xx_syscon_enable_uart_clock(unsigned int port, bool enable) +{ + volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; + uint32_t mask = 1 << port; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + if (enable) + syscon->rcgc1 |= mask; + else + syscon->rcgc1 &= ~mask; + + delay_3_clocks(); + + rtems_interrupt_enable(level); +} + +void lm3s69xx_syscon_enable_ssi_clock(unsigned int port, bool enable) +{ + volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; + uint32_t mask = 1 << (port + 4); + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + if (enable) + syscon->rcgc1 |= mask; + else + syscon->rcgc1 &= ~mask; + + delay_3_clocks(); + + rtems_interrupt_enable(level); +} + +void lm3s69xx_syscon_enable_pwm_clock(bool enable) +{ + volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + + if (enable) + syscon->rcgc0 |= SYSCONRCGC0_PWM; + else + syscon->rcgc0 &= ~SYSCONRCGC0_PWM; + + delay_3_clocks(); + + rtems_interrupt_enable(level); +} + +/** + * Sets PWMDIV field in the RCC register. + * + * @note div should be one of SCRCC_PWMDIV_DIV?_VAL constants. + */ +void lm3s69xx_syscon_set_pwmdiv(unsigned int div) +{ + volatile lm3s69xx_syscon *syscon = LM3S69XX_SYSCON; + rtems_interrupt_level level; + + rtems_interrupt_disable(level); + syscon->rcc = (syscon->rcc & ~SYSCONRCC_PWMDIV_MSK) | SYSCONRCC_PWMDIV(div) + | SYSCONRCC_USEPWMDIV; + rtems_interrupt_enable(level); +} |