Update Packages' Patches

This commit is contained in:
Khoi Hoang
2022-10-26 18:48:12 -04:00
committed by GitHub
parent a91b9a48be
commit 7b6913932c
63 changed files with 7347 additions and 5845 deletions

View File

@@ -1,129 +1,164 @@
/* /*
Stream.h - base class for character-based streams. Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. All right reserved. Copyright (c) 2010 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis parsing functions based on TextFinder library by Michael Margolis
*/ */
#ifndef Stream_h #ifndef Stream_h
#define Stream_h #define Stream_h
#include <inttypes.h> #include <inttypes.h>
#include "Print.h" #include "Print.h"
// compatability macros for testing // compatability macros for testing
/* /*
#define getInt() parseInt() #define getInt() parseInt()
#define getInt(ignore) parseInt(ignore) #define getInt(ignore) parseInt(ignore)
#define getFloat() parseFloat() #define getFloat() parseFloat()
#define getFloat(ignore) parseFloat(ignore) #define getFloat(ignore) parseFloat(ignore)
#define getString( pre_string, post_string, buffer, length) #define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length) readBytesBetween( pre_string, terminator, buffer, length)
*/ */
// This enumeration provides the lookahead options for parseInt(), parseFloat() // This enumeration provides the lookahead options for parseInt(), parseFloat()
// The rules set out here are used until either the first valid character is found // The rules set out here are used until either the first valid character is found
// or a time out occurs due to lack of input. // or a time out occurs due to lack of input.
enum LookaheadMode{ enum LookaheadMode
SKIP_ALL, // All invalid characters are ignored. {
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. SKIP_ALL, // All invalid characters are ignored.
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
}; SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
};
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
class Stream : public Print
{ class Stream : public Print
protected: {
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read protected:
unsigned long _startMillis = 0; // used for timeout measurement unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
int timedRead(); // read stream with timeout unsigned long _startMillis = 0; // used for timeout measurement
int timedPeek(); // peek stream with timeout int timedRead(); // read stream with timeout
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout int timedPeek(); // peek stream with timeout
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0; public:
virtual int read() = 0; virtual int available() = 0;
virtual int peek() = 0; virtual int read() = 0;
virtual int peek() = 0;
Stream() {_timeout=1000;}
Stream()
// parsing methods {
_timeout = 1000;
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second }
unsigned long getTimeout(void) { return _timeout; }
// parsing methods
bool find(char *target); // reads data from the stream until the target string is found
bool find(uint8_t *target) { return find ((char *)target); } void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
// returns true if target string is found, false if timed out (see setTimeout) unsigned long getTimeout(void)
{
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found return _timeout;
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 find(char *target); // reads data from the stream until the target string is found
bool find(char target) { return find (&target, 1); } bool find(uint8_t *target)
{
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found return find ((char *)target);
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } }
// returns true if target string is found, false if timed out (see setTimeout)
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); } 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)
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); {
// returns the first valid (long) integer value from the current position. return find ((char *)target, length);
// lookahead determines how parseInt looks ahead in the stream. }
// See LookaheadMode enumeration at the top of the file. // returns true if target string is found, false if timed out
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream. bool find(char target)
{
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); return find (&target, 1);
// float version of parseInt }
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } bool findUntil(uint8_t *target, char *terminator)
// 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) return findUntil((char *)target, terminator);
}
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); } bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
// terminates if length characters have been read, timeout, or if the terminator character detected bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen)
// returns the number of characters placed in the buffer (0 means no valid data found) {
return findUntil((char *)target, targetLen, terminate, termLen);
// Arduino String functions to be added here }
String readString();
String readStringUntil(char terminator); long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// returns the first valid (long) integer value from the current position.
protected: // lookahead determines how parseInt looks ahead in the stream.
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } // See LookaheadMode enumeration at the top of the file.
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } // Lookahead is terminated by the first character that is not a valid part of an integer.
// These overload exists for compatibility with any class that has derived // Once parsing commences, 'ignore' will be skipped in the stream.
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected. float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// float version of parseInt
struct MultiTarget {
const char *str; // string you're searching for size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t len; // length of string you're searching for size_t readBytes( uint8_t *buffer, size_t length)
size_t index; // index used by the search routine. {
}; return readBytes((char *)buffer, length);
}
// This allows you to search for an arbitrary number of strings. // terminates if length characters have been read or timeout (see setTimeout)
// Returns index of the target that is found first or -1 if timeout occurs. // returns the number of characters placed in the buffer (0 means no valid data found)
int findMulti(struct MultiTarget *targets, int tCount);
}; 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)
#undef NO_IGNORE_CHAR {
#endif 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 ignore)
{
return parseInt(SKIP_ALL, ignore);
}
float parseFloat(char ignore)
{
return parseFloat(SKIP_ALL, ignore);
}
// These overload exists for compatibility with any class that has derived
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected.
struct MultiTarget
{
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
};
#undef NO_IGNORE_CHAR
#endif

View File

@@ -1,129 +1,164 @@
/* /*
Stream.h - base class for character-based streams. Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. All right reserved. Copyright (c) 2010 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis parsing functions based on TextFinder library by Michael Margolis
*/ */
#ifndef Stream_h #ifndef Stream_h
#define Stream_h #define Stream_h
#include <inttypes.h> #include <inttypes.h>
#include "Print.h" #include "Print.h"
// compatability macros for testing // compatability macros for testing
/* /*
#define getInt() parseInt() #define getInt() parseInt()
#define getInt(ignore) parseInt(ignore) #define getInt(ignore) parseInt(ignore)
#define getFloat() parseFloat() #define getFloat() parseFloat()
#define getFloat(ignore) parseFloat(ignore) #define getFloat(ignore) parseFloat(ignore)
#define getString( pre_string, post_string, buffer, length) #define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length) readBytesBetween( pre_string, terminator, buffer, length)
*/ */
// This enumeration provides the lookahead options for parseInt(), parseFloat() // This enumeration provides the lookahead options for parseInt(), parseFloat()
// The rules set out here are used until either the first valid character is found // The rules set out here are used until either the first valid character is found
// or a time out occurs due to lack of input. // or a time out occurs due to lack of input.
enum LookaheadMode{ enum LookaheadMode
SKIP_ALL, // All invalid characters are ignored. {
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. SKIP_ALL, // All invalid characters are ignored.
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
}; SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
};
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
class Stream : public Print
{ class Stream : public Print
protected: {
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read protected:
unsigned long _startMillis = 0; // used for timeout measurement unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
int timedRead(); // read stream with timeout unsigned long _startMillis = 0; // used for timeout measurement
int timedPeek(); // peek stream with timeout int timedRead(); // read stream with timeout
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout int timedPeek(); // peek stream with timeout
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0; public:
virtual int read() = 0; virtual int available() = 0;
virtual int peek() = 0; virtual int read() = 0;
virtual int peek() = 0;
Stream() {_timeout=1000;}
Stream()
// parsing methods {
_timeout = 1000;
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second }
unsigned long getTimeout(void) { return _timeout; }
// parsing methods
bool find(char *target); // reads data from the stream until the target string is found
bool find(uint8_t *target) { return find ((char *)target); } void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
// returns true if target string is found, false if timed out (see setTimeout) unsigned long getTimeout(void)
{
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found return _timeout;
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 find(char *target); // reads data from the stream until the target string is found
bool find(char target) { return find (&target, 1); } bool find(uint8_t *target)
{
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found return find ((char *)target);
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } }
// returns true if target string is found, false if timed out (see setTimeout)
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); } 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)
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); {
// returns the first valid (long) integer value from the current position. return find ((char *)target, length);
// lookahead determines how parseInt looks ahead in the stream. }
// See LookaheadMode enumeration at the top of the file. // returns true if target string is found, false if timed out
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream. bool find(char target)
{
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); return find (&target, 1);
// float version of parseInt }
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } bool findUntil(uint8_t *target, char *terminator)
// 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) return findUntil((char *)target, terminator);
}
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); } bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
// terminates if length characters have been read, timeout, or if the terminator character detected bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen)
// returns the number of characters placed in the buffer (0 means no valid data found) {
return findUntil((char *)target, targetLen, terminate, termLen);
// Arduino String functions to be added here }
String readString();
String readStringUntil(char terminator); long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// returns the first valid (long) integer value from the current position.
protected: // lookahead determines how parseInt looks ahead in the stream.
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } // See LookaheadMode enumeration at the top of the file.
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } // Lookahead is terminated by the first character that is not a valid part of an integer.
// These overload exists for compatibility with any class that has derived // Once parsing commences, 'ignore' will be skipped in the stream.
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected. float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// float version of parseInt
struct MultiTarget {
const char *str; // string you're searching for size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t len; // length of string you're searching for size_t readBytes( uint8_t *buffer, size_t length)
size_t index; // index used by the search routine. {
}; return readBytes((char *)buffer, length);
}
// This allows you to search for an arbitrary number of strings. // terminates if length characters have been read or timeout (see setTimeout)
// Returns index of the target that is found first or -1 if timeout occurs. // returns the number of characters placed in the buffer (0 means no valid data found)
int findMulti(struct MultiTarget *targets, int tCount);
}; 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)
#undef NO_IGNORE_CHAR {
#endif 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 ignore)
{
return parseInt(SKIP_ALL, ignore);
}
float parseFloat(char ignore)
{
return parseFloat(SKIP_ALL, ignore);
}
// These overload exists for compatibility with any class that has derived
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected.
struct MultiTarget
{
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
};
#undef NO_IGNORE_CHAR
#endif

View File

@@ -0,0 +1,466 @@
/*
Copyright (c) 2014 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 <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "Arduino.h"
#include "Print.h"
//using namespace arduino;
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--)
{
if (write(*buffer++))
n++;
else
break;
}
return n;
}
size_t Print::print(const __FlashStringHelper *ifsh)
{
return print(reinterpret_cast<const char *>(ifsh));
}
size_t Print::print(const String &s)
{
return write(s.c_str(), s.length());
}
size_t Print::print(const char str[])
{
return write(str);
}
size_t Print::print(char c)
{
return write(c);
}
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, 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)
{
return write(n);
}
else if (base == 10)
{
if (n < 0)
{
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
if (base == 0)
return write(n);
else
return printNumber(n, base);
}
size_t Print::print(long long n, int base)
{
if (base == 0)
{
return write(n);
}
else if (base == 10)
{
if (n < 0)
{
int t = print('-');
n = -n;
return printULLNumber(n, 10) + t;
}
return printULLNumber(n, 10);
}
else
{
return printULLNumber(n, base);
}
}
size_t Print::print(unsigned long long n, int base)
{
if (base == 0)
return write(n);
else
return printULLNumber(n, base);
}
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void)
{
return write("\r\n");
}
size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}
size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long num, int base)
{
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(long long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long 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;
}
size_t Print::printf(const char * format, ...)
{
char buf[256];
int len;
va_list ap;
va_start(ap, format);
len = vsnprintf(buf, 256, format, ap);
this->write(buf, len);
va_end(ap);
return len;
}
// Private Methods /////////////////////////////////////////////////////////////
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];
*str = '\0';
// prevent crash if called with base == 1
if (base < 2)
base = 10;
do
{
char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while (n);
return write(str);
}
// REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// {
// // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65];
// char *str = &buf[64];
// *str = '\0';
// // prevent crash if called with base == 1
// if (base < 2) base = 10;
// do {
// unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base;
// n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n);
// return write(str);
// }
// FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{
// if limited to base 10 and 16 the bufsize can be 20
char buf[64];
uint8_t i = 0;
uint8_t innerLoops = 0;
// prevent crash if called with base == 1
if (base < 2)
base = 10;
// process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base;
uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}
while (n64 > th16)
{
// 64 bit math part
uint64_t q = n64 / th16;
uint16_t r = n64 - q * th16;
n64 = q;
// 16 bit math loop to do remainder. (note buffer is filled reverse)
for (uint8_t j = 0; j < innerLoops; j++)
{
uint16_t qq = r / base;
buf[i++] = r - qq * base;
r = qq;
}
}
uint16_t n16 = n64;
while (n16 > 0)
{
uint16_t qq = n16 / base;
buf[i++] = n16 - qq * base;
n16 = qq;
}
size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes;
}
size_t Print::printFloat(double number, int digits)
{
if (digits < 0)
digits = 2;
size_t n = 0;
if (isnan(number))
return print("nan");
if (isinf(number))
return print("inf");
if (number > 4294967040.0)
return print ("ovf"); // constant determined empirically
if (number < -4294967040.0)
return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i = 0; i < digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
}
size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline)
{
if (buffer == NULL || len == 0)
return 0;
for (int i = 0; i < len; i++)
{
if ( i != 0 )
print(delim);
if ( byteline && (i % byteline == 0) )
println();
this->printf("%02X", buffer[i]);
}
return (len * 3 - 1);
}
size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline)
{
if (buffer == NULL || len == 0)
return 0;
for (int i = 0; i < len; i++)
{
if (i != 0)
print(delim);
if ( byteline && (i % byteline == 0) )
println();
this->printf("%02X", buffer[len - 1 - i]);
}
return (len * 3 - 1);
}

View File

@@ -0,0 +1,123 @@
/*
Copyright (c) 2016 Arduino LLC. 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
*/
#pragma once
#include <inttypes.h>
#include <stdio.h> // for size_t
#include "WString.h"
#include "Printable.h"
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
class Print
{
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int);
protected:
void setWriteError(int err = 1)
{
write_error = err;
}
public:
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)
{
if (str == NULL)
return 0;
return write((const uint8_t *)str, strlen(str));
}
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block"
// should be overridden by subclasses with buffering
virtual int availableForWrite()
{
return 0;
}
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(long long, int = DEC);
size_t print(unsigned long long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
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(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBufferReverse(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline);
}
virtual void flush() { /* Empty implementation for backward compatibility */ }
};

View File

@@ -0,0 +1,99 @@
/*
Udp.cpp: Library to send/receive UDP packets.
NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
1) UDP does not guarantee the order in which assembled UDP packets are received. This
might not happen often in practice, but in larger network topologies, a UDP
packet can be received out of sequence.
2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
aware of it. Again, this may not be a concern in practice on small local networks.
For more information, see http://www.cafeaulait.org/course/week12/35.html
MIT License:
Copyright (c) 2008 Bjoern Hartmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
bjoern@cs.stanford.edu 12/30/2008
*/
#ifndef udp_h
#define udp_h
#include <Stream.h>
#include <IPAddress.h>
class UDP : public Stream
{
public:
virtual uint8_t begin(uint16_t) = 0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
// KH, add virtual function to support Multicast, necessary for many services (MDNS, UPnP, etc.)
virtual uint8_t beginMulticast(IPAddress, uint16_t)
{
return 0; // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure
}
virtual void stop() = 0; // Finish with the UDP socket
// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) = 0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) = 0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() = 0;
// Write a single byte into the packet
virtual size_t write(uint8_t) = 0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket() = 0;
// Number of bytes remaining in the current packet
virtual int available() = 0;
// Read a single byte from the current packet
virtual int read() = 0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) = 0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) = 0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() = 0;
virtual void flush() = 0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() = 0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr)
{
return addr.raw_address();
};
};
#endif

View File

