mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 18:41:11 +00:00
USART: Split RX driver between L and F families
The USART peripheral in the L and F families is different enough to need different receive drivers. In particular, the L family USART perihperal has no way of disabling the overflow error bit. So for that family we check and clear the bit, and keep a count of overflows. Signed-off-by: Anton Staaf <robotboy@chromium.org> BRANCH=None BUG=None TEST=make buildall -j Change-Id: Iea26c242d5177afd552a3bd4d6ab1a9c7a65f90e Reviewed-on: https://chromium-review.googlesource.com/288978 Trybot-Ready: Anton Staaf <robotboy@chromium.org> Tested-by: Anton Staaf <robotboy@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Anton Staaf <robotboy@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
77f68f204f
commit
014d180b1d
@@ -35,7 +35,8 @@ chip-$(CONFIG_COMMON_GPIO)+=gpio.o gpio-$(CHIP_FAMILY).o
|
||||
chip-$(CONFIG_COMMON_TIMER)+=hwtimer$(TIMER_TYPE).o
|
||||
chip-$(CONFIG_I2C)+=i2c-$(CHIP_FAMILY).o
|
||||
chip-$(CONFIG_STREAM_USART)+=usart.o usart-$(CHIP_FAMILY).o
|
||||
chip-$(CONFIG_STREAM_USART)+=usart_rx_interrupt.o usart_tx_interrupt.o
|
||||
chip-$(CONFIG_STREAM_USART)+=usart_rx_interrupt-$(CHIP_FAMILY).o
|
||||
chip-$(CONFIG_STREAM_USART)+=usart_tx_interrupt.o
|
||||
chip-$(CONFIG_STREAM_USART)+=usart_tx_dma.o
|
||||
chip-$(CONFIG_STREAM_USB)+=usb-stream.o
|
||||
chip-$(CONFIG_WATCHDOG)+=watchdog.o
|
||||
|
||||
@@ -189,16 +189,19 @@
|
||||
#define STM32_USART_RQR(base) STM32_USART_REG(base, 0x18)
|
||||
#define STM32_USART_ISR(base) STM32_USART_REG(base, 0x1C)
|
||||
#define STM32_USART_ICR(base) STM32_USART_REG(base, 0x20)
|
||||
#define STM32_USART_ICR_ORECF (1 << 3)
|
||||
#define STM32_USART_ICR_TCCF (1 << 6)
|
||||
#define STM32_USART_RDR(base) STM32_USART_REG(base, 0x24)
|
||||
#define STM32_USART_TDR(base) STM32_USART_REG(base, 0x28)
|
||||
/* register alias */
|
||||
#define STM32_USART_SR(base) STM32_USART_ISR(base)
|
||||
#define STM32_USART_SR_ORE (1 << 3)
|
||||
#define STM32_USART_SR_RXNE (1 << 5)
|
||||
#define STM32_USART_SR_TC (1 << 6)
|
||||
#define STM32_USART_SR_TXE (1 << 7)
|
||||
#else /* !CHIP_FAMILY_STM32F0 */
|
||||
#define STM32_USART_SR(base) STM32_USART_REG(base, 0x00)
|
||||
#define STM32_USART_SR_ORE (1 << 3)
|
||||
#define STM32_USART_SR_RXNE (1 << 5)
|
||||
#define STM32_USART_SR_TC (1 << 6)
|
||||
#define STM32_USART_SR_TXE (1 << 7)
|
||||
|
||||
@@ -42,7 +42,7 @@ void usart_init(struct usart_config const *config)
|
||||
*/
|
||||
STM32_USART_CR1(base) = 0x0000;
|
||||
STM32_USART_CR2(base) = 0x0000;
|
||||
STM32_USART_CR3(base) = STM32_USART_CR3_OVRDIS;
|
||||
STM32_USART_CR3(base) = 0x0000;
|
||||
|
||||
/*
|
||||
* Enable the RX, TX, and variant specific HW.
|
||||
@@ -51,6 +51,12 @@ void usart_init(struct usart_config const *config)
|
||||
config->tx->init(config);
|
||||
config->hw->ops->enable(config);
|
||||
|
||||
/*
|
||||
* Clear error counts.
|
||||
*/
|
||||
config->state->rx_overrun = 0;
|
||||
config->state->rx_dropped = 0;
|
||||
|
||||
/*
|
||||
* Enable the USART, this must be done last since most of the
|
||||
* configuration bits require that the USART be disabled for writes to
|
||||
@@ -98,6 +104,6 @@ void usart_set_baud_f(struct usart_config const *config, int frequency_hz)
|
||||
|
||||
void usart_interrupt(struct usart_config const *config)
|
||||
{
|
||||
config->tx->interrupt(config);
|
||||
config->rx->interrupt(config);
|
||||
}
|
||||
config->tx->interrupt(config);
|
||||
config->rx->interrupt(config);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ struct usart_state {
|
||||
* in the RX queue.
|
||||
*/
|
||||
uint32_t rx_dropped;
|
||||
uint32_t rx_overrun;
|
||||
};
|
||||
|
||||
struct usart_config;
|
||||
|
||||
1
chip/stm32/usart_rx_interrupt-stm32f0.c
Symbolic link
1
chip/stm32/usart_rx_interrupt-stm32f0.c
Symbolic link
@@ -0,0 +1 @@
|
||||
usart_rx_interrupt.c
|
||||
1
chip/stm32/usart_rx_interrupt-stm32f3.c
Symbolic link
1
chip/stm32/usart_rx_interrupt-stm32f3.c
Symbolic link
@@ -0,0 +1 @@
|
||||
usart_rx_interrupt.c
|
||||
64
chip/stm32/usart_rx_interrupt-stm32l.c
Normal file
64
chip/stm32/usart_rx_interrupt-stm32l.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/* Interrupt based USART RX driver for STM32L */
|
||||
|
||||
#include "usart.h"
|
||||
|
||||
#include "atomic.h"
|
||||
#include "common.h"
|
||||
#include "queue.h"
|
||||
#include "registers.h"
|
||||
|
||||
static void usart_rx_init(struct usart_config const *config)
|
||||
{
|
||||
intptr_t base = config->hw->base;
|
||||
|
||||
STM32_USART_CR1(base) |= STM32_USART_CR1_RXNEIE;
|
||||
STM32_USART_CR1(base) |= STM32_USART_CR1_RE;
|
||||
}
|
||||
|
||||
static void usart_rx_interrupt_handler(struct usart_config const *config)
|
||||
{
|
||||
intptr_t base = config->hw->base;
|
||||
int32_t status = STM32_USART_SR(base);
|
||||
|
||||
/*
|
||||
* We have to check and clear the overrun error flag on STM32L because
|
||||
* we can't disable it.
|
||||
*/
|
||||
if (status & STM32_USART_SR_ORE) {
|
||||
/*
|
||||
* In the unlikely event that the overrun error bit was set but
|
||||
* the RXNE bit was not (possibly because a read was done from
|
||||
* RDR without first reading the status register) we do a read
|
||||
* here to clear the overrun error bit.
|
||||
*/
|
||||
if (!(status & STM32_USART_SR_RXNE))
|
||||
(void)STM32_USART_RDR(config->hw->base);
|
||||
|
||||
atomic_add(&config->state->rx_overrun, 1);
|
||||
}
|
||||
|
||||
if (status & STM32_USART_SR_RXNE) {
|
||||
uint8_t byte = STM32_USART_RDR(base);
|
||||
|
||||
if (!queue_add_unit(config->producer.queue, &byte))
|
||||
atomic_add(&config->state->rx_dropped, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct usart_rx const usart_rx_interrupt = {
|
||||
.producer_ops = {
|
||||
/*
|
||||
* Nothing to do here, we either had enough space in the queue
|
||||
* when a character came in or we dropped it already.
|
||||
*/
|
||||
.read = NULL,
|
||||
},
|
||||
|
||||
.init = usart_rx_init,
|
||||
.interrupt = usart_rx_interrupt_handler,
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/* Interrupt based USART RX driver for STM32 */
|
||||
/* Interrupt based USART RX driver for STM32F0 and STM32F3 */
|
||||
|
||||
#include "usart.h"
|
||||
|
||||
@@ -18,20 +18,20 @@ static void usart_rx_init(struct usart_config const *config)
|
||||
|
||||
STM32_USART_CR1(base) |= STM32_USART_CR1_RXNEIE;
|
||||
STM32_USART_CR1(base) |= STM32_USART_CR1_RE;
|
||||
STM32_USART_CR3(base) |= STM32_USART_CR3_OVRDIS;
|
||||
}
|
||||
|
||||
static void usart_rx_interrupt_handler(struct usart_config const *config)
|
||||
{
|
||||
intptr_t base = config->hw->base;
|
||||
uint8_t byte;
|
||||
intptr_t base = config->hw->base;
|
||||
int32_t status = STM32_USART_SR(base);
|
||||
|
||||
if (!(STM32_USART_SR(base) & STM32_USART_SR_RXNE))
|
||||
return;
|
||||
if (status & STM32_USART_SR_RXNE) {
|
||||
uint8_t byte = STM32_USART_RDR(base);
|
||||
|
||||
byte = STM32_USART_RDR(base);
|
||||
|
||||
if (!queue_add_unit(config->producer.queue, &byte))
|
||||
atomic_add(&config->state->rx_dropped, 1);
|
||||
if (!queue_add_unit(config->producer.queue, &byte))
|
||||
atomic_add(&config->state->rx_dropped, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct usart_rx const usart_rx_interrupt = {
|
||||
|
||||
Reference in New Issue
Block a user