GCC Code Coverage Report


Directory: src/gate/
File: src/gate/io/gpiodevices.c
Date: 2026-03-20 22:56:14
Exec Total Coverage
Lines: 0 150 0.0%
Functions: 0 14 0.0%
Branches: 0 80 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/io/gpiodevices.h"
30 #include "gate/results.h"
31
32
33 #if defined(GATE_SYS_LINUX)
34 # define GATE_IO_GPIODEVICE_GPIOD_IMPL 1
35 # define GATE_IO_I2CDEVICE_IOCTL_IMPL 1
36 #elif defined(GATE_SYS_ARDUINO)
37 # define GATE_IO_GPIODEVICE_ARDUINO_IMPL 1
38 # define GATE_IO_I2CDEVICE_WIRE_IMPL 1
39 #elif defined(GATE_SYS_WIN)
40 # define GATE_IO_GPIODEVICE_NO_IMPL 1
41 # define GATE_IO_I2CDEVICE_FTD2XX_IMPL 1
42 #else
43 # define GATE_IO_GPIODEVICE_NO_IMPL 1
44 # define GATE_IO_I2CDEVICE_NO_IMPL 1
45 #endif
46
47
48
49
50
51 #if defined(GATE_IO_GPIODEVICE_GPIOD_IMPL)
52
53 #include "gate/debugging.h"
54 #include "gate/io/platform/gpiodevice_libgpiod.h"
55 #include "gate/environments.h"
56
57 gate_result_t gate_gpiodevice_default_path(gate_string_t* device_path)
58 {
59 static gate_string_t const envname = GATE_STRING_INIT_STATIC("GATE_GPIO_DEVICE_PATH");
60 return gate_env_get_var(&envname, device_path);
61 gate_string_create_empty(device_path);
62 return GATE_RESULT_OK;
63 }
64
65
66 gate_result_t gate_gpiodevice_open(gate_string_t const* device_path, gate_enumint_t flags, gate_gpiodevice_t* ptr_device_handle)
67 {
68 gate_result_t ret;
69 gate_cstrbuffer_t pathbuffer = GATE_INIT_EMPTY;
70 gpiod_code_t* const gpiod = get_gpiod_functions();
71
72 if (gpiod == NULL)
73 {
74 return GATE_RESULT_NOTAVAILABLE;
75 }
76
77 do
78 {
79 gpiod_chip_t* ptr_chip;
80
81 if (NULL == gate_cstrbuffer_create_string(&pathbuffer, device_path, false))
82 {
83 ret = GATE_RESULT_OUTOFMEMORY;
84 break;
85 }
86
87 ptr_chip = gpiod->chip_open(gate_cstrbuffer_get(&pathbuffer));
88 if (!ptr_chip)
89 {
90 ret = GATE_RESULT_FAILED;
91 break;
92 }
93
94 /* success case: */
95 if (ptr_device_handle)
96 {
97 *ptr_device_handle = (gate_gpiodevice_t)ptr_chip;
98 }
99 else
100 {
101 gpiod->chip_close(ptr_chip);
102 }
103 ret = GATE_RESULT_OK;
104 } while (0);
105
106 gate_cstrbuffer_destroy(&pathbuffer);
107 return ret;
108 }
109
110
111 gate_result_t gate_gpiodevice_close(gate_gpiodevice_t* ptr_device_handle)
112 {
113 gpiod_code_t* const gpiod = get_gpiod_functions();
114
115 if (gpiod == NULL)
116 {
117 return GATE_RESULT_NOTAVAILABLE;
118 }
119
120 if (!ptr_device_handle)
121 {
122 return GATE_RESULT_INVALIDARG;
123 }
124 else if (*ptr_device_handle)
125 {
126 gpiod_chip_t* ptr_chip = (struct gpiod_chip*)*ptr_device_handle;
127 gpiod->chip_close(ptr_chip);
128 *ptr_device_handle = NULL;
129 return GATE_RESULT_OK;
130 }
131 else
132 {
133 /* the device handle was already cleared, no action required */
134 return GATE_RESULT_OK_UNCHANGED;
135 }
136 }
137
138
139 gate_result_t gate_gpiodevice_lines_list(gate_gpiodevice_t* ptr_device_handle, gate_gpiodevice_list_lines_callback_t callback, void* param)
140 {
141 gate_result_t ret;
142 struct gpiod_chip_info* ptr_info = NULL;
143
144 GATE_DEBUG_ASSERT(ptr_device_handle != NULL);
145 GATE_DEBUG_ASSERT(*ptr_device_handle != NULL);
146
147 do
148 {
149 gate_size_t line_count = 0;
150 gate_size_t ndx;
151 gate_bool_t continue_loop = true;
152 gpiod_chip_t* ptr_chip = (struct gpiod_chip*)*ptr_device_handle;
153
154 ret = gate_gpiod_get_chip_infos(ptr_chip, NULL, NULL, &line_count);
155 GATE_BREAK_IF_FAILED(ret);
156
157 /* iterate available lines and notify usable ones: */
158 for (ndx = 0; continue_loop && (ndx != line_count); ++ndx)
159 {
160 bool is_used = false;
161 gate_string_t str_name = GATE_STRING_INIT_EMPTY;
162 ret = gate_gpiod_get_line_infos(ptr_chip, ndx, &str_name, NULL, NULL, &is_used);
163 if (GATE_FAILED(ret))
164 {
165 continue;
166 }
167 if (callback)
168 {
169 continue_loop = callback((gate_intptr_t)ndx, &str_name, is_used, param);
170 }
171 gate_string_release(&str_name);
172 }
173 /* success case */
174 ret = GATE_RESULT_OK;
175 } while (0);
176 return ret;
177 }
178
179 gate_result_t gate_gpiodevice_lines_get_config(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_enumint_t* ptr_config)
180 {
181 gate_result_t ret = GATE_RESULT_FAILED;
182 /*
183 struct gpiod_line_info* ptr_lineinfo = NULL;
184
185 GATE_DEBUG_ASSERT(ptr_device_handle != NULL);
186 GATE_DEBUG_ASSERT(*ptr_device_handle != NULL);
187
188 do
189 {
190 struct gpiod_chip* ptr_chip = (struct gpiod_chip*)*ptr_device_handle;
191 enum gpiod_line_direction direction;
192
193 ptr_lineinfo = gpiod_chip_get_line_info(ptr_chip, line_address);
194 if (NULL == ptr_lineinfo)
195 {
196 ret = GATE_RESULT_FAILED;
197 break;
198 }
199
200 direction = gpiod_line_info_get_direction(ptr_lineinfo);
201
202 if (ptr_config != NULL)
203 {
204 switch(direction)
205 {
206 case GPIOD_LINE_DIRECTION_INPUT: *ptr_config = GATE_GPIODEVICE_LINE_CONFIG_INPUT; break;
207 case GPIOD_LINE_DIRECTION_OUTPUT: *ptr_config = GATE_GPIODEVICE_LINE_CONFIG_OUTPUT; break;
208 default: *ptr_config = 0; break;
209 }
210 }
211 ret = GATE_RESULT_OK;
212 } while (0);
213
214 if (ptr_lineinfo != NULL)
215 {
216 gpiod_line_info_free(ptr_lineinfo);
217 }
218 */
219 return ret;
220 }
221
222
223 gate_result_t gate_gpiodevice_lines_set_config(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_enumint_t config)
224 {
225 gate_result_t ret = GATE_RESULT_FAILED;
226 /*
227 struct gpiod_line_settings* new_settings = NULL;
228 struct gpiod_line_config* new_config = NULL;
229 struct gpiod_line_request* new_request = NULL;
230
231 GATE_DEBUG_ASSERT(ptr_device_handle != NULL);
232 GATE_DEBUG_ASSERT(*ptr_device_handle != NULL);
233
234 do
235 {
236 struct gpiod_chip* ptr_chip = (struct gpiod_chip*)*ptr_device_handle;
237 enum gpiod_line_direction new_direction = (config == GATE_GPIODEVICE_LINE_CONFIG_INPUT) ? GPIOD_LINE_DIRECTION_INPUT : GPIOD_LINE_DIRECTION_OUTPUT;
238 unsigned int target_line = (unsigned int)line_address;
239
240 new_settings = gpiod_line_settings_new();
241 if (!new_settings)
242 {
243 ret = GATE_RESULT_OUTOFMEMORY;
244 break;
245 }
246
247 new_config = gpiod_line_config_new();
248 if (!new_config)
249 {
250 ret = GATE_RESULT_OUTOFMEMORY;
251 break;
252 }
253
254 if (0 != gpiod_line_settings_set_direction(new_settings, new_direction))
255 {
256 ret = GATE_RESULT_FAILED;
257 break;
258 }
259
260 if (0 != gpiod_line_config_add_line_settings(new_config, &target_line, 1, new_settings))
261 {
262 ret = GATE_RESULT_FAILED;
263 break;
264 }
265
266 new_request = gpiod_chip_request_lines(ptr_chip, NULL, new_config);
267 if (NULL == new_request)
268 {
269 ret = GATE_RESULT_FAILED;
270 break;
271 }
272
273 if(0 != gpiod_line_request_reconfigure_lines(new_request, new_config))
274 {
275 ret = GATE_RESULT_EXECUTIONFAILED;
276 break;
277 }
278 ret = GATE_RESULT_OK;
279 } while (0);
280
281 if (new_request) gpiod_line_request_release(new_request);
282 if (new_config) gpiod_line_config_free(new_config);
283 if (new_settings) gpiod_line_settings_free(new_settings);
284 */
285 return ret;
286 }
287
288
289 gate_result_t gate_gpiodevice_lines_read(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_intptr_t* ptr_value)
290 {
291 gate_result_t ret;
292 gpiod_chip_t* ptr_chip;
293 int value = 0;
294
295 GATE_DEBUG_ASSERT(ptr_device_handle != NULL);
296 GATE_DEBUG_ASSERT(*ptr_device_handle != NULL);
297
298 ptr_chip = (gpiod_chip_t*)*ptr_device_handle;
299 ret = gate_gpiod_read_line_value(ptr_chip, line_address, &value);
300 if (GATE_SUCCEEDED(ret))
301 {
302 if (ptr_value) *ptr_value = value;
303 }
304 return ret;
305 }
306
307
308 gate_result_t gate_gpiodevice_lines_write(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_intptr_t value)
309 {
310 gate_result_t ret;
311 gpiod_chip_t* ptr_chip;
312
313 GATE_DEBUG_ASSERT(ptr_device_handle != NULL);
314 GATE_DEBUG_ASSERT(*ptr_device_handle != NULL);
315
316 ptr_chip = (gpiod_chip_t*)*ptr_device_handle;
317 ret = gate_gpiod_write_line_value(ptr_chip, line_address, value);
318 return ret;
319 }
320
321 #endif /* GATE_IO_GPIODEVICE_GPIOD_IMPL */
322
323
324
325 #if defined(GATE_IO_GPIODEVICE_ARDUINO_IMPL)
326
327 #include "gate/platform/arduino/arduino_gate.h"
328
329 static gate_gpiodevice_t const invalid_handle = (gate_gpiodevice_t)0x00;
330 static gate_gpiodevice_t const default_handle = (gate_gpiodevice_t)0x01;
331
332 gate_result_t gate_gpiodevice_default_path(gate_string_t* device_path)
333 {
334 gate_string_create_empty(device_path);
335 return GATE_RESULT_OK;
336 }
337
338 gate_result_t gate_gpiodevice_open(gate_string_t const* device_path, gate_enumint_t flags, gate_gpiodevice_t* ptr_device_handle)
339 {
340 if (ptr_device_handle)
341 {
342 *ptr_device_handle = default_handle;
343 }
344 return GATE_RESULT_OK;
345 }
346
347 gate_result_t gate_gpiodevice_close(gate_gpiodevice_t* ptr_device_handle)
348 {
349 if (ptr_device_handle)
350 {
351 *ptr_device_handle = invalid_handle;
352 }
353 return GATE_RESULT_OK;
354 }
355
356 gate_result_t gate_gpiodevice_lines_list(gate_gpiodevice_t* ptr_device_handle, gate_gpiodevice_list_lines_callback_t callback, void* param)
357 {
358 if (*ptr_device_handle != default_handle)
359 {
360 return GATE_RESULT_INVALIDARG;
361 }
362 else if (callback != NULL)
363 {
364 gate_result_t ret = GATE_RESULT_FAILED;
365 gate_size_t pin_count = gate_arduino_pin_count();
366 gate_size_t ndx;
367 gate_bool_t continue_loop = true;
368 static gate_string_t const descr = GATE_STRING_INIT_STATIC("Digital pin");
369 for (ndx = 0; (ndx != pin_count) && continue_loop; ++ndx)
370 {
371 if (callback)
372 {
373 gate_intptr_t line = (gate_intptr_t)ndx;
374
375 continue_loop = callback(line, &descr, false, param);
376 }
377 }
378 }
379 return GATE_RESULT_OK;
380 }
381
382 gate_result_t gate_gpiodevice_lines_get_config(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_enumint_t* ptr_config)
383 {
384 if (*ptr_device_handle != default_handle)
385 {
386 return GATE_RESULT_INVALIDARG;
387 }
388 return GATE_RESULT_NOTIMPLEMENTED;
389 }
390
391 gate_result_t gate_gpiodevice_lines_set_config(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_enumint_t config)
392 {
393 if (*ptr_device_handle != default_handle)
394 {
395 return GATE_RESULT_INVALIDARG;
396 }
397 else
398 {
399 gate_uint8_t const pin_num = (gate_uint8_t)line_address;
400 gate_arduino_pin_mode_t mode;
401 switch(config)
402 {
403 case GATE_GPIODEVICE_LINE_CONFIG_INPUT: mode = gate_arduino_pin_mode_input; break;
404 case GATE_GPIODEVICE_LINE_CONFIG_OUTPUT: mode = gate_arduino_pin_mode_output; break;
405 default: return GATE_RESULT_INVALIDARG;
406 }
407 gate_arduino_pin_init(pin_num, mode);
408 return GATE_RESULT_OK;
409 }
410 }
411
412 gate_result_t gate_gpiodevice_lines_read(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_intptr_t* ptr_value)
413 {
414 if (*ptr_device_handle != default_handle)
415 {
416 return GATE_RESULT_INVALIDARG;
417 }
418 else
419 {
420 gate_uint8_t const pin_num = (gate_uint8_t)line_address;
421 if (ptr_value)
422 {
423 *ptr_value = gate_arduino_pin_get_value(pin_num);
424 }
425 return GATE_RESULT_OK;
426 }
427 }
428
429 gate_result_t gate_gpiodevice_lines_write(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_intptr_t value)
430 {
431 if (*ptr_device_handle != default_handle)
432 {
433 return GATE_RESULT_INVALIDARG;
434 }
435 else
436 {
437 gate_uint8_t const pin_num = (gate_uint8_t)line_address;
438 gate_arduino_pin_set_high(pin_num, value != 0);
439 //gate_arduino_pin_set_value(pin_num, (int)value);
440 return GATE_RESULT_OK;
441 }
442 }
443
444 #endif /* GATE_IO_GPIODEVICE_ARDUINO_IMPL */
445
446
447
448 #if defined(GATE_IO_GPIODEVICE_NO_IMPL)
449
450 gate_result_t gate_gpiodevice_default_path(gate_string_t* device_path)
451 {
452 GATE_UNUSED_ARG(device_path);
453 return GATE_RESULT_NOTIMPLEMENTED;
454 }
455
456 gate_result_t gate_gpiodevice_open(gate_string_t const* device_path, gate_enumint_t flags, gate_gpiodevice_t* ptr_device_handle)
457 {
458 GATE_UNUSED_ARG(device_path);
459 GATE_UNUSED_ARG(flags);
460 GATE_UNUSED_ARG(ptr_device_handle);
461 return GATE_RESULT_NOTIMPLEMENTED;
462 }
463
464 gate_result_t gate_gpiodevice_close(gate_gpiodevice_t* ptr_device_handle)
465 {
466 GATE_UNUSED_ARG(ptr_device_handle);
467 return GATE_RESULT_NOTIMPLEMENTED;
468 }
469
470 gate_result_t gate_gpiodevice_lines_list(gate_gpiodevice_t* ptr_device_handle, gate_gpiodevice_list_lines_callback_t callback, void* param)
471 {
472 GATE_UNUSED_ARG(ptr_device_handle);
473 GATE_UNUSED_ARG(callback);
474 GATE_UNUSED_ARG(param);
475 return GATE_RESULT_NOTIMPLEMENTED;
476 }
477
478 gate_result_t gate_gpiodevice_lines_get_config(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_enumint_t* ptr_config)
479 {
480 GATE_UNUSED_ARG(ptr_device_handle);
481 GATE_UNUSED_ARG(line_address);
482 GATE_UNUSED_ARG(ptr_config);
483 return GATE_RESULT_NOTIMPLEMENTED;
484 }
485
486 gate_result_t gate_gpiodevice_lines_set_config(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_enumint_t config)
487 {
488 GATE_UNUSED_ARG(ptr_device_handle);
489 GATE_UNUSED_ARG(line_address);
490 GATE_UNUSED_ARG(config);
491 return GATE_RESULT_NOTIMPLEMENTED;
492 }
493
494 gate_result_t gate_gpiodevice_lines_read(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_intptr_t* ptr_value)
495 {
496 GATE_UNUSED_ARG(ptr_device_handle);
497 GATE_UNUSED_ARG(line_address);
498 GATE_UNUSED_ARG(ptr_value);
499 return GATE_RESULT_NOTIMPLEMENTED;
500 }
501
502 gate_result_t gate_gpiodevice_lines_write(gate_gpiodevice_t* ptr_device_handle, gate_intptr_t line_address, gate_intptr_t value)
503 {
504 GATE_UNUSED_ARG(ptr_device_handle);
505 GATE_UNUSED_ARG(line_address);
506 GATE_UNUSED_ARG(value);
507 return GATE_RESULT_NOTIMPLEMENTED;
508 }
509
510 #endif /* GATE_IO_GPIODEVICE_NO_IMPL */
511
512
513
514 #if defined(GATE_IO_I2CDEVICE_IOCTL_IMPL)
515
516 #include "gate/environments.h"
517 #include "gate/platforms.h"
518 #include "gate/files.h"
519 #include <linux/i2c-dev.h>
520 #include <fcntl.h>
521
522 gate_result_t GATE_CALL gate_i2cdevice_default_path(gate_string_t* device_path)
523 {
524 static gate_string_t const envname = GATE_STRING_INIT_STATIC("GATE_I2C_DEVICE_PATH");
525 gate_result_t result = gate_env_get_var(&envname, device_path);
526 if (GATE_FAILED(result))
527 {
528 static gate_string_t const default_devpath = GATE_STRING_INIT_STATIC("/dev/i2c-1");
529 result = gate_file_exists(&default_devpath);
530 if (GATE_SUCCEEDED(result))
531 {
532 gate_string_duplicate(device_path, &default_devpath);
533 }
534 }
535 return result;
536 }
537
538
539 gate_result_t gate_i2cdevice_open(gate_string_t const* device_path, gate_enumint_t flags, gate_i2cdevice_t* ptr_device_handle)
540 {
541 gate_result_t ret;
542 gate_cstrbuffer_t buffer = GATE_INIT_EMPTY;
543
544 do
545 {
546 int fd;
547 if (NULL == gate_cstrbuffer_create_string(&buffer, device_path, false))
548 {
549 ret = GATE_RESULT_OUTOFMEMORY;
550 break;
551 }
552
553 fd = gate_posix_open(gate_cstrbuffer_get(&buffer), O_RDWR, 0);
554 if (fd == -1)
555 {
556 ret = GATE_RESULT_NOTAVAILABLE;
557 break;
558 }
559
560 /* success case reached */
561 ret = GATE_RESULT_OK;
562 if (ptr_device_handle)
563 {
564 *ptr_device_handle = (gate_i2cdevice_t)(gate_intptr_t)fd;
565 }
566 else
567 {
568 gate_posix_close(fd);
569 }
570 } while (0);
571 gate_cstrbuffer_destroy(&buffer);
572 return ret;
573 }
574
575 gate_result_t gate_i2cdevice_close(gate_i2cdevice_t* ptr_device_handle)
576 {
577 if (!ptr_device_handle)
578 {
579 return GATE_RESULT_INVALIDARG;
580 }
581 else
582 {
583 int fd = (int)(gate_intptr_t)(*ptr_device_handle);
584 if (fd != -1)
585 {
586 gate_posix_close(fd);
587 *ptr_device_handle = (gate_i2cdevice_t)(gate_intptr_t)-1;
588 }
589 return GATE_RESULT_OK;
590 }
591 }
592
593 static gate_result_t fd_i2c_select_slave(int fd, int slave_address)
594 {
595 int result = gate_posix_ioctl(fd, I2C_SLAVE, (void*)(gate_intptr_t)slave_address);
596 return result < 0 ? GATE_RESULT_FAILED : GATE_RESULT_OK;
597 }
598
599 gate_result_t gate_i2cdevice_send(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address,
600 void const* const* content_blocks, gate_size_t const* content_blocks_lengths, gate_size_t count,
601 gate_size_t* bytes_sent)
602 {
603 gate_result_t ret;
604
605 do
606 {
607 int fd;
608 ptrdiff_t write_result;
609 gate_size_t bytes_total = 0;
610 if (!ptr_device_handle)
611 {
612 ret = GATE_RESULT_INVALIDARG;
613 break;
614 }
615
616 fd = (int)(gate_intptr_t)(*ptr_device_handle);
617 ret = fd_i2c_select_slave(fd, (int)i2c_address);
618 GATE_BREAK_IF_FAILED(ret);
619
620 if (count == 1)
621 {
622 bytes_total = content_blocks_lengths[0];
623 write_result = gate_posix_write(fd, content_blocks[0], bytes_total);
624 }
625 else
626 {
627 char buffer[GATE_MAX_STACK_COPYBUFFER_LENGTH];
628 gate_size_t avail = sizeof(buffer);
629 gate_size_t ndx;
630 ptrdiff_t result;
631
632 bytes_total = 0;
633 for (ndx = 0; ndx != count; ++ndx)
634 {
635 void const* const block = content_blocks[ndx];
636 gate_size_t blocklen = content_blocks_lengths[ndx];
637 if (blocklen > avail)
638 {
639 ret = GATE_RESULT_OVERFLOW;
640 break;
641 }
642 gate_mem_copy(&buffer[bytes_total], block, blocklen);
643 bytes_total += blocklen;
644 avail -= blocklen;
645 }
646 GATE_BREAK_IF_FAILED(ret);
647
648 write_result = gate_posix_write(fd, buffer, bytes_total);
649 }
650
651 if (write_result != (ptrdiff_t)bytes_total)
652 {
653 ret = GATE_RESULT_FAILED;
654 break;
655 }
656
657 ret = GATE_RESULT_OK;
658 if (bytes_sent)
659 {
660 *bytes_sent = bytes_total;
661 }
662 } while (0);
663
664 return ret;
665 }
666
667 gate_result_t gate_i2cdevice_receive(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address,
668 void* content, gate_size_t content_length, gate_size_t* bytes_received)
669 {
670 gate_result_t ret;
671
672 do
673 {
674 int fd;
675 ptrdiff_t read_result;
676
677 if (!ptr_device_handle)
678 {
679 ret = GATE_RESULT_INVALIDARG;
680 break;
681 }
682
683 fd = (int)(gate_intptr_t)(*ptr_device_handle);
684 ret = fd_i2c_select_slave(fd, (int)i2c_address);
685 GATE_BREAK_IF_FAILED(ret);
686
687 read_result = gate_posix_read(fd, content, content_length);
688
689 ret = (read_result == (ptrdiff_t)content_length)
690 ? GATE_RESULT_OK
691 : GATE_RESULT_FAILED;
692
693 if (bytes_received)
694 {
695 *bytes_received = (gate_size_t)read_result;
696 }
697 } while (0);
698
699 return ret;
700 }
701
702 #endif /* GATE_IO_I2CDEVICE_IOCTL_IMPL */
703
704
705
706
707 #if defined(GATE_IO_I2CDEVICE_WIRE_IMPL)
708
709 #include "carduino.h"
710
711 static gate_i2cdevice_t invalid_i2cdevice = (gate_i2cdevice_t)0x00;
712 static gate_i2cdevice_t default_i2cdevice = (gate_i2cdevice_t)0x02;
713
714 gate_result_t GATE_CALL gate_i2cdevice_default_path(gate_string_t* device_path)
715 {
716 gate_string_create_empty(device_path);
717 return GATE_RESULT_OK;
718 }
719
720 gate_result_t gate_i2cdevice_open(gate_string_t const* device_path, gate_enumint_t flags, gate_i2cdevice_t* ptr_device_handle)
721 {
722 carduino_i2c_master_init(0, true);
723 *ptr_device_handle = default_i2cdevice;
724 return GATE_RESULT_OK;
725 }
726
727 gate_result_t gate_i2cdevice_close(gate_i2cdevice_t* ptr_device_handle)
728 {
729 *ptr_device_handle = invalid_i2cdevice;
730 return GATE_RESULT_OK;
731 }
732
733 gate_result_t gate_i2cdevice_send(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address,
734 void const* const* content_blocks, gate_size_t const* content_blocks_lengths, gate_size_t count,
735 gate_size_t* bytes_sent)
736 {
737 if(!ptr_device_handle || (*ptr_device_handle != default_i2cdevice))
738 {
739 return GATE_RESULT_INVALIDARG;
740 }
741 else
742 {
743 unsigned const sent = carduino_i2c_master_send_blocks((unsigned char)i2c_address,
744 (char const* const*)content_blocks, content_blocks_lengths, count);
745 *bytes_sent = sent;
746 return GATE_RESULT_OK;
747 }
748 }
749
750 gate_result_t gate_i2cdevice_receive(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address,
751 void* content, gate_size_t content_length, gate_size_t* bytes_received)
752 {
753 if(!ptr_device_handle || (*ptr_device_handle != default_i2cdevice))
754 {
755 return GATE_RESULT_INVALIDARG;
756 }
757 else
758 {
759 int received = carduino_i2c_master_request(i2c_address, (char*)content, (int)content_length);
760 if (bytes_received)
761 {
762 *bytes_received = (gate_size_t)received;
763 }
764 return GATE_RESULT_OK;
765 }
766 }
767
768 #endif /* GATE_IO_I2CDEVICE_WIRE_IMPL */
769
770
771
772 #if defined(GATE_IO_I2CDEVICE_FTD2XX_IMPL)
773
774 #include "gate/platforms.h"
775 #include "gate/libraries.h"
776
777
778
779 typedef ULONG FT_STATUS;
780 typedef PVOID FT_HANDLE;
781 typedef ULONG FT_DEVICE;
782
783 enum
784 {
785 FT_OK,
786 FT_INVALID_HANDLE,
787 FT_DEVICE_NOT_FOUND,
788 FT_DEVICE_NOT_OPENED,
789 FT_IO_ERROR,
790 FT_INSUFFICIENT_RESOURCES,
791 FT_INVALID_PARAMETER,
792 FT_INVALID_BAUD_RATE,
793
794 FT_DEVICE_NOT_OPENED_FOR_ERASE,
795 FT_DEVICE_NOT_OPENED_FOR_WRITE,
796 FT_FAILED_TO_WRITE_DEVICE,
797 FT_EEPROM_READ_FAILED,
798 FT_EEPROM_WRITE_FAILED,
799 FT_EEPROM_ERASE_FAILED,
800 FT_EEPROM_NOT_PRESENT,
801 FT_EEPROM_NOT_PROGRAMMED,
802 FT_INVALID_ARGS,
803 FT_NOT_SUPPORTED,
804 FT_OTHER_ERROR,
805 FT_DEVICE_LIST_NOT_READY
806 };
807
808 enum
809 {
810 FT_DEVICE_BM,
811 FT_DEVICE_AM,
812 FT_DEVICE_100AX,
813 FT_DEVICE_UNKNOWN,
814 FT_DEVICE_2232C,
815 FT_DEVICE_232R,
816 FT_DEVICE_2232H,
817 FT_DEVICE_4232H,
818 FT_DEVICE_232H,
819 FT_DEVICE_X_SERIES,
820 FT_DEVICE_4222H_0,
821 FT_DEVICE_4222H_1_2,
822 FT_DEVICE_4222H_3,
823 FT_DEVICE_4222_PROG,
824 FT_DEVICE_900,
825 FT_DEVICE_930,
826 FT_DEVICE_UMFTPD3A,
827 FT_DEVICE_2233HP,
828 FT_DEVICE_4233HP,
829 FT_DEVICE_2232HP,
830 FT_DEVICE_4232HP,
831 FT_DEVICE_233HP,
832 FT_DEVICE_232HP,
833 FT_DEVICE_2232HA,
834 FT_DEVICE_4232HA
835 };
836
837 typedef struct _ft_device_list_info_node
838 {
839 ULONG Flags;
840 ULONG Type;
841 ULONG ID;
842 DWORD LocId;
843 char SerialNumber[16];
844 char Description[64];
845 FT_HANDLE ftHandle;
846 } FT_DEVICE_LIST_INFO_NODE;
847
848 #define FT_API __stdcall
849
850 typedef FT_STATUS (FT_API *pfunc_FT_GetLibraryVersion)(LPDWORD lpdwVersion);
851 typedef FT_STATUS (FT_API *pfunc_FT_GetNumChannel)(LPDWORD lpdwNumDevs);
852 typedef FT_STATUS (FT_API *pfunc_FT_GetDeviceInfoList)(FT_DEVICE_LIST_INFO_NODE *pDest, LPDWORD lpdwNumDevs);
853 typedef FT_STATUS (FT_API *pfunc_FT_Open) (int iDevice, FT_HANDLE *ftHandle);
854 typedef FT_STATUS (FT_API *pfunc_FT_Close) (FT_HANDLE ftHandle);
855 typedef FT_STATUS (FT_API *pfunc_FT_ResetDevice) (FT_HANDLE ftHandle);
856 typedef FT_STATUS (FT_API *pfunc_FT_Purge) (FT_HANDLE ftHandle, DWORD dwMask);
857 typedef FT_STATUS (FT_API *pfunc_FT_SetUSBParameters) (FT_HANDLE ftHandle, DWORD dwInTransferSize, DWORD dwOutTransferSize);
858 typedef FT_STATUS (FT_API *pfunc_FT_SetChars) (FT_HANDLE ftHandle, UCHAR uEventCh, UCHAR uEventChEn, UCHAR uErrorCh, UCHAR uErrorChEn);
859 typedef FT_STATUS (FT_API *pfunc_FT_SetTimeouts) (FT_HANDLE ftHandle, DWORD dwReadTimeout, DWORD dwWriteTimeout);
860 typedef FT_STATUS (FT_API *pfunc_FT_SetLatencyTimer) (FT_HANDLE ftHandle, UCHAR ucTimer);
861 typedef FT_STATUS (FT_API *pfunc_FT_GetLatencyTimer) (FT_HANDLE ftHandle, UCHAR *ucTimer);
862 typedef FT_STATUS (FT_API *pfunc_FT_SetBitmode) (FT_HANDLE ftHandle, UCHAR ucMask, UCHAR ucMode);
863 typedef FT_STATUS (FT_API *pfunc_FT_GetQueueStatus) (FT_HANDLE ftHandle, LPDWORD lpdwAmountInRxQueue);
864 typedef FT_STATUS (FT_API *pfunc_FT_Read) (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpdwBytesReturned);
865 typedef FT_STATUS (FT_API *pfunc_FT_Write) (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpdwBytesWritten);
866 typedef FT_STATUS (FT_API *pfunc_FT_GetDeviceInfo)(FT_HANDLE ftHandle, FT_DEVICE *lpftDevice, LPDWORD lpdwID, PCHAR SerialNumber, PCHAR Description, LPVOID Dummy);
867
868 typedef struct FT_functions
869 {
870 pfunc_FT_GetLibraryVersion FT_GetLibraryVersion;
871 pfunc_FT_GetNumChannel FT_CreateDeviceInfoList;
872 pfunc_FT_GetDeviceInfoList FT_GetDeviceInfoList;
873 pfunc_FT_Open FT_Open;
874 pfunc_FT_Close FT_Close;
875 pfunc_FT_ResetDevice FT_ResetDevice;
876 pfunc_FT_Purge FT_Purge;
877 pfunc_FT_SetUSBParameters FT_SetUSBParameters;
878 pfunc_FT_SetChars FT_SetChars;
879 pfunc_FT_SetTimeouts FT_SetTimeouts;
880 pfunc_FT_SetLatencyTimer FT_SetLatencyTimer;
881 pfunc_FT_GetLatencyTimer FT_GetLatencyTimer;
882 pfunc_FT_SetBitmode FT_SetBitMode;
883 pfunc_FT_GetQueueStatus FT_GetQueueStatus;
884 pfunc_FT_Read FT_Read;
885 pfunc_FT_Write FT_Write;
886 pfunc_FT_GetDeviceInfo FT_GetDeviceInfo;
887 } FT_functions_t;
888
889 static FT_functions_t const* load_ftd2xx_functions()
890 {
891 static gate_string_t const libname = GATE_STRING_INIT_STATIC("ftd2xx.dll");
892 static FT_functions_t code;
893 static gate_library_t lib;
894 static gate_bool_t code_loaded = false;
895 FT_functions_t* ret = NULL;
896 do
897 {
898 if (code_loaded)
899 {
900 ret = &code;
901 break;
902
903 }
904
905 gate_result_t result;
906 result = gate_library_open(&libname, &lib, GATE_LIBRARY_FLAG_DEFAULT);
907 GATE_BREAK_IF_FAILED(result);
908
909 gate_library_get_function_name(lib, "FT_GetLibraryVersion", &code.FT_GetLibraryVersion);
910 gate_library_get_function_name(lib, "FT_CreateDeviceInfoList", &code.FT_CreateDeviceInfoList);
911 gate_library_get_function_name(lib, "FT_GetDeviceInfoList", &code.FT_GetDeviceInfoList);
912 gate_library_get_function_name(lib, "FT_Open", &code.FT_Open);
913 gate_library_get_function_name(lib, "FT_Close", &code.FT_Close);
914 gate_library_get_function_name(lib, "FT_ResetDevice", &code.FT_ResetDevice);
915 gate_library_get_function_name(lib, "FT_Purge", &code.FT_Purge);
916 gate_library_get_function_name(lib, "FT_SetUSBParameters", &code.FT_SetUSBParameters);
917 gate_library_get_function_name(lib, "FT_SetChars", &code.FT_SetChars);
918 gate_library_get_function_name(lib, "FT_SetTimeouts", &code.FT_SetTimeouts);
919 gate_library_get_function_name(lib, "FT_GetLatencyTimer", &code.FT_GetLatencyTimer);
920 gate_library_get_function_name(lib, "FT_SetLatencyTimer", &code.FT_SetLatencyTimer);
921 gate_library_get_function_name(lib, "FT_SetBitMode", &code.FT_SetBitMode);
922 gate_library_get_function_name(lib, "FT_GetQueueStatus", &code.FT_GetQueueStatus);
923 gate_library_get_function_name(lib, "FT_Read", &code.FT_Read);
924 gate_library_get_function_name(lib, "FT_Write", &code.FT_Write);
925 gate_library_get_function_name(lib, "FT_Read", &code.FT_Read);
926 gate_library_get_function_name(lib, "FT_GetDeviceInfo", &code.FT_GetDeviceInfo);
927
928 code_loaded = true;
929 ret = &code;
930 } while (0);
931
932 return ret;
933 }
934
935 static gate_bool_t is_valid_device_node(FT_DEVICE_LIST_INFO_NODE const* dev_node)
936 {
937 FT_STATUS status = FT_OK;
938 gate_size_t const descr_len = gate_str_length(dev_node->Description);
939
940 switch(dev_node->Type)
941 {
942 case FT_DEVICE_2232C:
943 return (dev_node->Description[descr_len - 1] == 0x41);
944 case FT_DEVICE_2232H:
945 case FT_DEVICE_2233HP:
946 case FT_DEVICE_2232HP:
947 case FT_DEVICE_2232HA:
948 return ((dev_node->Description[descr_len - 1] == 0x41) || (dev_node->Description[descr_len - 1] == 0x42));
949 case FT_DEVICE_4232H:
950 case FT_DEVICE_4233HP:
951 case FT_DEVICE_4232HP:
952 case FT_DEVICE_4232HA:
953 return ((dev_node->Description[descr_len - 1] == 0x41) || (dev_node->Description[descr_len - 1] == 0x42));
954 case FT_DEVICE_232H:
955 case FT_DEVICE_232HP:
956 case FT_DEVICE_233HP:
957 return true;
958 default:
959 return false;
960 };
961 }
962
963
964 static gate_size_t i2c_get_channel_count()
965 {
966 FT_functions_t const* code = load_ftd2xx_functions();
967 DWORD all_channels;
968 FT_STATUS status;
969 gate_size_t counter;
970
971 if (code == NULL)
972 {
973 /* error: no lib */
974 return 0;
975 }
976
977 status = code->FT_CreateDeviceInfoList(&all_channels);
978 if (status != FT_OK)
979 {
980 /* error, no channel infos */
981 return 0;
982 }
983
984 counter = 0;
985 if (all_channels > 0)
986 {
987 FT_DEVICE_LIST_INFO_NODE* ptr_nodes = (FT_DEVICE_LIST_INFO_NODE*)gate_mem_alloc(all_channels * sizeof(FT_DEVICE_LIST_INFO_NODE));
988 if (ptr_nodes != NULL)
989 {
990 DWORD ndx;
991 status = code->FT_GetDeviceInfoList(ptr_nodes, &all_channels);
992 for (ndx = 0; ndx < all_channels; ++ndx)
993 {
994 if (is_valid_device_node(&ptr_nodes[ndx]))
995 {
996 ++counter;
997 }
998 }
999 gate_mem_dealloc(ptr_nodes);
1000 }
1001 }
1002 return counter;
1003 }
1004
1005 static gate_result_t i2c_get_channel_info(gate_size_t channel_index, FT_DEVICE_LIST_INFO_NODE* ptr_channel_info, int* ptr_dev_index)
1006 {
1007 gate_result_t ret = GATE_RESULT_NOMATCH;
1008 FT_functions_t const* code = load_ftd2xx_functions();
1009 DWORD all_channels;
1010 FT_STATUS status;
1011
1012 if (code == NULL)
1013 {
1014 /* error: no lib */
1015 return GATE_RESULT_NOTSUPPORTED;
1016 }
1017
1018 status = code->FT_CreateDeviceInfoList(&all_channels);
1019 if (status != FT_OK)
1020 {
1021 /* error, no channel infos */
1022 return GATE_RESULT_FAILED;
1023 }
1024
1025 if (all_channels > 0)
1026 {
1027 gate_size_t channel_counter = 0;
1028 FT_DEVICE_LIST_INFO_NODE* ptr_nodes = (FT_DEVICE_LIST_INFO_NODE*)gate_mem_alloc(all_channels * sizeof(FT_DEVICE_LIST_INFO_NODE));
1029 if (ptr_nodes != NULL)
1030 {
1031 DWORD ndx;
1032 status = code->FT_GetDeviceInfoList(ptr_nodes, &all_channels);
1033 for (ndx = 0; ndx < all_channels; ++ndx)
1034 {
1035 if (is_valid_device_node(&ptr_nodes[ndx]))
1036 {
1037 if (channel_counter == channel_index)
1038 {
1039 /* desired channel index found */
1040 if (ptr_channel_info != NULL)
1041 {
1042 gate_mem_copy(ptr_channel_info, &ptr_nodes[ndx], sizeof(FT_DEVICE_LIST_INFO_NODE));
1043 }
1044 if (ptr_dev_index != NULL)
1045 {
1046 *ptr_dev_index = (int)ndx;
1047 }
1048 ret = GATE_RESULT_OK;
1049 break;
1050 }
1051 ++channel_counter;
1052 }
1053 }
1054 gate_mem_dealloc(ptr_nodes);
1055 }
1056 }
1057 return ret;
1058 }
1059
1060 static gate_result_t i2c_open_channel(int dev_index, FT_HANDLE* dev_handle)
1061 {
1062 gate_result_t ret = GATE_RESULT_NOMATCH;
1063 FT_functions_t const* code = load_ftd2xx_functions();
1064 DWORD all_channels;
1065 FT_STATUS status;
1066
1067 if (code == NULL)
1068 {
1069 /* error: no lib */
1070 return GATE_RESULT_NOTSUPPORTED;
1071 }
1072
1073 status = code->FT_Open(dev_index, dev_handle);
1074 if (status != FT_OK)
1075 {
1076 return GATE_RESULT_FAILED;
1077 }
1078 /* success case */
1079 return GATE_RESULT_OK;
1080 }
1081
1082 static gate_result_t i2c_close_channel(FT_HANDLE dev_handle)
1083 {
1084 FT_functions_t const* const code = load_ftd2xx_functions();
1085
1086 if (code == NULL)
1087 {
1088 /* error: no lib */
1089 return GATE_RESULT_NOTSUPPORTED;
1090 }
1091 else
1092 {
1093 FT_STATUS const status = code->FT_Close(dev_handle);
1094 return status == FT_OK ? GATE_RESULT_OK : GATE_RESULT_FAILED;
1095 }
1096 }
1097
1098 #define MIN_CLOCK_RATE 0
1099 #define MAX_CLOCK_RATE 30000000
1100 #define MIN_LATENCY_TIMER 0
1101 #define MAX_LATENCY_TIMER 255
1102
1103 #define FT_PURGE_RX 1
1104 #define FT_PURGE_TX 2
1105
1106 #define USB_INPUT_BUFFER_SIZE 65536
1107 #define USB_OUTPUT_BUFFER_SIZE 65536
1108
1109 #define DISABLE_EVENT 0
1110 #define DISABLE_CHAR 0
1111 #define DEVICE_READ_TIMEOUT_INFINITE 0
1112 #define DEVICE_READ_TIMEOUT 5000
1113 #define DEVICE_WRITE_TIMEOUT 5000
1114
1115
1116 #define CHECK_FT_STATUS(status) if (status != FT_OK) return GATE_RESULT_FAILED;
1117
1118 static gate_result_t i2c_init_channel(FT_HANDLE dev_handle, gate_uint32_t clockRate, gate_uint32_t latencyTimer, gate_uint32_t configOptions, gate_uint32_t pin)
1119 {
1120 FT_functions_t const* const code = load_ftd2xx_functions();
1121
1122 if (code == NULL)
1123 {
1124 /* error: no lib */
1125 return GATE_RESULT_NOTSUPPORTED;
1126 }
1127 else
1128 {
1129 FT_STATUS status;
1130 FT_DEVICE ft_device;
1131 DWORD device_id;
1132 CHAR serial_number[32] = GATE_INIT_EMPTY;
1133 CHAR description[128] = GATE_INIT_EMPTY;
1134
1135 if ((clockRate < MIN_CLOCK_RATE)
1136 || (clockRate > MAX_CLOCK_RATE)
1137 || (latencyTimer < MIN_LATENCY_TIMER)
1138 || (latencyTimer > MAX_LATENCY_TIMER))
1139 return FT_INVALID_PARAMETER;
1140
1141 status = code->FT_GetDeviceInfo(dev_handle, &ft_device, &device_id, serial_number, description, NULL);
1142 CHECK_FT_STATUS(status);
1143
1144 status = code->FT_ResetDevice(dev_handle);
1145 CHECK_FT_STATUS(status);
1146
1147 status = code->FT_Purge(dev_handle, FT_PURGE_RX | FT_PURGE_TX);
1148 CHECK_FT_STATUS(status);
1149
1150 status = code->FT_SetUSBParameters(dev_handle, USB_INPUT_BUFFER_SIZE, USB_OUTPUT_BUFFER_SIZE);
1151 CHECK_FT_STATUS(status);
1152
1153 status = code->FT_SetChars(dev_handle, FALSE, DISABLE_EVENT, FALSE, DISABLE_CHAR);
1154 CHECK_FT_STATUS(status);
1155
1156 status = code->FT_SetTimeouts(dev_handle, DEVICE_READ_TIMEOUT, DEVICE_WRITE_TIMEOUT);
1157 CHECK_FT_STATUS(status);
1158
1159 status = code->FT_SetLatencyTimer(dev_handle, (UCHAR)latencyTimer);
1160 CHECK_FT_STATUS(status);
1161
1162 /* TODO: */
1163 /*
1164 if (!(Pin&0xFF))
1165 {
1166 status = Mid_ResetMPSSE(handle);
1167 CHECK_STATUS(status);
1168 }
1169 status = Mid_EnableMPSSEIn(handle);
1170 CHECK_STATUS(status);
1171 status = Mid_SetDeviceLoopbackState(handle, MID_LOOPBACK_TRUE);
1172 CHECK_STATUS(status);
1173 status = Mid_SyncMPSSE(handle);
1174 CHECK_STATUS(status);
1175 INFRA_SLEEP(50);
1176 status = Mid_SetClock(handle, ftDevice, clockRate);
1177 CHECK_STATUS(status);
1178 INFRA_SLEEP(20);
1179 status = Mid_SetDeviceLoopbackState(handle, MID_LOOPBACK_FALSE);
1180 CHECK_STATUS(status);
1181 status = Mid_EmptyDeviceInputBuff(handle);
1182 CHECK_STATUS(status);
1183 if(configOptions & I2C_ENABLE_PIN_STATE_CONFIG)
1184 {
1185 status = Mid_SetGPIOLow(handle, (Pin&0xFF00) >> 8, Pin & 0xFF);
1186 CHECK_STATUS(status);
1187 }
1188 else
1189 {
1190 status = Mid_SetGPIOLow(handle, MID_SET_LOW_BYTE_DATA_BITS_DATA, MID_SET_LOW_BYTE_DATA_BITS_DATA);
1191 CHECK_STATUS(status);
1192 }
1193 if ((ftDevice == FT_DEVICE_232H) && (configOptions & I2C_ENABLE_DRIVE_ONLY_ZERO))
1194 {
1195 uint8 buffer[3];//3
1196 DWORD noOfBytesToTransfer;
1197 DWORD noOfBytesTransferred;
1198 DBG(MSG_DEBUG,"Enabling DRIVE_ONLY_ZERO\n");
1199 noOfBytesToTransfer = 3;
1200 noOfBytesTransferred = 0;
1201 buffer[0] = MPSSE_CMD_ENABLE_DRIVE_ONLY_ZERO;
1202 buffer[1] = 0x03;
1203 buffer[2] = 0x00;
1204 status = FT_Channel_Write(I2C, handle, noOfBytesToTransfer, buffer,&noOfBytesTransferred);
1205 CHECK_STATUS(status);
1206 }
1207 */
1208 }
1209
1210 }
1211
1212 static gate_result_t i2c_write_channel(FT_HANDLE dev_handle, void const* buffer, gate_size_t buffer_len, gate_size_t* written)
1213 {
1214 FT_functions_t const* const code = load_ftd2xx_functions();
1215
1216 if (code == NULL)
1217 {
1218 /* error: no lib */
1219 return GATE_RESULT_NOTSUPPORTED;
1220 }
1221 else
1222 {
1223 DWORD buflen = (DWORD)buffer_len;
1224 DWORD transferred = 0;
1225 FT_STATUS status = code->FT_Write(dev_handle, (LPVOID)buffer, buflen, &transferred);
1226 if (written) *written = (gate_size_t)transferred;
1227 return status == FT_OK ? GATE_RESULT_OK : GATE_RESULT_FAILED;
1228 }
1229 }
1230
1231 static gate_result_t i2c_read_channel(FT_HANDLE dev_handle, void* buffer, gate_size_t buffer_len, gate_size_t* received)
1232 {
1233 FT_functions_t const* const code = load_ftd2xx_functions();
1234
1235 if (code == NULL)
1236 {
1237 /* error: no lib */
1238 return GATE_RESULT_NOTSUPPORTED;
1239 }
1240 else
1241 {
1242 DWORD buflen = (DWORD)buffer_len;
1243 DWORD transferred = 0;
1244 FT_STATUS status = code->FT_Read(dev_handle, buffer, buflen, &transferred);
1245 if (received) *received = (gate_size_t)transferred;
1246 return status == FT_OK ? GATE_RESULT_OK : GATE_RESULT_FAILED;
1247 }
1248 }
1249
1250
1251
1252 gate_result_t GATE_CALL gate_i2cdevice_default_path(gate_string_t* device_path)
1253 {
1254 GATE_UNUSED_ARG(device_path);
1255 return GATE_RESULT_NOTIMPLEMENTED;
1256 }
1257
1258
1259 gate_result_t gate_i2cdevice_open(gate_string_t const* device_path, gate_enumint_t flags, gate_i2cdevice_t* ptr_device_handle)
1260 {
1261 GATE_UNUSED_ARG(device_path);
1262 GATE_UNUSED_ARG(flags);
1263 GATE_UNUSED_ARG(ptr_device_handle);
1264 return GATE_RESULT_NOTIMPLEMENTED;
1265 }
1266
1267 gate_result_t gate_i2cdevice_close(gate_i2cdevice_t* ptr_device_handle)
1268 {
1269 GATE_UNUSED_ARG(ptr_device_handle);
1270 return GATE_RESULT_NOTIMPLEMENTED;
1271 }
1272
1273 gate_result_t gate_i2cdevice_send(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address,
1274 void const* const* content_blocks, gate_size_t const* content_block_lengths, gate_size_t count, gate_size_t* bytes_sent)
1275 {
1276 GATE_UNUSED_ARG(ptr_device_handle);
1277 GATE_UNUSED_ARG(i2c_address);
1278 GATE_UNUSED_ARG(content_blocks);
1279 GATE_UNUSED_ARG(content_block_lengths);
1280 GATE_UNUSED_ARG(count);
1281 GATE_UNUSED_ARG(bytes_sent);
1282 return GATE_RESULT_NOTIMPLEMENTED;
1283 }
1284
1285 gate_result_t gate_i2cdevice_receive(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address, void* content, gate_size_t content_length, gate_size_t* bytes_received)
1286 {
1287 GATE_UNUSED_ARG(ptr_device_handle);
1288 GATE_UNUSED_ARG(i2c_address);
1289 GATE_UNUSED_ARG(content);
1290 GATE_UNUSED_ARG(content_length);
1291 GATE_UNUSED_ARG(bytes_received);
1292 return GATE_RESULT_NOTIMPLEMENTED;
1293 }
1294
1295 #endif /* GATE_IO_I2CDEVICE_FTD2XX_IMPL */
1296
1297
1298
1299
1300
1301 #if defined(GATE_IO_I2CDEVICE_NO_IMPL)
1302
1303 gate_result_t GATE_CALL gate_i2cdevice_default_path(gate_string_t* device_path)
1304 {
1305 GATE_UNUSED_ARG(device_path);
1306 return GATE_RESULT_NOTIMPLEMENTED;
1307 }
1308
1309
1310 gate_result_t gate_i2cdevice_open(gate_string_t const* device_path, gate_enumint_t flags, gate_i2cdevice_t* ptr_device_handle)
1311 {
1312 GATE_UNUSED_ARG(device_path);
1313 GATE_UNUSED_ARG(flags);
1314 GATE_UNUSED_ARG(ptr_device_handle);
1315 return GATE_RESULT_NOTIMPLEMENTED;
1316 }
1317
1318 gate_result_t gate_i2cdevice_close(gate_i2cdevice_t* ptr_device_handle)
1319 {
1320 GATE_UNUSED_ARG(ptr_device_handle);
1321 return GATE_RESULT_NOTIMPLEMENTED;
1322 }
1323
1324 gate_result_t gate_i2cdevice_send(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address,
1325 void const* const* content_blocks, gate_size_t const* content_block_lengths, gate_size_t count, gate_size_t* bytes_sent)
1326 {
1327 GATE_UNUSED_ARG(ptr_device_handle);
1328 GATE_UNUSED_ARG(i2c_address);
1329 GATE_UNUSED_ARG(content_blocks);
1330 GATE_UNUSED_ARG(content_block_lengths);
1331 GATE_UNUSED_ARG(count);
1332 GATE_UNUSED_ARG(bytes_sent);
1333 return GATE_RESULT_NOTIMPLEMENTED;
1334 }
1335
1336 gate_result_t gate_i2cdevice_receive(gate_i2cdevice_t* ptr_device_handle, gate_uint8_t i2c_address, void* content, gate_size_t content_length, gate_size_t* bytes_received)
1337 {
1338 GATE_UNUSED_ARG(ptr_device_handle);
1339 GATE_UNUSED_ARG(i2c_address);
1340 GATE_UNUSED_ARG(content);
1341 GATE_UNUSED_ARG(content_length);
1342 GATE_UNUSED_ARG(bytes_received);
1343 return GATE_RESULT_NOTIMPLEMENTED;
1344 }
1345
1346 #endif /* GATE_IO_I2CDEVICE_NO_IMPL */
1347