source: trunk/kitgen/usb.c@ 176

Last change on this file since 176 was 175, checked in by demin, 12 years ago

initial commit

File size: 30.8 KB
RevLine 
[175]1
2/*
3 Copyright (c) 2009, Pavel Demin
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms,
8 with or without modification, are permitted
9 provided that the following conditions are met:
10
11 * Redistributions of source code must retain
12 the above copyright notice, this list of conditions
13 and the following disclaimer.
14 * Redistributions in binary form must reproduce
15 the above copyright notice, this list of conditions
16 and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
18 * Neither the name of the SRMlite nor the names of its
19 contributors may be used to endorse or promote products
20 derived from this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*/
34
35#include <tcl.h>
36
37#include <stdint.h>
38
39#include <usb.h>
40#include <blt.h>
41
42/* ----------------------------------------------------------------- */
43
44typedef struct UsbDevice {
45 Tcl_Command token;
46 usb_dev_handle *device;
47} UsbDevice;
48
49/* ----------------------------------------------------------------- */
50
51static void
52UsbDeviceDestroy(ClientData clientData)
53{
54 UsbDevice *statePtr = (UsbDevice *) clientData;
55
56 if(statePtr->device != NULL)
57 {
58 usb_close(statePtr->device);
59 }
60
61 ckfree((char *)statePtr);
62}
63
64/* ----------------------------------------------------------------- */
65
66static int
67UsbReadRawObjCmd(UsbDevice *statePtr, Tcl_Interp *interp, Tcl_Obj *CONST obj)
68{
69 unsigned char *data;
70 int read_size, size;
71
72 Tcl_Obj *result;
73
74 if(TCL_OK != Tcl_GetIntFromObj(interp, obj, &size))
75 {
76 Tcl_AppendResult(interp, "Parameter size is not an integer", NULL);
77 return TCL_ERROR;
78 }
79
80 data = ckalloc((unsigned int)(size + 2));
81 read_size = usb_bulk_read(statePtr->device, 0x86, data, size + 2, 1000);
82
83 if(read_size < 0)
84 {
85 ckfree(data);
86
87 Tcl_AppendResult(interp, usb_strerror(), NULL);
88
89 return TCL_ERROR;
90 }
91
92 if(data[0] > 0)
93 {
94 ckfree(data);
95
96 Tcl_AppendResult(interp, "Busy", NULL);
97
98 return 5;
99 }
100
101 if(read_size != size + 2)
102 {
103 ckfree(data);
104
105 Tcl_AppendResult(interp, "Read less than requested", NULL);
106
107 return TCL_ERROR;
108 }
109
110 result = Tcl_NewByteArrayObj(data + 2, size);
111
112 ckfree(data);
113
114 Tcl_SetObjResult(interp, result);
115
116 return TCL_OK;
117}
118
119/* ----------------------------------------------------------------- */
120
121static int
122UsbReadHexObjCmd(UsbDevice *statePtr, Tcl_Interp *interp, Tcl_Obj *CONST objv[])
123{
124 unsigned char *buffer;
125 unsigned char *data;
126 int word_size, char_size, data_size, read_size, i, j, pos;
127
128 unsigned char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
129
130 Tcl_Obj *result;
131
132 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[0], &word_size))
133 {
134 Tcl_AppendResult(interp, "Parameter width is not an integer", NULL);
135 return TCL_ERROR;
136 }
137
138 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[1], &data_size))
139 {
140 Tcl_AppendResult(interp, "Parameter size is not an integer", NULL);
141 return TCL_ERROR;
142 }
143
144 char_size = 3 + 2*word_size;
145
146 data = ckalloc((unsigned int)(data_size*word_size + 2));
147 buffer = ckalloc((unsigned int)(data_size*char_size));
148
149 read_size = usb_bulk_read(statePtr->device, 0x86, data, data_size*word_size + 2, 1000);
150
151 if(read_size < 0)
152 {
153 ckfree(buffer);
154 ckfree(data);
155
156 Tcl_AppendResult(interp, usb_strerror(), NULL);
157
158 return TCL_ERROR;
159 }
160
161 if(data[0] > 0)
162 {
163 ckfree(buffer);
164 ckfree(data);
165
166 Tcl_AppendResult(interp, "Busy", NULL);
167
168 return 5;
169 }
170
171 if(read_size != data_size*word_size + 2)
172 {
173 ckfree(buffer);
174 ckfree(data);
175
176 Tcl_AppendResult(interp, "Read less than requested", NULL);
177
178 return TCL_ERROR;
179 }
180
181 for(i = 0; i < data_size; ++i)
182 {
183 buffer[i*char_size + 0] = '0';
184 buffer[i*char_size + 1] = 'x';
185 for(j = 1; j <= word_size; ++j)
186 {
187 pos = 2 + i*word_size + word_size - j;
188 buffer[i*char_size + 0 + 2*j] = hexval[(data[pos] >> 4) & 0x0F];
189 buffer[i*char_size + 1 + 2*j] = hexval[(data[pos]) & 0x0F];
190 }
191 buffer[i*char_size + 2*word_size + 2] = ' ';
192 }
193
194 result = Tcl_NewStringObj(buffer, data_size*char_size);
195
196 ckfree(buffer);
197 ckfree(data);
198
199 Tcl_SetObjResult(interp, result);
200
201 return TCL_OK;
202}
203
204/* ----------------------------------------------------------------- */
205
206static int
207UsbReadBltObjCmd(UsbDevice *statePtr, Tcl_Interp *interp, Tcl_Obj *CONST objv[])
208{
209 unsigned char *data;
210 int word_size, data_size, read_size, i, j, pos;
211 unsigned long long int value;
212
213 char *name;
214 Blt_Vector *vec;
215
216 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[0], &word_size))
217 {
218 Tcl_AppendResult(interp, "Parameter width is not an integer", NULL);
219 return TCL_ERROR;
220 }
221
222 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[1], &data_size))
223 {
224 Tcl_AppendResult(interp, "Parameter size is not an integer", NULL);
225 return TCL_ERROR;
226 }
227
228 name = Tcl_GetString(objv[2]);
229 if(TCL_OK != Blt_GetVector(interp, name, &vec))
230 {
231 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
232 return TCL_ERROR;
233 }
234
235 if(Blt_VecSize(vec) < data_size)
236 {
237 Tcl_AppendResult(interp, "BLT vector size is less than the data size", NULL);
238 return TCL_ERROR;
239 }
240
241 data = ckalloc((unsigned int)(data_size*word_size + 2));
242
243 read_size = usb_bulk_read(statePtr->device, 0x86, data, data_size*word_size + 2, 1000);
244
245 if(read_size < 0)
246 {
247 ckfree(data);
248
249 Tcl_AppendResult(interp, usb_strerror(), NULL);
250
251 return TCL_ERROR;
252 }
253
254 if(data[0] > 0)
255 {
256 ckfree(data);
257
258 Tcl_AppendResult(interp, "Busy", NULL);
259
260 return 5;
261 }
262
263 if(read_size != data_size*word_size + 2)
264 {
265 ckfree(data);
266
267 Tcl_AppendResult(interp, "Read less than requested", NULL);
268
269 return TCL_ERROR;
270 }
271
272 for(i = 0; i < data_size; ++i)
273 {
274 value = 0;
275 for(j = 1; j <= word_size; ++j)
276 {
277 pos = 2 + i*word_size + word_size - j;
278 value = (value << 8) | data[pos];
279 }
280 Blt_VecData(vec)[i] = (double)value;
281 }
282
283 ckfree(data);
284
285 Blt_ResetVector(vec, Blt_VecData(vec), data_size, Blt_VecSize(vec), TCL_STATIC);
286
287 return TCL_OK;
288}
289
290/* ----------------------------------------------------------------- */
291
292static int
293UsbReadOscObjCmd(UsbDevice *statePtr, Tcl_Interp *interp, Tcl_Obj *CONST objv[])
294{
295 unsigned char *data;
296 int data_size, read_size, i, j, pos, value;
297
298 Tcl_DictSearch search;
299 Tcl_Obj *key, *object;
300 int done;
301
302 char *name;
303 Blt_Vector *vec[15];
304
305 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[0], &data_size))
306 {
307 Tcl_AppendResult(interp, "Parameter size is not an integer", NULL);
308 return TCL_ERROR;
309 }
310
311 if(TCL_OK != Tcl_DictObjFirst(interp, objv[1], &search, &key, &object, &done))
312 {
313 Tcl_AppendResult(interp, "Cannot read dict variable", name, NULL);
314 return TCL_ERROR;
315 }
316
317 for(i = 0; (i < 15) && (!done) ; ++i, Tcl_DictObjNext(&search, &key, &object, &done))
318 {
319 name = Tcl_GetString(object);
320 if(TCL_OK != Blt_GetVector(interp, name, &vec[i]))
321 {
322 Tcl_DictObjDone(&search);
323 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
324 return TCL_ERROR;
325 }
326 if(Blt_VecSize(vec[i]) < data_size)
327 {
328 Tcl_DictObjDone(&search);
329 Tcl_AppendResult(interp, "BLT vector size is less than the data size", NULL);
330 return TCL_ERROR;
331 }
332 }
333 Tcl_DictObjDone(&search);
334
335 data = ckalloc((unsigned int)(data_size * 8 + 2));
336
337 read_size = usb_bulk_read(statePtr->device, 0x86, data, data_size * 8 + 2, 1000);
338
339 if(read_size < 0)
340 {
341 ckfree(data);
342
343 Tcl_AppendResult(interp, usb_strerror(), NULL);
344
345 return TCL_ERROR;
346 }
347
348 if(data[0] > 0)
349 {
350 ckfree(data);
351
352 Tcl_AppendResult(interp, "Busy", NULL);
353
354 return 5;
355 }
356
357 if(read_size != data_size * 8 + 2)
358 {
359 ckfree(data);
360
361 Tcl_AppendResult(interp, "Read less than requested", NULL);
362
363 return TCL_ERROR;
364 }
365
366 for(i = 0; i < data_size; ++i)
367 {
368 pos = 2 + i * 8;
369
370 value = data[pos + 1] & 0x0F;
371 value = (value << 8) | data[pos];
372 Blt_VecData(vec[0])[i] = (double)value;
373
374 value = data[pos + 2];
375 value = (value << 4) | (data[pos + 1] >> 4);
376 Blt_VecData(vec[1])[i] = (double)value;
377
378 value = data[pos + 4] & 0x0F;
379 value = (value << 8) | data[pos + 3];
380 Blt_VecData(vec[2])[i] = (double)value;
381
382 value = data[pos + 5];
383 value = (value << 4) | (data[pos + 4] >> 4);
384
385 for(j = 0; j < 12; ++j)
386 {
387 Blt_VecData(vec[j+3])[i] = (double)((value & 1) + (j * 2));
388 value >>= 1;
389 }
390 }
391
392 ckfree(data);
393
394 for(i = 0; i < 15; ++i)
395 {
396 Blt_ResetVector(vec[i], Blt_VecData(vec[i]), data_size, Blt_VecSize(vec[i]), TCL_STATIC);
397 }
398
399 return TCL_OK;
400}
401
402/* ----------------------------------------------------------------- */
403
404static int
405UsbWriteRawObjCmd(UsbDevice *statePtr, Tcl_Interp *interp, Tcl_Obj *CONST obj)
406{
407 unsigned char *data;
408 int size, i;
409
410 Tcl_Obj *result;
411
412 data = Tcl_GetByteArrayFromObj(obj, &size);
413/*
414 for(i = 0; i < size; ++i) printf(" %02x", data[i]);
415 printf("\n");
416 printf("size = %d\n", size);
417 fflush(stdout);
418*/
419// size = usb_bulk_write(statePtr->device , 0x06, data, size, 1000);
420 size = usb_bulk_write(statePtr->device , 0x08, data, size, 1000);
421
422 if(size >= 0)
423 {
424 result = Tcl_NewIntObj(size);
425
426 Tcl_SetObjResult(interp, result);
427
428 return TCL_OK;
429 }
430 else
431 {
432 Tcl_AppendResult(interp, usb_strerror(), NULL);
433
434 return TCL_ERROR;
435 }
436}
437
438/* ----------------------------------------------------------------- */
439
440static int
441UsbControlObjCmd(UsbDevice *statePtr, Tcl_Interp *interp, Tcl_Obj *CONST objv[])
442{
443 unsigned char *data;
444 int addr, size, i;
445
446 Tcl_Obj *result;
447
448 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[0], &addr))
449 {
450 Tcl_AppendResult(interp, "Parameter addr is not an integer", NULL);
451 return TCL_ERROR;
452 }
453
454 data = Tcl_GetByteArrayFromObj(objv[1], &size);
455
456 size = usb_control_msg(statePtr->device, 0x40, 0xa0, addr, 0, data, size, 1000);
457
458 if(size >= 0)
459 {
460 result = Tcl_NewIntObj(size);
461
462 Tcl_SetObjResult(interp, result);
463
464 return TCL_OK;
465 }
466 else
467 {
468 Tcl_AppendResult(interp, usb_strerror(), NULL);
469
470 return TCL_ERROR;
471 }
472}
473
474
475/* ----------------------------------------------------------------- */
476
477static int
478UsbDeviceObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
479{
480 char *option;
481
482 UsbDevice *statePtr = (UsbDevice *) clientData;
483
484 if(objc < 2)
485 {
486 Tcl_WrongNumArgs(interp, 1, objv, "command ?arg?");
487 return TCL_ERROR;
488 }
489
490 option = Tcl_GetStringFromObj(objv[1], NULL);
491
492 if(strcmp(option, "readRaw") == 0)
493 {
494 if(objc != 3)
495 {
496 Tcl_WrongNumArgs(interp, 1, objv, "readRaw size");
497 return TCL_ERROR;
498 }
499 return UsbReadRawObjCmd(statePtr, interp, objv[2]);
500 }
501 else if(strcmp(option, "readHex") == 0)
502 {
503 if(objc != 4)
504 {
505 Tcl_WrongNumArgs(interp, 1, objv, "readHex width size");
506 return TCL_ERROR;
507 }
508 return UsbReadHexObjCmd(statePtr, interp, objv + 2);
509 }
510 else if(strcmp(option, "readBlt") == 0)
511 {
512 if(objc != 5)
513 {
514 Tcl_WrongNumArgs(interp, 1, objv, "readBlt width size vector");
515 return TCL_ERROR;
516 }
517 return UsbReadBltObjCmd(statePtr, interp, objv + 2);
518 }
519 else if(strcmp(option, "readOsc") == 0)
520 {
521 if(objc != 4)
522 {
523 Tcl_WrongNumArgs(interp, 1, objv, "readOsc size dict");
524 return TCL_ERROR;
525 }
526 return UsbReadOscObjCmd(statePtr, interp, objv + 2);
527 }
528 else if(strcmp(option, "writeRaw") == 0)
529 {
530 if(objc != 3)
531 {
532 Tcl_WrongNumArgs(interp, 1, objv, "writeRaw data");
533 return TCL_ERROR;
534 }
535 return UsbWriteRawObjCmd(statePtr, interp, objv[2]);
536 }
537 else if(strcmp(option, "control") == 0)
538 {
539 if(objc != 4)
540 {
541 Tcl_WrongNumArgs(interp, 1, objv, "control addr data");
542 return TCL_ERROR;
543 }
544 return UsbControlObjCmd(statePtr, interp, objv + 2);
545 }
546 else if(strcmp(option, "disconnect") == 0)
547 {
548 if(objc != 2)
549 {
550 Tcl_WrongNumArgs(interp, 1, objv, "disconnect");
551 return TCL_ERROR;
552 }
553 Tcl_DeleteCommandFromToken(interp, statePtr->token);
554 return TCL_OK;
555 }
556
557 Tcl_AppendResult(interp, "bad option \"", option,
558 "\": must be read, read8, read16, read32, write, control, convert or disconnect", NULL);
559 return TCL_ERROR;
560}
561
562/* ----------------------------------------------------------------- */
563
564static int
565UsbConnectObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
566{
567 char cmdName[256];
568 Tcl_CmdInfo cmdInfo;
569 int cmdCounter;
570
571 int idVendor, idProduct;
572 int bConfigurationValue, bInterfaceNumber, bAlternateSetting;
573
574 UsbDevice *statePtr = (UsbDevice *) clientData;
575
576 struct usb_bus *bus;
577 struct usb_device *dev;
578 struct usb_device *current_device;
579 struct usb_dev_handle *device_handle;
580
581 int rc;
582
583 if(objc != 6)
584 {
585 Tcl_WrongNumArgs(interp, 1, objv, "idVendor idProduct bConfigurationValue bInterfaceNumber bAlternateSetting");
586 return TCL_ERROR;
587 }
588
589 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[1], &idVendor))
590 {
591 Tcl_AppendResult(interp, "Parameter idVendor is not an integer", NULL);
592 return TCL_ERROR;
593 }
594
595 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[2], &idProduct))
596 {
597 Tcl_AppendResult(interp, "Parameter idProduct is not an integer", NULL);
598 return TCL_ERROR;
599 }
600
601 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[3], &bConfigurationValue))
602 {
603 Tcl_AppendResult(interp, "Parameter bConfigurationValue is not an integer", NULL);
604 return TCL_ERROR;
605 }
606
607 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[4], &bInterfaceNumber))
608 {
609 Tcl_AppendResult(interp, "Parameter bInterfaceNumber is not an integer", NULL);
610 return TCL_ERROR;
611 }
612
613 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[5], &bAlternateSetting))
614 {
615 Tcl_AppendResult(interp, "Parameter bAlternateSetting is not an integer", NULL);
616 return TCL_ERROR;
617 }
618
619 usb_find_busses();
620 usb_find_devices();
621
622 current_device = NULL;
623 for(bus = usb_get_busses(); bus && current_device == NULL; bus = bus->next)
624 {
625 for(dev = bus->devices; dev && current_device == NULL; dev = dev->next)
626 {
627 if((dev->descriptor.idVendor == idVendor) &&
628 (dev->descriptor.idProduct == idProduct)) {
629 current_device = dev;
630 }
631 }
632 }
633
634 if(current_device == NULL)
635 {
636 Tcl_AppendResult(interp, "No CY7C68013 device present", NULL);
637 return TCL_ERROR;
638 }
639
640 device_handle = usb_open(current_device);
641 if(device_handle == NULL)
642 {
643 Tcl_AppendResult(interp, usb_strerror(), NULL);
644 return TCL_ERROR;
645 }
646
647 rc = usb_set_configuration(device_handle, bConfigurationValue);
648 if(rc != 0)
649 {
650 Tcl_AppendResult(interp, usb_strerror(), NULL);
651 return TCL_ERROR;
652 }
653
654 rc = usb_claim_interface(device_handle, bInterfaceNumber);
655 if(rc != 0)
656 {
657 Tcl_AppendResult(interp, usb_strerror(), NULL);
658 return TCL_ERROR;
659 }
660
661 rc = usb_set_altinterface(device_handle, bAlternateSetting);
662 if(rc != 0)
663 {
664 Tcl_AppendResult(interp, usb_strerror(), NULL);
665 return TCL_ERROR;
666 }
667
668 statePtr = (UsbDevice *) ckalloc((unsigned int) sizeof(UsbDevice));
669 memset(statePtr, 0, sizeof(UsbDevice));
670
671 statePtr->device = device_handle;
672
673 cmdCounter = 0;
674 do {
675 sprintf(cmdName, "::usb::device_%d_%d_%d", idVendor, idProduct, cmdCounter);
676 cmdCounter++;
677 } while(Tcl_GetCommandInfo(interp, cmdName, &cmdInfo));
678
679 statePtr->token = Tcl_CreateObjCommand(interp, cmdName, UsbDeviceObjCmd,
680 (ClientData) statePtr, UsbDeviceDestroy);
681
682 Tcl_SetResult(interp, cmdName, TCL_VOLATILE);
683 return TCL_OK;
684}
685
686/* ----------------------------------------------------------------- */
687
688static int
689UsbConvertObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
690{
691 unsigned char *buffer, tmp[3];
692 unsigned char *data;
693 int length, size, i;
694
695 Tcl_Obj *result;
696
697 if(objc != 2)
698 {
699 Tcl_WrongNumArgs(interp, 1, objv, "data");
700 return TCL_ERROR;
701 }
702
703 data = Tcl_GetStringFromObj(objv[1], &size);
704
705 buffer = ckalloc((unsigned int) (size/2));
706
707 tmp[2] = 0;
708 length = 0;
709
710 for(i = 1; i < size; i += 2)
711 {
712 tmp[0] = data[i - 1];
713 tmp[1] = data[i];
714 buffer[length++] = strtoul(tmp, 0, 16);
715 }
716
717 result = Tcl_NewByteArrayObj(buffer, length);
718
719 ckfree(buffer);
720
721 Tcl_SetObjResult(interp, result);
722
723 return TCL_OK;
724}
725
726/* ----------------------------------------------------------------- */
727
728static int
729UsbConvertBltObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
730{
731 unsigned char *data;
732 int size, width, length, i, j, pos, value;
733
734 char *name;
735 Blt_Vector *vec;
736
737 if(objc != 4)
738 {
739 Tcl_WrongNumArgs(interp, 1, objv, "data width vector");
740 return TCL_ERROR;
741 }
742
743 data = Tcl_GetByteArrayFromObj(objv[1], &size);
744
745 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[2], &width))
746 {
747 Tcl_AppendResult(interp, "Parameter width is not an integer", NULL);
748 return TCL_ERROR;
749 }
750
751 length = size / width;
752
753 name = Tcl_GetString(objv[3]);
754 if(TCL_OK != Blt_GetVector(interp, name, &vec))
755 {
756 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
757 return TCL_ERROR;
758 }
759
760 if(Blt_VecSize(vec) < length)
761 {
762 Tcl_AppendResult(interp, "BLT vector size is less than the data length", NULL);
763 return TCL_ERROR;
764 }
765
766 for(i = 0; i < length; ++i)
767 {
768 value = 0;
769 for(j = 1; j <= width; ++j)
770 {
771 pos = i*width + width - j;
772 value = (value << 8) | data[pos];
773 }
774 Blt_VecData(vec)[i] = (double)value;
775 }
776
777 Blt_ResetVector(vec, Blt_VecData(vec), length, Blt_VecSize(vec), TCL_STATIC);
778
779 return TCL_OK;
780}
781
782/* ----------------------------------------------------------------- */
783
784static int
785UsbConvertEptObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
786{
787 unsigned char *data;
788 int size, length, i, j, pos, value;
789
790 Tcl_DictSearch search;
791 Tcl_Obj *key, *object;
792 int done;
793
794 char *name;
795 Blt_Vector *vec[16];
796
797 if(objc != 3)
798 {
799 Tcl_WrongNumArgs(interp, 1, objv, "data dict");
800 return TCL_ERROR;
801 }
802
803 data = Tcl_GetByteArrayFromObj(objv[1], &size);
804 length = size / 8;
805
806 if(TCL_OK != Tcl_DictObjFirst(interp, objv[2], &search, &key, &object, &done))
807 {
808 Tcl_AppendResult(interp, "Cannot read dict variable", name, NULL);
809 return TCL_ERROR;
810 }
811
812 for(i = 0; (i < 16) && (!done) ; ++i, Tcl_DictObjNext(&search, &key, &object, &done))
813 {
814 name = Tcl_GetString(object);
815 if(TCL_OK != Blt_GetVector(interp, name, &vec[i]))
816 {
817 Tcl_DictObjDone(&search);
818 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
819 return TCL_ERROR;
820 }
821 if(Blt_VecSize(vec[i]) < length)
822 {
823 Tcl_DictObjDone(&search);
824 Tcl_AppendResult(interp, "BLT vector size is less than the data size", NULL);
825 return TCL_ERROR;
826 }
827 }
828 Tcl_DictObjDone(&search);
829
830 for(i = 0; i < length; ++i)
831 {
832 pos = i * 8;
833
834 value = data[pos + 1] & 0x0F;
835 value = (value << 8) | data[pos];
836 Blt_VecData(vec[0])[i] = (double)value;
837
838 value = data[pos + 2];
839 value = (value << 4) | (data[pos + 1] >> 4);
840 Blt_VecData(vec[1])[i] = (double)value;
841
842 value = data[pos + 4] & 0x0F;
843 value = (value << 8) | data[pos + 3];
844 Blt_VecData(vec[2])[i] = (double)value;
845
846 value = data[pos + 5];
847 value = (value << 4) | (data[pos + 4] >> 4);
848 Blt_VecData(vec[3])[i] = (double)value;
849
850 value = data[pos + 7] & 0x0F;
851 value = (value << 8) | data[pos + 6];
852
853 for(j = 0; j < 12; ++j)
854 {
855 Blt_VecData(vec[j+4])[i] = (double)((value & 1) + (j * 2));
856 value >>= 1;
857 }
858 }
859
860 for(i = 0; i < 16; ++i)
861 {
862 Blt_ResetVector(vec[i], Blt_VecData(vec[i]), length, Blt_VecSize(vec[i]), TCL_STATIC);
863 }
864
865 return TCL_OK;
866}
867
868/* ----------------------------------------------------------------- */
869
870static int
871UsbConvertOscObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
872{
873 unsigned char *data;
874 int size, length, i, j, pos, value;
875
876 Tcl_DictSearch search;
877 Tcl_Obj *key, *object;
878 int done;
879
880 char *name;
881 Blt_Vector *vec[16];
882
883 if(objc != 3)
884 {
885 Tcl_WrongNumArgs(interp, 1, objv, "data dict");
886 return TCL_ERROR;
887 }
888
889 data = Tcl_GetByteArrayFromObj(objv[1], &size);
890 length = size / 8;
891
892 if(TCL_OK != Tcl_DictObjFirst(interp, objv[2], &search, &key, &object, &done))
893 {
894 Tcl_AppendResult(interp, "Cannot read dict variable", name, NULL);
895 return TCL_ERROR;
896 }
897
898 for(i = 0; (i < 16) && (!done) ; ++i, Tcl_DictObjNext(&search, &key, &object, &done))
899 {
900 name = Tcl_GetString(object);
901 if(TCL_OK != Blt_GetVector(interp, name, &vec[i]))
902 {
903 Tcl_DictObjDone(&search);
904 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
905 return TCL_ERROR;
906 }
907 if(Blt_VecSize(vec[i]) < length)
908 {
909 Tcl_DictObjDone(&search);
910 Tcl_AppendResult(interp, "BLT vector size is less than the data size", NULL);
911 return TCL_ERROR;
912 }
913 }
914 Tcl_DictObjDone(&search);
915
916 for(i = 0; i < length; ++i)
917 {
918 pos = i * 8;
919
920 value = data[pos + 1] & 0x0F;
921 value = (value << 8) | data[pos];
922 Blt_VecData(vec[0])[i] = (double)value;
923
924 value = data[pos + 2];
925 value = (value << 4) | (data[pos + 1] >> 4);
926 Blt_VecData(vec[1])[i] = (double)value;
927
928 value = data[pos + 4] & 0x0F;
929 value = (value << 8) | data[pos + 3];
930 Blt_VecData(vec[2])[i] = (double)value;
931
932 value = data[pos + 5];
933 value = (value << 4) | (data[pos + 4] >> 4);
934 Blt_VecData(vec[3])[i] = (double)value;
935
936 value = data[pos + 7] & 0x0F;
937 value = (value << 8) | data[pos + 6];
938 Blt_VecData(vec[4])[i] = (double)value;
939
940 value = data[pos + 7] >> 4;
941
942 for(j = 0; j < 4; ++j)
943 {
944 Blt_VecData(vec[j+5])[i] = (double)((value & 1) << 8);
945 value >>= 1;
946 }
947 }
948
949 for(i = 0; i < 9; ++i)
950 {
951 Blt_ResetVector(vec[i], Blt_VecData(vec[i]), length, Blt_VecSize(vec[i]), TCL_STATIC);
952 }
953
954 return TCL_OK;
955}
956
957/* ----------------------------------------------------------------- */
958
959/* ----------------------------------------------------------------- */
960
961static int
962UsbConvertOsc16ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
963{
964 unsigned char *data;
965 int size, length, i, j, pos, value;
966
967 Tcl_DictSearch search;
968 Tcl_Obj *key, *object;
969 int done;
970
971 char *name;
972 Blt_Vector *vec[18];
973
974 if(objc != 3)
975 {
976 Tcl_WrongNumArgs(interp, 1, objv, "data dict");
977 return TCL_ERROR;
978 }
979
980 data = Tcl_GetByteArrayFromObj(objv[1], &size);
981 length = size / 16;
982
983 if(TCL_OK != Tcl_DictObjFirst(interp, objv[2], &search, &key, &object, &done))
984 {
985 Tcl_AppendResult(interp, "Cannot read dict variable", name, NULL);
986 return TCL_ERROR;
987 }
988
989 for(i = 0; (i < 18) && (!done) ; ++i, Tcl_DictObjNext(&search, &key, &object, &done))
990 {
991 name = Tcl_GetString(object);
992 if(TCL_OK != Blt_GetVector(interp, name, &vec[i]))
993 {
994 Tcl_DictObjDone(&search);
995 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
996 return TCL_ERROR;
997 }
998 if(Blt_VecSize(vec[i]) < length)
999 {
1000 Tcl_DictObjDone(&search);
1001 Tcl_AppendResult(interp, "BLT vector size is less than the data size", NULL);
1002 return TCL_ERROR;
1003 }
1004 }
1005 Tcl_DictObjDone(&search);
1006
1007 for(i = 0; i < length; ++i)
1008 {
1009 pos = i * 16;
1010
1011 value = data[pos + 1] & 0x0F;
1012 value = (value << 8) | data[pos];
1013 Blt_VecData(vec[0])[i] = (double)value;
1014
1015 value = data[pos + 2];
1016 value = (value << 4) | (data[pos + 1] >> 4);
1017 Blt_VecData(vec[1])[i] = (double)value;
1018
1019 value = data[pos + 4] & 0x0F;
1020 value = (value << 8) | data[pos + 3];
1021 Blt_VecData(vec[2])[i] = (double)value;
1022
1023 value = data[pos + 5];
1024 value = (value << 4) | (data[pos + 4] >> 4);
1025 Blt_VecData(vec[3])[i] = (double)value;
1026
1027 value = data[pos + 7] & 0x0F;
1028 value = (value << 8) | data[pos + 6];
1029 Blt_VecData(vec[4])[i] = (double)value;
1030
1031 value = data[pos + 8];
1032 value = (value << 4) | (data[pos + 7] >> 4);
1033 Blt_VecData(vec[5])[i] = (double)value;
1034
1035 value = data[pos + 10] & 0x0F;
1036 value = (value << 8) | data[pos + 9];
1037 Blt_VecData(vec[6])[i] = (double)value;
1038
1039 value = data[pos + 11];
1040 value = (value << 4) | (data[pos + 10] >> 4);
1041 Blt_VecData(vec[7])[i] = (double)value;
1042
1043 value = data[pos + 13] & 0x0F;
1044 value = (value << 8) | data[pos + 12];
1045 Blt_VecData(vec[8])[i] = (double)value;
1046
1047 value = data[pos + 14];
1048 value = (value << 4) | (data[pos + 13] >> 4);
1049 Blt_VecData(vec[9])[i] = (double)value;
1050
1051 value = data[pos + 15];
1052
1053 for(j = 0; j < 8; ++j)
1054 {
1055 Blt_VecData(vec[j+10])[i] = (double)((value & 1) << 8);
1056 value >>= 1;
1057 }
1058 }
1059
1060 for(i = 0; i < 18; ++i)
1061 {
1062 Blt_ResetVector(vec[i], Blt_VecData(vec[i]), length, Blt_VecSize(vec[i]), TCL_STATIC);
1063 }
1064
1065 return TCL_OK;
1066}
1067
1068/* ----------------------------------------------------------------- */
1069
1070static int
1071UsbFormatOscCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
1072{
1073 char *name;
1074 int first, last, done, max, i, j;
1075
1076 Tcl_DictSearch search;
1077 Tcl_Obj *key, *object, *result, *eol;
1078
1079 Blt_Vector *vec[32];
1080
1081 if(objc != 4)
1082 {
1083 Tcl_WrongNumArgs(interp, 1, objv, "dict first last");
1084 return TCL_ERROR;
1085 }
1086
1087 if(TCL_OK != Tcl_DictObjFirst(interp, objv[1], &search, &key, &object, &done))
1088 {
1089 Tcl_AppendResult(interp, "Cannot read dict variable", name, NULL);
1090 return TCL_ERROR;
1091 }
1092
1093 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[2], &first))
1094 {
1095 Tcl_AppendResult(interp, "Parameter first is not an integer", NULL);
1096 return TCL_ERROR;
1097 }
1098
1099 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[3], &last))
1100 {
1101 Tcl_AppendResult(interp, "Parameter last is not an integer", NULL);
1102 return TCL_ERROR;
1103 }
1104
1105 if(last < first)
1106 {
1107 return TCL_OK;
1108 }
1109
1110 for(i = 0; (i < 32) && (!done); ++i, Tcl_DictObjNext(&search, &key, &object, &done))
1111 {
1112 name = Tcl_GetString(object);
1113 if(TCL_OK != Blt_GetVector(interp, name, &vec[i]))
1114 {
1115 Tcl_DictObjDone(&search);
1116 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
1117 return TCL_ERROR;
1118 }
1119 if(Blt_VecLength(vec[i]) <= last)
1120 {
1121 last = Blt_VecLength(vec[i]) - 1;
1122 }
1123 max = i;
1124 }
1125 Tcl_DictObjDone(&search);
1126
1127 if(first < 0)
1128 {
1129 first = 0;
1130 }
1131
1132 result = Tcl_NewObj();
1133 eol = Tcl_NewStringObj("\n", -1);
1134
1135 Tcl_IncrRefCount(result);
1136 Tcl_IncrRefCount(eol);
1137
1138 for(i = first; i <= last; ++i)
1139 {
1140 for(j = 0; j <= max; ++j)
1141 {
1142 if(j > 0)
1143 {
1144 Tcl_AppendPrintfToObj(result, "\t%g", Blt_VecData(vec[j])[i]);
1145 }
1146 else
1147 {
1148 Tcl_AppendPrintfToObj(result, "%g", Blt_VecData(vec[j])[i]);
1149 }
1150 }
1151 Tcl_AppendObjToObj(result, eol);
1152 }
1153
1154 Tcl_SetObjResult(interp, result);
1155
1156 Tcl_DecrRefCount(eol);
1157 Tcl_DecrRefCount(result);
1158
1159 return TCL_OK;
1160}
1161
1162/* ----------------------------------------------------------------- */
1163
1164static int
1165UsbIntegrateBltObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
1166{
1167 int length, i, xmin, xmax, flag;
1168 double entr, mean;
1169
1170 char *name;
1171 Blt_Vector *vec;
1172
1173 Tcl_Obj *result;
1174
1175 if(objc != 5)
1176 {
1177 Tcl_WrongNumArgs(interp, 1, objv, "vector xmin xmax flag");
1178 return TCL_ERROR;
1179 }
1180
1181 name = Tcl_GetString(objv[1]);
1182 if(TCL_OK != Blt_GetVector(interp, name, &vec))
1183 {
1184 Tcl_AppendResult(interp, "Cannot find BLT vector", name, NULL);
1185 return TCL_ERROR;
1186 }
1187
1188 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[2], &xmin))
1189 {
1190 Tcl_AppendResult(interp, "Parameter xmin is not an integer", NULL);
1191 return TCL_ERROR;
1192 }
1193
1194 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[3], &xmax))
1195 {
1196 Tcl_AppendResult(interp, "Parameter xmax is not an integer", NULL);
1197 return TCL_ERROR;
1198 }
1199
1200 if(TCL_OK != Tcl_GetIntFromObj(interp, objv[4], &flag))
1201 {
1202 Tcl_AppendResult(interp, "Parameter flag is not an integer", NULL);
1203 return TCL_ERROR;
1204 }
1205
1206 length = Blt_VecLength(vec);
1207 entr = 0.0;
1208 mean = 0.0;
1209
1210 if(xmin < 0) xmin = 0;
1211 if(xmax >= length) xmax = length - 1;
1212 if(xmax < xmin) xmax = xmin;
1213
1214 for(i = xmin; i <= xmax; ++i)
1215 {
1216 entr += Blt_VecData(vec)[i];
1217 mean += i * Blt_VecData(vec)[i];
1218 }
1219
1220 if(flag)
1221 {
1222 result = Tcl_NewDoubleObj(entr > 0.0 ? mean / entr : 0.0);
1223 }
1224 else
1225 {
1226 result = Tcl_NewDoubleObj(entr);
1227 }
1228
1229 Tcl_SetObjResult(interp, result);
1230
1231 return TCL_OK;
1232}
1233
1234/* ----------------------------------------------------------------- */
1235
1236int
1237Usb_Init(Tcl_Interp *interp)
1238{
1239 usb_init();
1240
1241 Tcl_CreateObjCommand(interp, "usb::connect", UsbConnectObjCmd,
1242 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1243
1244 Tcl_CreateObjCommand(interp, "usb::convert", UsbConvertObjCmd,
1245 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1246
1247 Tcl_CreateObjCommand(interp, "usb::convertBlt", UsbConvertBltObjCmd,
1248 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1249
1250 Tcl_CreateObjCommand(interp, "usb::convertEpt", UsbConvertOscObjCmd,
1251 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1252
1253 Tcl_CreateObjCommand(interp, "usb::convertOsc", UsbConvertOscObjCmd,
1254 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1255
1256 Tcl_CreateObjCommand(interp, "usb::convertOsc16", UsbConvertOsc16ObjCmd,
1257 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1258
1259 Tcl_CreateObjCommand(interp, "usb::formatOsc", UsbFormatOscCmd,
1260 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1261
1262 Tcl_CreateObjCommand(interp, "usb::integrateBlt", UsbIntegrateBltObjCmd,
1263 (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
1264
1265 return Tcl_PkgProvide(interp, "usb", "0.1");
1266}
Note: See TracBrowser for help on using the repository browser.