Project

General

Profile

Statistics
| Branch: | Revision:

root / arduino-1.0 / libraries / SoftwareSerial / SoftwareSerial.cpp @ 58d82c77

History | View | Annotate | Download (13.1 KB)

1 58d82c77 Tom Mullins
/*
2
SoftwareSerial.cpp (formerly NewSoftSerial.cpp) - 
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
// 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
//
46
// Lookup table
47
//
48
typedef struct _DELAY_TABLE
49
{
50
  long baud;
51
  unsigned short rx_delay_centering;
52
  unsigned short rx_delay_intrabit;
53
  unsigned short rx_delay_stopbit;
54
  unsigned short tx_delay;
55
} DELAY_TABLE;
56
57
#if F_CPU == 16000000
58
59
static const DELAY_TABLE PROGMEM table[] = 
60
{
61
  //  baud    rxcenter   rxintra    rxstop    tx
62
  { 115200,   1,         17,        17,       12,    },
63
  { 57600,    10,        37,        37,       33,    },
64
  { 38400,    25,        57,        57,       54,    },
65
  { 31250,    31,        70,        70,       68,    },
66
  { 28800,    34,        77,        77,       74,    },
67
  { 19200,    54,        117,       117,      114,   },
68
  { 14400,    74,        156,       156,      153,   },
69
  { 9600,     114,       236,       236,      233,   },
70
  { 4800,     233,       474,       474,      471,   },
71
  { 2400,     471,       950,       950,      947,   },
72
  { 1200,     947,       1902,      1902,     1899,  },
73
  { 300,      3804,      7617,      7617,     7614,  },
74
};
75
76
const int XMIT_START_ADJUSTMENT = 5;
77
78
#elif F_CPU == 8000000
79
80
static const DELAY_TABLE table[] PROGMEM = 
81
{
82
  //  baud    rxcenter    rxintra    rxstop  tx
83
  { 115200,   1,          5,         5,      3,      },
84
  { 57600,    1,          15,        15,     13,     },
85
  { 38400,    2,          25,        26,     23,     },
86
  { 31250,    7,          32,        33,     29,     },
87
  { 28800,    11,         35,        35,     32,     },
88
  { 19200,    20,         55,        55,     52,     },
89
  { 14400,    30,         75,        75,     72,     },
90
  { 9600,     50,         114,       114,    112,    },
91
  { 4800,     110,        233,       233,    230,    },
92
  { 2400,     229,        472,       472,    469,    },
93
  { 1200,     467,        948,       948,    945,    },
94
  { 300,      1895,       3805,      3805,   3802,   },
95
};
96
97
const int XMIT_START_ADJUSTMENT = 4;
98
99
#elif F_CPU == 20000000
100
101
// 20MHz support courtesy of the good people at macegr.com.
102
// Thanks, Garrett!
103
104
static const DELAY_TABLE PROGMEM table[] =
105
{
106
  //  baud    rxcenter    rxintra    rxstop  tx
107
  { 115200,   3,          21,        21,     18,     },
108
  { 57600,    20,         43,        43,     41,     },
109
  { 38400,    37,         73,        73,     70,     },
110
  { 31250,    45,         89,        89,     88,     },
111
  { 28800,    46,         98,        98,     95,     },
112
  { 19200,    71,         148,       148,    145,    },
113
  { 14400,    96,         197,       197,    194,    },
114
  { 9600,     146,        297,       297,    294,    },
115
  { 4800,     296,        595,       595,    592,    },
116
  { 2400,     592,        1189,      1189,   1186,   },
117
  { 1200,     1187,       2379,      2379,   2376,   },
118
  { 300,      4759,       9523,      9523,   9520,   },
119
};
120
121
const int XMIT_START_ADJUSTMENT = 6;
122
123
#else
124
125
#error This version of SoftwareSerial supports only 20, 16 and 8MHz processors
126
127
#endif
128
129
//
130
// Statics
131
//
132
SoftwareSerial *SoftwareSerial::active_object = 0;
133
char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF]; 
134
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
135
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
136
137
//
138
// Debugging
139
//
140
// This function generates a brief pulse
141
// for debugging or measuring on an oscilloscope.
142
inline void DebugPulse(uint8_t pin, uint8_t count)
143
{
144
#if _DEBUG
145
  volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
146
147
  uint8_t val = *pport;
148
  while (count--)
149
  {
150
    *pport = val | digitalPinToBitMask(pin);
151
    *pport = val;
152
  }
153
#endif
154
}
155
156
//
157
// Private methods
158
//
159
160
/* static */ 
161
inline void SoftwareSerial::tunedDelay(uint16_t delay) { 
162
  uint8_t tmp=0;
163
164
  asm volatile("sbiw    %0, 0x01 \n\t"
165
    "ldi %1, 0xFF \n\t"
166
    "cpi %A0, 0xFF \n\t"
167
    "cpc %B0, %1 \n\t"
168
    "brne .-10 \n\t"
169
    : "+r" (delay), "+a" (tmp)
170
    : "0" (delay)
171
    );
172
}
173
174
// This function sets the current object as the "listening"
175
// one and returns true if it replaces another 
176
bool SoftwareSerial::listen()
177
{
178
  if (active_object != this)
179
  {
180
    _buffer_overflow = false;
181
    uint8_t oldSREG = SREG;
182
    cli();
183
    _receive_buffer_head = _receive_buffer_tail = 0;
184
    active_object = this;
185
    SREG = oldSREG;
186
    return true;
187
  }
188
189
  return false;
190
}
191
192
//
193
// The receive routine called by the interrupt handler
194
//
195
void SoftwareSerial::recv()
196
{
197
198
#if GCC_VERSION < 40302
199
// Work-around for avr-gcc 4.3.0 OSX version bug
200
// Preserve the registers that the compiler misses
201
// (courtesy of Arduino forum user *etracer*)
202
  asm volatile(
203
    "push r18 \n\t"
204
    "push r19 \n\t"
205
    "push r20 \n\t"
206
    "push r21 \n\t"
207
    "push r22 \n\t"
208
    "push r23 \n\t"
209
    "push r26 \n\t"
210
    "push r27 \n\t"
211
    ::);
212
#endif  
213
214
  uint8_t d = 0;
215
216
  // If RX line is high, then we don't see any start bit
217
  // so interrupt is probably not for us
218
  if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
219
  {
220
    // Wait approximately 1/2 of a bit width to "center" the sample
221
    tunedDelay(_rx_delay_centering);
222
    DebugPulse(_DEBUG_PIN2, 1);
223
224
    // Read each of the 8 bits
225
    for (uint8_t i=0x1; i; i <<= 1)
226
    {
227
      tunedDelay(_rx_delay_intrabit);
228
      DebugPulse(_DEBUG_PIN2, 1);
229
      uint8_t noti = ~i;
230
      if (rx_pin_read())
231
        d |= i;
232
      else // else clause added to ensure function timing is ~balanced
233
        d &= noti;
234
    }
235
236
    // skip the stop bit
237
    tunedDelay(_rx_delay_stopbit);
238
    DebugPulse(_DEBUG_PIN2, 1);
239
240
    if (_inverse_logic)
241
      d = ~d;
242
243
    // if buffer full, set the overflow flag and return
244
    if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head) 
245
    {
246
      // save new data in buffer: tail points to where byte goes
247
      _receive_buffer[_receive_buffer_tail] = d; // save new byte
248
      _receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
249
    } 
250
    else 
251
    {
252
#if _DEBUG // for scope: pulse pin as overflow indictator
253
      DebugPulse(_DEBUG_PIN1, 1);
254
#endif
255
      _buffer_overflow = true;
256
    }
257
  }
