diff --git a/include/libopencm3/lm3s/rcc.h b/include/libopencm3/lm3s/rcc.h
new file mode 100644
index 00000000..853f90e4
--- /dev/null
+++ b/include/libopencm3/lm3s/rcc.h
@@ -0,0 +1,107 @@
+/** @defgroup rcc_defines RCC Defines
+ *
+ * @brief Defined Constants and Types for the LM3S Reset and Clock
+ * Control
+ *
+ * @ingroup LM3S_defines
+ *
+ * @version 1.0.0
+ *
+ * @author @htmlonly © @endhtmlonly 2009
+ * Daniele Lacamera \
+ *
+ * @date 21 November 2015
+ *
+ * LGPL License Terms @ref lgpl_license
+ * */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2015 Daniele Lacamera
+ *
+ * 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 .
+ */
+
+#ifndef LIBOPENCM3_RCC_H
+#define LIBOPENCM3_RCC_H
+#include
+
+/* --- RCC registers ------------------------------------------------------- */
+
+#define RCC_RIS MMIO32(0x400FE050)
+#define RCC_CR MMIO32(0x400FE060)
+#define RCC2_CR MMIO32(0x400FE070)
+
+/* RCC1 bits */
+#define RCC_SYSDIV_MASK (0x0F << 23)
+#define RCC_SYSDIV_12_5MHZ (0x0F << 23)
+#define RCC_SYSDIV_50MHZ (0x03 << 23)
+
+#define RCC_USESYSDIV (1 << 22)
+#define RCC_USEPWMDIV (1 << 20)
+
+#define RCC_PWMDIV_MASK (0x07 << 17)
+#define RCC_PWMDIV_64 (0x07 << 17)
+
+#define RCC_OFF (1 << 13)
+#define RCC_BYPASS (1 << 11)
+
+#define RCC_XTAL_MASK (0x0F << 6)
+/* For other values, see datasheet section 23.2.2 - table 23-9 */
+#define RCC_XTAL_6MHZ_RESET (0x0B << 6)
+#define RCC_XTAL_8MHZ_400MHZ (0x0D << 6)
+
+
+#define RCC_OSCRC_MASK (0x03 << 4)
+#define RCC_OSCRC_MOSC (0x00 << 4)
+#define RCC_OSCRC_IOSC (0x01 << 4)
+#define RCC_OSCRC_IOSC_Q (0x02 << 4)
+#define RCC_OSCRC_30KHZ (0x03 << 4)
+
+#define RCC_IOSCDIS (1 << 1)
+#define RCC_MOSCDIS (1 << 0)
+
+/* RCC2 bits */
+#define RCC2_USERRCC2 (1 << 31)
+#define RCC2_SYSDIV2_MASK 0x7f
+#define RCC2_SYSDIV2_SHIFT 23
+
+#define RCC2_OFF (1 << 13)
+#define RCC2_BYPASS (1 << 11)
+
+/* RIS bit */
+#define RIS_PLLLRIS (1 << 6)
+
+
+/* From Datasheet description for reset values
+ * Section 6.4 - Register Descriptions
+ */
+
+/* Register 8: RCC
+ * Type R/W, reset 0x078E.3AD1
+ */
+#define RCC_RESET_VALUE (0x078E3AD1)
+
+/* Register 10: RCC2
+ * Type R/W, reset 0x0780.2810
+ */
+#define RCC2_RESET_VALUE (0x07802810)
+
+BEGIN_DECLS
+
+int rcc_clock_setup_in_xtal_8mhz_out_50mhz(void);
+
+END_DECLS
+
+#endif
diff --git a/include/libopencm3/lm3s/usart.h b/include/libopencm3/lm3s/usart.h
new file mode 100644
index 00000000..09aa2af6
--- /dev/null
+++ b/include/libopencm3/lm3s/usart.h
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2015 Daniele Lacamera
+ *
+ * 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 .
+ */
+
+#ifndef LM3S_USART_H
+#define LM3S_USART_H
+
+#include
+
+
+
+#define USART0_BASE 0x4000C000
+#define USART1_BASE 0x4000D000
+#define USART2_BASE 0x4000E000
+
+/* --- Universal Synchronous Asynchronous Receiver Transmitter (USART) */
+#define USART_DR(x) MMIO32((x) + 0x0000)
+#define USART_IR(x) MMIO32((x) + 0x0004)
+#define USART_FR(x) MMIO32((x) + 0x0018)
+#define USART_ILPR(x) MMIO32((x) + 0x0020)
+#define USART_IBRD(x) MMIO32((x) + 0x0024)
+#define USART_FBRD(x) MMIO32((x) + 0x0028)
+#define USART_LCRH(x) MMIO32((x) + 0x002c)
+#define USART_CTL(x) MMIO32((x) + 0x0030)
+#define USART_IFLS(x) MMIO32((x) + 0x0034)
+#define USART_IM(x) MMIO32((x) + 0x0038)
+#define USART_RIS(x) MMIO32((x) + 0x003c)
+#define USART_MIS(x) MMIO32((x) + 0x0040)
+#define USART_IC(x) MMIO32((x) + 0x0044)
+
+/* USART Data Register (USART_DR) */
+/* Bits [31:12] - Reserved */
+#define USART_DR_OE (0x01 << 11)
+#define USART_DR_BE (0x01 << 10)
+#define USART_DR_PE (0x01 << 9)
+#define USART_DR_FE (0x01 << 8)
+
+/* USART Flags Register (USART_FR) */
+/* Bits [31:8] - Reserved */
+#define USART_FR_TXFE (0x01 << 7)
+#define USART_FR_RXFF (0x01 << 6)
+#define USART_FR_TXFF (0x01 << 5)
+#define USART_FR_RXFE (0x01 << 4)
+#define USART_FR_BUSY (0x01 << 3)
+/* Bits [2:0] - Reserved */
+
+/* USART Interrupt Mask Register (USART_IM) */
+/* Bits [31:11] - Reserved */
+#define USART_IM_OE (0x01 << 10)
+#define USART_IM_BE (0x01 << 9)
+#define USART_IM_PE (0x01 << 8)
+#define USART_IM_FE (0x01 << 7)
+#define USART_IM_RT (0x01 << 6)
+#define USART_IM_TX (0x01 << 5)
+#define USART_IM_RX (0x01 << 4)
+/* Bits [3:0] - Reserved */
+
+/* USART Interrupt Clear Register (USART_IC) */
+/* Bits [31:11] - Reserved */
+#define USART_IC_OE (0x01 << 10)
+#define USART_IC_BE (0x01 << 9)
+#define USART_IC_PE (0x01 << 8)
+#define USART_IC_FE (0x01 << 7)
+#define USART_IC_RT (0x01 << 6)
+#define USART_IC_TX (0x01 << 5)
+#define USART_IC_RX (0x01 << 4)
+/* Bits [3:0] - Reserved */
+
+enum usart_stopbits {
+ USART_STOPBITS_1,
+ USART_STOPBITS_1_5,
+ USART_STOPBITS_2,
+};
+
+enum usart_parity {
+ USART_PARITY_NONE,
+ USART_PARITY_ODD,
+ USART_PARITY_EVEN,
+};
+
+enum usart_mode {
+ USART_MODE_DISABLED,
+ USART_MODE_RX,
+ USART_MODE_TX,
+ USART_MODE_TX_RX,
+};
+
+enum usart_flowcontrol {
+ USART_FLOWCONTROL_NONE,
+ USART_FLOWCONTROL_RTS_CTS,
+};
+
+void usart_send(uint32_t usart, uint16_t data);
+uint16_t usart_recv(uint32_t usart);
+bool usart_is_send_ready(uint32_t usart);
+bool usart_is_recv_ready(uint32_t usart);
+void usart_send_blocking(uint32_t usart, uint16_t data);
+uint16_t usart_recv_blocking(uint32_t usart);
+void usart_enable_rx_interrupt(uint32_t usart);
+void usart_disable_rx_interrupt(uint32_t usart);
+void usart_clear_rx_interrupt(uint32_t usart);
+void usart_enable_tx_interrupt(uint32_t usart);
+void usart_disable_tx_interrupt(uint32_t usart);
+void usart_clear_tx_interrupt(uint32_t usart);
+bool usart_get_interrupt_source(uint32_t usart, uint32_t flag);
+
+#endif
+
diff --git a/lib/lm3s/Makefile b/lib/lm3s/Makefile
index 4a763e28..135219f9 100644
--- a/lib/lm3s/Makefile
+++ b/lib/lm3s/Makefile
@@ -34,7 +34,7 @@ TGT_CFLAGS = -Os \
TGT_CFLAGS += $(DEBUG_FLAGS)
# ARFLAGS = rcsv
ARFLAGS = rcs
-OBJS = gpio.o vector.o assert.o
+OBJS = gpio.o vector.o assert.o rcc.o usart.o
VPATH += ../cm3
diff --git a/lib/lm3s/rcc.c b/lib/lm3s/rcc.c
new file mode 100644
index 00000000..96c09504
--- /dev/null
+++ b/lib/lm3s/rcc.c
@@ -0,0 +1,77 @@
+/** @defgroup rcc_file RCC Controller
+
+@brief LM3S RCC Controller
+
+@ingroup LM3Sxx
+
+@version 1.0.0
+
+@author @htmlonly © @endhtmlonly 2015
+Daniele Lacamera
+
+@date 21 November 2015
+
+LGPL License Terms @ref lgpl_license
+*/
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2015 Daniele Lacamera
+ *
+ * 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 .
+ */
+
+#include
+#include
+#include
+
+int rcc_clock_setup_in_xtal_8mhz_out_50mhz(void)
+{
+ uint32_t rcc = RCC_RESET_VALUE;
+ uint32_t rcc2 = RCC2_RESET_VALUE;
+
+ /* Stage 0: Reset values applied */
+ RCC_CR = rcc;
+ RCC2_CR = rcc2;
+ __dmb();
+
+ /* Stage 1: Reset Oscillators and select configured values */
+ RCC_CR = RCC_SYSDIV_50MHZ | RCC_PWMDIV_64 | RCC_XTAL_8MHZ_400MHZ | RCC_USEPWMDIV;
+ RCC2_CR = (4 - 1) << RCC2_SYSDIV2_SHIFT;
+ __dmb();
+
+ /* Stage 2: Power on oscillators */
+ rcc &= ~RCC_OFF;
+ rcc2 &= ~RCC2_OFF;
+ RCC_CR = rcc;
+ RCC2_CR = rcc2;
+ __dmb();
+
+ /* Stage 3: Set USESYSDIV */
+ rcc |= RCC_BYPASS | RCC_USESYSDIV;
+ RCC_CR = rcc;
+ __dmb();
+
+ /* Stage 4: Wait for PLL raw interrupt */
+ while ((RCC_RIS & RIS_PLLLRIS) == 0)
+ ;
+
+ /* Stage 5: Disable bypass */
+ rcc &= ~RCC_BYPASS;
+ rcc2 &= ~RCC2_BYPASS;
+ RCC_CR = rcc;
+ RCC2_CR = rcc2;
+ __dmb();
+ return 0;
+}
diff --git a/lib/lm3s/usart.c b/lib/lm3s/usart.c
new file mode 100644
index 00000000..6ac26ccb
--- /dev/null
+++ b/lib/lm3s/usart.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Gareth McMullin
+ * Copyright (C) 2015 Daniele Lacamera
+ *
+ * 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 .
+ */
+
+#include
+
+void usart_send(uint32_t usart, uint16_t data)
+{
+ USART_DR(usart) = data;
+}
+
+uint16_t usart_recv(uint32_t usart)
+{
+ return USART_DR(usart) & 0xff;
+}
+
+void usart_send_blocking(uint32_t usart, uint16_t data)
+{
+ while (!usart_is_send_ready(usart));
+ usart_send(usart, data);
+}
+
+bool usart_is_recv_ready(uint32_t usart)
+{
+ return((USART_FR(usart) & USART_FR_RXFE) == 0);
+}
+
+bool usart_is_send_ready(uint32_t usart)
+{
+ return((USART_FR(usart) & USART_FR_BUSY) == 0);
+}
+
+uint16_t usart_recv_blocking(uint32_t usart)
+{
+ while (!usart_is_recv_ready(usart));
+ return usart_recv(usart);
+}
+
+void usart_enable_rx_interrupt(uint32_t usart)
+{
+ USART_IM(usart) |= USART_IM_RX;
+}
+
+void usart_enable_tx_interrupt(uint32_t usart)
+{
+ USART_IM(usart) |= USART_IM_TX;
+}
+
+void usart_disable_rx_interrupt(uint32_t usart)
+{
+ USART_IM(usart) &= (~USART_IM_RX);
+}
+
+void usart_disable_tx_interrupt(uint32_t usart)
+{
+ USART_IM(usart) &= (~USART_IM_TX);
+}
+
+void usart_clear_rx_interrupt(uint32_t usart)
+{
+ USART_IC(usart) |= USART_IC_RX;
+}
+
+void usart_clear_tx_interrupt(uint32_t usart)
+{
+ USART_IC(usart) |= USART_IC_TX;
+}
+
+bool usart_get_interrupt_source(uint32_t usart, uint32_t flag)
+{
+ return ((USART_RIS(usart) & flag) != 0);
+}