summaryrefslogtreecommitdiff
path: root/n/avr/modules/uart/uart.avr.c
diff options
context:
space:
mode:
Diffstat (limited to 'n/avr/modules/uart/uart.avr.c')
-rw-r--r--n/avr/modules/uart/uart.avr.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/n/avr/modules/uart/uart.avr.c b/n/avr/modules/uart/uart.avr.c
index eee9679..2f5c87e 100644
--- a/n/avr/modules/uart/uart.avr.c
+++ b/n/avr/modules/uart/uart.avr.c
@@ -22,14 +22,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* }}} */
+#include "common.h"
#include "uart.h"
#include "uart_common.h"
#if AC_UART (PORT) != -1
-#include <avr/io.h>
-#include <avr/signal.h>
+#include "io.h"
/* Tested AVR check. */
#if defined (__AVR_ATmega8__)
@@ -91,14 +91,16 @@
#endif
/* Mode. */
-#define POLLING 0
-#define RING 1
+#define POLLING 1
+#define RING 2
#define SEND_MODE AC_UART (SEND_MODE)
#define RECV_MODE AC_UART (RECV_MODE)
#if RECV_MODE == POLLING
# define RECV_IE 0
-#else
+#elif RECV_MODE == RING
# define RECV_IE _BV (RXCIE)
+#else
+# error "uart: bad mode"
#endif
/* Parity. */
@@ -147,9 +149,16 @@ static uint8_t uart_recv_buffer[RECV_BUFFER_SIZE];
static volatile uint8_t uart_recv_head, uart_recv_tail;
#endif
-/* Last error code. */
+/* Full buffer politic. */
+#define DROP 1
+#define WAIT 2
+#define SEND_BUFFER_FULL AC_UART (SEND_BUFFER_FULL)
+#if SEND_BUFFER_FULL != DROP && SEND_BUFFER_FULL != WAIT
+# error "uart: bad full buffer politic"
+#endif
+
+/* Error code. */
#define ERROR_BITS (_BV (FE) | _BV (DOR) | _BV (PE))
-static volatile uint8_t uart_error_code;
/* +AutoDec */
/* -AutoDec */
@@ -175,7 +184,6 @@ uart_init (void)
uart_send_head = 0;
uart_send_tail = 0;
#endif
- uart_error_code = 0;
}
/** Read a char. */
@@ -183,12 +191,14 @@ uint8_t
uart_getc (void)
{
#if RECV_MODE == POLLING
- uint8_t tmperr;
+ uint8_t tmperr, c;
loop_until_bit_is_set (UCSRA, RXC);
tmperr = UCSRA & ERROR_BITS;
+ c = UDR;
if (tmperr)
- uart_error_code = tmperr;
- return UDR;
+ return 0xff;
+ else
+ return c;
#elif RECV_MODE == RING
uint8_t tmptail = uart_recv_tail;
while (uart_recv_head == tmptail)
@@ -204,26 +214,29 @@ void
uart_putc (uint8_t c)
{
#if SEND_MODE == POLLING
+# if SEND_BUFFER_FULL == WAIT
loop_until_bit_is_set (UCSRA, UDRE);
+# else
+ if (!(UCSRA & _BV (UDRE)))
+ return;
+# endif
UDR = c;
#elif SEND_MODE == RING
uint8_t tmphead;
tmphead = (uart_send_head + 1) & SEND_BUFFER_MASK;
+# if SEND_BUFFER_FULL == WAIT
while (tmphead == uart_send_tail)
;
+# else
+ if (tmphead == uart_send_tail)
+ return;
+# endif
uart_send_buffer[tmphead] = c;
uart_send_head = tmphead;
UCSRB |= _BV (UDRIE);
#endif
}
-/** Retrieve error condition, 0 if no error. */
-uint8_t
-uart_error (void)
-{
- return uart_error_code;
-}
-
/** Retrieve availlable chars. */
uint8_t
uart_poll (void)
@@ -244,14 +257,18 @@ SIGNAL (SIG_UART_RECV)
uint8_t tmphead;
uint8_t tmperr;
tmperr = UCSRA & ERROR_BITS;
- if (tmperr)
- uart_error_code = tmperr;
c = UDR;
+ if (tmperr)
+ c = 0xff;
tmphead = (uart_recv_head + 1) & RECV_BUFFER_MASK;
uart_recv_head = tmphead;
/* If overflowed, clear the receive buffer. */
if (tmphead == uart_recv_tail)
- uart_error_code = 0xff;
+ {
+ tmphead = (tmphead + 1) & RECV_BUFFER_MASK;
+ uart_recv_head = tmphead;
+ c = 0xff;
+ }
uart_recv_buffer[tmphead] = c;
}