@@ -0,0 +1,163 @@
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
# Copyright (c) 2016 Sandeep Mistry All right reserved.
# Copyright (c) 2017 Adafruit Industries. All rights 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
name=Seeed nRF52 Boards
version=1.0.0
# Compile variables
# -----------------
compiler.warning_flags=-Werror=return-type
compiler.warning_flags.none=-Werror=return-type
compiler.warning_flags.default=-Werror=return-type
compiler.warning_flags.more=-Wall -Werror=return-type
compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-unused-parameter -Wno-missing-field-initializers -Wno-pointer-arith
# Allow changing optimization settings via platform.local.txt / boards.local.txt
compiler.optimization_flag=-Ofast
compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
compiler.c.cmd=arm-none-eabi-gcc
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g {compiler.warning_flags} {build.float_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD
# KH, Error here to use gcc, must use g++
#compiler.c.elf.cmd=arm-none-eabi-gcc
compiler.c.elf.cmd=arm-none-eabi-g++
compiler.c.elf.flags={compiler.optimization_flag} -Wl,--gc-sections -save-temps
compiler.S.cmd=arm-none-eabi-gcc
compiler.S.flags=-mcpu={build.mcu} -mthumb -mabi=aapcs {compiler.optimization_flag} -g -c {build.float_flags} -x assembler-with-cpp
compiler.cpp.cmd=arm-none-eabi-g++
compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g {compiler.warning_flags} {build.float_flags} -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD
compiler.ar.cmd=arm-none-eabi-ar
compiler.ar.flags=rcs
compiler.objcopy.cmd=arm-none-eabi-objcopy
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
compiler.elf2bin.flags=-O binary
compiler.elf2bin.cmd=arm-none-eabi-objcopy
compiler.elf2hex.flags=-O ihex
compiler.elf2hex.cmd=arm-none-eabi-objcopy
compiler.ldflags=-mcpu={build.mcu} -mthumb {build.float_flags} -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--wrap=malloc -Wl,--wrap=free --specs=nano.specs --specs=nosys.specs
compiler.size.cmd=arm-none-eabi-size
# this can be overriden in boards.txt
# Logger 0: Serial (CDC), 1 Serial1 (UART), 2 Segger RTT
build.float_flags=-mfloat-abi=hard -mfpu=fpv4-sp-d16 -u _printf_float
build.debug_flags=-DCFG_DEBUG=0
build.logger_flags=-DCFG_LOGGER=0
build.sysview_flags=-DCFG_SYSVIEW=0
# USB flags
build.flags.usb= -DUSBCON -DUSE_TINYUSB -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
compiler.cpp.extra_flags=
compiler.S.extra_flags=
compiler.ar.extra_flags=
compiler.libraries.ldflags=
compiler.elf2bin.extra_flags=
compiler.elf2hex.extra_flags=
compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.7.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.7.0.path}/CMSIS/DSP/Include/"
compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.7.0.path}/CMSIS/DSP/Lib/GCC/" -larm_cortexM4lf_math
# common compiler for nrf
rtos.path={build.core.path}/freertos
nordic.path={build.core.path}/nordic
build.flags.nrf= -DSOFTDEVICE_PRESENT -DARDUINO_NRF52_ADAFRUIT -DNRF52_SERIES -DDX_CC_TEE -DLFS_NAME_MAX=64 {compiler.optimization_flag} {build.debug_flags} {build.logger_flags} {build.sysview_flags} {compiler.arm.cmsis.c.flags} "-I{nordic.path}" "-I{nordic.path}/nrfx" "-I{nordic.path}/nrfx/hal" "-I{nordic.path}/nrfx/mdk" "-I{nordic.path}/nrfx/soc" "-I{nordic.path}/nrfx/drivers/include" "-I{nordic.path}/nrfx/drivers/src" "-I{nordic.path}/softdevice/{build.sd_name}_nrf52_{build.sd_version}_API/include" "-I{nordic.path}/softdevice/{build.sd_name}_nrf52_{build.sd_version}_API/include/nrf52" "-I{rtos.path}/Source/include" "-I{rtos.path}/config" "-I{rtos.path}/portable/GCC/nrf52" "-I{rtos.path}/portable/CMSIS/nrf52" "-I{build.core.path}/sysview/SEGGER" "-I{build.core.path}/sysview/Config" "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"
# Compile patterns
# ----------------
## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} '-DARDUINO_BSP_VERSION="{version}"' {compiler.c.extra_flags} {build.extra_flags} {build.flags.nrf} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} '-DARDUINO_BSP_VERSION="{version}"' {compiler.cpp.extra_flags} {build.extra_flags} {build.flags.nrf} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.flags.nrf} {includes} "{source_file}" -o "{object_file}"
## Create archives
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-L{build.core.path}/linker" "-T{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group {compiler.arm.cmsis.ldflags} -lm "{build.path}/{archive_file}" {compiler.libraries.ldflags} -Wl,--end-group
## Create output (bin file)
#recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2bin.cmd}" {compiler.elf2bin.flags} {compiler.elf2bin.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
## Create output (hex file)
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
## Create dfu package zip file
recipe.objcopy.zip.pattern="{tools.nrfutil.cmd}" dfu genpkg --dev-type 0x0052 --sd-req {build.sd_fwid} --application "{build.path}/{build.project_name}.hex" "{build.path}/{build.project_name}.zip"
## Create uf2 file
#recipe.objcopy.uf2.pattern=python "{runtime.platform.path}/tools/uf2conv/uf2conv.py" -f 0xADA52840 -c -o "{build.path}/{build.project_name}.uf2" "{build.path}/{build.project_name}.hex"
## Save bin
recipe.output.tmp_file_bin={build.project_name}.bin
recipe.output.save_file_bin={build.project_name}.save.bin
## Save hex
recipe.output.tmp_file_hex={build.project_name}.hex
recipe.output.save_file_hexu={build.project_name}.save.hex
## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=^(?:\.text|\.data|)\s+([0-9]+).*
recipe.size.regex.data=^(?:\.data|\.bss)\s+([0-9]+).*
## Export Compiled Binary
recipe.output.tmp_file={build.project_name}.hex
recipe.output.save_file={build.project_name}.{build.variant}.hex
#***************************************************
# adafruit-nrfutil for uploading
# https://github.com/adafruit/Adafruit_nRF52_nrfutil
# pre-built binaries are provided for macos and windows
#***************************************************
tools.nrfutil.cmd=adafruit-nrfutil
tools.nrfutil.cmd.windows={runtime.platform.path}/tools/adafruit-nrfutil/win32/adafruit-nrfutil.exe
tools.nrfutil.cmd.macosx={runtime.platform.path}/tools/adafruit-nrfutil/macos/adafruit-nrfutil
tools.nrfutil.upload.params.verbose=--verbose
tools.nrfutil.upload.params.quiet=
tools.nrfutil.upload.pattern="{cmd}" {upload.verbose} dfu serial -pkg "{build.path}/{build.project_name}.zip" -p {serial.port} -b 115200 --singlebank
#***************************************************
# Burning bootloader with either jlink or nrfutil
#***************************************************
# Bootloader version
tools.bootburn.bootloader.file={runtime.platform.path}/bootloader/{build.variant}/{build.variant}_bootloader-0.6.2_{build.sd_name}_{build.sd_version}
tools.bootburn.bootloader.params.verbose=
tools.bootburn.bootloader.params.quiet=
tools.bootburn.bootloader.pattern={program.burn_pattern}
# erase flash page while programming
tools.bootburn.erase.params.verbose=
tools.bootburn.erase.params.quiet=
tools.bootburn.erase.pattern=

View File

@@ -53,7 +53,7 @@ static const int A2 = PIN_A2;
static const int A3 = PIN_A3; static const int A3 = PIN_A3;
// D0 - D10 // D0 - D10
#define D26 (26u) #define D26 (26u)
#define D1 (27u) #define D1 (27u)
#define D2 (28u) #define D2 (28u)
#define D3 (29u) #define D3 (29u)

View File

@@ -6,7 +6,7 @@
#define __PINS_ARDUINO__ #define __PINS_ARDUINO__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" unsigned int PINCOUNT_fn(); extern "C" unsigned int PINCOUNT_fn();
#endif #endif
// Pin count // Pin count
@@ -25,7 +25,7 @@ extern PinName digitalPinToPinName(pin_size_t P);
// Digital pins // Digital pins
// ---- // ----
#define PIN_D0 (26u) #define PIN_D0 (26u)
#define PIN_D1 (27u) #define PIN_D1 (27u)
#define PIN_D2 (28u) #define PIN_D2 (28u)
#define PIN_D3 (29u) #define PIN_D3 (29u)
@@ -89,35 +89,35 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SDA (6u) #define SDA (6u)
#define SCL (7u) #define SCL (7u)
#define SERIAL_HOWMANY 1 #define SERIAL_HOWMANY 1
#define SERIAL1_TX (digitalPinToPinName(PIN_SERIAL_TX)) #define SERIAL1_TX (digitalPinToPinName(PIN_SERIAL_TX))
#define SERIAL1_RX (digitalPinToPinName(PIN_SERIAL_RX)) #define SERIAL1_RX (digitalPinToPinName(PIN_SERIAL_RX))
#define SERIAL_CDC 1 #define SERIAL_CDC 1
#define HAS_UNIQUE_ISERIAL_DESCRIPTOR #define HAS_UNIQUE_ISERIAL_DESCRIPTOR
#define BOARD_VENDORID 0x2886 #define BOARD_VENDORID 0x2886
#define BOARD_PRODUCTID 0x8042 #define BOARD_PRODUCTID 0x8042
#define BOARD_NAME "RaspberryPi Pico" #define BOARD_NAME "RaspberryPi Pico"
uint8_t getUniqueSerialNumber(uint8_t* name); uint8_t getUniqueSerialNumber(uint8_t* name);
void _ontouch1200bps_(); void _ontouch1200bps_();
#define SPI_HOWMANY (1) #define SPI_HOWMANY (1)
#define SPI_MISO (digitalPinToPinName(PIN_SPI_MISO)) #define SPI_MISO (digitalPinToPinName(PIN_SPI_MISO))
#define SPI_MOSI (digitalPinToPinName(PIN_SPI_MOSI)) #define SPI_MOSI (digitalPinToPinName(PIN_SPI_MOSI))
#define SPI_SCK (digitalPinToPinName(PIN_SPI_SCK)) #define SPI_SCK (digitalPinToPinName(PIN_SPI_SCK))
#define WIRE_HOWMANY (1) #define WIRE_HOWMANY (1)
#define I2C_SDA (digitalPinToPinName(SDA)) #define I2C_SDA (digitalPinToPinName(SDA))
#define I2C_SCL (digitalPinToPinName(SCL)) #define I2C_SCL (digitalPinToPinName(SCL))
#define digitalPinToPort(P) (digitalPinToPinName(P)/32) #define digitalPinToPort(P) (digitalPinToPinName(P)/32)
#define SERIAL_PORT_USBVIRTUAL SerialUSB #define SERIAL_PORT_USBVIRTUAL SerialUSB
#define SERIAL_PORT_MONITOR SerialUSB #define SERIAL_PORT_MONITOR SerialUSB
#define SERIAL_PORT_HARDWARE Serial1 #define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1 #define SERIAL_PORT_HARDWARE_OPEN Serial1
#define USB_MAX_POWER (500) #define USB_MAX_POWER (500)
#endif //__PINS_ARDUINO__ #endif //__PINS_ARDUINO__

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -76,16 +76,16 @@ int __debug_buf(const char* head, char* buf, int len);
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -100,25 +100,25 @@ int __debug_buf(const char* head, char* buf, int len);
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#ifdef __cplusplus #ifdef __cplusplus
template<class T, class L> template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (b < a) ? b : a; return (b < a) ? b : a;
} }
template<class T, class L> template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (a < b) ? b : a; return (a < b) ? b : a;
} }
#else #else
#ifndef min #ifndef min
#define min(a,b) \ #define min(a,b) \
@@ -147,8 +147,8 @@ int __debug_buf(const char* head, char* buf, int len);
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused)); static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void) static inline unsigned char __interruptsStatus(void)
{ {
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html // See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html
return (__get_PRIMASK() ? 0 : 1); return (__get_PRIMASK() ? 0 : 1);
} }
#define interruptsStatus() __interruptsStatus() #define interruptsStatus() __interruptsStatus()
#endif #endif
@@ -164,18 +164,18 @@ static inline unsigned char __interruptsStatus(void)
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// USB // USB
#ifdef USE_TINYUSB #ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_Core.h" #include "Adafruit_TinyUSB_Core.h"
#else #else
#include "USB/USBDesc.h" #include "USB/USBDesc.h"
#include "USB/USBCore.h" #include "USB/USBCore.h"
#include "USB/USBAPI.h" #include "USB/USBAPI.h"
#include "USB/USB_host.h" #include "USB/USB_host.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -35,386 +35,432 @@
/* default implementation: may be overridden */ /* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::write(const uint8_t *buffer, size_t size)
{ {
size_t n = 0; size_t n = 0;
while (size--) {
if (write(*buffer++)) n++; while (size--)
else break; {
} if (write(*buffer++))
return n; n++;
else
break;
}
return n;
} }
size_t Print::print(const __FlashStringHelper *ifsh) size_t Print::print(const __FlashStringHelper *ifsh)
{ {
return print(reinterpret_cast<const char *>(ifsh)); return print(reinterpret_cast<const char *>(ifsh));
} }
size_t Print::print(const String &s) size_t Print::print(const String &s)
{ {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
size_t Print::print(const char str[]) size_t Print::print(const char str[])
{ {
return write(str); return write(str);
} }
size_t Print::print(char c) size_t Print::print(char c)
{ {
return write(c); return write(c);
} }
size_t Print::print(unsigned char b, int base) size_t Print::print(unsigned char b, int base)
{ {
return print((unsigned long) b, base); return print((unsigned long) b, base);
} }
size_t Print::print(int n, int base) size_t Print::print(int n, int base)
{ {
return print((long) n, base); return print((long) n, base);
} }
size_t Print::print(unsigned int n, int base) size_t Print::print(unsigned int n, int base)
{ {
return print((unsigned long) n, base); return print((unsigned long) n, base);
} }
size_t Print::print(long n, int base) size_t Print::print(long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printNumber(n, 10) + t; if (n < 0)
} {
return printNumber(n, 10); int t = print('-');
} else { n = -n;
return printNumber(n, base); return printNumber(n, 10) + t;
} }
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
} }
size_t Print::print(unsigned long n, int base) size_t Print::print(unsigned long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printNumber(n, base); return write(n);
else
return printNumber(n, base);
} }
size_t Print::print(long long n, int base) size_t Print::print(long long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printULLNumber(n, 10) + t; if (n < 0)
} {
return printULLNumber(n, 10); int t = print('-');
} else { n = -n;
return printULLNumber(n, base); return printULLNumber(n, 10) + t;
} }
return printULLNumber(n, 10);
}
else
{
return printULLNumber(n, base);
}
} }
size_t Print::print(unsigned long long n, int base) size_t Print::print(unsigned long long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printULLNumber(n, base); return write(n);
else
return printULLNumber(n, base);
} }
size_t Print::print(double n, int digits) size_t Print::print(double n, int digits)
{ {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::println(const __FlashStringHelper *ifsh) size_t Print::println(const __FlashStringHelper *ifsh)
{ {
size_t n = print(ifsh); size_t n = print(ifsh);
n += println(); n += println();
return n; return n;
} }
size_t Print::print(const Printable& x) size_t Print::print(const Printable& x)
{ {
return x.printTo(*this); return x.printTo(*this);
} }
size_t Print::println(void) size_t Print::println(void)
{ {
return write("\r\n"); return write("\r\n");
} }
size_t Print::println(const String &s) size_t Print::println(const String &s)
{ {
size_t n = print(s); size_t n = print(s);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const char c[]) size_t Print::println(const char c[])
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(char c) size_t Print::println(char c)
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned char b, int base) size_t Print::println(unsigned char b, int base)
{ {
size_t n = print(b, base); size_t n = print(b, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(int num, int base) size_t Print::println(int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned int num, int base) size_t Print::println(unsigned int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long num, int base) size_t Print::println(long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long num, int base) size_t Print::println(unsigned long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long long num, int base) size_t Print::println(long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long long num, int base) size_t Print::println(unsigned long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(double num, int digits) size_t Print::println(double num, int digits)
{ {
size_t n = print(num, digits); size_t n = print(num, digits);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const Printable& x) size_t Print::println(const Printable& x)
{ {
size_t n = print(x); size_t n = print(x);
n += println(); n += println();
return n; return n;
} }
size_t Print::printf(const char * format, ...) size_t Print::printf(const char * format, ...)
{ {
char buf[256]; char buf[256];
int len; int len;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
len = vsnprintf(buf, 256, format, ap); len = vsnprintf(buf, 256, format, ap);
this->write(buf, len); this->write(buf, len);
va_end(ap); va_end(ap);
return len; return len;
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
size_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 buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; char *str = &buf[sizeof(buf) - 1];
*str = '\0'; *str = '\0';
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
do { do
char c = n % base; {
n /= base; char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10; *--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n); } while (n);
return write(str); return write(str);
} }
// REFERENCE IMPLEMENTATION FOR ULL // REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base) // size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// { // {
// // if limited to base 10 and 16 the bufsize can be smaller // // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65]; // char buf[65];
// char *str = &buf[64]; // char *str = &buf[64];
// *str = '\0'; // *str = '\0';
// // prevent crash if called with base == 1 // // prevent crash if called with base == 1
// if (base < 2) base = 10; // if (base < 2) base = 10;
// do { // do {
// unsigned long long t = n / base; // unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base; // char c = n - t * base; // faster than c = n%base;
// n = t; // n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10; // *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n); // } while(n);
// return write(str); // return write(str);
// } // }
// FAST IMPLEMENTATION FOR ULL // FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base) size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{ {
// if limited to base 10 and 16 the bufsize can be 20 // if limited to base 10 and 16 the bufsize can be 20
char buf[64]; char buf[64];
uint8_t i = 0; uint8_t i = 0;
uint8_t innerLoops = 0; uint8_t innerLoops = 0;
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
// process chunks that fit in "16 bit math". // process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base; uint16_t top = 0xFFFF / base;
uint16_t th16 = 1; uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}
while (n64 > th16) while (th16 < top)
{ {
// 64 bit math part th16 *= base;
uint64_t q = n64 / th16; innerLoops++;
uint16_t r = n64 - q*th16; }
n64 = q;
// 16 bit math loop to do remainder. (note buffer is filled reverse) while (n64 > th16)
for (uint8_t j=0; j < innerLoops; j++) {
{ // 64 bit math part
uint16_t qq = r/base; uint64_t q = n64 / th16;
buf[i++] = r - qq*base; uint16_t r = n64 - q * th16;
r = qq; n64 = q;
}
}
uint16_t n16 = n64; // 16 bit math loop to do remainder. (note buffer is filled reverse)
while (n16 > 0) for (uint8_t j = 0; j < innerLoops; j++)
{ {
uint16_t qq = n16/base; uint16_t qq = r / base;
buf[i++] = n16 - qq*base; buf[i++] = r - qq * base;
n16 = qq; r = qq;
} }
}
size_t bytes = i; uint16_t n16 = n64;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes; while (n16 > 0)
{
uint16_t qq = n16 / base;
buf[i++] = n16 - qq * base;
n16 = qq;
}
size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes;
} }
size_t Print::printFloat(double number, int digits) size_t Print::printFloat(double number, int digits)
{ {
if (digits < 0) if (digits < 0)
digits = 2; digits = 2;
size_t n = 0; size_t n = 0;
if (isnan(number)) return print("nan"); if (isnan(number))
if (isinf(number)) return print("inf"); return print("nan");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers if (isinf(number))
if (number < 0.0) return print("inf");
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00" if (number > 4294967040.0)
double rounding = 0.5; return print ("ovf"); // constant determined empirically
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding; if (number < -4294967040.0)
return print ("ovf"); // constant determined empirically
// Extract the integer part of the number and print it // Handle negative numbers
unsigned long int_part = (unsigned long)number; if (number < 0.0)
double remainder = number - (double)int_part; {
n += print(int_part); n += print('-');
number = -number;
}
// Print the decimal point, but only if there are digits beyond // Round correctly so that print(1.999, 2) prints as "2.00"
if (digits > 0) { double rounding = 0.5;
n += print(".");
}
// Extract digits from the remainder one at a time for (uint8_t i = 0; i < digits; ++i)
while (digits-- > 0) rounding /= 10.0;
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n; number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
} }
size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if ( i != 0 ) print(delim); if ( i != 0 )
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[i]);
}
return (len * 3 - 1);
} }
size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if (i != 0) print(delim); if (i != 0)
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[len-1-i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[len - 1 - i]);
}
return (len * 3 - 1);
} }

View File

@@ -32,77 +32,93 @@
class Print class Print
{ {
private: private:
int write_error; int write_error;
size_t printNumber(unsigned long, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t); size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int); size_t printFloat(double, int);
protected: protected:
void setWriteError(int err = 1) { write_error = err; } void setWriteError(int err = 1)
public: {
Print() : write_error(0) {} write_error = err;
}
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; } int getWriteError()
void clearWriteError() { setWriteError(0); } {
return write_error;
}
void clearWriteError()
{
setWriteError(0);
}
virtual size_t write(uint8_t) = 0; virtual size_t write(uint8_t) = 0;
size_t write(const char *str) { size_t write(const char *str)
if (str == NULL) return 0; {
return write((const uint8_t *)str, strlen(str)); if (str == NULL)
} return 0;
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block" return write((const uint8_t *)str, strlen(str));
// should be overridden by subclasses with buffering }
virtual int availableForWrite() { return 0; } virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
size_t print(const __FlashStringHelper *); // default to zero, meaning "a single write may block"
size_t print(const String &); // should be overridden by subclasses with buffering
size_t print(const char[]); virtual int availableForWrite()
size_t print(char); {
size_t print(unsigned char, int = DEC); return 0;
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 print(const Printable&);
size_t println(const __FlashStringHelper *); size_t print(const __FlashStringHelper *);
size_t println(const String &s); size_t print(const String &);
size_t println(const char[]); size_t print(const char[]);
size_t println(char); size_t print(char);
size_t println(unsigned char, int = DEC); size_t print(unsigned char, int = DEC);
size_t println(int, int = DEC); size_t print(int, int = DEC);
size_t println(unsigned int, int = DEC); size_t print(unsigned int, int = DEC);
size_t println(long, int = DEC); size_t print(long, int = DEC);
size_t println(unsigned long, int = DEC); size_t print(unsigned long, int = DEC);
size_t println(long long, int = DEC); size_t print(long long, int = DEC);
size_t println(unsigned long long, int = DEC); size_t print(unsigned long long, int = DEC);
size_t println(double, int = 2); size_t print(double, int = 2);
size_t println(const Printable&); size_t print(const Printable&);
size_t println(void);
size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim=' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim=' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim=' ', int byteline = 0); size_t println(const __FlashStringHelper *);
size_t printBufferReverse(char const buffer[], int size, char delim=' ', int byteline = 0) size_t println(const String &s);
{ size_t println(const char[]);
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline); 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(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ } size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBufferReverse(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline);
}
virtual void flush() { /* Empty implementation for backward compatibility */ }
}; };

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -76,16 +76,16 @@ int __debug_buf(const char* head, char* buf, int len);
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -100,25 +100,25 @@ int __debug_buf(const char* head, char* buf, int len);
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#ifdef __cplusplus #ifdef __cplusplus
template<class T, class L> template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (b < a) ? b : a; return (b < a) ? b : a;
} }
template<class T, class L> template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (a < b) ? b : a; return (a < b) ? b : a;
} }
#else #else
#ifndef min #ifndef min
#define min(a,b) \ #define min(a,b) \
@@ -147,8 +147,8 @@ int __debug_buf(const char* head, char* buf, int len);
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused)); static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void) static inline unsigned char __interruptsStatus(void)
{ {
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html // See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html
return (__get_PRIMASK() ? 0 : 1); return (__get_PRIMASK() ? 0 : 1);
} }
#define interruptsStatus() __interruptsStatus() #define interruptsStatus() __interruptsStatus()
#endif #endif
@@ -164,18 +164,18 @@ static inline unsigned char __interruptsStatus(void)
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// USB // USB
#ifdef USE_TINYUSB #ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_Core.h" #include "Adafruit_TinyUSB_Core.h"
#else #else
#include "USB/USBDesc.h" #include "USB/USBDesc.h"
#include "USB/USBCore.h" #include "USB/USBCore.h"
#include "USB/USBAPI.h" #include "USB/USBAPI.h"
#include "USB/USB_host.h" #include "USB/USB_host.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -35,386 +35,432 @@
/* default implementation: may be overridden */ /* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::write(const uint8_t *buffer, size_t size)
{ {
size_t n = 0; size_t n = 0;
while (size--) {
if (write(*buffer++)) n++; while (size--)
else break; {
} if (write(*buffer++))
return n; n++;
else
break;
}
return n;
} }
size_t Print::print(const __FlashStringHelper *ifsh) size_t Print::print(const __FlashStringHelper *ifsh)
{ {
return print(reinterpret_cast<const char *>(ifsh)); return print(reinterpret_cast<const char *>(ifsh));
} }
size_t Print::print(const String &s) size_t Print::print(const String &s)
{ {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
size_t Print::print(const char str[]) size_t Print::print(const char str[])
{ {
return write(str); return write(str);
} }
size_t Print::print(char c) size_t Print::print(char c)
{ {
return write(c); return write(c);
} }
size_t Print::print(unsigned char b, int base) size_t Print::print(unsigned char b, int base)
{ {
return print((unsigned long) b, base); return print((unsigned long) b, base);
} }
size_t Print::print(int n, int base) size_t Print::print(int n, int base)
{ {
return print((long) n, base); return print((long) n, base);
} }
size_t Print::print(unsigned int n, int base) size_t Print::print(unsigned int n, int base)
{ {
return print((unsigned long) n, base); return print((unsigned long) n, base);
} }
size_t Print::print(long n, int base) size_t Print::print(long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printNumber(n, 10) + t; if (n < 0)
} {
return printNumber(n, 10); int t = print('-');
} else { n = -n;
return printNumber(n, base); return printNumber(n, 10) + t;
} }
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
} }
size_t Print::print(unsigned long n, int base) size_t Print::print(unsigned long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printNumber(n, base); return write(n);
else
return printNumber(n, base);
} }
size_t Print::print(long long n, int base) size_t Print::print(long long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printULLNumber(n, 10) + t; if (n < 0)
} {
return printULLNumber(n, 10); int t = print('-');
} else { n = -n;
return printULLNumber(n, base); return printULLNumber(n, 10) + t;
} }
return printULLNumber(n, 10);
}
else
{
return printULLNumber(n, base);
}
} }
size_t Print::print(unsigned long long n, int base) size_t Print::print(unsigned long long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printULLNumber(n, base); return write(n);
else
return printULLNumber(n, base);
} }
size_t Print::print(double n, int digits) size_t Print::print(double n, int digits)
{ {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::println(const __FlashStringHelper *ifsh) size_t Print::println(const __FlashStringHelper *ifsh)
{ {
size_t n = print(ifsh); size_t n = print(ifsh);
n += println(); n += println();
return n; return n;
} }
size_t Print::print(const Printable& x) size_t Print::print(const Printable& x)
{ {
return x.printTo(*this); return x.printTo(*this);
} }
size_t Print::println(void) size_t Print::println(void)
{ {
return write("\r\n"); return write("\r\n");
} }
size_t Print::println(const String &s) size_t Print::println(const String &s)
{ {
size_t n = print(s); size_t n = print(s);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const char c[]) size_t Print::println(const char c[])
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(char c) size_t Print::println(char c)
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned char b, int base) size_t Print::println(unsigned char b, int base)
{ {
size_t n = print(b, base); size_t n = print(b, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(int num, int base) size_t Print::println(int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned int num, int base) size_t Print::println(unsigned int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long num, int base) size_t Print::println(long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long num, int base) size_t Print::println(unsigned long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long long num, int base) size_t Print::println(long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long long num, int base) size_t Print::println(unsigned long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(double num, int digits) size_t Print::println(double num, int digits)
{ {
size_t n = print(num, digits); size_t n = print(num, digits);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const Printable& x) size_t Print::println(const Printable& x)
{ {
size_t n = print(x); size_t n = print(x);
n += println(); n += println();
return n; return n;
} }
size_t Print::printf(const char * format, ...) size_t Print::printf(const char * format, ...)
{ {
char buf[256]; char buf[256];
int len; int len;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
len = vsnprintf(buf, 256, format, ap); len = vsnprintf(buf, 256, format, ap);
this->write(buf, len); this->write(buf, len);
va_end(ap); va_end(ap);
return len; return len;
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
size_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 buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; char *str = &buf[sizeof(buf) - 1];
*str = '\0'; *str = '\0';
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
do { do
char c = n % base; {
n /= base; char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10; *--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n); } while (n);
return write(str); return write(str);
} }
// REFERENCE IMPLEMENTATION FOR ULL // REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base) // size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// { // {
// // if limited to base 10 and 16 the bufsize can be smaller // // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65]; // char buf[65];
// char *str = &buf[64]; // char *str = &buf[64];
// *str = '\0'; // *str = '\0';
// // prevent crash if called with base == 1 // // prevent crash if called with base == 1
// if (base < 2) base = 10; // if (base < 2) base = 10;
// do { // do {
// unsigned long long t = n / base; // unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base; // char c = n - t * base; // faster than c = n%base;
// n = t; // n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10; // *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n); // } while(n);
// return write(str); // return write(str);
// } // }
// FAST IMPLEMENTATION FOR ULL // FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base) size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{ {
// if limited to base 10 and 16 the bufsize can be 20 // if limited to base 10 and 16 the bufsize can be 20
char buf[64]; char buf[64];
uint8_t i = 0; uint8_t i = 0;
uint8_t innerLoops = 0; uint8_t innerLoops = 0;
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
// process chunks that fit in "16 bit math". // process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base; uint16_t top = 0xFFFF / base;
uint16_t th16 = 1; uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}
while (n64 > th16) while (th16 < top)
{ {
// 64 bit math part th16 *= base;
uint64_t q = n64 / th16; innerLoops++;
uint16_t r = n64 - q*th16; }
n64 = q;
// 16 bit math loop to do remainder. (note buffer is filled reverse) while (n64 > th16)
for (uint8_t j=0; j < innerLoops; j++) {
{ // 64 bit math part
uint16_t qq = r/base; uint64_t q = n64 / th16;
buf[i++] = r - qq*base; uint16_t r = n64 - q * th16;
r = qq; n64 = q;
}
}
uint16_t n16 = n64; // 16 bit math loop to do remainder. (note buffer is filled reverse)
while (n16 > 0) for (uint8_t j = 0; j < innerLoops; j++)
{ {
uint16_t qq = n16/base; uint16_t qq = r / base;
buf[i++] = n16 - qq*base; buf[i++] = r - qq * base;
n16 = qq; r = qq;
} }
}
size_t bytes = i; uint16_t n16 = n64;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes; while (n16 > 0)
{
uint16_t qq = n16 / base;
buf[i++] = n16 - qq * base;
n16 = qq;
}
size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes;
} }
size_t Print::printFloat(double number, int digits) size_t Print::printFloat(double number, int digits)
{ {
if (digits < 0) if (digits < 0)
digits = 2; digits = 2;
size_t n = 0; size_t n = 0;
if (isnan(number)) return print("nan"); if (isnan(number))
if (isinf(number)) return print("inf"); return print("nan");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers if (isinf(number))
if (number < 0.0) return print("inf");
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00" if (number > 4294967040.0)
double rounding = 0.5; return print ("ovf"); // constant determined empirically
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding; if (number < -4294967040.0)
return print ("ovf"); // constant determined empirically
// Extract the integer part of the number and print it // Handle negative numbers
unsigned long int_part = (unsigned long)number; if (number < 0.0)
double remainder = number - (double)int_part; {
n += print(int_part); n += print('-');
number = -number;
}
// Print the decimal point, but only if there are digits beyond // Round correctly so that print(1.999, 2) prints as "2.00"
if (digits > 0) { double rounding = 0.5;
n += print(".");
}
// Extract digits from the remainder one at a time for (uint8_t i = 0; i < digits; ++i)
while (digits-- > 0) rounding /= 10.0;
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n; number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
} }
size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if ( i != 0 ) print(delim); if ( i != 0 )
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[i]);
}
return (len * 3 - 1);
} }
size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if (i != 0) print(delim); if (i != 0)
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[len-1-i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[len - 1 - i]);
}
return (len * 3 - 1);
} }

View File

@@ -32,77 +32,93 @@
class Print class Print
{ {
private: private:
int write_error; int write_error;
size_t printNumber(unsigned long, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t); size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int); size_t printFloat(double, int);
protected: protected:
void setWriteError(int err = 1) { write_error = err; } void setWriteError(int err = 1)
public: {
Print() : write_error(0) {} write_error = err;
}
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; } int getWriteError()
void clearWriteError() { setWriteError(0); } {
return write_error;
}
void clearWriteError()
{
setWriteError(0);
}
virtual size_t write(uint8_t) = 0; virtual size_t write(uint8_t) = 0;
size_t write(const char *str) { size_t write(const char *str)
if (str == NULL) return 0; {
return write((const uint8_t *)str, strlen(str)); if (str == NULL)
} return 0;
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block" return write((const uint8_t *)str, strlen(str));
// should be overridden by subclasses with buffering }
virtual int availableForWrite() { return 0; } virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
size_t print(const __FlashStringHelper *); // default to zero, meaning "a single write may block"
size_t print(const String &); // should be overridden by subclasses with buffering
size_t print(const char[]); virtual int availableForWrite()
size_t print(char); {
size_t print(unsigned char, int = DEC); return 0;
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 print(const Printable&);
size_t println(const __FlashStringHelper *); size_t print(const __FlashStringHelper *);
size_t println(const String &s); size_t print(const String &);
size_t println(const char[]); size_t print(const char[]);
size_t println(char); size_t print(char);
size_t println(unsigned char, int = DEC); size_t print(unsigned char, int = DEC);
size_t println(int, int = DEC); size_t print(int, int = DEC);
size_t println(unsigned int, int = DEC); size_t print(unsigned int, int = DEC);
size_t println(long, int = DEC); size_t print(long, int = DEC);
size_t println(unsigned long, int = DEC); size_t print(unsigned long, int = DEC);
size_t println(long long, int = DEC); size_t print(long long, int = DEC);
size_t println(unsigned long long, int = DEC); size_t print(unsigned long long, int = DEC);
size_t println(double, int = 2); size_t print(double, int = 2);
size_t println(const Printable&); size_t print(const Printable&);
size_t println(void);
size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim=' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim=' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim=' ', int byteline = 0); size_t println(const __FlashStringHelper *);
size_t printBufferReverse(char const buffer[], int size, char delim=' ', int byteline = 0) size_t println(const String &s);
{ size_t println(const char[]);
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline); 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(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ } size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBufferReverse(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline);
}
virtual void flush() { /* Empty implementation for backward compatibility */ }
}; };

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -76,16 +76,16 @@ int __debug_buf(const char* head, char* buf, int len);
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -100,25 +100,25 @@ int __debug_buf(const char* head, char* buf, int len);
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#ifdef __cplusplus #ifdef __cplusplus
template<class T, class L> template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (b < a) ? b : a; return (b < a) ? b : a;
} }
template<class T, class L> template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (a < b) ? b : a; return (a < b) ? b : a;
} }
#else #else
#ifndef min #ifndef min
#define min(a,b) \ #define min(a,b) \
@@ -147,8 +147,8 @@ int __debug_buf(const char* head, char* buf, int len);
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused)); static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void) static inline unsigned char __interruptsStatus(void)
{ {
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html // See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html
return (__get_PRIMASK() ? 0 : 1); return (__get_PRIMASK() ? 0 : 1);
} }
#define interruptsStatus() __interruptsStatus() #define interruptsStatus() __interruptsStatus()
#endif #endif
@@ -164,18 +164,18 @@ static inline unsigned char __interruptsStatus(void)
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// USB // USB
#ifdef USE_TINYUSB #ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_Core.h" #include "Adafruit_TinyUSB_Core.h"
#else #else
#include "USB/USBDesc.h" #include "USB/USBDesc.h"
#include "USB/USBCore.h" #include "USB/USBCore.h"
#include "USB/USBAPI.h" #include "USB/USBAPI.h"
#include "USB/USB_host.h" #include "USB/USB_host.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -35,386 +35,432 @@
/* default implementation: may be overridden */ /* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::write(const uint8_t *buffer, size_t size)
{ {
size_t n = 0; size_t n = 0;
while (size--) {
if (write(*buffer++)) n++; while (size--)
else break; {
} if (write(*buffer++))
return n; n++;
else
break;
}
return n;
} }
size_t Print::print(const __FlashStringHelper *ifsh) size_t Print::print(const __FlashStringHelper *ifsh)
{ {
return print(reinterpret_cast<const char *>(ifsh)); return print(reinterpret_cast<const char *>(ifsh));
} }
size_t Print::print(const String &s) size_t Print::print(const String &s)
{ {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
size_t Print::print(const char str[]) size_t Print::print(const char str[])
{ {
return write(str); return write(str);
} }
size_t Print::print(char c) size_t Print::print(char c)
{ {
return write(c); return write(c);
} }
size_t Print::print(unsigned char b, int base) size_t Print::print(unsigned char b, int base)
{ {
return print((unsigned long) b, base); return print((unsigned long) b, base);
} }
size_t Print::print(int n, int base) size_t Print::print(int n, int base)
{ {
return print((long) n, base); return print((long) n, base);
} }
size_t Print::print(unsigned int n, int base) size_t Print::print(unsigned int n, int base)
{ {
return print((unsigned long) n, base); return print((unsigned long) n, base);
} }
size_t Print::print(long n, int base) size_t Print::print(long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printNumber(n, 10) + t; if (n < 0)
} {
return printNumber(n, 10); int t = print('-');
} else { n = -n;
return printNumber(n, base); return printNumber(n, 10) + t;
} }
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
} }
size_t Print::print(unsigned long n, int base) size_t Print::print(unsigned long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printNumber(n, base); return write(n);
else
return printNumber(n, base);
} }
size_t Print::print(long long n, int base) size_t Print::print(long long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printULLNumber(n, 10) + t; if (n < 0)
} {
return printULLNumber(n, 10); int t = print('-');
} else { n = -n;
return printULLNumber(n, base); return printULLNumber(n, 10) + t;
} }
return printULLNumber(n, 10);
}
else
{
return printULLNumber(n, base);
}
} }
size_t Print::print(unsigned long long n, int base) size_t Print::print(unsigned long long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printULLNumber(n, base); return write(n);
else
return printULLNumber(n, base);
} }
size_t Print::print(double n, int digits) size_t Print::print(double n, int digits)
{ {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::println(const __FlashStringHelper *ifsh) size_t Print::println(const __FlashStringHelper *ifsh)
{ {
size_t n = print(ifsh); size_t n = print(ifsh);
n += println(); n += println();
return n; return n;
} }
size_t Print::print(const Printable& x) size_t Print::print(const Printable& x)
{ {
return x.printTo(*this); return x.printTo(*this);
} }
size_t Print::println(void) size_t Print::println(void)
{ {
return write("\r\n"); return write("\r\n");
} }
size_t Print::println(const String &s) size_t Print::println(const String &s)
{ {
size_t n = print(s); size_t n = print(s);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const char c[]) size_t Print::println(const char c[])
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(char c) size_t Print::println(char c)
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned char b, int base) size_t Print::println(unsigned char b, int base)
{ {
size_t n = print(b, base); size_t n = print(b, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(int num, int base) size_t Print::println(int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned int num, int base) size_t Print::println(unsigned int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long num, int base) size_t Print::println(long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long num, int base) size_t Print::println(unsigned long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long long num, int base) size_t Print::println(long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long long num, int base) size_t Print::println(unsigned long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(double num, int digits) size_t Print::println(double num, int digits)
{ {
size_t n = print(num, digits); size_t n = print(num, digits);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const Printable& x) size_t Print::println(const Printable& x)
{ {
size_t n = print(x); size_t n = print(x);
n += println(); n += println();
return n; return n;
} }
size_t Print::printf(const char * format, ...) size_t Print::printf(const char * format, ...)
{ {
char buf[256]; char buf[256];
int len; int len;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
len = vsnprintf(buf, 256, format, ap); len = vsnprintf(buf, 256, format, ap);
this->write(buf, len); this->write(buf, len);
va_end(ap); va_end(ap);
return len; return len;
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
size_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 buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; char *str = &buf[sizeof(buf) - 1];
*str = '\0'; *str = '\0';
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
do { do
char c = n % base; {
n /= base; char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10; *--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n); } while (n);
return write(str); return write(str);
} }
// REFERENCE IMPLEMENTATION FOR ULL // REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base) // size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// { // {
// // if limited to base 10 and 16 the bufsize can be smaller // // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65]; // char buf[65];
// char *str = &buf[64]; // char *str = &buf[64];
// *str = '\0'; // *str = '\0';
// // prevent crash if called with base == 1 // // prevent crash if called with base == 1
// if (base < 2) base = 10; // if (base < 2) base = 10;
// do { // do {
// unsigned long long t = n / base; // unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base; // char c = n - t * base; // faster than c = n%base;
// n = t; // n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10; // *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n); // } while(n);
// return write(str); // return write(str);
// } // }
// FAST IMPLEMENTATION FOR ULL // FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base) size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{ {
// if limited to base 10 and 16 the bufsize can be 20 // if limited to base 10 and 16 the bufsize can be 20
char buf[64]; char buf[64];
uint8_t i = 0; uint8_t i = 0;
uint8_t innerLoops = 0; uint8_t innerLoops = 0;
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
// process chunks that fit in "16 bit math". // process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base; uint16_t top = 0xFFFF / base;
uint16_t th16 = 1; uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}
while (n64 > th16) while (th16 < top)
{ {
// 64 bit math part th16 *= base;
uint64_t q = n64 / th16; innerLoops++;
uint16_t r = n64 - q*th16; }
n64 = q;
// 16 bit math loop to do remainder. (note buffer is filled reverse) while (n64 > th16)
for (uint8_t j=0; j < innerLoops; j++) {
{ // 64 bit math part
uint16_t qq = r/base; uint64_t q = n64 / th16;
buf[i++] = r - qq*base; uint16_t r = n64 - q * th16;
r = qq; n64 = q;
}
}
uint16_t n16 = n64; // 16 bit math loop to do remainder. (note buffer is filled reverse)
while (n16 > 0) for (uint8_t j = 0; j < innerLoops; j++)
{ {
uint16_t qq = n16/base; uint16_t qq = r / base;
buf[i++] = n16 - qq*base; buf[i++] = r - qq * base;
n16 = qq; r = qq;
} }
}
size_t bytes = i; uint16_t n16 = n64;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes; while (n16 > 0)
{
uint16_t qq = n16 / base;
buf[i++] = n16 - qq * base;
n16 = qq;
}
size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes;
} }
size_t Print::printFloat(double number, int digits) size_t Print::printFloat(double number, int digits)
{ {
if (digits < 0) if (digits < 0)
digits = 2; digits = 2;
size_t n = 0; size_t n = 0;
if (isnan(number)) return print("nan"); if (isnan(number))
if (isinf(number)) return print("inf"); return print("nan");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers if (isinf(number))
if (number < 0.0) return print("inf");
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00" if (number > 4294967040.0)
double rounding = 0.5; return print ("ovf"); // constant determined empirically
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding; if (number < -4294967040.0)
return print ("ovf"); // constant determined empirically
// Extract the integer part of the number and print it // Handle negative numbers
unsigned long int_part = (unsigned long)number; if (number < 0.0)
double remainder = number - (double)int_part; {
n += print(int_part); n += print('-');
number = -number;
}
// Print the decimal point, but only if there are digits beyond // Round correctly so that print(1.999, 2) prints as "2.00"
if (digits > 0) { double rounding = 0.5;
n += print(".");
}
// Extract digits from the remainder one at a time for (uint8_t i = 0; i < digits; ++i)
while (digits-- > 0) rounding /= 10.0;
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n; number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
} }
size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if ( i != 0 ) print(delim); if ( i != 0 )
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[i]);
}
return (len * 3 - 1);
} }
size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if (i != 0) print(delim); if (i != 0)
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[len-1-i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[len - 1 - i]);
}
return (len * 3 - 1);
} }

View File

@@ -32,77 +32,93 @@
class Print class Print
{ {
private: private:
int write_error; int write_error;
size_t printNumber(unsigned long, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t); size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int); size_t printFloat(double, int);
protected: protected:
void setWriteError(int err = 1) { write_error = err; } void setWriteError(int err = 1)
public: {
Print() : write_error(0) {} write_error = err;
}
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; } int getWriteError()
void clearWriteError() { setWriteError(0); } {
return write_error;
}
void clearWriteError()
{
setWriteError(0);
}
virtual size_t write(uint8_t) = 0; virtual size_t write(uint8_t) = 0;
size_t write(const char *str) { size_t write(const char *str)
if (str == NULL) return 0; {
return write((const uint8_t *)str, strlen(str)); if (str == NULL)
} return 0;
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block" return write((const uint8_t *)str, strlen(str));
// should be overridden by subclasses with buffering }
virtual int availableForWrite() { return 0; } virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
size_t print(const __FlashStringHelper *); // default to zero, meaning "a single write may block"
size_t print(const String &); // should be overridden by subclasses with buffering
size_t print(const char[]); virtual int availableForWrite()
size_t print(char); {
size_t print(unsigned char, int = DEC); return 0;
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 print(const Printable&);
size_t println(const __FlashStringHelper *); size_t print(const __FlashStringHelper *);
size_t println(const String &s); size_t print(const String &);
size_t println(const char[]); size_t print(const char[]);
size_t println(char); size_t print(char);
size_t println(unsigned char, int = DEC); size_t print(unsigned char, int = DEC);
size_t println(int, int = DEC); size_t print(int, int = DEC);
size_t println(unsigned int, int = DEC); size_t print(unsigned int, int = DEC);
size_t println(long, int = DEC); size_t print(long, int = DEC);
size_t println(unsigned long, int = DEC); size_t print(unsigned long, int = DEC);
size_t println(long long, int = DEC); size_t print(long long, int = DEC);
size_t println(unsigned long long, int = DEC); size_t print(unsigned long long, int = DEC);
size_t println(double, int = 2); size_t print(double, int = 2);
size_t println(const Printable&); size_t print(const Printable&);
size_t println(void);
size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim=' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim=' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim=' ', int byteline = 0); size_t println(const __FlashStringHelper *);
size_t printBufferReverse(char const buffer[], int size, char delim=' ', int byteline = 0) size_t println(const String &s);
{ size_t println(const char[]);
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline); 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(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ } size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBufferReverse(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline);
}
virtual void flush() { /* Empty implementation for backward compatibility */ }
}; };

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -76,16 +76,16 @@ int __debug_buf(const char* head, char* buf, int len);
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -100,25 +100,25 @@ int __debug_buf(const char* head, char* buf, int len);
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#ifdef __cplusplus #ifdef __cplusplus
template<class T, class L> template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (b < a) ? b : a; return (b < a) ? b : a;
} }
template<class T, class L> template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (a < b) ? b : a; return (a < b) ? b : a;
} }
#else #else
#ifndef min #ifndef min
#define min(a,b) \ #define min(a,b) \
@@ -147,8 +147,8 @@ int __debug_buf(const char* head, char* buf, int len);
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused)); static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void) static inline unsigned char __interruptsStatus(void)
{ {
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html // See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html
return (__get_PRIMASK() ? 0 : 1); return (__get_PRIMASK() ? 0 : 1);
} }
#define interruptsStatus() __interruptsStatus() #define interruptsStatus() __interruptsStatus()
#endif #endif
@@ -164,18 +164,18 @@ static inline unsigned char __interruptsStatus(void)
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// USB // USB
#ifdef USE_TINYUSB #ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_Core.h" #include "Adafruit_TinyUSB_Core.h"
#else #else
#include "USB/USBDesc.h" #include "USB/USBDesc.h"
#include "USB/USBCore.h" #include "USB/USBCore.h"
#include "USB/USBAPI.h" #include "USB/USBAPI.h"
#include "USB/USB_host.h" #include "USB/USB_host.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -35,386 +35,432 @@
/* default implementation: may be overridden */ /* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::write(const uint8_t *buffer, size_t size)
{ {
size_t n = 0; size_t n = 0;
while (size--) {
if (write(*buffer++)) n++; while (size--)
else break; {
} if (write(*buffer++))
return n; n++;
else
break;
}
return n;
} }
size_t Print::print(const __FlashStringHelper *ifsh) size_t Print::print(const __FlashStringHelper *ifsh)
{ {
return print(reinterpret_cast<const char *>(ifsh)); return print(reinterpret_cast<const char *>(ifsh));
} }
size_t Print::print(const String &s) size_t Print::print(const String &s)
{ {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
size_t Print::print(const char str[]) size_t Print::print(const char str[])
{ {
return write(str); return write(str);
} }
size_t Print::print(char c) size_t Print::print(char c)
{ {
return write(c); return write(c);
} }
size_t Print::print(unsigned char b, int base) size_t Print::print(unsigned char b, int base)
{ {
return print((unsigned long) b, base); return print((unsigned long) b, base);
} }
size_t Print::print(int n, int base) size_t Print::print(int n, int base)
{ {
return print((long) n, base); return print((long) n, base);
} }
size_t Print::print(unsigned int n, int base) size_t Print::print(unsigned int n, int base)
{ {
return print((unsigned long) n, base); return print((unsigned long) n, base);
} }
size_t Print::print(long n, int base) size_t Print::print(long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printNumber(n, 10) + t; if (n < 0)
} {
return printNumber(n, 10); int t = print('-');
} else { n = -n;
return printNumber(n, base); return printNumber(n, 10) + t;
} }
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
} }
size_t Print::print(unsigned long n, int base) size_t Print::print(unsigned long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printNumber(n, base); return write(n);
else
return printNumber(n, base);
} }
size_t Print::print(long long n, int base) size_t Print::print(long long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printULLNumber(n, 10) + t; if (n < 0)
} {
return printULLNumber(n, 10); int t = print('-');
} else { n = -n;
return printULLNumber(n, base); return printULLNumber(n, 10) + t;
} }
return printULLNumber(n, 10);
}
else
{
return printULLNumber(n, base);
}
} }
size_t Print::print(unsigned long long n, int base) size_t Print::print(unsigned long long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printULLNumber(n, base); return write(n);
else
return printULLNumber(n, base);
} }
size_t Print::print(double n, int digits) size_t Print::print(double n, int digits)
{ {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::println(const __FlashStringHelper *ifsh) size_t Print::println(const __FlashStringHelper *ifsh)
{ {
size_t n = print(ifsh); size_t n = print(ifsh);
n += println(); n += println();
return n; return n;
} }
size_t Print::print(const Printable& x) size_t Print::print(const Printable& x)
{ {
return x.printTo(*this); return x.printTo(*this);
} }
size_t Print::println(void) size_t Print::println(void)
{ {
return write("\r\n"); return write("\r\n");
} }
size_t Print::println(const String &s) size_t Print::println(const String &s)
{ {
size_t n = print(s); size_t n = print(s);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const char c[]) size_t Print::println(const char c[])
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(char c) size_t Print::println(char c)
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned char b, int base) size_t Print::println(unsigned char b, int base)
{ {
size_t n = print(b, base); size_t n = print(b, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(int num, int base) size_t Print::println(int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned int num, int base) size_t Print::println(unsigned int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long num, int base) size_t Print::println(long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long num, int base) size_t Print::println(unsigned long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long long num, int base) size_t Print::println(long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long long num, int base) size_t Print::println(unsigned long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(double num, int digits) size_t Print::println(double num, int digits)
{ {
size_t n = print(num, digits); size_t n = print(num, digits);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const Printable& x) size_t Print::println(const Printable& x)
{ {
size_t n = print(x); size_t n = print(x);
n += println(); n += println();
return n; return n;
} }
size_t Print::printf(const char * format, ...) size_t Print::printf(const char * format, ...)
{ {
char buf[256]; char buf[256];
int len; int len;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
len = vsnprintf(buf, 256, format, ap); len = vsnprintf(buf, 256, format, ap);
this->write(buf, len); this->write(buf, len);
va_end(ap); va_end(ap);
return len; return len;
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
size_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 buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; char *str = &buf[sizeof(buf) - 1];
*str = '\0'; *str = '\0';
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
do { do
char c = n % base; {
n /= base; char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10; *--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n); } while (n);
return write(str); return write(str);
} }
// REFERENCE IMPLEMENTATION FOR ULL // REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base) // size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// { // {
// // if limited to base 10 and 16 the bufsize can be smaller // // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65]; // char buf[65];
// char *str = &buf[64]; // char *str = &buf[64];
// *str = '\0'; // *str = '\0';
// // prevent crash if called with base == 1 // // prevent crash if called with base == 1
// if (base < 2) base = 10; // if (base < 2) base = 10;
// do { // do {
// unsigned long long t = n / base; // unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base; // char c = n - t * base; // faster than c = n%base;
// n = t; // n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10; // *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n); // } while(n);
// return write(str); // return write(str);
// } // }
// FAST IMPLEMENTATION FOR ULL // FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base) size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{ {
// if limited to base 10 and 16 the bufsize can be 20 // if limited to base 10 and 16 the bufsize can be 20
char buf[64]; char buf[64];
uint8_t i = 0; uint8_t i = 0;
uint8_t innerLoops = 0; uint8_t innerLoops = 0;
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
// process chunks that fit in "16 bit math". // process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base; uint16_t top = 0xFFFF / base;
uint16_t th16 = 1; uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}
while (n64 > th16) while (th16 < top)
{ {
// 64 bit math part th16 *= base;
uint64_t q = n64 / th16; innerLoops++;
uint16_t r = n64 - q*th16; }
n64 = q;
// 16 bit math loop to do remainder. (note buffer is filled reverse) while (n64 > th16)
for (uint8_t j=0; j < innerLoops; j++) {
{ // 64 bit math part
uint16_t qq = r/base; uint64_t q = n64 / th16;
buf[i++] = r - qq*base; uint16_t r = n64 - q * th16;
r = qq; n64 = q;
}
}
uint16_t n16 = n64; // 16 bit math loop to do remainder. (note buffer is filled reverse)
while (n16 > 0) for (uint8_t j = 0; j < innerLoops; j++)
{ {
uint16_t qq = n16/base; uint16_t qq = r / base;
buf[i++] = n16 - qq*base; buf[i++] = r - qq * base;
n16 = qq; r = qq;
} }
}
size_t bytes = i; uint16_t n16 = n64;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes; while (n16 > 0)
{
uint16_t qq = n16 / base;
buf[i++] = n16 - qq * base;
n16 = qq;
}
size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes;
} }
size_t Print::printFloat(double number, int digits) size_t Print::printFloat(double number, int digits)
{ {
if (digits < 0) if (digits < 0)
digits = 2; digits = 2;
size_t n = 0; size_t n = 0;
if (isnan(number)) return print("nan"); if (isnan(number))
if (isinf(number)) return print("inf"); return print("nan");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers if (isinf(number))
if (number < 0.0) return print("inf");
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00" if (number > 4294967040.0)
double rounding = 0.5; return print ("ovf"); // constant determined empirically
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding; if (number < -4294967040.0)
return print ("ovf"); // constant determined empirically
// Extract the integer part of the number and print it // Handle negative numbers
unsigned long int_part = (unsigned long)number; if (number < 0.0)
double remainder = number - (double)int_part; {
n += print(int_part); n += print('-');
number = -number;
}
// Print the decimal point, but only if there are digits beyond // Round correctly so that print(1.999, 2) prints as "2.00"
if (digits > 0) { double rounding = 0.5;
n += print(".");
}
// Extract digits from the remainder one at a time for (uint8_t i = 0; i < digits; ++i)
while (digits-- > 0) rounding /= 10.0;
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n; number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
} }
size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if ( i != 0 ) print(delim); if ( i != 0 )
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[i]);
}
return (len * 3 - 1);
} }
size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if (i != 0) print(delim); if (i != 0)
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[len-1-i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[len - 1 - i]);
}
return (len * 3 - 1);
} }

View File

@@ -32,77 +32,93 @@
class Print class Print
{ {
private: private:
int write_error; int write_error;
size_t printNumber(unsigned long, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t); size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int); size_t printFloat(double, int);
protected: protected:
void setWriteError(int err = 1) { write_error = err; } void setWriteError(int err = 1)
public: {
Print() : write_error(0) {} write_error = err;
}
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; } int getWriteError()
void clearWriteError() { setWriteError(0); } {
return write_error;
}
void clearWriteError()
{
setWriteError(0);
}
virtual size_t write(uint8_t) = 0; virtual size_t write(uint8_t) = 0;
size_t write(const char *str) { size_t write(const char *str)
if (str == NULL) return 0; {
return write((const uint8_t *)str, strlen(str)); if (str == NULL)
} return 0;
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block" return write((const uint8_t *)str, strlen(str));
// should be overridden by subclasses with buffering }
virtual int availableForWrite() { return 0; } virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
size_t print(const __FlashStringHelper *); // default to zero, meaning "a single write may block"
size_t print(const String &); // should be overridden by subclasses with buffering
size_t print(const char[]); virtual int availableForWrite()
size_t print(char); {
size_t print(unsigned char, int = DEC); return 0;
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 print(const Printable&);
size_t println(const __FlashStringHelper *); size_t print(const __FlashStringHelper *);
size_t println(const String &s); size_t print(const String &);
size_t println(const char[]); size_t print(const char[]);
size_t println(char); size_t print(char);
size_t println(unsigned char, int = DEC); size_t print(unsigned char, int = DEC);
size_t println(int, int = DEC); size_t print(int, int = DEC);
size_t println(unsigned int, int = DEC); size_t print(unsigned int, int = DEC);
size_t println(long, int = DEC); size_t print(long, int = DEC);
size_t println(unsigned long, int = DEC); size_t print(unsigned long, int = DEC);
size_t println(long long, int = DEC); size_t print(long long, int = DEC);
size_t println(unsigned long long, int = DEC); size_t print(unsigned long long, int = DEC);
size_t println(double, int = 2); size_t print(double, int = 2);
size_t println(const Printable&); size_t print(const Printable&);
size_t println(void);
size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim=' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim=' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim=' ', int byteline = 0); size_t println(const __FlashStringHelper *);
size_t printBufferReverse(char const buffer[], int size, char delim=' ', int byteline = 0) size_t println(const String &s);
{ size_t println(const char[]);
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline); 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(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ } size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBufferReverse(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline);
}
virtual void flush() { /* Empty implementation for backward compatibility */ }
}; };

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -76,16 +76,16 @@ int __debug_buf(const char* head, char* buf, int len);
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -100,25 +100,25 @@ int __debug_buf(const char* head, char* buf, int len);
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#ifdef __cplusplus #ifdef __cplusplus
template<class T, class L> template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (b < a) ? b : a; return (b < a) ? b : a;
} }
template<class T, class L> template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (a < b) ? b : a; return (a < b) ? b : a;
} }
#else #else
#ifndef min #ifndef min
#define min(a,b) \ #define min(a,b) \
@@ -147,8 +147,8 @@ int __debug_buf(const char* head, char* buf, int len);
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused)); static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void) static inline unsigned char __interruptsStatus(void)
{ {
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html // See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html
return (__get_PRIMASK() ? 0 : 1); return (__get_PRIMASK() ? 0 : 1);
} }
#define interruptsStatus() __interruptsStatus() #define interruptsStatus() __interruptsStatus()
#endif #endif
@@ -164,18 +164,18 @@ static inline unsigned char __interruptsStatus(void)
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// USB // USB
#ifdef USE_TINYUSB #ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_Core.h" #include "Adafruit_TinyUSB_Core.h"
#else #else
#include "USB/USBDesc.h" #include "USB/USBDesc.h"
#include "USB/USBCore.h" #include "USB/USBCore.h"
#include "USB/USBAPI.h" #include "USB/USBAPI.h"
#include "USB/USB_host.h" #include "USB/USB_host.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -35,386 +35,432 @@
/* default implementation: may be overridden */ /* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::write(const uint8_t *buffer, size_t size)
{ {
size_t n = 0; size_t n = 0;
while (size--) {
if (write(*buffer++)) n++; while (size--)
else break; {
} if (write(*buffer++))
return n; n++;
else
break;
}
return n;
} }
size_t Print::print(const __FlashStringHelper *ifsh) size_t Print::print(const __FlashStringHelper *ifsh)
{ {
return print(reinterpret_cast<const char *>(ifsh)); return print(reinterpret_cast<const char *>(ifsh));
} }
size_t Print::print(const String &s) size_t Print::print(const String &s)
{ {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
size_t Print::print(const char str[]) size_t Print::print(const char str[])
{ {
return write(str); return write(str);
} }
size_t Print::print(char c) size_t Print::print(char c)
{ {
return write(c); return write(c);
} }
size_t Print::print(unsigned char b, int base) size_t Print::print(unsigned char b, int base)
{ {
return print((unsigned long) b, base); return print((unsigned long) b, base);
} }
size_t Print::print(int n, int base) size_t Print::print(int n, int base)
{ {
return print((long) n, base); return print((long) n, base);
} }
size_t Print::print(unsigned int n, int base) size_t Print::print(unsigned int n, int base)
{ {
return print((unsigned long) n, base); return print((unsigned long) n, base);
} }
size_t Print::print(long n, int base) size_t Print::print(long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printNumber(n, 10) + t; if (n < 0)
} {
return printNumber(n, 10); int t = print('-');
} else { n = -n;
return printNumber(n, base); return printNumber(n, 10) + t;
} }
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
} }
size_t Print::print(unsigned long n, int base) size_t Print::print(unsigned long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printNumber(n, base); return write(n);
else
return printNumber(n, base);
} }
size_t Print::print(long long n, int base) size_t Print::print(long long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printULLNumber(n, 10) + t; if (n < 0)
} {
return printULLNumber(n, 10); int t = print('-');
} else { n = -n;
return printULLNumber(n, base); return printULLNumber(n, 10) + t;
} }
return printULLNumber(n, 10);
}
else
{
return printULLNumber(n, base);
}
} }
size_t Print::print(unsigned long long n, int base) size_t Print::print(unsigned long long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printULLNumber(n, base); return write(n);
else
return printULLNumber(n, base);
} }
size_t Print::print(double n, int digits) size_t Print::print(double n, int digits)
{ {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::println(const __FlashStringHelper *ifsh) size_t Print::println(const __FlashStringHelper *ifsh)
{ {
size_t n = print(ifsh); size_t n = print(ifsh);
n += println(); n += println();
return n; return n;
} }
size_t Print::print(const Printable& x) size_t Print::print(const Printable& x)
{ {
return x.printTo(*this); return x.printTo(*this);
} }
size_t Print::println(void) size_t Print::println(void)
{ {
return write("\r\n"); return write("\r\n");
} }
size_t Print::println(const String &s) size_t Print::println(const String &s)
{ {
size_t n = print(s); size_t n = print(s);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const char c[]) size_t Print::println(const char c[])
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(char c) size_t Print::println(char c)
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned char b, int base) size_t Print::println(unsigned char b, int base)
{ {
size_t n = print(b, base); size_t n = print(b, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(int num, int base) size_t Print::println(int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned int num, int base) size_t Print::println(unsigned int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long num, int base) size_t Print::println(long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long num, int base) size_t Print::println(unsigned long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long long num, int base) size_t Print::println(long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long long num, int base) size_t Print::println(unsigned long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(double num, int digits) size_t Print::println(double num, int digits)
{ {
size_t n = print(num, digits); size_t n = print(num, digits);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const Printable& x) size_t Print::println(const Printable& x)
{ {
size_t n = print(x); size_t n = print(x);
n += println(); n += println();
return n; return n;
} }
size_t Print::printf(const char * format, ...) size_t Print::printf(const char * format, ...)
{ {
char buf[256]; char buf[256];
int len; int len;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
len = vsnprintf(buf, 256, format, ap); len = vsnprintf(buf, 256, format, ap);
this->write(buf, len); this->write(buf, len);
va_end(ap); va_end(ap);
return len; return len;
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
size_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 buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; char *str = &buf[sizeof(buf) - 1];
*str = '\0'; *str = '\0';
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
do { do
char c = n % base; {
n /= base; char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10; *--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n); } while (n);
return write(str); return write(str);
} }
// REFERENCE IMPLEMENTATION FOR ULL // REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base) // size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// { // {
// // if limited to base 10 and 16 the bufsize can be smaller // // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65]; // char buf[65];
// char *str = &buf[64]; // char *str = &buf[64];
// *str = '\0'; // *str = '\0';
// // prevent crash if called with base == 1 // // prevent crash if called with base == 1
// if (base < 2) base = 10; // if (base < 2) base = 10;
// do { // do {
// unsigned long long t = n / base; // unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base; // char c = n - t * base; // faster than c = n%base;
// n = t; // n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10; // *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n); // } while(n);
// return write(str); // return write(str);
// } // }
// FAST IMPLEMENTATION FOR ULL // FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base) size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{ {
// if limited to base 10 and 16 the bufsize can be 20 // if limited to base 10 and 16 the bufsize can be 20
char buf[64]; char buf[64];
uint8_t i = 0; uint8_t i = 0;
uint8_t innerLoops = 0; uint8_t innerLoops = 0;
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
// process chunks that fit in "16 bit math". // process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base; uint16_t top = 0xFFFF / base;
uint16_t th16 = 1; uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}
while (n64 > th16) while (th16 < top)
{ {
// 64 bit math part th16 *= base;
uint64_t q = n64 / th16; innerLoops++;
uint16_t r = n64 - q*th16; }
n64 = q;
// 16 bit math loop to do remainder. (note buffer is filled reverse) while (n64 > th16)
for (uint8_t j=0; j < innerLoops; j++) {
{ // 64 bit math part
uint16_t qq = r/base; uint64_t q = n64 / th16;
buf[i++] = r - qq*base; uint16_t r = n64 - q * th16;
r = qq; n64 = q;
}
}
uint16_t n16 = n64; // 16 bit math loop to do remainder. (note buffer is filled reverse)
while (n16 > 0) for (uint8_t j = 0; j < innerLoops; j++)
{ {
uint16_t qq = n16/base; uint16_t qq = r / base;
buf[i++] = n16 - qq*base; buf[i++] = r - qq * base;
n16 = qq; r = qq;
} }
}
size_t bytes = i; uint16_t n16 = n64;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes; while (n16 > 0)
{
uint16_t qq = n16 / base;
buf[i++] = n16 - qq * base;
n16 = qq;
}
size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes;
} }
size_t Print::printFloat(double number, int digits) size_t Print::printFloat(double number, int digits)
{ {
if (digits < 0) if (digits < 0)
digits = 2; digits = 2;
size_t n = 0; size_t n = 0;
if (isnan(number)) return print("nan"); if (isnan(number))
if (isinf(number)) return print("inf"); return print("nan");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers if (isinf(number))
if (number < 0.0) return print("inf");
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00" if (number > 4294967040.0)
double rounding = 0.5; return print ("ovf"); // constant determined empirically
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding; if (number < -4294967040.0)
return print ("ovf"); // constant determined empirically
// Extract the integer part of the number and print it // Handle negative numbers
unsigned long int_part = (unsigned long)number; if (number < 0.0)
double remainder = number - (double)int_part; {
n += print(int_part); n += print('-');
number = -number;
}
// Print the decimal point, but only if there are digits beyond // Round correctly so that print(1.999, 2) prints as "2.00"
if (digits > 0) { double rounding = 0.5;
n += print(".");
}
// Extract digits from the remainder one at a time for (uint8_t i = 0; i < digits; ++i)
while (digits-- > 0) rounding /= 10.0;
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n; number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
} }
size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if ( i != 0 ) print(delim); if ( i != 0 )
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[i]);
}
return (len * 3 - 1);
} }
size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if (i != 0) print(delim); if (i != 0)
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[len-1-i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[len - 1 - i]);
}
return (len * 3 - 1);
} }

View File

@@ -32,77 +32,93 @@
class Print class Print
{ {
private: private:
int write_error; int write_error;
size_t printNumber(unsigned long, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t); size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int); size_t printFloat(double, int);
protected: protected:
void setWriteError(int err = 1) { write_error = err; } void setWriteError(int err = 1)
public: {
Print() : write_error(0) {} write_error = err;
}
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; } int getWriteError()
void clearWriteError() { setWriteError(0); } {
return write_error;
}
void clearWriteError()
{
setWriteError(0);
}
virtual size_t write(uint8_t) = 0; virtual size_t write(uint8_t) = 0;
size_t write(const char *str) { size_t write(const char *str)
if (str == NULL) return 0; {
return write((const uint8_t *)str, strlen(str)); if (str == NULL)
} return 0;
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block" return write((const uint8_t *)str, strlen(str));
// should be overridden by subclasses with buffering }
virtual int availableForWrite() { return 0; } virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
size_t print(const __FlashStringHelper *); // default to zero, meaning "a single write may block"
size_t print(const String &); // should be overridden by subclasses with buffering
size_t print(const char[]); virtual int availableForWrite()
size_t print(char); {
size_t print(unsigned char, int = DEC); return 0;
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 print(const Printable&);
size_t println(const __FlashStringHelper *); size_t print(const __FlashStringHelper *);
size_t println(const String &s); size_t print(const String &);
size_t println(const char[]); size_t print(const char[]);
size_t println(char); size_t print(char);
size_t println(unsigned char, int = DEC); size_t print(unsigned char, int = DEC);
size_t println(int, int = DEC); size_t print(int, int = DEC);
size_t println(unsigned int, int = DEC); size_t print(unsigned int, int = DEC);
size_t println(long, int = DEC); size_t print(long, int = DEC);
size_t println(unsigned long, int = DEC); size_t print(unsigned long, int = DEC);
size_t println(long long, int = DEC); size_t print(long long, int = DEC);
size_t println(unsigned long long, int = DEC); size_t print(unsigned long long, int = DEC);
size_t println(double, int = 2); size_t print(double, int = 2);
size_t println(const Printable&); size_t print(const Printable&);
size_t println(void);
size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim=' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim=' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim=' ', int byteline = 0); size_t println(const __FlashStringHelper *);
size_t printBufferReverse(char const buffer[], int size, char delim=' ', int byteline = 0) size_t println(const String &s);
{ size_t println(const char[]);
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline); 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(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ } size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBufferReverse(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline);
}
virtual void flush() { /* Empty implementation for backward compatibility */ }
}; };

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -76,16 +76,16 @@ int __debug_buf(const char* head, char* buf, int len);
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -100,25 +100,25 @@ int __debug_buf(const char* head, char* buf, int len);
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#ifdef __cplusplus #ifdef __cplusplus
template<class T, class L> template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (b < a) ? b : a; return (b < a) ? b : a;
} }
template<class T, class L> template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{ {
return (a < b) ? b : a; return (a < b) ? b : a;
} }
#else #else
#ifndef min #ifndef min
#define min(a,b) \ #define min(a,b) \
@@ -147,8 +147,8 @@ int __debug_buf(const char* head, char* buf, int len);
static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused)); static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
static inline unsigned char __interruptsStatus(void) static inline unsigned char __interruptsStatus(void)
{ {
// See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html // See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDBIBGJ.html
return (__get_PRIMASK() ? 0 : 1); return (__get_PRIMASK() ? 0 : 1);
} }
#define interruptsStatus() __interruptsStatus() #define interruptsStatus() __interruptsStatus()
#endif #endif
@@ -164,18 +164,18 @@ static inline unsigned char __interruptsStatus(void)
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// USB // USB
#ifdef USE_TINYUSB #ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_Core.h" #include "Adafruit_TinyUSB_Core.h"
#else #else
#include "USB/USBDesc.h" #include "USB/USBDesc.h"
#include "USB/USBCore.h" #include "USB/USBCore.h"
#include "USB/USBAPI.h" #include "USB/USBAPI.h"
#include "USB/USB_host.h" #include "USB/USB_host.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -35,386 +35,432 @@
/* default implementation: may be overridden */ /* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size) size_t Print::write(const uint8_t *buffer, size_t size)
{ {
size_t n = 0; size_t n = 0;
while (size--) {
if (write(*buffer++)) n++; while (size--)
else break; {
} if (write(*buffer++))
return n; n++;
else
break;
}
return n;
} }
size_t Print::print(const __FlashStringHelper *ifsh) size_t Print::print(const __FlashStringHelper *ifsh)
{ {
return print(reinterpret_cast<const char *>(ifsh)); return print(reinterpret_cast<const char *>(ifsh));
} }
size_t Print::print(const String &s) size_t Print::print(const String &s)
{ {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
size_t Print::print(const char str[]) size_t Print::print(const char str[])
{ {
return write(str); return write(str);
} }
size_t Print::print(char c) size_t Print::print(char c)
{ {
return write(c); return write(c);
} }
size_t Print::print(unsigned char b, int base) size_t Print::print(unsigned char b, int base)
{ {
return print((unsigned long) b, base); return print((unsigned long) b, base);
} }
size_t Print::print(int n, int base) size_t Print::print(int n, int base)
{ {
return print((long) n, base); return print((long) n, base);
} }
size_t Print::print(unsigned int n, int base) size_t Print::print(unsigned int n, int base)
{ {
return print((unsigned long) n, base); return print((unsigned long) n, base);
} }
size_t Print::print(long n, int base) size_t Print::print(long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printNumber(n, 10) + t; if (n < 0)
} {
return printNumber(n, 10); int t = print('-');
} else { n = -n;
return printNumber(n, base); return printNumber(n, 10) + t;
} }
return printNumber(n, 10);
}
else
{
return printNumber(n, base);
}
} }
size_t Print::print(unsigned long n, int base) size_t Print::print(unsigned long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printNumber(n, base); return write(n);
else
return printNumber(n, base);
} }
size_t Print::print(long long n, int base) size_t Print::print(long long n, int base)
{ {
if (base == 0) { if (base == 0)
return write(n); {
} else if (base == 10) { return write(n);
if (n < 0) { }
int t = print('-'); else if (base == 10)
n = -n; {
return printULLNumber(n, 10) + t; if (n < 0)
} {
return printULLNumber(n, 10); int t = print('-');
} else { n = -n;
return printULLNumber(n, base); return printULLNumber(n, 10) + t;
} }
return printULLNumber(n, 10);
}
else
{
return printULLNumber(n, base);
}
} }
size_t Print::print(unsigned long long n, int base) size_t Print::print(unsigned long long n, int base)
{ {
if (base == 0) return write(n); if (base == 0)
else return printULLNumber(n, base); return write(n);
else
return printULLNumber(n, base);
} }
size_t Print::print(double n, int digits) size_t Print::print(double n, int digits)
{ {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t Print::println(const __FlashStringHelper *ifsh) size_t Print::println(const __FlashStringHelper *ifsh)
{ {
size_t n = print(ifsh); size_t n = print(ifsh);
n += println(); n += println();
return n; return n;
} }
size_t Print::print(const Printable& x) size_t Print::print(const Printable& x)
{ {
return x.printTo(*this); return x.printTo(*this);
} }
size_t Print::println(void) size_t Print::println(void)
{ {
return write("\r\n"); return write("\r\n");
} }
size_t Print::println(const String &s) size_t Print::println(const String &s)
{ {
size_t n = print(s); size_t n = print(s);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const char c[]) size_t Print::println(const char c[])
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(char c) size_t Print::println(char c)
{ {
size_t n = print(c); size_t n = print(c);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned char b, int base) size_t Print::println(unsigned char b, int base)
{ {
size_t n = print(b, base); size_t n = print(b, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(int num, int base) size_t Print::println(int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned int num, int base) size_t Print::println(unsigned int num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long num, int base) size_t Print::println(long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long num, int base) size_t Print::println(unsigned long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(long long num, int base) size_t Print::println(long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(unsigned long long num, int base) size_t Print::println(unsigned long long num, int base)
{ {
size_t n = print(num, base); size_t n = print(num, base);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(double num, int digits) size_t Print::println(double num, int digits)
{ {
size_t n = print(num, digits); size_t n = print(num, digits);
n += println(); n += println();
return n; return n;
} }
size_t Print::println(const Printable& x) size_t Print::println(const Printable& x)
{ {
size_t n = print(x); size_t n = print(x);
n += println(); n += println();
return n; return n;
} }
size_t Print::printf(const char * format, ...) size_t Print::printf(const char * format, ...)
{ {
char buf[256]; char buf[256];
int len; int len;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
len = vsnprintf(buf, 256, format, ap); len = vsnprintf(buf, 256, format, ap);
this->write(buf, len); this->write(buf, len);
va_end(ap); va_end(ap);
return len; return len;
} }
// Private Methods ///////////////////////////////////////////////////////////// // Private Methods /////////////////////////////////////////////////////////////
size_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 buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1]; char *str = &buf[sizeof(buf) - 1];
*str = '\0'; *str = '\0';
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
do { do
char c = n % base; {
n /= base; char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10; *--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n); } while (n);
return write(str); return write(str);
} }
// REFERENCE IMPLEMENTATION FOR ULL // REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base) // size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// { // {
// // if limited to base 10 and 16 the bufsize can be smaller // // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65]; // char buf[65];
// char *str = &buf[64]; // char *str = &buf[64];
// *str = '\0'; // *str = '\0';
// // prevent crash if called with base == 1 // // prevent crash if called with base == 1
// if (base < 2) base = 10; // if (base < 2) base = 10;
// do { // do {
// unsigned long long t = n / base; // unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base; // char c = n - t * base; // faster than c = n%base;
// n = t; // n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10; // *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n); // } while(n);
// return write(str); // return write(str);
// } // }
// FAST IMPLEMENTATION FOR ULL // FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base) size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{ {
// if limited to base 10 and 16 the bufsize can be 20 // if limited to base 10 and 16 the bufsize can be 20
char buf[64]; char buf[64];
uint8_t i = 0; uint8_t i = 0;
uint8_t innerLoops = 0; uint8_t innerLoops = 0;
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if (base < 2) base = 10; if (base < 2)
base = 10;
// process chunks that fit in "16 bit math". // process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base; uint16_t top = 0xFFFF / base;
uint16_t th16 = 1; uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}
while (n64 > th16) while (th16 < top)
{ {
// 64 bit math part th16 *= base;
uint64_t q = n64 / th16; innerLoops++;
uint16_t r = n64 - q*th16; }
n64 = q;
// 16 bit math loop to do remainder. (note buffer is filled reverse) while (n64 > th16)
for (uint8_t j=0; j < innerLoops; j++) {
{ // 64 bit math part
uint16_t qq = r/base; uint64_t q = n64 / th16;
buf[i++] = r - qq*base; uint16_t r = n64 - q * th16;
r = qq; n64 = q;
}
}
uint16_t n16 = n64; // 16 bit math loop to do remainder. (note buffer is filled reverse)
while (n16 > 0) for (uint8_t j = 0; j < innerLoops; j++)
{ {
uint16_t qq = n16/base; uint16_t qq = r / base;
buf[i++] = n16 - qq*base; buf[i++] = r - qq * base;
n16 = qq; r = qq;
} }
}
size_t bytes = i; uint16_t n16 = n64;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes; while (n16 > 0)
{
uint16_t qq = n16 / base;
buf[i++] = n16 - qq * base;
n16 = qq;
}
size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
return bytes;
} }
size_t Print::printFloat(double number, int digits) size_t Print::printFloat(double number, int digits)
{ {
if (digits < 0) if (digits < 0)
digits = 2; digits = 2;
size_t n = 0; size_t n = 0;
if (isnan(number)) return print("nan"); if (isnan(number))
if (isinf(number)) return print("inf"); return print("nan");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers if (isinf(number))
if (number < 0.0) return print("inf");
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00" if (number > 4294967040.0)
double rounding = 0.5; return print ("ovf"); // constant determined empirically
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding; if (number < -4294967040.0)
return print ("ovf"); // constant determined empirically
// Extract the integer part of the number and print it // Handle negative numbers
unsigned long int_part = (unsigned long)number; if (number < 0.0)
double remainder = number - (double)int_part; {
n += print(int_part); n += print('-');
number = -number;
}
// Print the decimal point, but only if there are digits beyond // Round correctly so that print(1.999, 2) prints as "2.00"
if (digits > 0) { double rounding = 0.5;
n += print(".");
}
// Extract digits from the remainder one at a time for (uint8_t i = 0; i < digits; ++i)
while (digits-- > 0) rounding /= 10.0;
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n; number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
{
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
} }
size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBuffer(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if ( i != 0 ) print(delim); if ( i != 0 )
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[i]);
}
return (len * 3 - 1);
} }
size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline) size_t Print::printBufferReverse(uint8_t const buffer[], int len, char delim, int byteline)
{ {
if (buffer == NULL || len == 0) return 0; if (buffer == NULL || len == 0)
return 0;
for(int i=0; i<len; i++) for (int i = 0; i < len; i++)
{ {
if (i != 0) print(delim); if (i != 0)
if ( byteline && (i%byteline == 0) ) println(); print(delim);
this->printf("%02X", buffer[len-1-i]); if ( byteline && (i % byteline == 0) )
} println();
return (len*3 - 1); this->printf("%02X", buffer[len - 1 - i]);
}
return (len * 3 - 1);
} }

View File

@@ -32,77 +32,93 @@
class Print class Print
{ {
private: private:
int write_error; int write_error;
size_t printNumber(unsigned long, uint8_t); size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t); size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int); size_t printFloat(double, int);
protected: protected:
void setWriteError(int err = 1) { write_error = err; } void setWriteError(int err = 1)
public: {
Print() : write_error(0) {} write_error = err;
}
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; } int getWriteError()
void clearWriteError() { setWriteError(0); } {
return write_error;
}
void clearWriteError()
{
setWriteError(0);
}
virtual size_t write(uint8_t) = 0; virtual size_t write(uint8_t) = 0;
size_t write(const char *str) { size_t write(const char *str)
if (str == NULL) return 0; {
return write((const uint8_t *)str, strlen(str)); if (str == NULL)
} return 0;
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block" return write((const uint8_t *)str, strlen(str));
// should be overridden by subclasses with buffering }
virtual int availableForWrite() { return 0; } virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size)
{
return write((const uint8_t *)buffer, size);
}
size_t print(const __FlashStringHelper *); // default to zero, meaning "a single write may block"
size_t print(const String &); // should be overridden by subclasses with buffering
size_t print(const char[]); virtual int availableForWrite()
size_t print(char); {
size_t print(unsigned char, int = DEC); return 0;
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 print(const Printable&);
size_t println(const __FlashStringHelper *); size_t print(const __FlashStringHelper *);
size_t println(const String &s); size_t print(const String &);
size_t println(const char[]); size_t print(const char[]);
size_t println(char); size_t print(char);
size_t println(unsigned char, int = DEC); size_t print(unsigned char, int = DEC);
size_t println(int, int = DEC); size_t print(int, int = DEC);
size_t println(unsigned int, int = DEC); size_t print(unsigned int, int = DEC);
size_t println(long, int = DEC); size_t print(long, int = DEC);
size_t println(unsigned long, int = DEC); size_t print(unsigned long, int = DEC);
size_t println(long long, int = DEC); size_t print(long long, int = DEC);
size_t println(unsigned long long, int = DEC); size_t print(unsigned long long, int = DEC);
size_t println(double, int = 2); size_t print(double, int = 2);
size_t println(const Printable&); size_t print(const Printable&);
size_t println(void);
size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim=' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim=' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim=' ', int byteline = 0); size_t println(const __FlashStringHelper *);
size_t printBufferReverse(char const buffer[], int size, char delim=' ', int byteline = 0) size_t println(const String &s);
{ size_t println(const char[]);
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline); 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(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ } size_t printf(const char * format, ...);
size_t printBuffer(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBuffer(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBuffer((uint8_t const*) buffer, size, delim, byteline);
}
size_t printBufferReverse(uint8_t const buffer[], int len, char delim = ' ', int byteline = 0);
size_t printBufferReverse(char const buffer[], int size, char delim = ' ', int byteline = 0)
{
return printBufferReverse((uint8_t const*) buffer, size, delim, byteline);
}
virtual void flush() { /* Empty implementation for backward compatibility */ }
}; };

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -1,217 +1,273 @@
#include "MbedUdp.h" #include "MbedUdp.h"
arduino::MbedUDP::MbedUDP() { arduino::MbedUDP::MbedUDP()
_packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE]; {
_current_packet = NULL; _packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE];
_current_packet_size = 0; _current_packet = NULL;
// if this allocation fails then ::begin will fail _current_packet_size = 0;
// if this allocation fails then ::begin will fail
} }
arduino::MbedUDP::~MbedUDP() { arduino::MbedUDP::~MbedUDP()
delete[] _packet_buffer; {
delete[] _packet_buffer;
} }
uint8_t arduino::MbedUDP::begin(uint16_t port) { uint8_t arduino::MbedUDP::begin(uint16_t port)
// success = 1, fail = 0 {
// success = 1, fail = 0
nsapi_error_t rt = _socket.open(getNetwork()); nsapi_error_t rt = _socket.open(getNetwork());
if (rt != NSAPI_ERROR_OK) {
return 0;
}
if (_socket.bind(port) < 0) { if (rt != NSAPI_ERROR_OK)
return 0; //Failed to bind UDP Socket to port {
} return 0;
}
if (!_packet_buffer) { if (_socket.bind(port) < 0)
return 0; {
} return 0; //Failed to bind UDP Socket to port
}
_socket.set_blocking(false); if (!_packet_buffer)
_socket.set_timeout(0); {
return 0;
}
return 1; _socket.set_blocking(false);
_socket.set_timeout(0);
return 1;
} }
uint8_t arduino::MbedUDP::beginMulticast(IPAddress ip, uint16_t port) { uint8_t arduino::MbedUDP::beginMulticast(IPAddress ip, uint16_t port)
// success = 1, fail = 0 {
if (begin(port) != 1) { // success = 1, fail = 0
return 0; if (begin(port) != 1)
} {
return 0;
}
SocketAddress socketAddress = SocketHelpers::socketAddressFromIpAddress(ip, port); SocketAddress socketAddress = SocketHelpers::socketAddressFromIpAddress(ip, port);
if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK) { if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK)
printf("Error joining the multicast group\n"); {
return 0; printf("Error joining the multicast group\n");
} return 0;
}
return 1; return 1;
} }
void arduino::MbedUDP::stop() { void arduino::MbedUDP::stop()
_socket.close(); {
_socket.close();
} }
int arduino::MbedUDP::beginPacket(IPAddress ip, uint16_t port) { int arduino::MbedUDP::beginPacket(IPAddress ip, uint16_t port)
_host = SocketHelpers::socketAddressFromIpAddress(ip, port); {
//If IP is null and port is 0 the initialization failed _host = SocketHelpers::socketAddressFromIpAddress(ip, port);
txBuffer.clear(); //If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; txBuffer.clear();
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
} }
int arduino::MbedUDP::beginPacket(const char *host, uint16_t port) { int arduino::MbedUDP::beginPacket(const char *host, uint16_t port)
_host = SocketAddress(host, port); {
txBuffer.clear(); _host = SocketAddress(host, port);
getNetwork()->gethostbyname(host, &_host); txBuffer.clear();
//If IP is null and port is 0 the initialization failed getNetwork()->gethostbyname(host, &_host);
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; //If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
} }
int arduino::MbedUDP::endPacket() { int arduino::MbedUDP::endPacket()
_socket.set_blocking(true); {
_socket.set_timeout(1000); _socket.set_blocking(true);
_socket.set_timeout(1000);
size_t size = txBuffer.available(); size_t size = txBuffer.available();
uint8_t buffer[size]; uint8_t buffer[size];
for (int i = 0; i < size; i++) {
buffer[i] = txBuffer.read_char();
}
nsapi_size_or_error_t ret = _socket.sendto(_host, buffer, size); for (int i = 0; i < size; i++)
_socket.set_blocking(false); {
_socket.set_timeout(0); buffer[i] = txBuffer.read_char();
if (ret < 0) { }
return 0;
} nsapi_size_or_error_t ret = _socket.sendto(_host, buffer, size);
return size; _socket.set_blocking(false);
_socket.set_timeout(0);
if (ret < 0)
{
return 0;
}
return size;
} }
// Write a single byte into the packet // Write a single byte into the packet
size_t arduino::MbedUDP::write(uint8_t byte) { size_t arduino::MbedUDP::write(uint8_t byte)
return write(&byte, 1); {
return write(&byte, 1);
} }
// Write size bytes from buffer into the packet // Write size bytes from buffer into the packet
size_t arduino::MbedUDP::write(const uint8_t *buffer, size_t size) { size_t arduino::MbedUDP::write(const uint8_t *buffer, size_t size)
for (int i = 0; i<size; i++) { {
if (txBuffer.availableForStore()) { for (int i = 0; i < size; i++)
txBuffer.store_char(buffer[i]); {
} else { if (txBuffer.availableForStore())
return 0; {
} txBuffer.store_char(buffer[i]);
} }
return size; else
{
return 0;
}
}
return size;
} }
int arduino::MbedUDP::parsePacket() { int arduino::MbedUDP::parsePacket()
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE); {
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE);
if (ret == NSAPI_ERROR_WOULD_BLOCK) { if (ret == NSAPI_ERROR_WOULD_BLOCK)
// no data {
return 0; // no data
} else if (ret == NSAPI_ERROR_NO_SOCKET) { return 0;
// socket was not created correctly. }
return -1; else if (ret == NSAPI_ERROR_NO_SOCKET)
} {
// error codes below zero are errors // socket was not created correctly.
else if (ret <= 0) { return -1;
// something else went wrong, need some tracing info... }
return -1; // error codes below zero are errors
} else if (ret <= 0)
{
// something else went wrong, need some tracing info...
return -1;
}
// set current packet states // set current packet states
_current_packet = _packet_buffer; _current_packet = _packet_buffer;
_current_packet_size = ret; _current_packet_size = ret;
return _current_packet_size; return _current_packet_size;
} }
int arduino::MbedUDP::available() { int arduino::MbedUDP::available()
return _current_packet_size; {
return _current_packet_size;
} }
// Read a single byte from the current packet // Read a single byte from the current packet
int arduino::MbedUDP::read() { int arduino::MbedUDP::read()
// no current packet... {
if (_current_packet == NULL) { // no current packet...
// try reading the next frame, if there is no data return if (_current_packet == NULL)
if (parsePacket() == 0) return -1; {
} // try reading the next frame, if there is no data return
if (parsePacket() == 0)
return -1;
}
_current_packet++; _current_packet++;
// check for overflow // check for overflow
if (_current_packet > _packet_buffer + _current_packet_size) { if (_current_packet > _packet_buffer + _current_packet_size)
// try reading the next packet... {
if (parsePacket() > 0) { // try reading the next packet...
// if so, read first byte of next packet; if (parsePacket() > 0)
return read(); {
} else { // if so, read first byte of next packet;
// no new data... not sure what to return here now return read();
return -1; }
} else
} {
// no new data... not sure what to return here now
return -1;
}
}
return _current_packet[0]; return _current_packet[0];
} }
// Read up to len bytes from the current packet and place them into buffer // Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available // Returns the number of bytes read, or 0 if none are available
int arduino::MbedUDP::read(unsigned char *buffer, size_t len) { int arduino::MbedUDP::read(unsigned char *buffer, size_t len)
// Q: does Arduino read() function handle fragmentation? I won't for now... {
if (_current_packet == NULL) { // Q: does Arduino read() function handle fragmentation? I won't for now...
if (parsePacket() == 0) return 0; if (_current_packet == NULL)
} {
if (parsePacket() == 0)
return 0;
}
// how much data do we have in the current packet? // how much data do we have in the current packet?
int offset = _current_packet - _packet_buffer; int offset = _current_packet - _packet_buffer;
if (offset < 0) {
return 0;
}
int max_bytes = _current_packet_size - offset; if (offset < 0)
if (max_bytes < 0) { {
return 0; return 0;
} }
// at the end of the packet? int max_bytes = _current_packet_size - offset;
if (max_bytes == 0) {
// try read next packet...
if (parsePacket() > 0) {
return read(buffer, len);
} else {
return 0;
}
}
if (len > (size_t)max_bytes) len = max_bytes; if (max_bytes < 0)
{
return 0;
}
// copy to target buffer // at the end of the packet?
memcpy(buffer, _current_packet, len); if (max_bytes == 0)
{
// try read next packet...
if (parsePacket() > 0)
{
return read(buffer, len);
}
else
{
return 0;
}
}
_current_packet += len; if (len > (size_t)max_bytes)
len = max_bytes;
return len; // copy to target buffer
memcpy(buffer, _current_packet, len);
_current_packet += len;
return len;
} }
IPAddress arduino::MbedUDP::remoteIP() { IPAddress arduino::MbedUDP::remoteIP()
nsapi_addr_t address = _remoteHost.get_addr(); {
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); nsapi_addr_t address = _remoteHost.get_addr();
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]);
} }
uint16_t arduino::MbedUDP::remotePort() { uint16_t arduino::MbedUDP::remotePort()
return _remoteHost.get_port(); {
return _remoteHost.get_port();
} }
void arduino::MbedUDP::flush() { void arduino::MbedUDP::flush()
// TODO: a real check to ensure transmission has been completed {
// TODO: a real check to ensure transmission has been completed
} }
int arduino::MbedUDP::peek() { int arduino::MbedUDP::peek()
if (_current_packet_size < 1) { {
return -1; if (_current_packet_size < 1)
} {
return -1;
}
return _current_packet[0]; return _current_packet[0];
} }

