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); +}