diff options
Diffstat (limited to 'chip/stm32/usart_rx_interrupt-stm32f3.c')
-rw-r--r--[l---------] | chip/stm32/usart_rx_interrupt-stm32f3.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/chip/stm32/usart_rx_interrupt-stm32f3.c b/chip/stm32/usart_rx_interrupt-stm32f3.c index a756455f9b..dfbe6ec3ff 120000..100644 --- a/chip/stm32/usart_rx_interrupt-stm32f3.c +++ b/chip/stm32/usart_rx_interrupt-stm32f3.c @@ -1 +1,49 @@ -usart_rx_interrupt.c
\ No newline at end of file +/* Copyright 2014 The ChromiumOS Authors + * 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 STM32F0 and STM32F3 */ + +#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; + 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; + int32_t status = STM32_USART_SR(base); + + if (status & STM32_USART_SR_RXNE) { + uint8_t byte = STM32_USART_RDR(base); + + if (!queue_add_unit(config->producer.queue, &byte)) + atomic_add((atomic_t *)&(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, + .info = NULL, +}; |