LoSerial.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "Robots/LoBot/io/LoSerial.H"
00046 #include "Robots/LoBot/misc/LoExcept.H"
00047
00048
00049 #include <errno.h>
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 namespace lobot {
00062
00063
00064
00065 #ifdef HAVE_LIBSERIAL
00066
00067
00068
00069 static SerialPort::BaudRate baud_rate_enum(int baud_rate)
00070 {
00071 if (baud_rate < 63)
00072 return SerialPort::BAUD_50 ;
00073 if (baud_rate < 93)
00074 return SerialPort::BAUD_75 ;
00075 if (baud_rate < 122)
00076 return SerialPort::BAUD_110 ;
00077 if (baud_rate < 142)
00078 return SerialPort::BAUD_134 ;
00079 if (baud_rate < 175)
00080 return SerialPort::BAUD_150 ;
00081 if (baud_rate < 250)
00082 return SerialPort::BAUD_200 ;
00083 if (baud_rate < 450)
00084 return SerialPort::BAUD_300 ;
00085 if (baud_rate < 900)
00086 return SerialPort::BAUD_600 ;
00087 if (baud_rate < 1500)
00088 return SerialPort::BAUD_1200 ;
00089 if (baud_rate < 2100)
00090 return SerialPort::BAUD_1800 ;
00091 if (baud_rate < 3600)
00092 return SerialPort::BAUD_2400 ;
00093 if (baud_rate < 7200)
00094 return SerialPort::BAUD_4800 ;
00095 if (baud_rate < 14400)
00096 return SerialPort::BAUD_9600 ;
00097 if (baud_rate < 28800)
00098 return SerialPort::BAUD_19200 ;
00099 if (baud_rate < 48000)
00100 return SerialPort::BAUD_38400 ;
00101 if (baud_rate < 86400)
00102 return SerialPort::BAUD_57600 ;
00103 if (baud_rate < 172800)
00104 return SerialPort::BAUD_115200 ;
00105 return SerialPort::BAUD_230400 ;
00106 }
00107
00108
00109 Serial::Serial(const ModelManager&, const std::string& device, int baud_rate)
00110 : m_serial(device)
00111 {
00112 #ifdef LOBOT_SERIAL_DEVMODE
00113 ;
00114 #else
00115 try
00116 {
00117 m_serial.Open(baud_rate_enum(baud_rate)) ;
00118 }
00119 catch (std::exception&)
00120 {
00121 throw io_error(SERIAL_PORT_INIT_ERROR) ;
00122 }
00123 #endif
00124 }
00125
00126
00127 bool Serial::ready()
00128 {
00129 return m_serial.IsDataAvailable() ;
00130 }
00131
00132
00133 int Serial::read(char buf[], int n)
00134 {
00135 int i = 0 ;
00136 try
00137 {
00138 for (; i < n; ++i)
00139 buf[i] = m_serial.ReadByte() ;
00140 }
00141 catch (std::exception&)
00142 {
00143 }
00144 return i ;
00145 }
00146
00147
00148 void Serial::write(char buf[], int n)
00149 {
00150 try
00151 {
00152 for (int i = 0; i < n; ++i)
00153 m_serial.WriteByte(buf[i]) ;
00154 }
00155 catch (std::exception&)
00156 {
00157 throw io_error(SERIAL_PORT_WRITE_ERROR) ;
00158 }
00159 }
00160
00161 #else // don't HAVE_LIBSERIAL ==> fall back to INVT serial port support
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 Serial::
00175 Serial(const ModelManager& mgr, const std::string& device, int baud_rate)
00176 : m_serial(new ::Serial(const_cast<ModelManager&>(mgr),
00177 "LobotSerialPort", "LobotSerialPort")),
00178 m_peek_flag(false), m_peek_char(0)
00179 {
00180 #ifdef LOBOT_SERIAL_DEVMODE
00181 ;
00182 #else
00183 ModelManager& M = const_cast<ModelManager&>(mgr) ;
00184
00185 bool i_stopped_the_model_manager = false ;
00186 if (M.started()) {
00187 M.stop() ;
00188 i_stopped_the_model_manager = true ;
00189 }
00190
00191 M.addSubComponent(m_serial) ;
00192 m_serial->configure(device.c_str(), baud_rate, "8N1", false, false, 0) ;
00193
00194 M.exportOptions(MC_RECURSE) ;
00195 if (i_stopped_the_model_manager)
00196 M.start() ;
00197 #endif
00198 }
00199
00200
00201 bool Serial::ready()
00202 {
00203 if (m_peek_flag)
00204 return true ;
00205
00206 m_serial->setBlocking(false) ;
00207
00208 bool is_ready = false ;
00209 switch (m_serial->read(& m_peek_char, 1))
00210 {
00211 case -1:
00212 if (errno == EAGAIN)
00213 is_ready = false ;
00214 else
00215 throw io_error(SERIAL_PORT_READ_ERROR) ;
00216 break ;
00217
00218 case 0:
00219
00220 is_ready = false ;
00221 break ;
00222
00223 case 1:
00224 if (m_peek_char != '\0') {
00225 is_ready = true ;
00226 m_peek_flag = true ;
00227 }
00228 break ;
00229
00230 default:
00231 errno = 0 ;
00232 throw io_error(SERIAL_PORT_READ_ERROR) ;
00233 break ;
00234 }
00235
00236 m_serial->setBlocking(true) ;
00237 return is_ready ;
00238 }
00239
00240
00241 int Serial::read(char buf[], int n)
00242 {
00243 if (n <= 0)
00244 throw io_error(SERIAL_PORT_BAD_ARG) ;
00245
00246 if (m_peek_flag) {
00247 buf[0] = m_peek_char ;
00248 m_peek_flag = false ;
00249 m_peek_char = 0 ;
00250 return 1 + m_serial->read(buf + 1, n - 1) ;
00251 }
00252 return m_serial->read(buf, n) ;
00253 }
00254
00255
00256 void Serial::write(char buf[], int n)
00257 {
00258 if (n <= 0)
00259 throw io_error(SERIAL_PORT_BAD_ARG) ;
00260 m_serial->write(buf, n) ;
00261 }
00262
00263 #endif // HAVE_LIBSERIAL
00264
00265
00266
00267
00268
00269 void Serial::read_full(char buf[], int n)
00270 {
00271 for (int m = n; m > 0;)
00272 m -= read(buf + n - m, m) ;
00273 }
00274
00275
00276 void Serial::eat(int n)
00277 {
00278 char buf[n] ;
00279 read_full(buf, n) ;
00280 }
00281
00282
00283 Serial::~Serial(){}
00284
00285
00286
00287 }
00288
00289
00290
00291
00292