1 /* 2 * Author: Jon Trulson <jtrulson (at) ics.com> 3 * Copyright (c) 2014 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 "ublox6.h" 30 31 using namespace upm; 32 using namespace std; 33 34 Ublox6::Ublox6(int uart) 35 { 36 m_ttyFd = -1; 37 38 if ( !(m_uart = mraa_uart_init(uart)) ) 39 { 40 throw std::invalid_argument(std::string(__FUNCTION__) + 41 ": mraa_uart_init() failed"); 42 return; 43 } 44 45 // This requires a recent MRAA (1/2015) 46 const char *devPath = mraa_uart_get_dev_path(m_uart); 47 48 if (!devPath) 49 { 50 throw std::runtime_error(std::string(__FUNCTION__) + 51 ": mraa_uart_get_dev_path() failed"); 52 return; 53 } 54 55 // now open the tty 56 if ( (m_ttyFd = open(devPath, O_RDWR)) == -1) 57 { 58 string err = __FUNCTION__; 59 err += ": open of " + std::string(devPath) + " failed: " + 60 std::string(strerror(errno)); 61 62 throw std::runtime_error(err); 63 return; 64 } 65 } 66 67 Ublox6::~Ublox6() 68 { 69 if (m_ttyFd != -1) 70 close(m_ttyFd); 71 } 72 73 bool Ublox6::dataAvailable() 74 { 75 if (m_ttyFd == -1) 76 return false; 77 78 struct timeval timeout; 79 80 // no waiting 81 timeout.tv_sec = 0; 82 timeout.tv_usec = 0; 83 84 int nfds; 85 fd_set readfds; 86 87 FD_ZERO(&readfds); 88 89 FD_SET(m_ttyFd, &readfds); 90 91 if (select(m_ttyFd + 1, &readfds, NULL, NULL, &timeout) > 0) 92 return true; // data is ready 93 else 94 return false; 95 } 96 97 int Ublox6::readData(char *buffer, int len) 98 { 99 if (m_ttyFd == -1) 100 return(-1); 101 102 int rv = read(m_ttyFd, buffer, len); 103 104 if (rv < 0) 105 { 106 string err = string(__FUNCTION__) + ": read failed: " + 107 string(strerror(errno)); 108 109 throw std::runtime_error(err); 110 return rv; 111 } 112 113 return rv; 114 } 115 116 int Ublox6::writeData(char * buffer, int len) 117 { 118 if (m_ttyFd == -1) 119 return(-1); 120 121 int rv = write(m_ttyFd, buffer, len); 122 123 if (rv < 0) 124 { 125 string err = string(__FUNCTION__) + ": write failed: " + 126 string(strerror(errno)); 127 128 throw std::runtime_error(err); 129 return rv; 130 } 131 132 tcdrain(m_ttyFd); 133 134 return rv; 135 } 136 137 bool Ublox6::setupTty(speed_t baud) 138 { 139 if (m_ttyFd == -1) 140 return(false); 141 142 struct termios termio; 143 144 // get current modes 145 tcgetattr(m_ttyFd, &termio); 146 147 // setup for a 'raw' mode. 81N, no echo or special character 148 // handling, such as flow control. 149 cfmakeraw(&termio); 150 151 // set our baud rates 152 cfsetispeed(&termio, baud); 153 cfsetospeed(&termio, baud); 154 155 // make it so 156 int rv; 157 if ( (rv = tcsetattr(m_ttyFd, TCSAFLUSH, &termio)) < 0) 158 { 159 string err = string(__FUNCTION__) + ": tcsetattr failed: " + 160 string(strerror(errno)); 161 162 throw std::runtime_error(err); 163 return false; 164 } 165 166 return true; 167 } 168