258
259
#if GCC_VERSION < 40302
260
// Work-around for avr-gcc 4.3.0 OSX version bug
261
// Restore the registers that the compiler misses
262
  asm volatile(
263
    "pop r27 \n\t"
264
    "pop r26 \n\t"
265
    "pop r23 \n\t"
266
    "pop r22 \n\t"
267
    "pop r21 \n\t"
268
    "pop r20 \n\t"
269
    "pop r19 \n\t"
270
    "pop r18 \n\t"
271
    ::);
272
#endif
273
}
274
275
void SoftwareSerial::tx_pin_write(uint8_t pin_state)
276
{
277
  if (pin_state == LOW)
278
    *_transmitPortRegister &= ~_transmitBitMask;
279
  else
280
    *_transmitPortRegister |= _transmitBitMask;
281
}
282
283
uint8_t SoftwareSerial::rx_pin_read()
284
{
285
  return *_receivePortRegister & _receiveBitMask;
286
}
287
288
//
289
// Interrupt handling
290
//
291
292
/* static */
293
inline void SoftwareSerial::handle_interrupt()
294
{
295
  if (active_object)
296
  {
297
    active_object->recv();
298
  }
299
}
300
301
#if defined(PCINT0_vect)
302
ISR(PCINT0_vect)
303
{
304
  SoftwareSerial::handle_interrupt();
305
}
306
#endif
307
308
#if defined(PCINT1_vect)
309
ISR(PCINT1_vect)
310
{
311
  SoftwareSerial::handle_interrupt();
312
}
313
#endif
314
315
#if defined(PCINT2_vect)
316
ISR(PCINT2_vect)
317
{
318
  SoftwareSerial::handle_interrupt();
319
}
320
#endif
321
322
#if defined(PCINT3_vect)
323
ISR(PCINT3_vect)
324
{
325
  SoftwareSerial::handle_interrupt();
326
}
327
#endif
328
329
//
330
// Constructor
331
//
332
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) : 
333
  _rx_delay_centering(0),
334
  _rx_delay_intrabit(0),
335
  _rx_delay_stopbit(0),
336
  _tx_delay(0),
337
  _buffer_overflow(false),
