summaryrefslogtreecommitdiff
path: root/digital/ucoolib/ucoolib/hal/uart
diff options
context:
space:
mode:
Diffstat (limited to 'digital/ucoolib/ucoolib/hal/uart')
-rw-r--r--digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc15
-rw-r--r--digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc76
-rw-r--r--digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh12
3 files changed, 58 insertions, 45 deletions
diff --git a/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc b/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc
index d08d9323..217baf91 100644
--- a/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc
+++ b/digital/ucoolib/ucoolib/hal/uart/test/test_uart.cc
@@ -53,9 +53,12 @@ main (int argc, const char **argv)
{
ucoo::arch_init (argc, argv);
ucoo::Stream &ts = ucoo::test_stream ();
- ucoo::Uart u1 (0, 38400, ucoo::Uart::EVEN, 1);
- ucoo::Uart u3 (2, 38400, ucoo::Uart::EVEN, 1);
- ucoo::Uart u4 (3, 38400, ucoo::Uart::EVEN, 1);
+ ucoo::Uart u1 (0);
+ ucoo::Uart u3 (2);
+ ucoo::Uart u4 (3);
+ u1.enable (38400, ucoo::Uart::EVEN, 1);
+ u3.enable (38400, ucoo::Uart::EVEN, 1);
+ u4.enable (38400, ucoo::Uart::EVEN, 1);
// For this test, shorten B6 & B7 to have a loopback on UART1, shorten C10
// & C11 to connect UART3 to UART4.
rcc_peripheral_enable_clock (&RCC_AHB1ENR, RCC_AHB1ENR_IOPBEN
@@ -107,13 +110,13 @@ main (int argc, const char **argv)
u->write (buf, buf_i);
break;
case 'O':
- u->setup (38400, ucoo::Uart::ODD, 1);
+ u->enable (38400, ucoo::Uart::ODD, 1);
break;
case 'E':
- u->setup (38400, ucoo::Uart::EVEN, 1);
+ u->enable (38400, ucoo::Uart::EVEN, 1);
break;
case 'N':
- u->setup (38400, ucoo::Uart::NONE, 1);
+ u->enable (38400, ucoo::Uart::NONE, 1);
break;
default:
if (buf_i < static_cast<int> (sizeof (buf)))
diff --git a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc
index 0fc97efe..980bc6b9 100644
--- a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc
+++ b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.cc
@@ -83,57 +83,61 @@ void usart6_isr () { ucoo::Uart::isr (5); }
namespace ucoo {
-Uart::Uart (int n, int speed, Parity parity, int stop_bits)
- : n_ (n), error_char_ (default_error_char)
+Uart::Uart (int n)
+ : n_ (n), error_char_ (default_error_char), enabled_ (false)
{
assert (n < uart_nb);
assert (!uart_instances[n]);
uart_instances[n] = this;
- setup (speed, parity, stop_bits);
}
Uart::~Uart ()
{
- setup (0);
+ disable ();
uart_instances[n_] = 0;
}
void
-Uart::setup (int speed, Parity parity, int stop_bits)
+Uart::enable (int speed, Parity parity, int stop_bits)
{
+ enabled_ = true;
uint32_t base = uart_hardware[n_].base;
- if (speed)
- {
- // Turn on.
- rcc_peripheral_enable_clock
- (uart_hardware[n_].apb == 1 ? &RCC_APB1ENR : &RCC_APB2ENR,
- uart_hardware[n_].rcc_en);
- // Set speed, rounded to nearest.
- int apb_freq = uart_hardware[n_].apb == 1 ? rcc_ppre1_frequency
- : rcc_ppre2_frequency;
- USART_BRR (base) = (2 * apb_freq + speed) / (2 * speed);
- // Set parameters and enable.
- if (stop_bits == 1)
- USART_CR2 (base) = USART_CR2_STOPBITS_1;
- else if (stop_bits == 2)
- USART_CR2 (base) = USART_CR2_STOPBITS_2;
- else
- assert_unreachable ();
- USART_CR3 (base) = 0;
- uint32_t cr1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
- if (parity != NONE)
- cr1 |= USART_CR1_M | USART_CR1_PCE;
- if (parity == ODD)
- cr1 |= USART_CR1_PS;
- USART_CR1 (base) = cr1;
- // Reset status.
- (void) USART_SR (base);
- (void) USART_DR (base);
- // Enable interrupts.
- nvic_enable_irq (uart_hardware[n_].irq);
- }
+ // Turn on.
+ rcc_peripheral_enable_clock
+ (uart_hardware[n_].apb == 1 ? &RCC_APB1ENR : &RCC_APB2ENR,
+ uart_hardware[n_].rcc_en);
+ // Set speed, rounded to nearest.
+ int apb_freq = uart_hardware[n_].apb == 1 ? rcc_ppre1_frequency
+ : rcc_ppre2_frequency;
+ USART_BRR (base) = (2 * apb_freq + speed) / (2 * speed);
+ // Set parameters and enable.
+ if (stop_bits == 1)
+ USART_CR2 (base) = USART_CR2_STOPBITS_1;
+ else if (stop_bits == 2)
+ USART_CR2 (base) = USART_CR2_STOPBITS_2;
else
+ assert_unreachable ();
+ USART_CR3 (base) = 0;
+ uint32_t cr1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ if (parity != NONE)
+ cr1 |= USART_CR1_M | USART_CR1_PCE;
+ if (parity == ODD)
+ cr1 |= USART_CR1_PS;
+ USART_CR1 (base) = cr1;
+ // Reset status.
+ (void) USART_SR (base);
+ (void) USART_DR (base);
+ // Enable interrupts.
+ nvic_enable_irq (uart_hardware[n_].irq);
+}
+
+void
+Uart::disable ()
+{
+ if (enabled_)
{
+ enabled_ = false;
+ uint32_t base = uart_hardware[n_].base;
// Stop UART.
nvic_disable_irq (uart_hardware[n_].irq);
USART_CR1 (base) = 0;
@@ -153,6 +157,7 @@ Uart::set_error_char (char c)
int
Uart::read (char *buf, int count)
{
+ assert (enabled_);
if (block_)
while (rx_fifo_.empty ())
barrier ();
@@ -162,6 +167,7 @@ Uart::read (char *buf, int count)
int
Uart::write (const char *buf, int count)
{
+ assert (enabled_);
int left = count;
while (left)
{
diff --git a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh
index e807e9e9..1bfbcdb3 100644
--- a/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh
+++ b/digital/ucoolib/ucoolib/hal/uart/uart.stm32.hh
@@ -42,12 +42,14 @@ class Uart : public Stream
/// Default error character.
static const char default_error_char = '~';
public:
- /// Initialise the Nth UART with given parameters.
- Uart (int n, int speed = 0, Parity parity = NONE, int stop_bits = 1);
+ /// Constructor for the Nth UART.
+ Uart (int n);
/// Shutdown UART.
~Uart ();
- /// Change UART settings, use speed 0 to stop UART.
- void setup (int speed, Parity parity = NONE, int stop_bits = 1);
+ /// Enable and setup UART.
+ void enable (int speed, Parity parity = NONE, int stop_bits = 1);
+ /// Disable.
+ void disable ();
/// Change the error character.
void set_error_char (char c);
/// See Stream::read.
@@ -67,6 +69,8 @@ class Uart : public Stream
Fifo<char, UCOO_CONFIG_HAL_UART_TX_BUFFER> tx_fifo_;
/// Error character, inserted in case of error.
char error_char_;
+ /// Is it enabled?
+ bool enabled_;
};
} // namespace ucoo