diff options
author | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-01 01:10:47 -0400 |
---|---|---|
committer | Marti Bolivar <mbolivar@leaflabs.com> | 2012-06-01 01:28:51 -0400 |
commit | d483f8fa0c7c1f65c926b24d6c66275953d03c4f (patch) | |
tree | 84cd29e2f201fbd6bbac753027c146061e0f05e4 /wirish/HardwareSerial.cpp | |
parent | b1e06d3acaa72976042314c1debec008c5ac54d7 (diff) | |
download | librambutan-d483f8fa0c7c1f65c926b24d6c66275953d03c4f.tar.gz librambutan-d483f8fa0c7c1f65c926b24d6c66275953d03c4f.zip |
Bring back HardwareSerial.
To make this happen, we need to have <board/board.h> tell us whether
or not it's got each of the USARTs. Do that with BOARD_HAVE_USARTn,
for n = 1,...,6. This lets us define HardwareSerial instances only
when appropriate, and gets rid of some board-specific hacks we'd
accumulated.
The new <libmaple/usart.h> now has a convenience function for
determining the bus rate by using the appropriate STM32_PCLKx macro,
so we can shave a uint32 per instance, which is nice given that
they're all going to be in memory. This changes the constructor
arguments, but the API only specifies the semantics of the predefined
instances, so this is still backwards-compatible. (We should look into
storing the instances in Flash -- they don't change, after all.)
We don't actually need struct usart_dev's definition in
HardwareSerial.h, so replace it with a forward declaration and include
<libmaple/usart.h> it in HardwareSerial.cpp instead.
Assert some copyrights.
Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Diffstat (limited to 'wirish/HardwareSerial.cpp')
-rw-r--r-- | wirish/HardwareSerial.cpp | 98 |
1 files changed, 56 insertions, 42 deletions
diff --git a/wirish/HardwareSerial.cpp b/wirish/HardwareSerial.cpp index 0f12e72..3f418e2 100644 --- a/wirish/HardwareSerial.cpp +++ b/wirish/HardwareSerial.cpp @@ -2,6 +2,7 @@ * The MIT License * * Copyright (c) 2010 Perry Hung. + * Copyright (c) 2011, 2012 LeafLabs, LLC. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -34,36 +35,36 @@ #include <libmaple/libmaple.h> #include <libmaple/gpio.h> #include <libmaple/timer.h> +#include <libmaple/usart.h> -#include <wirish/boards.h> - -#define TX1 BOARD_USART1_TX_PIN -#define RX1 BOARD_USART1_RX_PIN -#define TX2 BOARD_USART2_TX_PIN -#define RX2 BOARD_USART2_RX_PIN -#define TX3 BOARD_USART3_TX_PIN -#define RX3 BOARD_USART3_RX_PIN -#if defined STM32_HIGH_DENSITY && !defined(BOARD_maple_RET6) -#define TX4 BOARD_UART4_TX_PIN -#define RX4 BOARD_UART4_RX_PIN -#define TX5 BOARD_UART5_TX_PIN -#define RX5 BOARD_UART5_RX_PIN -#endif +#define DEFINE_HWSERIAL(name, n) \ + HardwareSerial name(USART##n, \ + BOARD_USART##n##_TX_PIN, \ + BOARD_USART##n##_RX_PIN) -HardwareSerial Serial1(USART1, TX1, RX1, STM32_PCLK2); -HardwareSerial Serial2(USART2, TX2, RX2, STM32_PCLK1); -HardwareSerial Serial3(USART3, TX3, RX3, STM32_PCLK1); -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) -HardwareSerial Serial4(UART4, TX4, RX4, STM32_PCLK1); -HardwareSerial Serial5(UART5, TX5, RX5, STM32_PCLK1); +#if BOARD_HAVE_USART1 +DEFINE_HWSERIAL(Serial1, 1); +#endif +#if BOARD_HAVE_USART2 +DEFINE_HWSERIAL(Serial2, 2); +#endif +#if BOARD_HAVE_USART3 +DEFINE_HWSERIAL(Serial3, 3); +#endif +#if BOARD_HAVE_UART4 +DEFINE_HWSERIAL(Serial4, 4); +#endif +#if BOARD_HAVE_UART5 +DEFINE_HWSERIAL(Serial5, 5); +#endif +#if BOARD_HAVE_USART6 +DEFINE_HWSERIAL(Serial6, 6); #endif HardwareSerial::HardwareSerial(usart_dev *usart_device, uint8 tx_pin, - uint8 rx_pin, - uint32 clock_speed) { + uint8 rx_pin) { this->usart_device = usart_device; - this->clock_speed = clock_speed; this->tx_pin = tx_pin; this->rx_pin = rx_pin; } @@ -72,31 +73,44 @@ HardwareSerial::HardwareSerial(usart_dev *usart_device, * Set up/tear down */ +#if STM32_MCU_SERIES == STM32_SERIES_F1 +/* F1 MCUs have no GPIO_AFR[HL], so turn off PWM if there's a conflict + * on this GPIO bit. */ +static void disable_timer_if_necessary(timer_dev *dev, uint8 ch) { + if (txi->timer_device != NULL) { + timer_set_mode(txi->timer_device, txi->timer_channel, TIMER_DISABLED); + } +} +#elif (STM32_MCU_SERIES == STM32_SERIES_F2) || \ + (STM32_MCU_SERIES == STM32_SERIES_F4) +#define disable_timer_if_necessary(dev, ch) ((void)0) +#else +#warn "Unsupported STM32 series; timer conflicts are possible" +#endif + void HardwareSerial::begin(uint32 baud) { - ASSERT(baud <= usart_device->max_baud); + ASSERT(baud <= this->usart_device->max_baud); - if (baud > usart_device->max_baud) { + if (baud > this->usart_device->max_baud) { return; } - const stm32_pin_info *txi = &PIN_MAP[tx_pin]; - const stm32_pin_info *rxi = &PIN_MAP[rx_pin]; + const stm32_pin_info *txi = &PIN_MAP[this->tx_pin]; + const stm32_pin_info *rxi = &PIN_MAP[this->rx_pin]; - gpio_set_mode(txi->gpio_device, txi->gpio_bit, GPIO_AF_OUTPUT_PP); - gpio_set_mode(rxi->gpio_device, rxi->gpio_bit, GPIO_INPUT_FLOATING); - - if (txi->timer_device != NULL) { - /* Turn off any PWM if there's a conflict on this GPIO bit. */ - timer_set_mode(txi->timer_device, txi->timer_channel, TIMER_DISABLED); - } + disable_timer_if_necessary(txi->timer_device, txi->timer_channel); - usart_init(usart_device); - usart_set_baud_rate(usart_device, clock_speed, baud); - usart_enable(usart_device); + usart_async_gpio_cfg(this->usart_device, + rxi->gpio_device, rxi->gpio_bit, + txi->gpio_device, txi->gpio_bit, + 0); + usart_init(this->usart_device); + usart_set_baud_rate(this->usart_device, USART_USE_PCLK, baud); + usart_enable(this->usart_device); } void HardwareSerial::end(void) { - usart_disable(usart_device); + usart_disable(this->usart_device); } /* @@ -104,17 +118,17 @@ void HardwareSerial::end(void) { */ uint8 HardwareSerial::read(void) { - return usart_getc(usart_device); + return usart_getc(this->usart_device); } uint32 HardwareSerial::available(void) { - return usart_data_available(usart_device); + return usart_data_available(this->usart_device); } void HardwareSerial::write(unsigned char ch) { - usart_putc(usart_device, ch); + usart_putc(this->usart_device, ch); } void HardwareSerial::flush(void) { - usart_reset_rx(usart_device); + usart_reset_rx(this->usart_device); } |