00001
00013 #ifndef __DJI_HARDDRIVER_MANIFOLD_H__
00014 #define __DJI_HARDDRIVER_MANIFOLD_H__
00015
00016
00017 #include <stdio.h>
00018 #include <string>
00019 #include <string.h>
00020 #include <unistd.h>
00021 #include <sys/ioctl.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <pthread.h>
00025 #include <fcntl.h>
00026 #include <termios.h>
00027 #include <sys/time.h>
00028 #include <dji_sdk_lib/DJI_Type.h>
00029 #include <dji_sdk_lib/DJI_HardDriver.h>
00030
00031 #define BUFFER_SIZE 1024
00032
00033 namespace DJI {
00034
00035 namespace onboardSDK {
00036
00037 class HardDriver_Manifold : public HardDriver {
00038
00039 public:
00040 HardDriver_Manifold(std::string device, unsigned int baudrate) {
00041 m_device = device;
00042 m_baudrate = baudrate;
00043 m_memLock = PTHREAD_MUTEX_INITIALIZER;
00044 m_msgLock = PTHREAD_MUTEX_INITIALIZER;
00045 m_ackLock = PTHREAD_MUTEX_INITIALIZER;
00046 pthread_cond_init (&ack_recv_cv, NULL);
00047 }
00048
00049
00050 ~HardDriver_Manifold() {
00051 _serialClose();
00052 pthread_mutex_destroy(&m_memLock);
00053 pthread_mutex_destroy(&m_msgLock);
00054 pthread_mutex_destroy(&m_ackLock);
00055 pthread_cond_destroy(&ack_recv_cv);
00056 }
00057
00058
00059 void init()
00060 {
00061 API_LOG(this, STATUS_LOG, "Open serial device %s with baudrate %u...\n",
00062 m_device.c_str(), m_baudrate);
00063 if( _serialStart(m_device.c_str(), m_baudrate) < 0 )
00064 {
00065 _serialClose();
00066 API_LOG(this, ERROR_LOG, "Failed to start serial device\n");
00067 deviceStatus = false;
00068 }
00069
00070 deviceStatus = true;
00071
00072
00073
00074
00076
00077
00078
00079
00080
00081
00082
00083
00084 }
00085
00086
00090 void usbHandshake(std::string device) {
00091 _serialStart(device.c_str(), 38400);
00092 _serialStart(device.c_str(), 19200);
00093 _serialStart(device.c_str(), 38400);
00094 _serialStart(device.c_str(), 19200);
00095 }
00096
00097
00098 void setBaudrate(unsigned int baudrate) {
00099 m_baudrate = baudrate;
00100 }
00101
00102
00103 void setDevice(std::string device) {
00104 m_device = device;
00105 }
00106
00107
00108 bool getDevieStatus()
00109 {
00110 return deviceStatus;
00111 }
00112
00113 time_ms getTimeStamp() {
00114 #ifdef __MACH__
00115 struct timeval now;
00116 gettimeofday(&now, NULL);
00117 return (uint64_t)now.tv_sec * 1000 + (uint64_t) (now.tv_usec / 1.0e3);
00118 #else
00119 struct timespec time;
00120 clock_gettime(CLOCK_REALTIME, &time);
00121 return (uint64_t)time.tv_sec * 1000 + (uint64_t)(time.tv_nsec / 1.0e6);
00122 #endif
00123 }
00124
00125
00126 size_t send(const uint8_t *buf, size_t len) {
00127 return _serialWrite(buf, len);
00128 }
00129
00130
00131 size_t readall(uint8_t *buf, size_t maxlen) {
00132 return _serialRead(buf, maxlen);
00133 }
00134
00135
00136 void lockMemory() {
00137 pthread_mutex_lock(&m_memLock);
00138 }
00139
00140
00141 void freeMemory() {
00142 pthread_mutex_unlock(&m_memLock);
00143 }
00144
00145
00146 void lockMSG() {
00147 pthread_mutex_lock(&m_msgLock);
00148 }
00149
00150
00151 void freeMSG() {
00152 pthread_mutex_unlock(&m_msgLock);
00153 }
00154
00155 void lockACK() {
00156 pthread_mutex_lock(&m_ackLock);
00157 }
00158
00159
00160 void freeACK() {
00161 pthread_mutex_unlock(&m_ackLock);
00162 }
00163
00164 void notify() {
00165 pthread_cond_signal(&ack_recv_cv);
00166 }
00167
00168 void wait(int timeoutInSeconds){
00169 struct timespec curTime, absTimeout;
00170
00171 clock_gettime(CLOCK_REALTIME, &curTime);
00172
00173 absTimeout.tv_sec = curTime.tv_sec + timeoutInSeconds;
00174 absTimeout.tv_nsec = curTime.tv_nsec;
00175 pthread_cond_timedwait(&ack_recv_cv, &m_ackLock, &absTimeout);
00176 }
00177
00178 private:
00179 std::string m_device;
00180 unsigned int m_baudrate;
00181 pthread_mutex_t m_memLock;
00182
00183
00184 pthread_mutex_t m_ackLock;
00185 pthread_mutex_t m_msgLock;
00186 pthread_cond_t ack_recv_cv;
00187
00188 int m_serial_fd;
00189 fd_set m_serial_fd_set;
00190
00191 bool deviceStatus;
00192
00193
00194 bool _serialOpen(const char* dev) {
00195
00196 m_serial_fd = open(dev, O_RDWR | O_NONBLOCK);
00197 if(m_serial_fd < 0) {
00198 API_LOG(this, ERROR_LOG, "Failed to open serial device %s\n", dev);
00199 return false;
00200 }
00201 return true;
00202 }
00203
00204
00205 bool _serialClose() {
00206 close(m_serial_fd);
00207 m_serial_fd = -1;
00208 return true;
00209 }
00210
00211
00212 bool _serialFlush() {
00213 if(m_serial_fd < 0) {
00214 API_LOG(this, ERROR_LOG, "flushing fail because no device is opened\n");
00215 return false;
00216 } else {
00217 tcflush(m_serial_fd, TCIFLUSH);
00218 return true;
00219 }
00220 }
00221
00222
00223 bool _serialConfig(int baudrate, char data_bits, char parity_bits, char stop_bits) {
00224 int st_baud[] = {
00225 B4800,
00226 B9600,
00227 B19200,
00228 B38400,
00229 B57600,
00230 B115200,
00231 B230400,
00232 B921600
00233 };
00234 int std_rate[] = {
00235 4800,
00236 9600,
00237 19200,
00238 38400,
00239 57600,
00240 115200,
00241 230400,
00242 921600,
00243 1000000,
00244 1152000,
00245 3000000,
00246 };
00247
00248 int i,j;
00249 struct termios newtio, oldtio;
00250
00251 if (tcgetattr(m_serial_fd, &oldtio) != 0) {
00252 API_LOG(this, ERROR_LOG, "fail to save current port\n");
00253 return false;
00254 }
00255 memset(&newtio, 0, sizeof(newtio));
00256
00257
00258 newtio.c_cflag |= CLOCAL | CREAD;
00259 newtio.c_cflag &= ~CSIZE;
00260
00261
00262 switch (data_bits) {
00263 case 7:
00264 newtio.c_cflag |= CS7;
00265 break;
00266 case 8:
00267 newtio.c_cflag |= CS8;
00268 break;
00269 }
00270
00271 switch (parity_bits) {
00272
00273 case 'O':
00274 case 'o':
00275 newtio.c_cflag |= PARENB;
00276 newtio.c_cflag |= PARODD;
00277 break;
00278
00279 case 'E':
00280 case 'e':
00281 newtio.c_cflag |= PARENB;
00282 newtio.c_cflag &= ~PARODD;
00283 break;
00284
00285 case 'N':
00286 case 'n':
00287 newtio.c_cflag &= ~PARENB;
00288 break;
00289 }
00290
00291 j = sizeof(std_rate) / 4;
00292 for(i = 0; i < j; ++i) {
00293 if(std_rate[i] == baudrate) {
00294
00295 cfsetispeed(&newtio, st_baud[i]);
00296 cfsetospeed(&newtio, st_baud[i]);
00297 break;
00298 }
00299 }
00300
00301 if( stop_bits == 1 )
00302 newtio.c_cflag &= ~CSTOPB;
00303 else if ( stop_bits == 2 )
00304 newtio.c_cflag |= CSTOPB;
00305
00306
00307 newtio.c_cc[VTIME] = 1;
00308 newtio.c_cc[VMIN] = 1;
00309
00310
00311 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
00312 newtio.c_oflag &= ~OPOST;
00313
00314
00315 tcflush(m_serial_fd,TCIFLUSH);
00316
00317
00318 if((tcsetattr(m_serial_fd,TCSANOW,&newtio))!=0) {
00319 API_LOG(this, ERROR_LOG, "fail to active configuration\n");
00320 return false;
00321 }
00322 return true;
00323 }
00324
00325
00326 int _serialStart(const char *dev_name, int baud_rate) {
00327 const char *ptemp;
00328 if(dev_name == NULL) {
00329 ptemp = "/dev/ttyUSB0";
00330 } else {
00331 ptemp = dev_name;
00332 }
00333 if(true == _serialOpen(ptemp)
00334 && true == _serialConfig(baud_rate,8,'N',1)) {
00335
00336 FD_ZERO(&m_serial_fd_set);
00337 FD_SET(m_serial_fd, &m_serial_fd_set);
00338 return m_serial_fd;
00339
00340 }
00341 return -1;
00342 }
00343
00344
00345 int _serialWrite(const unsigned char *buf, int len) {
00346 return write(m_serial_fd, buf, len);
00347 }
00348
00349
00350 int _serialRead(unsigned char *buf, int len) {
00351 int saved = 0;
00352 int ret = -1;
00353
00354 if(NULL == buf) {
00355 return -1;
00356 } else {
00357 for(; saved < len ;) {
00358 ret = read(m_serial_fd,buf + saved,len - saved);
00359 if(ret > 0)
00360 saved += ret;
00361 else
00362 break;
00363 }
00364 return saved;
00365 }
00366 }
00367
00368
00369 };
00370
00371 }
00372
00373 }
00374
00375
00376 #endif