openEmbroider  0.1
an open source embroidery software
master.hpp
1 #pragma once
2 
3 #include "uartconnect.hpp"
4 #include "comm.hpp"
5 
6 #include <errno.h>
7 #include <termios.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <thread>
15 #include <time.h>
16 #include <sys/socket.h>
17 #include <bluetooth/bluetooth.h>
18 #include <bluetooth/rfcomm.h>
19 
20 class PcUart
21 {
22 protected:
23  PcUart(const char* name)
24  {
25  if (!strncmp(name, "/dev/tty", 8))
26  {
27  fd = open (name, O_RDWR | O_NOCTTY | O_SYNC);
28  if (fd < 0)
29  {
30  printf ("error %d opening %s: %s", errno, name, strerror (errno));
31  return;
32  }
33  struct termios tty;
34  memset (&tty, 0, sizeof tty);
35  if (tcgetattr (fd, &tty) != 0)
36  {
37  printf ("error %d from tcgetattr", errno);
38  return;
39  }
40 
41  //cfsetospeed (&tty, 115220);
42  //cfsetispeed (&tty, 115220);
43  cfsetospeed (&tty, 9600);
44  cfsetispeed (&tty, 9600);
45 
46  tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
47  // disable IGNBRK for mismatched speed tests; otherwise receive break
48  // as \000 chars
49  tty.c_iflag &= ~IGNBRK; // disable break processing
50  tty.c_lflag = 0; // no signaling chars, no echo,
51  // no canonical processing
52  tty.c_oflag = 0; // no remapping, no delays
53  tty.c_cc[VMIN] = 0; // read doesn't block
54  tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
55 
56  tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
57 
58  tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
59  // enable reading
60  tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
61  tty.c_cflag |= 0;
62  tty.c_cflag &= ~CSTOPB;
63  tty.c_cflag &= ~CRTSCTS;
64 
65  if (tcsetattr (fd, TCSANOW, &tty) != 0)
66  {
67  printf ("error %d from tcsetattr", errno);
68  return;
69  }
70  memset (&tty, 0, sizeof tty);
71  if (tcgetattr (fd, &tty) != 0)
72  {
73  printf ("error %d from tggetattr", errno);
74  return;
75  }
76 
77  tty.c_cc[VMIN] = 1; // blocking
78  tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
79 
80  if (tcsetattr (fd, TCSANOW, &tty) != 0)
81  printf ("error %d setting term attributes", errno);
82  }
83  else
84  { // try bluetooth open
85  struct sockaddr_rc addr = { 0 };
86  addr.rc_family = AF_BLUETOOTH;
87  addr.rc_channel = (uint8_t) 1;
88  str2ba(name, &addr.rc_bdaddr);
89  fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
90  connect(fd, (struct sockaddr *)&addr, sizeof(addr));
91  }
92  }
93  bool uartwrite(const void* buf, size_t count)
94  {
95  return write (fd, buf, count) == (ssize_t)count;
96  }
97  void startReader()
98  {
99  std::thread th(&PcUart::reader, this);
100  th.detach();
101  }
102  void reader()
103  {
104  uint8_t c;
105  while (1)
106  if (read(fd, (void*)&c, 1) == 1)
107  uartOnChar(c);
108  }
109  virtual void uartOnChar(uint8_t c) = 0;
110  ~PcUart()
111  {
112  if (fd)
113  close(fd);
114  }
115  int fd;
116 };
117 
118 class CommMaster : public Comm, public PcUart, public UartConnect<37>
119 {
120 public:
121  CommMaster(const char* portname, unsigned msTimeout, unsigned retries) :
122  PcUart(portname), sequence(0), sequenceAck(0), sndBuffer(msgBuffer+2), msTimeout(msTimeout), retries(retries)
123  {
124  startReader();
125  }
126  bool ack()
127  {
128  return sequence == sequenceAck;
129  }
130 
131  virtual void addPoints(const uint8_t* xys, unsigned points)
132  {
133  if (!points)
134  return;
135  points = points<=16 ? points : 16;
136  for (unsigned i=0; i<2*points; i++) {
137  sndBuffer[i] = xys[i];
138  }
139  sendCommand(Command::kAddPoints, points);
140  }
141  virtual void deletePoints() { sendCommand(Command::kDeletePoints); }
142  virtual void stopMove() { sendCommand(Command::kStopMove); }
143  virtual void startMove() { sendCommand(Command::kStartMove); }
144  virtual void setParam() { sendCommand(Command::kSetParam); }
145  virtual void gotoXY(PosType x, PosType y)
146  {
147  writePosType(sndBuffer, x, 0);
148  writePosType(sndBuffer, y, 1);
149  sendCommand(Command::kGotoXY);
150  }
151  virtual void movedXdY(PosType dx, PosType dy)
152  {
153  writePosType(sndBuffer, dx, 0);
154  writePosType(sndBuffer, dy, 1);
155  sendCommand(Command::kMovedXdY);
156  }
157  virtual void gotoNextPoint() { sendCommand(Command::kGotoNextPoint); }
158  virtual void setNPoint(uint16_t nPoint)
159  {
160  sndBuffer[0] = nPoint>>8;
161  sndBuffer[1] = nPoint&0xff;
162  sendCommand(Command::kSetNPoint);
163  }
164  virtual void setPos(PosType x, PosType y)
165  {
166  writePosType(sndBuffer, x, 0);
167  writePosType(sndBuffer, y, 1);
168  sendCommand(Command::kSetPos);
169  }
170 private:
171  void sendCommand(Command cmd, uint8_t len=1)
172  {
173  msgBuffer[0] = ++sequence;
174  len = len ? (len<=16 ? len-1 : 15) : 0;
175  msgBuffer[1] = (len<<4) | (uint8_t)cmd;
176  sendMsg(msgBuffer);
177  //printf("Command %u...", sequence);
178  //fflush(stdout);
179  struct timespec dt;
180  unsigned ms, tries;
181  for (tries=0; (tries<retries) && (sequence != sequenceAck); tries++)
182  {
183  for (ms=0; (ms<msTimeout) && (sequence != sequenceAck); ms++)
184  {
185  dt.tv_sec = 0;
186  dt.tv_nsec = 1000000;
187  while(nanosleep(&dt,&dt)<0 && errno==EINTR);
188  }
189  }
190  /*if (sequence == sequenceAck)
191  printf("\t\t\tack in %u ms\n", msTimeout*(tries-1)+ms-1);
192  else
193  printf("\t\t\ttimeout\n");*/
194  }
195  virtual void onMsg(uint8_t* buffer)
196  {
197  SlaveInfo* pInfo = (SlaveInfo*)buffer;
198  sequenceAck = pInfo->sequence;
199  memcpy(&info, pInfo, sizeof(info));
200  printf("Seq %u, status %u, spaceSize %u, freeSpace %u, pos (%d,%d), nPoint %u\n",
201  info.sequence, info.status, info.spaceSize, info.freeSpace, info.posX, info.posY, info.nPoint);
202  }
203  virtual void send(const uint8_t* buffer, unsigned len)
204  {
205  uartwrite(buffer, len);
206  }
207  virtual void uartOnChar(uint8_t c)
208  {
209  onChar(c);
210  }
211 public:
212  SlaveInfo info;
213 private:
214  uint8_t sequence;
215  uint8_t sequenceAck;
216  uint8_t msgBuffer[kPacketSize-3];
217  uint8_t* sndBuffer;
218  unsigned msTimeout;
219  unsigned retries;
220 };
Definition: master.hpp:20
Definition: comm.hpp:22
Definition: master.hpp:118
Definition: comm.hpp:67
Definition: uartconnect.hpp:6