View File

@@ -25,79 +25,82 @@
#include "netsocket/UDPSocket.h" #include "netsocket/UDPSocket.h"
#ifndef WIFI_UDP_BUFFER_SIZE #ifndef WIFI_UDP_BUFFER_SIZE
#define WIFI_UDP_BUFFER_SIZE 508 #define WIFI_UDP_BUFFER_SIZE 508
#endif #endif
namespace arduino { namespace arduino
{
class MbedUDP : public UDP { class MbedUDP : public UDP
private: {
UDPSocket _socket; // Mbed OS socket private:
SocketAddress _host; // Host to be used to send data UDPSocket _socket; // Mbed OS socket
SocketAddress _remoteHost; // Remote host that sent incoming packets SocketAddress _host; // Host to be used to send data
SocketAddress _remoteHost; // Remote host that sent incoming packets
uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket) uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket)
// The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet // The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet
// these two variables are used to cache the state of the current packet // these two variables are used to cache the state of the current packet
uint8_t* _current_packet; uint8_t* _current_packet;
size_t _current_packet_size; size_t _current_packet_size;
RingBufferN<WIFI_UDP_BUFFER_SIZE> txBuffer; RingBufferN<WIFI_UDP_BUFFER_SIZE> txBuffer;
protected: protected:
virtual NetworkInterface* getNetwork() = 0; virtual NetworkInterface* getNetwork() = 0;
public: public:
MbedUDP(); // Constructor MbedUDP(); // Constructor
~MbedUDP(); ~MbedUDP();
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop(); // Finish with the UDP socket virtual void stop(); // Finish with the UDP socket
// Sending UDP packets // Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port // Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port); virtual int beginPacket(IPAddress ip, uint16_t port);
// Start building up a packet to send to the remote host specific in host and port // Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char* host, uint16_t port); virtual int beginPacket(const char* host, uint16_t port);
// Finish off this packet and send it // Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error // Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket(); virtual int endPacket();
// Write a single byte into the packet // Write a single byte into the packet
virtual size_t write(uint8_t); virtual size_t write(uint8_t);
// Write size bytes from buffer into the packet // Write size bytes from buffer into the packet
virtual size_t write(const uint8_t* buffer, size_t size); virtual size_t write(const uint8_t* buffer, size_t size);
using Print::write; using Print::write;
// Start processing the next available incoming packet // Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available // Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket(); virtual int parsePacket();
// Number of bytes remaining in the current packet // Number of bytes remaining in the current packet
virtual int available(); virtual int available();
// Read a single byte from the current packet // Read a single byte from the current packet
virtual int read(); virtual int read();
// Read up to len bytes from the current packet and place them into buffer // Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available // Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len); virtual int read(unsigned char* buffer, size_t len);
// Read up to len characters from the current packet and place them into buffer // Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available // Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) { virtual int read(char* buffer, size_t len)
return read((unsigned char*)buffer, len); {
}; return read((unsigned char*)buffer, len);
// Return the next byte from the current packet without moving on to the next byte };
virtual int peek(); // Return the next byte from the current packet without moving on to the next byte
virtual void flush(); // Finish reading the current packet virtual int peek();
virtual void flush(); // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet // Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP(); virtual IPAddress remoteIP();
// // Return the port of the host who sent the current incoming packet // // Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort(); virtual uint16_t remotePort();
friend class MbedSocketClass; friend class MbedSocketClass;
}; };
} }

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -1,217 +1,273 @@
#include "MbedUdp.h" #include "MbedUdp.h"
arduino::MbedUDP::MbedUDP() { arduino::MbedUDP::MbedUDP()
_packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE]; {
_current_packet = NULL; _packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE];
_current_packet_size = 0; _current_packet = NULL;
// if this allocation fails then ::begin will fail _current_packet_size = 0;
// if this allocation fails then ::begin will fail
} }
arduino::MbedUDP::~MbedUDP() { arduino::MbedUDP::~MbedUDP()
delete[] _packet_buffer; {
delete[] _packet_buffer;
} }
uint8_t arduino::MbedUDP::begin(uint16_t port) { uint8_t arduino::MbedUDP::begin(uint16_t port)
// success = 1, fail = 0 {
// success = 1, fail = 0
nsapi_error_t rt = _socket.open(getNetwork()); nsapi_error_t rt = _socket.open(getNetwork());
if (rt != NSAPI_ERROR_OK) {
return 0;
}
if (_socket.bind(port) < 0) { if (rt != NSAPI_ERROR_OK)
return 0; //Failed to bind UDP Socket to port {
} return 0;
}
if (!_packet_buffer) { if (_socket.bind(port) < 0)
return 0; {
} return 0; //Failed to bind UDP Socket to port
}
_socket.set_blocking(false); if (!_packet_buffer)
_socket.set_timeout(0); {
return 0;
}
return 1; _socket.set_blocking(false);
_socket.set_timeout(0);
return 1;
} }
uint8_t arduino::MbedUDP::beginMulticast(IPAddress ip, uint16_t port) { uint8_t arduino::MbedUDP::beginMulticast(IPAddress ip, uint16_t port)
// success = 1, fail = 0 {
if (begin(port) != 1) { // success = 1, fail = 0
return 0; if (begin(port) != 1)
} {
return 0;
}
SocketAddress socketAddress = SocketHelpers::socketAddressFromIpAddress(ip, port); SocketAddress socketAddress = SocketHelpers::socketAddressFromIpAddress(ip, port);
if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK) { if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK)
printf("Error joining the multicast group\n"); {
return 0; printf("Error joining the multicast group\n");
} return 0;
}
return 1; return 1;
} }
void arduino::MbedUDP::stop() { void arduino::MbedUDP::stop()
_socket.close(); {
_socket.close();
} }
int arduino::MbedUDP::beginPacket(IPAddress ip, uint16_t port) { int arduino::MbedUDP::beginPacket(IPAddress ip, uint16_t port)
_host = SocketHelpers::socketAddressFromIpAddress(ip, port); {
//If IP is null and port is 0 the initialization failed _host = SocketHelpers::socketAddressFromIpAddress(ip, port);
txBuffer.clear(); //If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; txBuffer.clear();
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
} }
int arduino::MbedUDP::beginPacket(const char *host, uint16_t port) { int arduino::MbedUDP::beginPacket(const char *host, uint16_t port)
_host = SocketAddress(host, port); {
txBuffer.clear(); _host = SocketAddress(host, port);
getNetwork()->gethostbyname(host, &_host); txBuffer.clear();
//If IP is null and port is 0 the initialization failed getNetwork()->gethostbyname(host, &_host);
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; //If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
} }
int arduino::MbedUDP::endPacket() { int arduino::MbedUDP::endPacket()
_socket.set_blocking(true); {
_socket.set_timeout(1000); _socket.set_blocking(true);
_socket.set_timeout(1000);
size_t size = txBuffer.available(); size_t size = txBuffer.available();
uint8_t buffer[size]; uint8_t buffer[size];
for (int i = 0; i < size; i++) {
buffer[i] = txBuffer.read_char();
}
nsapi_size_or_error_t ret = _socket.sendto(_host, buffer, size); for (int i = 0; i < size; i++)
_socket.set_blocking(false); {
_socket.set_timeout(0); buffer[i] = txBuffer.read_char();
if (ret < 0) { }
return 0;
} nsapi_size_or_error_t ret = _socket.sendto(_host, buffer, size);
return size; _socket.set_blocking(false);
_socket.set_timeout(0);
if (ret < 0)
{
return 0;
}
return size;
} }
// Write a single byte into the packet // Write a single byte into the packet
size_t arduino::MbedUDP::write(uint8_t byte) { size_t arduino::MbedUDP::write(uint8_t byte)
return write(&byte, 1); {
return write(&byte, 1);
} }
// Write size bytes from buffer into the packet // Write size bytes from buffer into the packet
size_t arduino::MbedUDP::write(const uint8_t *buffer, size_t size) { size_t arduino::MbedUDP::write(const uint8_t *buffer, size_t size)
for (int i = 0; i<size; i++) { {
if (txBuffer.availableForStore()) { for (int i = 0; i < size; i++)
txBuffer.store_char(buffer[i]); {
} else { if (txBuffer.availableForStore())
return 0; {
} txBuffer.store_char(buffer[i]);
} }
return size; else
{
return 0;
}
}
return size;
} }
int arduino::MbedUDP::parsePacket() { int arduino::MbedUDP::parsePacket()
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE); {
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE);
if (ret == NSAPI_ERROR_WOULD_BLOCK) { if (ret == NSAPI_ERROR_WOULD_BLOCK)
// no data {
return 0; // no data
} else if (ret == NSAPI_ERROR_NO_SOCKET) { return 0;
// socket was not created correctly. }
return -1; else if (ret == NSAPI_ERROR_NO_SOCKET)
} {
// error codes below zero are errors // socket was not created correctly.
else if (ret <= 0) { return -1;
// something else went wrong, need some tracing info... }
return -1; // error codes below zero are errors
} else if (ret <= 0)
{
// something else went wrong, need some tracing info...
return -1;
}
// set current packet states // set current packet states
_current_packet = _packet_buffer; _current_packet = _packet_buffer;
_current_packet_size = ret; _current_packet_size = ret;
return _current_packet_size; return _current_packet_size;
} }
int arduino::MbedUDP::available() { int arduino::MbedUDP::available()
return _current_packet_size; {
return _current_packet_size;
} }
// Read a single byte from the current packet // Read a single byte from the current packet
int arduino::MbedUDP::read() { int arduino::MbedUDP::read()
// no current packet... {
if (_current_packet == NULL) { // no current packet...
// try reading the next frame, if there is no data return if (_current_packet == NULL)
if (parsePacket() == 0) return -1; {
} // try reading the next frame, if there is no data return
if (parsePacket() == 0)
return -1;
}
_current_packet++; _current_packet++;
// check for overflow // check for overflow
if (_current_packet > _packet_buffer + _current_packet_size) { if (_current_packet > _packet_buffer + _current_packet_size)
// try reading the next packet... {
if (parsePacket() > 0) { // try reading the next packet...
// if so, read first byte of next packet; if (parsePacket() > 0)
return read(); {
} else { // if so, read first byte of next packet;
// no new data... not sure what to return here now return read();
return -1; }
} else
} {
// no new data... not sure what to return here now
return -1;
}
}
return _current_packet[0]; return _current_packet[0];
} }
// Read up to len bytes from the current packet and place them into buffer // Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available // Returns the number of bytes read, or 0 if none are available
int arduino::MbedUDP::read(unsigned char *buffer, size_t len) { int arduino::MbedUDP::read(unsigned char *buffer, size_t len)
// Q: does Arduino read() function handle fragmentation? I won't for now... {
if (_current_packet == NULL) { // Q: does Arduino read() function handle fragmentation? I won't for now...
if (parsePacket() == 0) return 0; if (_current_packet == NULL)
} {
if (parsePacket() == 0)
return 0;
}
// how much data do we have in the current packet? // how much data do we have in the current packet?
int offset = _current_packet - _packet_buffer; int offset = _current_packet - _packet_buffer;
if (offset < 0) {
return 0;
}
int max_bytes = _current_packet_size - offset; if (offset < 0)
if (max_bytes < 0) { {
return 0; return 0;
} }
// at the end of the packet? int max_bytes = _current_packet_size - offset;
if (max_bytes == 0) {
// try read next packet...
if (parsePacket() > 0) {
return read(buffer, len);
} else {
return 0;
}
}
if (len > (size_t)max_bytes) len = max_bytes; if (max_bytes < 0)
{
return 0;
}
// copy to target buffer // at the end of the packet?
memcpy(buffer, _current_packet, len); if (max_bytes == 0)
{
// try read next packet...
if (parsePacket() > 0)
{
return read(buffer, len);
}
else
{
return 0;
}
}
_current_packet += len; if (len > (size_t)max_bytes)
len = max_bytes;
return len; // copy to target buffer
memcpy(buffer, _current_packet, len);
_current_packet += len;
return len;
} }
IPAddress arduino::MbedUDP::remoteIP() { IPAddress arduino::MbedUDP::remoteIP()
nsapi_addr_t address = _remoteHost.get_addr(); {
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); nsapi_addr_t address = _remoteHost.get_addr();
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]);
} }
uint16_t arduino::MbedUDP::remotePort() { uint16_t arduino::MbedUDP::remotePort()
return _remoteHost.get_port(); {
return _remoteHost.get_port();
} }
void arduino::MbedUDP::flush() { void arduino::MbedUDP::flush()
// TODO: a real check to ensure transmission has been completed {
// TODO: a real check to ensure transmission has been completed
} }
int arduino::MbedUDP::peek() { int arduino::MbedUDP::peek()
if (_current_packet_size < 1) { {
return -1; if (_current_packet_size < 1)
} {
return -1;
}
return _current_packet[0]; return _current_packet[0];
} }

