Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Thu Jul 14 2022 20:23:26 by
1.7.2