diff --git a/STM32F4/cores/maple/Arduino.h b/STM32F4/cores/maple/Arduino.h index 7278f89..d02a50c 100644 --- a/STM32F4/cores/maple/Arduino.h +++ b/STM32F4/cores/maple/Arduino.h @@ -2,3 +2,5 @@ #define Arduino_h #include "WProgram.h" #endif + +#include "variant.h" diff --git a/STM32F4/cores/maple/Print.cpp b/STM32F4/cores/maple/Print.cpp index 58c7cc7..5334ac6 100644 --- a/STM32F4/cores/maple/Print.cpp +++ b/STM32F4/cores/maple/Print.cpp @@ -1,6 +1,7 @@ /* * Print.cpp - Base class that provides print() and println() * Copyright (c) 2008 David A. Mellis. All right reserved. + * Copyright (c) 2011 LeafLabs, LLC. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -23,7 +24,8 @@ #include "Print.h" -#include +#include "wirish_math.h" +#include "limits.h" #ifndef LLONG_MAX /* @@ -40,143 +42,192 @@ #define LLONG_MAX 9223372036854775807LL #endif -#include "wirish_math.h" - /* * Public methods */ -void Print::write(const char *str) { +size_t Print::write(const char *str) { + size_t n = 0; while (*str) { write(*str++); + n++; } + return n; } -void Print::write(const void *buffer, uint32 size) { +size_t Print::write(const void *buffer, uint32 size) { + size_t n = 0; uint8 *ch = (uint8*)buffer; while (size--) { write(*ch++); + n++; } + return n; } -void Print::print(uint8 b, int base) { +size_t Print::print(uint8 b, int base) { print((uint64)b, base); } -void Print::print(char c) { - write(c); +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); } -void Print::print(const char str[]) { - write(str); +size_t Print::print(char c) { + return write(c); } -void Print::print(int n, int base) { - print((long long)n, base); +size_t Print::print(const char str[]) { + return write(str); } -void Print::print(unsigned int n, int base) { - print((unsigned long long)n, base); +size_t Print::print(int n, int base) { + return print((long long)n, base); } -void Print::print(long n, int base) { - print((long long)n, base); +size_t Print::print(unsigned int n, int base) { + return print((unsigned long long)n, base); } -void Print::print(unsigned long n, int base) { - print((unsigned long long)n, base); +size_t Print::print(long n, int base) { + return print((long long)n, base); } -void Print::print(long long n, int base) { - if (base == BYTE) { - write((uint8)n); - return; +size_t Print::print(unsigned long n, int base) { + return print((unsigned long long)n, base); +} + +size_t Print::print(long long n, int base) { + if (base == BYTE) + { + return write((uint8)n); } if (n < 0) { print('-'); n = -n; } - printNumber(n, base); + return printNumber(n, base); } -void Print::print(unsigned long long n, int base) { +size_t Print::print(unsigned long long n, int base) { +size_t c=0; if (base == BYTE) { - write((uint8)n); + c= write((uint8)n); } else { - printNumber(n, base); + c= printNumber(n, base); } + return c; } -void Print::print(double n, int digits) { - printFloat(n, digits); +size_t Print::print(double n, int digits) { + return printFloat(n, digits); } -void Print::println(void) { - print('\r'); - print('\n'); +size_t Print::println(void) +{ + size_t n = print('\r'); + n += print('\n'); + return n; } -void Print::println(char c) { - print(c); - println(); +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; } -void Print::println(const char c[]) { - print(c); - println(); +size_t Print::println(char c) { + size_t n = print(c); + n += println(); + return n; } -void Print::println(uint8 b, int base) { - print(b, base); - println(); +size_t Print::println(const char c[]) { + size_t n = print(c); + n += println(); + return n; } -void Print::println(int n, int base) { - print(n, base); - println(); +size_t Print::println(uint8 b, int base) { + size_t n = print(b, base); + n += println(); + return n; } -void Print::println(unsigned int n, int base) { - print(n, base); - println(); +size_t Print::println(int n, int base) { + size_t s = print(n, base); + s += println(); + return s; } -void Print::println(long n, int base) { - print((long long)n, base); - println(); +size_t Print::println(unsigned int n, int base) { + size_t s = print(n, base); + s += println(); + return s; } -void Print::println(unsigned long n, int base) { - print((unsigned long long)n, base); - println(); +size_t Print::println(long n, int base) { + size_t s = print((long long)n, base); + s += println(); + return s; } -void Print::println(long long n, int base) { - print(n, base); - println(); +size_t Print::println(unsigned long n, int base) { + size_t s = print((unsigned long long)n, base); + s += println(); + return s; } -void Print::println(unsigned long long n, int base) { - print(n, base); - println(); +size_t Print::println(long long n, int base) { + size_t s = print(n, base); + s += println(); + return s; } -void Print::println(double n, int digits) { - print(n, digits); - println(); +size_t Print::println(unsigned long long n, int base) { + size_t s = print(n, base); + s += println(); + return s; } +size_t Print::println(double n, int digits) { + size_t s = print(n, digits); + s += println(); + return s; +} + +#ifdef SUPPORTS_PRINTF +#include +#include +// Work in progress to support printf. +// Need to implement stream FILE to write individual chars to chosen serial port +int Print::printf (__const char *__restrict __format, ...) + { +FILE *__restrict __stream; + int ret_status = 0; + + + va_list args; + va_start(args,__format); + ret_status = vfprintf(__stream, __format, args); + va_end(args); + return ret_status; + } + #endif + /* * Private methods */ -void Print::printNumber(unsigned long long n, uint8 base) { +size_t Print::printNumber(unsigned long long n, uint8 base) { unsigned char buf[CHAR_BIT * sizeof(long long)]; unsigned long i = 0; - + size_t s=0; if (n == 0) { print('0'); - return; + return 1; } while (n > 0) { @@ -185,12 +236,14 @@ void Print::printNumber(unsigned long long n, uint8 base) { } for (; i > 0; i--) { - print((char)(buf[i - 1] < 10 ? + s += print((char)(buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10)); } + return s; } + /* According to snprintf(), * * nextafter((double)numeric_limits::max(), 0.0) ~= 9.22337e+18 @@ -208,19 +261,20 @@ void Print::printNumber(unsigned long long n, uint8 base) { * * http://kurtstephens.com/files/p372-steele.pdf */ -void Print::printFloat(double number, uint8 digits) { +size_t Print::printFloat(double number, uint8 digits) { +size_t s=0; // Hackish fail-fast behavior for large-magnitude doubles if (abs(number) >= LARGE_DOUBLE_TRESHOLD) { if (number < 0.0) { - print('-'); + s=print('-'); } - print(""); - return; + s+=print(""); + return s; } // Handle negative numbers if (number < 0.0) { - print('-'); + s+=print('-'); number = -number; } @@ -235,18 +289,20 @@ void Print::printFloat(double number, uint8 digits) { // Extract the integer part of the number and print it long long int_part = (long long)number; double remainder = number - int_part; - print(int_part); + s+=print(int_part); // Print the decimal point, but only if there are digits beyond if (digits > 0) { - print("."); + s+=print("."); } // Extract digits from the remainder one at a time while (digits-- > 0) { remainder *= 10.0; int to_print = (int)remainder; - print(to_print); + s+=print(to_print); remainder -= to_print; } + return s; } + diff --git a/STM32F4/cores/maple/Print.h b/STM32F4/cores/maple/Print.h index c0c63cb..5961a02 100644 --- a/STM32F4/cores/maple/Print.h +++ b/STM32F4/cores/maple/Print.h @@ -20,10 +20,11 @@ * Modified 12 April 2011 by Marti Bolivar */ -#ifndef _PRINT_H_ -#define _PRINT_H_ +#ifndef _WIRISH_PRINT_H_ +#define _WIRISH_PRINT_H_ -#include "libmaple_types.h" +#include +#include "WString.h" enum { BYTE = 0, @@ -35,33 +36,49 @@ enum { class Print { public: - virtual void write(uint8 ch) = 0; - virtual void write(const char *str); - virtual void write(const void *buf, uint32 len); - void print(char); - void print(const char[]); - void print(uint8, 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(long long, int=DEC); - void print(unsigned long long, int=DEC); - void print(double, int=2); - void println(void); - void println(char); - void println(const char[]); - void println(uint8, 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(long long, int=DEC); - void println(unsigned long long, int=DEC); - void println(double, int=2); + virtual size_t write(uint8 ch) = 0; + virtual size_t write(const char *str); + virtual size_t write(const void *buf, uint32 len); + + size_t print(const String &); + size_t print(char); + size_t print(const char[]); + size_t print(uint8, 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(long long, int=DEC); + size_t print(unsigned long long, int=DEC); + size_t print(double, int=2); + size_t println(void); + size_t println(const String &s); + size_t println(char); + size_t println(const char[]); + size_t println(uint8, 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(long long, int=DEC); + size_t println(unsigned long long, int=DEC); + size_t println(double, int=2); +#ifdef SUPPORTS_PRINTF +// Roger Clark. Work in progress to add printf support + int printf(const char * format, ...); +#endif + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + protected: + void setWriteError(int err = 1) { write_error = err; } + private: - void printNumber(unsigned long long, uint8); - void printFloat(double, uint8); + int write_error; + size_t printNumber(unsigned long long, uint8); + size_t printFloat(double, uint8); }; #endif diff --git a/STM32F4/cores/maple/Stream.cpp b/STM32F4/cores/maple/Stream.cpp new file mode 100644 index 0000000..9c581be --- /dev/null +++ b/STM32F4/cores/maple/Stream.cpp @@ -0,0 +1,270 @@ +/* + 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 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 +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit() +{ + int c; + while (1) { + c = timedPeek(); + if (c < 0) return c; // timeout + if (c == '-') return c; + if (c >= '0' && c <= '9') return c; + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, (char*)""); +} + +// 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]) + index = 0; // reset index if any char does not match + + 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; + } + } + + 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 = peekNextDigit(); + // 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'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == skipChar ); + + if(isNegative) + value = -value; + return value; +} + + +// as parseInt but returns a floating point value +float Stream::parseFloat() +{ + return 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; + int c; + float fraction = 1.0; + + c = peekNextDigit(); + // 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; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + 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, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// 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) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + diff --git a/STM32F4/cores/maple/Stream.h b/STM32F4/cores/maple/Stream.h new file mode 100644 index 0000000..5cf5ddf --- /dev/null +++ b/STM32F4/cores/maple/Stream.h @@ -0,0 +1,102 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 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 + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#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 +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(); // 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=1000;} + +// parsing methods + + void setTimeout(unsigned 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 + bool find(uint8_t *target) { return find ((char *)target); } + // 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 + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // 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(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + + + 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. + + float parseFloat(); // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // 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) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // 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) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + 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(char skipChar); // as above but the given skipChar is ignored +}; + +#endif diff --git a/STM32F4/cores/maple/WString.cpp b/STM32F4/cores/maple/WString.cpp new file mode 100644 index 0000000..939ca0e --- /dev/null +++ b/STM32F4/cores/maple/WString.cpp @@ -0,0 +1,746 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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 "WString.h" +#include "itoa.h" +#include "avr/dtostrf.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +void String::move(String &rhs) +{ + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + 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 ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left > len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + 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; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + 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); + index--; + } + } +} + +void String::remove(unsigned int index){ + if (index >= len) { return; } + int count = len - index; + remove(index, count); +} + +void String::remove(unsigned int index, unsigned int count){ + if (index >= len) { return; } + if (count <= 0) { return; } + if (index + count > len) { count = len - index; } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count,len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + if (buffer) return float(atof(buffer)); + return 0; +} diff --git a/STM32F4/cores/maple/WString.h b/STM32F4/cores/maple/WString.h new file mode 100644 index 0000000..7402430 --- /dev/null +++ b/STM32F4/cores/maple/WString.h @@ -0,0 +1,224 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + 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 String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + const char * c_str() const { return buffer; } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #ifdef __GXX_EXPERIMENTAL_CXX0X__ + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/STM32F4/cores/maple/itoa.c b/STM32F4/cores/maple/itoa.c new file mode 100644 index 0000000..fc35766 --- /dev/null +++ b/STM32F4/cores/maple/itoa.c @@ -0,0 +1,170 @@ +/* + Copyright (c) 2011 Arduino. 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 "itoa.h" +#include + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#if 0 +/* reverse: reverse string s in place */ +static void reverse( char s[] ) +{ + int i, j ; + char c ; + + for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- ) + { + c = s[i] ; + s[i] = s[j] ; + s[j] = c ; + } +} + +/* itoa: convert n to characters in s */ +extern void itoa( int n, char s[] ) +{ + int i, sign ; + + if ( (sign = n) < 0 ) /* record sign */ + { + n = -n; /* make n positive */ + } + + i = 0; + do + { /* generate digits in reverse order */ + s[i++] = n % 10 + '0'; /* get next digit */ + } while ((n /= 10) > 0) ; /* delete it */ + + if (sign < 0 ) + { + s[i++] = '-'; + } + + s[i] = '\0'; + + reverse( s ) ; +} + +#else + +extern char* itoa( int value, char *string, int radix ) +{ + return ltoa( value, string, radix ) ; +} + +extern char* ltoa( long value, char *string, int radix ) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v; + int sign; + char *sp; + + if ( string == NULL ) + { + return 0 ; + } + + if (radix > 36 || radix <= 1) + { + return 0 ; + } + + sign = (radix == 10 && value < 0); + if (sign) + { + v = -value; + } + else + { + v = (unsigned long)value; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + if (sign) + *sp++ = '-'; + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} + +extern char* utoa( unsigned long value, char *string, int radix ) +{ + return ultoa( value, string, radix ) ; +} + +extern char* ultoa( unsigned long value, char *string, int radix ) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v = value; + char *sp; + + if ( string == NULL ) + { + return 0; + } + + if (radix > 36 || radix <= 1) + { + return 0; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} +#endif /* 0 */ + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/STM32F4/cores/maple/itoa.h b/STM32F4/cores/maple/itoa.h new file mode 100644 index 0000000..59af109 --- /dev/null +++ b/STM32F4/cores/maple/itoa.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2011 Arduino. 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 _ITOA_ +#define _ITOA_ + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#if 0 + +extern void itoa( int n, char s[] ) ; + +#else + +extern char* itoa( int value, char *string, int radix ) ; +extern char* ltoa( long value, char *string, int radix ) ; +extern char* utoa( unsigned long value, char *string, int radix ) ; +extern char* ultoa( unsigned long value, char *string, int radix ) ; +#endif /* 0 */ + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // _ITOA_ diff --git a/STM32F4/cores/maple/libmaple/HardwareSerial.cpp b/STM32F4/cores/maple/libmaple/HardwareSerial.cpp index a5669c0..a156770 100644 --- a/STM32F4/cores/maple/libmaple/HardwareSerial.cpp +++ b/STM32F4/cores/maple/libmaple/HardwareSerial.cpp @@ -140,8 +140,9 @@ uint32 HardwareSerial::pending(void) { return usart_data_pending(usart_device); } -void HardwareSerial::write(unsigned char ch) { +size_t HardwareSerial::write(unsigned char ch) { usart_putc(usart_device, ch); + return 1; } void HardwareSerial::flush(void) { diff --git a/STM32F4/cores/maple/libmaple/HardwareSerial.h b/STM32F4/cores/maple/libmaple/HardwareSerial.h index baf4a7c..9cad064 100644 --- a/STM32F4/cores/maple/libmaple/HardwareSerial.h +++ b/STM32F4/cores/maple/libmaple/HardwareSerial.h @@ -62,7 +62,7 @@ public: uint32 pending(void); int read(void); void flush(void); - virtual void write(unsigned char); + virtual size_t write(unsigned char); using Print::write; /* Pin accessors */ diff --git a/STM32F4/cores/maple/usb_serial.cpp b/STM32F4/cores/maple/usb_serial.cpp index 873e49d..71d3b37 100644 --- a/STM32F4/cores/maple/usb_serial.cpp +++ b/STM32F4/cores/maple/usb_serial.cpp @@ -50,18 +50,18 @@ void USBSerial::end(void) { disableUSB(); } -void USBSerial::write(uint8 ch) { +size_t USBSerial::write(uint8 ch) { const uint8 buf[] = {ch}; - this->write(buf, 1); + return this->write(buf, 1); } -void USBSerial::write(const char *str) { - this->write(str, strlen(str)); +size_t USBSerial::write(const char *str) { + return this->write(str, strlen(str)); } -void USBSerial::write(const void *buf, uint32 len) { +size_t USBSerial::write(const void *buf, uint32 len) { if (!(usbIsConnected() && usbIsConfigured()) || !buf) { - return; + return 0; } uint32 txed = 0; @@ -75,6 +75,7 @@ void USBSerial::write(const void *buf, uint32 len) { } old_txed = txed; } + return txed; } uint32 USBSerial::available(void) { diff --git a/STM32F4/cores/maple/usb_serial.h b/STM32F4/cores/maple/usb_serial.h index ce33302..44bd1e8 100644 --- a/STM32F4/cores/maple/usb_serial.h +++ b/STM32F4/cores/maple/usb_serial.h @@ -49,9 +49,9 @@ public: uint32 read(void *buf, uint32 len); uint8 read(void); - void write(uint8); - void write(const char *str); - void write(const void*, uint32); + size_t write(uint8); + size_t write(const char *str); + size_t write(const void*, uint32); uint8 getRTS(); uint8 getDTR(); diff --git a/STM32F4/cores/maple/wirish.h b/STM32F4/cores/maple/wirish.h index 6be8423..75d4aec 100644 --- a/STM32F4/cores/maple/wirish.h +++ b/STM32F4/cores/maple/wirish.h @@ -44,6 +44,7 @@ #include "wirish_debug.h" #include "wirish_math.h" #include "wirish_time.h" +#include #include "HardwareSPI.h" #include "HardwareSerial.h" #include "HardwareTimer.h" @@ -56,8 +57,6 @@ #define true 0x1 #define false 0x0 -#define LSBFIRST 0 -#define MSBFIRST 1 #define lowByte(w) ((w) & 0xFF) #define highByte(w) (((w) >> 8) & 0xFF) diff --git a/STM32F4/cores/maple/wirish_constants.h b/STM32F4/cores/maple/wirish_constants.h new file mode 100644 index 0000000..06a85ae --- /dev/null +++ b/STM32F4/cores/maple/wirish_constants.h @@ -0,0 +1,17 @@ +#ifndef _WIRING_CONSTANTS_ +#define _WIRING_CONSTANTS_ + +#ifdef __cplusplus +extern "C"{ +#endif + +enum BitOrder { + LSBFIRST = 0, + MSBFIRST = 1 +}; + +#ifdef __cplusplus +} +#endif + +#endif