summaryrefslogtreecommitdiff
path: root/ucoo/hal/uart/uart.stm32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ucoo/hal/uart/uart.stm32.cc')
-rw-r--r--ucoo/hal/uart/uart.stm32.cc121
1 files changed, 60 insertions, 61 deletions
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);
}