From a740bf058854353c3086e32a95faf53acd06ba2f Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Thu, 23 Nov 2006 16:02:55 +0000 Subject: [PATCH] Replaced avr-lib serial with custom code in wiring.c. --- readme.txt | 4 + targets/arduino/Serial.c | 45 ------ targets/arduino/Serial.h | 32 ---- targets/arduino/avrlibdefs.h | 77 --------- targets/arduino/avrlibtypes.h | 84 ---------- targets/arduino/buffer.c | 110 ------------- targets/arduino/buffer.h | 56 ------- targets/arduino/global.h | 40 ----- targets/arduino/rprintf.h | 135 ---------------- targets/arduino/uart.c | 284 ---------------------------------- targets/arduino/uart.h | 148 ------------------ targets/arduino/wiring.c | 72 +++++++-- 12 files changed, 65 insertions(+), 1022 deletions(-) delete mode 100644 targets/arduino/Serial.c delete mode 100755 targets/arduino/Serial.h delete mode 100755 targets/arduino/avrlibdefs.h delete mode 100755 targets/arduino/avrlibtypes.h delete mode 100755 targets/arduino/buffer.c delete mode 100755 targets/arduino/buffer.h delete mode 100755 targets/arduino/global.h delete mode 100755 targets/arduino/rprintf.h delete mode 100755 targets/arduino/uart.c delete mode 100755 targets/arduino/uart.h diff --git a/readme.txt b/readme.txt index 5c4bef8cc..1268f17ff 100644 --- a/readme.txt +++ b/readme.txt @@ -47,6 +47,10 @@ UPDATES 0007 +Replaced avr-lib's uart routines with custom code for handling serial +communication and modified C++ serial commands to call the C serial commands, +saving ~1 KB of space; the code may behave slightly differently in border +cases (e.g. non-standard speeds, or on overflow). Adding Sonar library for controlling Parallax Ultrasonic PING))) sensors. Defining binary constants: e.g. B1010 is 6. Digital pins 0 and 1 can be used for i/o until a call to Serial.begin(). diff --git a/targets/arduino/Serial.c b/targets/arduino/Serial.c deleted file mode 100644 index 528118316..000000000 --- a/targets/arduino/Serial.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - Serial.c - Serial library for Wiring - Based on Hernando Barragan's original C implementation - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "Serial.h" -#include "uart.h" - -void uart_init(uint8_t uart, long baudrate) -{ - uartInit(); - uartSetBaudRate(baudrate); -} - -int uart_read(uint8_t uart) -{ - return uartGetByte(); -} - -uint8_t uart_available(uint8_t uart) -{ - return uartGetRxBuffer()->datalength; -} - -void uart_write(uint8_t uart, char *buf, uint8_t len) -{ - int i; - for (i = 0; i < len; i++) - uartSendByte(buf[i]); -} diff --git a/targets/arduino/Serial.h b/targets/arduino/Serial.h deleted file mode 100755 index ae3fc14a2..000000000 --- a/targets/arduino/Serial.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Serial.h - Serial library for Wiring - Based on Hernando Barragan's original C implementation - Copyright (c) 2006 Nicholas Zambetti. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef Serial_h -#define Serial_h - -#include - -void uart_init(uint8_t, long); -int uart_read(uint8_t); -uint8_t uart_available(uint8_t); -void uart_write(uint8_t, char*, uint8_t); - -#endif - diff --git a/targets/arduino/avrlibdefs.h b/targets/arduino/avrlibdefs.h deleted file mode 100755 index 7116dde42..000000000 --- a/targets/arduino/avrlibdefs.h +++ /dev/null @@ -1,77 +0,0 @@ -/*! \file avrlibdefs.h \brief AVRlib global defines and macros. */ -//***************************************************************************** -// -// File Name : 'avrlibdefs.h' -// Title : AVRlib global defines and macros include file -// Author : Pascal Stang -// Created : 7/12/2001 -// Revised : 9/30/2002 -// Version : 1.1 -// Target MCU : Atmel AVR series -// Editor Tabs : 4 -// -// Description : This include file is designed to contain items useful to all -// code files and projects, regardless of specific implementation. -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - - -#ifndef AVRLIBDEFS_H -#define AVRLIBDEFS_H - -// Code compatibility to new AVR-libc -// outb(), inb(), BV(), sbi(), cbi(), sei(), cli() -#ifndef outb - #define outb(addr, data) addr = (data) -#endif -#ifndef inb - #define inb(addr) (addr) -#endif -#ifndef BV - #define BV(bit) (1<<(bit)) -#endif -#ifndef cbi - #define cbi(reg,bit) reg &= ~(BV(bit)) -#endif -#ifndef sbi - #define sbi(reg,bit) reg |= (BV(bit)) -#endif -#ifndef cli - #define cli() __asm__ __volatile__ ("cli" ::) -#endif -#ifndef sei - #define sei() __asm__ __volatile__ ("sei" ::) -#endif - -// support for individual port pin naming in the mega128 -// see port128.h for details -#ifdef __AVR_ATmega128__ -// not currently necessary due to inclusion -// of these defines in newest AVR-GCC -// do a quick test to see if include is needed -#ifndef PD0 - #include "port128.h" -#endif -#endif - -// use this for packed structures -// (this is seldom necessary on an 8-bit architecture like AVR, -// but can assist in code portability to AVR) -#define GNUC_PACKED __attribute__((packed)) - -// port address helpers -#define DDR(x) ((x)-1) // address of data direction register of port x -#define PIN(x) ((x)-2) // address of input register of port x - -// MIN/MAX/ABS macros -#define MIN(a,b) ((ab)?(a):(b)) -#define ABS(x) ((x>0)?(x):(-x)) - -// constants -#define PI 3.14159265359 - -#endif diff --git a/targets/arduino/avrlibtypes.h b/targets/arduino/avrlibtypes.h deleted file mode 100755 index 4d44ac562..000000000 --- a/targets/arduino/avrlibtypes.h +++ /dev/null @@ -1,84 +0,0 @@ -/*! \file avrlibtypes.h \brief AVRlib global types and typedefines. */ -//***************************************************************************** -// -// File Name : 'avrlibtypes.h' -// Title : AVRlib global types and typedefines include file -// Author : Pascal Stang -// Created : 7/12/2001 -// Revised : 9/30/2002 -// Version : 1.0 -// Target MCU : Atmel AVR series -// Editor Tabs : 4 -// -// Description : Type-defines required and used by AVRlib. Most types are also -// generally useful. -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - - -#ifndef AVRLIBTYPES_H -#define AVRLIBTYPES_H - -#ifndef WIN32 - // true/false defines - #define FALSE 0 - #define TRUE -1 -#endif - -// datatype definitions macros -typedef unsigned char u08; -typedef signed char s08; -typedef unsigned short u16; -typedef signed short s16; -typedef unsigned long u32; -typedef signed long s32; -typedef unsigned long long u64; -typedef signed long long s64; - -/* use inttypes.h instead -// C99 standard integer type definitions -typedef unsigned char uint8_t; -typedef signed char int8_t; -typedef unsigned short uint16_t; -typedef signed short int16_t; -typedef unsigned long uint32_t; -typedef signed long int32_t; -typedef unsigned long uint64_t; -typedef signed long int64_t; -*/ -// maximum value that can be held -// by unsigned data types (8,16,32bits) -#define MAX_U08 255 -#define MAX_U16 65535 -#define MAX_U32 4294967295 - -// maximum values that can be held -// by signed data types (8,16,32bits) -#define MIN_S08 -128 -#define MAX_S08 127 -#define MIN_S16 -32768 -#define MAX_S16 32767 -#define MIN_S32 -2147483648 -#define MAX_S32 2147483647 - -#ifndef WIN32 - // more type redefinitions - typedef unsigned char BOOL; - typedef unsigned char BYTE; - typedef unsigned int WORD; - typedef unsigned long DWORD; - - typedef unsigned char UCHAR; - typedef unsigned int UINT; - typedef unsigned short USHORT; - typedef unsigned long ULONG; - - typedef char CHAR; - typedef int INT; - typedef long LONG; -#endif - -#endif diff --git a/targets/arduino/buffer.c b/targets/arduino/buffer.c deleted file mode 100755 index 67c05f922..000000000 --- a/targets/arduino/buffer.c +++ /dev/null @@ -1,110 +0,0 @@ -/*! \file buffer.c \brief Multipurpose byte buffer structure and methods. */ -//***************************************************************************** -// -// File Name : 'buffer.c' -// Title : Multipurpose byte buffer structure and methods -// Author : Pascal Stang - Copyright (C) 2001-2002 -// Created : 9/23/2001 -// Revised : 9/23/2001 -// Version : 1.0 -// Target MCU : any -// Editor Tabs : 4 -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - -#include "buffer.h" - -// global variables - -// initialization - -void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size) -{ - // set start pointer of the buffer - buffer->dataptr = start; - buffer->size = size; - // initialize index and length - buffer->dataindex = 0; - buffer->datalength = 0; -} - -// access routines -unsigned char bufferGetFromFront(cBuffer* buffer) -{ - unsigned char data = 0; - - // check to see if there's data in the buffer - if(buffer->datalength) - { - // get the first character from buffer - data = buffer->dataptr[buffer->dataindex]; - // move index down and decrement length - buffer->dataindex++; - if(buffer->dataindex >= buffer->size) - { - buffer->dataindex %= buffer->size; - } - buffer->datalength--; - } - // return - return data; -} - -void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes) -{ - // dump numbytes from the front of the buffer - // are we dumping less than the entire buffer? - if(numbytes < buffer->datalength) - { - // move index down by numbytes and decrement length by numbytes - buffer->dataindex += numbytes; - if(buffer->dataindex >= buffer->size) - { - buffer->dataindex %= buffer->size; - } - buffer->datalength -= numbytes; - } - else - { - // flush the whole buffer - buffer->datalength = 0; - } -} - -unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index) -{ - // return character at index in buffer - return buffer->dataptr[(buffer->dataindex+index)%(buffer->size)]; -} - -unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data) -{ - // make sure the buffer has room - if(buffer->datalength < buffer->size) - { - // save data byte at end of buffer - buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data; - // increment the length - buffer->datalength++; - // return success - return -1; - } - else return 0; -} - -unsigned char bufferIsNotFull(cBuffer* buffer) -{ - // check to see if the buffer has room - // return true if there is room - return (buffer->datalength < buffer->size); -} - -void bufferFlush(cBuffer* buffer) -{ - // flush contents of the buffer - buffer->datalength = 0; -} - diff --git a/targets/arduino/buffer.h b/targets/arduino/buffer.h deleted file mode 100755 index 727cd7881..000000000 --- a/targets/arduino/buffer.h +++ /dev/null @@ -1,56 +0,0 @@ -/*! \file buffer.h \brief Multipurpose byte buffer structure and methods. */ -//***************************************************************************** -// -// File Name : 'buffer.h' -// Title : Multipurpose byte buffer structure and methods -// Author : Pascal Stang - Copyright (C) 2001-2002 -// Created : 9/23/2001 -// Revised : 11/16/2002 -// Version : 1.1 -// Target MCU : any -// Editor Tabs : 4 -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - -#ifndef BUFFER_H -#define BUFFER_H - -// structure/typdefs - -// the cBuffer structure -typedef struct struct_cBuffer -{ - unsigned char *dataptr; // the physical memory address where the buffer is stored - unsigned short size; // the allocated size of the buffer - unsigned short datalength; // the length of the data currently in the buffer - unsigned short dataindex; // the index into the buffer where the data starts -} cBuffer; - -// function prototypes - -//! initialize a buffer to start at a given address and have given size -void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size); - -//! get the first byte from the front of the buffer -unsigned char bufferGetFromFront(cBuffer* buffer); - -//! dump (discard) the first numbytes from the front of the buffer -void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes); - -//! get a byte at the specified index in the buffer (kind of like array access) -// ** note: this does not remove the byte that was read from the buffer -unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index); - -//! add a byte to the end of the buffer -unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data); - -//! check if the buffer is full/not full (returns non-zero value if not full) -unsigned char bufferIsNotFull(cBuffer* buffer); - -//! flush (clear) the contents of the buffer -void bufferFlush(cBuffer* buffer); - -#endif diff --git a/targets/arduino/global.h b/targets/arduino/global.h deleted file mode 100755 index e2893c8d0..000000000 --- a/targets/arduino/global.h +++ /dev/null @@ -1,40 +0,0 @@ -/*! \file global.h \brief AVRlib project global include. */ -//***************************************************************************** -// -// File Name : 'global.h' -// Title : AVRlib project global include -// Author : Pascal Stang - Copyright (C) 2001-2002 -// Created : 7/12/2001 -// Revised : 9/30/2002 -// Version : 1.1 -// Target MCU : Atmel AVR series -// Editor Tabs : 4 -// -// Description : This include file is designed to contain items useful to all -// code files and projects. -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - -#ifndef GLOBAL_H -#define GLOBAL_H - -// global AVRLIB defines -#include "avrlibdefs.h" -// global AVRLIB types definitions -#include "avrlibtypes.h" - -// project/system dependent defines - -// CPU clock speed -//#define F_CPU 16000000 // 16MHz processor -//#define F_CPU 14745000 // 14.745MHz processor -//#define F_CPU 8000000 // 8MHz processor -//#define F_CPU 7372800 // 7.37MHz processor -//#define F_CPU 4000000 // 4MHz processor -//#define F_CPU 3686400 // 3.69MHz processor -#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond - -#endif diff --git a/targets/arduino/rprintf.h b/targets/arduino/rprintf.h deleted file mode 100755 index 63af4ea6b..000000000 --- a/targets/arduino/rprintf.h +++ /dev/null @@ -1,135 +0,0 @@ -/*! \file rprintf.h \brief printf routine and associated routines. */ -//**************************************************************************** -// -// File Name : 'rprintf.h' -// Title : printf routine and associated routines -// Author : Pascal Stang - Copyright (C) 2000-2002 -// Created : 2000.12.26 -// Revised : 2003.5.1 -// Version : 1.0 -// Target MCU : Atmel AVR series and other targets -// Editor Tabs : 4 -// -// NOTE: This code is currently below version 1.0, and therefore is considered -// to be lacking in some functionality or documentation, or may not be fully -// tested. Nonetheless, you can expect most functions to work. -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//**************************************************************************** - -#ifndef RPRINTF_H -#define RPRINTF_H - -// needed for use of PSTR below -#include - -// configuration -// defining RPRINTF_SIMPLE will compile a smaller, simpler, and faster printf() function -// defining RPRINTF_COMPLEX will compile a larger, more capable, and slower printf() function -#ifndef RPRINTF_COMPLEX - #define RPRINTF_SIMPLE -#endif - -// Define RPRINTF_FLOAT to enable the floating-point printf function: rprintfFloat() -// (adds +4600bytes or 2.2Kwords of code) - -// defines/constants -#define STRING_IN_RAM 0 -#define STRING_IN_ROM 1 - -// make a putchar for those that are used to using it -//#define putchar(c) rprintfChar(c); - -// functions - -//! initializes the rprintf library for an output stream -// you must call this initializer once before using any other rprintf function -// the argument must be a single-character stream output function -void rprintfInit(void (*putchar_func)(unsigned char c)); - -//! prints a single character to the current output device -void rprintfChar(unsigned char c); - -//! prints a null-terminated string stored in RAM -void rprintfStr(char str[]); - -//! prints a section of a string stored in RAM -// begins printing at position indicated by -// prints number of characters indicated by -void rprintfStrLen(char str[], unsigned int start, unsigned int len); - -//! prints a string stored in program rom -// NOTE: this function does not actually store your string in -// program rom, but merely reads it assuming you stored it properly. -void rprintfProgStr(const prog_char str[]); -// Using the function rprintfProgStrM(...) automatically causes -// your string to be stored in ROM, thereby not wasting precious RAM -// Example usage: -// rprintfProgStrM("Hello, this string is stored in program rom"); -#define rprintfProgStrM(string) (rprintfProgStr(PSTR(string))) - -//! prints a carriage return and line feed -// useful when printing to serial ports/terminals -void rprintfCRLF(void); - -// prints the number contained in "data" in hex format -// u04,u08,u16,and u32 functions handle 4,8,16,or 32 bits respectively -void rprintfu04(unsigned char data); ///< print 4-bit hex number -void rprintfu08(unsigned char data); ///< print 8-bit hex number -void rprintfu16(unsigned short data); ///< print 16-bit hex number -void rprintfu32(unsigned long data); ///< print 32-bit hex number - -//! a flexible integer number printing routine -void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n); - -#ifdef RPRINTF_FLOAT - //! floating-point print routine - void rprintfFloat(char numDigits, double x); -#endif - -// NOTE: Below you'll see the function prototypes of rprintf1RamRom and -// rprintf2RamRom. rprintf1RamRom and rprintf2RamRom are both reduced versions -// of the regular C printf() command. However, they are modified to be able -// to read their text/format strings from RAM or ROM in the Atmel microprocessors. -// Unless you really intend to, do not use the "RamRom" versions of the functions -// directly. Instead use the #defined function versions: -// -// printfx("text/format",args) ...to keep your text/format string stored in RAM -// - or - -// printfxROM("text/format",args) ...to keep your text/format string stored in ROM -// -// where x is either 1 or 2 for the simple or more powerful version of printf() -// -// Since there is much more ROM than RAM available in the Atmel microprocessors, -// and nearly all text/format strings are constant (never change in the course -// of the program), you should try to use the ROM printf version exclusively. -// This will ensure you leave as much RAM as possible for program variables and -// data. - -#ifdef RPRINTF_SIMPLE - // a simple printf routine - int rprintf1RamRom(unsigned char stringInRom, const char *format, ...); - // #defines for RAM or ROM operation - #define rprintf1(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) - #define rprintf1RAM(format, args...) rprintf1RamRom(STRING_IN_RAM, format, ## args) - - // *** Default rprintf(...) *** - // this next line determines what the the basic rprintf() defaults to: - #define rprintf(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) -#endif - -#ifdef RPRINTF_COMPLEX - // a more powerful printf routine - int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...); - // #defines for RAM or ROM operation - #define rprintf2(format, args...) rprintf2RamRom(STRING_IN_ROM, format, ## args) - #define rprintf2RAM(format, args...) rprintf2RamRom(STRING_IN_RAM, format, ## args) - - // *** Default rprintf(...) *** - // this next line determines what the the basic rprintf() defaults to: - #define rprintf(format, args...) rprintf2RamRom(STRING_IN_ROM, PSTR(format), ## args) -#endif - -#endif diff --git a/targets/arduino/uart.c b/targets/arduino/uart.c deleted file mode 100755 index 727a6374b..000000000 --- a/targets/arduino/uart.c +++ /dev/null @@ -1,284 +0,0 @@ -/*! \file uart.c \brief UART driver with buffer support. */ -// ***************************************************************************** -// -// File Name : 'uart.c' -// Title : UART driver with buffer support -// Author : Pascal Stang - Copyright (C) 2000-2002 -// Created : 11/22/2000 -// Revised : 06/09/2003 -// Version : 1.3 -// Target MCU : ATMEL AVR Series -// Editor Tabs : 4 -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -// ***************************************************************************** - -#include -#include -#include - -#include "buffer.h" -#include "uart.h" - -// UART global variables -// flag variables -volatile u08 uartReadyTx; ///< uartReadyTx flag -volatile u08 uartBufferedTx; ///< uartBufferedTx flag -// receive and transmit buffers -cBuffer uartRxBuffer; ///< uart receive buffer -cBuffer uartTxBuffer; ///< uart transmit buffer -unsigned short uartRxOverflow; ///< receive overflow counter - -#ifndef UART_BUFFERS_EXTERNAL_RAM - // using internal ram, - // automatically allocate space in ram for each buffer - static char uartRxData[UART_RX_BUFFER_SIZE]; - static char uartTxData[UART_TX_BUFFER_SIZE]; -#endif - -typedef void (*voidFuncPtru08)(unsigned char); -volatile static voidFuncPtru08 UartRxFunc; - -//! enable and initialize the uart -void uartInit(void) -{ - // initialize the buffers - uartInitBuffers(); - // initialize user receive handler - UartRxFunc = 0; - - // enable RxD/TxD and interrupts - outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); - - // set default baud rate - uartSetBaudRate(UART_DEFAULT_BAUD_RATE); - // initialize states - uartReadyTx = TRUE; - uartBufferedTx = FALSE; - // clear overflow count - uartRxOverflow = 0; - // enable interrupts - sei(); -} - -//! create and initialize the uart transmit and receive buffers -void uartInitBuffers(void) -{ - #ifndef UART_BUFFERS_EXTERNAL_RAM - // initialize the UART receive buffer - bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE); - // initialize the UART transmit buffer - bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE); - #else - // initialize the UART receive buffer - bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE); - // initialize the UART transmit buffer - bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE); - #endif -} - -//! redirects received data to a user function -void uartSetRxHandler(void (*rx_func)(unsigned char c)) -{ - // set the receive interrupt to run the supplied user function - UartRxFunc = rx_func; -} - -//! set the uart baud rate -void uartSetBaudRate(u32 baudrate) -{ - // calculate division factor for requested baud rate, and set it - u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1); - outb(UBRRL, bauddiv); - #ifdef UBRRH - outb(UBRRH, bauddiv>>8); - #endif -} - -//! returns the receive buffer structure -cBuffer* uartGetRxBuffer(void) -{ - // return rx buffer pointer - return &uartRxBuffer; -} - -//! returns the transmit buffer structure -cBuffer* uartGetTxBuffer(void) -{ - // return tx buffer pointer - return &uartTxBuffer; -} - -//! transmits a byte over the uart -void uartSendByte(u08 txData) -{ - // wait for the transmitter to be ready - while(!uartReadyTx); - // send byte - outb(UDR, txData); - // set ready state to FALSE - uartReadyTx = FALSE; -} - -//! gets a single byte from the uart receive buffer (getchar-style) -int uartGetByte(void) -{ - u08 c; - if(uartReceiveByte(&c)) - return c; - else - return -1; -} - -//! gets a byte (if available) from the uart receive buffer -u08 uartReceiveByte(u08* rxData) -{ - // make sure we have a receive buffer - if(uartRxBuffer.size) - { - // make sure we have data - if(uartRxBuffer.datalength) - { - // get byte from beginning of buffer - *rxData = bufferGetFromFront(&uartRxBuffer); - return TRUE; - } - else - { - // no data - return FALSE; - } - } - else - { - // no buffer - return FALSE; - } -} - -//! flush all data out of the receive buffer -void uartFlushReceiveBuffer(void) -{ - // flush all data from receive buffer - //bufferFlush(&uartRxBuffer); - // same effect as above - uartRxBuffer.datalength = 0; -} - -//! return true if uart receive buffer is empty -u08 uartReceiveBufferIsEmpty(void) -{ - if(uartRxBuffer.datalength == 0) - { - return TRUE; - } - else - { - return FALSE; - } -} - -//! add byte to end of uart Tx buffer -void uartAddToTxBuffer(u08 data) -{ - // add data byte to the end of the tx buffer - bufferAddToEnd(&uartTxBuffer, data); -} - -//! start transmission of the current uart Tx buffer contents -void uartSendTxBuffer(void) -{ - // turn on buffered transmit - uartBufferedTx = TRUE; - // send the first byte to get things going by interrupts - uartSendByte(bufferGetFromFront(&uartTxBuffer)); -} -/* -//! transmit nBytes from buffer out the uart -u08 uartSendBuffer(char *buffer, u16 nBytes) -{ - register u08 first; - register u16 i; - - // check if there's space (and that we have any bytes to send at all) - if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes) - { - // grab first character - first = *buffer++; - // copy user buffer to uart transmit buffer - for(i = 0; i < nBytes-1; i++) - { - // put data bytes at end of buffer - bufferAddToEnd(&uartTxBuffer, *buffer++); - } - - // send the first byte to get things going by interrupts - uartBufferedTx = TRUE; - uartSendByte(first); - // return success - return TRUE; - } - else - { - // return failure - return FALSE; - } -} -*/ -//! UART Transmit Complete Interrupt Handler -UART_INTERRUPT_HANDLER(SIG_UART_TRANS) -{ - // check if buffered tx is enabled - if(uartBufferedTx) - { - // check if there's data left in the buffer - if(uartTxBuffer.datalength) - { - // send byte from top of buffer - outb(UDR, bufferGetFromFront(&uartTxBuffer)); - } - else - { - // no data left - uartBufferedTx = FALSE; - // return to ready state - uartReadyTx = TRUE; - } - } - else - { - // we're using single-byte tx mode - // indicate transmit complete, back to ready - uartReadyTx = TRUE; - } -} - -//! UART Receive Complete Interrupt Handler -UART_INTERRUPT_HANDLER(SIG_UART_RECV) -{ - u08 c; - - // get received char - c = inb(UDR); - - // if there's a user function to handle this receive event - if(UartRxFunc) - { - // call it and pass the received data - UartRxFunc(c); - } - else - { - // otherwise do default processing - // put received char in buffer - // check if there's space - if( !bufferAddToEnd(&uartRxBuffer, c) ) - { - // no space in buffer - // count overflow - uartRxOverflow++; - } - } -} diff --git a/targets/arduino/uart.h b/targets/arduino/uart.h deleted file mode 100755 index 16a14ba5d..000000000 --- a/targets/arduino/uart.h +++ /dev/null @@ -1,148 +0,0 @@ -/*! \file uart.h \brief UART driver with buffer support. */ -//***************************************************************************** -// -// File Name : 'uart.h' -// Title : UART driver with buffer support -// Author : Pascal Stang - Copyright (C) 2000-2002 -// Created : 11/22/2000 -// Revised : 02/01/2004 -// Version : 1.3 -// Target MCU : ATMEL AVR Series -// Editor Tabs : 4 -// -// This code is distributed under the GNU Public License -// which can be found at http://www.gnu.org/licenses/gpl.txt -// -//***************************************************************************** - -#ifndef UART_H -#define UART_H - -#include "global.h" -#include "buffer.h" - -//! default baud rate -//! can be changed by using uartSetBaudRate() -#define UART_DEFAULT_BAUD_RATE 9600 - -// buffer memory allocation defines -// buffer sizes -#ifndef UART_TX_BUFFER_SIZE -#define UART_TX_BUFFER_SIZE 0x0040 ///< number of bytes for uart transmit buffer -#endif -#ifndef UART_RX_BUFFER_SIZE -#define UART_RX_BUFFER_SIZE 0x0040 ///< number of bytes for uart receive buffer -#endif - -// define this key if you wish to use -// external RAM for the UART buffers -//#define UART_BUFFER_EXTERNAL_RAM -#ifdef UART_BUFFER_EXTERNAL_RAM - // absolute address of uart buffers - #define UART_TX_BUFFER_ADDR 0x1000 - #define UART_RX_BUFFER_ADDR 0x1100 -#endif - -// type of interrupt handler to use -// *do not change unless you know what you're doing -// Value may be SIGNAL or INTERRUPT -#ifndef UART_INTERRUPT_HANDLER -#define UART_INTERRUPT_HANDLER SIGNAL -#endif - -// compatibility with most newer processors -#ifdef UCSRB - #define UCR UCSRB -#endif -// compatibility with old Mega processors -#if defined(UBRR) && !defined(UBRRL) - #define UBRRL UBRR -#endif -// DAM: it seems the ATmega168 includes a '0' in its register names, despite -// having only one uart -#if defined(__AVR_ATmega168__) - #define RXCIE RXCIE0 - #define TXCIE TXCIE0 - #define RXEN RXEN0 - #define TXEN TXEN0 - #define UDR UDR0 - #define UCR UCSR0B - #define UBRRL UBRR0L - #define UBRRH UBRR0H - #define SIG_UART_TRANS USART_TX_vect - #define SIG_UART_RECV USART_RX_vect -#endif -// compatibility with dual-uart processors -// (if you need to use both uarts, please use the uart2 library) -#if defined(__AVR_ATmega128__) - #define UDR UDR0 - #define UCR UCSR0B - #define UBRRL UBRR0L - #define UBRRH UBRR0H - #define SIG_UART_TRANS SIG_UART0_TRANS - #define SIG_UART_RECV SIG_UART0_RECV - #define SIG_UART_DATA SIG_UART0_DATA -#endif -#if defined(__AVR_ATmega161__) - #define UDR UDR0 - #define UCR UCSR0B - #define UBRRL UBRR0 - #define SIG_UART_TRANS SIG_UART0_TRANS - #define SIG_UART_RECV SIG_UART0_RECV - #define SIG_UART_DATA SIG_UART0_DATA -#endif - -// functions - -//! initializes transmit and receive buffers -// called from uartInit() -void uartInitBuffers(void); - -//! initializes uart -void uartInit(void); - -//! redirects received data to a user function -void uartSetRxHandler(void (*rx_func)(unsigned char c)); - -//! sets the uart baud rate -void uartSetBaudRate(u32 baudrate); - -//! returns pointer to the receive buffer structure -cBuffer* uartGetRxBuffer(void); - -//! returns pointer to the transmit buffer structure -cBuffer* uartGetTxBuffer(void); - -//! sends a single byte over the uart -void uartSendByte(u08 data); - -//! gets a single byte from the uart receive buffer (getchar-style) -// returns the byte, or -1 if no byte is available -int uartGetByte(void); - -//! gets a single byte from the uart receive buffer -// Function returns TRUE if data was available, FALSE if not. -// Actual data is returned in variable pointed to by "data". -// example usage: -// char myReceivedByte; -// uartReceiveByte( &myReceivedByte ); -u08 uartReceiveByte(u08* data); - -//! returns TRUE/FALSE if receive buffer is empty/not-empty -u08 uartReceiveBufferIsEmpty(void); - -//! flushes (deletes) all data from receive buffer -void uartFlushReceiveBuffer(void); - -//! add byte to end of uart Tx buffer -void uartAddToTxBuffer(u08 data); - -//! begins transmission of the transmit buffer under interrupt control -void uartSendTxBuffer(void); - -//! sends a buffer of length nBytes via the uart using interrupt control -u08 uartSendBuffer(char *buffer, u16 nBytes); - -#endif - - diff --git a/targets/arduino/wiring.c b/targets/arduino/wiring.c index 03a7f8619..55b5f62d7 100755 --- a/targets/arduino/wiring.c +++ b/targets/arduino/wiring.c @@ -36,11 +36,19 @@ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif -// from Pascal's avrlib -#include "uart.h" - #include "wiring.h" +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which rx_buffer_head is the index of the +// location to which to write the next incoming character and rx_buffer_tail +// is the index of the location from which to read +#define RX_BUFFER_SIZE 128 + +unsigned char rx_buffer[RX_BUFFER_SIZE]; + +int rx_buffer_head = 0; +int rx_buffer_tail = 0; + // The number of times timer 0 has overflowed since the program started. // Must be volatile or gcc will optimize away some uses of it. volatile unsigned long timer0_overflow_count; @@ -241,23 +249,64 @@ void analogWrite(int pin, int val) void beginSerial(long baud) { - uartInit(); - uartSetBaudRate(baud); + UBRRH = ((F_CPU / 16 + baud / 2) / baud - 1) >> 8; + UBRRL = ((F_CPU / 16 + baud / 2) / baud - 1); + + // enable rx and tx + sbi(UCSRB, RXEN); + sbi(UCSRB, TXEN); + + // enable interrupt on complete reception of a byte + sbi(UCSRB, RXCIE); + + // defaults to 8-bit, no parity, 1 stop bit } void serialWrite(unsigned char c) { - uartSendByte(c); +#if defined(__AVR_ATmega168__) + while (!(UCSR0A & (1 << UDRE0))) + ; + + UDR0 = c; +#else + while (!(UCSRA & (1 << UDRE))) + ; + + UDR = c; +#endif } int serialAvailable() { - return uartGetRxBuffer()->datalength; + return (rx_buffer_head - rx_buffer_tail) % RX_BUFFER_SIZE; } int serialRead() { - return uartGetByte(); + // if the head isn't ahead of the tail, we don't have any characters + if (rx_buffer_head == rx_buffer_tail) { + return -1; + } else { + unsigned char c = rx_buffer[rx_buffer_tail]; + rx_buffer_tail = (rx_buffer_tail + 1) % RX_BUFFER_SIZE; + return c; + } +} + +SIGNAL(SIG_UART_RECV) +{ + unsigned char c = UDR; + int i = (rx_buffer_head + 1) % RX_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if (i != rx_buffer_tail) { + rx_buffer[rx_buffer_head] = c; + rx_buffer_head = i; + } } void printMode(int mode) @@ -522,9 +571,10 @@ int main(void) // enable a2d conversions sbi(ADCSRA, ADEN); - - // disconnect USART from pins 0 and 1 so they can be used as normal - // digital i/o; they will be reconnected in any call to Serial.begin() + + // the bootloader connects pins 0 and 1 to the USART; disconnect them here + // so they can be used as normal digital i/o; they will be reconnected in + // Serial.begin() #if defined(__AVR_ATmega168__) UCSR0B = 0; #else