Home | History | Annotate | Download | only in hm11
      1 /*
      2  * Author: Jon Trulson <jtrulson (at) ics.com>
      3  * Copyright (c) 2015 Intel Corporation.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be
     14  * included in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #include <iostream>
     26 #include <string>
     27 #include <stdexcept>
     28 
     29 #include "hm11.h"
     30 
     31 using namespace upm;
     32 using namespace std;
     33 
     34 static const int defaultDelay = 100;     // max wait time for read
     35 
     36 HM11::HM11(int uart)
     37 {
     38   m_ttyFd = -1;
     39 
     40   if ( !(m_uart = mraa_uart_init(uart)) )
     41     {
     42       throw std::invalid_argument(std::string(__FUNCTION__) +
     43                                   ": mraa_uart_init() failed");
     44       return;
     45     }
     46 
     47   // This requires a recent MRAA (1/2015)
     48   const char *devPath = mraa_uart_get_dev_path(m_uart);
     49 
     50   if (!devPath)
     51     {
     52       throw std::runtime_error(std::string(__FUNCTION__) +
     53                                ": mraa_uart_get_dev_path() failed");
     54       return;
     55     }
     56 
     57   // now open the tty
     58   if ( (m_ttyFd = open(devPath, O_RDWR)) == -1)
     59     {
     60       throw std::runtime_error(std::string(__FUNCTION__) +
     61                                ": open of " +
     62                                string(devPath) + " failed:" +
     63                                string(strerror(errno)));
     64       return;
     65     }
     66 }
     67 
     68 HM11::~HM11()
     69 {
     70   if (m_ttyFd != -1)
     71     close(m_ttyFd);
     72 }
     73 
     74 bool HM11::dataAvailable(unsigned int millis)
     75 {
     76   if (m_ttyFd == -1)
     77     return false;
     78 
     79   struct timeval timeout;
     80 
     81   // no waiting
     82   timeout.tv_sec = 0;
     83   timeout.tv_usec = millis * 1000;
     84 
     85   int nfds;
     86   fd_set readfds;
     87 
     88   FD_ZERO(&readfds);
     89 
     90   FD_SET(m_ttyFd, &readfds);
     91 
     92   if (select(m_ttyFd + 1, &readfds, NULL, NULL, &timeout) > 0)
     93     return true;                // data is ready
     94   else
     95     return false;
     96 }
     97 
     98 int HM11::readData(char *buffer, int len)
     99 {
    100   if (m_ttyFd == -1)
    101     return(-1);
    102 
    103   int rv = read(m_ttyFd, buffer, len);
    104 
    105   if (rv < 0)
    106     {
    107       throw std::runtime_error(std::string(__FUNCTION__) +
    108                                ": read() failed: " +
    109                                string(strerror(errno)));
    110       return rv;
    111     }
    112 
    113   return rv;
    114 }
    115 
    116 int HM11::writeData(char *buffer, int len)
    117 {
    118   if (m_ttyFd == -1)
    119     return(-1);
    120 
    121   // first, flush any pending but unread input
    122 
    123   tcflush(m_ttyFd, TCIFLUSH);
    124 
    125   int rv = write(m_ttyFd, buffer, len);
    126 
    127   if (rv < 0)
    128     {
    129       throw std::runtime_error(std::string(__FUNCTION__) +
    130                                ": write() failed: " +
    131                                string(strerror(errno)));
    132       return rv;
    133     }
    134 
    135   tcdrain(m_ttyFd);
    136 
    137   return rv;
    138 }
    139 
    140 bool HM11::setupTty(speed_t baud)
    141 {
    142   if (m_ttyFd == -1)
    143     return(false);
    144 
    145   struct termios termio;
    146 
    147   // get current modes
    148   tcgetattr(m_ttyFd, &termio);
    149 
    150   // setup for a 'raw' mode.  81N, no echo or special character
    151   // handling, such as flow control.
    152   cfmakeraw(&termio);
    153 
    154   // set our baud rates
    155   cfsetispeed(&termio, baud);
    156   cfsetospeed(&termio, baud);
    157 
    158   // make it so
    159   if (tcsetattr(m_ttyFd, TCSAFLUSH, &termio) < 0)
    160     {
    161       throw std::runtime_error(std::string(__FUNCTION__) +
    162                                ": tcsetattr() failed: " +
    163                                string(strerror(errno)));
    164       return false;
    165     }
    166 
    167   return true;
    168 }
    169 
    170