source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.cpp @ 46

Last change on this file since 46 was 46, checked in by jrpelegrina, 4 years ago

First release to Xenial

File size: 13.1 KB
Line 
1/*
2SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
3Multi-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
14This library is free software; you can redistribute it and/or
15modify it under the terms of the GNU Lesser General Public
16License as published by the Free Software Foundation; either
17version 2.1 of the License, or (at your option) any later version.
18
19This library is distributed in the hope that it will be useful,
20but WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22Lesser General Public License for more details.
23
24You should have received a copy of the GNU Lesser General Public
25License along with this library; if not, write to the Free Software
26Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27
28The latest version of this library can always be found at
29http://arduiniana.org.
30*/
31
32// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
33// oscilloscope or logic analyzer.  Beware: it also slightly modifies
34// the bit times, so don't rely on it too much at high baud rates
35#define _DEBUG 0
36#define _DEBUG_PIN1 11
37#define _DEBUG_PIN2 13
38//
39// Includes
40//
41#include <avr/interrupt.h>
42#include <avr/pgmspace.h>
43#include <Arduino.h>
44#include <SoftwareSerial.h>
45#include <util/delay_basic.h>
46
47//
48// Statics
49//
50SoftwareSerial *SoftwareSerial::active_object = 0;
51char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF]; 
52volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
53volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
54
55//
56// Debugging
57//
58// This function generates a brief pulse
59// for debugging or measuring on an oscilloscope.
60#if _DEBUG
61inline void DebugPulse(uint8_t pin, uint8_t count)
62{
63  volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
64
65  uint8_t val = *pport;
66  while (count--)
67  {
68    *pport = val | digitalPinToBitMask(pin);
69    *pport = val;
70  }
71}
72#else
73inline void DebugPulse(uint8_t, uint8_t) {}
74#endif
75
76//
77// Private methods
78//
79
80/* static */ 
81inline void SoftwareSerial::tunedDelay(uint16_t delay) { 
82  _delay_loop_2(delay);
83}
84
85// This function sets the current object as the "listening"
86// one and returns true if it replaces another
87bool SoftwareSerial::listen()
88{
89  if (!_rx_delay_stopbit)
90    return false;
91
92  if (active_object != this)
93  {
94    if (active_object)
95      active_object->stopListening();
96
97    _buffer_overflow = false;
98    _receive_buffer_head = _receive_buffer_tail = 0;
99    active_object = this;
100
101    setRxIntMsk(true);
102    return true;
103  }
104
105  return false;
106}
107
108// Stop listening. Returns true if we were actually listening.
109bool SoftwareSerial::stopListening()
110{
111  if (active_object == this)
112  {
113    setRxIntMsk(false);
114    active_object = NULL;
115    return true;
116  }
117  return false;
118}
119
120//
121// The receive routine called by the interrupt handler
122//
123void SoftwareSerial::recv()
124{
125
126#if GCC_VERSION < 40302
127// Work-around for avr-gcc 4.3.0 OSX version bug
128// Preserve the registers that the compiler misses
129// (courtesy of Arduino forum user *etracer*)
130  asm volatile(
131    "push r18 \n\t"
132    "push r19 \n\t"
133    "push r20 \n\t"
134    "push r21 \n\t"
135    "push r22 \n\t"
136    "push r23 \n\t"
137    "push r26 \n\t"
138    "push r27 \n\t"
139    ::);
140#endif 
141
142  uint8_t d = 0;
143
144  // If RX line is high, then we don't see any start bit
145  // so interrupt is probably not for us
146  if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
147  {
148    // Disable further interrupts during reception, this prevents
149    // triggering another interrupt directly after we return, which can
150    // cause problems at higher baudrates.
151    setRxIntMsk(false);
152
153    // Wait approximately 1/2 of a bit width to "center" the sample
154    tunedDelay(_rx_delay_centering);
155    DebugPulse(_DEBUG_PIN2, 1);
156
157    // Read each of the 8 bits
158    for (uint8_t i=8; i > 0; --i)
159    {
160      tunedDelay(_rx_delay_intrabit);
161      d >>= 1;
162      DebugPulse(_DEBUG_PIN2, 1);
163      if (rx_pin_read())
164        d |= 0x80;
165    }
166
167    if (_inverse_logic)
168      d = ~d;
169
170    // if buffer full, set the overflow flag and return
171    uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
172    if (next != _receive_buffer_head)
173    {
174      // save new data in buffer: tail points to where byte goes
175      _receive_buffer[_receive_buffer_tail] = d; // save new byte
176      _receive_buffer_tail = next;
177    } 
178    else 
179    {
180      DebugPulse(_DEBUG_PIN1, 1);
181      _buffer_overflow = true;
182    }
183
184    // skip the stop bit
185    tunedDelay(_rx_delay_stopbit);
186    DebugPulse(_DEBUG_PIN1, 1);
187
188    // Re-enable interrupts when we're sure to be inside the stop bit
189    setRxIntMsk(true);
190
191  }
192
193#if GCC_VERSION < 40302
194// Work-around for avr-gcc 4.3.0 OSX version bug
195// Restore the registers that the compiler misses
196  asm volatile(
197    "pop r27 \n\t"
198    "pop r26 \n\t"
199    "pop r23 \n\t"
200    "pop r22 \n\t"
201    "pop r21 \n\t"
202    "pop r20 \n\t"
203    "pop r19 \n\t"
204    "pop r18 \n\t"
205    ::);
206#endif
207}
208
209uint8_t SoftwareSerial::rx_pin_read()
210{
211  return *_receivePortRegister & _receiveBitMask;
212}
213
214//
215// Interrupt handling
216//
217
218/* static */
219inline void SoftwareSerial::handle_interrupt()
220{
221  if (active_object)
222  {
223    active_object->recv();
224  }
225}
226
227#if defined(PCINT0_vect)
228ISR(PCINT0_vect)
229{
230  SoftwareSerial::handle_interrupt();
231}
232#endif
233
234#if defined(PCINT1_vect)
235ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
236#endif
237
238#if defined(PCINT2_vect)
239ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
240#endif
241
242#if defined(PCINT3_vect)
243ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
244#endif
245
246//
247// Constructor
248//
249SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) : 
250  _rx_delay_centering(0),
251  _rx_delay_intrabit(0),
252  _rx_delay_stopbit(0),
253  _tx_delay(0),
254  _buffer_overflow(false),
255  _inverse_logic(inverse_logic)
256{
257  setTX(transmitPin);
258  setRX(receivePin);
259}
260
261//
262// Destructor
263//
264SoftwareSerial::~SoftwareSerial()
265{
266  end();
267}
268
269void SoftwareSerial::setTX(uint8_t tx)
270{
271  // First write, then set output. If we do this the other way around,
272  // the pin would be output low for a short while before switching to
273  // output hihg. Now, it is input with pullup for a short while, which
274  // is fine. With inverse logic, either order is fine.
275  digitalWrite(tx, _inverse_logic ? LOW : HIGH);
276  pinMode(tx, OUTPUT);
277  _transmitBitMask = digitalPinToBitMask(tx);
278  uint8_t port = digitalPinToPort(tx);
279  _transmitPortRegister = portOutputRegister(port);
280}
281
282void SoftwareSerial::setRX(uint8_t rx)
283{
284  pinMode(rx, INPUT);
285  if (!_inverse_logic)
286    digitalWrite(rx, HIGH);  // pullup for normal logic!
287  _receivePin = rx;
288  _receiveBitMask = digitalPinToBitMask(rx);
289  uint8_t port = digitalPinToPort(rx);
290  _receivePortRegister = portInputRegister(port);
291}
292
293uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) {
294  if (num > sub)
295    return num - sub;
296  else
297    return 1;
298}
299
300//
301// Public methods
302//
303
304void SoftwareSerial::begin(long speed)
305{
306  _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
307
308  // Precalculate the various delays, in number of 4-cycle delays
309  uint16_t bit_delay = (F_CPU / speed) / 4;
310
311  // 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit,
312  // 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits,
313  // 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit
314  // These are all close enough to just use 15 cycles, since the inter-bit
315  // timings are the most critical (deviations stack 8 times)
316  _tx_delay = subtract_cap(bit_delay, 15 / 4);
317
318  // Only setup rx when we have a valid PCINT for this pin
319  if (digitalPinToPCICR(_receivePin)) {
320    #if GCC_VERSION > 40800
321    // Timings counted from gcc 4.8.2 output. This works up to 115200 on
322    // 16Mhz and 57600 on 8Mhz.
323    //
324    // When the start bit occurs, there are 3 or 4 cycles before the
325    // interrupt flag is set, 4 cycles before the PC is set to the right
326    // interrupt vector address and the old PC is pushed on the stack,
327    // and then 75 cycles of instructions (including the RJMP in the
328    // ISR vector table) until the first delay. After the delay, there
329    // are 17 more cycles until the pin value is read (excluding the
330    // delay in the loop).
331    // We want to have a total delay of 1.5 bit time. Inside the loop,
332    // we already wait for 1 bit time - 23 cycles, so here we wait for
333    // 0.5 bit time - (71 + 18 - 22) cycles.
334    _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
335
336    // There are 23 cycles in each loop iteration (excluding the delay)
337    _rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
338
339    // There are 37 cycles from the last bit read to the start of
340    // stopbit delay and 11 cycles from the delay until the interrupt
341    // mask is enabled again (which _must_ happen during the stopbit).
342    // This delay aims at 3/4 of a bit time, meaning the end of the
343    // delay will be at 1/4th of the stopbit. This allows some extra
344    // time for ISR cleanup, which makes 115200 baud at 16Mhz work more
345    // reliably
346    _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
347    #else // Timings counted from gcc 4.3.2 output
348    // Note that this code is a _lot_ slower, mostly due to bad register
349    // allocation choices of gcc. This works up to 57600 on 16Mhz and
350    // 38400 on 8Mhz.
351    _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4);
352    _rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4);
353    _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4);
354    #endif
355
356
357    // Enable the PCINT for the entire port here, but never disable it
358    // (others might also need it, so we disable the interrupt by using
359    // the per-pin PCMSK register).
360    *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
361    // Precalculate the pcint mask register and value, so setRxIntMask
362    // can be used inside the ISR without costing too much time.
363    _pcint_maskreg = digitalPinToPCMSK(_receivePin);
364    _pcint_maskvalue = _BV(digitalPinToPCMSKbit(_receivePin));
365
366    tunedDelay(_tx_delay); // if we were low this establishes the end
367  }
368
369#if _DEBUG
370  pinMode(_DEBUG_PIN1, OUTPUT);
371  pinMode(_DEBUG_PIN2, OUTPUT);
372#endif
373
374  listen();
375}
376
377void SoftwareSerial::setRxIntMsk(bool enable)
378{
379    if (enable)
380      *_pcint_maskreg |= _pcint_maskvalue;
381    else
382      *_pcint_maskreg &= ~_pcint_maskvalue;
383}
384
385void SoftwareSerial::end()
386{
387  stopListening();
388}
389
390
391// Read data from buffer
392int SoftwareSerial::read()
393{
394  if (!isListening())
395    return -1;
396
397  // Empty buffer?
398  if (_receive_buffer_head == _receive_buffer_tail)
399    return -1;
400
401  // Read from "head"
402  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
403  _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
404  return d;
405}
406
407int SoftwareSerial::available()
408{
409  if (!isListening())
410    return 0;
411
412  return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
413}
414
415size_t SoftwareSerial::write(uint8_t b)
416{
417  if (_tx_delay == 0) {
418    setWriteError();
419    return 0;
420  }
421
422  // By declaring these as local variables, the compiler will put them
423  // in registers _before_ disabling interrupts and entering the
424  // critical timing sections below, which makes it a lot easier to
425  // verify the cycle timings
426  volatile uint8_t *reg = _transmitPortRegister;
427  uint8_t reg_mask = _transmitBitMask;
428  uint8_t inv_mask = ~_transmitBitMask;
429  uint8_t oldSREG = SREG;
430  bool inv = _inverse_logic;
431  uint16_t delay = _tx_delay;
432
433  if (inv)
434    b = ~b;
435
436  cli();  // turn off interrupts for a clean txmit
437
438  // Write the start bit
439  if (inv)
440    *reg |= reg_mask;
441  else
442    *reg &= inv_mask;
443
444  tunedDelay(delay);
445
446  // Write each of the 8 bits
447  for (uint8_t i = 8; i > 0; --i)
448  {
449    if (b & 1) // choose bit
450      *reg |= reg_mask; // send 1
451    else
452      *reg &= inv_mask; // send 0
453
454    tunedDelay(delay);
455    b >>= 1;
456  }
457
458  // restore pin to natural state
459  if (inv)
460    *reg &= inv_mask;
461  else
462    *reg |= reg_mask;
463
464  SREG = oldSREG; // turn interrupts back on
465  tunedDelay(_tx_delay);
466 
467  return 1;
468}
469
470void SoftwareSerial::flush()
471{
472  // There is no tx buffering, simply return
473}
474
475int SoftwareSerial::peek()
476{
477  if (!isListening())
478    return -1;
479
480  // Empty buffer?
481  if (_receive_buffer_head == _receive_buffer_tail)
482    return -1;
483
484  // Read from "head"
485  return _receive_buffer[_receive_buffer_head];
486}
Note: See TracBrowser for help on using the repository browser.