Instrument Neutral Distributed Interface INDI  2.0.2
quantum_wheel.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2016 Radek Kaczorek <rkaczorek AT gmail DOT com>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7  .
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12  .
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 *******************************************************************************/
18 
19 #include "quantum_wheel.h"
20 
22 
23 #include <memory>
24 #include <cstring>
25 #include <termios.h>
26 #include <unistd.h>
27 
28 #include "indicom.h"
29 
30 #define VERSION_MAJOR 0
31 #define VERSION_MINOR 3
32 
33 #define QUANTUM_TIMEOUT 5
34 
35 std::unique_ptr<QFW> qfw(new QFW());
36 
38 {
42 }
43 
44 void QFW::debugTriggered(bool enable)
45 {
46  INDI_UNUSED(enable);
47 }
48 
49 void QFW::simulationTriggered(bool enable)
50 {
51  INDI_UNUSED(enable);
52 }
53 
54 const char *QFW::getDefaultName()
55 {
56  return (const char *)"Quantum Wheel";
57 }
58 
60 {
61  if (isSimulation())
62  {
63  IDMessage(getDeviceName(), "Simulation: connected");
64  PortFD = 1;
65  return true;
66  }
67  // check serial connection
68  if (PortFD < 0 || isatty(PortFD) == 0)
69  {
70  IDMessage(getDeviceName(), "Device /dev/ttyACM0 is not available\n");
71  return false;
72  }
73  // read description
74  char cmd[10] = {"SN\r\n"};
75  char resp[255] = {0};
76  if (send_command(PortFD, cmd, resp) < 2)
77  return false;
78 
79  // SN should respond SN<number>, this identifies a Quantum wheel
80  return strncmp(cmd, resp, 2) == 0;
81 }
82 
84 {
88 
89  serialConnection->setDefaultPort("/dev/ttyACM0");
90 
91  FilterSlotN[0].min = 1;
92  FilterSlotN[0].max = 7;
93  CurrentFilter = 1;
94 
95  return true;
96 }
97 
98 //bool QFW::updateProperties()
99 //{
100 // INDI::FilterWheel::updateProperties();
101 
102 // if (isConnected())
103 // {
104 // // read number of filters
105 // char cmd[10] = {"EN\r\n"};
106 // char resp[255]={0};
107 // if (send_command(PortFD, cmd, resp) < 2)
108 // return false;
109 // int numFilters = resp[1] - '0';
110 // //FilterNameTP->ntp = numFilters;
111 // for (int i = 0; i < numFilters; i++)
112 // {
113 // sprintf(cmd, "F%1d\r\n", i);
114 // if (send_command(PortFD, cmd, resp) < 3)
115 // return false;
116 // char name[64];
117 // int n = strlen(resp);
118 // strncpy(name, &resp[2], n - 4);
119 // name[n] = 0;
120 // IUFillText(&FilterNameT[i], name, name, name);
121 // }
122 // }
123 
124 // return true;
125 //}
126 
127 void QFW::ISGetProperties(const char *dev)
128 {
130 }
131 
133 {
134  return CurrentFilter;
135 }
136 
137 bool QFW::SelectFilter(int position)
138 {
139  // count from 0 to 6 for positions 1 to 7
140  position = position - 1;
141 
142  if (position < 0 || position > 6)
143  return false;
144 
145  if (isSimulation())
146  {
147  CurrentFilter = position + 1;
149  return true;
150  }
151 
152  // goto
153  char targetpos[255] = {0};
154  char curpos[255] = {0};
155  char dmp[255];
156  int err;
157  int nbytes;
158 
159  // format target position G[0-6]
160  sprintf(targetpos, "G%d\r\n ", position);
161 
162  // write command
163  //int len = strlen(targetpos);
164 
165  err = tty_write_string(PortFD, targetpos, &nbytes);
166  if (err)
167  {
168  char errmsg[255];
169  tty_error_msg(err, errmsg, MAXRBUF);
170  LOGF_ERROR("Serial write error: %s", errmsg);
171  return false;
172  }
173  //res = write(PortFD, targetpos, len);
174  dump(dmp, targetpos);
175  LOGF_DEBUG("CMD: %s", dmp);
176 
177  // format target marker P[0-6]
178  sprintf(targetpos, "P%d", position);
179 
180  // check current position
181  do
182  {
183  usleep(100 * 1000);
184  //res = read(PortFD, curpos, 255);
185  err = tty_read_section(PortFD, curpos, '\n', QUANTUM_TIMEOUT, &nbytes);
186  if (err)
187  {
188  char errmsg[255];
189  tty_error_msg(err, errmsg, MAXRBUF);
190  LOGF_ERROR("Serial read error: %s", errmsg);
191  return false;
192  }
193  curpos[nbytes] = 0;
194  dump(dmp, curpos);
195  LOGF_DEBUG("REP: %s", dmp);
196  }
197  while (strncmp(targetpos, curpos, 2) != 0);
198 
199  // return current position to indi
200  CurrentFilter = position + 1;
202  LOGF_DEBUG("CurrentFilter set to %d", CurrentFilter);
203 
204  return true;
205 }
206 
207 void QFW::dump(char *buf, const char *data)
208 {
209  int i = 0;
210  int n = 0;
211  while(data[i] != 0)
212  {
213  if (isprint(data[i]))
214  {
215  buf[n] = data[i];
216  n++;
217  }
218  else
219  {
220  sprintf(buf + n, "[%02X]", data[i]);
221  n += 4;
222  }
223  i++;
224  }
225 }
226 
227 // Send a command to the mount. Return the number of bytes received or 0 if
228 // case of error
229 // commands are null terminated, replies end with /n
230 int QFW::send_command(int fd, const char* cmd, char *resp)
231 {
232  int err;
233  int nbytes = 0;
234  char errmsg[MAXRBUF];
235  int cmd_len = strlen(cmd);
236  char dmp[255];
237 
238  dump(dmp, cmd);
239  LOGF_DEBUG("CMD <%s>", dmp);
240 
241  tcflush(fd, TCIOFLUSH);
242  if ((err = tty_write(fd, cmd, cmd_len, &nbytes)) != TTY_OK)
243  {
244  tty_error_msg(err, errmsg, MAXRBUF);
245  LOGF_ERROR("Serial write error: %s", errmsg);
246  return 0;
247  }
248 
249  err = tty_read_section(fd, resp, '\n', QUANTUM_TIMEOUT, &nbytes);
250  if (err)
251  {
252  tty_error_msg(err, errmsg, MAXRBUF);
253  LOGF_ERROR("Serial read error: %s", errmsg);
254  return 0;
255  }
256 
257  resp[nbytes] = 0;
258  dump(dmp, resp);
259  LOGF_DEBUG("RES <%s>", dmp);
260  return nbytes;
261 }
262 
void setDefaultPort(const char *port)
setDefaultPort Set default port. Call this function in initProperties() of your driver if you want to...
const char * getDeviceName() const
Definition: basedevice.cpp:821
void setDeviceName(const char *dev)
Set the device name.
Definition: basedevice.cpp:815
void addSimulationControl()
Add Simulation control to the driver.
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
bool isSimulation() const
void addDebugControl()
Add Debug control to the driver.
void SelectFilterDone(int newpos)
The child class calls this function when the hardware successfully finished selecting a new filter wh...
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Connection::Serial * serialConnection
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
void setFilterConnection(const uint8_t &value)
setFilterConnection Set Filter connection mode. Child class should call this in the constructor befor...
int PortFD
For Serial & TCP connections.
const char * getDefaultName()
void debugTriggered(bool enable)
Inform driver that the debug option was triggered. This function is called after setDebug is triggere...
void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
bool SelectFilter(int)
Select a new filter position.
bool Handshake()
perform handshake with device to check communication
bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
int QueryFilter()
Return current filter position.
void simulationTriggered(bool enable)
Inform driver that the simulation option was triggered. This function is called after setSimulation i...
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition: indicom.c:566
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
Definition: indicom.c:474
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1167
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
#define INDI_UNUSED(x)
Definition: indidevapi.h:131
void IDMessage(const char *dev, const char *fmt,...)
Definition: indidriver.c:960
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
#define MAXRBUF
Definition: indiserver.cpp:102
int fd
Definition: intelliscope.c:43
__u8 cmd[4]
Definition: pwc-ioctl.h:2
#define VERSION_MAJOR
#define QUANTUM_TIMEOUT
std::unique_ptr< QFW > qfw(new QFW())
#define VERSION_MINOR