arduino-0018-windows
This commit is contained in:
parent
157fd6f1a1
commit
f39fc49523
5182 changed files with 950586 additions and 0 deletions
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Stdio demo, UART implementation
|
||||
*
|
||||
* $Id: uart.c,v 1.1 2005/12/28 21:38:59 joerg_wunsch Exp $
|
||||
*/
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
/*
|
||||
* Initialize the UART to 9600 Bd, tx/rx, 8N1.
|
||||
*/
|
||||
void
|
||||
uart_init(void)
|
||||
{
|
||||
#if F_CPU < 2000000UL && defined(U2X)
|
||||
UCSRA = _BV(U2X); /* improve baud rate error by using 2x clk */
|
||||
UBRRL = (F_CPU / (8UL * UART_BAUD)) - 1;
|
||||
#else
|
||||
UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1;
|
||||
#endif
|
||||
UCSRB = _BV(TXEN) | _BV(RXEN); /* tx/rx enable */
|
||||
}
|
||||
|
||||
/*
|
||||
* Send character c down the UART Tx, wait until tx holding register
|
||||
* is empty.
|
||||
*/
|
||||
int
|
||||
uart_putchar(char c, FILE *stream)
|
||||
{
|
||||
|
||||
if (c == '\a')
|
||||
{
|
||||
fputs("*ring*\n", stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
uart_putchar('\r', stream);
|
||||
loop_until_bit_is_set(UCSRA, UDRE);
|
||||
UDR = c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a character from the UART Rx.
|
||||
*
|
||||
* This features a simple line-editor that allows to delete and
|
||||
* re-edit the characters entered, until either CR or NL is entered.
|
||||
* Printable characters entered will be echoed using uart_putchar().
|
||||
*
|
||||
* Editing characters:
|
||||
*
|
||||
* . \b (BS) or \177 (DEL) delete the previous character
|
||||
* . ^u kills the entire input buffer
|
||||
* . ^w deletes the previous word
|
||||
* . ^r sends a CR, and then reprints the buffer
|
||||
* . \t will be replaced by a single space
|
||||
*
|
||||
* All other control characters will be ignored.
|
||||
*
|
||||
* The internal line buffer is RX_BUFSIZE (80) characters long, which
|
||||
* includes the terminating \n (but no terminating \0). If the buffer
|
||||
* is full (i. e., at RX_BUFSIZE-1 characters in order to keep space for
|
||||
* the trailing \n), any further input attempts will send a \a to
|
||||
* uart_putchar() (BEL character), although line editing is still
|
||||
* allowed.
|
||||
*
|
||||
* Input errors while talking to the UART will cause an immediate
|
||||
* return of -1 (error indication). Notably, this will be caused by a
|
||||
* framing error (e. g. serial line "break" condition), by an input
|
||||
* overrun, and by a parity error (if parity was enabled and automatic
|
||||
* parity recognition is supported by hardware).
|
||||
*
|
||||
* Successive calls to uart_getchar() will be satisfied from the
|
||||
* internal buffer until that buffer is emptied again.
|
||||
*/
|
||||
int
|
||||
uart_getchar(FILE *stream)
|
||||
{
|
||||
uint8_t c;
|
||||
char *cp, *cp2;
|
||||
static char b[RX_BUFSIZE];
|
||||
static char *rxp;
|
||||
|
||||
if (rxp == 0)
|
||||
for (cp = b;;)
|
||||
{
|
||||
loop_until_bit_is_set(UCSRA, RXC);
|
||||
if (UCSRA & _BV(FE))
|
||||
return _FDEV_EOF;
|
||||
if (UCSRA & _BV(DOR))
|
||||
return _FDEV_ERR;
|
||||
c = UDR;
|
||||
/* behaviour similar to Unix stty ICRNL */
|
||||
if (c == '\r')
|
||||
c = '\n';
|
||||
if (c == '\n')
|
||||
{
|
||||
*cp = c;
|
||||
uart_putchar(c, stream);
|
||||
rxp = b;
|
||||
break;
|
||||
}
|
||||
else if (c == '\t')
|
||||
c = ' ';
|
||||
|
||||
if ((c >= (uint8_t)' ' && c <= (uint8_t)'\x7e') ||
|
||||
c >= (uint8_t)'\xa0')
|
||||
{
|
||||
if (cp == b + RX_BUFSIZE - 1)
|
||||
uart_putchar('\a', stream);
|
||||
else
|
||||
{
|
||||
*cp++ = c;
|
||||
uart_putchar(c, stream);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'c' & 0x1f:
|
||||
return -1;
|
||||
|
||||
case '\b':
|
||||
case '\x7f':
|
||||
if (cp > b)
|
||||
{
|
||||
uart_putchar('\b', stream);
|
||||
uart_putchar(' ', stream);
|
||||
uart_putchar('\b', stream);
|
||||
cp--;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r' & 0x1f:
|
||||
uart_putchar('\r', stream);
|
||||
for (cp2 = b; cp2 < cp; cp2++)
|
||||
uart_putchar(*cp2, stream);
|
||||
break;
|
||||
|
||||
case 'u' & 0x1f:
|
||||
while (cp > b)
|
||||
{
|
||||
uart_putchar('\b', stream);
|
||||
uart_putchar(' ', stream);
|
||||
uart_putchar('\b', stream);
|
||||
cp--;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w' & 0x1f:
|
||||
while (cp > b && cp[-1] != ' ')
|
||||
{
|
||||
uart_putchar('\b', stream);
|
||||
uart_putchar(' ', stream);
|
||||
uart_putchar('\b', stream);
|
||||
cp--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
c = *rxp++;
|
||||
if (c == '\n')
|
||||
rxp = 0;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
Reference in a new issue