Руслан Бредун / Mbed 2 deprecated stm32-sensor-base2

Dependencies:   mbed Watchdog

Dependents:   STM32-MC_node

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RS485.cpp Source File

RS485.cpp

00001 #include "RS485.h"
00002 #include <stdarg.h>
00003  
00004 typedef unsigned int word;
00005 typedef uint8_t byte;
00006 typedef uint8_t boolean;
00007 typedef void (*voidFuncPtr)(void);
00008 Timer lapse;
00009     const byte STX = '\4';
00010     const byte ETX = '\8';
00011  
00012 RS485::RS485(PinName tx, PinName rx, PinName dere)
00013     : BufferedSerial(tx, rx )
00014 {
00015     return;
00016 }
00017     
00018  
00019 byte RS485::crc8(const byte *addr, byte len)
00020 {
00021   byte crc = 0;
00022   while (len--)
00023     {
00024     byte inbyte = *addr++;
00025     for (byte i = 8; i; i--)
00026       {
00027       byte mix = (crc ^ inbyte) & 0x01;
00028       crc >>= 1;
00029       if (mix)
00030         crc ^= 0x8C;
00031       inbyte >>= 1;
00032       }  // end of for
00033     }  // end of while
00034   return crc;
00035 }  // end of crc8
00036  
00037 void RS485::sendComplemented( const byte what)
00038 {
00039   byte c ;
00040   // first nibble
00041   c = what >> 4;
00042   putc((c << 4) | (c ^ 0x0F));
00043  
00044   // second nibble
00045   c = what & 0x0F;
00046   putc((c << 4) | (c ^ 0x0F));
00047 }  // end of sendComplemented
00048  
00049  
00050 void RS485::sendMsg(const byte * data, const byte length)
00051 {
00052   putc(STX);  // STX
00053   for (byte i = 0; i < length; i++)
00054     //sendComplemented (data[i]);
00055     putc(data[i]);
00056   //putc(ETX);  // ETX
00057   //sendComplemented(crc8(data, length));
00058   putc(crc8(data, length));
00059 }  // end of sendMsg
00060  
00061 // receive a message, maximum "length" bytes, timeout after "timeout" clock_mseconds
00062 // if nothing received, or an error (eg. bad CRC, bad data) return 0
00063 // otherwise, returns length of received data
00064 byte RS485::recvMsg (byte * data,                    // buffer to receive into
00065               const byte length,              // maximum buffer size
00066               unsigned long timeout)          // clock_mseconds before timing out
00067   {
00068  
00069   unsigned long start_time = lapse.read_ms();
00070  
00071   bool have_stx = false;
00072  
00073   // variables below are set when we get an STX
00074   bool have_etx;
00075   byte input_pos;
00076   bool first_nibble;
00077   byte current_byte;
00078  
00079   while (lapse.read_ms() - start_time < timeout)
00080     {
00081     if (readable() > 0)
00082       {
00083       byte inByte = getc();
00084  
00085       switch (inByte)
00086         {
00087  
00088         case STX:   // start of text
00089           have_stx = true;
00090           have_etx = false;
00091           input_pos = 0;
00092           first_nibble = true;
00093           start_time = lapse.read_ms();  // reset timeout period
00094           data[0] = STX;
00095           break;
00096  
00097         default:
00098           // wait until packet officially starts
00099           if (!have_stx)
00100             break;
00101  
00102           // check byte is in valid form (4 bits followed by 4 bits complemented)
00103           if ((inByte >> 4) != ((inByte & 0x0F) ^ 0x0F) )
00104             return 0;  // bad character
00105  
00106           // convert back
00107           inByte >>= 4;
00108  
00109           // high-order nibble?
00110           if (first_nibble)
00111             {
00112             current_byte = inByte;
00113             first_nibble = false;
00114             break;
00115             }  // end of first nibble
00116  
00117           // low-order nibble
00118           current_byte <<= 4;
00119           current_byte |= inByte;
00120           first_nibble = true;
00121  
00122           // if we have the ETX this must be the CRC
00123           if (have_etx)
00124             {
00125             if (crc8 (data, input_pos) != current_byte)
00126               return 0;  // bad crc
00127             return input_pos;  // return received length
00128             }  // end if have ETX already
00129  
00130           // keep adding if not full
00131           if (input_pos < length)
00132             data [input_pos++] = current_byte;
00133           else
00134             return 0;  // overflow
00135           break;
00136  
00137         }  // end of switch
00138       }  // end of incoming data
00139     } // end of while not timed out
00140  
00141   return 0;  // timeout
00142 } // end of recvMsg
00143