View File

@@ -25,79 +25,82 @@
#include "netsocket/UDPSocket.h" #include "netsocket/UDPSocket.h"
#ifndef WIFI_UDP_BUFFER_SIZE #ifndef WIFI_UDP_BUFFER_SIZE
#define WIFI_UDP_BUFFER_SIZE 508 #define WIFI_UDP_BUFFER_SIZE 508
#endif #endif
namespace arduino { namespace arduino
{
class MbedUDP : public UDP { class MbedUDP : public UDP
private: {
UDPSocket _socket; // Mbed OS socket private:
SocketAddress _host; // Host to be used to send data UDPSocket _socket; // Mbed OS socket
SocketAddress _remoteHost; // Remote host that sent incoming packets SocketAddress _host; // Host to be used to send data
SocketAddress _remoteHost; // Remote host that sent incoming packets
uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket) uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket)
// The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet // The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet
// these two variables are used to cache the state of the current packet // these two variables are used to cache the state of the current packet
uint8_t* _current_packet; uint8_t* _current_packet;
size_t _current_packet_size; size_t _current_packet_size;
RingBufferN<WIFI_UDP_BUFFER_SIZE> txBuffer; RingBufferN<WIFI_UDP_BUFFER_SIZE> txBuffer;
protected: protected:
virtual NetworkInterface* getNetwork() = 0; virtual NetworkInterface* getNetwork() = 0;
public: public:
MbedUDP(); // Constructor MbedUDP(); // Constructor
~MbedUDP(); ~MbedUDP();
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop(); // Finish with the UDP socket virtual void stop(); // Finish with the UDP socket
// Sending UDP packets // Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port // Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port); virtual int beginPacket(IPAddress ip, uint16_t port);
// Start building up a packet to send to the remote host specific in host and port // Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char* host, uint16_t port); virtual int beginPacket(const char* host, uint16_t port);
// Finish off this packet and send it // Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error // Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket(); virtual int endPacket();
// Write a single byte into the packet // Write a single byte into the packet
virtual size_t write(uint8_t); virtual size_t write(uint8_t);
// Write size bytes from buffer into the packet // Write size bytes from buffer into the packet
virtual size_t write(const uint8_t* buffer, size_t size); virtual size_t write(const uint8_t* buffer, size_t size);
using Print::write; using Print::write;
// Start processing the next available incoming packet // Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available // Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket(); virtual int parsePacket();
// Number of bytes remaining in the current packet // Number of bytes remaining in the current packet
virtual int available(); virtual int available();
// Read a single byte from the current packet // Read a single byte from the current packet
virtual int read(); virtual int read();
// Read up to len bytes from the current packet and place them into buffer // Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available // Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len); virtual int read(unsigned char* buffer, size_t len);
// Read up to len characters from the current packet and place them into buffer // Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available // Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) { virtual int read(char* buffer, size_t len)
return read((unsigned char*)buffer, len); {
}; return read((unsigned char*)buffer, len);
// Return the next byte from the current packet without moving on to the next byte };
virtual int peek(); // Return the next byte from the current packet without moving on to the next byte
virtual void flush(); // Finish reading the current packet virtual int peek();
virtual void flush(); // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet // Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP(); virtual IPAddress remoteIP();
// // Return the port of the host who sent the current incoming packet // // Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort(); virtual uint16_t remotePort();
friend class MbedSocketClass; friend class MbedSocketClass;
}; };
} }

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -1,217 +1,273 @@
#include "MbedUdp.h" #include "MbedUdp.h"
arduino::MbedUDP::MbedUDP() { arduino::MbedUDP::MbedUDP()
_packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE]; {
_current_packet = NULL; _packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE];
_current_packet_size = 0; _current_packet = NULL;
// if this allocation fails then ::begin will fail _current_packet_size = 0;
// if this allocation fails then ::begin will fail
} }
arduino::MbedUDP::~MbedUDP() { arduino::MbedUDP::~MbedUDP()
delete[] _packet_buffer; {
delete[] _packet_buffer;
} }
uint8_t arduino::MbedUDP::begin(uint16_t port) { uint8_t arduino::MbedUDP::begin(uint16_t port)
// success = 1, fail = 0 {
// success = 1, fail = 0
nsapi_error_t rt = _socket.open(getNetwork()); nsapi_error_t rt = _socket.open(getNetwork());
if (rt != NSAPI_ERROR_OK) {
return 0;
}
if (_socket.bind(port) < 0) { if (rt != NSAPI_ERROR_OK)
return 0; //Failed to bind UDP Socket to port {
} return 0;
}
if (!_packet_buffer) { if (_socket.bind(port) < 0)
return 0; {
} return 0; //Failed to bind UDP Socket to port
}
_socket.set_blocking(false); if (!_packet_buffer)
_socket.set_timeout(0); {
return 0;
}
return 1; _socket.set_blocking(false);
_socket.set_timeout(0);
return 1;
} }
uint8_t arduino::MbedUDP::beginMulticast(IPAddress ip, uint16_t port) { uint8_t arduino::MbedUDP::beginMulticast(IPAddress ip, uint16_t port)
// success = 1, fail = 0 {
if (begin(port) != 1) { // success = 1, fail = 0
return 0; if (begin(port) != 1)
} {
return 0;
}
SocketAddress socketAddress = SocketHelpers::socketAddressFromIpAddress(ip, port); SocketAddress socketAddress = SocketHelpers::socketAddressFromIpAddress(ip, port);
if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK) { if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK)
printf("Error joining the multicast group\n"); {
return 0; printf("Error joining the multicast group\n");
} return 0;
}
return 1; return 1;
} }
void arduino::MbedUDP::stop() { void arduino::MbedUDP::stop()
_socket.close(); {
_socket.close();
} }
int arduino::MbedUDP::beginPacket(IPAddress ip, uint16_t port) { int arduino::MbedUDP::beginPacket(IPAddress ip, uint16_t port)
_host = SocketHelpers::socketAddressFromIpAddress(ip, port); {
//If IP is null and port is 0 the initialization failed _host = SocketHelpers::socketAddressFromIpAddress(ip, port);
txBuffer.clear(); //If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; txBuffer.clear();
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
} }
int arduino::MbedUDP::beginPacket(const char *host, uint16_t port) { int arduino::MbedUDP::beginPacket(const char *host, uint16_t port)
_host = SocketAddress(host, port); {
txBuffer.clear(); _host = SocketAddress(host, port);
getNetwork()->gethostbyname(host, &_host); txBuffer.clear();
//If IP is null and port is 0 the initialization failed getNetwork()->gethostbyname(host, &_host);
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; //If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
} }
int arduino::MbedUDP::endPacket() { int arduino::MbedUDP::endPacket()
_socket.set_blocking(true); {
_socket.set_timeout(1000); _socket.set_blocking(true);
_socket.set_timeout(1000);
size_t size = txBuffer.available(); size_t size = txBuffer.available();
uint8_t buffer[size]; uint8_t buffer[size];
for (int i = 0; i < size; i++) {
buffer[i] = txBuffer.read_char();
}
nsapi_size_or_error_t ret = _socket.sendto(_host, buffer, size); for (int i = 0; i < size; i++)
_socket.set_blocking(false); {
_socket.set_timeout(0); buffer[i] = txBuffer.read_char();
if (ret < 0) { }
return 0;
} nsapi_size_or_error_t ret = _socket.sendto(_host, buffer, size);
return size; _socket.set_blocking(false);
_socket.set_timeout(0);
if (ret < 0)
{
return 0;
}
return size;
} }
// Write a single byte into the packet // Write a single byte into the packet
size_t arduino::MbedUDP::write(uint8_t byte) { size_t arduino::MbedUDP::write(uint8_t byte)
return write(&byte, 1); {
return write(&byte, 1);
} }
// Write size bytes from buffer into the packet // Write size bytes from buffer into the packet
size_t arduino::MbedUDP::write(const uint8_t *buffer, size_t size) { size_t arduino::MbedUDP::write(const uint8_t *buffer, size_t size)
for (int i = 0; i<size; i++) { {
if (txBuffer.availableForStore()) { for (int i = 0; i < size; i++)
txBuffer.store_char(buffer[i]); {
} else { if (txBuffer.availableForStore())
return 0; {
} txBuffer.store_char(buffer[i]);
} }
return size; else
{
return 0;
}
}
return size;
} }
int arduino::MbedUDP::parsePacket() { int arduino::MbedUDP::parsePacket()
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE); {
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE);
if (ret == NSAPI_ERROR_WOULD_BLOCK) { if (ret == NSAPI_ERROR_WOULD_BLOCK)
// no data {
return 0; // no data
} else if (ret == NSAPI_ERROR_NO_SOCKET) { return 0;
// socket was not created correctly. }
return -1; else if (ret == NSAPI_ERROR_NO_SOCKET)
} {
// error codes below zero are errors // socket was not created correctly.
else if (ret <= 0) { return -1;
// something else went wrong, need some tracing info... }
return -1; // error codes below zero are errors
} else if (ret <= 0)
{
// something else went wrong, need some tracing info...
return -1;
}
// set current packet states // set current packet states
_current_packet = _packet_buffer; _current_packet = _packet_buffer;
_current_packet_size = ret; _current_packet_size = ret;
return _current_packet_size; return _current_packet_size;
} }
int arduino::MbedUDP::available() { int arduino::MbedUDP::available()
return _current_packet_size; {
return _current_packet_size;
} }
// Read a single byte from the current packet // Read a single byte from the current packet
int arduino::MbedUDP::read() { int arduino::MbedUDP::read()
// no current packet... {
if (_current_packet == NULL) { // no current packet...
// try reading the next frame, if there is no data return if (_current_packet == NULL)
if (parsePacket() == 0) return -1; {
} // try reading the next frame, if there is no data return
if (parsePacket() == 0)
return -1;
}
_current_packet++; _current_packet++;
// check for overflow // check for overflow
if (_current_packet > _packet_buffer + _current_packet_size) { if (_current_packet > _packet_buffer + _current_packet_size)
// try reading the next packet... {
if (parsePacket() > 0) { // try reading the next packet...
// if so, read first byte of next packet; if (parsePacket() > 0)
return read(); {
} else { // if so, read first byte of next packet;
// no new data... not sure what to return here now return read();
return -1; }
} else
} {
// no new data... not sure what to return here now
return -1;
}
}
return _current_packet[0]; return _current_packet[0];
} }
// Read up to len bytes from the current packet and place them into buffer // Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available // Returns the number of bytes read, or 0 if none are available
int arduino::MbedUDP::read(unsigned char *buffer, size_t len) { int arduino::MbedUDP::read(unsigned char *buffer, size_t len)
// Q: does Arduino read() function handle fragmentation? I won't for now... {
if (_current_packet == NULL) { // Q: does Arduino read() function handle fragmentation? I won't for now...
if (parsePacket() == 0) return 0; if (_current_packet == NULL)
} {
if (parsePacket() == 0)
return 0;
}
// how much data do we have in the current packet? // how much data do we have in the current packet?
int offset = _current_packet - _packet_buffer; int offset = _current_packet - _packet_buffer;
if (offset < 0) {
return 0;
}
int max_bytes = _current_packet_size - offset; if (offset < 0)
if (max_bytes < 0) { {
return 0; return 0;
} }
// at the end of the packet? int max_bytes = _current_packet_size - offset;
if (max_bytes == 0) {
// try read next packet...
if (parsePacket() > 0) {
return read(buffer, len);
} else {
return 0;
}
}
if (len > (size_t)max_bytes) len = max_bytes; if (max_bytes < 0)
{
return 0;
}
// copy to target buffer // at the end of the packet?
memcpy(buffer, _current_packet, len); if (max_bytes == 0)
{
// try read next packet...
if (parsePacket() > 0)
{
return read(buffer, len);
}
else
{
return 0;
}
}
_current_packet += len; if (len > (size_t)max_bytes)
len = max_bytes;
return len; // copy to target buffer
memcpy(buffer, _current_packet, len);
_current_packet += len;
return len;
} }
IPAddress arduino::MbedUDP::remoteIP() { IPAddress arduino::MbedUDP::remoteIP()
nsapi_addr_t address = _remoteHost.get_addr(); {
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); nsapi_addr_t address = _remoteHost.get_addr();
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]);
} }
uint16_t arduino::MbedUDP::remotePort() { uint16_t arduino::MbedUDP::remotePort()
return _remoteHost.get_port(); {
return _remoteHost.get_port();
} }
void arduino::MbedUDP::flush() { void arduino::MbedUDP::flush()
// TODO: a real check to ensure transmission has been completed {
// TODO: a real check to ensure transmission has been completed
} }
int arduino::MbedUDP::peek() { int arduino::MbedUDP::peek()
if (_current_packet_size < 1) { {
return -1; if (_current_packet_size < 1)
} {
return -1;
}
return _current_packet[0]; return _current_packet[0];
} }

