]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
Remove flow control, factor out ring buffer
authorLeo C <erbl259-lmu@yahoo.de>
Sun, 27 Jul 2014 20:58:42 +0000 (22:58 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Sun, 27 Jul 2014 20:58:42 +0000 (22:58 +0200)
avr/ring.h [new file with mode: 0644]
avr/serial.c

diff --git a/avr/ring.h b/avr/ring.h
new file mode 100644 (file)
index 0000000..d57f9aa
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef RING_H
+#define RING_H
+
+struct ring {
+       uint8_t *data;
+       uint_fast8_t mask;
+       volatile uint_fast8_t begin;
+       volatile uint_fast8_t end;
+};
+
+
+static inline
+void ring_init(struct ring *ring, uint8_t *buf, int size)
+{
+       ring->data = buf;
+       ring->mask = (size-1) & 0xff;
+       ring->begin = 0;
+       ring->end = 0;
+}
+
+static inline
+int ring_write_ch(struct ring *ring, uint8_t ch)
+{
+       uint_fast8_t ep = ring->end;
+
+       ring->data[ep] = ch;
+       ep = (ep + 1) & ring->mask;
+
+       if ((ep) != ring->begin) {
+               ring->end = ep;
+               return 1;
+       }
+
+       return -1;
+}
+
+#if 0
+static inline
+int ring_write(struct ring *ring, uint8_t *data, int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++) {
+               if (ring_write_ch(ring, data[i]) < 0)
+                       return -i;
+       }
+
+       return i;
+}
+#endif
+
+static inline
+int ring_read_ch(struct ring *ring)
+{
+       int ret = -1;
+       uint_fast8_t bp = ring->begin;
+
+       if (bp != ring->end) {
+               ret = ring->data[bp];
+               ring->begin = (bp + 1) & ring->mask;
+       }
+
+       return ret;
+}
+
+
+static inline
+int_fast8_t ring_is_empty(struct ring *ring)
+{
+       return ring->begin == ring->end;
+}
+
+#endif /* RING_H */
+
index 4b3cd42c580e0ca95d8f7a136e7878a6f81925b1..2d2c5515ddba3c4f441d48b712fbbfe62cd1bd16 100644 (file)
@@ -7,6 +7,7 @@
 #include <errno.h>
 #include <stdio.h>
 
+#include "ring.h"
 #include "serial.h"
 
 
@@ -14,31 +15,9 @@ static int _write(char c, FILE *stream);
 static FILE mystdout = FDEV_SETUP_STREAM(_write, 
                NULL, _FDEV_SETUP_WRITE);
 
-#define CTL_S  ('S'-'@')               /* DC3 (Stop) */
-#define CTL_Q  ('Q'-'@')               /* DC1 (Start) */
 
-typedef enum {
-       IDLE,
-       ACTIVE,
-       REQ_STOP,
-       REQ_CONT,
-       STOPPED
-} xmit_stat_t;
 
-
-static volatile uint8_t stat_tx;
-static volatile uint8_t stat_rx;
-
-
-struct ring {
-       uint8_t *data;
-       uint_fast8_t mask;
-       volatile uint_fast8_t begin;
-       volatile uint_fast8_t end;
-};
-
-
-#define BUFFER_SIZE 256
+#define BUFFER_SIZE 64
 
 #if ((BUFFER_SIZE-1) & BUFFER_SIZE)
 # error: BUFFER_SIZE not power of 2
@@ -54,60 +33,6 @@ uint8_t rx_ring_buffer[BUFFER_SIZE];
 uint8_t tx_ring_buffer[BUFFER_SIZE];
 
 
-static void ring_init(struct ring *ring, uint8_t *buf, int size)
-{
-       ring->data = buf;
-       ring->mask = (size-1) & 0xff;
-       ring->begin = 0;
-       ring->end = 0;
-}
-
-static int ring_write_ch(struct ring *ring, uint8_t ch)
-{
-       uint_fast8_t ep = (ring->end + 1) & ring->mask;
-
-       if ((ep) != ring->begin) {
-               ring->data[ring->end] = ch;
-               ring->end = ep;
-               return 1;
-       }
-
-       return -1;
-}
-
-#if 0
-static int ring_write(struct ring *ring, uint8_t *data, int size)
-{
-       int i;
-
-       for (i = 0; i < size; i++) {
-               if (ring_write_ch(ring, data[i]) < 0)
-                       return -i;
-       }
-
-       return i;
-}
-#endif
-
-static int ring_read_ch(struct ring *ring)
-{
-       int ret = -1;
-       uint_fast8_t i = ring->begin;
-
-       if (i != ring->end) {
-               ret = ring->data[i];
-               ring->begin = (i +1) & ring->mask;
-       }
-
-       return ret;
-}
-
-
-static int_fast8_t ring_is_empty(struct ring *ring)
-{
-       return ring->begin == ring->end;
-}
-
 
 /* Initialize UART */
 
@@ -122,17 +47,14 @@ void usart0_setup(void) {
                ring_init(&rx_ring, rx_ring_buffer, BUFFER_SIZE);
                ring_init(&tx_ring, tx_ring_buffer, BUFFER_SIZE);
 
-               stat_tx = ACTIVE;
-               stat_rx = ACTIVE;
-
-               UCSR0A = _BV(U2X0);
-               UBRR0L = F_CPU / BAUD / 8 - 1;
+               UCSR0A = 0;
+               UBRR0  = F_CPU / BAUD / 16 - 1;
                UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
                UCSR0C = 3 << UCSZ00;
        };
 }
 
-
+/*--------------------------------------------------------------------------*/
 
 /* UART RXC interrupt */
 
@@ -141,41 +63,23 @@ ISR(USART0_RX_vect)
        uint8_t d;
 
        d = UDR0;
-
-       switch (d) {
-       case CTL_S:
-               stat_tx = REQ_STOP;
-               break;
-       case CTL_Q:
-               if ((stat_tx == STOPPED) || stat_tx == REQ_STOP) {
-                       UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0) | _BV(UDRIE0);
-                       stat_tx = ACTIVE;
-               }
-               break;
-       default:
-               ring_write_ch(&rx_ring, d);
-               break;
-       }
+       ring_write_ch(&rx_ring, d);
 }
 
 /* UART UDRE interrupt */
 
 ISR(USART0_UDRE_vect)
 {
-       uint8_t s;
+       int d = ring_read_ch(&tx_ring);
 
-       s = !ring_is_empty(&tx_ring);
-       if ((s == 0) || (stat_tx != ACTIVE)) {
+       if (d < 0) {
+               /* Disable TX empty interrupt. */
                UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
-               if (s)
-                       stat_tx = STOPPED;
        } else {
-               UDR0 = ring_read_ch(&tx_ring);
+               UDR0 = d;
        }
 }
 
-
-
 /*--------------------------------------------------------------------------*/
 
 void serial_setup(void)
@@ -206,12 +110,8 @@ void serial_putc(uint8_t data)
 {
        while (ring_write_ch(&tx_ring, data) < 0)
                ;
-       switch (stat_tx) {
-       case ACTIVE:
-       default:
-               /* Enable the TXE interrupt. */
-               UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0) | _BV(UDRIE0);
-               break;
-       }
+
+       /* Enable the TXE interrupt. */
+       UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0) | _BV(UDRIE0);
 }