Remove generated files
[framework/connectivity/libgphoto2.git] / camlibs / digita / serial.c
1 /*
2  * serial.c
3  *
4  *  Serial digita support
5  *
6  * Copyright 1999-2001 Johannes Erdfelt
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include "config.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <termios.h>
31 #include <unistd.h>
32 #ifdef OS2
33 #include <db.h>
34 #endif
35
36 #include "gphoto2-endian.h"
37 #include "digita.h"
38
39 #define GP_MODULE "digita"
40
41 #include <gphoto2/gphoto2-port.h>
42
43 #define MAX_BEACON_RETRIES      5
44 #define MAX_BEACON_TIMEOUTS     2
45
46 /*
47  * u8  0xA5
48  * u8  0x5A
49  * u16 vendorid
50  * u16 deviceid
51  * u8  checksum
52  */
53 #define BEACON_LEN              7
54
55 /*
56  * u8  0x5A
57  * u8  0xA5
58  * u8  0x55 (iftype)
59  * u8  commflag
60  *  u4 reserved
61  *  u2 pod_receive_mode
62  *  u2 host_receive_mode
63  * u32 dataspeed
64  * u16 deviceframesize
65  * u16 hostframesize
66  * u8  checksum
67  */
68 #define BEACON_ACK_LENGTH       13
69
70 /*
71  * s8  result
72  * u8  commflag
73  *  u4 reserved
74  *  u2 pod_receive_mode
75  *  u2 host_receive_mode
76  * u32 dataspeed
77  * u16 deviceframesize
78  * u16 hostframesize
79  */
80 #define BEACON_COMP_LENGTH      10
81
82 #define POLL_LENGTH_MASK        0x03FF
83 #define POLL_BOB                0x0400
84 #define POLL_EOB                0x0800
85 #define POLL_CMD                0x1000
86 #define POLL_POLL_MASK          0xE000
87 #define POLL_POLL               (1 << 13)
88
89 #define POLL_ACK                0x01
90 #define POLL_NAK                0x02
91
92 static unsigned int checksum(const unsigned char *buffer, int len)
93 {
94         int i;
95         int limit = len - 1;
96         unsigned int sum = 0;
97
98         for (i = 0; i < limit; i++)
99                 sum += *(buffer++);
100
101         return sum & 0xff;
102 }
103
104 static int poll_and_wait(gp_port *dev, int length, int bob, int eob)
105 {
106         unsigned short s, poll, poll_reply;
107
108         poll = POLL_POLL | POLL_CMD | (length & POLL_LENGTH_MASK) |
109                 (bob ? POLL_BOB : 0) | (eob ? POLL_EOB : 0);
110
111         do {
112                 s = htons(poll);
113                 if (gp_port_write(dev, (void *)&s, sizeof(s)) < 0)
114                         return -1;
115                 if (gp_port_read(dev, (void *)&s, sizeof(s)) < 0)
116                         return -1;
117                 poll_reply = ntohs(s);
118         } while (poll_reply & POLL_NAK);
119
120         return 0;
121 }
122
123 static int digita_serial_send(CameraPrivateLibrary *dev, void *_buffer, int len)
124 {
125         char *buffer = _buffer;
126         unsigned short s;
127         int sent = 0, size;
128
129         while (sent < len) {
130                 if ((len - sent) > dev->deviceframesize)
131                         size = dev->deviceframesize;
132                 else
133                         size = len - sent;
134
135                 if (poll_and_wait(dev->gpdev, size, sent == 0, (size + sent) == len) < 0)
136                         return -1;
137
138                 if (gp_port_write(dev->gpdev, buffer + sent, size) < 0)
139                         return -1;
140
141                 sent += size;
142         }
143
144         s = 0;
145         if (gp_port_write(dev->gpdev, (void *)&s, sizeof(s)) < 0)
146                 return -1;
147
148         return len;
149 }
150
151 static int poll_and_reply(gp_port *dev, int *length, int *eob, int nak)
152 {
153         unsigned short s, poll;
154
155         if (gp_port_read(dev, (void *)&s, sizeof(s)) < 0)
156                 return -1;
157
158         poll = ntohs(s);
159         if (length)
160                 *length = poll & POLL_LENGTH_MASK;
161         if (eob)
162                 *eob = poll & POLL_EOB;
163
164         s = htons(nak ? POLL_NAK : POLL_ACK);
165         if (gp_port_write(dev, (void *)&s, sizeof(s)) < 0)
166                 return -1;
167
168         return 0;
169 }
170
171 static int digita_serial_read(CameraPrivateLibrary *dev, void *_buffer, int len)
172 {
173         char *buffer = _buffer;
174         unsigned short s;
175         int received = 0, size, eob;
176
177         while (received < len) {
178                 if (poll_and_reply(dev->gpdev, &size, &eob, 0) < 0)
179                         return -1;
180
181                 if (gp_port_read(dev->gpdev, buffer + received, size) < 0)
182                         return -1;
183
184                 received += size;
185                 if (eob)
186                         break;
187         }
188
189         if (gp_port_read(dev->gpdev, (void *)&s, sizeof(s)) < 0)
190                 return -1;
191
192         return received;
193 }
194
195 int digita_serial_open(CameraPrivateLibrary *dev, Camera *camera)
196 {
197         GPPortSettings settings;
198         int selected_speed;
199         int ret, retries, negotiated = 0;
200         unsigned char buffer[20];
201         unsigned short s;
202         unsigned int l;
203
204         /* Get the settings */
205         ret = gp_port_get_settings(camera->port, &settings);
206         if (ret < 0)
207                 return ret;
208
209         /* Remember the selected speed */
210         selected_speed = settings.serial.speed;
211         if (!selected_speed)
212                 selected_speed = 115200;        /* Try the maximum speed */
213
214         /* Set the settings */
215         settings.serial.speed = 9600;
216         settings.serial.bits = 8;
217         settings.serial.parity = 0;
218         settings.serial.stopbits = 1;
219         ret = gp_port_set_settings(camera->port, settings);
220         if (ret < 0)
221                 return ret;
222
223         dev->send = digita_serial_send;
224         dev->read = digita_serial_read;
225
226         gp_port_send_break(dev->gpdev, 4);
227
228         usleep(10000);
229
230         /* FIXME: In some situations we may want to try a slower speed */
231         for (retries = 0; !negotiated && retries < MAX_BEACON_RETRIES; retries++) {
232                 unsigned char csum;
233                 int i, timeouts = 0;
234
235                 /*
236                  * Read the beacon
237                  */
238                 memset(buffer, 0, sizeof(buffer));
239
240                 for (i = 0; (i < BEACON_LEN * 2) && (timeouts < MAX_BEACON_TIMEOUTS); i++) {
241                         /* We specifically eat as much as we can to catch any */
242                         /* garbage before or after */
243                         ret = gp_port_read(dev->gpdev, (void *)buffer, 1);
244                         if (ret < 0) {
245                                 GP_DEBUG("couldn't read beacon (ret = %d)", ret);
246                                 timeouts++;
247                                 continue;
248                         }
249
250                         if (buffer[0] == 0xA5)
251                                 break;
252                 }
253
254                 if (timeouts >= MAX_BEACON_TIMEOUTS)
255                         continue;
256
257                 ret = gp_port_read(dev->gpdev, (void *)(buffer + 1), BEACON_LEN - 1);
258                 if (ret < 0) {
259                         GP_DEBUG("couldn't read beacon (ret = %d)", ret);
260                         continue;
261                 }
262
263                 if (buffer[0] != 0xA5 || buffer[1] != 0x5A) {
264                         GP_DEBUG("Invalid header for beacon 0x%02x 0x%02x", buffer[0], buffer[1]);
265                         continue;
266                 }
267
268                 csum = buffer[6];
269                 buffer[6] = 0;
270                 if (checksum(buffer, BEACON_LEN) != csum) {
271                         GP_DEBUG("Beacon checksum failed (calculated 0x%02x, received 0x%02x)",
272                                 checksum(buffer, BEACON_LEN), csum);
273                         continue;
274                 }
275
276                 memcpy((void *)&s, &buffer[2], 2);
277                 GP_DEBUG("Vendor: 0x%04x", ntohs(s));
278                 memcpy((void *)&s, &buffer[4], 2);
279                 GP_DEBUG("Product: 0x%04x", ntohs(s));
280
281                 /*
282                  * Send the beacon acknowledgement
283                  */
284                 buffer[0] = 0x5A;       /* Magic */
285                 buffer[1] = 0xA5;
286                 buffer[2] = 0x55;       /* I/F Type */
287                 buffer[3] = 0;          /* Comm Flag */
288                 l = htonl(selected_speed);
289                 memcpy(&buffer[4], (void *)&l, 4);      /* Data speed */
290                 s = htons(1023);
291                 memcpy(&buffer[8], (void *)&s, 2);      /* Device Frame Size */
292                 s = htons(1023);
293                 memcpy(&buffer[10], (void *)&s, 2);     /* Host Frame Size */
294                 buffer[12] = 0;
295                 buffer[12] = checksum(buffer, BEACON_ACK_LENGTH);
296
297                 ret = gp_port_write(dev->gpdev, (void *)buffer, BEACON_ACK_LENGTH);
298                 if (ret < 0) {
299                         GP_DEBUG("couldn't write beacon (ret = %d)", ret);
300                         return -1;
301                 }
302
303                 /*
304                  * Read the beacon completion
305                  */
306                 ret = gp_port_read(dev->gpdev, (void *)buffer, BEACON_COMP_LENGTH);
307                 if (ret < 0) {
308                         GP_DEBUG("couldn't read beacon_comp (ret = %d)", ret);
309                         continue;
310                 }
311
312                 if ((signed char)buffer[0] < 0) {
313                         GP_DEBUG("Bad status %d during beacon completion", (signed int)buffer[0]);
314                         continue;
315                 }
316
317                 memcpy((void *)&s, &buffer[6], sizeof(s));
318                 dev->deviceframesize = ntohs(s);
319
320                 memcpy((void *)&l, &buffer[2], sizeof(l));
321                 GP_DEBUG("negotiated %d", ntohl(l));
322                 settings.serial.speed = ntohl(l);
323
324                 usleep(100000); /* Wait before */
325
326                 ret = gp_port_set_settings(dev->gpdev, settings);
327                 if (ret < 0)
328                         return ret;
329
330                 usleep(100000); /* Wait after */
331
332                 /*
333                  * The host interface spec mentions kTestSerialData, but
334                  * doesn't elaborate anywhere else on it. So, I guess we
335                  * assume everything is working here
336                  */
337                 negotiated = 1;
338         }
339
340         return negotiated ? 0 : -1;
341 }
342