diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2018-04-12 18:04:00 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2018-04-20 11:19:37 -0400 |
commit | 6793970198645d94f39328ab465f736eb9cce8b4 (patch) | |
tree | 556f80de0f5c89985f7a18f49d5fff26ff2a50bd /src/stm32f1/serial.c | |
parent | 606222da5bb6d3754a5f38ae676a0c32fd79b59c (diff) | |
download | kutter-6793970198645d94f39328ab465f736eb9cce8b4.tar.gz kutter-6793970198645d94f39328ab465f736eb9cce8b4.tar.xz kutter-6793970198645d94f39328ab465f736eb9cce8b4.zip |
serial_irq: Add new generic/serial_irq.c code
Extract out common code from avr/serial.c, sam3x8e/serial.c, and
stm32f1/serial.c into a new generic/serial_irq.c file.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/stm32f1/serial.c')
-rw-r--r-- | src/stm32f1/serial.c | 124 |
1 files changed, 11 insertions, 113 deletions
diff --git a/src/stm32f1/serial.c b/src/stm32f1/serial.c index d79c74f8..bc6ebb94 100644 --- a/src/stm32f1/serial.c +++ b/src/stm32f1/serial.c @@ -4,30 +4,15 @@ // // This file may be distributed under the terms of the GNU GPLv3 license. -#include <string.h> // memmove +#include <stdint.h> #include "autoconf.h" // CONFIG_SERIAL_BAUD -#include "command.h" // DECL_CONSTANT +#include "board/serial_irq.h" // serial_rx_byte +#include "sched.h" // DECL_INIT #include "stm32f1xx.h" // UART #include "stm32f1xx_ll_bus.h" #include "stm32f1xx_ll_rcc.h" #include "stm32f1xx_ll_usart.h" #include "stm32f1xx_ll_gpio.h" -#include "board/irq.h" -#include "board/io.h" -#include "sched.h" // DECL_INIT - -#define SERIAL_BUFFER_SIZE 96 -static char receive_buf[SERIAL_BUFFER_SIZE]; -static uint32_t receive_pos; -static char transmit_buf[SERIAL_BUFFER_SIZE]; -static uint32_t transmit_pos, transmit_max; - - -/**************************************************************** - * Serial hardware - ****************************************************************/ - -DECL_CONSTANT(SERIAL_BAUD, CONFIG_SERIAL_BAUD); void serial_init(void) @@ -60,107 +45,20 @@ DECL_INIT(serial_init); void __visible USART1_IRQHandler(void) { - if (LL_USART_IsActiveFlag_RXNE(USART1) || LL_USART_IsActiveFlag_ORE(USART1)) { - uint8_t data = LL_USART_ReceiveData8(USART1); - if (data == MESSAGE_SYNC) - sched_wake_tasks(); - if (receive_pos >= sizeof(receive_buf)) - // Serial overflow - ignore it as crc error will force retransmit - return; - receive_buf[receive_pos++] = data; - return; - } + if (LL_USART_IsActiveFlag_RXNE(USART1) || LL_USART_IsActiveFlag_ORE(USART1)) + serial_rx_byte(LL_USART_ReceiveData8(USART1)); if (LL_USART_IsActiveFlag_TXE(USART1)) { - if (transmit_pos >= transmit_max) + uint8_t data; + int ret = serial_get_tx_byte(&data); + if (ret) LL_USART_DisableIT_TXE(USART1); else - LL_USART_TransmitData8(USART1, transmit_buf[transmit_pos++]); + LL_USART_TransmitData8(USART1, data); } } -// Enable tx interrupts -static void -enable_tx_irq(void) -{ - LL_USART_EnableIT_TXE(USART1); -} - -/**************************************************************** - * Console access functions - ****************************************************************/ - -// Remove from the receive buffer the given number of bytes -static void -console_pop_input(uint32_t len) -{ - uint32_t copied = 0; - for (;;) { - uint32_t rpos = readl(&receive_pos); - uint32_t needcopy = rpos - len; - if (needcopy) { - memmove(&receive_buf[copied], &receive_buf[copied + len] - , needcopy - copied); - copied = needcopy; - sched_wake_tasks(); - } - irqstatus_t flag = irq_save(); - if (rpos != readl(&receive_pos)) { - // Raced with irq handler - retry - irq_restore(flag); - continue; - } - receive_pos = needcopy; - irq_restore(flag); - break; - } -} - -// Process any incoming commands -void -console_task(void) -{ - uint8_t pop_count; - uint32_t rpos = readl(&receive_pos); - int8_t ret = command_find_block(receive_buf, rpos, &pop_count); - if (ret > 0) - command_dispatch(receive_buf, pop_count); - if (ret) - console_pop_input(pop_count); -} -DECL_TASK(console_task); - -// Encode and transmit a "response" message void -console_sendf(const struct command_encoder *ce, va_list args) +serial_enable_tx_irq(void) { - // Verify space for message - uint32_t tpos = readl(&transmit_pos), tmax = readl(&transmit_max); - if (tpos >= tmax) { - tpos = tmax = 0; - writel(&transmit_max, 0); - writel(&transmit_pos, 0); - } - uint32_t max_size = ce->max_size; - if (tmax + max_size > sizeof(transmit_buf)) { - if (tmax + max_size - tpos > sizeof(transmit_buf)) - // Not enough space for message - return; - // Disable TX irq and move buffer - writel(&transmit_max, 0); - tpos = readl(&transmit_pos); - tmax -= tpos; - memmove(&transmit_buf[0], &transmit_buf[tpos], tmax); - writel(&transmit_pos, 0); - writel(&transmit_max, tmax); - enable_tx_irq(); - } - - // Generate message - char *buf = &transmit_buf[tmax]; - uint32_t msglen = command_encodef(buf, ce, args); - command_add_frame(buf, msglen); - - // Start message transmit - writel(&transmit_max, tmax + msglen); - enable_tx_irq(); + LL_USART_EnableIT_TXE(USART1); } |