aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dispatch/vector_nvic.c2
-rw-r--r--lib/stm32/desig.c (renamed from lib/stm32/f1/desig.c)2
-rw-r--r--lib/stm32/exti2.c (renamed from lib/stm32/f4/exti.c)20
-rw-r--r--lib/stm32/f2/Makefile4
-rw-r--r--lib/stm32/f2/exti.c146
-rw-r--r--lib/stm32/f4/Makefile4
-rw-r--r--lib/stm32/f4/gpio.c142
-rw-r--r--lib/stm32/gpio2.c (renamed from lib/stm32/f2/gpio.c)8
-rw-r--r--lib/stm32/l1/Makefile36
-rw-r--r--lib/stm32/l1/libopencm3_stm32l1.ld83
-rw-r--r--lib/stm32/l1/rcc.c357
-rw-r--r--lib/stm32/l1/stm32l15xx8.ld31
-rw-r--r--lib/stm32/l1/stm32l15xxb.ld31
-rw-r--r--lib/stm32/usart.c2
14 files changed, 574 insertions, 294 deletions
diff --git a/lib/dispatch/vector_nvic.c b/lib/dispatch/vector_nvic.c
index b8e9b7f..33104eb 100644
--- a/lib/dispatch/vector_nvic.c
+++ b/lib/dispatch/vector_nvic.c
@@ -4,6 +4,8 @@
# include "../stm32/f2/vector_nvic.c"
#elif defined(STM32F4)
# include "../stm32/f4/vector_nvic.c"
+#elif defined(STM32L1)
+# include "../stm32/l1/vector_nvic.c"
#elif defined(EFM32TG)
# include "../efm32/efm32tg/vector_nvic.c"
diff --git a/lib/stm32/f1/desig.c b/lib/stm32/desig.c
index 7ae968e..0743dc8 100644
--- a/lib/stm32/f1/desig.c
+++ b/lib/stm32/desig.c
@@ -17,7 +17,7 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libopencm3/stm32/f1/desig.h>
+#include <libopencm3/stm32/desig.h>
u16 desig_get_flash_size(void)
{
diff --git a/lib/stm32/f4/exti.c b/lib/stm32/exti2.c
index f69e99e..bea2f4d 100644
--- a/lib/stm32/f4/exti.c
+++ b/lib/stm32/exti2.c
@@ -2,6 +2,7 @@
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -15,11 +16,22 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This provides the code for the "next gen" EXTI block provided in F2/F4/L1
+ * devices. (differences only in the source selection)
*/
#include <libopencm3/stm32/exti.h>
-#include <libopencm3/stm32/f4/syscfg.h>
+#include <libopencm3/stm32/syscfg.h>
+#if defined(STM32F2)
+#include <libopencm3/stm32/f2/gpio.h>
+#elif defined(STM32F4)
#include <libopencm3/stm32/f4/gpio.h>
+#elif defined(STM32L1)
+#include <libopencm3/stm32/l1/gpio.h>
+#else
+#error "invalid/unknown stm32 family for this code"
+#endif
void exti_set_trigger(u32 extis, exti_trigger_type trig)
{
@@ -121,18 +133,24 @@ void exti_select_source(u32 exti, u32 gpioport)
case GPIOE:
bits = 0xb;
break;
+#if defined(STM32L1)
+#else
case GPIOF:
bits = 0xa;
break;
case GPIOG:
bits = 0x9;
break;
+#endif
case GPIOH:
bits = 0x8;
break;
+#if defined(STM32L1)
+#else
case GPIOI:
bits = 0x7;
break;
+#endif
}
/* Ensure that only valid EXTI lines are used. */
diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile
index 5cbb977..b64a033 100644
--- a/lib/stm32/f2/Makefile
+++ b/lib/stm32/f2/Makefile
@@ -28,8 +28,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32F2
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = rcc.o gpio.o usart.o spi.o flash.o \
- i2c.o exti.o timer.o
+OBJS = rcc.o gpio2.o usart.o spi.o flash.o \
+ i2c.o exti2.o timer.o
VPATH += ../../usb:../:../../cm3
diff --git a/lib/stm32/f2/exti.c b/lib/stm32/f2/exti.c
deleted file mode 100644
index 5280914..0000000
--- a/lib/stm32/f2/exti.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz>
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <libopencm3/stm32/exti.h>
-#include <libopencm3/stm32/f2/syscfg.h>
-#include <libopencm3/stm32/f2/gpio.h>
-
-void exti_set_trigger(u32 extis, exti_trigger_type trig)
-{
- switch (trig) {
- case EXTI_TRIGGER_RISING:
- EXTI_RTSR |= extis;
- EXTI_FTSR &= ~extis;
- break;
- case EXTI_TRIGGER_FALLING:
- EXTI_RTSR &= ~extis;
- EXTI_FTSR |= extis;
- break;
- case EXTI_TRIGGER_BOTH:
- EXTI_RTSR |= extis;
- EXTI_FTSR |= extis;
- break;
- }
-}
-
-void exti_enable_request(u32 extis)
-{
- /* Enable interrupts. */
- EXTI_IMR |= extis;
-
- /* Enable events. */
- EXTI_EMR |= extis;
-}
-
-void exti_disable_request(u32 extis)
-{
- /* Disable interrupts. */
- EXTI_IMR &= ~extis;
-
- /* Disable events. */
- EXTI_EMR &= ~extis;
-}
-
-/*
- * Reset the interrupt request by writing a 1 to the corresponding
- * pending bit register.
- */
-void exti_reset_request(u32 extis)
-{
- EXTI_PR = extis;
-}
-
-/*
- * Remap an external interrupt line to the corresponding pin on the
- * specified GPIO port.
- *
- * TODO: This could be rewritten in fewer lines of code.
- */
-void exti_select_source(u32 exti, u32 gpioport)
-{
- u8 shift, bits;
-
- shift = bits = 0;
-
- switch (exti) {
- case EXTI0:
- case EXTI4:
- case EXTI8:
- case EXTI12:
- shift = 0;
- break;
- case EXTI1:
- case EXTI5:
- case EXTI9:
- case EXTI13:
- shift = 4;
- break;
- case EXTI2:
- case EXTI6:
- case EXTI10:
- case EXTI14:
- shift = 8;
- break;
- case EXTI3:
- case EXTI7:
- case EXTI11:
- case EXTI15:
- shift = 12;
- break;
- }
-
- switch (gpioport) {
- case GPIOA:
- bits = 0xf;
- break;
- case GPIOB:
- bits = 0xe;
- break;
- case GPIOC:
- bits = 0xd;
- break;
- case GPIOD:
- bits = 0xc;
- break;
- case GPIOE:
- bits = 0xb;
- break;
- case GPIOF:
- bits = 0xa;
- break;
- case GPIOG:
- bits = 0x9;
- break;
- }
-
- /* Ensure that only valid EXTI lines are used. */
- if (exti < EXTI4) {
- SYSCFG_EXTICR1 &= ~(0x000F << shift);
- SYSCFG_EXTICR1 |= (~bits << shift);
- } else if (exti < EXTI8) {
- SYSCFG_EXTICR2 &= ~(0x000F << shift);
- SYSCFG_EXTICR2 |= (~bits << shift);
- } else if (exti < EXTI12) {
- SYSCFG_EXTICR3 &= ~(0x000F << shift);
- SYSCFG_EXTICR3 |= (~bits << shift);
- } else if (exti < EXTI16) {
- SYSCFG_EXTICR4 &= ~(0x000F << shift);
- SYSCFG_EXTICR4 |= (~bits << shift);
- }
-}
diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile
index 614a37e..09fe573 100644
--- a/lib/stm32/f4/Makefile
+++ b/lib/stm32/f4/Makefile
@@ -29,8 +29,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-ffunction-sections -fdata-sections -MD -DSTM32F4
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = rcc.o gpio.o usart.o spi.o flash.o \
- i2c.o exti.o pwr.o timer.o \
+OBJS = rcc.o gpio2.o usart.o spi.o flash.o \
+ i2c.o exti2.o pwr.o timer.o \
usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \
usb_f207.o adc.o dma.o
diff --git a/lib/stm32/f4/gpio.c b/lib/stm32/f4/gpio.c
deleted file mode 100644
index aa2fda4..0000000
--- a/lib/stm32/f4/gpio.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * This file is part of the libopencm3 project.
- *
- * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <libopencm3/stm32/f4/gpio.h>
-
-void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios)
-{
- u16 i;
- u32 moder, pupd;
-
- /*
- * We want to set the config only for the pins mentioned in gpios,
- * but keeping the others, so read out the actual config first.
- */
- moder = GPIO_MODER(gpioport);
- pupd = GPIO_PUPDR(gpioport);
-
- for (i = 0; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
-
- moder &= ~GPIO_MODE_MASK(i);
- moder |= GPIO_MODE(i, mode);
- pupd &= ~GPIO_PUPD_MASK(i);
- pupd |= GPIO_PUPD(i, pull_up_down);
- }
-
- /* Set mode and pull up/down control registers. */
- GPIO_MODER(gpioport) = moder;
- GPIO_PUPDR(gpioport) = pupd;
-}
-
-void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios)
-{
- u16 i;
- u32 ospeedr;
-
- if (otype == 0x1)
- GPIO_OTYPER(gpioport) |= gpios;
- else
- GPIO_OTYPER(gpioport) &= ~gpios;
-
- ospeedr = GPIO_OSPEEDR(gpioport);
-
- for (i = 0; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
- ospeedr &= ~GPIO_OSPEED_MASK(i);
- ospeedr |= GPIO_OSPEED(i, speed);
- }
-
- GPIO_OSPEEDR(gpioport) = ospeedr;
-}
-
-void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios)
-{
- u16 i;
- u32 afrl, afrh;
-
- afrl = GPIO_AFRL(gpioport);
- afrh = GPIO_AFRH(gpioport);
-
- for (i = 0; i < 8; i++) {
- if (!((1 << i) & gpios))
- continue;
- afrl &= ~GPIO_AFR_MASK(i);
- afrl |= GPIO_AFR(i, alt_func_num);
- }
-
- for (i = 8; i < 16; i++) {
- if (!((1 << i) & gpios))
- continue;
- afrh &= ~GPIO_AFR_MASK(i - 8);
- afrh |= GPIO_AFR(i - 8, alt_func_num);
- }
-
- GPIO_AFRL(gpioport) = afrl;
- GPIO_AFRH(gpioport) = afrh;
-}
-
-void gpio_set(u32 gpioport, u16 gpios)
-{
- GPIO_BSRR(gpioport) = gpios;
-}
-
-void gpio_clear(u32 gpioport, u16 gpios)
-{
- GPIO_BSRR(gpioport) = gpios << 16;
-}
-
-u16 gpio_get(u32 gpioport, u16 gpios)
-{
- return gpio_port_read(gpioport) & gpios;
-}
-
-void gpio_toggle(u32 gpioport, u16 gpios)
-{
- GPIO_ODR(gpioport) ^= gpios;
-}
-
-u16 gpio_port_read(u32 gpioport)
-{
- return (u16)GPIO_IDR(gpioport);
-}
-
-void gpio_port_write(u32 gpioport, u16 data)
-{
- GPIO_ODR(gpioport) = data;
-}
-
-void gpio_port_config_lock(u32 gpioport, u16 gpios)
-{
- u32 reg32;
-
- /* Special "Lock Key Writing Sequence", see datasheet. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */
- GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */
- reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */
-
- /* Tell the compiler the variable is actually used. It will get optimized out anyways. */
- reg32 = reg32;
-
- /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */
-}
diff --git a/lib/stm32/f2/gpio.c b/lib/stm32/gpio2.c
index c577c3a..c185e98 100644
--- a/lib/stm32/f2/gpio.c
+++ b/lib/stm32/gpio2.c
@@ -17,7 +17,15 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
+#if defined(STM32F2)
#include <libopencm3/stm32/f2/gpio.h>
+#elif defined(STM32F4)
+#include <libopencm3/stm32/f4/gpio.h>
+#elif defined(STM32L1)
+#include <libopencm3/stm32/l1/gpio.h>
+#else
+#error "invalid/unknown stm32 family for this code"
+#endif
void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios)
{
diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile
new file mode 100644
index 0000000..9e07b2d
--- /dev/null
+++ b/lib/stm32/l1/Makefile
@@ -0,0 +1,36 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+##
+## This library is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public License
+## along with this library. If not, see <http://www.gnu.org/licenses/>.
+##
+
+LIBNAME = libopencm3_stm32l1
+
+PREFIX ?= arm-none-eabi
+#PREFIX ?= arm-elf
+CC = $(PREFIX)-gcc
+AR = $(PREFIX)-ar
+CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
+ -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
+ -ffunction-sections -fdata-sections -MD -DSTM32L1
+# ARFLAGS = rcsv
+ARFLAGS = rcs
+OBJS = rcc.o gpio2.o desig.o crc.o usart.o exti2.o
+
+VPATH += ../../usb:../:../../cm3
+
+include ../../Makefile.include
+
diff --git a/lib/stm32/l1/libopencm3_stm32l1.ld b/lib/stm32/l1/libopencm3_stm32l1.ld
new file mode 100644
index 0000000..9d165f6
--- /dev/null
+++ b/lib/stm32/l1/libopencm3_stm32l1.ld
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Generic linker script for STM32 targets using libopencm3. */
+
+/* Memory regions must be defined in the ld script which includes this one. */
+
+/* Enforce emmition of the vector table. */
+EXTERN (vector_table)
+
+/* Define the entry point of the output file. */
+ENTRY(reset_handler)
+
+/* Define sections. */
+SECTIONS
+{
+ .text : {
+ *(.vectors) /* Vector table */
+ *(.text*) /* Program code */
+ . = ALIGN(4);
+ *(.rodata*) /* Read-only data */
+ . = ALIGN(4);
+ } >rom
+
+ /*
+ * Another section used by C++ stuff, appears when using newlib with
+ * 64bit (long long) printf support
+ */
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } >rom
+ .ARM.exidx : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >rom
+
+ . = ALIGN(4);
+ _etext = .;
+
+ .data : {
+ _data = .;
+ *(.data*) /* Read-write initialized data */
+ . = ALIGN(4);
+ _edata = .;
+ } >ram AT >rom
+ _data_loadaddr = LOADADDR(.data);
+
+ .bss : {
+ *(.bss*) /* Read-write zero initialized data */
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } >ram
+
+ /*
+ * The .eh_frame section appears to be used for C++ exception handling.
+ * You may need to fix this if you're using C++.
+ */
+ /DISCARD/ : { *(.eh_frame) }
+
+ . = ALIGN(4);
+ end = .;
+}
+
+PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
+
diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c
new file mode 100644
index 0000000..a023622
--- /dev/null
+++ b/lib/stm32/l1/rcc.c
@@ -0,0 +1,357 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com>
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ * Based on the F4 code...
+ */
+
+#include <libopencm3/stm32/l1/rcc.h>
+
+/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */
+u32 rcc_ppre1_frequency = 2097000;
+u32 rcc_ppre2_frequency = 2097000;
+
+void rcc_osc_ready_int_clear(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CIR |= RCC_CIR_PLLRDYC;
+ break;
+ case HSE:
+ RCC_CIR |= RCC_CIR_HSERDYC;
+ break;
+ case HSI:
+ RCC_CIR |= RCC_CIR_HSIRDYC;
+ break;
+ case LSE:
+ RCC_CIR |= RCC_CIR_LSERDYC;
+ break;
+ case LSI:
+ RCC_CIR |= RCC_CIR_LSIRDYC;
+ break;
+ case MSI:
+ RCC_CIR |= RCC_CIR_MSIRDYC;
+ break;
+ }
+}
+
+void rcc_osc_ready_int_enable(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CIR |= RCC_CIR_PLLRDYIE;
+ break;
+ case HSE:
+ RCC_CIR |= RCC_CIR_HSERDYIE;
+ break;
+ case HSI:
+ RCC_CIR |= RCC_CIR_HSIRDYIE;
+ break;
+ case LSE:
+ RCC_CIR |= RCC_CIR_LSERDYIE;
+ break;
+ case LSI:
+ RCC_CIR |= RCC_CIR_LSIRDYIE;
+ break;
+ case MSI:
+ RCC_CIR |= RCC_CIR_MSIRDYIE;
+ break;
+ }
+}
+
+void rcc_osc_ready_int_disable(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CIR &= ~RCC_CIR_PLLRDYIE;
+ break;
+ case HSE:
+ RCC_CIR &= ~RCC_CIR_HSERDYIE;
+ break;
+ case HSI:
+ RCC_CIR &= ~RCC_CIR_HSIRDYIE;
+ break;
+ case LSE:
+ RCC_CIR &= ~RCC_CIR_LSERDYIE;
+ break;
+ case LSI:
+ RCC_CIR &= ~RCC_CIR_LSIRDYIE;
+ break;
+ case MSI:
+ RCC_CIR &= ~RCC_CIR_MSIRDYIE;
+ break;
+ }
+}
+
+int rcc_osc_ready_int_flag(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
+ break;
+ case HSE:
+ return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
+ break;
+ case HSI:
+ return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0);
+ break;
+ case LSE:
+ return ((RCC_CIR & RCC_CIR_LSERDYF) != 0);
+ break;
+ case LSI:
+ return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0);
+ break;
+ case MSI:
+ return ((RCC_CIR & RCC_CIR_MSIRDYF) != 0);
+ break;
+ }
+
+ /* Shouldn't be reached. */
+ return -1;
+}
+
+void rcc_css_int_clear(void)
+{
+ RCC_CIR |= RCC_CIR_CSSC;
+}
+
+int rcc_css_int_flag(void)
+{
+ return ((RCC_CIR & RCC_CIR_CSSF) != 0);
+}
+
+void rcc_wait_for_osc_ready(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ while ((RCC_CR & RCC_CR_PLLRDY) == 0);
+ break;
+ case HSE:
+ while ((RCC_CR & RCC_CR_HSERDY) == 0);
+ break;
+ case HSI:
+ while ((RCC_CR & RCC_CR_HSIRDY) == 0);
+ break;
+ case MSI:
+ while ((RCC_CR & RCC_CR_MSIRDY) == 0);
+ break;
+ case LSE:
+ while ((RCC_CSR & RCC_CSR_LSERDY) == 0);
+ break;
+ case LSI:
+ while ((RCC_CSR & RCC_CSR_LSIRDY) == 0);
+ break;
+ }
+}
+
+void rcc_wait_for_sysclk_status(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_PLLCLK);
+ break;
+ case HSE:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_HSECLK);
+ break;
+ case HSI:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_HSICLK);
+ break;
+ case MSI:
+ while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_SYSCLKSEL_MSICLK);
+ break;
+ default:
+ /* Shouldn't be reached. */
+ break;
+ }
+}
+
+void rcc_osc_on(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CR |= RCC_CR_PLLON;
+ break;
+ case MSI:
+ RCC_CR |= RCC_CR_MSION;
+ break;
+ case HSE:
+ RCC_CR |= RCC_CR_HSEON;
+ break;
+ case HSI:
+ RCC_CR |= RCC_CR_HSION;
+ break;
+ case LSE:
+ RCC_CSR |= RCC_CSR_LSEON;
+ break;
+ case LSI:
+ RCC_CSR |= RCC_CSR_LSION;
+ break;
+ }
+}
+
+void rcc_osc_off(osc_t osc)
+{
+ switch (osc) {
+ case PLL:
+ RCC_CR &= ~RCC_CR_PLLON;
+ break;
+ case MSI:
+ RCC_CR &= ~RCC_CR_MSION;
+ break;
+ case HSE:
+ RCC_CR &= ~RCC_CR_HSEON;
+ break;
+ case HSI:
+ RCC_CR &= ~RCC_CR_HSION;
+ break;
+ case LSE:
+ RCC_CSR &= ~RCC_CSR_LSEON;
+ break;
+ case LSI:
+ RCC_CSR &= ~RCC_CSR_LSION;
+ break;
+ }
+}
+
+void rcc_css_enable(void)
+{
+ RCC_CR |= RCC_CR_CSSON;
+}
+
+void rcc_css_disable(void)
+{
+ RCC_CR &= ~RCC_CR_CSSON;
+}
+
+void rcc_osc_bypass_enable(osc_t osc)
+{
+ switch (osc) {
+ case HSE:
+ RCC_CR |= RCC_CR_HSEBYP;
+ break;
+ case LSE:
+ RCC_CSR |= RCC_CSR_LSEBYP;
+ break;
+ case PLL:
+ case HSI:
+ case LSI:
+ case MSI:
+ /* Do nothing, only HSE/LSE allowed here. */
+ break;
+ }
+}
+
+void rcc_osc_bypass_disable(osc_t osc)
+{
+ switch (osc) {
+ case HSE:
+ RCC_CR &= ~RCC_CR_HSEBYP;
+ break;
+ case LSE:
+ RCC_CSR &= ~RCC_CSR_LSEBYP;
+ break;
+ case PLL:
+ case HSI:
+ case LSI:
+ case MSI:
+ /* Do nothing, only HSE/LSE allowed here. */
+ break;
+ }
+}
+
+void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en)
+{
+ *reg |= en;
+}
+
+void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en)
+{
+ *reg &= ~en;
+}
+
+void rcc_peripheral_reset(volatile u32 *reg, u32 reset)
+{
+ *reg |= reset;
+}
+
+void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset)
+{
+ *reg &= ~clear_reset;
+}
+
+void rcc_set_sysclk_source(u32 clk)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 1) | (1 << 0));
+ RCC_CFGR = (reg32 | clk);
+}
+
+void rcc_set_pll_source(u32 pllsrc)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~(1 << 16);
+ RCC_CFGR = (reg32 | (pllsrc << 16));
+}
+
+void rcc_set_ppre2(u32 ppre2)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 13) | (1 << 12) | (1 << 11));
+ RCC_CFGR = (reg32 | (ppre2 << 11));
+}
+
+void rcc_set_ppre1(u32 ppre1)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 10) | (1 << 9) | (1 << 8));
+ RCC_CFGR = (reg32 | (ppre1 << 8));
+}
+
+void rcc_set_hpre(u32 hpre)
+{
+ u32 reg32;
+
+ reg32 = RCC_CFGR;
+ reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
+ RCC_CFGR = (reg32 | (hpre << 4));
+}
+
+void rcc_set_rtcpre(u32 rtcpre)
+{
+ u32 reg32;
+
+ reg32 = RCC_CR;
+ reg32 &= ~((1 << 30) | (1 << 29));
+ RCC_CR = (reg32 | (rtcpre << 29));
+}
+
+u32 rcc_system_clock_source(void)
+{
+ /* Return the clock source which is used as system clock. */
+ return ((RCC_CFGR & 0x000c) >> 2);
+}
+
diff --git a/lib/stm32/l1/stm32l15xx8.ld b/lib/stm32/l1/stm32l15xx8.ld
new file mode 100644
index 0000000..1f20f57
--- /dev/null
+++ b/lib/stm32/l1/stm32l15xx8.ld
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Linker script for STM32L15xx8, 64K flash, 10K RAM. */
+
+/* Define memory regions. */
+MEMORY
+{
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
+}
+
+/* Include the common ld script. */
+INCLUDE libopencm3_stm32l1.ld
+
diff --git a/lib/stm32/l1/stm32l15xxb.ld b/lib/stm32/l1/stm32l15xxb.ld
new file mode 100644
index 0000000..4c14b71
--- /dev/null
+++ b/lib/stm32/l1/stm32l15xxb.ld
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Linker script for STM32L15xxB, 128K flash, 16K RAM. */
+
+/* Define memory regions. */
+MEMORY
+{
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 16K
+}
+
+/* Include the common ld script. */
+INCLUDE libopencm3_stm32l1.ld
+
diff --git a/lib/stm32/usart.c b/lib/stm32/usart.c
index 5cf861b..1faf486 100644
--- a/lib/stm32/usart.c
+++ b/lib/stm32/usart.c
@@ -46,6 +46,8 @@ LGPL License Terms @ref lgpl_license
# include <libopencm3/stm32/f2/rcc.h>
#elif defined(STM32F4)
# include <libopencm3/stm32/f4/rcc.h>
+#elif defined(STM32L1)
+# include <libopencm3/stm32/l1/rcc.h>
#else
# error "stm32 family not defined."
#endif