enhering

Untitled

Sep 9th, 2017
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.04 KB | None | 0 0
  1.  
  2. #include "Serial.h"
  3.  
  4. // see http://linux.die.net/man/3/termios for more info.
  5.  
  6. Serial::Serial() {
  7.   m_strSerialPortDevice = "/dev/cua0";
  8.  
  9.   m_nDataBits     = 8;
  10.   m_nSerialParity = 0;
  11.   m_nStopBits     = 1;
  12.   m_nBaudRate     = 9600;
  13.   m_eFlowControl  = FLOW_CONTROL_XONXOFF;
  14.  
  15.   m_bSimulationMode = false;
  16. }
  17.  
  18. Serial::~Serial() {
  19.   close(m_nFD);
  20. }
  21.  
  22. void Serial::SetSerialPortDevice(std::string strSerialPortDevice) {
  23.   m_strSerialPortDevice = strSerialPortDevice;
  24. }
  25.  
  26. void Serial::SetStopBits(int nStopBits) {
  27.   m_nStopBits = nStopBits;
  28. }
  29.  
  30. void Serial::SetParity(int nSerialParity) {
  31.   m_nSerialParity = nSerialParity;
  32. }
  33.  
  34. void Serial::SetDataBits(int nDataBits) {
  35.   m_nDataBits = nDataBits;
  36. }
  37.  
  38. void Serial::SetBaudRate(long nBaudRate) {
  39.   m_nBaudRate = nBaudRate;
  40. }
  41.  
  42. void Serial::SetXONXOFFFlowControl() {
  43.   m_eFlowControl = FLOW_CONTROL_XONXOFF;
  44. }
  45.  
  46. void Serial::SetCTSRTSFlowControl() {
  47.   m_eFlowControl = FLOW_CONTROL_CTSRTS;
  48. }
  49.  
  50. void Serial::SetNoFlowControl() {
  51.   m_eFlowControl = FLOW_CONTROL_NONE;
  52. }
  53.  
  54. bool Serial::OpenSerialPort() {
  55.  
  56.   // From http://www.easysw.com/~mike/serial/serial.html
  57.   struct termios options;
  58.   struct sigaction saio;           /* definition of signal action */
  59.  
  60.  
  61.   m_nFD = open(m_strSerialPortDevice.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
  62.  
  63.   if (m_nFD == -1) {
  64.     perror("open_port: Unable to open serial port.");
  65.     m_pcLogger->Log(logERROR, "open_port: Unable to open serial port.");
  66.     m_pcLogger->Log(logERROR, m_strSerialPortDevice.c_str());
  67.     exit(0);
  68.   }
  69.   else {
  70.  
  71.     /* install the signal handler before making the device asynchronous */
  72.     saio.sa_handler = m_pSignalHandlerCallback;
  73.     sigemptyset(&saio.sa_mask);
  74.     saio.sa_flags = SA_RESTART;
  75.     // saio.sa_restorer = NULL;
  76.     sigaction(SIGIO, &saio, NULL);
  77.  
  78.  
  79.     /* allow the process to receive SIGIO */
  80.     fcntl(m_nFD, F_SETOWN, getpid());
  81.  
  82.     /* Make the file descriptor asynchronous (the manual page says only
  83.        O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
  84.     fcntl(m_nFD, F_SETFL, O_ASYNC|O_NONBLOCK|fcntl(m_nFD, F_GETFL));
  85.  
  86.    
  87.     m_pcLogger->Log(logINFO, "Serial port opened successfully");
  88.     return(1);
  89.   }
  90. }
  91.  
  92. bool Serial::SetupSerialPort() {
  93.  
  94.   struct termios options;
  95.  
  96.   /* get the current options */
  97.   if (tcgetattr(m_nFD, &options) < 0) {
  98.     perror("SetupSerialPort: Couldn't get term attributes");
  99.     m_pcLogger->Log(logERROR, "SetupSerialPort: Couldn't get term attributes");
  100.     return 0;
  101.   }
  102.  
  103.   //stty -F /dev/ttyUSB0 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
  104.  
  105.   switch(m_nDataBits) {
  106.     case 5:
  107.       options.c_cflag |= CS5;
  108.       break;
  109.     case 6:
  110.       options.c_cflag |= CS6;
  111.       break;
  112.     case 7:
  113.       options.c_cflag |= CS7;
  114.       break;
  115.     case 8:
  116.     default:
  117.       options.c_cflag |= CS8;
  118.   }
  119.  
  120.   switch (m_nSerialParity) {
  121.     case 2:
  122.       options.c_cflag |= PARENB;
  123.       options.c_cflag &= ~PARODD;
  124.       break;
  125.     case 1:
  126.       options.c_cflag |= PARENB;
  127.       options.c_cflag |= PARODD;
  128.       break;
  129.     case 0:
  130.       options.c_cflag &= ~PARENB;
  131.  
  132.     default:
  133.       options.c_cflag &= ~PARENB;
  134.   }
  135.  
  136.   switch (m_nStopBits) {
  137.     case 2:
  138.       options.c_cflag |= CSTOPB;
  139.       break;
  140.     case 1:
  141.     default:
  142.       options.c_cflag &= ~CSTOPB;
  143.  
  144.   }
  145.  
  146.   options.c_cflag &= ~CSIZE;
  147.  
  148.   options.c_cflag |= CREAD;
  149.   options.c_cflag |= CLOCAL;  // turn on READ & ignore ctrl lines
  150.  
  151.   switch (m_nBaudRate) {
  152.     case 0:
  153.       cfsetispeed(&options, B0);
  154.       cfsetospeed(&options, B0);
  155.       break;
  156.     case 50:
  157.       cfsetispeed(&options, B50);
  158.       cfsetospeed(&options, B50);
  159.       break;
  160.     case 75:
  161.       cfsetispeed(&options, B75);
  162.       cfsetospeed(&options, B75);
  163.       break;
  164.     case 110:
  165.       cfsetispeed(&options, B110);
  166.       cfsetospeed(&options, B110);
  167.       break;
  168.     case 134:
  169.       cfsetispeed(&options, B134);
  170.       cfsetospeed(&options, B134);
  171.       break;
  172.     case 150:
  173.       cfsetispeed(&options, B150);
  174.       cfsetospeed(&options, B150);
  175.       break;
  176.     case 200:
  177.       cfsetispeed(&options, B200);
  178.       cfsetospeed(&options, B200);
  179.       break;
  180.     case 300:
  181.       cfsetispeed(&options, B300);
  182.       cfsetospeed(&options, B300);
  183.       break;
  184.     case 600:
  185.       cfsetispeed(&options, B600);
  186.       cfsetospeed(&options, B600);
  187.       break;
  188.     case 1200:
  189.       cfsetispeed(&options, B1200);
  190.       cfsetospeed(&options, B1200);
  191.       break;
  192.     case 1800:
  193.       cfsetispeed(&options, B1800);
  194.       cfsetospeed(&options, B1800);
  195.       break;
  196.     case 2400:
  197.       cfsetispeed(&options, B2400);
  198.       cfsetospeed(&options, B2400);
  199.       break;
  200.     case 4800:
  201.       cfsetispeed(&options, B4800);
  202.       cfsetospeed(&options, B4800);
  203.       break;
  204.     case 9600:
  205.       cfsetispeed(&options, B9600);
  206.       cfsetospeed(&options, B9600);
  207.       break;
  208.     case 19200:
  209.       cfsetispeed(&options, B19200);
  210.       cfsetospeed(&options, B19200);
  211.       break;
  212.     case 38400:
  213.       cfsetispeed(&options, B38400);
  214.       cfsetospeed(&options, B38400);
  215.       break;
  216.     case 57600:
  217.       cfsetispeed(&options, B57600);
  218.       cfsetospeed(&options, B57600);
  219.       break;
  220.     case 115200:
  221.       cfsetispeed(&options, B115200);
  222.       cfsetospeed(&options, B115200);
  223.       break;
  224.     case 230400:
  225.       cfsetispeed(&options, B230400);
  226.       cfsetospeed(&options, B230400);
  227.       break;
  228.     default:
  229.       cfsetispeed(&options, B115200);
  230.       cfsetospeed(&options, B115200);
  231.       break;    
  232.   }
  233.  
  234.   options.c_iflag |= IGNBRK;
  235.   options.c_iflag &= ~BRKINT;
  236.   options.c_iflag &= ~ICRNL;
  237.   options.c_iflag &= ~IMAXBEL;
  238.   options.c_iflag &= ~IXANY;
  239.  
  240.   switch (m_eFlowControl) {
  241.     case FLOW_CONTROL_XONXOFF:
  242.       options.c_iflag |= IXON;
  243.       options.c_iflag |= IXOFF;
  244.       options.c_iflag &= ~CRTSCTS;
  245.       break;
  246.     case FLOW_CONTROL_CTSRTS:
  247.       options.c_iflag &= ~IXON;
  248.       options.c_iflag &= ~IXOFF;
  249.       options.c_iflag |= CRTSCTS;
  250.       break;
  251.     case FLOW_CONTROL_NONE:
  252.     default:
  253.       options.c_iflag &= ~IXON;
  254.       options.c_iflag &= ~IXOFF;
  255.       options.c_iflag &= ~CRTSCTS;
  256.       break;
  257.   }
  258.  
  259.   options.c_oflag &= ~OPOST;
  260.   options.c_oflag &= ~ONLCR;
  261.  
  262.   options.c_lflag &= ~ISIG;
  263.   options.c_lflag &= ~ICANON;
  264.   //options.c_lflag &= ~IEXTEN;
  265.   options.c_lflag &= ~ECHO;
  266.   options.c_lflag &= ~ECHOE;
  267.   // options.c_lflag &= ~ECHOK;
  268.   // options.c_lflag &= ~ECHOCTL;
  269.   // options.c_lflag &= ~ECHOKE;
  270.   //options.c_lflag |= NOFLSH;
  271.  
  272.   // see: http://unixwiz.net/techtips/termios-vmin-vtime.html
  273.   options.c_cc[VMIN]  = 0;
  274.   options.c_cc[VTIME] = 20;
  275.  
  276.   /* set the options */
  277.   if( tcsetattr(m_nFD, TCSANOW, &options) < 0) {
  278.     perror("init_serialport: Couldn't set term attributes");
  279.     m_pcLogger->Log(logERROR, "SetupSerialPort: Couldn't set term attributes");
  280.     return 0;
  281.   }
  282.  
  283.   m_pcLogger->Log(logINFO, "Serial port configured successfully.");
  284.   return(1);
  285. }
  286.  
  287. int Serial::SerialPortWriteByte(uint8_t nByte) {
  288.  
  289.   if (! m_bSimulationMode) {
  290.     int nLength = 1;
  291.     int n = write(m_nFD, &nByte, nLength);
  292.  
  293.     if ( n != nLength) {
  294.       m_strLogMessage = "Error sending byte" ;
  295.       m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  296.       exit(EXIT_FAILURE);
  297.     }
  298.   }
  299.   m_strLogMessage = "Sent byte";
  300.   m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  301.   return 0;
  302. }
  303.  
  304. int Serial::SerialPortWrite(const std::string strIn) {
  305.   std::string strMessage = strIn;
  306.  
  307.   if (! m_bSimulationMode) {
  308.     int nLength = strMessage.length();
  309.     int n = write(m_nFD, strMessage.c_str(), nLength);
  310.  
  311.     if ( n != nLength) {
  312.       m_strLogMessage = "Error sending " + strIn;
  313.       m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  314.       exit(EXIT_FAILURE);
  315.     }
  316.   }
  317.   m_strLogMessage = "Sent: " + strIn;
  318.   m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  319.   return 0;
  320. }
  321.  
  322. std::string Serial::SerialPortReadUntil(char until) {
  323.  
  324.   if (! m_bSimulationMode) {
  325.     int nNumTries = 0;
  326.  
  327.     std::string strBuffer = "";
  328.    
  329.     char b[1];
  330.     int i=0;
  331.     do {
  332.       int n = read(m_nFD, b, 1);  // read a char at a time
  333.       if ( n == -1 ) return "";    // couldn't read
  334.       if ( n == 0 ) {
  335.        
  336.         nNumTries++;
  337.         if (nNumTries > 2) {
  338.           m_strLogMessage = "Timeout. Received nothing.";
  339.           m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  340.           return "";
  341.         }
  342.        
  343.         usleep( 100 ); // wait 10 msec try again
  344.         //printf("-\n");
  345.         continue;
  346.       }
  347.       strBuffer += b[0];
  348.       i++;
  349.     } while( b[0] != until );
  350.      
  351.     m_strLogMessage = "Received: ->" + strBuffer + "<-";
  352.     m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  353.  
  354.     return strBuffer;
  355.   }
  356.   else {
  357.     //SIMULATION MODE
  358.     m_strLogMessage = "Received: SIMULATION MODE";
  359.     m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  360.  
  361.     return "{\"qr\":3, \"rx\":30}";
  362.   }
  363.  
  364. }
  365.  
  366. uint8_t Serial::SerialPortReadByte() {
  367.  
  368.   int nNumTries = 0;
  369.  
  370.   std::string strBuffer = "";
  371.  
  372.   char b[1];
  373.   int i=0;
  374.   while (1) {
  375.     int n = read(m_nFD, b, 1);  // read a char at a time
  376.     if ( n == -1 ) return 0;    // couldn't read
  377.     if ( n == 0 ) {
  378.      
  379.       nNumTries++;
  380.       if (nNumTries > 2) {
  381.         m_strLogMessage = "Timeout. Received nothing.";
  382.         m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  383.         return 0;
  384.       }
  385.      
  386.       usleep( 1000 ); // wait 10 msec try again
  387.       //printf("-\n");
  388.       continue;
  389.     }
  390.     m_strLogMessage = "Received byte ";
  391.     m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  392.  
  393.     return (uint8_t) b[0];
  394.   }    
  395. }
  396.  
  397. std::string Serial::SerialPortReadUntilEmpty() {
  398.  
  399.   if (! m_bSimulationMode) {
  400.  
  401.     int nNumTries = 0;
  402.  
  403.     std::string strBuffer = "";
  404.    
  405.     char b[1];
  406.     int i=0;
  407.     int n;
  408.  
  409.     do {
  410.       n = read(m_nFD, b, 1);  // read a char at a time
  411.       if ( n == -1 ) return "COULD NOT READ FROM PORT";    // couldn't read
  412.  
  413.       strBuffer += b[0];
  414.       i++;
  415.     } while(n != 0);
  416.  
  417.     m_strLogMessage = "Received: ->" + strBuffer + "<-";
  418.     m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  419.  
  420.     return strBuffer;
  421.   }
  422.   else {
  423.     //SIMULATION MODE
  424.     m_strLogMessage = "Received: SIMULATION MODE";
  425.     m_pcLogger->Log(logINFO, m_strLogMessage.c_str());
  426.  
  427.     return "{\"qr\":3, \"rx\":30}";
  428.   }
  429. }
  430.  
  431. void Serial::SerialPortFlush() {
  432.   if (! m_bSimulationMode) {
  433.     tcflush(m_nFD, TCIOFLUSH); // clear buffer
  434.   }
  435. }
Advertisement
Add Comment
Please, Sign In to add comment