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/avr/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/avr/serial.c')
-rw-r--r-- | src/avr/serial.c | 119 |
1 files changed, 9 insertions, 110 deletions
diff --git a/src/avr/serial.c b/src/avr/serial.c index 5fcf54d6..4b72bf76 100644 --- a/src/avr/serial.c +++ b/src/avr/serial.c @@ -1,31 +1,14 @@ // AVR serial port code. // -// Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net> +// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net> // // This file may be distributed under the terms of the GNU GPLv3 license. #include <avr/interrupt.h> // USART0_RX_vect -#include <string.h> // memmove #include "autoconf.h" // CONFIG_SERIAL_BAUD -#include "board/io.h" // readb -#include "board/misc.h" // console_sendf -#include "command.h" // DECL_CONSTANT -#include "irq.h" // irq_save -#include "pgm.h" // READP +#include "board/serial_irq.h" // serial_rx_byte #include "sched.h" // DECL_INIT -static char receive_buf[192]; -static uint8_t receive_pos; -static char transmit_buf[96]; -static uint8_t transmit_pos, transmit_max; - - -/**************************************************************** - * Serial hardware - ****************************************************************/ - -DECL_CONSTANT(SERIAL_BAUD, CONFIG_SERIAL_BAUD); - // Define serial port registers on AT90USB1286 #if !defined(UCSR0A) && defined(UCSR1A) #define UCSR0A UCSR1A @@ -64,107 +47,23 @@ DECL_INIT(serial_init); // Rx interrupt - data available to be read. ISR(USART0_RX_vect) { - uint8_t data = UDR0; - 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; + serial_rx_byte(UDR0); } // Tx interrupt - data can be written to serial. ISR(USART0_UDRE_vect) { - if (transmit_pos >= transmit_max) + uint8_t data; + int ret = serial_get_tx_byte(&data); + if (ret) UCSR0B &= ~(1<<UDRIE0); else - UDR0 = transmit_buf[transmit_pos++]; + UDR0 = data; } // Enable tx interrupts -static void -enable_tx_irq(void) -{ - UCSR0B |= 1<<UDRIE0; -} - - -/**************************************************************** - * Console access functions - ****************************************************************/ - -// Remove from the receive buffer the given number of bytes -static void -console_pop_input(uint8_t len) -{ - uint8_t copied = 0; - for (;;) { - uint8_t rpos = readb(&receive_pos); - uint8_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 != readb(&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) +serial_enable_tx_irq(void) { - uint8_t pop_count, rpos = readb(&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) -{ - // Verify space for message - uint8_t tpos = readb(&transmit_pos), tmax = readb(&transmit_max); - if (tpos >= tmax) { - tpos = tmax = 0; - writeb(&transmit_max, 0); - writeb(&transmit_pos, 0); - } - uint8_t max_size = READP(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 - writeb(&transmit_max, 0); - tpos = readb(&transmit_pos); - tmax -= tpos; - memmove(&transmit_buf[0], &transmit_buf[tpos], tmax); - writeb(&transmit_pos, 0); - writeb(&transmit_max, tmax); - enable_tx_irq(); - } - - // Generate message - char *buf = &transmit_buf[tmax]; - uint8_t msglen = command_encodef(buf, ce, args); - command_add_frame(buf, msglen); - - // Start message transmit - writeb(&transmit_max, tmax + msglen); - enable_tx_irq(); + UCSR0B |= 1<<UDRIE0; } |