View File

@@ -25,79 +25,82 @@
#include "netsocket/UDPSocket.h" #include "netsocket/UDPSocket.h"
#ifndef WIFI_UDP_BUFFER_SIZE #ifndef WIFI_UDP_BUFFER_SIZE
#define WIFI_UDP_BUFFER_SIZE 508 #define WIFI_UDP_BUFFER_SIZE 508
#endif #endif
namespace arduino { namespace arduino
{
class MbedUDP : public UDP { class MbedUDP : public UDP
private: {
UDPSocket _socket; // Mbed OS socket private:
SocketAddress _host; // Host to be used to send data UDPSocket _socket; // Mbed OS socket
SocketAddress _remoteHost; // Remote host that sent incoming packets SocketAddress _host; // Host to be used to send data
SocketAddress _remoteHost; // Remote host that sent incoming packets
uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket) uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket)
// The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet // The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet
// these two variables are used to cache the state of the current packet // these two variables are used to cache the state of the current packet
uint8_t* _current_packet; uint8_t* _current_packet;
size_t _current_packet_size; size_t _current_packet_size;
RingBufferN<WIFI_UDP_BUFFER_SIZE> txBuffer; RingBufferN<WIFI_UDP_BUFFER_SIZE> txBuffer;
protected: protected:
virtual NetworkInterface* getNetwork() = 0; virtual NetworkInterface* getNetwork() = 0;
public: public:
MbedUDP(); // Constructor MbedUDP(); // Constructor
~MbedUDP(); ~MbedUDP();
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop(); // Finish with the UDP socket virtual void stop(); // Finish with the UDP socket
// Sending UDP packets // Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port // Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port); virtual int beginPacket(IPAddress ip, uint16_t port);
// Start building up a packet to send to the remote host specific in host and port // Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char* host, uint16_t port); virtual int beginPacket(const char* host, uint16_t port);
// Finish off this packet and send it // Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error // Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket(); virtual int endPacket();
// Write a single byte into the packet // Write a single byte into the packet
virtual size_t write(uint8_t); virtual size_t write(uint8_t);
// Write size bytes from buffer into the packet // Write size bytes from buffer into the packet
virtual size_t write(const uint8_t* buffer, size_t size); virtual size_t write(const uint8_t* buffer, size_t size);
using Print::write; using Print::write;
// Start processing the next available incoming packet // Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available // Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket(); virtual int parsePacket();
// Number of bytes remaining in the current packet // Number of bytes remaining in the current packet
virtual int available(); virtual int available();
// Read a single byte from the current packet // Read a single byte from the current packet
virtual int read(); virtual int read();
// Read up to len bytes from the current packet and place them into buffer // Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available // Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len); virtual int read(unsigned char* buffer, size_t len);
// Read up to len characters from the current packet and place them into buffer // Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available // Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) { virtual int read(char* buffer, size_t len)
return read((unsigned char*)buffer, len); {
}; return read((unsigned char*)buffer, len);
// Return the next byte from the current packet without moving on to the next byte };
virtual int peek(); // Return the next byte from the current packet without moving on to the next byte
virtual void flush(); // Finish reading the current packet virtual int peek();
virtual void flush(); // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet // Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP(); virtual IPAddress remoteIP();
// // Return the port of the host who sent the current incoming packet // // Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort(); virtual uint16_t remotePort();
friend class MbedSocketClass; friend class MbedSocketClass;
}; };
} }

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -1,28 +1,28 @@
/* Copyright (C) 2012 mbed.org, MIT License /* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction, and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software. substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef LWIPOPTS_H #ifndef LWIPOPTS_H
#define LWIPOPTS_H #define LWIPOPTS_H
// Workaround for Linux timeval // Workaround for Linux timeval
#if defined (TOOLCHAIN_GCC) #if defined (TOOLCHAIN_GCC)
#define LWIP_TIMEVAL_PRIVATE 0 #define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "nsapi_types.h" #include "nsapi_types.h"
#include "mbed_retarget.h" #include "mbed_retarget.h"
@@ -35,7 +35,7 @@
#define NO_SYS 0 #define NO_SYS 0
#if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED #if !MBED_CONF_LWIP_IPV4_ENABLED && !MBED_CONF_LWIP_IPV6_ENABLED
#error "Either IPv4 or IPv6 must be enabled." #error "Either IPv4 or IPv6 must be enabled."
#endif #endif
#define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED #define LWIP_IPV4 MBED_CONF_LWIP_IPV4_ENABLED
@@ -47,16 +47,16 @@
// On dual stack configuration how long to wait for both or preferred stack // On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up. // addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE #if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0 #define PREF_ADDR_TIMEOUT 0
#else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else #else
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT #define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0 #define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif #endif
@@ -68,52 +68,52 @@
#define PREF_IPV6 2 #define PREF_IPV6 2
#if MBED_CONF_LWIP_IP_VER_PREF == 6 #if MBED_CONF_LWIP_IP_VER_PREF == 6
#define IP_VERSION_PREF PREF_IPV6 #define IP_VERSION_PREF PREF_IPV6
#elif MBED_CONF_LWIP_IP_VER_PREF == 4 #elif MBED_CONF_LWIP_IP_VER_PREF == 4
#define IP_VERSION_PREF PREF_IPV4 #define IP_VERSION_PREF PREF_IPV4
#else #else
#error "Either IPv4 or IPv6 must be preferred." #error "Either IPv4 or IPv6 must be preferred."
#endif #endif
#undef LWIP_DEBUG #undef LWIP_DEBUG
#if MBED_CONF_LWIP_DEBUG_ENABLED #if MBED_CONF_LWIP_DEBUG_ENABLED
#define LWIP_DEBUG 1 #define LWIP_DEBUG 1
#endif #endif
#if NO_SYS == 0 #if NO_SYS == 0
#include "cmsis_os2.h" #include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1 #define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED
#define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT
// Thread stacks use 8-byte alignment // Thread stacks use 8-byte alignment
#define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos)) #define LWIP_ALIGN_UP(pos, align) ((pos) % (align) ? (pos) + ((align) - (pos) % (align)) : (pos))
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
// For LWIP debug, double the stack // For LWIP debug, double the stack
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE*2, 8)
#elif MBED_DEBUG #elif MBED_DEBUG
// When debug is enabled on the build increase stack 25 percent // When debug is enabled on the build increase stack 25 percent
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE + MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE / 4, 8)
#else #else
#define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8) #define TCPIP_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_TCPIP_THREAD_STACKSIZE, 8)
#endif #endif
// Thread priority (osPriorityNormal by default) // Thread priority (osPriorityNormal by default)
#define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY) #define TCPIP_THREAD_PRIO (MBED_CONF_LWIP_TCPIP_THREAD_PRIORITY)
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2, 8)
#else #else
#define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8) #define DEFAULT_THREAD_STACKSIZE LWIP_ALIGN_UP(MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE, 8)
#endif #endif
#define MEMP_NUM_SYS_TIMEOUT 16 #define MEMP_NUM_SYS_TIMEOUT 16
#define sys_msleep(ms) sys_msleep(ms) #define sys_msleep(ms) sys_msleep(ms)
#endif #endif
@@ -143,16 +143,16 @@
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE #define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE #ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE #undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else #else
#ifndef PBUF_POOL_BUFSIZE #ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6 #if LWIP_IPV6
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#elif LWIP_IPV4 #elif LWIP_IPV4
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+20+20+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif #endif
#endif #endif
#endif #endif
#define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE #define MEM_SIZE MBED_CONF_LWIP_MEM_SIZE
@@ -181,14 +181,14 @@
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX #define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
#if MBED_CONF_LWIP_TCP_ENABLED #if MBED_CONF_LWIP_TCP_ENABLED
#define LWIP_TCP 1 #define LWIP_TCP 1
#define TCP_OVERSIZE 0 #define TCP_OVERSIZE 0
#define LWIP_TCP_KEEPALIVE 1 #define LWIP_TCP_KEEPALIVE 1
#define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT #define TCP_CLOSE_TIMEOUT MBED_CONF_LWIP_TCP_CLOSE_TIMEOUT
#else #else
#define LWIP_TCP 0 #define LWIP_TCP 0
#endif #endif
#define LWIP_DNS 1 #define LWIP_DNS 1
@@ -251,13 +251,13 @@
#define UDP_LPC_EMAC LWIP_DBG_OFF #define UDP_LPC_EMAC LWIP_DBG_OFF
#ifdef LWIP_DEBUG #ifdef LWIP_DEBUG
#define MEMP_OVERFLOW_CHECK 1 #define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1 #define MEMP_SANITY_CHECK 1
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#else #else
#define LWIP_NOASSERT 1 #define LWIP_NOASSERT 1
#define LWIP_STATS 0 #define LWIP_STATS 0
#endif #endif
#define TRACE_TO_ASCII_HEX_DUMP 0 #define TRACE_TO_ASCII_HEX_DUMP 0
@@ -269,18 +269,18 @@
// Interface type configuration // Interface type configuration
#if MBED_CONF_LWIP_ETHERNET_ENABLED #if MBED_CONF_LWIP_ETHERNET_ENABLED
#define LWIP_ARP 1 #define LWIP_ARP 1
#define LWIP_ETHERNET 1 #define LWIP_ETHERNET 1
#define LWIP_DHCP LWIP_IPV4 #define LWIP_DHCP LWIP_IPV4
#else #else
#define LWIP_ARP 0 #define LWIP_ARP 0
#define LWIP_ETHERNET 0 #define LWIP_ETHERNET 0
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED #endif // MBED_CONF_LWIP_ETHERNET_ENABLED
#if MBED_CONF_LWIP_L3IP_ENABLED #if MBED_CONF_LWIP_L3IP_ENABLED
#define LWIP_L3IP 1 #define LWIP_L3IP 1
#else #else
#define LWIP_L3IP 0 #define LWIP_L3IP 0
#endif #endif
//Maximum size of network interface name //Maximum size of network interface name
@@ -291,27 +291,27 @@
// Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration // Enable PPP for now either from lwIP PPP configuration (obsolete) or from PPP service configuration
#if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED #if MBED_CONF_PPP_ENABLED || MBED_CONF_LWIP_PPP_ENABLED
#define PPP_SUPPORT 1 #define PPP_SUPPORT 1
#if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED #if MBED_CONF_PPP_IPV4_ENABLED || MBED_CONF_LWIP_IPV4_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV4_ENABLED
#error LWIP: IPv4 PPP enabled but not IPv4 #error LWIP: IPv4 PPP enabled but not IPv4
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV4_SUPPORT 1 #define PPP_IPV4_SUPPORT 1
#endif #endif
#if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED #if MBED_CONF_PPP_IPV6_ENABLED || MBED_CONF_LWIP_IPV6_ENABLED
#define LWIP 0x11991199 #define LWIP 0x11991199
#if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED #if (MBED_CONF_NSAPI_DEFAULT_STACK == LWIP) && !MBED_CONF_LWIP_IPV6_ENABLED
#error LWIP: IPv6 PPP enabled but not IPv6 #error LWIP: IPv6 PPP enabled but not IPv6
#endif #endif
#undef LWIP #undef LWIP
#define PPP_IPV6_SUPPORT 1 #define PPP_IPV6_SUPPORT 1
// Later to be dynamic for use for multiple interfaces // Later to be dynamic for use for multiple interfaces
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0 #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif #endif
#endif #endif
@@ -320,7 +320,7 @@
// Make sure we default these to off, so // Make sure we default these to off, so
// LWIP doesn't default to on // LWIP doesn't default to on
#ifndef LWIP_ARP #ifndef LWIP_ARP
#define LWIP_ARP 0 #define LWIP_ARP 0
#endif #endif
// Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914 // Checksum-on-copy disabled due to https://savannah.nongnu.org/bugs/?50914
@@ -337,9 +337,9 @@
#include "lwip_tcp_isn.h" #include "lwip_tcp_isn.h"
#define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn #define LWIP_HOOK_TCP_ISN lwip_hook_tcp_isn
#ifdef MBEDTLS_MD5_C #ifdef MBEDTLS_MD5_C
#define LWIP_USE_EXTERNAL_MBEDTLS 1 #define LWIP_USE_EXTERNAL_MBEDTLS 1
#else #else
#define LWIP_USE_EXTERNAL_MBEDTLS 0 #define LWIP_USE_EXTERNAL_MBEDTLS 0
#endif #endif
#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS MBED_CONF_LWIP_ND6_RDNSS_MAX_DNS_SERVERS

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
portenta_h7_rules () {
echo ""
echo "# Portenta H7 bootloader mode UDEV rules"
echo ""
cat <<EOF
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="035b", GROUP="plugdev", MODE="0666"
EOF
}
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
portenta_h7_rules > /etc/udev/rules.d/49-portenta_h7.rules
# reload udev rules
echo "Reload rules..."
udevadm trigger
udevadm control --reload-rules

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -70,19 +70,19 @@ void loop( void ) ;
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#include <bits/stl_algobase.h> #include <bits/stl_algobase.h>
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -94,30 +94,30 @@ void loop( void ) ;
#include "WInterrupts.h" #include "WInterrupts.h"
#ifndef __cplusplus #ifndef __cplusplus
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L> #define min(a,b) ((a)<(b)?(a):(b))
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) #define max(a,b) ((a)>(b)?(a):(b))
{ #define abs(x) ((x)>0?(x):-(x))
return (a < b) ? b : a; #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
}
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (a < b) ? b : a;
}
#endif #endif
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
@@ -138,13 +138,13 @@ void loop( void ) ;
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// Allows publishing the Beta core under samd-beta / arduino organization // Allows publishing the Beta core under samd-beta / arduino organization
#ifndef ARDUINO_ARCH_SAMD #ifndef ARDUINO_ARCH_SAMD
#define ARDUINO_ARCH_SAMD #define ARDUINO_ARCH_SAMD
#endif #endif
// USB Device // USB Device
@@ -154,7 +154,7 @@ void loop( void ) ;
#include "USB/USB_host.h" #include "USB/USB_host.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "USB/CDC.h" #include "USB/CDC.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -44,7 +44,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -70,19 +70,19 @@ void loop( void ) ;
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#include <bits/stl_algobase.h> #include <bits/stl_algobase.h>
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -94,30 +94,30 @@ void loop( void ) ;
#include "WInterrupts.h" #include "WInterrupts.h"
#ifndef __cplusplus #ifndef __cplusplus
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L> #define min(a,b) ((a)<(b)?(a):(b))
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) #define max(a,b) ((a)>(b)?(a):(b))
{ #define abs(x) ((x)>0?(x):-(x))
return (a < b) ? b : a; #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
}
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (a < b) ? b : a;
}
#endif #endif
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
@@ -138,13 +138,13 @@ void loop( void ) ;
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// Allows publishing the Beta core under samd-beta / arduino organization // Allows publishing the Beta core under samd-beta / arduino organization
#ifndef ARDUINO_ARCH_SAMD #ifndef ARDUINO_ARCH_SAMD
#define ARDUINO_ARCH_SAMD #define ARDUINO_ARCH_SAMD
#endif #endif
// USB Device // USB Device
@@ -154,7 +154,7 @@ void loop( void ) ;
#include "USB/USB_host.h" #include "USB/USB_host.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "USB/CDC.h" #include "USB/CDC.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -45,7 +45,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -75,19 +75,19 @@ void loop( void ) ;
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#include <bits/stl_algobase.h> #include <bits/stl_algobase.h>
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -99,30 +99,30 @@ void loop( void ) ;
#include "WInterrupts.h" #include "WInterrupts.h"
#ifndef __cplusplus #ifndef __cplusplus
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L> #define min(a,b) ((a)<(b)?(a):(b))
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) #define max(a,b) ((a)>(b)?(a):(b))
{ #define abs(x) ((x)>0?(x):-(x))
return (a < b) ? b : a; #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
}
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (a < b) ? b : a;
}
#endif #endif
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
@@ -143,13 +143,13 @@ void loop( void ) ;
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// Allows publishing the Beta core under samd-beta / arduino organization // Allows publishing the Beta core under samd-beta / arduino organization
#ifndef ARDUINO_ARCH_SAMD #ifndef ARDUINO_ARCH_SAMD
#define ARDUINO_ARCH_SAMD #define ARDUINO_ARCH_SAMD
#endif #endif
// USB Device // USB Device
@@ -159,7 +159,7 @@ void loop( void ) ;
#include "USB/USB_host.h" #include "USB/USB_host.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "USB/CDC.h" #include "USB/CDC.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -45,7 +45,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -75,19 +75,19 @@ void loop( void ) ;
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#include <bits/stl_algobase.h> #include <bits/stl_algobase.h>
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -99,30 +99,30 @@ void loop( void ) ;
#include "WInterrupts.h" #include "WInterrupts.h"
#ifndef __cplusplus #ifndef __cplusplus
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L> #define min(a,b) ((a)<(b)?(a):(b))
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) #define max(a,b) ((a)>(b)?(a):(b))
{ #define abs(x) ((x)>0?(x):-(x))
return (a < b) ? b : a; #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
}
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (a < b) ? b : a;
}
#endif #endif
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
@@ -143,13 +143,13 @@ void loop( void ) ;
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// Allows publishing the Beta core under samd-beta / arduino organization // Allows publishing the Beta core under samd-beta / arduino organization
#ifndef ARDUINO_ARCH_SAMD #ifndef ARDUINO_ARCH_SAMD
#define ARDUINO_ARCH_SAMD #define ARDUINO_ARCH_SAMD
#endif #endif
// USB Device // USB Device
@@ -159,7 +159,7 @@ void loop( void ) ;
#include "USB/USB_host.h" #include "USB/USB_host.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "USB/CDC.h" #include "USB/CDC.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -45,7 +45,7 @@ typedef uint16_t word;
#include "itoa.h" #include "itoa.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// Include Atmel headers // Include Atmel headers
@@ -75,19 +75,19 @@ void loop( void ) ;
// The following headers are for C++ only compilation // The following headers are for C++ only compilation
#ifdef __cplusplus #ifdef __cplusplus
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
#include "Tone.h" #include "Tone.h"
#include "WMath.h" #include "WMath.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "pulse.h" #include "pulse.h"
#include <bits/stl_algobase.h> #include <bits/stl_algobase.h>
#endif #endif
#include "delay.h" #include "delay.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "Uart.h" #include "Uart.h"
#endif #endif
// Include board variant // Include board variant
@@ -99,30 +99,30 @@ void loop( void ) ;
#include "WInterrupts.h" #include "WInterrupts.h"
#ifndef __cplusplus #ifndef __cplusplus
// undefine stdlib's abs if encountered // undefine stdlib's abs if encountered
#ifdef abs #ifdef abs
#undef abs #undef abs
#endif // abs #endif // abs
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L> #define min(a,b) ((a)<(b)?(a):(b))
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) #define max(a,b) ((a)>(b)?(a):(b))
{ #define abs(x) ((x)>0?(x):-(x))
return (a < b) ? b : a; #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
}
#else
//using std::min;
//using std::max;
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (a < b) ? b : a;
}
#endif #endif
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
@@ -143,13 +143,13 @@ void loop( void ) ;
#define bit(b) (1UL << (b)) #define bit(b) (1UL << (b))
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606) #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts // Interrupts
#define digitalPinToInterrupt(P) ( P ) #define digitalPinToInterrupt(P) ( P )
#endif #endif
// Allows publishing the Beta core under samd-beta / arduino organization // Allows publishing the Beta core under samd-beta / arduino organization
#ifndef ARDUINO_ARCH_SAMD #ifndef ARDUINO_ARCH_SAMD
#define ARDUINO_ARCH_SAMD #define ARDUINO_ARCH_SAMD
#endif #endif
// USB Device // USB Device
@@ -159,7 +159,7 @@ void loop( void ) ;
#include "USB/USB_host.h" #include "USB/USB_host.h"
#ifdef __cplusplus #ifdef __cplusplus
#include "USB/CDC.h" #include "USB/CDC.h"
#endif #endif
#endif // Arduino_h #endif // Arduino_h

View File

@@ -1,24 +1,24 @@
/* /*
Stream.cpp - adds parsing methods to Stream class Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved. Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011 Created July 2011
parsing functions based on TextFinder library by Michael Margolis parsing functions based on TextFinder library by Michael Margolis
*/ */
#include <Arduino.h> #include <Arduino.h>
@@ -28,65 +28,65 @@
// private method to read stream with timeout // private method to read stream with timeout
int Stream::timedRead() int Stream::timedRead()
{ {
int c; int c;
unsigned long startMillis = millis(); unsigned long startMillis = millis();
do do
{ {
c = read(); c = read();
if (c >= 0) if (c >= 0)
return c; return c;
yield(); yield();
} while (millis() - startMillis < _timeout); } while (millis() - startMillis < _timeout);
Serial.print(("timedRead timeout = ")); Serial.print(("timedRead timeout = "));
Serial.println(_timeout); Serial.println(_timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
} }
// private method to peek stream with timeout // private method to peek stream with timeout
int Stream::timedPeek() int Stream::timedPeek()
{ {
int c; int c;
unsigned long startMillis = millis(); unsigned long startMillis = millis();
do do
{ {
c = peek(); c = peek();
if (c >= 0) if (c >= 0)
return c; return c;
yield(); yield();
} while (millis() - startMillis < _timeout); } while (millis() - startMillis < _timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
} }
// returns peek of the next digit in the stream or -1 if timeout // returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters // discards non-numeric characters
int Stream::peekNextDigit() int Stream::peekNextDigit()
{ {
int c; int c;
while (1) while (1)
{ {
c = timedPeek(); c = timedPeek();
if (c < 0) if (c < 0)
return c; // timeout return c; // timeout
if (c == '-') if (c == '-')
return c; return c;
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')
return c; return c;
read(); // discard non-numeric read(); // discard non-numeric
} }
} }
// Public Methods // Public Methods
@@ -94,31 +94,31 @@ int Stream::peekNextDigit()
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{ {
_timeout = timeout; _timeout = timeout;
} }
// find returns true if the target string is found // find returns true if the target string is found
bool Stream::find(const char *target) bool Stream::find(const char *target)
{ {
return findUntil(target, NULL); return findUntil(target, NULL);
} }
// reads data from the stream until the target string of given length is found // 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 // returns true if target string is found, false if timed out
bool Stream::find(const char *target, size_t length) bool Stream::find(const char *target, size_t length)
{ {
return findUntil(target, length, NULL, 0); return findUntil(target, length, NULL, 0);
} }
// as find but search ends if the terminator string is found // as find but search ends if the terminator string is found
bool Stream::findUntil(const char *target, const char *terminator) bool Stream::findUntil(const char *target, const char *terminator)
{ {
if (target == nullptr) if (target == nullptr)
return true; return true;
size_t tlen = (terminator == nullptr) ? 0 : strlen(terminator); size_t tlen = (terminator == nullptr) ? 0 : strlen(terminator);
return findUntil(target, strlen(target), terminator, tlen); return findUntil(target, strlen(target), terminator, tlen);
} }
// reads data from the stream until the target string of the given length is found // reads data from the stream until the target string of the given length is found
@@ -126,45 +126,45 @@ bool Stream::findUntil(const char *target, const char *terminator)
// returns true if target string is found, false if terminated or timed out // returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen)
{ {
size_t index = 0; // maximum target string length is 64k bytes! size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0; size_t termIndex = 0;
int c; int c;
if ( target == nullptr) if ( target == nullptr)
return true; return true;
if ( *target == 0) if ( *target == 0)
return true; // return true if target is a null string return true; // return true if target is a null string
if (terminator == nullptr) if (terminator == nullptr)
termLen = 0; termLen = 0;
while ( (c = timedRead()) > 0) while ( (c = timedRead()) > 0)
{ {
if ( c == target[index]) if ( c == target[index])
{ {
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if (++index >= targetLen) if (++index >= targetLen)
{ {
// return true if all chars in the target match // return true if all chars in the target match
return true; return true;
} }
} }
else else
{ {
index = 0; // reset index if any char does not match index = 0; // reset index if any char does not match
} }
if (termLen > 0 && c == terminator[termIndex]) if (termLen > 0 && c == terminator[termIndex])
{ {
if (++termIndex >= termLen) if (++termIndex >= termLen)
return false; // return false if terminate string found before target string return false; // return false if terminate string found before target string
} }
else else
termIndex = 0; termIndex = 0;
} }
return false; return false;
} }
@@ -173,95 +173,93 @@ bool Stream::findUntil(const char *target, size_t targetLen, const char *termina
// function is terminated by the first character that is not a digit. // function is terminated by the first character that is not a digit.
long Stream::parseInt() long Stream::parseInt()
{ {
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
} }
// as above but a given skipChar is ignored // as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored // this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar) long Stream::parseInt(char skipChar)
{ {
boolean isNegative = false; boolean isNegative = false;
long value = 0; long value = 0;
int c; int c;
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if (c < 0) if (c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
do do
{ {
if (c == skipChar) if (c == skipChar)
; // ignore this charactor ; // ignore this charactor
else if (c == '-') else if (c == '-')
isNegative = true; isNegative = true;
else if (c >= '0' && c <= '9') // is c a digit? else if (c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} } while ( (c >= '0' && c <= '9') || c == skipChar );
while ( (c >= '0' && c <= '9') || c == skipChar );
if (isNegative) if (isNegative)
value = -value; value = -value;
return value; return value;
} }
// as parseInt but returns a floating point value // as parseInt but returns a floating point value
float Stream::parseFloat() float Stream::parseFloat()
{ {
return parseFloat(NO_SKIP_CHAR); return parseFloat(NO_SKIP_CHAR);
} }
// 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 // this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar) float Stream::parseFloat(char skipChar)
{ {
boolean isNegative = false; boolean isNegative = false;
boolean isFraction = false; boolean isFraction = false;
long value = 0; long value = 0;
int c; int c;
float fraction = 1.0; float fraction = 1.0;
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if (c < 0) if (c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
do do
{ {
if (c == skipChar) if (c == skipChar)
; // ignore ; // ignore
else if (c == '-') else if (c == '-')
isNegative = true; isNegative = true;
else if (c == '.') else if (c == '.')
isFraction = true; isFraction = true;
else if (c >= '0' && c <= '9') else if (c >= '0' && c <= '9')
{ {
// is c a digit? // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
if (isFraction) if (isFraction)
fraction *= 0.1f; fraction *= 0.1f;
} }
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} } while ( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
while ( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
if (isNegative) if (isNegative)
value = -value; value = -value;
if (isFraction) if (isFraction)
return value * fraction; return value * fraction;
else else
return value; return value;
} }
// read characters from stream into buffer // read characters from stream into buffer
@@ -271,26 +269,26 @@ float Stream::parseFloat(char skipChar)
// //
size_t Stream::readBytes(char *buffer, size_t length) size_t Stream::readBytes(char *buffer, size_t length)
{ {
if (buffer == nullptr) if (buffer == nullptr)
return 0; return 0;
size_t count = 0; size_t count = 0;
while (count < length) while (count < length)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; break;
} }
*buffer++ = (char)c; *buffer++ = (char)c;
count++; count++;
} }
return count; return count;
} }
@@ -300,34 +298,34 @@ size_t Stream::readBytes(char *buffer, size_t length)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{ {
if (buffer == nullptr) if (buffer == nullptr)
return 0; return 0;
if (length < 1) if (length < 1)
return 0; return 0;
length--; length--;
size_t index = 0; size_t index = 0;
while (index < length) while (index < length)
{ {
int c = timedRead(); int c = timedRead();
if (c == terminator) if (c == terminator)
break; break;
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; break;
} }
*buffer++ = (char)c; *buffer++ = (char)c;
index++; index++;
} }
*buffer = 0; *buffer = 0;
return index; // return number of characters, not including null terminator return index; // return number of characters, not including null terminator
} }
#if 1 #if 1
@@ -335,112 +333,112 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
String Stream::readString(size_t max) String Stream::readString(size_t max)
{ {
String ret; String ret;
int c = timedRead(); int c = timedRead();
while (c >= 0) while (c >= 0)
{ {
ret += (char)c; ret += (char)c;
c = timedRead(); c = timedRead();
} }
return ret; return ret;
} }
char readStringBuffer[2048]; char readStringBuffer[2048];
char* Stream::readCharsUntil(char terminator, size_t max) char* Stream::readCharsUntil(char terminator, size_t max)
{ {
uint16_t offset = 0; uint16_t offset = 0;
int c = timedRead(); int c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
while (c >= 0 && c != terminator) while (c >= 0 && c != terminator)
{ {
c = timedRead(); c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
} }
readStringBuffer[offset] = 0; readStringBuffer[offset] = 0;
return readStringBuffer; return readStringBuffer;
} }
String Stream::readStringUntil(char terminator, size_t max) String Stream::readStringUntil(char terminator, size_t max)
{ {
String ret; String ret;
uint16_t offset = 0; uint16_t offset = 0;
int c = timedRead(); int c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
while (c >= 0 && c != terminator) while (c >= 0 && c != terminator)
{ {
c = timedRead(); c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
} }
readStringBuffer[offset] = 0; readStringBuffer[offset] = 0;
ret = String(readStringBuffer); ret = String(readStringBuffer);
return String(readStringBuffer); return String(readStringBuffer);
} }
#else #else
String Stream::readString(size_t max) String Stream::readString(size_t max)
{ {
String str; String str;
size_t length = 0; size_t length = 0;
while (length < max) while (length < max)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; // timeout break; // timeout
} }
if (c == 0) if (c == 0)
break; break;
str += (char)c; str += (char)c;
length++; length++;
} }
return str; return str;
} }
String Stream::readStringUntil(char terminator, size_t max) String Stream::readStringUntil(char terminator, size_t max)
{ {
String str; String str;
size_t length = 0; size_t length = 0;
while (length < max) while (length < max)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; // timeout break; // timeout
} }
if (c == 0 || c == terminator) if (c == 0 || c == terminator)
break; break;
str += (char)c; str += (char)c;
length++; length++;
} }
return str; return str;
} }
#endif #endif

