1 | /* |
2 | SoftwareSerial.h (formerly NewSoftSerial.h) - |
3 | Multi-instance software serial library for Arduino/Wiring |
4 | -- Interrupt-driven receive and other improvements by ladyada |
5 | (http://ladyada.net) |
6 | -- Tuning, circular buffer, derivation from class Print/Stream, |
7 | multi-instance support, porting to 8MHz processors, |
8 | various optimizations, PROGMEM delay tables, inverse logic and |
9 | direct port writing by Mikal Hart (http://www.arduiniana.org) |
10 | -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) |
11 | -- 20MHz processor support by Garrett Mace (http://www.macetech.com) |
12 | -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) |
13 | |
14 | This library is free software; you can redistribute it and/or |
15 | modify it under the terms of the GNU Lesser General Public |
16 | License as published by the Free Software Foundation; either |
17 | version 2.1 of the License, or (at your option) any later version. |
18 | |
19 | This library is distributed in the hope that it will be useful, |
20 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
22 | Lesser General Public License for more details. |
23 | |
24 | You should have received a copy of the GNU Lesser General Public |
25 | License along with this library; if not, write to the Free Software |
26 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
27 | |
28 | The latest version of this library can always be found at |
29 | http://arduiniana.org. |
30 | */ |
31 |
|
32 | #ifndef SoftwareSerial_h |
33 | #define SoftwareSerial_h |
34 |
|
35 | #include <inttypes.h> |
36 | #include <Stream.h> |
37 |
|
38 | /****************************************************************************** |
39 | * Definitions |
40 | ******************************************************************************/ |
41 |
|
42 | #ifndef _SS_MAX_RX_BUFF |
43 | #define _SS_MAX_RX_BUFF 64 // RX buffer size |
44 | #endif |
45 |
|
46 | #ifndef GCC_VERSION |
47 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) |
48 | #endif |
49 |
|
50 | class SoftwareSerial : public Stream |
51 | { |
52 | private: |
53 | // per object data |
54 | uint8_t _receivePin; |
55 | uint8_t _receiveBitMask; |
56 | volatile uint8_t *_receivePortRegister; |
57 | uint8_t _transmitBitMask; |
58 | volatile uint8_t *_transmitPortRegister; |
59 | volatile uint8_t *_pcint_maskreg; |
60 | uint8_t _pcint_maskvalue; |
61 |
|
62 | // Expressed as 4-cycle delays (must never be 0!) |
63 | uint16_t _rx_delay_centering; |
64 | uint16_t _rx_delay_intrabit; |
65 | uint16_t _rx_delay_stopbit; |
66 | uint16_t _tx_delay; |
67 |
|
68 | uint16_t _buffer_overflow:1; |
69 | uint16_t _inverse_logic:1; |
70 |
|
71 | // static data |
72 | static uint8_t _receive_buffer[_SS_MAX_RX_BUFF]; |
73 | static volatile uint8_t _receive_buffer_tail; |
74 | static volatile uint8_t _receive_buffer_head; |
75 | static SoftwareSerial *active_object; |
76 |
|
77 | // private methods |
78 | inline void recv() __attribute__((__always_inline__)); |
79 | uint8_t rx_pin_read(); |
80 | void setTX(uint8_t transmitPin); |
81 | void setRX(uint8_t receivePin); |
82 | inline void setRxIntMsk(bool enable) __attribute__((__always_inline__)); |
83 |
|
84 | // Return num - sub, or 1 if the result would be < 1 |
85 | static uint16_t subtract_cap(uint16_t num, uint16_t sub); |
86 |
|
87 | // private static method for timing |
88 | static inline void tunedDelay(uint16_t delay); |
89 |
|
90 | public: |
91 | // public methods |
92 | SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false); |
93 | ~SoftwareSerial(); |
94 | void begin(long speed); |
95 | bool listen(); |
96 | void end(); |
97 | bool isListening() { return this == active_object; } |
98 | bool stopListening(); |
99 | bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; } |
100 | int peek(); |
101 |
|
102 | virtual size_t write(uint8_t byte); |
103 | virtual int read(); |
104 | virtual int available(); |
105 | virtual void flush(); |
106 | operator bool() { return true; } |
107 | |
108 | using Print::write; |
109 |
|
110 | // public only for easy access by interrupt handlers |
111 | static inline void handle_interrupt() __attribute__((__always_inline__)); |
112 | }; |
113 |
|
114 | // Arduino 0012 workaround |
115 | #undef int |
116 | #undef char |
117 | #undef long |
118 | #undef byte |
119 | #undef float |
120 | #undef abs |
121 | #undef round |
122 |
|
123 | #endif |
124 |
|