DJI_HardDriver_Manifold.h
Go to the documentation of this file.
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             uint8_t buf[BUFFER_SIZE];
00073             usleep(5000);
00074 
00076             if(_serialRead(buf, BUFFER_SIZE) > 0)
00077             {
00078               API_LOG(this, STATUS_LOG, "Succeeded to read from serial device\n");
00079               deviceStatus = true;
00080               return;
00081             }
00082             API_LOG(this, ERROR_LOG, "Failed to read from serial device\n");
00083             deviceStatus = false;
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   //Use clock_gettime instead of getttimeofday for compatibility with POSIX APIs
00171   clock_gettime(CLOCK_REALTIME, &curTime);
00172   //absTimeout = curTime;
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         // Message synchronization data
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             // notice: use O_NONBLOCK to raise the frequency that read data from buffer
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             /* save current port parameter */
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             /* config the size of char */
00258             newtio.c_cflag |= CLOCAL | CREAD;
00259             newtio.c_cflag &= ~CSIZE;
00260 
00261             /* config data bit */
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             /* config the parity bit */
00271             switch (parity_bits) {
00272                 /* odd */
00273             case 'O':
00274             case 'o':
00275                 newtio.c_cflag |= PARENB;
00276                 newtio.c_cflag |= PARODD;
00277                 break;
00278                 /* even */
00279             case 'E':
00280             case 'e':
00281                 newtio.c_cflag |= PARENB;
00282                 newtio.c_cflag &= ~PARODD;
00283                 break;
00284                 /* none */
00285             case 'N':
00286             case 'n':
00287                 newtio.c_cflag &= ~PARENB;
00288                 break;
00289             }
00290             /* config baudrate */
00291             j = sizeof(std_rate) / 4;
00292             for(i = 0; i < j; ++i) {
00293                 if(std_rate[i] == baudrate) {
00294                     /* set standard baudrate */
00295                     cfsetispeed(&newtio, st_baud[i]);
00296                     cfsetospeed(&newtio, st_baud[i]);
00297                     break;
00298                 }
00299             }
00300             /* config stop bit */
00301             if( stop_bits == 1 )
00302                 newtio.c_cflag &=  ~CSTOPB;
00303             else if ( stop_bits == 2 )
00304                 newtio.c_cflag |=  CSTOPB;
00305 
00306             /* config waiting time & min number of char */
00307             newtio.c_cc[VTIME]  = 1;
00308             newtio.c_cc[VMIN] = 1;
00309 
00310             /* using the raw data mode */
00311             newtio.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);
00312             newtio.c_oflag  &= ~OPOST;
00313 
00314             /* flush the hardware fifo */
00315             tcflush(m_serial_fd,TCIFLUSH);
00316 
00317             /* activite the configuration */
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


dji_sdk
Author(s): Botao Hu
autogenerated on Thu Jun 6 2019 17:55:29