From 4695b47da68a5b2f75270bea21e15b8f1b9fd6ff Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 25 Jul 2016 15:18:40 +0200 Subject: Switch to CMSIS --- ucoo/hal/uart/test/Makefile | 2 +- ucoo/hal/uart/test/test_uart.cc | 17 +++-- ucoo/hal/uart/test/test_uart_disc.cc | 23 +++---- ucoo/hal/uart/uart.stm32.cc | 121 +++++++++++++++++------------------ ucoo/hal/uart/uart.stm32.hh | 18 +++++- 5 files changed, 94 insertions(+), 87 deletions(-) (limited to 'ucoo/hal/uart') 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 # 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 - 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 -#include -#include +#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 () { Uart::isr (0); } -void usart3_isr () { ucoo::Uart::isr (2); } +template<> +void interrupt () { Uart::isr (1); } -void uart4_isr () { ucoo::Uart::isr (3); } +template<> +void interrupt () { Uart::isr (2); } -void uart5_isr () { ucoo::Uart::isr (4); } +template<> +void interrupt () { Uart::isr (3); } -void usart6_isr () { ucoo::Uart::isr (5); } +template<> +void interrupt () { Uart::isr (4); } -} - -namespace ucoo { +#ifdef USART6_BASE +template<> +void interrupt () { 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 (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 (uart.tx_fifo_.pop ()); + base->DR = static_cast (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. -- cgit v1.2.3