338
  _inverse_logic(inverse_logic)
339
{
340
  setTX(transmitPin);
341
  setRX(receivePin);
342
}
343
344
//
345
// Destructor
346
//
347
SoftwareSerial::~SoftwareSerial()
348
{
349
  end();
350
}
351
352
void SoftwareSerial::setTX(uint8_t tx)
353
{
354
  pinMode(tx, OUTPUT);
355
  digitalWrite(tx, HIGH);
356
  _transmitBitMask = digitalPinToBitMask(tx);
357
  uint8_t port = digitalPinToPort(tx);
358
  _transmitPortRegister = portOutputRegister(port);
359
}
360
361
void SoftwareSerial::setRX(uint8_t rx)
362
{
363
  pinMode(rx, INPUT);
364
  if (!_inverse_logic)
365
    digitalWrite(rx, HIGH);  // pullup for normal logic!
366
  _receivePin = rx;
367
  _receiveBitMask = digitalPinToBitMask(rx);
368
  uint8_t port = digitalPinToPort(rx);
369
  _receivePortRegister = portInputRegister(port);
370
}
371
372
//
373
// Public methods
374
//
375
376
void SoftwareSerial::begin(long speed)
377
{
378
  _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
379
380
  for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
381
  {
382
    long baud = pgm_read_dword(&table[i].baud);
383
    if (baud == speed)
384
    {
385
      _rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
386
      _rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
387
      _rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
388
      _tx_delay = pgm_read_word(&table[i].tx_delay);
389
      break;
390
    }
391
  }
392
393
  // Set up RX interrupts, but only if we have a valid RX baud rate
394
  if (_rx_delay_stopbit)
395
  {
396
    if (digitalPinToPCICR(_receivePin))
397
    {
398
      *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
399
      *digitalPinToPCMSK(_receivePin) |= _BV(digitalPinToPCMSKbit(_receivePin));
400
    }
401
    tunedDelay(_tx_delay); // if we were low this establishes the end
402
  }
403
404
#if _DEBUG
405
  pinMode(_DEBUG_PIN1, OUTPUT);
406
  pinMode(_DEBUG_PIN2, OUTPUT);
407
#endif
408
409
  listen();
410
}
411
412
void SoftwareSerial::end()
413
{
414
  if (digitalPinToPCMSK(_receivePin))
415
    *digitalPinToPCMSK(_receivePin) &= ~_BV(digitalPinToPCMSKbit(_receivePin));
416
}
417
418
419
// Read data from buffer
420
int SoftwareSerial::read()
421
{
422
  if (!isListening())
423
    return -1;
424
425
  // Empty buffer?
426
  if (_receive_buffer_head == _receive_buffer_tail)
427
    return -1;
428
429
  // Read from "head"
430
  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
431
  _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
432
  return d;
433
}
434
435
int SoftwareSerial::available()
436
{
437
  if (!isListening())
438
    return 0;
439
440
  return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
441
}
442
443
size_t SoftwareSerial::write(uint8_t b)
444
{
445
  if (_tx_delay == 0) {
446
    setWriteError();
447
    return 0;
448
  }
449
450
  uint8_t oldSREG = SREG;
451
  cli();  // turn off interrupts for a clean txmit
452
453
  // Write the start bit
454
  tx_pin_write(_inverse_logic ? HIGH : LOW);
455
  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);
456
457
  // Write each of the 8 bits
458
  if (_inverse_logic)
459
  {
460
    for (byte mask = 0x01; mask; mask <<= 1)
461
    {
462
      if (b & mask) // choose bit
463
        tx_pin_write(LOW); // send 1
464
      else
465
        tx_pin_write(HIGH); // send 0
466
    
467
      tunedDelay(_tx_delay);
468
    }
469
470
    tx_pin_write(LOW); // restore pin to natural state
471
  }
472
  else
473
  {
474
    for (byte mask = 0x01; mask; mask <<= 1)
475
    {
476
      if (b & mask) // choose bit
477
        tx_pin_write(HIGH); // send 1
478
      else
479
        tx_pin_write(LOW); // send 0
480
    
481
      tunedDelay(_tx_delay);
482
    }
483
484
    tx_pin_write(HIGH); // restore pin to natural state
485
  }
486
487
  SREG = oldSREG; // turn interrupts back on
488
  tunedDelay(_tx_delay);
489
  
490
  return 1;
491
}
492
493
void SoftwareSerial::flush()
494
{
495
  if (!isListening())
496
    return;
497
498
  uint8_t oldSREG = SREG;
499
  cli();
500
  _receive_buffer_head = _receive_buffer_tail = 0;
501
  SREG = oldSREG;
502
}
503
504
int SoftwareSerial::peek()
505
{
506
  if (!isListening())
507
    return -1;
508
509
  // Empty buffer?
510
  if (_receive_buffer_head == _receive_buffer_tail)
511
    return -1;
512
513
  // Read from "head"
514
  return _receive_buffer[_receive_buffer_head];
515
}