View File

@@ -25,124 +25,124 @@
class Stream : public Print class Stream : public Print
{ {
public: public:
constexpr Stream() : _timeout(1000), read_error(0) {} constexpr Stream() : _timeout(1000), read_error(0) {}
virtual int available() = 0; virtual int available() = 0;
virtual int read() = 0; virtual int read() = 0;
virtual int peek() = 0; virtual int peek() = 0;
void setTimeout(unsigned long timeout); void setTimeout(unsigned long timeout);
bool find(const char *target); bool find(const char *target);
bool find(const uint8_t *target)
{
return find ((const char *)target);
}
bool find(const String &target)
{
return find(target.c_str());
}
bool find(const char *target, size_t length);
bool find(const uint8_t *target, size_t length)
{
return find ((const char *)target, length);
}
bool find(const String &target, size_t length)
{
return find(target.c_str(), length);
}
bool findUntil(const char *target, const char *terminator);
bool findUntil(const uint8_t *target, const char *terminator)
{
return findUntil((const char *)target, terminator);
}
bool findUntil(const String &target, const char *terminator)
{
return findUntil(target.c_str(), terminator);
}
bool findUntil(const char *target, const String &terminator)
{
return findUntil(target, terminator.c_str());
}
bool findUntil(const String &target, const String &terminator)
{
return findUntil(target.c_str(), terminator.c_str());
}
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen)
{
return findUntil((const char *)target, targetLen, terminate, termLen);
}
bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen);
bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytes(uint8_t *buffer, size_t length)
{
return readBytes((char *)buffer, length);
}
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length)
{
return readBytesUntil(terminator, (char *)buffer, length);
}
//////////////////////////////////////////////////////////// bool find(const uint8_t *target)
String readString(size_t max = 512); {
String readStringUntil(char terminator, size_t max = 512); return find ((const char *)target);
}
// KH, to not use String bool find(const String &target)
char* readCharsUntil(char terminator, size_t max = 512); {
//////////////////////////////////////////////////////////// return find(target.c_str());
}
int getReadError() bool find(const char *target, size_t length);
{
return read_error;
}
void clearReadError()
{
setReadError(0);
}
protected:
void setReadError(int err = 1)
{
read_error = err;
}
unsigned long _timeout;
// KH bool find(const uint8_t *target, size_t length)
int timedRead(); {
int timedPeek(); return find ((const char *)target, length);
int peekNextDigit(); }
//////
private: bool find(const String &target, size_t length)
char read_error; {
return find(target.c_str(), length);
}
bool findUntil(const char *target, const char *terminator);
bool findUntil(const uint8_t *target, const char *terminator)
{
return findUntil((const char *)target, terminator);
}
bool findUntil(const String &target, const char *terminator)
{
return findUntil(target.c_str(), terminator);
}
bool findUntil(const char *target, const String &terminator)
{
return findUntil(target, terminator.c_str());
}
bool findUntil(const String &target, const String &terminator)
{
return findUntil(target.c_str(), terminator.c_str());
}
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen)
{
return findUntil((const char *)target, targetLen, terminate, termLen);
}
bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen);
bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytes(uint8_t *buffer, size_t length)
{
return readBytes((char *)buffer, length);
}
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length)
{
return readBytesUntil(terminator, (char *)buffer, length);
}
////////////////////////////////////////////////////////////
String readString(size_t max = 512);
String readStringUntil(char terminator, size_t max = 512);
// KH, to not use String
char* readCharsUntil(char terminator, size_t max = 512);
////////////////////////////////////////////////////////////
int getReadError()
{
return read_error;
}
void clearReadError()
{
setReadError(0);
}
protected:
void setReadError(int err = 1)
{
read_error = err;
}
unsigned long _timeout;
// KH
int timedRead();
int timedPeek();
int peekNextDigit();
//////
private:
char read_error;
}; };
#endif #endif

