mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-30 19:52:13 +01:00
Replaced avr-lib serial with custom code in wiring.c.
This commit is contained in:
parent
e3a0eeb6df
commit
a740bf0588
@ -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().
|
||||
|
@ -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]);
|
||||
}
|
@ -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 <inttypes.h>
|
||||
|
||||
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
|
||||
|
@ -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) ((a<b)?(a):(b))
|
||||
#define MAX(a,b) ((a>b)?(a):(b))
|
||||
#define ABS(x) ((x>0)?(x):(-x))
|
||||
|
||||
// constants
|
||||
#define PI 3.14159265359
|
||||
|
||||
#endif
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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
|
@ -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 <avr/pgmspace.h>
|
||||
|
||||
// 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 <start>
|
||||
// prints number of characters indicated by <len>
|
||||
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
|
@ -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 <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/signal.h>
|
||||
|
||||
#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++;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
@ -523,8 +572,9 @@ 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user