Merge remote-tracking branch 'refs/remotes/rogerclarkmelbourne/master'

This commit is contained in:
stevstrong 2016-09-23 17:07:49 +02:00
commit 43b3376881
7 changed files with 61 additions and 14 deletions

View File

@ -195,4 +195,5 @@ size_t HardwareSerial::write(unsigned char ch) {
void HardwareSerial::flush(void) {
usart_reset_rx(this->usart_device);
usart_reset_tx(this->usart_device);
}

View File

@ -40,6 +40,7 @@
*/
void usart_init(usart_dev *dev) {
rb_init(dev->rb, USART_RX_BUF_SIZE, dev->rx_buf);
rb_init(dev->wb, USART_TX_BUF_SIZE, dev->tx_buf);
rcc_clk_enable(dev->clk_id);
nvic_irq_enable(dev->irq_num);
}
@ -69,6 +70,8 @@ void usart_disable(usart_dev *dev) {
/* FIXME this misbehaves (on F1) if you try to use PWM on TX afterwards */
usart_reg_map *regs = dev->regs;
while(!rb_is_empty(dev->wb))
; // wait for TX completed
/* TC bit must be high before disabling the USART */
while((regs->CR1 & USART_CR1_UE) && !(regs->SR & USART_SR_TC))
;
@ -78,6 +81,7 @@ void usart_disable(usart_dev *dev) {
/* Clean up buffer */
usart_reset_rx(dev);
usart_reset_tx(dev);
}
/**
@ -90,9 +94,20 @@ void usart_disable(usart_dev *dev) {
uint32 usart_tx(usart_dev *dev, const uint8 *buf, uint32 len) {
usart_reg_map *regs = dev->regs;
uint32 txed = 0;
while ((regs->SR & USART_SR_TXE) && (txed < len)) {
while (rb_is_empty(dev->wb) && (regs->SR & USART_SR_TXE) && (txed < len)) {
regs->DR = buf[txed++];
}
regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE while populating the buffer
while (txed < len) {
if (rb_safe_insert(dev->wb, buf[txed])) {
txed++;
}
else
break;
}
if (!rb_is_empty(dev->wb)) {
regs->CR1 |= USART_CR1_TXEIE;
}
return txed;
}

View File

@ -41,9 +41,11 @@
*/
static ring_buffer usart1_rb;
static ring_buffer usart1_wb;
static usart_dev usart1 = {
.regs = USART1_BASE,
.rb = &usart1_rb,
.wb = &usart1_wb,
.max_baud = 4500000UL,
.clk_id = RCC_USART1,
.irq_num = NVIC_USART1,
@ -52,9 +54,11 @@ static usart_dev usart1 = {
usart_dev *USART1 = &usart1;
static ring_buffer usart2_rb;
static ring_buffer usart2_wb;
static usart_dev usart2 = {
.regs = USART2_BASE,
.rb = &usart2_rb,
.wb = &usart2_wb,
.max_baud = 2250000UL,
.clk_id = RCC_USART2,
.irq_num = NVIC_USART2,
@ -63,9 +67,11 @@ static usart_dev usart2 = {
usart_dev *USART2 = &usart2;
static ring_buffer usart3_rb;
static ring_buffer usart3_wb;
static usart_dev usart3 = {
.regs = USART3_BASE,
.rb = &usart3_rb,
.wb = &usart3_wb,
.max_baud = 2250000UL,
.clk_id = RCC_USART3,
.irq_num = NVIC_USART3,
@ -75,9 +81,11 @@ usart_dev *USART3 = &usart3;
#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
static ring_buffer uart4_rb;
static ring_buffer uart4_wb;
static usart_dev uart4 = {
.regs = UART4_BASE,
.rb = &uart4_rb,
.wb = &uart4_wb,
.max_baud = 2250000UL,
.clk_id = RCC_UART4,
.irq_num = NVIC_UART4,
@ -86,9 +94,11 @@ static usart_dev uart4 = {
usart_dev *UART4 = &uart4;
static ring_buffer uart5_rb;
static ring_buffer uart5_wb;
static usart_dev uart5 = {
.regs = UART5_BASE,
.rb = &uart5_rb,
.wb = &uart5_wb,
.max_baud = 2250000UL,
.clk_id = RCC_UART5,
.irq_num = NVIC_UART5,
@ -191,23 +201,23 @@ void usart_foreach(void (*fn)(usart_dev*)) {
*/
void __irq_usart1(void) {
usart_irq(&usart1_rb, USART1_BASE);
usart_irq(&usart1_rb, &usart1_wb, USART1_BASE);
}
void __irq_usart2(void) {
usart_irq(&usart2_rb, USART2_BASE);
usart_irq(&usart2_rb, &usart2_wb, USART2_BASE);
}
void __irq_usart3(void) {
usart_irq(&usart3_rb, USART3_BASE);
usart_irq(&usart3_rb, &usart3_wb, USART3_BASE);
}
#ifdef STM32_HIGH_DENSITY
void __irq_uart4(void) {
usart_irq(&uart4_rb, UART4_BASE);
usart_irq(&uart4_rb, &uart4_wb, UART4_BASE);
}
void __irq_uart5(void) {
usart_irq(&uart5_rb, UART5_BASE);
usart_irq(&uart5_rb, &uart5_wb, UART5_BASE);
}
#endif

View File

@ -190,5 +190,5 @@ TwoWire::~TwoWire() {
}
// Declare the instance that the users of the library can use
//TwoWire Wire(SCL, SDA, SOFT_STANDARD);
TwoWire Wire(PB6, PB7, SOFT_STANDARD);
TwoWire Wire(SCL, SDA, SOFT_STANDARD);
//TwoWire Wire(PB6, PB7, SOFT_STANDARD);

View File

@ -47,8 +47,8 @@
* On the Maple, let the default pins be in the same location as the Arduino
* pins
*/
#define SDA 19
#define SCL 20
#define SDA PB7
#define SCL PB6
#define SOFT_STANDARD 27
#define SOFT_FAST 0

View File

@ -381,16 +381,22 @@ typedef struct usart_reg_map {
#define USART_RX_BUF_SIZE 64
#endif
#ifndef USART_TX_BUF_SIZE
#define USART_TX_BUF_SIZE 64
#endif
/** USART device type */
typedef struct usart_dev {
usart_reg_map *regs; /**< Register map */
ring_buffer *rb; /**< RX ring buffer */
ring_buffer *wb; /**< TX ring buffer */
uint32 max_baud; /**< @brief Deprecated.
* Maximum baud rate. */
uint8 rx_buf[USART_RX_BUF_SIZE]; /**< @brief Deprecated.
* Actual RX buffer used by rb.
* This field will be removed in
* a future release. */
uint8 tx_buf[USART_TX_BUF_SIZE]; /**< Actual TX buffer used by wb */
rcc_clk_id clk_id; /**< RCC clock information */
nvic_irq_num irq_num; /**< USART NVIC interrupt */
} usart_dev;
@ -502,6 +508,14 @@ static inline void usart_reset_rx(usart_dev *dev) {
rb_reset(dev->rb);
}
/**
* @brief Discard the contents of a serial port's RX buffer.
* @param dev Serial port whose buffer to empty.
*/
static inline void usart_reset_tx(usart_dev *dev) {
rb_reset(dev->wb);
}
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -37,13 +37,13 @@
#include <libmaple/ring_buffer.h>
#include <libmaple/usart.h>
static inline __always_inline void usart_irq(ring_buffer *rb, usart_reg_map *regs) {
/* We can get RXNE and ORE interrupts here. Only RXNE signifies
* availability of a byte in DR.
static inline __always_inline void usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs) {
/* Handling RXNEIE and TXEIE interrupts.
* RXNE signifies availability of a byte in DR.
*
* See table 198 (sec 27.4, p809) in STM document RM0008 rev 15.
* We enable RXNEIE. */
if (regs->SR & USART_SR_RXNE) {
if ((regs->CR1 & USART_CR1_RXNEIE) && (regs->SR & USART_SR_RXNE)) {
#ifdef USART_SAFE_INSERT
/* If the buffer is full and the user defines USART_SAFE_INSERT,
* ignore new bytes. */
@ -53,6 +53,13 @@ static inline __always_inline void usart_irq(ring_buffer *rb, usart_reg_map *reg
rb_push_insert(rb, (uint8)regs->DR);
#endif
}
/* TXE signifies readiness to send a byte to DR. */
if ((regs->CR1 & USART_CR1_TXEIE) && (regs->SR & USART_SR_TXE)) {
if (!rb_is_empty(wb))
regs->DR=rb_remove(wb);
else
regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE
}
}
uint32 _usart_clock_freq(usart_dev *dev);