diff options
Diffstat (limited to 'libmaple')
-rw-r--r-- | libmaple/usart.c | 302 | ||||
-rw-r--r-- | libmaple/usart.h | 315 | ||||
-rw-r--r-- | libmaple/util.c | 53 |
3 files changed, 435 insertions, 235 deletions
diff --git a/libmaple/usart.c b/libmaple/usart.c index 494a29f..df5e2c5 100644 --- a/libmaple/usart.c +++ b/libmaple/usart.c @@ -23,212 +23,214 @@ *****************************************************************************/ /** + * @file usart.c * @brief USART control routines */ -#include "libmaple.h" -#include "rcc.h" -#include "nvic.h" #include "usart.h" -#define USART1_BASE 0x40013800 -#define USART2_BASE 0x40004400 -#define USART3_BASE 0x40004800 -#define UART4_BASE 0x40004C00 // High-density devices only (Maple Native) -#define UART5_BASE 0x40005000 // High-density devices only (Maple Native) - -#define USART_UE BIT(13) -#define USART_M BIT(12) -#define USART_TE BIT(3) -#define USART_RE BIT(2) -#define USART_RXNEIE BIT(5) // read data register not empty interrupt enable -#define USART_TC BIT(6) - -/* usart descriptor table */ -struct usart_dev usart_dev_table[] = { - [USART1] = { - .base = (usart_port*)USART1_BASE, - .rcc_dev_num = RCC_USART1, - .nvic_dev_num = NVIC_USART1 - }, - [USART2] = { - .base = (usart_port*)USART2_BASE, - .rcc_dev_num = RCC_USART2, - .nvic_dev_num = NVIC_USART2 - }, - [USART3] = { - .base = (usart_port*)USART3_BASE, - .rcc_dev_num = RCC_USART3, - .nvic_dev_num = NVIC_USART3 - }, -#ifdef STM32_HIGH_DENSITY - /* TODO test */ - [UART4] = { - .base = (usart_port*)UART4_BASE, - .rcc_dev_num = RCC_UART4, - .nvic_dev_num = NVIC_UART4 - }, - [UART5] = { - .base = (usart_port*)UART5_BASE, - .rcc_dev_num = RCC_UART5, - .nvic_dev_num = NVIC_UART5 - }, -#endif -}; - /* - * Usart interrupt handlers. + * Devices */ -static inline void usart_irq(int usart_num) { -#ifdef USART_SAFE_INSERT - /* Ignore old bytes if the user defines USART_SAFE_INSERT. */ - rb_safe_insert(&(usart_dev_table[usart_num].rb), - (uint8)((usart_dev_table[usart_num].base)->DR)); -#else - /* By default, push bytes around in the ring buffer. */ - rb_push_insert(&(usart_dev_table[usart_num].rb), - (uint8)((usart_dev_table[usart_num].base)->DR)); -#endif -} - -/* TODO: Check the disassembly for the following functions to make - sure GCC inlined properly. */ - -void __irq_usart1(void) { - usart_irq(USART1); -} - -void __irq_usart2(void) { - usart_irq(USART2); -} - -void __irq_usart3(void) { - usart_irq(USART3); -} +static ring_buffer usart1_rb; +static usart_dev usart1 = { + .regs = USART1_BASE, + .rb = &usart1_rb, + .max_baud = 4500000UL, + .clk_id = RCC_USART1, + .irq_num = NVIC_USART1 +}; +usart_dev *USART1 = &usart1; + +static ring_buffer usart2_rb; +static usart_dev usart2 = { + .regs = USART2_BASE, + .rb = &usart2_rb, + .max_baud = 2250000UL, + .clk_id = RCC_USART2, + .irq_num = NVIC_USART2 +}; +usart_dev *USART2 = &usart2; + +static ring_buffer usart3_rb; +static usart_dev usart3 = { + .regs = USART3_BASE, + .rb = &usart3_rb, + .max_baud = 2250000UL, + .clk_id = RCC_USART3, + .irq_num = NVIC_USART3 +}; +usart_dev *USART3 = &usart3; #ifdef STM32_HIGH_DENSITY -void __irq_uart4(void) { - usart_irq(UART4); -} - -void __irq_uart5(void) { - usart_irq(UART5); -} +static ring_buffer uart4_rb; +static usart_dev uart4 = { + .regs = UART4_BASE, + .rb = &uart4_rb, + .max_baud = 2250000UL, + .clk_id = RCC_UART4, + .irq_num = NVIC_UART4 +}; +usart_dev *UART4 = &uart4; + +static ring_buffer uart5_rb; +static usart_dev uart5 = { + .regs = UART5_BASE, + .rb = &uart5_rb, + .max_baud = 2250000UL, + .clk_id = RCC_UART5, + .irq_num = NVIC_UART5 +}; +usart_dev *UART5 = &uart5; #endif /** - * @brief Enable a USART in single buffer transmission mode, multibuffer - * receiver mode. - * @param usart_num USART to be initialized - * @param baud Baud rate to be set at + * @brief Initialize a serial port. + * @param dev Serial port to be initialized */ -void usart_init(uint8 usart_num, uint32 baud) { -#ifdef STM32_HIGH_DENSITY - ASSERT(usart_num <= UART5); -#else - ASSERT(usart_num <= USART3); -#endif - usart_port *port; - ring_buffer *ring_buf; +void usart_init(usart_dev *dev) { + rb_init(dev->rb, USART_RX_BUF_SIZE, dev->rx_buf); + rcc_clk_enable(dev->clk_id); + nvic_irq_enable(dev->irq_num); +} - uint32 clk_speed; +/** + * @brief Configure a serial port's baud rate. + * + * @param dev Serial port to be configured + * @param clock_speed MCU clock speed, in megahertz. + * @param baud Baud rate for transmit/receive. + */ +void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud) { uint32 integer_part; uint32 fractional_part; uint32 tmp; - port = usart_dev_table[usart_num].base; - rcc_clk_enable(usart_dev_table[usart_num].rcc_dev_num); - nvic_irq_enable(usart_dev_table[usart_num].nvic_dev_num); - - /* usart1 is mad fast */ - clk_speed = (usart_num == USART1) ? 72000000UL : 36000000UL; - - /* Initialize rx ring buffer */ - rb_init(&usart_dev_table[usart_num].rb, - sizeof (usart_dev_table[usart_num].rx_buf), - usart_dev_table[usart_num].rx_buf); - - /* Set baud rate */ - integer_part = ((25 * clk_speed) / (4 * baud)); + /* See ST RM0008 for the details on configuring the baud rate register */ + integer_part = (25 * clock_speed) / (4 * baud); tmp = (integer_part / 100) << 4; - fractional_part = integer_part - (100 * (tmp >> 4)); tmp |= (((fractional_part * 16) + 50) / 100) & ((uint8)0x0F); - port->BRR = (uint16)tmp; - - port->CR1 = USART_TE | // transmitter enable - USART_RE | // receiver enable - USART_RXNEIE; // receive interrupt enable - - - /* Enable the USART and set mode to 8n1 */ - port->CR1 |= USART_UE; + dev->regs->BRR = (uint16)tmp; } /** - * @brief Turn off all USARTs. + * @brief Enable a serial port. + * + * USART is enabled in single buffer transmission mode, multibuffer + * receiver mode, at the given baud rate, 8n1. + * + * Serial port must have a baud rate configured to work properly. + * + * @param dev Serial port to enable. + * @see usart_set_baud_rate() */ -void usart_disable_all() { - usart_disable(USART1); - usart_disable(USART2); - usart_disable(USART3); -#ifdef STM32_HIGH_DENSITY - usart_disable(UART4); - usart_disable(UART5); -#endif +void usart_enable(usart_dev *dev) { + usart_reg_map *regs = dev->regs; + regs->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; + regs->CR1 |= USART_CR1_UE; } /** - * @brief Turn off a USART. - * @param USART to be disabled + * @brief Turn off a serial port. + * @param dev Serial port to be disabled */ -void usart_disable(uint8 usart_num) { - usart_port *port = usart_dev_table[usart_num].base; +void usart_disable(usart_dev *dev) { + /* FIXME this misbehaves if you try to use PWM on TX afterwards */ + usart_reg_map *regs = dev->regs; - /* TC bit must be high before disabling the usart */ - while((port->CR1 & USART_UE) && !(port->SR & USART_TC)) + /* TC bit must be high before disabling the USART */ + while((regs->CR1 & USART_CR1_UE) && !(regs->SR & USART_SR_TC)) ; /* Disable UE */ - port->CR1 = 0; + regs->CR1 = 0; /* Clean up buffer */ - usart_reset_rx(usart_num); + usart_reset_rx(dev); } +/** + * @brief Call a function on each USART. + * @param fn Function to call. + */ +void usart_foreach(void (*fn)(usart_dev *dev)) { + fn(USART1); + fn(USART2); + fn(USART3); +#ifdef STM32_HIGH_DENSITY + fn(UART4); + fn(UART5); +#endif +} /** - * @brief Print a null terminated string to the specified USART - * - * @param usart_num usart to send on - * @param str string to send + * @brief Print a null-terminated string to the specified serial port. + * @param dev Serial port to send the string on + * @param str String to send */ -void usart_putstr(uint8 usart_num, const char* str) { +void usart_putstr(usart_dev *dev, const char* str) { char ch; - while((ch = *(str++)) != '\0') { - usart_putc(usart_num, ch); + while ((ch = *(str++)) != '\0') { + usart_putc(dev, ch); } } /** - * @brief Print an unsigned integer to the specified usart + * @brief Print an unsigned integer to the specified serial port. * - * @param usart_num usart to send on - * @param val number to print + * @param dev Serial port to send on + * @param val Number to print */ -void usart_putudec(uint8 usart_num, uint32 val) { +void usart_putudec(usart_dev *dev, uint32 val) { char digits[12]; - int i; + int i = 0; - i = 0; do { digits[i++] = val % 10 + '0'; val /= 10; } while (val > 0); + while (--i >= 0) { - usart_putc(usart_num, digits[i]); + usart_putc(dev, digits[i]); } } + +/* + * Interrupt handlers. + */ + +static inline void usart_irq(usart_dev *dev) { +#ifdef USART_SAFE_INSERT + /* Ignore new bytes if the user defines USART_SAFE_INSERT. */ + rb_safe_insert(dev->rb, (uint8)dev->regs->DR); +#else + /* By default, push bytes around in the ring buffer. */ + rb_push_insert(dev->rb, (uint8)dev->regs->DR); +#endif +} + +void __irq_usart1(void) { + usart_irq(USART1); +} + +void __irq_usart2(void) { + usart_irq(USART2); +} + +void __irq_usart3(void) { + usart_irq(USART3); +} + +#ifdef STM32_HIGH_DENSITY +void __irq_uart4(void) { + usart_irq(UART4); +} + +void __irq_uart5(void) { + usart_irq(UART5); +} +#endif diff --git a/libmaple/usart.h b/libmaple/usart.h index 90b3415..7a93da0 100644 --- a/libmaple/usart.h +++ b/libmaple/usart.h @@ -30,94 +30,293 @@ #ifndef _USART_H_ #define _USART_H_ +#include "libmaple_types.h" +#include "util.h" +#include "rcc.h" +#include "nvic.h" #include "ring_buffer.h" #ifdef __cplusplus extern "C"{ #endif -#define USART_TXE BIT(7) +/* + * Register maps and devices + */ + +/** USART register map type */ +typedef struct usart_reg_map { + __io uint32 SR; /**< Status register */ + __io uint32 DR; /**< Data register */ + __io uint32 BRR; /**< Baud rate register */ + __io uint32 CR1; /**< Control register 1 */ + __io uint32 CR2; /**< Control register 2 */ + __io uint32 CR3; /**< Control register 3 */ + __io uint32 GTPR; /**< Guard time and prescaler register */ +} usart_reg_map; -/* usart device numbers */ -enum { - USART1, - USART2, - USART3, +/** USART1 register map base pointer */ +#define USART1_BASE ((struct usart_reg_map*)0x40013800) +/** USART2 register map base pointer */ +#define USART2_BASE ((struct usart_reg_map*)0x40004400) +/** USART3 register map base pointer */ +#define USART3_BASE ((struct usart_reg_map*)0x40004800) #ifdef STM32_HIGH_DENSITY - UART4, - UART5, +/** UART4 register map base pointer */ +#define UART4_BASE ((struct usart_reg_map*)0x40004C00) +/** UART5 register map base pointer */ +#define UART5_BASE ((struct usart_reg_map*)0x40005000) #endif -}; - -/* peripheral register struct */ -typedef struct usart_port { - volatile uint32 SR; // Status register - volatile uint32 DR; // Data register - volatile uint32 BRR; // Baud rate register - volatile uint32 CR1; // Control register 1 - volatile uint32 CR2; // Control register 2 - volatile uint32 CR3; // Control register 3 - volatile uint32 GTPR; // Guard time and prescaler register -} usart_port; - -/* usart descriptor */ -struct usart_dev { - usart_port *base; - ring_buffer rb; - uint8 rx_buf[64]; - const uint8 rcc_dev_num; - const uint8 nvic_dev_num; -}; - -extern struct usart_dev usart_dev_table[]; + +/* + * Register bit definitions + */ + +/* Status register */ + +#define USART_SR_CTS_BIT 9 +#define USART_SR_LBD_BIT 8 +#define USART_SR_TXE_BIT 7 +#define USART_SR_TC_BIT 6 +#define USART_SR_RXNE_BIT 5 +#define USART_SR_IDLE_BIT 4 +#define USART_SR_ORE_BIT 3 +#define USART_SR_NE_BIT 2 +#define USART_SR_FE_BIT 1 +#define USART_SR_PE_BIT 0 + +#define USART_SR_CTS BIT(USART_SR_CTS_BIT) +#define USART_SR_LBD BIT(USART_SR_LBD_BIT) +#define USART_SR_TXE BIT(USART_SR_TXE_BIT) +#define USART_SR_TC BIT(USART_SR_TC_BIT) +#define USART_SR_RXNE BIT(USART_SR_RXNE_BIT) +#define USART_SR_IDLE BIT(USART_SR_IDLE_BIT) +#define USART_SR_ORE BIT(USART_SR_ORE_BIT) +#define USART_SR_NE BIT(USART_SR_NE_BIT) +#define USART_SR_FE BIT(USART_SR_FE_BIT) +#define USART_SR_PE BIT(USART_SR_PE_BIT) + +/* Data register */ + +#define USART_DR_DR 0xFF + +/* Baud rate register */ + +#define USART_BRR_DIV_MANTISSA (0xFFF << 4) +#define USART_BRR_DIV_FRACTION 0xF + +/* Control register 1 */ + +#define USART_CR1_UE_BIT 13 +#define USART_CR1_M_BIT 12 +#define USART_CR1_WAKE_BIT 11 +#define USART_CR1_PCE_BIT 10 +#define USART_CR1_PS_BIT 9 +#define USART_CR1_PEIE_BIT 8 +#define USART_CR1_TXEIE_BIT 7 +#define USART_CR1_TCIE_BIT 6 +#define USART_CR1_RXNEIE_BIT 5 +#define USART_CR1_IDLEIE_BIT 4 +#define USART_CR1_TE_BIT 3 +#define USART_CR1_RE_BIT 2 +#define USART_CR1_RWU_BIT 1 +#define USART_CR1_SBK_BIT 0 + +#define USART_CR1_UE BIT(USART_CR1_UE_BIT) +#define USART_CR1_M BIT(USART_CR1_M_BIT) +#define USART_CR1_WAKE BIT(USART_CR1_WAKE_BIT) +#define USART_CR1_WAKE_IDLE (0 << USART_CR1_WAKE_BIT) +#define USART_CR1_WAKE_ADDR (1 << USART_CR1_WAKE_BIT) +#define USART_CR1_PCE BIT(USART_CR1_PCE_BIT) +#define USART_CR1_PS BIT(USART_CR1_PS_BIT) +#define USART_CR1_PS_EVEN (0 << USART_CR1_PS_BIT) +#define USART_CR1_PS_ODD (1 << USART_CR1_PS_BIT) +#define USART_CR1_PEIE BIT(USART_CR1_PEIE_BIT) +#define USART_CR1_TXEIE BIT(USART_CR1_TXEIE_BIT) +#define USART_CR1_TCIE BIT(USART_CR1_TCIE_BIT) +#define USART_CR1_RXNEIE BIT(USART_CR1_RXNEIE_BIT) +#define USART_CR1_IDLEIE BIT(USART_CR1_IDLEIE_BIT) +#define USART_CR1_TE BIT(USART_CR1_TE_BIT) +#define USART_CR1_RE BIT(USART_CR1_RE_BIT) +#define USART_CR1_RWU BIT(USART_CR1_RWU_BIT) +#define USART_CR1_RWU_ACTIVE (0 << USART_CR1_RWU_BIT) +#define USART_CR1_RWU_MUTE (1 << USART_CR1_RWU_BIT) +#define USART_CR1_SBK BIT(USART_CR1_SBK_BIT) + +/* Control register 2 */ + +#define USART_CR2_LINEN_BIT 14 +#define USART_CR2_CLKEN_BIT 11 +#define USART_CR2_CPOL_BIT 10 +#define USART_CR2_CPHA_BIT 9 +#define USART_CR2_LBCL_BIT 8 +#define USART_CR2_LBDIE_BIT 6 +#define USART_CR2_LBDL_BIT 5 + +#define USART_CR2_LINEN BIT(USART_CR2_LINEN_BIT) +#define USART_CR2_STOP (0x3 << 12) +#define USART_CR2_STOP_BITS_1 (0x0 << 12) +/* Not on UART4, UART5 */ +#define USART_CR2_STOP_BITS_POINT_5 (0x1 << 12) +/* Not on UART4, UART5 */ +#define USART_CR2_STOP_BITS_1_POINT_5 (0x3 << 12) +#define USART_CR2_STOP_BITS_2 (0x2 << 12) +#define USART_CR2_CLKEN BIT(USART_CR2_CLKEN_BIT) +/* Not on UART4, UART5 */ +#define USART_CR2_CPOL BIT(USART_CR2_CPOL_BIT) +#define USART_CR2_CPOL_LOW (0x0 << USART_CR2_CLKEN_BIT) +#define USART_CR2_CPOL_HIGH (0x1 << USART_CR2_CLKEN_BIT) +/* Not on UART4, UART5 */ +#define USART_CR2_CPHA BIT(USART_CR2_CPHA_BIT) +#define USART_CR2_CPHA_FIRST (0x0 << USART_CR2_CPHA_BIT) +#define USART_CR2_CPHA_SECOND (0x1 << USART_CR2_CPHA_BIT) +/* Not on UART4, UART5 */ +#define USART_CR2_LBCL BIT(USART_CR2_LBCL_BIT) +#define USART_CR2_LBDIE BIT(USART_CR2_LBDIE_BIT) +#define USART_CR2_LBDL BIT(USART_CR2_LBDL_BIT) +#define USART_CR2_LBDL_10_BIT (0 << USART_CR2_LBDL_BIT) +#define USART_CR2_LBDL_11_BIT (1 << USART_CR2_LBDL_BIT) +#define USART_CR2_ADD 0xF + +/* Control register 3 */ + +#define USART_CR3_CTSIE_BIT 10 +#define USART_CR3_CTSE_BIT 9 +#define USART_CR3_RTSE_BIT 8 +#define USART_CR3_DMAT_BIT 7 +#define USART_CR3_DMAR_BIT 6 +#define USART_CR3_SCEN_BIT 5 +#define USART_CR3_NACK_BIT 4 +#define USART_CR3_HDSEL_BIT 3 +#define USART_CR3_IRLP_BIT 2 +#define USART_CR3_IREN_BIT 1 +#define USART_CR3_EIE_BIT 0 + +/* Not on UART4, UART5 */ +#define USART_CR3_CTSIE BIT(USART_CR3_CTSIE_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_CTSE BIT(USART_CR3_CTSE_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_RTSE BIT(USART_CR3_RTSE_BIT) +/* Not on UART5 */ +#define USART_CR3_DMAT BIT(USART_CR3_DMAT_BIT) +/* Not on UART5 */ +#define USART_CR3_DMAR BIT(USART_CR3_DMAR_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_SCEN BIT(USART_CR3_SCEN_BIT) +/* Not on UART4, UART5 */ +#define USART_CR3_NACK BIT(USART_CR3_NACK_BIT) +#define USART_CR3_HDSEL BIT(USART_CR3_HDSEL_BIT) +#define USART_CR3_IRLP BIT(USART_CR3_IRLP_BIT) +#define USART_CR3_IRLP_NORMAL (0 << USART_CR3_IRLP_BIT) +#define USART_CR3_IRLP_LOW_POWER (1 << USART_CR3_IRLP_BIT) +#define USART_CR3_IREN BIT(USART_CR3_IREN_BIT) +#define USART_CR3_EIE BIT(USART_CR3_EIE_BIT) + +/* Guard time and prescaler register */ + +/* Not on UART4, UART5 */ +#define USART_GTPR_GT (0xFF << 8) +/* Not on UART4, UART5 */ +#define USART_GTPR_PSC 0xFF + +/* + * Devices + */ + +#define USART_RX_BUF_SIZE 64 + +/** USART device type */ +typedef struct usart_dev { + usart_reg_map *regs; + ring_buffer *rb; + uint32 max_baud; + uint8 rx_buf[USART_RX_BUF_SIZE]; + rcc_clk_id clk_id; + nvic_irq_num irq_num; +} usart_dev; + +/** USART1 device */ +extern usart_dev *USART1; +/** USART2 device */ +extern usart_dev *USART2; +/** USART3 device */ +extern usart_dev *USART3; +#ifdef STM32_HIGH_DENSITY +/** UART4 device */ +extern usart_dev *UART4; +/** UART5 device */ +extern usart_dev *UART5; +#endif + +#ifdef STM32_MEDIUM_DENSITY +#define NR_USARTS 3 +#elif defined(STM32_HIGH_DENSITY) +#define NR_USARTS 5 +#else +#warn "Only medium and high density devices are currently supported" +#endif + +void usart_init(usart_dev *dev); +void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud); +void usart_enable(usart_dev *dev); +void usart_disable(usart_dev *dev); +void usart_foreach(void (*fn)(usart_dev *dev)); +void usart_putstr(usart_dev *dev, const char*); +void usart_putudec(usart_dev *dev, uint32 val); /** - * @brief send one character on a usart - * @param usart_num usart to send on - * @param byte byte to send + * @brief Disable all serial ports. */ -static inline void usart_putc(uint8 usart_num, uint8 byte) { - usart_port *port = usart_dev_table[usart_num].base; +static inline void usart_disable_all(void) { + usart_foreach(usart_disable); +} - /* Wait for the buffer to empty */ - while ((port->SR & USART_TXE) == 0) +/** + * @brief Transmit one character on a serial port. + * @param dev Serial port to send on. + * @param byte Byte to transmit. + */ +static inline void usart_putc(usart_dev* dev, uint8 byte) { + usart_reg_map *regs = dev->regs; + + while ((regs->SR & USART_SR_TXE) == 0) ; - port->DR = byte; + regs->DR = byte; } /** - * @brief read one character from a usart - * @param usart_num usart to read from + * @brief Read one character from a serial port. + * + * It's not safe to call this function if the serial port has no data + * available. + * + * @param dev Serial port to read from * @return byte read + * @see usart_data_available() */ -static inline uint8 usart_getc(uint8 usart_num) { - return rb_remove(&usart_dev_table[usart_num].rb); +static inline uint8 usart_getc(usart_dev *dev) { + return rb_remove(dev->rb); } /** - * @brief return the amount of data available in the rx buffer - * @param usart_num which usart to check - * @return number of bytes in the rx buffer + * @brief Return the amount of data available in a serial port's RX buffer. + * @param dev Serial port to check + * @return Number of bytes in dev's RX buffer. */ -static inline uint32 usart_data_available(uint8 usart_num) { - return rb_full_count(&usart_dev_table[usart_num].rb); +static inline uint32 usart_data_available(usart_dev *dev) { + return rb_full_count(dev->rb); } /** - * @brief removes the contents of the rx fifo - * @param usart_num which usart to reset + * @brief Discard the contents of a serial port's RX buffer. + * @param dev Serial port whose buffer to empty. */ -static inline void usart_reset_rx(uint8 usart_num) { - rb_reset(&usart_dev_table[usart_num].rb); +static inline void usart_reset_rx(usart_dev *dev) { + rb_reset(dev->rb); } -void usart_init(uint8 usart_num, uint32 baud); -void usart_disable(uint8 usart_num); -void usart_disable_all(); -void usart_putstr(uint8 usart_num, const char*); -void usart_putudec(uint8 usart_num, uint32 val); - #ifdef __cplusplus } // extern "C" #endif diff --git a/libmaple/util.c b/libmaple/util.c index 77af5b8..4a234ae 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -24,7 +24,7 @@ /** * @brief Utility procedures for debugging, mostly an error LED fade - * and messages dumped over a uart for failed asserts. + * and messages dumped over a UART for failed asserts. */ #include "libmaple.h" @@ -34,38 +34,38 @@ #include "adc.h" #include "timer.h" -/* Failed asserts send out a message on this USART. */ -#ifndef ERROR_USART_NUM -#define ERROR_USART_NUM USART2 +/* Failed ASSERT()s send out a message using this USART config. */ +#ifndef ERROR_USART +#define ERROR_USART USART2 +#define ERROR_USART_CLK_SPEED 72000000UL #define ERROR_USART_BAUD 9600 #define ERROR_TX_PORT GPIOA #define ERROR_TX_PIN 2 #endif /* If you define ERROR_LED_PORT and ERROR_LED_PIN, then a failed - assert will also throb an LED connected to that port an pin. - FIXME this should work together with wirish somehow. */ + * ASSERT() will also throb() an LED connected to that port and pin. + */ #if defined(ERROR_LED_PORT) && defined(ERROR_LED_PIN) #define HAVE_ERROR_LED #endif /** * @brief Disables all peripheral interrupts except USB and fades the - * error LED. - * - * Called from exc.S with global interrupts disabled. + * error LED. */ +/* (Called from exc.S with global interrupts disabled.) */ void __error(void) { /* Turn off peripheral interrupts */ nvic_irq_disable_all(); - /* Turn off timers */ + /* Turn off timers */ timer_disable_all(); /* Turn off ADC */ adc_disable_all(); - /* Turn off all usarts */ + /* Turn off all USARTs */ usart_disable_all(); /* Turn the USB interrupt back on so the bootloader keeps on functioning */ @@ -78,33 +78,33 @@ void __error(void) { } /** - * @brief Prints an error message on a uart upon a failed assertion - * and error throbs. + * @brief Print an error message on a UART upon a failed assertion + * and throb the error LED, if there is one defined. * @param file Source file of failed assertion * @param line Source line of failed assertion * @param exp String representation of failed assertion * @sideeffect Turns of all peripheral interrupts except USB. */ void _fail(const char* file, int line, const char* exp) { - /* Initialize the error usart */ + /* Initialize the error USART */ gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_AF_OUTPUT_PP); - usart_init(ERROR_USART_NUM, ERROR_USART_BAUD); + usart_init(ERROR_USART); + usart_set_baud_rate(ERROR_USART, ERROR_USART_CLK_SPEED, ERROR_USART_BAUD); /* Print failed assert message */ - usart_putstr(ERROR_USART_NUM, "ERROR: FAILED ASSERT("); - usart_putstr(ERROR_USART_NUM, exp); - usart_putstr(ERROR_USART_NUM, "): "); - usart_putstr(ERROR_USART_NUM, file); - usart_putstr(ERROR_USART_NUM, ": "); - usart_putudec(ERROR_USART_NUM, line); - usart_putc(ERROR_USART_NUM, '\n'); - usart_putc(ERROR_USART_NUM, '\r'); + usart_putstr(ERROR_USART, "ERROR: FAILED ASSERT("); + usart_putstr(ERROR_USART, exp); + usart_putstr(ERROR_USART, "): "); + usart_putstr(ERROR_USART, file); + usart_putstr(ERROR_USART, ": "); + usart_putudec(ERROR_USART, line); + usart_putc(ERROR_USART, '\n'); + usart_putc(ERROR_USART, '\r'); /* Error fade */ __error(); } - /** * @brief Fades the error LED on and off * @sideeffect Sets output push-pull on ERROR_LED_PIN. @@ -117,7 +117,7 @@ void throb(void) { uint32 i = 0; gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_OUTPUT_PP); - /* Error fade */ + /* Error fade. */ while (1) { if (CC == TOP_CNT) { slope = -1; @@ -138,9 +138,8 @@ void throb(void) { i++; } #else - /* No error LED is connected; do nothing. */ + /* No error LED is defined; do nothing. */ while (1) ; #endif } - |