• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Author: Jon Trulson <jtrulson@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 
HM11(int uart)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 
~HM11()68 HM11::~HM11()
69 {
70   if (m_ttyFd != -1)
71     close(m_ttyFd);
72 }
73 
dataAvailable(unsigned int millis)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 
readData(char * buffer,int len)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 
writeData(char * buffer,int len)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 
setupTty(speed_t baud)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