D:/DRISSI/arduino-0022/arduino-0022/libraries/SoftwareSerial/SoftwareSerial.cpp
00001 /*
00002   SoftwareSerial.cpp - Software serial library
00003   Copyright (c) 2006 David A. Mellis.  All right reserved.
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the Free Software
00017   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00020 /******************************************************************************
00021  * Includes
00022  ******************************************************************************/
00023 
00024 #include "WConstants.h"
00025 #include "SoftwareSerial.h"
00026 
00027 /******************************************************************************
00028  * Definitions
00029  ******************************************************************************/
00030 
00031 /******************************************************************************
00032  * Constructors
00033  ******************************************************************************/
00034 
00035 SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin)
00036 {
00037   _receivePin = receivePin;
00038   _transmitPin = transmitPin;
00039   _baudRate = 0;
00040 }
00041 
00042 /******************************************************************************
00043  * User API
00044  ******************************************************************************/
00045 
00046 void SoftwareSerial::begin(long speed)
00047 {
00048   _baudRate = speed;
00049   _bitPeriod = 1000000 / _baudRate;
00050 
00051   digitalWrite(_transmitPin, HIGH);
00052   delayMicroseconds( _bitPeriod); // if we were low this establishes the end
00053 }
00054 
00055 int SoftwareSerial::read()
00056 {
00057   int val = 0;
00058   int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50);
00059   
00060   // one byte of serial data (LSB first)
00061   // ...--\    /--\/--\/--\/--\/--\/--\/--\/--\/--...
00062   //     \--/\--/\--/\--/\--/\--/\--/\--/\--/
00063   //    start  0   1   2   3   4   5   6   7 stop
00064 
00065   while (digitalRead(_receivePin));
00066 
00067   // confirm that this is a real start bit, not line noise
00068   if (digitalRead(_receivePin) == LOW) {
00069     // frame start indicated by a falling edge and low start bit
00070     // jump to the middle of the low start bit
00071     delayMicroseconds(bitDelay / 2 - clockCyclesToMicroseconds(50));
00072         
00073     // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
00074     for (int offset = 0; offset < 8; offset++) {
00075         // jump to middle of next bit
00076         delayMicroseconds(bitDelay);
00077         
00078         // read bit
00079         val |= digitalRead(_receivePin) << offset;
00080     }
00081         
00082     delayMicroseconds(_bitPeriod);
00083     
00084     return val;
00085   }
00086   
00087   return -1;
00088 }
00089 
00090 void SoftwareSerial::print(uint8_t b)
00091 {
00092   if (_baudRate == 0)
00093     return;
00094     
00095   int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
00096   byte mask;
00097 
00098   digitalWrite(_transmitPin, LOW);
00099   delayMicroseconds(bitDelay);
00100 
00101   for (mask = 0x01; mask; mask <<= 1) {
00102     if (b & mask){ // choose bit
00103       digitalWrite(_transmitPin,HIGH); // send 1
00104     }
00105     else{
00106       digitalWrite(_transmitPin,LOW); // send 1
00107     }
00108     delayMicroseconds(bitDelay);
00109   }
00110 
00111   digitalWrite(_transmitPin, HIGH);
00112   delayMicroseconds(bitDelay);
00113 }
00114 
00115 void SoftwareSerial::print(const char *s)
00116 {
00117   while (*s)
00118     print(*s++);
00119 }
00120 
00121 void SoftwareSerial::print(char c)
00122 {
00123   print((uint8_t) c);
00124 }
00125 
00126 void SoftwareSerial::print(int n)
00127 {
00128   print((long) n);
00129 }
00130 
00131 void SoftwareSerial::print(unsigned int n)
00132 {
00133   print((unsigned long) n);
00134 }
00135 
00136 void SoftwareSerial::print(long n)
00137 {
00138   if (n < 0) {
00139     print('-');
00140     n = -n;
00141   }
00142   printNumber(n, 10);
00143 }
00144 
00145 void SoftwareSerial::print(unsigned long n)
00146 {
00147   printNumber(n, 10);
00148 }
00149 
00150 void SoftwareSerial::print(long n, int base)
00151 {
00152   if (base == 0)
00153     print((char) n);
00154   else if (base == 10)
00155     print(n);
00156   else
00157     printNumber(n, base);
00158 }
00159 
00160 void SoftwareSerial::println(void)
00161 {
00162   print('\r');
00163   print('\n');  
00164 }
00165 
00166 void SoftwareSerial::println(char c)
00167 {
00168   print(c);
00169   println();  
00170 }
00171 
00172 void SoftwareSerial::println(const char c[])
00173 {
00174   print(c);
00175   println();
00176 }
00177 
00178 void SoftwareSerial::println(uint8_t b)
00179 {
00180   print(b);
00181   println();
00182 }
00183 
00184 void SoftwareSerial::println(int n)
00185 {
00186   print(n);
00187   println();
00188 }
00189 
00190 void SoftwareSerial::println(long n)
00191 {
00192   print(n);
00193   println();  
00194 }
00195 
00196 void SoftwareSerial::println(unsigned long n)
00197 {
00198   print(n);
00199   println();  
00200 }
00201 
00202 void SoftwareSerial::println(long n, int base)
00203 {
00204   print(n, base);
00205   println();
00206 }
00207 
00208 // Private Methods /////////////////////////////////////////////////////////////
00209 
00210 void SoftwareSerial::printNumber(unsigned long n, uint8_t base)
00211 {
00212   unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. 
00213   unsigned long i = 0;
00214 
00215   if (n == 0) {
00216     print('0');
00217     return;
00218   } 
00219 
00220   while (n > 0) {
00221     buf[i++] = n % base;
00222     n /= base;
00223   }
00224 
00225   for (; i > 0; i--)
00226     print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
00227 }