From 4da2833a81b28f1aeb598a4b8e588ec605f907bd Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sat, 28 Apr 2012 12:44:49 +0200 Subject: [PATCH] [sam] updated Print class and all derivated classes. --- .../arduino/sam/cores/sam/HardwareSerial.h | 32 ++- hardware/arduino/sam/cores/sam/Print.cpp | 187 +++++++++++------- hardware/arduino/sam/cores/sam/Print.h | 63 +++--- hardware/arduino/sam/cores/sam/Printable.h | 40 ++++ hardware/arduino/sam/cores/sam/UARTClass.cpp | 3 +- hardware/arduino/sam/cores/sam/UARTClass.h | 3 +- hardware/arduino/sam/cores/sam/USARTClass.cpp | 3 +- hardware/arduino/sam/cores/sam/USARTClass.h | 3 +- hardware/arduino/sam/cores/sam/USB/USBAPI.h | 1 - hardware/arduino/sam/cores/sam/WString.cpp | 44 ++--- hardware/arduino/sam/cores/sam/WString.h | 4 +- hardware/arduino/sam/cores/sam/new.cpp | 18 ++ hardware/arduino/sam/cores/sam/new.h | 22 +++ 13 files changed, 276 insertions(+), 147 deletions(-) create mode 100644 hardware/arduino/sam/cores/sam/Printable.h create mode 100644 hardware/arduino/sam/cores/sam/new.cpp create mode 100644 hardware/arduino/sam/cores/sam/new.h diff --git a/hardware/arduino/sam/cores/sam/HardwareSerial.h b/hardware/arduino/sam/cores/sam/HardwareSerial.h index b76f2efbd..29fb5d65b 100644 --- a/hardware/arduino/sam/cores/sam/HardwareSerial.h +++ b/hardware/arduino/sam/cores/sam/HardwareSerial.h @@ -19,28 +19,24 @@ #ifndef HardwareSerial_h #define HardwareSerial_h -#include +#include + #include "Stream.h" -#include "RingBuffer.h" class HardwareSerial : public Stream { - protected: - RingBuffer *_rx_buffer ; - RingBuffer *_tx_buffer ; - public: - virtual void begin( const uint32_t dwBaudRate ) =0 ; - virtual void end( void ) =0 ; - virtual int available( void ) =0 ; - virtual int peek( void ) =0 ; - virtual int read( void ) =0 ; - virtual void flush( void ) =0 ; - virtual void write( const uint8_t c ) =0 ; + void begin(unsigned long); + void end(); + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool(); +}; -// virtual void write( const char *str ) ; -// virtual void write( const uint8_t *buffer, size_t size ) ; - using Print::write ; // pull in write(str) and write(buf, size) from Print -} ; +extern void serialEventRun(void) __attribute__((weak)); -#endif // HardwareSerial_h +#endif diff --git a/hardware/arduino/sam/cores/sam/Print.cpp b/hardware/arduino/sam/cores/sam/Print.cpp index ff9604cbb..123370f4d 100644 --- a/hardware/arduino/sam/cores/sam/Print.cpp +++ b/hardware/arduino/sam/cores/sam/Print.cpp @@ -30,141 +30,173 @@ // Public Methods ////////////////////////////////////////////////////////////// /* default implementation: may be overridden */ -void Print::write(const char *str) +size_t Print::write(const uint8_t *buffer, size_t size) { - while (*str) - write(*str++); -} - -/* default implementation: may be overridden */ -void Print::write(const uint8_t *buffer, size_t size) -{ - while (size--) - write(*buffer++); -} - -void Print::print( const String &s ) -{ - for ( int i = 0 ; i < (int)s.length() ; i++ ) - { - write( s[i] ) ; + size_t n = 0; + while (size--) { + n += write(*buffer++); } + return n; } -void Print::print(const char str[]) +size_t Print::print(const __FlashStringHelper *ifsh) { - write(str); + return print(reinterpret_cast(ifsh)); } -void Print::print(char c) +size_t Print::print(const String &s) { - write(c); + size_t n = 0; + for (uint16_t i = 0; i < s.length(); i++) { + n += write(s[i]); + } + return n; } -void Print::print(unsigned char b, int base) +size_t Print::print(const char str[]) { - print((unsigned long) b, base); + return write(str); } -void Print::print(int n, int base) +size_t Print::print(char c) { - print((long) n, base); + return write(c); } -void Print::print(unsigned int n, int base) +size_t Print::print(unsigned char b, int base) { - print((unsigned long) n, base); + return print((unsigned long) b, base); } -void Print::print(long n, int base) +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) { if (base == 0) { - write(n); + return write(n); } else if (base == 10) { if (n < 0) { - print('-'); + int t = print('-'); n = -n; + return printNumber(n, 10) + t; } - printNumber(n, 10); + return printNumber(n, 10); } else { - printNumber(n, base); + return printNumber(n, base); } } -void Print::print(unsigned long n, int base) +size_t 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) +size_t Print::print(double n, int digits) { - printFloat(n, digits); + return printFloat(n, digits); } -void Print::println(void) +size_t Print::println(const __FlashStringHelper *ifsh) { - print('\r'); - print('\n'); + size_t n = print(ifsh); + n += println(); + return n; } -void Print::println(const String &s) +size_t Print::print(const Printable& x) { - print(s); - println(); + return x.printTo(*this); } -void Print::println(const char c[]) +size_t Print::println(void) { - print(c); - println(); + size_t n = print('\r'); + n += print('\n'); + return n; } -void Print::println(char c) +size_t Print::println(const String &s) { - print(c); - println(); + size_t n = print(s); + n += println(); + return n; } -void Print::println(unsigned char b, int base) +size_t Print::println(const char c[]) { - print(b, base); - println(); + size_t n = print(c); + n += println(); + return n; } -void Print::println(int n, int base) +size_t Print::println(char c) { - print(n, base); - println(); + size_t n = print(c); + n += println(); + return n; } -void Print::println(unsigned int n, int base) +size_t Print::println(unsigned char b, int base) { - print(n, base); - println(); + size_t n = print(b, base); + n += println(); + return n; } -void Print::println(long n, int base) +size_t Print::println(int num, int base) { - print(n, base); - println(); + size_t n = print(num, base); + n += println(); + return n; } -void Print::println(unsigned long n, int base) +size_t Print::println(unsigned int num, int base) { - print(n, base); - println(); + size_t n = print(num, base); + n += println(); + return n; } -void Print::println(double n, int digits) +size_t Print::println(long num, int base) { - print(n, digits); - println(); + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + 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 ///////////////////////////////////////////////////////////// -void 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]; @@ -180,15 +212,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) +size_t Print::printFloat(double number, uint8_t digits) { + size_t n = 0; + // Handle negative numbers if (number < 0.0) { - print('-'); + n += print('-'); number = -number; } @@ -202,18 +236,21 @@ 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); + n += print(int_part); // Print the decimal point, but only if there are digits beyond - if (digits > 0) - print("."); + if (digits > 0) { + n += print("."); + } // Extract digits from the remainder one at a time while (digits-- > 0) { remainder *= 10.0; int toPrint = int(remainder); - print(toPrint); + n += print(toPrint); remainder -= toPrint; } + + return n; } diff --git a/hardware/arduino/sam/cores/sam/Print.h b/hardware/arduino/sam/cores/sam/Print.h index 7885617ed..1af6b723f 100644 --- a/hardware/arduino/sam/cores/sam/Print.h +++ b/hardware/arduino/sam/cores/sam/Print.h @@ -24,6 +24,7 @@ #include // for size_t #include "WString.h" +#include "Printable.h" #define DEC 10 #define HEX 16 @@ -33,33 +34,45 @@ class Print { private: - void printNumber(unsigned long, uint8_t); - void 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 void write(uint8_t) = 0; - virtual void write(const char *str); - virtual void write(const uint8_t *buffer, size_t size); + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); } + virtual size_t write(const uint8_t *buffer, size_t size); + + 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&); - 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 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(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/hardware/arduino/sam/cores/sam/Printable.h b/hardware/arduino/sam/cores/sam/Printable.h new file mode 100644 index 000000000..d03c9af62 --- /dev/null +++ b/hardware/arduino/sam/cores/sam/Printable.h @@ -0,0 +1,40 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. 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 Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/hardware/arduino/sam/cores/sam/UARTClass.cpp b/hardware/arduino/sam/cores/sam/UARTClass.cpp index 106a79cc5..16188b128 100644 --- a/hardware/arduino/sam/cores/sam/UARTClass.cpp +++ b/hardware/arduino/sam/cores/sam/UARTClass.cpp @@ -107,7 +107,7 @@ void UARTClass::flush( void ) ; } -void UARTClass::write( const uint8_t uc_data ) +size_t UARTClass::write( const uint8_t uc_data ) { // Check if the transmitter is ready while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) @@ -115,6 +115,7 @@ void UARTClass::write( const uint8_t uc_data ) // Send character _pUart->UART_THR = uc_data; + return 1; } void UARTClass::IrqHandler( void ) diff --git a/hardware/arduino/sam/cores/sam/UARTClass.h b/hardware/arduino/sam/cores/sam/UARTClass.h index 03e00f0a1..5665429c9 100644 --- a/hardware/arduino/sam/cores/sam/UARTClass.h +++ b/hardware/arduino/sam/cores/sam/UARTClass.h @@ -20,6 +20,7 @@ #define _UART_CLASS_ #include "HardwareSerial.h" +#include "RingBuffer.h" // Includes Atmel CMSIS #include @@ -43,7 +44,7 @@ class UARTClass : public HardwareSerial int peek( void ) ; int read( void ) ; void flush( void ) ; - void write( const uint8_t c ) ; + size_t write( const uint8_t c ) ; void IrqHandler( void ) ; diff --git a/hardware/arduino/sam/cores/sam/USARTClass.cpp b/hardware/arduino/sam/cores/sam/USARTClass.cpp index c00f3df57..6531c4c5b 100644 --- a/hardware/arduino/sam/cores/sam/USARTClass.cpp +++ b/hardware/arduino/sam/cores/sam/USARTClass.cpp @@ -108,7 +108,7 @@ void USARTClass::flush( void ) ; } -void USARTClass::write( const uint8_t uc_data ) +size_t USARTClass::write( const uint8_t uc_data ) { // Check if the transmitter is ready while ((_pUsart->US_CSR & US_CSR_TXRDY) != US_CSR_TXRDY) @@ -116,6 +116,7 @@ void USARTClass::write( const uint8_t uc_data ) // Send character _pUsart->US_THR = uc_data ; + return 1; } void USARTClass::IrqHandler( void ) diff --git a/hardware/arduino/sam/cores/sam/USARTClass.h b/hardware/arduino/sam/cores/sam/USARTClass.h index 9d93a98a1..85356f2fa 100644 --- a/hardware/arduino/sam/cores/sam/USARTClass.h +++ b/hardware/arduino/sam/cores/sam/USARTClass.h @@ -20,6 +20,7 @@ #define _USART_CLASS_ #include "HardwareSerial.h" +#include "RingBuffer.h" // Includes Atmel CMSIS #include @@ -43,7 +44,7 @@ class USARTClass : public HardwareSerial int peek( void ) ; int read( void ) ; void flush( void ) ; - void write( const uint8_t c ) ; + size_t write( const uint8_t c ) ; void IrqHandler( void ) ; diff --git a/hardware/arduino/sam/cores/sam/USB/USBAPI.h b/hardware/arduino/sam/cores/sam/USB/USBAPI.h index 8fcf0f2c1..8a248ae11 100644 --- a/hardware/arduino/sam/cores/sam/USB/USBAPI.h +++ b/hardware/arduino/sam/cores/sam/USB/USBAPI.h @@ -39,7 +39,6 @@ public: virtual int read(void); virtual void flush(void); virtual size_t write(uint8_t); - virtual void write(uint8_t); operator bool(); }; extern Serial_ Serial; diff --git a/hardware/arduino/sam/cores/sam/WString.cpp b/hardware/arduino/sam/cores/sam/WString.cpp index d0b86ece9..824fe804b 100644 --- a/hardware/arduino/sam/cores/sam/WString.cpp +++ b/hardware/arduino/sam/cores/sam/WString.cpp @@ -150,13 +150,13 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) /* Copy and Move */ /*********************************************/ -String & String::copy(const char *cstr, unsigned int length) +String & String::copy(const char *cstr, unsigned int _length) { - if (!reserve(length)) { + if (!reserve(_length)) { invalidate(); return *this; } - len = length; + len = _length; strcpy(buffer, cstr); return *this; } @@ -224,11 +224,11 @@ unsigned char String::concat(const String &s) return concat(s.buffer, s.len); } -unsigned char String::concat(const char *cstr, unsigned int length) +unsigned char String::concat(const char *cstr, unsigned int _length) { - unsigned int newlen = len + length; + unsigned int newlen = len + _length; if (!cstr) return 0; - if (length == 0) return 1; + if (_length == 0) return 1; if (!reserve(newlen)) return 0; strcpy(buffer + len, cstr); len = newlen; @@ -252,7 +252,7 @@ unsigned char String::concat(char c) unsigned char String::concat(unsigned char num) { char buf[4]; -// itoa(num, buf, 10); + itoa(num, buf, 10); return concat(buf, strlen(buf)); } @@ -499,9 +499,9 @@ int String::lastIndexOf( char theChar ) const return lastIndexOf(theChar, len - 1); } -int String::lastIndexOf(char ch, int fromIndex) const +int String::lastIndexOf(char ch, unsigned int fromIndex) const { - if (fromIndex >= len || fromIndex < 0) return -1; + if (fromIndex >= len) return -1; char tempchar = buffer[fromIndex + 1]; buffer[fromIndex + 1] = '\0'; char* temp = strrchr( buffer, ch ); @@ -515,15 +515,15 @@ int String::lastIndexOf(const String &s2) const return lastIndexOf(s2, len - s2.len); } -int String::lastIndexOf(const String &s2, int fromIndex) const +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const { - if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1; + if (s2.len == 0 || len == 0 || s2.len > len) return -1; if (fromIndex >= len) fromIndex = len - 1; int found = -1; for (char *p = buffer; p <= buffer + fromIndex; p++) { p = strstr(p, s2.buffer); if (!p) break; - if (p - buffer <= fromIndex) found = p - buffer; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; } return found; } @@ -554,24 +554,24 @@ String String::substring(unsigned int left, unsigned int right) const /* Modification */ /*********************************************/ -void String::replace(char find, char replace) +void String::replace(char find, char _replace) { if (!buffer) return; for (char *p = buffer; *p; p++) { - if (*p == find) *p = replace; + if (*p == find) *p = _replace; } } -void String::replace(const String& find, const String& replace) +void String::replace(const String& find, const String& _replace) { if (len == 0 || find.len == 0) return; - int diff = replace.len - find.len; + int diff = _replace.len - find.len; char *readFrom = buffer; char *foundAt; if (diff == 0) { while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { - memcpy(foundAt, replace.buffer, replace.len); - readFrom = foundAt + replace.len; + memcpy(foundAt, _replace.buffer, _replace.len); + readFrom = foundAt + _replace.len; } } else if (diff < 0) { char *writeTo = buffer; @@ -579,8 +579,8 @@ void String::replace(const String& find, const String& replace) unsigned int n = foundAt - readFrom; memcpy(writeTo, readFrom, n); writeTo += n; - memcpy(writeTo, replace.buffer, replace.len); - writeTo += replace.len; + memcpy(writeTo, _replace.buffer, _replace.len); + writeTo += _replace.len; readFrom = foundAt + find.len; len += diff; } @@ -594,12 +594,12 @@ void String::replace(const String& find, const String& replace) if (size == len) return; if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! int index = len - 1; - while ((index = lastIndexOf(find, index)) >= 0) { + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { readFrom = buffer + index + find.len; memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); len += diff; buffer[len] = 0; - memcpy(buffer + index, replace.buffer, replace.len); + memcpy(buffer + index, _replace.buffer, _replace.len); index--; } } diff --git a/hardware/arduino/sam/cores/sam/WString.h b/hardware/arduino/sam/cores/sam/WString.h index 01f144ac6..5f490b949 100644 --- a/hardware/arduino/sam/cores/sam/WString.h +++ b/hardware/arduino/sam/cores/sam/WString.h @@ -153,9 +153,9 @@ public: int indexOf( const String &str ) const; int indexOf( const String &str, unsigned int fromIndex ) const; int lastIndexOf( char ch ) const; - int lastIndexOf( char ch, int fromIndex ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; int lastIndexOf( const String &str ) const; - int lastIndexOf( const String &str, int fromIndex ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; String substring( unsigned int beginIndex ) const; String substring( unsigned int beginIndex, unsigned int endIndex ) const; diff --git a/hardware/arduino/sam/cores/sam/new.cpp b/hardware/arduino/sam/cores/sam/new.cpp new file mode 100644 index 000000000..0f6d4220e --- /dev/null +++ b/hardware/arduino/sam/cores/sam/new.cpp @@ -0,0 +1,18 @@ +#include + +void * operator new(size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);}; +void __cxa_guard_release (__guard *g) {*(char *)g = 1;}; +void __cxa_guard_abort (__guard *) {}; + +void __cxa_pure_virtual(void) {}; + diff --git a/hardware/arduino/sam/cores/sam/new.h b/hardware/arduino/sam/cores/sam/new.h new file mode 100644 index 000000000..cd940ce8b --- /dev/null +++ b/hardware/arduino/sam/cores/sam/new.h @@ -0,0 +1,22 @@ +/* Header to define new/delete operators as they aren't provided by avr-gcc by default + Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453 + */ + +#ifndef NEW_H +#define NEW_H + +#include + +void * operator new(size_t size); +void operator delete(void * ptr); + +__extension__ typedef int __guard __attribute__((mode (__DI__))); + +extern "C" int __cxa_guard_acquire(__guard *); +extern "C" void __cxa_guard_release (__guard *); +extern "C" void __cxa_guard_abort (__guard *); + +extern "C" void __cxa_pure_virtual(void); + +#endif +