From ca1f64682a51c9097ab699694f85aa0a47bee1d0 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Fri, 12 Aug 2011 16:59:24 -0400 Subject: [PATCH 01/11] Adding SCL, SDA, and LED #defines. --- pins/mega/pins_arduino.h | 4 ++++ pins/standard/pins_arduino.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/pins/mega/pins_arduino.h b/pins/mega/pins_arduino.h index e3785e4..acbd28f 100644 --- a/pins/mega/pins_arduino.h +++ b/pins/mega/pins_arduino.h @@ -32,6 +32,10 @@ const static uint8_t MOSI = 51; const static uint8_t MISO = 50; const static uint8_t SCK = 52; +const static uint8_t SDA = 20; +const static uint8_t SCL = 21; +const static uint8_t LED = 13; + const static uint8_t A0 = 54; const static uint8_t A1 = 55; const static uint8_t A2 = 56; diff --git a/pins/standard/pins_arduino.h b/pins/standard/pins_arduino.h index 8fabb17..b42755d 100644 --- a/pins/standard/pins_arduino.h +++ b/pins/standard/pins_arduino.h @@ -32,6 +32,10 @@ const static uint8_t MOSI = 11; const static uint8_t MISO = 12; const static uint8_t SCK = 13; +const static uint8_t SDA = 18; +const static uint8_t SCL = 19; +const static uint8_t LED = 13; + const static uint8_t A0 = 14; const static uint8_t A1 = 15; const static uint8_t A2 = 16; From cafbc48008ec9cb5cd68b29a93f59b81423322f7 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Fri, 12 Aug 2011 17:31:22 -0400 Subject: [PATCH 02/11] Adding pin-change interrupt pin mapping macros to pins_arduino.h. http://code.google.com/p/arduino/issues/detail?id=490 --- pins/mega/pins_arduino.h | 25 +++++++++++++++++++++++++ pins/standard/pins_arduino.h | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/pins/mega/pins_arduino.h b/pins/mega/pins_arduino.h index acbd28f..b25f858 100644 --- a/pins/mega/pins_arduino.h +++ b/pins/mega/pins_arduino.h @@ -53,6 +53,31 @@ const static uint8_t A13 = 67; const static uint8_t A14 = 68; const static uint8_t A15 = 69; +// A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) +// Only pins available for RECEIVE (TRANSMIT can be on any pin): +// (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me) +// Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 + +#define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \ + (((p) >= 50) && ((p) <= 53)) || \ + (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) + +#define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ + 0 ) ) + +#define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \ + ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ + ((uint8_t *)0) ) ) + +#define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ + ( ((p) == 50) ? 3 : \ + ( ((p) == 51) ? 2 : \ + ( ((p) == 52) ? 1 : \ + ( ((p) == 53) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ + 0 ) ) ) ) ) ) + #ifdef ARDUINO_MAIN const uint16_t PROGMEM port_to_mode_PGM[] = { diff --git a/pins/standard/pins_arduino.h b/pins/standard/pins_arduino.h index b42755d..8e25435 100644 --- a/pins/standard/pins_arduino.h +++ b/pins/standard/pins_arduino.h @@ -45,6 +45,11 @@ const static uint8_t A5 = 19; const static uint8_t A6 = 20; const static uint8_t A7 = 21; +#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0)) +#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1)) +#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0)))) +#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14))) + #ifdef ARDUINO_MAIN // On the Arduino board, digital pins are also used From 39573e5cf7e5db5f0892fc6d33e0d53ede5e0d17 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Fri, 12 Aug 2011 18:27:00 -0400 Subject: [PATCH 03/11] Adding basic macros for analog + digital pin information. http://code.google.com/p/arduino/issues/detail?id=495 --- pins/mega/pins_arduino.h | 5 +++++ pins/standard/pins_arduino.h | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/pins/mega/pins_arduino.h b/pins/mega/pins_arduino.h index b25f858..237173a 100644 --- a/pins/mega/pins_arduino.h +++ b/pins/mega/pins_arduino.h @@ -27,6 +27,11 @@ #include +#define NUM_DIGITAL_PINS 70 +#define NUM_ANALOG_INPUTS 16 +#define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1) +#define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46)) + const static uint8_t SS = 53; const static uint8_t MOSI = 51; const static uint8_t MISO = 50; diff --git a/pins/standard/pins_arduino.h b/pins/standard/pins_arduino.h index 8e25435..3999d1f 100644 --- a/pins/standard/pins_arduino.h +++ b/pins/standard/pins_arduino.h @@ -27,6 +27,16 @@ #include +#define NUM_DIGITAL_PINS 20 +#define NUM_ANALOG_INPUTS 6 +#define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1) + +#if defined(__AVR_ATmega8__) +#define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11) +#else +#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) +#endif + const static uint8_t SS = 10; const static uint8_t MOSI = 11; const static uint8_t MISO = 12; From 31ff05504fd862a3dfeace691027cc69af213c1d Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Wed, 17 Aug 2011 13:53:49 -0400 Subject: [PATCH 04/11] Integrating Stream searching & parsing (Michael Margolis) This from Michael's TextFinder library, incorporated into the Stream class: find(), findUntil(), parseInt(), parseFloat(), readChars(), readCharsUntil(), readCharsBetween(), setTimeout(). --- cores/arduino/Stream.cpp | 244 +++++++++++++++++++++++++++++++++++++++ cores/arduino/Stream.h | 64 ++++++++++ 2 files changed, 308 insertions(+) create mode 100644 cores/arduino/Stream.cpp diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp new file mode 100644 index 0000000..dea0aff --- /dev/null +++ b/cores/arduino/Stream.cpp @@ -0,0 +1,244 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. 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 + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 5 // default number of seconds to wait +#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field + +// private method to read stream with timeout +int Stream::timedRead() +{ + //Serial.println(_timeout); + this->_startMillis = millis(); + while(millis() - this->_startMillis < (this->_timeout * 1000L)) + { + if (this->available() > 0) { + return this->read(); + } + } + return -1; // -1 indicates timeout +} + +// returns the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::getNextDigit() +{ + int c; + do{ + c = timedRead(); + if( c < 0) + return c; // timeout + } + while( c != '-' && (c < '0' || c > '9') ) ; + +return c; +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout( long timeout) // sets the maximum number of seconds to wait +{ + this->_timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, NULL); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + size_t index = 0; // maximum target string length is 64k bytes! + size_t termIndex = 0; + int c; + + if( *target == 0) + return true; // return true if target is a null string + while( (c = timedRead()) > 0){ + if( c == target[index]){ + //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); + if(++index >= targetLen){ // return true if all chars in the target match + return true; + } + } + else{ + index = 0; // reset index if any char does not match + } + if(termLen > 0 && c == terminator[termIndex]){ + if(++termIndex >= termLen) + return false; // return false if terminate string found before target string + } + else + termIndex = 0; + } + return false; +} + + +// returns the first valid (long) integer value from the current position. +// initial characters that are not digits (or the minus sign) are skipped +// function is terminated by the first character that is not a digit. +long Stream::parseInt() +{ + return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) +} + +// as above but a given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +long Stream::parseInt(char skipChar) +{ + boolean isNegative = false; + long value = 0; + int c; + + c = getNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore this charactor + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + c = timedRead(); + } + while( (c >= '0' && c <= '9') || c == skipChar ); + + if(isNegative) + value = -value; + return value; +} + + +// as parseInt but returns a floating point value +float Stream::parseFloat() +{ + parseFloat(NO_SKIP_CHAR); +} + +// as above but the given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +float Stream::parseFloat(char skipChar){ + boolean isNegative = false; + boolean isFraction = false; + long value = 0; + float fValue; + char c; + float fraction = 1.0; + + c = getNextDigit(); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == skipChar) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + c = timedRead(); + } + while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, null is detected or timeout (see setTimeout) +// returns the number of characters placed in the buffer (0 means no valid data found) +int Stream::readChars( char *buffer, size_t length) +{ + return readCharsUntil( 0, buffer, length); +} + + +// as readChars with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +int Stream::readCharsUntil( char terminator, char *buffer, size_t length) +{ + int index = 0; + *buffer = 0; + while(index < length ){ + int c = timedRead(); + if( c <= 0 ){ + return 0; // timeout returns 0 ! + } + else if( c == terminator){ + buffer[index] = 0; // terminate the string + return index; // data got successfully + } + else{ + buffer[index++] = (char)c; + } + } + buffer[index] = 0; + return index; // here if buffer is full before detecting the terminator +} + + +// read characters found between pre_string and terminator into a buffer +// terminated when the terminator character is matched or the buffer is full +// returns the number of bytes placed in the buffer (0 means no valid data found) +int Stream::readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length) +{ + if( find( pre_string) ){ + return readCharsUntil(terminator, buffer, length); + } + return 0; //failed to find the prestring +} diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h index 93d8275..3f76392 100644 --- a/cores/arduino/Stream.h +++ b/cores/arduino/Stream.h @@ -15,6 +15,8 @@ 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 + + parsing functions based on TextFinder library by Michael Margolis */ #ifndef Stream_h @@ -23,13 +25,75 @@ #include #include "Print.h" +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(skipChar) parseInt(skipchar) +#define getFloat() parseFloat() +#define getFloat(skipChar) parseFloat(skipChar) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + class Stream : public Print { + private: + long _timeout; // number of seconds to wait for the next char before aborting timed read + long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int getNextDigit(); // returns the next numeric digit in the stream or -1 if timeout + public: virtual int available() = 0; virtual int read() = 0; virtual int peek() = 0; virtual void flush() = 0; + + Stream() {_timeout=5;} + +// parsing methods + + void setTimeout(long timeout); // sets maximum seconds to wait for stream data, default is 5 seconds + + bool find(char *target); // reads data from the stream until the target string is found + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + // returns true if target string is found, false if timed out + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + + + long parseInt(); // returns the first valid (long) integer value from the current position. + // initial characters that are not digits (or the minus sign) are skipped + // integer is terminated by the first character that is not a digit. + + long parseInt(char skipChar); // as above but the given skipChar is ignored + // as above but the given skipChar is ignored + // this allows format characters (typically commas) in values to be ignored + + float parseFloat(); // float version of parseInt + + float parseFloat(char skipChar); // as above but the given skipChar is ignored + + int readChars( char *buffer, size_t length); // read chars from stream into buffer + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + int readCharsUntil( char terminator, char *buffer, size_t length); // as readChars with terminator character + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + int readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length); + // read characters found between pre_string and terminator into a buffer + // terminated when the terminator character is matched or the buffer is full + // returns the number of bytes placed in the buffer (0 means no valid data found) + + + // Arduino String functions to be added here + }; #endif From 8dd6a40334613ce1c0c575a93bcd86ee1b109be6 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Wed, 17 Aug 2011 14:16:47 -0400 Subject: [PATCH 05/11] A few API changes to new Stream parsing functions. Renamed readChars() -> readBytes(), readCharsUntil() -> readBytesUntil(). Changed timeouts to milliseconds from seconds; default from 5 to 1 seconds. Removed readCharsBetween(). --- cores/arduino/Stream.cpp | 25 +++++++------------------ cores/arduino/Stream.h | 16 +++++----------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp index dea0aff..bf8304f 100644 --- a/cores/arduino/Stream.cpp +++ b/cores/arduino/Stream.cpp @@ -23,7 +23,7 @@ #include "Arduino.h" #include "Stream.h" -#define PARSE_TIMEOUT 5 // default number of seconds to wait +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait #define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field // private method to read stream with timeout @@ -31,7 +31,7 @@ int Stream::timedRead() { //Serial.println(_timeout); this->_startMillis = millis(); - while(millis() - this->_startMillis < (this->_timeout * 1000L)) + while(millis() - this->_startMillis < this->_timeout) { if (this->available() > 0) { return this->read(); @@ -58,7 +58,7 @@ return c; // Public Methods ////////////////////////////////////////////////////////////// -void Stream::setTimeout( long timeout) // sets the maximum number of seconds to wait +void Stream::setTimeout( long timeout) // sets the maximum number of milliseconds to wait { this->_timeout = timeout; } @@ -200,17 +200,17 @@ float Stream::parseFloat(char skipChar){ // read characters from stream into buffer // terminates if length characters have been read, null is detected or timeout (see setTimeout) // returns the number of characters placed in the buffer (0 means no valid data found) -int Stream::readChars( char *buffer, size_t length) +int Stream::readBytes( char *buffer, size_t length) { - return readCharsUntil( 0, buffer, length); + return readBytesUntil( 0, buffer, length); } -// as readChars with terminator character +// as readBytes with terminator character // terminates if length characters have been read, timeout, or if the terminator character detected // returns the number of characters placed in the buffer (0 means no valid data found) -int Stream::readCharsUntil( char terminator, char *buffer, size_t length) +int Stream::readBytesUntil( char terminator, char *buffer, size_t length) { int index = 0; *buffer = 0; @@ -231,14 +231,3 @@ int Stream::readCharsUntil( char terminator, char *buffer, size_t length) return index; // here if buffer is full before detecting the terminator } - -// read characters found between pre_string and terminator into a buffer -// terminated when the terminator character is matched or the buffer is full -// returns the number of bytes placed in the buffer (0 means no valid data found) -int Stream::readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length) -{ - if( find( pre_string) ){ - return readCharsUntil(terminator, buffer, length); - } - return 0; //failed to find the prestring -} diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h index 3f76392..1633f15 100644 --- a/cores/arduino/Stream.h +++ b/cores/arduino/Stream.h @@ -38,7 +38,7 @@ readBytesBetween( pre_string, terminator, buffer, length) class Stream : public Print { private: - long _timeout; // number of seconds to wait for the next char before aborting timed read + long _timeout; // number of milliseconds to wait for the next char before aborting timed read long _startMillis; // used for timeout measurement int timedRead(); // private method to read stream with timeout int getNextDigit(); // returns the next numeric digit in the stream or -1 if timeout @@ -49,11 +49,11 @@ class Stream : public Print virtual int peek() = 0; virtual void flush() = 0; - Stream() {_timeout=5;} + Stream() {_timeout=1000;} // parsing methods - void setTimeout(long timeout); // sets maximum seconds to wait for stream data, default is 5 seconds + void setTimeout(long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second bool find(char *target); // reads data from the stream until the target string is found // returns true if target string is found, false if timed out (see setTimeout) @@ -78,20 +78,14 @@ class Stream : public Print float parseFloat(char skipChar); // as above but the given skipChar is ignored - int readChars( char *buffer, size_t length); // read chars from stream into buffer + int readBytes( char *buffer, size_t length); // read chars from stream into buffer // terminates if length characters have been read or timeout (see setTimeout) // returns the number of characters placed in the buffer (0 means no valid data found) - int readCharsUntil( char terminator, char *buffer, size_t length); // as readChars with terminator character + int readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character // terminates if length characters have been read, timeout, or if the terminator character detected // returns the number of characters placed in the buffer (0 means no valid data found) - int readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length); - // read characters found between pre_string and terminator into a buffer - // terminated when the terminator character is matched or the buffer is full - // returns the number of bytes placed in the buffer (0 means no valid data found) - - // Arduino String functions to be added here }; From 9bc7be0d9a52edf77cf65554bce8a43123953107 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Thu, 18 Aug 2011 15:13:47 -0400 Subject: [PATCH 06/11] Stream.readBytesUntil() now writes null terminator within length. --- cores/arduino/Stream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp index bf8304f..d267bf0 100644 --- a/cores/arduino/Stream.cpp +++ b/cores/arduino/Stream.cpp @@ -214,7 +214,7 @@ int Stream::readBytesUntil( char terminator, char *buffer, size_t length) { int index = 0; *buffer = 0; - while(index < length ){ + while(index < length-1 ){ int c = timedRead(); if( c <= 0 ){ return 0; // timeout returns 0 ! From 69d1826e456781cfa33300e6fb4edc007dcc0fd3 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Tue, 23 Aug 2011 17:07:39 -0400 Subject: [PATCH 07/11] Renaming pins/ directory to the more generic variants/ http://code.google.com/p/arduino/issues/detail?id=588 --- boards.txt | 34 +++++++++++----------- {pins => variants}/mega/pins_arduino.h | 0 {pins => variants}/standard/pins_arduino.h | 0 3 files changed, 17 insertions(+), 17 deletions(-) rename {pins => variants}/mega/pins_arduino.h (100%) rename {pins => variants}/standard/pins_arduino.h (100%) diff --git a/boards.txt b/boards.txt index 88a7143..8a2af11 100644 --- a/boards.txt +++ b/boards.txt @@ -14,7 +14,7 @@ uno.bootloader.lock_bits=0x0F uno.build.mcu=atmega328p uno.build.f_cpu=16000000L uno.build.core=arduino -uno.build.pins=standard +uno.build.variant=standard ############################################################## @@ -35,7 +35,7 @@ atmega328.bootloader.lock_bits=0x0F atmega328.build.mcu=atmega328p atmega328.build.f_cpu=16000000L atmega328.build.core=arduino -atmega328.build.pins=standard +atmega328.build.variant=standard ############################################################## @@ -56,7 +56,7 @@ diecimila.bootloader.lock_bits=0x0F diecimila.build.mcu=atmega168 diecimila.build.f_cpu=16000000L diecimila.build.core=arduino -diecimila.build.pins=standard +diecimila.build.variant=standard ############################################################## @@ -77,7 +77,7 @@ mega2560.bootloader.lock_bits=0x0F mega2560.build.mcu=atmega2560 mega2560.build.f_cpu=16000000L mega2560.build.core=arduino -mega2560.build.pins=mega +mega2560.build.variant=mega ############################################################## @@ -98,7 +98,7 @@ mega.bootloader.lock_bits=0x0F mega.build.mcu=atmega1280 mega.build.f_cpu=16000000L mega.build.core=arduino -mega.build.pins=mega +mega.build.variant=mega ############################################################## @@ -119,7 +119,7 @@ mini.bootloader.lock_bits=0x0F mini.build.mcu=atmega168 mini.build.f_cpu=16000000L mini.build.core=arduino -mini.build.pins=standard +mini.build.variant=standard ############################################################## @@ -140,7 +140,7 @@ fio.bootloader.lock_bits=0x0F fio.build.mcu=atmega328p fio.build.f_cpu=8000000L fio.build.core=arduino -fio.build.pins=standard +fio.build.variant=standard ############################################################## @@ -162,7 +162,7 @@ bt328.bootloader.lock_bits=0x0F bt328.build.mcu=atmega328p bt328.build.f_cpu=16000000L bt328.build.core=arduino -bt328.build.pins=standard +bt328.build.variant=standard ############################################################## @@ -184,7 +184,7 @@ bt.bootloader.lock_bits=0x0F bt.build.mcu=atmega168 bt.build.f_cpu=16000000L bt.build.core=arduino -bt.build.pins=standard +bt.build.variant=standard ############################################################## @@ -205,7 +205,7 @@ lilypad328.bootloader.lock_bits=0x0F lilypad328.build.mcu=atmega328p lilypad328.build.f_cpu=8000000L lilypad328.build.core=arduino -lilypad328.build.pins=standard +lilypad328.build.variant=standard ############################################################## @@ -226,7 +226,7 @@ lilypad.bootloader.lock_bits=0x0F lilypad.build.mcu=atmega168 lilypad.build.f_cpu=8000000L lilypad.build.core=arduino -lilypad.build.pins=standard +lilypad.build.variant=standard ############################################################## @@ -247,7 +247,7 @@ pro5v328.bootloader.lock_bits=0x0F pro5v328.build.mcu=atmega328p pro5v328.build.f_cpu=16000000L pro5v328.build.core=arduino -pro5v328.build.pins=standard +pro5v328.build.variant=standard ############################################################## @@ -268,7 +268,7 @@ pro5v.bootloader.lock_bits=0x0F pro5v.build.mcu=atmega168 pro5v.build.f_cpu=16000000L pro5v.build.core=arduino -pro5v.build.pins=standard +pro5v.build.variant=standard ############################################################## @@ -289,7 +289,7 @@ pro328.bootloader.lock_bits=0x0F pro328.build.mcu=atmega328p pro328.build.f_cpu=8000000L pro328.build.core=arduino -pro328.build.pins=standard +pro328.build.variant=standard ############################################################## @@ -310,7 +310,7 @@ pro.bootloader.lock_bits=0x0F pro.build.mcu=atmega168 pro.build.f_cpu=8000000L pro.build.core=arduino -pro.build.pins=standard +pro.build.variant=standard ############################################################## @@ -331,7 +331,7 @@ atmega168.bootloader.lock_bits=0x0F atmega168.build.mcu=atmega168 atmega168.build.f_cpu=16000000L atmega168.build.core=arduino -atmega168.build.pins=standard +atmega168.build.variant=standard ############################################################## @@ -351,4 +351,4 @@ atmega8.bootloader.lock_bits=0x0F atmega8.build.mcu=atmega8 atmega8.build.f_cpu=16000000L atmega8.build.core=arduino -atmega8.build.pins=standard +atmega8.build.variant=standard diff --git a/pins/mega/pins_arduino.h b/variants/mega/pins_arduino.h similarity index 100% rename from pins/mega/pins_arduino.h rename to variants/mega/pins_arduino.h diff --git a/pins/standard/pins_arduino.h b/variants/standard/pins_arduino.h similarity index 100% rename from pins/standard/pins_arduino.h rename to variants/standard/pins_arduino.h From f5a15cb62f7257bf26cdedf30ce13f8cff802f79 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Tue, 23 Aug 2011 17:29:20 -0400 Subject: [PATCH 08/11] Distinguishing those boards with eight analog inputs (Fio, BT, Nano, Mini). http://code.google.com/p/arduino/issues/detail?id=499 --- boards.txt | 54 ++++++++++++++++++++--- variants/eightanaloginputs/pins_arduino.h | 27 ++++++++++++ 2 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 variants/eightanaloginputs/pins_arduino.h diff --git a/boards.txt b/boards.txt index 8a2af11..7adac62 100644 --- a/boards.txt +++ b/boards.txt @@ -18,7 +18,7 @@ uno.build.variant=standard ############################################################## -atmega328.name=Arduino Duemilanove or Nano w/ ATmega328 +atmega328.name=Arduino Duemilanove w/ ATmega328 atmega328.upload.protocol=stk500 atmega328.upload.maximum_size=30720 @@ -39,7 +39,7 @@ atmega328.build.variant=standard ############################################################## -diecimila.name=Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 +diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168 diecimila.upload.protocol=stk500 diecimila.upload.maximum_size=14336 @@ -60,6 +60,48 @@ diecimila.build.variant=standard ############################################################## +nano328.name=Arduino Nano w/ ATmega328 + +nano328.upload.protocol=stk500 +nano328.upload.maximum_size=30720 +nano328.upload.speed=57600 + +nano328.bootloader.low_fuses=0xFF +nano328.bootloader.high_fuses=0xDA +nano328.bootloader.extended_fuses=0x05 +nano328.bootloader.path=atmega +nano328.bootloader.file=ATmegaBOOT_168_atmega328.hex +nano328.bootloader.unlock_bits=0x3F +nano328.bootloader.lock_bits=0x0F + +nano328.build.mcu=atmega328p +nano328.build.f_cpu=16000000L +nano328.build.core=arduino +nano328.build.variant=eightanaloginputs + +############################################################## + +nano.name=Arduino Nano w/ ATmega168 + +nano.upload.protocol=stk500 +nano.upload.maximum_size=14336 +nano.upload.speed=19200 + +nano.bootloader.low_fuses=0xff +nano.bootloader.high_fuses=0xdd +nano.bootloader.extended_fuses=0x00 +nano.bootloader.path=atmega +nano.bootloader.file=ATmegaBOOT_168_diecimila.hex +nano.bootloader.unlock_bits=0x3F +nano.bootloader.lock_bits=0x0F + +nano.build.mcu=atmega168 +nano.build.f_cpu=16000000L +nano.build.core=arduino +nano.build.variant=eightanaloginputs + +############################################################## + mega2560.name=Arduino Mega 2560 mega2560.upload.protocol=stk500v2 @@ -119,7 +161,7 @@ mini.bootloader.lock_bits=0x0F mini.build.mcu=atmega168 mini.build.f_cpu=16000000L mini.build.core=arduino -mini.build.variant=standard +mini.build.variant=eightanaloginputs ############################################################## @@ -140,7 +182,7 @@ fio.bootloader.lock_bits=0x0F fio.build.mcu=atmega328p fio.build.f_cpu=8000000L fio.build.core=arduino -fio.build.variant=standard +fio.build.variant=eightanaloginputs ############################################################## @@ -162,7 +204,7 @@ bt328.bootloader.lock_bits=0x0F bt328.build.mcu=atmega328p bt328.build.f_cpu=16000000L bt328.build.core=arduino -bt328.build.variant=standard +bt328.build.variant=eightanaloginputs ############################################################## @@ -184,7 +226,7 @@ bt.bootloader.lock_bits=0x0F bt.build.mcu=atmega168 bt.build.f_cpu=16000000L bt.build.core=arduino -bt.build.variant=standard +bt.build.variant=eightanaloginputs ############################################################## diff --git a/variants/eightanaloginputs/pins_arduino.h b/variants/eightanaloginputs/pins_arduino.h new file mode 100644 index 0000000..52b37ef --- /dev/null +++ b/variants/eightanaloginputs/pins_arduino.h @@ -0,0 +1,27 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + 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., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#include "../standard/pins_arduino.h" +#undef NUM_ANALOG_INPUTS +#define NUM_ANALOG_INPUTS 8 From f282cbaf968f7142ef5abb68a92e970c3d5eea35 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Tue, 23 Aug 2011 19:12:03 -0400 Subject: [PATCH 09/11] write(), print(), and println() now return number of bytes written. The type is long, and negative values indicate errors. Needs more testing. http://code.google.com/p/arduino/issues/detail?id=551 --- cores/arduino/HardwareSerial.cpp | 5 +- cores/arduino/HardwareSerial.h | 2 +- cores/arduino/Print.cpp | 194 +++++++++++++++++++------------ cores/arduino/Print.h | 56 ++++----- cores/arduino/Printable.h | 2 +- 5 files changed, 151 insertions(+), 108 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index db6b149..a200da5 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -352,12 +352,13 @@ void HardwareSerial::flush() ; } -void HardwareSerial::write(uint8_t c) +long HardwareSerial::write(uint8_t c) { int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; // If the output buffer is full, there's nothing for it other than to // wait for the interrupt handler to empty it a bit + // ???: return 0 here instead? while (i == _tx_buffer->tail) ; @@ -365,6 +366,8 @@ void HardwareSerial::write(uint8_t c) _tx_buffer->head = i; sbi(*_ucsrb, _udrie); + + return 1; } // Preinstantiate Objects ////////////////////////////////////////////////////// diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index eefdcbe..4af8c59 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -55,7 +55,7 @@ class HardwareSerial : public Stream virtual int peek(void); virtual int read(void); virtual void flush(void); - virtual void write(uint8_t); + virtual long write(uint8_t); using Print::write; // pull in write(str) and write(buf, size) from Print }; diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 06ac52a..58b1032 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -30,167 +30,196 @@ // Public Methods ////////////////////////////////////////////////////////////// /* default implementation: may be overridden */ -void Print::write(const char *str) +long Print::write(const char *str) { - while (*str) - write(*str++); + long n = 0; + while (*str) { + if (write(*str++) <= 0) break; + n++; + } + return n; } /* default implementation: may be overridden */ -void Print::write(const uint8_t *buffer, size_t size) +long Print::write(const uint8_t *buffer, size_t size) { - while (size--) - write(*buffer++); + long n = 0; + while (size--) { + if (write(*buffer++) <= 0) break; + n++; + } + return n; } -void Print::print(const __FlashStringHelper *ifsh) +long Print::print(const __FlashStringHelper *ifsh) { const prog_char *p = (const prog_char *)ifsh; + long n = 0; while (1) { unsigned char c = pgm_read_byte(p++); - if (c == 0) return; - write(c); + if (c == 0) break; + if (write(c) <= 0) break; + n++; } + return n; } -void Print::print(const String &s) +long Print::print(const String &s) { + long n = 0; for (int i = 0; i < s.length(); i++) { - write(s[i]); + if (write(s[i]) < 0) break; + n++; } + return n; } -void Print::print(const char str[]) +long Print::print(const char str[]) { - write(str); + return write(str); } -void Print::print(char c) +long Print::print(char c) { - write(c); + return write(c); } -void Print::print(unsigned char b, int base) +long Print::print(unsigned char b, int base) { - print((unsigned long) b, base); + return print((unsigned long) b, base); } -void Print::print(int n, int base) +long Print::print(int n, int base) { - print((long) n, base); + return print((long) n, base); } -void Print::print(unsigned int n, int base) +long Print::print(unsigned int n, int base) { - print((unsigned long) n, base); + return print((unsigned long) n, base); } -void Print::print(long n, int base) +long Print::print(long n, int base) { if (base == 0) { - write(n); + return write(n); } else if (base == 10) { if (n < 0) { - print('-'); + long t = print('-'); + if (t <= 0) return t; n = -n; + return printNumber(n, 10) + 1; } - printNumber(n, 10); + return printNumber(n, 10); } else { - printNumber(n, base); + return printNumber(n, base); } } -void Print::print(unsigned long n, int base) +long Print::print(unsigned long n, int base) { - if (base == 0) write(n); - else printNumber(n, base); + if (base == 0) return write(n); + else return printNumber(n, base); } -void Print::print(double n, int digits) +long Print::print(double n, int digits) { - printFloat(n, digits); + return printFloat(n, digits); } -void Print::println(const __FlashStringHelper *ifsh) +long Print::println(const __FlashStringHelper *ifsh) { - print(ifsh); - println(); + long n = print(ifsh); + if (n >= 0) n += println(); + return n; } -void Print::print(const Printable& x) +long Print::print(const Printable& x) { - x.printTo(*this); + return x.printTo(*this); } -void Print::println(void) +long Print::println(void) { - print('\r'); - print('\n'); + long t = print('\r'); + if (t <= 0) return t; + if (print('\n') <= 0) return 1; + return 2; } -void Print::println(const String &s) +long Print::println(const String &s) { - print(s); - println(); + long n = print(s); + if (n >= 0) n += println(); + return n; } -void Print::println(const char c[]) +long Print::println(const char c[]) { - print(c); - println(); + long n = print(c); + if (n >= 0) n += println(); + return n; } -void Print::println(char c) +long Print::println(char c) { - print(c); - println(); + long n = print(c); + if (n > 0) n += println(); + return n; } -void Print::println(unsigned char b, int base) +long Print::println(unsigned char b, int base) { - print(b, base); - println(); + long n = print(b, base); + if (n >= 0) n += println(); + return n; } -void Print::println(int n, int base) +long Print::println(int num, int base) { - print(n, base); - println(); + long n = print(num, base); + if (n >= 0) n += println(); + return n; } -void Print::println(unsigned int n, int base) +long Print::println(unsigned int num, int base) { - print(n, base); - println(); + long n = print(num, base); + if (n >= 0) n += println(); + return n; } -void Print::println(long n, int base) +long Print::println(long num, int base) { - print(n, base); - println(); + long n = print(num, base); + if (n >= 0) n += println(); + return n; } -void Print::println(unsigned long n, int base) +long Print::println(unsigned long num, int base) { - print(n, base); - println(); + long n = print(num, base); + if (n >= 0) n += println(); + return n; } -void Print::println(double n, int digits) +long Print::println(double num, int digits) { - print(n, digits); - println(); + long n = print(num, digits); + if (n >= 0) n += println(); + return n; } -void Print::println(const Printable& x) +long Print::println(const Printable& x) { - print(x); - println(); + long n = print(x); + if (n >= 0) n += println(); + return n; } // Private Methods ///////////////////////////////////////////////////////////// -void Print::printNumber(unsigned long n, uint8_t base) { +long Print::printNumber(unsigned long n, uint8_t base) { char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; @@ -206,15 +235,17 @@ void Print::printNumber(unsigned long n, uint8_t base) { *--str = c < 10 ? c + '0' : c + 'A' - 10; } while(n); - write(str); + return write(str); } -void Print::printFloat(double number, uint8_t digits) +long Print::printFloat(double number, uint8_t digits) { + long n = 0, t; + // Handle negative numbers if (number < 0.0) { - print('-'); + if ((n = print('-')) <= 0) return n; number = -number; } @@ -228,18 +259,27 @@ void Print::printFloat(double number, uint8_t digits) // Extract the integer part of the number and print it unsigned long int_part = (unsigned long)number; double remainder = number - (double)int_part; - print(int_part); + if ((t = print(int_part)) < 0) return n; + + n += t; // Print the decimal point, but only if there are digits beyond - if (digits > 0) - print("."); + if (digits > 0) { + t = print("."); + if (t <= 0) return n; + n += t; + } // Extract digits from the remainder one at a time while (digits-- > 0) { remainder *= 10.0; int toPrint = int(remainder); - print(toPrint); + t = print(toPrint); + if (t <= 0) return n; + n += t; remainder -= toPrint; } + + return n; } diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index bf10b14..d5b02ff 100755 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -34,37 +34,37 @@ class Print { private: - void printNumber(unsigned long, uint8_t); - void printFloat(double, uint8_t); + long printNumber(unsigned long, uint8_t); + long printFloat(double, uint8_t); public: - virtual void write(uint8_t) = 0; - virtual void write(const char *str); - virtual void write(const uint8_t *buffer, size_t size); + virtual long write(uint8_t) = 0; + virtual long write(const char *str); + virtual long write(const uint8_t *buffer, size_t size); - void print(const __FlashStringHelper *); - void print(const String &); - void print(const char[]); - void print(char); - void print(unsigned char, int = DEC); - void print(int, int = DEC); - void print(unsigned int, int = DEC); - void print(long, int = DEC); - void print(unsigned long, int = DEC); - void print(double, int = 2); - void print(const Printable&); + long print(const __FlashStringHelper *); + long print(const String &); + long print(const char[]); + long print(char); + long print(unsigned char, int = DEC); + long print(int, int = DEC); + long print(unsigned int, int = DEC); + long print(long, int = DEC); + long print(unsigned long, int = DEC); + long print(double, int = 2); + long print(const Printable&); - void println(const __FlashStringHelper *); - void println(const String &s); - void println(const char[]); - void println(char); - void println(unsigned char, int = DEC); - void println(int, int = DEC); - void println(unsigned int, int = DEC); - void println(long, int = DEC); - void println(unsigned long, int = DEC); - void println(double, int = 2); - void println(const Printable&); - void println(void); + long println(const __FlashStringHelper *); + long println(const String &s); + long println(const char[]); + long println(char); + long println(unsigned char, int = DEC); + long println(int, int = DEC); + long println(unsigned int, int = DEC); + long println(long, int = DEC); + long println(unsigned long, int = DEC); + long println(double, int = 2); + long println(const Printable&); + long println(void); }; #endif diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h index d332aad..6814ee4 100644 --- a/cores/arduino/Printable.h +++ b/cores/arduino/Printable.h @@ -30,7 +30,7 @@ class Print; class Printable { public: - virtual void printTo(Print& p) const = 0; + virtual long printTo(Print& p) const = 0; }; #endif From 0635790dd111e91e5c488acc599cc404dc707abd Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Fri, 26 Aug 2011 14:20:41 -0400 Subject: [PATCH 10/11] Changing from long to ssize_t (int) for write(), print(), println() return. --- cores/arduino/HardwareSerial.cpp | 2 +- cores/arduino/HardwareSerial.h | 2 +- cores/arduino/Print.cpp | 90 ++++++++++++++++---------------- cores/arduino/Print.h | 58 ++++++++++---------- cores/arduino/Printable.h | 2 +- 5 files changed, 78 insertions(+), 76 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index a200da5..641c973 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -352,7 +352,7 @@ void HardwareSerial::flush() ; } -long HardwareSerial::write(uint8_t c) +ssize_t HardwareSerial::write(uint8_t c) { int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 4af8c59..960d3f5 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -55,7 +55,7 @@ class HardwareSerial : public Stream virtual int peek(void); virtual int read(void); virtual void flush(void); - virtual long write(uint8_t); + virtual ssize_t write(uint8_t); using Print::write; // pull in write(str) and write(buf, size) from Print }; diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 58b1032..192d9a3 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -30,9 +30,9 @@ // Public Methods ////////////////////////////////////////////////////////////// /* default implementation: may be overridden */ -long Print::write(const char *str) +ssize_t Print::write(const char *str) { - long n = 0; + ssize_t n = 0; while (*str) { if (write(*str++) <= 0) break; n++; @@ -41,9 +41,9 @@ long Print::write(const char *str) } /* default implementation: may be overridden */ -long Print::write(const uint8_t *buffer, size_t size) +ssize_t Print::write(const uint8_t *buffer, size_t size) { - long n = 0; + ssize_t n = 0; while (size--) { if (write(*buffer++) <= 0) break; n++; @@ -51,10 +51,10 @@ long Print::write(const uint8_t *buffer, size_t size) return n; } -long Print::print(const __FlashStringHelper *ifsh) +ssize_t Print::print(const __FlashStringHelper *ifsh) { const prog_char *p = (const prog_char *)ifsh; - long n = 0; + ssize_t n = 0; while (1) { unsigned char c = pgm_read_byte(p++); if (c == 0) break; @@ -64,9 +64,9 @@ long Print::print(const __FlashStringHelper *ifsh) return n; } -long Print::print(const String &s) +ssize_t Print::print(const String &s) { - long n = 0; + ssize_t n = 0; for (int i = 0; i < s.length(); i++) { if (write(s[i]) < 0) break; n++; @@ -74,38 +74,38 @@ long Print::print(const String &s) return n; } -long Print::print(const char str[]) +ssize_t Print::print(const char str[]) { return write(str); } -long Print::print(char c) +ssize_t Print::print(char c) { return write(c); } -long Print::print(unsigned char b, int base) +ssize_t Print::print(unsigned char b, int base) { return print((unsigned long) b, base); } -long Print::print(int n, int base) +ssize_t Print::print(int n, int base) { return print((long) n, base); } -long Print::print(unsigned int n, int base) +ssize_t Print::print(unsigned int n, int base) { return print((unsigned long) n, base); } -long Print::print(long n, int base) +ssize_t Print::print(long n, int base) { if (base == 0) { return write(n); } else if (base == 10) { if (n < 0) { - long t = print('-'); + int t = print('-'); if (t <= 0) return t; n = -n; return printNumber(n, 10) + 1; @@ -116,110 +116,110 @@ long Print::print(long n, int base) } } -long Print::print(unsigned long n, int base) +ssize_t Print::print(unsigned long n, int base) { if (base == 0) return write(n); else return printNumber(n, base); } -long Print::print(double n, int digits) +ssize_t Print::print(double n, int digits) { return printFloat(n, digits); } -long Print::println(const __FlashStringHelper *ifsh) +ssize_t Print::println(const __FlashStringHelper *ifsh) { - long n = print(ifsh); + ssize_t n = print(ifsh); if (n >= 0) n += println(); return n; } -long Print::print(const Printable& x) +ssize_t Print::print(const Printable& x) { return x.printTo(*this); } -long Print::println(void) +ssize_t Print::println(void) { - long t = print('\r'); + ssize_t t = print('\r'); if (t <= 0) return t; if (print('\n') <= 0) return 1; return 2; } -long Print::println(const String &s) +ssize_t Print::println(const String &s) { - long n = print(s); + ssize_t n = print(s); if (n >= 0) n += println(); return n; } -long Print::println(const char c[]) +ssize_t Print::println(const char c[]) { - long n = print(c); + ssize_t n = print(c); if (n >= 0) n += println(); return n; } -long Print::println(char c) +ssize_t Print::println(char c) { - long n = print(c); + ssize_t n = print(c); if (n > 0) n += println(); return n; } -long Print::println(unsigned char b, int base) +ssize_t Print::println(unsigned char b, int base) { - long n = print(b, base); + ssize_t n = print(b, base); if (n >= 0) n += println(); return n; } -long Print::println(int num, int base) +ssize_t Print::println(int num, int base) { - long n = print(num, base); + ssize_t n = print(num, base); if (n >= 0) n += println(); return n; } -long Print::println(unsigned int num, int base) +ssize_t Print::println(unsigned int num, int base) { - long n = print(num, base); + ssize_t n = print(num, base); if (n >= 0) n += println(); return n; } -long Print::println(long num, int base) +ssize_t Print::println(long num, int base) { - long n = print(num, base); + ssize_t n = print(num, base); if (n >= 0) n += println(); return n; } -long Print::println(unsigned long num, int base) +ssize_t Print::println(unsigned long num, int base) { - long n = print(num, base); + ssize_t n = print(num, base); if (n >= 0) n += println(); return n; } -long Print::println(double num, int digits) +ssize_t Print::println(double num, int digits) { - long n = print(num, digits); + ssize_t n = print(num, digits); if (n >= 0) n += println(); return n; } -long Print::println(const Printable& x) +ssize_t Print::println(const Printable& x) { - long n = print(x); + ssize_t n = print(x); if (n >= 0) n += println(); return n; } // Private Methods ///////////////////////////////////////////////////////////// -long Print::printNumber(unsigned long n, uint8_t base) { +ssize_t Print::printNumber(unsigned long n, uint8_t base) { char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; @@ -238,9 +238,9 @@ long Print::printNumber(unsigned long n, uint8_t base) { return write(str); } -long Print::printFloat(double number, uint8_t digits) +ssize_t Print::printFloat(double number, uint8_t digits) { - long n = 0, t; + ssize_t n = 0, t; // Handle negative numbers if (number < 0.0) diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index d5b02ff..3f303f3 100755 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -23,6 +23,8 @@ #include #include // for size_t +typedef int ssize_t; + #include "WString.h" #include "Printable.h" @@ -34,37 +36,37 @@ class Print { private: - long printNumber(unsigned long, uint8_t); - long printFloat(double, uint8_t); + ssize_t printNumber(unsigned long, uint8_t); + ssize_t printFloat(double, uint8_t); public: - virtual long write(uint8_t) = 0; - virtual long write(const char *str); - virtual long write(const uint8_t *buffer, size_t size); + virtual ssize_t write(uint8_t) = 0; + virtual ssize_t write(const char *str); + virtual ssize_t write(const uint8_t *buffer, size_t size); - long print(const __FlashStringHelper *); - long print(const String &); - long print(const char[]); - long print(char); - long print(unsigned char, int = DEC); - long print(int, int = DEC); - long print(unsigned int, int = DEC); - long print(long, int = DEC); - long print(unsigned long, int = DEC); - long print(double, int = 2); - long print(const Printable&); + ssize_t print(const __FlashStringHelper *); + ssize_t print(const String &); + ssize_t print(const char[]); + ssize_t print(char); + ssize_t print(unsigned char, int = DEC); + ssize_t print(int, int = DEC); + ssize_t print(unsigned int, int = DEC); + ssize_t print(long, int = DEC); + ssize_t print(unsigned long, int = DEC); + ssize_t print(double, int = 2); + ssize_t print(const Printable&); - long println(const __FlashStringHelper *); - long println(const String &s); - long println(const char[]); - long println(char); - long println(unsigned char, int = DEC); - long println(int, int = DEC); - long println(unsigned int, int = DEC); - long println(long, int = DEC); - long println(unsigned long, int = DEC); - long println(double, int = 2); - long println(const Printable&); - long println(void); + ssize_t println(const __FlashStringHelper *); + ssize_t println(const String &s); + ssize_t println(const char[]); + ssize_t println(char); + ssize_t println(unsigned char, int = DEC); + ssize_t println(int, int = DEC); + ssize_t println(unsigned int, int = DEC); + ssize_t println(long, int = DEC); + ssize_t println(unsigned long, int = DEC); + ssize_t println(double, int = 2); + ssize_t println(const Printable&); + ssize_t println(void); }; #endif diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h index 6814ee4..9065904 100644 --- a/cores/arduino/Printable.h +++ b/cores/arduino/Printable.h @@ -30,7 +30,7 @@ class Print; class Printable { public: - virtual long printTo(Print& p) const = 0; + virtual ssize_t printTo(Print& p) const = 0; }; #endif From 5130a1329462aa36d5f18e31851d3d9d5086e411 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Fri, 26 Aug 2011 16:08:14 -0400 Subject: [PATCH 11/11] Moving write errors out of return value into separate API methods. write(), print(), println() now return size_t (and don't use negative values to signal errors). Print adds writeError() for checking for write errors, clearWriteError() to reset the flag to false, and a protected setWriteError() for signalling errors. http://code.google.com/p/arduino/issues/detail?id=598 --- cores/arduino/HardwareSerial.cpp | 2 +- cores/arduino/HardwareSerial.h | 2 +- cores/arduino/Print.cpp | 150 ++++++++++++++----------------- cores/arduino/Print.h | 66 +++++++------- cores/arduino/Printable.h | 2 +- 5 files changed, 108 insertions(+), 114 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 641c973..d6be218 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -352,7 +352,7 @@ void HardwareSerial::flush() ; } -ssize_t HardwareSerial::write(uint8_t c) +size_t HardwareSerial::write(uint8_t c) { int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 960d3f5..1895f08 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -55,7 +55,7 @@ class HardwareSerial : public Stream virtual int peek(void); virtual int read(void); virtual void flush(void); - virtual ssize_t write(uint8_t); + virtual size_t write(uint8_t); using Print::write; // pull in write(str) and write(buf, size) from Print }; diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 192d9a3..8190d4f 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -30,85 +30,80 @@ // Public Methods ////////////////////////////////////////////////////////////// /* default implementation: may be overridden */ -ssize_t Print::write(const char *str) +size_t Print::write(const char *str) { - ssize_t n = 0; + size_t n = 0; while (*str) { - if (write(*str++) <= 0) break; - n++; + n += write(*str++); } return n; } /* default implementation: may be overridden */ -ssize_t Print::write(const uint8_t *buffer, size_t size) +size_t Print::write(const uint8_t *buffer, size_t size) { - ssize_t n = 0; + size_t n = 0; while (size--) { - if (write(*buffer++) <= 0) break; - n++; + n += write(*buffer++); } return n; } -ssize_t Print::print(const __FlashStringHelper *ifsh) +size_t Print::print(const __FlashStringHelper *ifsh) { const prog_char *p = (const prog_char *)ifsh; - ssize_t n = 0; + size_t n = 0; while (1) { unsigned char c = pgm_read_byte(p++); if (c == 0) break; - if (write(c) <= 0) break; - n++; + n += write(c); } return n; } -ssize_t Print::print(const String &s) +size_t Print::print(const String &s) { - ssize_t n = 0; + size_t n = 0; for (int i = 0; i < s.length(); i++) { - if (write(s[i]) < 0) break; - n++; + n += write(s[i]); } return n; } -ssize_t Print::print(const char str[]) +size_t Print::print(const char str[]) { return write(str); } -ssize_t Print::print(char c) +size_t Print::print(char c) { return write(c); } -ssize_t Print::print(unsigned char b, int base) +size_t Print::print(unsigned char b, int base) { return print((unsigned long) b, base); } -ssize_t Print::print(int n, int base) +size_t Print::print(int n, int base) { return print((long) n, base); } -ssize_t Print::print(unsigned int n, int base) +size_t Print::print(unsigned int n, int base) { return print((unsigned long) n, base); } -ssize_t Print::print(long n, int base) +size_t Print::print(long n, int base) { if (base == 0) { return write(n); } else if (base == 10) { if (n < 0) { int t = print('-'); - if (t <= 0) return t; n = -n; - return printNumber(n, 10) + 1; + return printNumber(n, 10) + t; } return printNumber(n, 10); } else { @@ -116,110 +111,109 @@ ssize_t Print::print(long n, int base) } } -ssize_t Print::print(unsigned long n, int base) +size_t Print::print(unsigned long n, int base) { if (base == 0) return write(n); else return printNumber(n, base); } -ssize_t Print::print(double n, int digits) +size_t Print::print(double n, int digits) { return printFloat(n, digits); } -ssize_t Print::println(const __FlashStringHelper *ifsh) +size_t Print::println(const __FlashStringHelper *ifsh) { - ssize_t n = print(ifsh); - if (n >= 0) n += println(); + size_t n = print(ifsh); + n += println(); return n; } -ssize_t Print::print(const Printable& x) +size_t Print::print(const Printable& x) { return x.printTo(*this); } -ssize_t Print::println(void) +size_t Print::println(void) { - ssize_t t = print('\r'); - if (t <= 0) return t; - if (print('\n') <= 0) return 1; - return 2; -} - -ssize_t Print::println(const String &s) -{ - ssize_t n = print(s); - if (n >= 0) n += println(); + size_t n = print('\r'); + n += print('\n'); return n; } -ssize_t Print::println(const char c[]) +size_t Print::println(const String &s) { - ssize_t n = print(c); - if (n >= 0) n += println(); + size_t n = print(s); + n += println(); return n; } -ssize_t Print::println(char c) +size_t Print::println(const char c[]) { - ssize_t n = print(c); - if (n > 0) n += println(); + size_t n = print(c); + n += println(); return n; } -ssize_t Print::println(unsigned char b, int base) +size_t Print::println(char c) { - ssize_t n = print(b, base); - if (n >= 0) n += println(); + size_t n = print(c); + n += println(); return n; } -ssize_t Print::println(int num, int base) +size_t Print::println(unsigned char b, int base) { - ssize_t n = print(num, base); - if (n >= 0) n += println(); + size_t n = print(b, base); + n += println(); return n; } -ssize_t Print::println(unsigned int num, int base) +size_t Print::println(int num, int base) { - ssize_t n = print(num, base); - if (n >= 0) n += println(); + size_t n = print(num, base); + n += println(); return n; } -ssize_t Print::println(long num, int base) +size_t Print::println(unsigned int num, int base) { - ssize_t n = print(num, base); - if (n >= 0) n += println(); + size_t n = print(num, base); + n += println(); return n; } -ssize_t Print::println(unsigned long num, int base) +size_t Print::println(long num, int base) { - ssize_t n = print(num, base); - if (n >= 0) n += println(); + size_t n = print(num, base); + n += println(); return n; } -ssize_t Print::println(double num, int digits) +size_t Print::println(unsigned long num, int base) { - ssize_t n = print(num, digits); - if (n >= 0) n += println(); + size_t n = print(num, base); + n += println(); return n; } -ssize_t Print::println(const Printable& x) +size_t Print::println(double num, int digits) { - ssize_t n = print(x); - if (n >= 0) n += println(); + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); return n; } // Private Methods ///////////////////////////////////////////////////////////// -ssize_t Print::printNumber(unsigned long n, uint8_t base) { +size_t Print::printNumber(unsigned long n, uint8_t base) { char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; @@ -238,14 +232,14 @@ ssize_t Print::printNumber(unsigned long n, uint8_t base) { return write(str); } -ssize_t Print::printFloat(double number, uint8_t digits) +size_t Print::printFloat(double number, uint8_t digits) { - ssize_t n = 0, t; + size_t n = 0; // Handle negative numbers if (number < 0.0) { - if ((n = print('-')) <= 0) return n; + n += print('-'); number = -number; } @@ -259,15 +253,11 @@ ssize_t Print::printFloat(double number, uint8_t digits) // Extract the integer part of the number and print it unsigned long int_part = (unsigned long)number; double remainder = number - (double)int_part; - if ((t = print(int_part)) < 0) return n; - - n += t; + n += print(int_part); // Print the decimal point, but only if there are digits beyond if (digits > 0) { - t = print("."); - if (t <= 0) return n; - n += t; + n += print("."); } // Extract digits from the remainder one at a time @@ -275,9 +265,7 @@ ssize_t Print::printFloat(double number, uint8_t digits) { remainder *= 10.0; int toPrint = int(remainder); - t = print(toPrint); - if (t <= 0) return n; - n += t; + n += print(toPrint); remainder -= toPrint; } diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index 3f303f3..fce302e 100755 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -23,8 +23,6 @@ #include #include // for size_t -typedef int ssize_t; - #include "WString.h" #include "Printable.h" @@ -36,37 +34,45 @@ typedef int ssize_t; class Print { private: - ssize_t printNumber(unsigned long, uint8_t); - ssize_t printFloat(double, uint8_t); + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } public: - virtual ssize_t write(uint8_t) = 0; - virtual ssize_t write(const char *str); - virtual ssize_t write(const uint8_t *buffer, size_t size); + Print() : write_error(0) {} + + int writeError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + virtual size_t write(const char *str); + virtual size_t write(const uint8_t *buffer, size_t size); - ssize_t print(const __FlashStringHelper *); - ssize_t print(const String &); - ssize_t print(const char[]); - ssize_t print(char); - ssize_t print(unsigned char, int = DEC); - ssize_t print(int, int = DEC); - ssize_t print(unsigned int, int = DEC); - ssize_t print(long, int = DEC); - ssize_t print(unsigned long, int = DEC); - ssize_t print(double, int = 2); - ssize_t print(const Printable&); + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); - ssize_t println(const __FlashStringHelper *); - ssize_t println(const String &s); - ssize_t println(const char[]); - ssize_t println(char); - ssize_t println(unsigned char, int = DEC); - ssize_t println(int, int = DEC); - ssize_t println(unsigned int, int = DEC); - ssize_t println(long, int = DEC); - ssize_t println(unsigned long, int = DEC); - ssize_t println(double, int = 2); - ssize_t println(const Printable&); - ssize_t println(void); + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); }; #endif diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h index 9065904..e22e87e 100644 --- a/cores/arduino/Printable.h +++ b/cores/arduino/Printable.h @@ -30,7 +30,7 @@ class Print; class Printable { public: - virtual ssize_t printTo(Print& p) const = 0; + virtual size_t printTo(Print& p) const = 0; }; #endif