View File

@@ -1,24 +1,24 @@
/* /*
Stream.cpp - adds parsing methods to Stream class Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved. Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011 Created July 2011
parsing functions based on TextFinder library by Michael Margolis parsing functions based on TextFinder library by Michael Margolis
*/ */
#include <Arduino.h> #include <Arduino.h>
@@ -28,65 +28,65 @@
// private method to read stream with timeout // private method to read stream with timeout
int Stream::timedRead() int Stream::timedRead()
{ {
int c; int c;
unsigned long startMillis = millis(); unsigned long startMillis = millis();
do do
{ {
c = read(); c = read();
if (c >= 0) if (c >= 0)
return c; return c;
yield(); yield();
} while (millis() - startMillis < _timeout); } while (millis() - startMillis < _timeout);
Serial.print(("timedRead timeout = ")); Serial.print(("timedRead timeout = "));
Serial.println(_timeout); Serial.println(_timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
} }
// private method to peek stream with timeout // private method to peek stream with timeout
int Stream::timedPeek() int Stream::timedPeek()
{ {
int c; int c;
unsigned long startMillis = millis(); unsigned long startMillis = millis();
do do
{ {
c = peek(); c = peek();
if (c >= 0) if (c >= 0)
return c; return c;
yield(); yield();
} while (millis() - startMillis < _timeout); } while (millis() - startMillis < _timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
} }
// returns peek of the next digit in the stream or -1 if timeout // returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters // discards non-numeric characters
int Stream::peekNextDigit() int Stream::peekNextDigit()
{ {
int c; int c;
while (1) while (1)
{ {
c = timedPeek(); c = timedPeek();
if (c < 0) if (c < 0)
return c; // timeout return c; // timeout
if (c == '-') if (c == '-')
return c; return c;
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')
return c; return c;
read(); // discard non-numeric read(); // discard non-numeric
} }
} }
// Public Methods // Public Methods
@@ -94,31 +94,31 @@ int Stream::peekNextDigit()
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{ {
_timeout = timeout; _timeout = timeout;
} }
// find returns true if the target string is found // find returns true if the target string is found
bool Stream::find(const char *target) bool Stream::find(const char *target)
{ {
return findUntil(target, NULL); return findUntil(target, NULL);
} }
// reads data from the stream until the target string of given length is found // 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 // returns true if target string is found, false if timed out
bool Stream::find(const char *target, size_t length) bool Stream::find(const char *target, size_t length)
{ {
return findUntil(target, length, NULL, 0); return findUntil(target, length, NULL, 0);
} }
// as find but search ends if the terminator string is found // as find but search ends if the terminator string is found
bool Stream::findUntil(const char *target, const char *terminator) bool Stream::findUntil(const char *target, const char *terminator)
{ {
if (target == nullptr) if (target == nullptr)
return true; return true;
size_t tlen = (terminator == nullptr) ? 0 : strlen(terminator); size_t tlen = (terminator == nullptr) ? 0 : strlen(terminator);
return findUntil(target, strlen(target), terminator, tlen); return findUntil(target, strlen(target), terminator, tlen);
} }
// reads data from the stream until the target string of the given length is found // reads data from the stream until the target string of the given length is found
@@ -126,45 +126,45 @@ bool Stream::findUntil(const char *target, const char *terminator)
// returns true if target string is found, false if terminated or timed out // returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen)
{ {
size_t index = 0; // maximum target string length is 64k bytes! size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0; size_t termIndex = 0;
int c; int c;
if ( target == nullptr) if ( target == nullptr)
return true; return true;
if ( *target == 0) if ( *target == 0)
return true; // return true if target is a null string return true; // return true if target is a null string
if (terminator == nullptr) if (terminator == nullptr)
termLen = 0; termLen = 0;
while ( (c = timedRead()) > 0) while ( (c = timedRead()) > 0)
{ {
if ( c == target[index]) if ( c == target[index])
{ {
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if (++index >= targetLen) if (++index >= targetLen)
{ {
// return true if all chars in the target match // return true if all chars in the target match
return true; return true;
} }
} }
else else
{ {
index = 0; // reset index if any char does not match index = 0; // reset index if any char does not match
} }
if (termLen > 0 && c == terminator[termIndex]) if (termLen > 0 && c == terminator[termIndex])
{ {
if (++termIndex >= termLen) if (++termIndex >= termLen)
return false; // return false if terminate string found before target string return false; // return false if terminate string found before target string
} }
else else
termIndex = 0; termIndex = 0;
} }
return false; return false;
} }
@@ -173,95 +173,93 @@ bool Stream::findUntil(const char *target, size_t targetLen, const char *termina
// function is terminated by the first character that is not a digit. // function is terminated by the first character that is not a digit.
long Stream::parseInt() long Stream::parseInt()
{ {
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
} }
// as above but a given skipChar is ignored // as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored // this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar) long Stream::parseInt(char skipChar)
{ {
boolean isNegative = false; boolean isNegative = false;
long value = 0; long value = 0;
int c; int c;
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if (c < 0) if (c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
do do
{ {
if (c == skipChar) if (c == skipChar)
; // ignore this charactor ; // ignore this charactor
else if (c == '-') else if (c == '-')
isNegative = true; isNegative = true;
else if (c >= '0' && c <= '9') // is c a digit? else if (c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} } while ( (c >= '0' && c <= '9') || c == skipChar );
while ( (c >= '0' && c <= '9') || c == skipChar );
if (isNegative) if (isNegative)
value = -value; value = -value;
return value; return value;
} }
// as parseInt but returns a floating point value // as parseInt but returns a floating point value
float Stream::parseFloat() float Stream::parseFloat()
{ {
return parseFloat(NO_SKIP_CHAR); return parseFloat(NO_SKIP_CHAR);
} }
// 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 // this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar) float Stream::parseFloat(char skipChar)
{ {
boolean isNegative = false; boolean isNegative = false;
boolean isFraction = false; boolean isFraction = false;
long value = 0; long value = 0;
int c; int c;
float fraction = 1.0; float fraction = 1.0;
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if (c < 0) if (c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
do do
{ {
if (c == skipChar) if (c == skipChar)
; // ignore ; // ignore
else if (c == '-') else if (c == '-')
isNegative = true; isNegative = true;
else if (c == '.') else if (c == '.')
isFraction = true; isFraction = true;
else if (c >= '0' && c <= '9') else if (c >= '0' && c <= '9')
{ {
// is c a digit? // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
if (isFraction) if (isFraction)
fraction *= 0.1f; fraction *= 0.1f;
} }
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} } while ( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
while ( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
if (isNegative) if (isNegative)
value = -value; value = -value;
if (isFraction) if (isFraction)
return value * fraction; return value * fraction;
else else
return value; return value;
} }
// read characters from stream into buffer // read characters from stream into buffer
@@ -271,26 +269,26 @@ float Stream::parseFloat(char skipChar)
// //
size_t Stream::readBytes(char *buffer, size_t length) size_t Stream::readBytes(char *buffer, size_t length)
{ {
if (buffer == nullptr) if (buffer == nullptr)
return 0; return 0;
size_t count = 0; size_t count = 0;
while (count < length) while (count < length)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; break;
} }
*buffer++ = (char)c; *buffer++ = (char)c;
count++; count++;
} }
return count; return count;
} }
@@ -300,34 +298,34 @@ size_t Stream::readBytes(char *buffer, size_t length)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{ {
if (buffer == nullptr) if (buffer == nullptr)
return 0; return 0;
if (length < 1) if (length < 1)
return 0; return 0;
length--; length--;
size_t index = 0; size_t index = 0;
while (index < length) while (index < length)
{ {
int c = timedRead(); int c = timedRead();
if (c == terminator) if (c == terminator)
break; break;
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; break;
} }
*buffer++ = (char)c; *buffer++ = (char)c;
index++; index++;
} }
*buffer = 0; *buffer = 0;
return index; // return number of characters, not including null terminator return index; // return number of characters, not including null terminator
} }
#if 1 #if 1
@@ -335,112 +333,112 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
String Stream::readString(size_t max) String Stream::readString(size_t max)
{ {
String ret; String ret;
int c = timedRead(); int c = timedRead();
while (c >= 0) while (c >= 0)
{ {
ret += (char)c; ret += (char)c;
c = timedRead(); c = timedRead();
} }
return ret; return ret;
} }
char readStringBuffer[2048]; char readStringBuffer[2048];
char* Stream::readCharsUntil(char terminator, size_t max) char* Stream::readCharsUntil(char terminator, size_t max)
{ {
uint16_t offset = 0; uint16_t offset = 0;
int c = timedRead(); int c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
while (c >= 0 && c != terminator) while (c >= 0 && c != terminator)
{ {
c = timedRead(); c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
} }
readStringBuffer[offset] = 0; readStringBuffer[offset] = 0;
return readStringBuffer; return readStringBuffer;
} }
String Stream::readStringUntil(char terminator, size_t max) String Stream::readStringUntil(char terminator, size_t max)
{ {
String ret; String ret;
uint16_t offset = 0; uint16_t offset = 0;
int c = timedRead(); int c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
while (c >= 0 && c != terminator) while (c >= 0 && c != terminator)
{ {
c = timedRead(); c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
} }
readStringBuffer[offset] = 0; readStringBuffer[offset] = 0;
ret = String(readStringBuffer); ret = String(readStringBuffer);
return String(readStringBuffer); return String(readStringBuffer);
} }
#else #else
String Stream::readString(size_t max) String Stream::readString(size_t max)
{ {
String str; String str;
size_t length = 0; size_t length = 0;
while (length < max) while (length < max)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; // timeout break; // timeout
} }
if (c == 0) if (c == 0)
break; break;
str += (char)c; str += (char)c;
length++; length++;
} }
return str; return str;
} }
String Stream::readStringUntil(char terminator, size_t max) String Stream::readStringUntil(char terminator, size_t max)
{ {
String str; String str;
size_t length = 0; size_t length = 0;
while (length < max) while (length < max)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; // timeout break; // timeout
} }
if (c == 0 || c == terminator) if (c == 0 || c == terminator)
break; break;
str += (char)c; str += (char)c;
length++; length++;
} }
return str; return str;
} }
#endif #endif

View File

@@ -25,124 +25,124 @@
class Stream : public Print class Stream : public Print
{ {
public: public:
constexpr Stream() : _timeout(1000), read_error(0) {} constexpr Stream() : _timeout(1000), read_error(0) {}
virtual int available() = 0; virtual int available() = 0;
virtual int read() = 0; virtual int read() = 0;
virtual int peek() = 0; virtual int peek() = 0;
void setTimeout(unsigned long timeout); void setTimeout(unsigned long timeout);
bool find(const char *target); bool find(const char *target);
bool find(const uint8_t *target)
{
return find ((const char *)target);
}
bool find(const String &target)
{
return find(target.c_str());
}
bool find(const char *target, size_t length);
bool find(const uint8_t *target, size_t length)
{
return find ((const char *)target, length);
}
bool find(const String &target, size_t length)
{
return find(target.c_str(), length);
}
bool findUntil(const char *target, const char *terminator);
bool findUntil(const uint8_t *target, const char *terminator)
{
return findUntil((const char *)target, terminator);
}
bool findUntil(const String &target, const char *terminator)
{
return findUntil(target.c_str(), terminator);
}
bool findUntil(const char *target, const String &terminator)
{
return findUntil(target, terminator.c_str());
}
bool findUntil(const String &target, const String &terminator)
{
return findUntil(target.c_str(), terminator.c_str());
}
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen)
{
return findUntil((const char *)target, targetLen, terminate, termLen);
}
bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen);
bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytes(uint8_t *buffer, size_t length)
{
return readBytes((char *)buffer, length);
}
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length)
{
return readBytesUntil(terminator, (char *)buffer, length);
}
//////////////////////////////////////////////////////////// bool find(const uint8_t *target)
String readString(size_t max = 512); {
String readStringUntil(char terminator, size_t max = 512); return find ((const char *)target);
}
// KH, to not use String bool find(const String &target)
char* readCharsUntil(char terminator, size_t max = 512); {
//////////////////////////////////////////////////////////// return find(target.c_str());
}
int getReadError() bool find(const char *target, size_t length);
{
return read_error;
}
void clearReadError()
{
setReadError(0);
}
protected:
void setReadError(int err = 1)
{
read_error = err;
}
unsigned long _timeout;
// KH bool find(const uint8_t *target, size_t length)
int timedRead(); {
int timedPeek(); return find ((const char *)target, length);
int peekNextDigit(); }
//////
private: bool find(const String &target, size_t length)
char read_error; {
return find(target.c_str(), length);
}
bool findUntil(const char *target, const char *terminator);
bool findUntil(const uint8_t *target, const char *terminator)
{
return findUntil((const char *)target, terminator);
}
bool findUntil(const String &target, const char *terminator)
{
return findUntil(target.c_str(), terminator);
}
bool findUntil(const char *target, const String &terminator)
{
return findUntil(target, terminator.c_str());
}
bool findUntil(const String &target, const String &terminator)
{
return findUntil(target.c_str(), terminator.c_str());
}
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen)
{
return findUntil((const char *)target, targetLen, terminate, termLen);
}
bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen);
bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytes(uint8_t *buffer, size_t length)
{
return readBytes((char *)buffer, length);
}
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length)
{
return readBytesUntil(terminator, (char *)buffer, length);
}
////////////////////////////////////////////////////////////
String readString(size_t max = 512);
String readStringUntil(char terminator, size_t max = 512);
// KH, to not use String
char* readCharsUntil(char terminator, size_t max = 512);
////////////////////////////////////////////////////////////
int getReadError()
{
return read_error;
}
void clearReadError()
{
setReadError(0);
}
protected:
void setReadError(int err = 1)
{
read_error = err;
}
unsigned long _timeout;
// KH
int timedRead();
int timedPeek();
int peekNextDigit();
//////
private:
char read_error;
}; };
#endif #endif

View File

