summaryrefslogtreecommitdiff
path: root/ucoo/hal/uart
diff options
context:
space:
mode:
authorNicolas Schodet2016-07-25 15:18:40 +0200
committerNicolas Schodet2019-10-09 23:05:44 +0200
commit4695b47da68a5b2f75270bea21e15b8f1b9fd6ff (patch)
tree6e5ef4d34ee69bcd6c6627f25a0ca3aa902d47e3 /ucoo/hal/uart
parentd7df91926bdb529e68eff9a215aef72072803b6e (diff)
Switch to CMSIS
Diffstat (limited to 'ucoo/hal/uart')
-rw-r--r--ucoo/hal/uart/test/Makefile2
-rw-r--r--ucoo/hal/uart/test/test_uart.cc17
-rw-r--r--ucoo/hal/uart/test/test_uart_disc.cc23
-rw-r--r--ucoo/hal/uart/uart.stm32.cc121
-rw-r--r--ucoo/hal/uart/uart.stm32.hh18
5 files changed, 94 insertions, 87 deletions
diff --git a/ucoo/hal/uart/test/Makefile b/ucoo/hal/uart/test/Makefile
index b1e9c71..4e00795 100644
--- a/ucoo/hal/uart/test/Makefile
+++ b/ucoo/hal/uart/test/Makefile
@@ -6,7 +6,7 @@ stm32f4_PROGS = test_uart_disc
test_uart_SOURCES = test_uart.cc
test_uart_disc_SOURCES = test_uart_disc.cc
-MODULES = ucoo/hal/uart
+MODULES = ucoo/hal/uart ucoo/hal/gpio
test_uart_disc_MODULES = $(MODULES) ucoo/base/test ucoo/hal/usb
include $(BASE)/build/top.mk
diff --git a/ucoo/hal/uart/test/test_uart.cc b/ucoo/hal/uart/test/test_uart.cc
index 6236938..b43b797 100644
--- a/ucoo/hal/uart/test/test_uart.cc
+++ b/ucoo/hal/uart/test/test_uart.cc
@@ -26,7 +26,6 @@
#include "ucoo/arch/arch.hh"
#if defined (TARGET_stm32)
-# include <libopencm3/stm32/rcc.h>
# include "ucoo/hal/gpio/gpio.hh"
#endif
@@ -41,14 +40,14 @@ main (int argc, const char **argv)
#elif defined (TARGET_stm32)
// D8, D9: UART3
// C12, D2: UART5
- rcc_periph_clock_enable (RCC_GPIOC);
- rcc_periph_clock_enable (RCC_GPIOD);
- gpio_mode_setup (GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO12);
- gpio_mode_setup (GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO8 | GPIO9);
- gpio_set_af (GPIOC, GPIO_AF8, GPIO12);
- gpio_set_af (GPIOD, GPIO_AF8, GPIO2);
- gpio_set_af (GPIOD, GPIO_AF7, GPIO8 | GPIO9);
- ucoo::Uart u0 (2), u1 (4);
+ ucoo::GPIOC.enable ();
+ ucoo::GPIOD.enable ();
+ ucoo::GPIOC[12].af (8);
+ ucoo::GPIOD[2].af (8);
+ ucoo::GPIOD[8].af (7);
+ ucoo::GPIOD[9].af (7);
+ ucoo::Uart u0 (ucoo::Uart::Instance::USART3);
+ ucoo::Uart u1 (ucoo::Uart::Instance::UART5);
u0.enable (38400, ucoo::Uart::Parity::EVEN, 1);
u1.enable (38400, ucoo::Uart::Parity::EVEN, 1);
#endif
diff --git a/ucoo/hal/uart/test/test_uart_disc.cc b/ucoo/hal/uart/test/test_uart_disc.cc
index 3893f7e..029b28d 100644
--- a/ucoo/hal/uart/test/test_uart_disc.cc
+++ b/ucoo/hal/uart/test/test_uart_disc.cc
@@ -27,8 +27,6 @@
#include "ucoo/hal/gpio/gpio.hh"
#include "ucoo/base/test/test.hh"
-#include <libopencm3/stm32/rcc.h>
-
static void
check_act (ucoo::Stream &ts, ucoo::Stream &u, char n)
{
@@ -53,23 +51,20 @@ main (int argc, const char **argv)
{
ucoo::arch_init (argc, argv);
ucoo::Stream &ts = ucoo::test_stream ();
- ucoo::Uart u1 (0);
- ucoo::Uart u3 (2);
- ucoo::Uart u4 (3);
+ ucoo::Uart u1 (ucoo::Uart::Instance::USART1);
+ ucoo::Uart u3 (ucoo::Uart::Instance::USART3);
+ ucoo::Uart u4 (ucoo::Uart::Instance::UART4);
u1.enable (38400, ucoo::Uart::Parity::EVEN, 1);
u3.enable (38400, ucoo::Uart::Parity::EVEN, 1);
u4.enable (38400, ucoo::Uart::Parity::EVEN, 1);
// For this test, shorten B6 & B7 to have a loopback on UART1, shorten C10
// & C11 to connect UART3 to UART4.
- rcc_periph_clock_enable (RCC_GPIOB);
- rcc_periph_clock_enable (RCC_GPIOC);
- gpio_mode_setup (GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE,
- GPIO6 | GPIO7);
- gpio_set_af (GPIOB, GPIO_AF7, GPIO6 | GPIO7);
- gpio_mode_setup (GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE,
- GPIO10 | GPIO11);
- gpio_set_af (GPIOC, GPIO_AF7, GPIO10);
- gpio_set_af (GPIOC, GPIO_AF8, GPIO11);
+ ucoo::GPIOB.enable ();
+ ucoo::GPIOC.enable ();
+ ucoo::GPIOB[6].af (7);
+ ucoo::GPIOB[7].af (7);
+ ucoo::GPIOC[10].af (7);
+ ucoo::GPIOC[11].af (8);
// Loop to report any activity on ports and provide a simple UI.
char buf[64];
int buf_i = 0;
diff --git a/ucoo/hal/uart/uart.stm32.cc b/ucoo/hal/uart/uart.stm32.cc
index 9fdeee9..b6efbb4 100644
--- a/ucoo/hal/uart/uart.stm32.cc
+++ b/ucoo/hal/uart/uart.stm32.cc
@@ -21,11 +21,9 @@
// DEALINGS IN THE SOFTWARE.
//
// }}}
-#include "uart.stm32.hh"
-
-#include <libopencm3/stm32/usart.h>
-#include <libopencm3/stm32/rcc.h>
-#include <libopencm3/cm3/nvic.h>
+#include "ucoo/hal/uart/uart.stm32.hh"
+#include "ucoo/arch/interrupt.arm.hh"
+#include "ucoo/arch/rcc.stm32.hh"
namespace ucoo {
@@ -33,95 +31,96 @@ namespace ucoo {
struct uart_hardware_t
{
/// UART base address.
- uint32_t base;
+ USART_TypeDef *base;
/// APB number.
- int apb;
- /// Clock enable identifier.
- enum rcc_periph_clken clken;
+ Bus apb;
+ /// RCC identifier, to enable clock.
+ Rcc rcc;
/// Corresponding IRQ.
- int irq;
+ Irq irq;
};
/// Information on UART hardware array, this is zero indexed, USART1 is at
/// index 0.
static const uart_hardware_t uart_hardware[] =
{
- { USART1, 2, RCC_USART1, NVIC_USART1_IRQ },
- { USART2, 1, RCC_USART2, NVIC_USART2_IRQ },
- { USART3, 1, RCC_USART3, NVIC_USART3_IRQ },
- { UART4, 1, RCC_UART4, NVIC_UART4_IRQ },
- { UART5, 1, RCC_UART5, NVIC_UART5_IRQ },
-#ifdef USART6
- { USART6, 2, RCC_USART6, NVIC_USART6_IRQ },
+ { reg::USART1, Bus::APB2, Rcc::USART1, Irq::USART1 },
+ { reg::USART2, Bus::APB1, Rcc::USART2, Irq::USART2 },
+ { reg::USART3, Bus::APB1, Rcc::USART3, Irq::USART3 },
+ { reg::UART4, Bus::APB1, Rcc::UART4, Irq::UART4 },
+ { reg::UART5, Bus::APB1, Rcc::UART5, Irq::UART5 },
+#ifdef USART6_BASE
+ { reg::USART6, Bus::APB2, Rcc::USART6, Irq::USART6 },
#endif
};
static Uart *uart_instances[lengthof (uart_hardware)];
-} // namespace ucoo
-
-extern "C" {
-
-void usart1_isr () { ucoo::Uart::isr (0); }
-
-void usart2_isr () { ucoo::Uart::isr (1); }
+template<>
+void interrupt<Irq::USART1> () { Uart::isr (0); }
-void usart3_isr () { ucoo::Uart::isr (2); }
+template<>
+void interrupt<Irq::USART2> () { Uart::isr (1); }
-void uart4_isr () { ucoo::Uart::isr (3); }
+template<>
+void interrupt<Irq::USART3> () { Uart::isr (2); }
-void uart5_isr () { ucoo::Uart::isr (4); }
+template<>
+void interrupt<Irq::UART4> () { Uart::isr (3); }
-void usart6_isr () { ucoo::Uart::isr (5); }
+template<>
+void interrupt<Irq::UART5> () { Uart::isr (4); }
-}
-
-namespace ucoo {
+#ifdef USART6_BASE
+template<>
+void interrupt<Irq::USART6> () { Uart::isr (5); }
+#endif
-Uart::Uart (int n)
- : n_ (n), error_char_ (default_error_char), enabled_ (false)
+Uart::Uart (Uart::Instance inst)
+ : n_ (static_cast<int> (inst)),
+ error_char_ (default_error_char), enabled_ (false)
{
- assert (n < lengthof (uart_instances));
- assert (!uart_instances[n]);
- uart_instances[n] = this;
+ assert (!uart_instances[n_]);
+ uart_instances[n_] = this;
}
Uart::~Uart ()
{
disable ();
- uart_instances[n_] = 0;
+ uart_instances[n_] = nullptr;
}
void
Uart::enable (int speed, Parity parity, int stop_bits)
{
enabled_ = true;
- uint32_t base = uart_hardware[n_].base;
+ auto base = uart_hardware[n_].base;
// Turn on.
- rcc_periph_clock_enable (uart_hardware[n_].clken);
+ rcc_peripheral_clock_enable (uart_hardware[n_].rcc);
// Set speed, rounded to nearest.
- int apb_freq = uart_hardware[n_].apb == 1 ? rcc_apb1_frequency
- : rcc_apb2_frequency;
- USART_BRR (base) = (2 * apb_freq + speed) / (2 * speed);
+ int apb_freq = uart_hardware[n_].apb == Bus::APB1 ? rcc_apb1_freq_hz
+ : rcc_apb2_freq_hz;
+ base->BRR = (2 * apb_freq + speed) / (2 * speed);
// Set parameters and enable.
if (stop_bits == 1)
- USART_CR2 (base) = USART_CR2_STOPBITS_1;
+ base->CR2 = USART_CR2_STOP_Bits_1;
else if (stop_bits == 2)
- USART_CR2 (base) = USART_CR2_STOPBITS_2;
+ base->CR2 = USART_CR2_STOP_Bits_2;
else
assert_unreachable ();
- USART_CR3 (base) = 0;
- uint32_t cr1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ base->CR3 = 0;
+ uint32_t cr1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE
+ | USART_CR1_RE;
if (parity != Parity::NONE)
cr1 |= USART_CR1_M | USART_CR1_PCE;
if (parity == Parity::ODD)
cr1 |= USART_CR1_PS;
- USART_CR1 (base) = cr1;
+ base->CR1 = cr1;
// Reset status.
- (void) USART_SR (base);
- (void) USART_DR (base);
+ (void) base->SR;
+ (void) base->DR;
// Enable interrupts.
- nvic_enable_irq (uart_hardware[n_].irq);
+ interrupt_enable (uart_hardware[n_].irq);
}
void
@@ -130,12 +129,12 @@ Uart::disable ()
if (enabled_)
{
enabled_ = false;
- uint32_t base = uart_hardware[n_].base;
+ auto base = uart_hardware[n_].base;
// Stop UART.
- nvic_disable_irq (uart_hardware[n_].irq);
- USART_CR1 (base) = 0;
+ interrupt_disable (uart_hardware[n_].irq);
+ base->CR1 = 0;
// Turn off.
- rcc_periph_clock_disable (uart_hardware[n_].clken);
+ rcc_peripheral_clock_disable (uart_hardware[n_].rcc);
}
}
@@ -165,7 +164,7 @@ Uart::write (const char *buf, int count)
int r = tx_fifo_.write (buf, left);
if (r)
{
- USART_CR1 (uart_hardware[n_].base) |= USART_CR1_TXEIE;
+ uart_hardware[n_].base->CR1 |= USART_CR1_TXEIE;
buf += r;
left -= r;
}
@@ -184,12 +183,12 @@ Uart::poll ()
void
Uart::isr (int n)
{
- uint32_t base = uart_hardware[n].base;
- uint32_t sr = USART_SR (base);
- uint32_t dr = USART_DR (base);
+ auto base = uart_hardware[n].base;
+ uint32_t sr = base->SR;
+ uint32_t dr = base->DR;
assert (uart_instances[n]);
Uart &uart = *uart_instances[n];
- if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE))
+ if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE))
{
dr = uart.error_char_;
// Datasheet is not really clear about this when error bits are set.
@@ -209,9 +208,9 @@ Uart::isr (int n)
{
bool was_full = uart.tx_fifo_.full ();
if (!uart.tx_fifo_.empty ())
- USART_DR (base) = static_cast<uint8_t> (uart.tx_fifo_.pop ());
+ base->DR = static_cast<uint8_t> (uart.tx_fifo_.pop ());
if (uart.tx_fifo_.empty ())
- USART_CR1 (base) &= ~USART_CR1_TXEIE;
+ base->CR1 &= ~USART_CR1_TXEIE;
if (was_full && uart.handler_)
uart.handler_ (false);
}
diff --git a/ucoo/hal/uart/uart.stm32.hh b/ucoo/hal/uart/uart.stm32.hh
index a38d4d6..bf73302 100644
--- a/ucoo/hal/uart/uart.stm32.hh
+++ b/ucoo/hal/uart/uart.stm32.hh
@@ -29,6 +29,8 @@
#include "config/ucoo/hal/uart.hh"
+#include "ucoo/arch/reg.hh"
+
namespace ucoo {
/// Universal asynchronous receiver transmitter (UART).
@@ -42,9 +44,21 @@ class Uart : public Stream
enum class Parity { ODD, EVEN, NONE };
/// Default error character.
static const char default_error_char = '~';
+ /// Available UARTS.
+ enum class Instance
+ {
+ USART1,
+ USART2,
+ USART3,
+ UART4,
+ UART5,
+#ifdef USART6_BASE
+ USART6,
+#endif
+ };
public:
- /// Constructor for the Nth UART.
- Uart (int n);
+ /// Constructor for an UART instance.
+ Uart (Instance inst);
/// Shutdown UART.
~Uart ();
/// Enable and setup UART.