From e011dab7b413949c942ad31c3d9c6003f76133c0 Mon Sep 17 00:00:00 2001 From: amcewen Date: Mon, 28 Mar 2011 12:08:53 +0100 Subject: Pulled out Client API into a base class to allow multiple derived classes to use it, and moved it (plus IPAddress) out of the Ethernet library so that other libraries can find it. First steps in integrating the WiFly code so it's easier to switch between that and Ethernet --- cores/arduino/IPAddress.cpp | 44 +++++++++++++++++++++++++++ cores/arduino/IPAddress.h | 72 +++++++++++++++++++++++++++++++++++++++++++++ cores/arduino/NetClient.h | 28 ++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 cores/arduino/IPAddress.cpp create mode 100644 cores/arduino/IPAddress.h create mode 100644 cores/arduino/NetClient.h (limited to 'cores') diff --git a/cores/arduino/IPAddress.cpp b/cores/arduino/IPAddress.cpp new file mode 100644 index 0000000..408d518 --- /dev/null +++ b/cores/arduino/IPAddress.cpp @@ -0,0 +1,44 @@ + +#include +#include + +IPAddress::IPAddress() +{ + memset(_address, 0, sizeof(_address)); +} + +IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) +{ + _address[0] = first_octet; + _address[1] = second_octet; + _address[2] = third_octet; + _address[3] = fourth_octet; +} + +IPAddress::IPAddress(uint32_t address) +{ + memcpy(_address, &address, sizeof(_address)); +} + +IPAddress::IPAddress(const uint8_t *address) +{ + memcpy(_address, address, sizeof(_address)); +} + +IPAddress& IPAddress::operator=(const uint8_t *address) +{ + memcpy(_address, address, sizeof(_address)); + return *this; +} + +IPAddress& IPAddress::operator=(uint32_t address) +{ + memcpy(_address, (const uint8_t *)&address, sizeof(_address)); + return *this; +} + +bool IPAddress::operator==(const uint8_t* addr) +{ + return memcmp(addr, _address, sizeof(_address)) == 0; +} + diff --git a/cores/arduino/IPAddress.h b/cores/arduino/IPAddress.h new file mode 100644 index 0000000..487e420 --- /dev/null +++ b/cores/arduino/IPAddress.h @@ -0,0 +1,72 @@ +/* + * + * MIT License: + * Copyright (c) 2011 Adrian McEwen + * 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. + * + * adrianm@mcqn.com 1/1/2011 + */ + +#ifndef IPAddress_h +#define IPAddress_h + +// A class to make it easier to handle and pass around IP addresses + +class IPAddress { +private: + uint8_t _address[4]; // IPv4 address + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t* raw_address() { return _address; }; + +public: + // Constructors + IPAddress(); + IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + IPAddress(uint32_t address); + IPAddress(const uint8_t *address); + + // Overloaded cast operator to allow IPAddress objects to be used where a pointer + // to a four-byte uint8_t array is expected + operator uint32_t() { return *((uint32_t*)_address); }; + bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); }; + bool operator==(const uint8_t* addr); + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const { return _address[index]; }; + uint8_t& operator[](int index) { return _address[index]; }; + + // Overloaded copy operators to allow initialisation of IPAddress objects from other types + IPAddress& operator=(const uint8_t *address); + IPAddress& operator=(uint32_t address); + + friend class EthernetClass; + friend class UDP; + friend class Client; + friend class Server; + friend class DhcpClass; + friend class DNSClient; +}; + +const IPAddress INADDR_NONE(0,0,0,0); + + +#endif diff --git a/cores/arduino/NetClient.h b/cores/arduino/NetClient.h new file mode 100644 index 0000000..d8df914 --- /dev/null +++ b/cores/arduino/NetClient.h @@ -0,0 +1,28 @@ +#ifndef netclient_h +#define netclient_h +#include "WProgram.h" +#include "Print.h" +#include "NetClient.h" +#include "IPAddress.h" + +class NetClient : public Stream { + +public: + virtual int connect(IPAddress ip, uint16_t port) =0; + virtual int connect(const char *host, uint16_t port) =0; + virtual void write(uint8_t) =0; + virtual void write(const char *str) =0; + virtual void write(const uint8_t *buf, size_t size) =0; + virtual int available() = 0; + virtual int read() = 0; + virtual int read(uint8_t *buf, size_t size) = 0; + virtual int peek() = 0; + virtual void flush() = 0; + virtual void stop() = 0; + virtual uint8_t connected() = 0; + virtual uint8_t operator==(int) = 0; + virtual uint8_t operator!=(int) = 0; + virtual operator bool() = 0; +}; + +#endif -- cgit v1.2.3-18-g5258 From e852be3e97763e621a0f8014a3db4bf92a650b50 Mon Sep 17 00:00:00 2001 From: amcewen Date: Thu, 31 Mar 2011 16:19:17 +0100 Subject: Pulled out Server API into the NetServer base class, and a few minor changes to get the NetClient API to work well with the WiFly library --- cores/arduino/NetClient.h | 2 -- cores/arduino/NetServer.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 cores/arduino/NetServer.h (limited to 'cores') diff --git a/cores/arduino/NetClient.h b/cores/arduino/NetClient.h index d8df914..ea64664 100644 --- a/cores/arduino/NetClient.h +++ b/cores/arduino/NetClient.h @@ -20,8 +20,6 @@ public: virtual void flush() = 0; virtual void stop() = 0; virtual uint8_t connected() = 0; - virtual uint8_t operator==(int) = 0; - virtual uint8_t operator!=(int) = 0; virtual operator bool() = 0; }; diff --git a/cores/arduino/NetServer.h b/cores/arduino/NetServer.h new file mode 100644 index 0000000..91f4848 --- /dev/null +++ b/cores/arduino/NetServer.h @@ -0,0 +1,11 @@ +#ifndef netserver_h +#define netserver_h + +class NetClient; + +class NetServer { +public: + virtual void begin() =0; +}; + +#endif -- cgit v1.2.3-18-g5258 From 2cedbeef132256ceca033f4b5073ab9aba818130 Mon Sep 17 00:00:00 2001 From: amcewen Date: Fri, 1 Apr 2011 21:10:38 +0100 Subject: Added Printable interface class to allow printing of classes such as IPAddress --- cores/arduino/Print.cpp | 11 +++++++++++ cores/arduino/Print.h | 3 +++ cores/arduino/Printable.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 cores/arduino/Printable.h (limited to 'cores') diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 4ee556d..f5e77e0 100755 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -101,6 +101,11 @@ void Print::print(double n, int digits) printFloat(n, digits); } +void Print::print(const Printable& x) +{ + x.printTo(*this); +} + void Print::println(void) { print('\r'); @@ -161,6 +166,12 @@ void Print::println(double n, int digits) println(); } +void Print::println(const Printable& x) +{ + print(x); + println(); +} + // Private Methods ///////////////////////////////////////////////////////////// void Print::printNumber(unsigned long n, uint8_t base) diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index b092ae5..d2014bf 100755 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -24,6 +24,7 @@ #include // for size_t #include "WString.h" +#include "Printable.h" #define DEC 10 #define HEX 16 @@ -50,6 +51,7 @@ class Print void print(long, int = DEC); void print(unsigned long, int = DEC); void print(double, int = 2); + void print(const Printable&); void println(const String &s); void println(const char[]); @@ -60,6 +62,7 @@ class Print void println(long, int = DEC); void println(unsigned long, int = DEC); void println(double, int = 2); + void println(const Printable&); void println(void); }; diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h new file mode 100644 index 0000000..fc64858 --- /dev/null +++ b/cores/arduino/Printable.h @@ -0,0 +1,32 @@ +/* + Printable.h - Interface class that allows printing of complex types + Copyright (c) 2011 Adrian McEwen. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +class Print; + +class Printable +{ + public: + virtual void printTo(Print& p) const =0; +}; + +#endif + -- cgit v1.2.3-18-g5258 From 49155d0a4604eb50d756527ef9512499d2ea6cf4 Mon Sep 17 00:00:00 2001 From: amcewen Date: Sat, 2 Apr 2011 11:33:27 +0100 Subject: Added a brief explanation of how you'd use Printable --- cores/arduino/Printable.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'cores') diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h index fc64858..e5d7732 100644 --- a/cores/arduino/Printable.h +++ b/cores/arduino/Printable.h @@ -22,6 +22,12 @@ class Print; +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + class Printable { public: -- cgit v1.2.3-18-g5258 From edee02eaf19c4d13324959e6db881dc327342561 Mon Sep 17 00:00:00 2001 From: amcewen Date: Sun, 10 Apr 2011 11:34:40 +0100 Subject: Added virtual destructor to Printable, which also requires new and delete operators to be added --- cores/arduino/Printable.h | 3 +++ cores/arduino/new.cpp | 18 ++++++++++++++++++ cores/arduino/new.h | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 cores/arduino/new.cpp create mode 100644 cores/arduino/new.h (limited to 'cores') diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h index e5d7732..5ff6077 100644 --- a/cores/arduino/Printable.h +++ b/cores/arduino/Printable.h @@ -20,6 +20,8 @@ #ifndef Printable_h #define Printable_h +#include + class Print; /** The Printable class provides a way for new classes to allow themselves to be printed. @@ -31,6 +33,7 @@ class Print; class Printable { public: + virtual ~Printable() {}; virtual void printTo(Print& p) const =0; }; diff --git a/cores/arduino/new.cpp b/cores/arduino/new.cpp new file mode 100644 index 0000000..0f6d422 --- /dev/null +++ b/cores/arduino/new.cpp @@ -0,0 +1,18 @@ +#include + +void * operator new(size_t size) +{ + return malloc(size); +} + +void operator delete(void * ptr) +{ + free(ptr); +} + +int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);}; +void __cxa_guard_release (__guard *g) {*(char *)g = 1;}; +void __cxa_guard_abort (__guard *) {}; + +void __cxa_pure_virtual(void) {}; + diff --git a/cores/arduino/new.h b/cores/arduino/new.h new file mode 100644 index 0000000..cd940ce --- /dev/null +++ b/cores/arduino/new.h @@ -0,0 +1,22 @@ +/* Header to define new/delete operators as they aren't provided by avr-gcc by default + Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453 + */ + +#ifndef NEW_H +#define NEW_H + +#include + +void * operator new(size_t size); +void operator delete(void * ptr); + +__extension__ typedef int __guard __attribute__((mode (__DI__))); + +extern "C" int __cxa_guard_acquire(__guard *); +extern "C" void __cxa_guard_release (__guard *); +extern "C" void __cxa_guard_abort (__guard *); + +extern "C" void __cxa_pure_virtual(void); + +#endif + -- cgit v1.2.3-18-g5258 From 528e95b14d333f7391f9baffc98a9f9362bde130 Mon Sep 17 00:00:00 2001 From: amcewen Date: Sun, 28 Aug 2011 22:26:07 +0100 Subject: Final changes to integrate latest core updates to WiFly branch --- cores/arduino/NetClient.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'cores') diff --git a/cores/arduino/NetClient.h b/cores/arduino/NetClient.h index ea64664..35bfa0a 100644 --- a/cores/arduino/NetClient.h +++ b/cores/arduino/NetClient.h @@ -1,6 +1,5 @@ #ifndef netclient_h #define netclient_h -#include "WProgram.h" #include "Print.h" #include "NetClient.h" #include "IPAddress.h" @@ -10,9 +9,9 @@ class NetClient : public Stream { public: virtual int connect(IPAddress ip, uint16_t port) =0; virtual int connect(const char *host, uint16_t port) =0; - virtual void write(uint8_t) =0; - virtual void write(const char *str) =0; - virtual void write(const uint8_t *buf, size_t size) =0; + virtual size_t write(uint8_t) =0; + virtual size_t write(const char *str) =0; + virtual size_t write(const uint8_t *buf, size_t size) =0; virtual int available() = 0; virtual int read() = 0; virtual int read(uint8_t *buf, size_t size) = 0; -- cgit v1.2.3-18-g5258 From 3f7d2c8977368de7b2309a511c36d2a5d802f7c9 Mon Sep 17 00:00:00 2001 From: amcewen Date: Mon, 29 Aug 2011 22:36:28 +0100 Subject: Changed names of the Ethernet classes: Client -> EthernetClient, NetClient -> Client, and basic testing performed --- cores/arduino/Client.h | 27 +++++++++++++++++++++++++++ cores/arduino/NetClient.h | 25 ------------------------- cores/arduino/NetServer.h | 11 ----------- cores/arduino/Server.h | 9 +++++++++ 4 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 cores/arduino/Client.h delete mode 100644 cores/arduino/NetClient.h delete mode 100644 cores/arduino/NetServer.h create mode 100644 cores/arduino/Server.h (limited to 'cores') diff --git a/cores/arduino/Client.h b/cores/arduino/Client.h new file mode 100644 index 0000000..ed9e9b4 --- /dev/null +++ b/cores/arduino/Client.h @@ -0,0 +1,27 @@ +#ifndef client_h +#define client_h +#include "Print.h" +#include "Stream.h" +#include "IPAddress.h" + +class Client : public Stream { + +public: + virtual int connect(IPAddress ip, uint16_t port) =0; + virtual int connect(const char *host, uint16_t port) =0; + virtual size_t write(uint8_t) =0; + virtual size_t write(const char *str) =0; + virtual size_t write(const uint8_t *buf, size_t size) =0; + virtual int available() = 0; + virtual int read() = 0; + virtual int read(uint8_t *buf, size_t size) = 0; + virtual int peek() = 0; + virtual void flush() = 0; + virtual void stop() = 0; + virtual uint8_t connected() = 0; + virtual operator bool() = 0; +protected: + uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); }; +}; + +#endif diff --git a/cores/arduino/NetClient.h b/cores/arduino/NetClient.h deleted file mode 100644 index 35bfa0a..0000000 --- a/cores/arduino/NetClient.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef netclient_h -#define netclient_h -#include "Print.h" -#include "NetClient.h" -#include "IPAddress.h" - -class NetClient : public Stream { - -public: - virtual int connect(IPAddress ip, uint16_t port) =0; - virtual int connect(const char *host, uint16_t port) =0; - virtual size_t write(uint8_t) =0; - virtual size_t write(const char *str) =0; - virtual size_t write(const uint8_t *buf, size_t size) =0; - virtual int available() = 0; - virtual int read() = 0; - virtual int read(uint8_t *buf, size_t size) = 0; - virtual int peek() = 0; - virtual void flush() = 0; - virtual void stop() = 0; - virtual uint8_t connected() = 0; - virtual operator bool() = 0; -}; - -#endif diff --git a/cores/arduino/NetServer.h b/cores/arduino/NetServer.h deleted file mode 100644 index 91f4848..0000000 --- a/cores/arduino/NetServer.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef netserver_h -#define netserver_h - -class NetClient; - -class NetServer { -public: - virtual void begin() =0; -}; - -#endif diff --git a/cores/arduino/Server.h b/cores/arduino/Server.h new file mode 100644 index 0000000..edab726 --- /dev/null +++ b/cores/arduino/Server.h @@ -0,0 +1,9 @@ +#ifndef server_h +#define server_h + +class Server { +public: + virtual void begin() =0; +}; + +#endif -- cgit v1.2.3-18-g5258 From 527ff3c7f8e3409ce0ea78b7fa689acd34d51332 Mon Sep 17 00:00:00 2001 From: amcewen Date: Tue, 30 Aug 2011 21:27:31 +0100 Subject: Created an abstract base class UDP to match the Client and Server classes, and reworked the Ethernet library to use it and derive EthernetUDP. --- cores/arduino/Udp.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 cores/arduino/Udp.h (limited to 'cores') diff --git a/cores/arduino/Udp.h b/cores/arduino/Udp.h new file mode 100644 index 0000000..1fb9cd3 --- /dev/null +++ b/cores/arduino/Udp.h @@ -0,0 +1,90 @@ +/* + * 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 +#include + +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 + 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 a string of characters into the packet + virtual size_t write(const char *str) =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 -- cgit v1.2.3-18-g5258 From 84a0ad9fd3be4e90d3dbd730246dc30851012a09 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Wed, 31 Aug 2011 15:39:20 -0400 Subject: Renaming writeError() to getWriteError() in Print (and Stream and friends). http://code.google.com/p/arduino/issues/detail?id=608 --- cores/arduino/Print.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cores') diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index fce302e..8530b03 100755 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -42,7 +42,7 @@ class Print public: Print() : write_error(0) {} - int writeError() { return write_error; } + int getWriteError() { return write_error; } void clearWriteError() { setWriteError(0); } virtual size_t write(uint8_t) = 0; -- cgit v1.2.3-18-g5258 From 7b0d88b954d7e62495cdf03d732f2d5f90ab5bec Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Wed, 31 Aug 2011 15:52:56 -0400 Subject: Moving serialEvent() calls from RX interrupts to main for() loop (after loop()). http://code.google.com/p/arduino/issues/detail?id=584 --- cores/arduino/HardwareSerial.cpp | 53 +++++++++++++++++++++++++++++++++++++--- cores/arduino/HardwareSerial.h | 2 ++ cores/arduino/main.cpp | 4 ++- 3 files changed, 54 insertions(+), 5 deletions(-) (limited to 'cores') diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index d6be218..3ed8d07 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -88,6 +88,8 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #else void serialEvent() __attribute__((weak)); void serialEvent() {} + volatile static unsigned char serialEvent_flag = 0; + #define serialEvent_implemented #if defined(USART_RX_vect) SIGNAL(USART_RX_vect) #elif defined(SIG_USART0_RECV) @@ -108,18 +110,20 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #error UDR not defined #endif store_char(c, &rx_buffer); - serialEvent(); + serialEvent_flag = 1; } #endif #if defined(USART1_RX_vect) void serialEvent1() __attribute__((weak)); void serialEvent1() {} + volatile static unsigned char serialEvent1_flag = 0; + #define serialEvent1_implemented SIGNAL(USART1_RX_vect) { unsigned char c = UDR1; store_char(c, &rx_buffer1); - serialEvent1(); + serialEvent1_flag = 1; } #elif defined(SIG_USART1_RECV) #error SIG_USART1_RECV @@ -128,11 +132,13 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #if defined(USART2_RX_vect) && defined(UDR2) void serialEvent2() __attribute__((weak)); void serialEvent2() {} + volatile static unsigned char serialEvent2_flag = 0; + #define serialEvent2_implemented SIGNAL(USART2_RX_vect) { unsigned char c = UDR2; store_char(c, &rx_buffer2); - serialEvent2(); + serialEvent2_flag = 1; } #elif defined(SIG_USART2_RECV) #error SIG_USART2_RECV @@ -141,16 +147,55 @@ inline void store_char(unsigned char c, ring_buffer *buffer) #if defined(USART3_RX_vect) && defined(UDR3) void serialEvent3() __attribute__((weak)); void serialEvent3() {} + volatile static unsigned char serialEvent3_flag = 0; + #define serialEvent3_implemented SIGNAL(USART3_RX_vect) { unsigned char c = UDR3; store_char(c, &rx_buffer3); - serialEvent3(); + serialEvent3_flag = 1; } #elif defined(SIG_USART3_RECV) #error SIG_USART3_RECV #endif +void serialEventRun(void) +{ + unsigned char flag, oldSREG; +#ifdef serialEvent_implemented + oldSREG = SREG; + noInterrupts(); + flag = serialEvent_flag; + serialEvent_flag = 0; + SREG = oldSREG; + if (flag) serialEvent(); +#endif +#ifdef serialEvent1_implemented + oldSREG = SREG; + noInterrupts(); + flag = serialEvent1_flag; + serialEvent1_flag = 0; + SREG = oldSREG; + if (flag) serialEvent1(); +#endif +#ifdef serialEvent2_implemented + oldSREG = SREG; + noInterrupts(); + flag = serialEvent2_flag; + serialEvent2_flag = 0; + SREG = oldSREG; + if (flag) serialEvent2(); +#endif +#ifdef serialEvent3_implemented + oldSREG = SREG; + noInterrupts(); + flag = serialEvent3_flag; + serialEvent3_flag = 0; + SREG = oldSREG; + if (flag) serialEvent3(); +#endif +} + #if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect) #error Don't know what the Data Register Empty vector is called for the first UART diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 1895f08..cbb0e5e 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -74,4 +74,6 @@ class HardwareSerial : public Stream extern HardwareSerial Serial3; #endif +extern void serialEventRun(void); + #endif diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 3c46f1e..1c2ea9a 100755 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -7,8 +7,10 @@ int main(void) setup(); - for (;;) + for (;;) { loop(); + serialEventRun(); + } return 0; } -- cgit v1.2.3-18-g5258