@@ -1,24 +1,24 @@
/* /*
Stream.cpp - adds parsing methods to Stream class Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved. Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011 Created July 2011
parsing functions based on TextFinder library by Michael Margolis parsing functions based on TextFinder library by Michael Margolis
*/ */
#include <Arduino.h> #include <Arduino.h>
@@ -28,65 +28,65 @@
// private method to read stream with timeout // private method to read stream with timeout
int Stream::timedRead() int Stream::timedRead()
{ {
int c; int c;
unsigned long startMillis = millis(); unsigned long startMillis = millis();
do do
{ {
c = read(); c = read();
if (c >= 0) if (c >= 0)
return c; return c;
yield(); yield();
} while (millis() - startMillis < _timeout); } while (millis() - startMillis < _timeout);
Serial.print(("timedRead timeout = ")); Serial.print(("timedRead timeout = "));
Serial.println(_timeout); Serial.println(_timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
} }
// private method to peek stream with timeout // private method to peek stream with timeout
int Stream::timedPeek() int Stream::timedPeek()
{ {
int c; int c;
unsigned long startMillis = millis(); unsigned long startMillis = millis();
do do
{ {
c = peek(); c = peek();
if (c >= 0) if (c >= 0)
return c; return c;
yield(); yield();
} while (millis() - startMillis < _timeout); } while (millis() - startMillis < _timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
} }
// returns peek of the next digit in the stream or -1 if timeout // returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters // discards non-numeric characters
int Stream::peekNextDigit() int Stream::peekNextDigit()
{ {
int c; int c;
while (1) while (1)
{ {
c = timedPeek(); c = timedPeek();
if (c < 0) if (c < 0)
return c; // timeout return c; // timeout
if (c == '-') if (c == '-')
return c; return c;
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')
return c; return c;
read(); // discard non-numeric read(); // discard non-numeric
} }
} }
// Public Methods // Public Methods
@@ -94,31 +94,31 @@ int Stream::peekNextDigit()
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{ {
_timeout = timeout; _timeout = timeout;
} }
// find returns true if the target string is found // find returns true if the target string is found
bool Stream::find(const char *target) bool Stream::find(const char *target)
{ {
return findUntil(target, NULL); return findUntil(target, NULL);
} }
// reads data from the stream until the target string of given length is found // 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 // returns true if target string is found, false if timed out
bool Stream::find(const char *target, size_t length) bool Stream::find(const char *target, size_t length)
{ {
return findUntil(target, length, NULL, 0); return findUntil(target, length, NULL, 0);
} }
// as find but search ends if the terminator string is found // as find but search ends if the terminator string is found
bool Stream::findUntil(const char *target, const char *terminator) bool Stream::findUntil(const char *target, const char *terminator)
{ {
if (target == nullptr) if (target == nullptr)
return true; return true;
size_t tlen = (terminator == nullptr) ? 0 : strlen(terminator); size_t tlen = (terminator == nullptr) ? 0 : strlen(terminator);
return findUntil(target, strlen(target), terminator, tlen); return findUntil(target, strlen(target), terminator, tlen);
} }
// reads data from the stream until the target string of the given length is found // reads data from the stream until the target string of the given length is found
@@ -126,45 +126,45 @@ bool Stream::findUntil(const char *target, const char *terminator)
// returns true if target string is found, false if terminated or timed out // returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen) bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen)
{ {
size_t index = 0; // maximum target string length is 64k bytes! size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0; size_t termIndex = 0;
int c; int c;
if ( target == nullptr) if ( target == nullptr)
return true; return true;
if ( *target == 0) if ( *target == 0)
return true; // return true if target is a null string return true; // return true if target is a null string
if (terminator == nullptr) if (terminator == nullptr)
termLen = 0; termLen = 0;
while ( (c = timedRead()) > 0) while ( (c = timedRead()) > 0)
{ {
if ( c == target[index]) if ( c == target[index])
{ {
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if (++index >= targetLen) if (++index >= targetLen)
{ {
// return true if all chars in the target match // return true if all chars in the target match
return true; return true;
} }
} }
else else
{ {
index = 0; // reset index if any char does not match index = 0; // reset index if any char does not match
} }
if (termLen > 0 && c == terminator[termIndex]) if (termLen > 0 && c == terminator[termIndex])
{ {
if (++termIndex >= termLen) if (++termIndex >= termLen)
return false; // return false if terminate string found before target string return false; // return false if terminate string found before target string
} }
else else
termIndex = 0; termIndex = 0;
} }
return false; return false;
} }
@@ -173,95 +173,93 @@ bool Stream::findUntil(const char *target, size_t targetLen, const char *termina
// function is terminated by the first character that is not a digit. // function is terminated by the first character that is not a digit.
long Stream::parseInt() long Stream::parseInt()
{ {
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout) return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
} }
// as above but a given skipChar is ignored // as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored // this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar) long Stream::parseInt(char skipChar)
{ {
boolean isNegative = false; boolean isNegative = false;
long value = 0; long value = 0;
int c; int c;
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if (c < 0) if (c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
do do
{ {
if (c == skipChar) if (c == skipChar)
; // ignore this charactor ; // ignore this charactor
else if (c == '-') else if (c == '-')
isNegative = true; isNegative = true;
else if (c >= '0' && c <= '9') // is c a digit? else if (c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} } while ( (c >= '0' && c <= '9') || c == skipChar );
while ( (c >= '0' && c <= '9') || c == skipChar );
if (isNegative) if (isNegative)
value = -value; value = -value;
return value; return value;
} }
// as parseInt but returns a floating point value // as parseInt but returns a floating point value
float Stream::parseFloat() float Stream::parseFloat()
{ {
return parseFloat(NO_SKIP_CHAR); return parseFloat(NO_SKIP_CHAR);
} }
// 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 // this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar) float Stream::parseFloat(char skipChar)
{ {
boolean isNegative = false; boolean isNegative = false;
boolean isFraction = false; boolean isFraction = false;
long value = 0; long value = 0;
int c; int c;
float fraction = 1.0; float fraction = 1.0;
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if (c < 0) if (c < 0)
return 0; // zero returned if timeout return 0; // zero returned if timeout
do do
{ {
if (c == skipChar) if (c == skipChar)
; // ignore ; // ignore
else if (c == '-') else if (c == '-')
isNegative = true; isNegative = true;
else if (c == '.') else if (c == '.')
isFraction = true; isFraction = true;
else if (c >= '0' && c <= '9') else if (c >= '0' && c <= '9')
{ {
// is c a digit? // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
if (isFraction) if (isFraction)
fraction *= 0.1f; fraction *= 0.1f;
} }
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} } while ( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
while ( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
if (isNegative) if (isNegative)
value = -value; value = -value;
if (isFraction) if (isFraction)
return value * fraction; return value * fraction;
else else
return value; return value;
} }
// read characters from stream into buffer // read characters from stream into buffer
@@ -271,26 +269,26 @@ float Stream::parseFloat(char skipChar)
// //
size_t Stream::readBytes(char *buffer, size_t length) size_t Stream::readBytes(char *buffer, size_t length)
{ {
if (buffer == nullptr) if (buffer == nullptr)
return 0; return 0;
size_t count = 0; size_t count = 0;
while (count < length) while (count < length)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; break;
} }
*buffer++ = (char)c; *buffer++ = (char)c;
count++; count++;
} }
return count; return count;
} }
@@ -300,34 +298,34 @@ size_t Stream::readBytes(char *buffer, size_t length)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{ {
if (buffer == nullptr) if (buffer == nullptr)
return 0; return 0;
if (length < 1) if (length < 1)
return 0; return 0;
length--; length--;
size_t index = 0; size_t index = 0;
while (index < length) while (index < length)
{ {
int c = timedRead(); int c = timedRead();
if (c == terminator) if (c == terminator)
break; break;
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; break;
} }
*buffer++ = (char)c; *buffer++ = (char)c;
index++; index++;
} }
*buffer = 0; *buffer = 0;
return index; // return number of characters, not including null terminator return index; // return number of characters, not including null terminator
} }
#if 1 #if 1
@@ -335,112 +333,112 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
String Stream::readString(size_t max) String Stream::readString(size_t max)
{ {
String ret; String ret;
int c = timedRead(); int c = timedRead();
while (c >= 0) while (c >= 0)
{ {
ret += (char)c; ret += (char)c;
c = timedRead(); c = timedRead();
} }
return ret; return ret;
} }
char readStringBuffer[2048]; char readStringBuffer[2048];
char* Stream::readCharsUntil(char terminator, size_t max) char* Stream::readCharsUntil(char terminator, size_t max)
{ {
uint16_t offset = 0; uint16_t offset = 0;
int c = timedRead(); int c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
while (c >= 0 && c != terminator) while (c >= 0 && c != terminator)
{ {
c = timedRead(); c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
} }
readStringBuffer[offset] = 0; readStringBuffer[offset] = 0;
return readStringBuffer; return readStringBuffer;
} }
String Stream::readStringUntil(char terminator, size_t max) String Stream::readStringUntil(char terminator, size_t max)
{ {
String ret; String ret;
uint16_t offset = 0; uint16_t offset = 0;
int c = timedRead(); int c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
while (c >= 0 && c != terminator) while (c >= 0 && c != terminator)
{ {
c = timedRead(); c = timedRead();
readStringBuffer[offset++] = c; readStringBuffer[offset++] = c;
} }
readStringBuffer[offset] = 0; readStringBuffer[offset] = 0;
ret = String(readStringBuffer); ret = String(readStringBuffer);
return String(readStringBuffer); return String(readStringBuffer);
} }
#else #else
String Stream::readString(size_t max) String Stream::readString(size_t max)
{ {
String str; String str;
size_t length = 0; size_t length = 0;
while (length < max) while (length < max)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; // timeout break; // timeout
} }
if (c == 0) if (c == 0)
break; break;
str += (char)c; str += (char)c;
length++; length++;
} }
return str; return str;
} }
String Stream::readStringUntil(char terminator, size_t max) String Stream::readStringUntil(char terminator, size_t max)
{ {
String str; String str;
size_t length = 0; size_t length = 0;
while (length < max) while (length < max)
{ {
int c = timedRead(); int c = timedRead();
if (c < 0) if (c < 0)
{ {
setReadError(); setReadError();
break; // timeout break; // timeout
} }
if (c == 0 || c == terminator) if (c == 0 || c == terminator)
break; break;
str += (char)c; str += (char)c;
length++; length++;
} }
return str; return str;
} }
#endif #endif

View File

@@ -25,124 +25,124 @@
class Stream : public Print class Stream : public Print
{ {
public: public:
constexpr Stream() : _timeout(1000), read_error(0) {} constexpr Stream() : _timeout(1000), read_error(0) {}
virtual int available() = 0; virtual int available() = 0;
virtual int read() = 0; virtual int read() = 0;
virtual int peek() = 0; virtual int peek() = 0;
void setTimeout(unsigned long timeout); void setTimeout(unsigned long timeout);
bool find(const char *target); bool find(const char *target);
bool find(const uint8_t *target)
{
return find ((const char *)target);
}
bool find(const String &target)
{
return find(target.c_str());
}
bool find(const char *target, size_t length);
bool find(const uint8_t *target, size_t length)
{
return find ((const char *)target, length);
}
bool find(const String &target, size_t length)
{
return find(target.c_str(), length);
}
bool findUntil(const char *target, const char *terminator);
bool findUntil(const uint8_t *target, const char *terminator)
{
return findUntil((const char *)target, terminator);
}
bool findUntil(const String &target, const char *terminator)
{
return findUntil(target.c_str(), terminator);
}
bool findUntil(const char *target, const String &terminator)
{
return findUntil(target, terminator.c_str());
}
bool findUntil(const String &target, const String &terminator)
{
return findUntil(target.c_str(), terminator.c_str());
}
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen)
{
return findUntil((const char *)target, targetLen, terminate, termLen);
}
bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen);
bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytes(uint8_t *buffer, size_t length)
{
return readBytes((char *)buffer, length);
}
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length)
{
return readBytesUntil(terminator, (char *)buffer, length);
}
//////////////////////////////////////////////////////////// bool find(const uint8_t *target)
String readString(size_t max = 512); {
String readStringUntil(char terminator, size_t max = 512); return find ((const char *)target);
}
// KH, to not use String bool find(const String &target)
char* readCharsUntil(char terminator, size_t max = 512); {
//////////////////////////////////////////////////////////// return find(target.c_str());
}
int getReadError() bool find(const char *target, size_t length);
{
return read_error;
}
void clearReadError()
{
setReadError(0);
}
protected:
void setReadError(int err = 1)
{
read_error = err;
}
unsigned long _timeout;
// KH bool find(const uint8_t *target, size_t length)
int timedRead(); {
int timedPeek(); return find ((const char *)target, length);
int peekNextDigit(); }
//////
private: bool find(const String &target, size_t length)
char read_error; {
return find(target.c_str(), length);
}
bool findUntil(const char *target, const char *terminator);
bool findUntil(const uint8_t *target, const char *terminator)
{
return findUntil((const char *)target, terminator);
}
bool findUntil(const String &target, const char *terminator)
{
return findUntil(target.c_str(), terminator);
}
bool findUntil(const char *target, const String &terminator)
{
return findUntil(target, terminator.c_str());
}
bool findUntil(const String &target, const String &terminator)
{
return findUntil(target.c_str(), terminator.c_str());
}
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen)
{
return findUntil((const char *)target, targetLen, terminate, termLen);
}
bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen);
bool findUntil(const String &target, size_t targetLen, const String &terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytes(uint8_t *buffer, size_t length)
{
return readBytes((char *)buffer, length);
}
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length)
{
return readBytesUntil(terminator, (char *)buffer, length);
}
////////////////////////////////////////////////////////////
String readString(size_t max = 512);
String readStringUntil(char terminator, size_t max = 512);
// KH, to not use String
char* readCharsUntil(char terminator, size_t max = 512);
////////////////////////////////////////////////////////////
int getReadError()
{
return read_error;
}
void clearReadError()
{
setReadError(0);
}
protected:
void setReadError(int err = 1)
{
read_error = err;
}
unsigned long _timeout;
// KH
int timedRead();
int timedPeek();
int peekNextDigit();
//////
private:
char read_error;
}; };
#endif #endif

View File

@@ -1,36 +1,36 @@
/* /*
* Udp.cpp: Library to send/receive UDP packets. Udp.cpp: Library to send/receive UDP packets.
*
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This 1) UDP does not guarantee the order in which assembled UDP packets are received. This
* might not happen often in practice, but in larger network topologies, a UDP might not happen often in practice, but in larger network topologies, a UDP
* packet can be received out of sequence. packet can be received out of sequence.
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
* aware of it. Again, this may not be a concern in practice on small local networks. aware of it. Again, this may not be a concern in practice on small local networks.
* For more information, see http://www.cafeaulait.org/course/week12/35.html For more information, see http://www.cafeaulait.org/course/week12/35.html
*
* MIT License: MIT License:
* Copyright (c) 2008 Bjoern Hartmann Copyright (c) 2008 Bjoern Hartmann
* Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. THE SOFTWARE.
*
* bjoern@cs.stanford.edu 12/30/2008 bjoern@cs.stanford.edu 12/30/2008
*/ */
#ifndef udp_h #ifndef udp_h
#define udp_h #define udp_h
@@ -38,52 +38,59 @@
#include <Stream.h> #include <Stream.h>
#include <IPAddress.h> #include <IPAddress.h>
class UDP : public Stream { class UDP : public Stream
{
public: public:
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t begin(uint16_t) = 0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure virtual uint8_t beginMulticast(IPAddress, uint16_t)
virtual void stop() =0; // Finish with the UDP socket {
return 0; // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure
}
virtual void stop() = 0; // Finish with the UDP socket
// Sending UDP packets // Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) =0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() =0;
// Write a single byte into the packet
virtual size_t write(uint8_t) =0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) =0;
// Start processing the next available incoming packet // Start building up a packet to send to the remote host specific in ip and port
// Returns the size of the packet in bytes, or 0 if no packets are available // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int parsePacket() =0; virtual int beginPacket(IPAddress ip, uint16_t port) = 0;
// Number of bytes remaining in the current packet // Start building up a packet to send to the remote host specific in host and port
virtual int available() =0; // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
// Read a single byte from the current packet virtual int beginPacket(const char *host, uint16_t port) = 0;
virtual int read() =0; // Finish off this packet and send it
// Read up to len bytes from the current packet and place them into buffer // Returns 1 if the packet was sent successfully, 0 if there was an error
// Returns the number of bytes read, or 0 if none are available virtual int endPacket() = 0;
virtual int read(unsigned char* buffer, size_t len) =0; // Write a single byte into the packet
// Read up to len characters from the current packet and place them into buffer virtual size_t write(uint8_t) = 0;
// Returns the number of characters read, or 0 if none are available // Write size bytes from buffer into the packet
virtual int read(char* buffer, size_t len) =0; virtual size_t write(const uint8_t *buffer, size_t size) = 0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
virtual void flush() =0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet // Start processing the next available incoming packet
virtual IPAddress remoteIP() =0; // Returns the size of the packet in bytes, or 0 if no packets are available
// Return the port of the host who sent the current incoming packet virtual int parsePacket() = 0;
virtual uint16_t remotePort() =0; // Number of bytes remaining in the current packet
protected: virtual int available() = 0;
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; // Read a single byte from the current packet
virtual int read() = 0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) = 0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) = 0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() = 0;
virtual void flush() = 0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() = 0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr)
{
return addr.raw_address();
};
}; };
#endif #endif

View File

@@ -1,36 +1,36 @@
/* /*
* Udp.cpp: Library to send/receive UDP packets. Udp.cpp: Library to send/receive UDP packets.
*
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This 1) UDP does not guarantee the order in which assembled UDP packets are received. This
* might not happen often in practice, but in larger network topologies, a UDP might not happen often in practice, but in larger network topologies, a UDP
* packet can be received out of sequence. packet can be received out of sequence.
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
* aware of it. Again, this may not be a concern in practice on small local networks. aware of it. Again, this may not be a concern in practice on small local networks.
* For more information, see http://www.cafeaulait.org/course/week12/35.html For more information, see http://www.cafeaulait.org/course/week12/35.html
*
* MIT License: MIT License:
* Copyright (c) 2008 Bjoern Hartmann Copyright (c) 2008 Bjoern Hartmann
* Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. THE SOFTWARE.
*
* bjoern@cs.stanford.edu 12/30/2008 bjoern@cs.stanford.edu 12/30/2008
*/ */
#ifndef udp_h #ifndef udp_h
#define udp_h #define udp_h
@@ -38,52 +38,59 @@
#include <Stream.h> #include <Stream.h>
#include <IPAddress.h> #include <IPAddress.h>
class UDP : public Stream { class UDP : public Stream
{
public: public:
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t begin(uint16_t) = 0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure virtual uint8_t beginMulticast(IPAddress, uint16_t)
virtual void stop() =0; // Finish with the UDP socket {
return 0; // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure
}
virtual void stop() = 0; // Finish with the UDP socket
// Sending UDP packets // Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) =0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() =0;
// Write a single byte into the packet
virtual size_t write(uint8_t) =0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) =0;
// Start processing the next available incoming packet // Start building up a packet to send to the remote host specific in ip and port
// Returns the size of the packet in bytes, or 0 if no packets are available // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int parsePacket() =0; virtual int beginPacket(IPAddress ip, uint16_t port) = 0;
// Number of bytes remaining in the current packet // Start building up a packet to send to the remote host specific in host and port
virtual int available() =0; // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
// Read a single byte from the current packet virtual int beginPacket(const char *host, uint16_t port) = 0;
virtual int read() =0; // Finish off this packet and send it
// Read up to len bytes from the current packet and place them into buffer // Returns 1 if the packet was sent successfully, 0 if there was an error
// Returns the number of bytes read, or 0 if none are available virtual int endPacket() = 0;
virtual int read(unsigned char* buffer, size_t len) =0; // Write a single byte into the packet
// Read up to len characters from the current packet and place them into buffer virtual size_t write(uint8_t) = 0;
// Returns the number of characters read, or 0 if none are available // Write size bytes from buffer into the packet
virtual int read(char* buffer, size_t len) =0; virtual size_t write(const uint8_t *buffer, size_t size) = 0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
virtual void flush() =0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet // Start processing the next available incoming packet
virtual IPAddress remoteIP() =0; // Returns the size of the packet in bytes, or 0 if no packets are available
// Return the port of the host who sent the current incoming packet virtual int parsePacket() = 0;
virtual uint16_t remotePort() =0; // Number of bytes remaining in the current packet
protected: virtual int available() = 0;
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; // Read a single byte from the current packet
virtual int read() = 0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) = 0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) = 0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() = 0;
virtual void flush() = 0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() = 0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr)
{
return addr.raw_address();
};
}; };
#endif #endif

View File

@@ -1,122 +1,122 @@
/* /*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE THE SOFTWARE
*/ */
#ifndef __PGMSPACE_H_ #ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1 #define __PGMSPACE_H_ 1
#include <inttypes.h> #include <inttypes.h>
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PSTR(str) (str)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
typedef void prog_void; typedef void prog_void;
typedef char prog_char; typedef char prog_char;
typedef unsigned char prog_uchar; typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t; typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t; typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t; typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t; typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t; typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t; typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t; typedef const void* int_farptr_t;
typedef const void* uint_farptr_t; typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n)) #define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n)) #define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c)) #define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c)) #define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b)) #define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src)) #define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept)) #define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a)) #define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n)) #define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) #define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept)) #define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c)) #define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim)) #define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept)) #define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b)) #define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim)) #define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) #define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a)) #define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len)) #define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src)) #define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src)) #define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) #define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2)) #define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2)) #define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_ptr(addr) (*(const void **)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) #define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr)) #define pgm_get_far_address(addr) (&(addr))
#endif #endif

View File

@@ -1,122 +1,122 @@
/* /*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE THE SOFTWARE
*/ */
#ifndef __PGMSPACE_H_ #ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1 #define __PGMSPACE_H_ 1
#include <inttypes.h> #include <inttypes.h>
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PSTR(str) (str)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
typedef void prog_void; typedef void prog_void;
typedef char prog_char; typedef char prog_char;
typedef unsigned char prog_uchar; typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t; typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t; typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t; typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t; typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t; typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t; typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t; typedef const void* int_farptr_t;
typedef const void* uint_farptr_t; typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n)) #define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n)) #define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c)) #define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c)) #define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b)) #define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src)) #define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept)) #define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a)) #define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n)) #define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) #define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept)) #define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c)) #define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim)) #define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept)) #define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b)) #define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim)) #define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) #define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a)) #define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len)) #define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src)) #define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src)) #define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) #define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2)) #define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2)) #define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_ptr(addr) (*(const void **)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) #define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr)) #define pgm_get_far_address(addr) (&(addr))
#endif #endif

View File

@@ -1,122 +1,122 @@
/* /*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE THE SOFTWARE
*/ */
#ifndef __PGMSPACE_H_ #ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1 #define __PGMSPACE_H_ 1
#include <inttypes.h> #include <inttypes.h>
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PSTR(str) (str)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
typedef void prog_void; typedef void prog_void;
typedef char prog_char; typedef char prog_char;
typedef unsigned char prog_uchar; typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t; typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t; typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t; typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t; typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t; typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t; typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t; typedef const void* int_farptr_t;
typedef const void* uint_farptr_t; typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n)) #define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n)) #define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c)) #define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c)) #define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b)) #define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src)) #define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept)) #define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a)) #define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n)) #define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) #define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept)) #define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c)) #define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim)) #define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept)) #define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b)) #define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim)) #define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) #define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a)) #define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len)) #define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src)) #define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src)) #define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) #define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2)) #define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2)) #define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_ptr(addr) (*(const void **)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) #define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr)) #define pgm_get_far_address(addr) (&(addr))
#endif #endif

View File

@@ -1,122 +1,122 @@
/* /*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE THE SOFTWARE
*/ */
#ifndef __PGMSPACE_H_ #ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1 #define __PGMSPACE_H_ 1
#include <inttypes.h> #include <inttypes.h>
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PSTR(str) (str)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
typedef void prog_void; typedef void prog_void;
typedef char prog_char; typedef char prog_char;
typedef unsigned char prog_uchar; typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t; typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t; typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t; typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t; typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t; typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t; typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t; typedef const void* int_farptr_t;
typedef const void* uint_farptr_t; typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n)) #define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n)) #define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c)) #define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c)) #define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b)) #define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src)) #define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept)) #define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a)) #define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n)) #define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) #define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept)) #define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c)) #define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim)) #define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept)) #define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b)) #define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim)) #define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) #define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a)) #define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len)) #define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src)) #define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src)) #define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) #define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2)) #define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2)) #define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_ptr(addr) (*(const void **)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) #define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr)) #define pgm_get_far_address(addr) (&(addr))
#endif #endif

View File

@@ -1,122 +1,122 @@
/* /*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE THE SOFTWARE
*/ */
#ifndef __PGMSPACE_H_ #ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1 #define __PGMSPACE_H_ 1
#include <inttypes.h> #include <inttypes.h>
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PSTR(str) (str)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
typedef void prog_void; typedef void prog_void;
typedef char prog_char; typedef char prog_char;
typedef unsigned char prog_uchar; typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t; typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t; typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t; typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t; typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t; typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t; typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t; typedef const void* int_farptr_t;
typedef const void* uint_farptr_t; typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n)) #define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n)) #define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c)) #define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c)) #define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b)) #define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src)) #define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept)) #define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a)) #define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n)) #define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) #define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept)) #define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c)) #define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim)) #define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept)) #define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b)) #define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim)) #define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) #define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a)) #define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len)) #define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src)) #define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src)) #define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) #define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2)) #define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2)) #define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_ptr(addr) (*(const void **)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) #define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr)) #define pgm_get_far_address(addr) (&(addr))
#endif #endif

View File

@@ -1,122 +1,122 @@
/* /*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE THE SOFTWARE
*/ */
#ifndef __PGMSPACE_H_ #ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1 #define __PGMSPACE_H_ 1
#include <inttypes.h> #include <inttypes.h>
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PSTR(str) (str)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
typedef void prog_void; typedef void prog_void;
typedef char prog_char; typedef char prog_char;
typedef unsigned char prog_uchar; typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t; typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t; typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t; typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t; typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t; typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t; typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t; typedef const void* int_farptr_t;
typedef const void* uint_farptr_t; typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n)) #define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n)) #define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c)) #define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c)) #define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b)) #define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src)) #define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept)) #define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a)) #define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n)) #define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) #define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept)) #define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c)) #define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim)) #define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept)) #define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b)) #define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim)) #define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) #define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a)) #define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len)) #define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src)) #define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src)) #define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) #define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2)) #define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2)) #define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_ptr(addr) (*(const void **)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) #define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr)) #define pgm_get_far_address(addr) (&(addr))
#endif #endif

View File

@@ -1,122 +1,122 @@
/* /*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE THE SOFTWARE
*/ */
#ifndef __PGMSPACE_H_ #ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1 #define __PGMSPACE_H_ 1
#include <inttypes.h> #include <inttypes.h>
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PSTR(str) (str)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
typedef void prog_void; typedef void prog_void;
typedef char prog_char; typedef char prog_char;
typedef unsigned char prog_uchar; typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t; typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t; typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t; typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t; typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t; typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t; typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t; typedef const void* int_farptr_t;
typedef const void* uint_farptr_t; typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n)) #define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) #define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) #define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n)) #define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c)) #define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c)) #define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b)) #define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src)) #define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) #define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept)) #define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) #define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) #define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a)) #define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n)) #define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) #define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) #define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept)) #define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c)) #define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim)) #define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept)) #define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b)) #define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim)) #define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) #define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a)) #define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len)) #define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) #define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src)) #define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) #define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src)) #define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) #define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) #define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2)) #define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) #define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) #define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) #define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2)) #define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) #define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) #define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) #define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__) #define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(const void **)(addr)) #define pgm_read_ptr(addr) (*(const void **)(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) #define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr) #define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) #define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr)) #define pgm_get_far_address(addr) (&(addr))
#endif #endif

View File

@@ -1,22 +1,22 @@
/* /*
* Arduino header for the Raspberry Pi Pico RP2040 Arduino header for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com> Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef Arduino_h #ifndef Arduino_h
#define Arduino_h #define Arduino_h
@@ -37,7 +37,7 @@
#include "debug_internal.h" #include "debug_internal.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// For compatibility to many platforms and libraries // For compatibility to many platforms and libraries
@@ -103,8 +103,9 @@ unsigned long millis();
// Template which will evaluate at *compile time* to a single 32b number // Template which will evaluate at *compile time* to a single 32b number
// with the specified bits set. // with the specified bits set.
template <size_t N> template <size_t N>
constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) { constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U)
return i < N ? (1L << a[i]) | __bitset(a, i+1) : 0; {
return i < N ? (1L << a[i]) | __bitset(a, i + 1) : 0;
} }
#endif #endif

View File

@@ -1,22 +1,22 @@
/* /*
* Arduino header for the Raspberry Pi Pico RP2040 Arduino header for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com> Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef Arduino_h #ifndef Arduino_h
#define Arduino_h #define Arduino_h
@@ -37,7 +37,7 @@
#include "debug_internal.h" #include "debug_internal.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C"{ extern "C" {
#endif // __cplusplus #endif // __cplusplus
// For compatibility to many platforms and libraries // For compatibility to many platforms and libraries
@@ -103,8 +103,9 @@ unsigned long millis();
// Template which will evaluate at *compile time* to a single 32b number // Template which will evaluate at *compile time* to a single 32b number
// with the specified bits set. // with the specified bits set.
template <size_t N> template <size_t N>
constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) { constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U)
return i < N ? (1L << a[i]) | __bitset(a, i+1) : 0; {
return i < N ? (1L << a[i]) | __bitset(a, i + 1) : 0;
} }
#endif #endif