diff options
-rw-r--r-- | usbhid-help.pd | 106 | ||||
-rw-r--r-- | usbhid.c | 181 |
2 files changed, 230 insertions, 57 deletions
diff --git a/usbhid-help.pd b/usbhid-help.pd index d00b3a0..bc152a6 100644 --- a/usbhid-help.pd +++ b/usbhid-help.pd @@ -1,26 +1,94 @@ -#N canvas 338 93 597 475 10; +#N canvas 338 93 633 511 10; #X obj 111 373 usbhid; -#X msg 125 14 bang; -#X msg 185 98 close; -#X msg 185 124 reset; -#X obj 84 408 print left; +#X msg 184 111 close; +#X msg 184 137 reset; +#X obj 6 408 print left; #X obj 175 410 print right; -#X text 196 161 [read page# usage# ...(; -#X text 209 210 [write page# usage# ...(; -#X msg 218 231 set write 1 30 1 31 1 38; -#X text 233 258 GARBAGE FOR TESTING; -#X msg 250 292 set read 1 30 word 1 31 1 38; -#X msg 198 142 print; -#X msg 177 78 open 1149 16392; -#X text 298 78 Gravis/Destroyer Tiltpad; -#X msg 205 182 set read 1 30 1 31; -#X connect 0 0 4 0; -#X connect 0 1 5 0; +#X text 195 174 [read page# usage# ...(; +#X text 208 223 [write page# usage# ...(; +#X msg 217 244 set write 1 30 1 31 1 38; +#X text 233 288 GARBAGE FOR TESTING; +#X msg 250 322 set read 1 30 word 1 31 1 38; +#X msg 197 155 print; +#X msg 176 91 open 1149 16392; +#X text 297 91 Gravis/Destroyer Tiltpad; +#X text 261 63 Microsoft 5-button Mouse; +#X msg 171 63 open 1118 57; +#X msg 159 42 open 1452 517; +#X text 258 42 Mitsumi Electric Apple Extended USB Keyboard; +#X msg 258 350 open 1118 57 \, get read; +#X msg 204 195 set read 1 2 1 48; +#X msg 221 267 get read; +#N canvas 0 22 454 304 buttons 0; +#X obj 99 36 inlet; +#X obj 63 108 & 1; +#X obj 63 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 93 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 123 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +4; +#X obj 153 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +8; +#X obj 183 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +16; +#X obj 223 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 263 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 303 130 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 93 108 & 2; +#X obj 123 108 & 4; +#X obj 153 108 & 8; +#X obj 183 108 & 16; +#X obj 223 108 & 32; +#X obj 263 108 & 64; +#X obj 303 108 & 128; +#X connect 0 0 1 0; +#X connect 0 0 10 0; +#X connect 0 0 11 0; +#X connect 0 0 12 0; +#X connect 0 0 13 0; +#X connect 0 0 14 0; +#X connect 0 0 15 0; +#X connect 0 0 16 0; +#X connect 1 0 2 0; +#X connect 10 0 3 0; +#X connect 11 0 4 0; +#X connect 12 0 5 0; +#X connect 13 0 6 0; +#X connect 14 0 7 0; +#X connect 15 0 8 0; +#X connect 16 0 9 0; +#X restore 44 482 pd buttons test; +#X obj 106 429 unpack float float float float; +#X obj 44 83 metro 400; +#X obj 46 57 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X floatatom 165 466 5 0 0 0 - - -; +#X floatatom 235 467 5 0 0 0 - - -; +#X floatatom 315 462 5 0 0 0 - - -; +#X msg 44 104 read 4; +#X msg 50 11 open vendorId productId; +#X text 220 11 these are in decimal \, rather than the usual hex; +#X connect 0 0 21 0; +#X connect 0 1 4 0; #X connect 1 0 0 0; #X connect 2 0 0 0; -#X connect 3 0 0 0; -#X connect 8 0 0 0; +#X connect 7 0 0 0; +#X connect 9 0 0 0; #X connect 10 0 0 0; #X connect 11 0 0 0; -#X connect 12 0 0 0; #X connect 14 0 0 0; +#X connect 15 0 0 0; +#X connect 17 0 0 0; +#X connect 18 0 0 0; +#X connect 19 0 0 0; +#X connect 21 0 20 0; +#X connect 21 1 24 0; +#X connect 21 2 25 0; +#X connect 21 3 26 0; +#X connect 22 0 27 0; +#X connect 23 0 22 0; +#X connect 27 0 0 0; @@ -84,6 +84,8 @@ typedef struct _usbhid t_int x_delay; t_int x_started; /* outlets */ + t_atom *output; + t_int output_count; t_outlet *x_data_outlet; t_outlet *x_control_outlet; } t_usbhid; @@ -113,6 +115,30 @@ static t_class *usbhid_class; * SUPPORT FUNCTIONS */ +/* add one new atom to the list to be outputted */ +static void add_atom_to_output(t_usbhid *x, t_atom *new_atom) +{ + t_atom *new_atom_list; + + new_atom_list = (t_atom *)getbytes((x->output_count + 1) * sizeof(t_atom)); + memcpy(new_atom_list, x->output, x->output_count * sizeof(t_atom)); + freebytes(x->output, x->output_count * sizeof(t_atom)); + x->output = new_atom_list; + memcpy(x->output + x->output_count, new_atom, sizeof(t_atom)); + ++(x->output_count); +} + +static void reset_output(t_usbhid *x) +{ + if(x->output) + { + freebytes(x->output, x->output_count * sizeof(t_atom)); + x->output = NULL; + x->output_count = 0; + } +} + + /* * This function is used in a HIDInterfaceMatcher to iterate thru all of the * HID devices on the USB bus @@ -201,9 +227,9 @@ static bool device_iterator (struct usb_dev_handle const* usbdev, void* custom, /* -------------------------------------------------------------------------- */ -static t_int* make_hid_packet(t_int element_count, t_int argc, t_atom *argv) +static t_int* make_hid_path(t_int element_count, t_int argc, t_atom *argv) { - DEBUG(post("make_hid_packet");); + DEBUG(post("make_hid_path");); t_int i; t_int *return_array = NULL; @@ -315,29 +341,39 @@ static void usbhid_open(t_usbhid *x, t_float vendor_id, t_float product_id) /* -------------------------------------------------------------------------- */ -static void usbhid_read(t_usbhid *x) +static void usbhid_read(t_usbhid *x,t_float length_arg) { DEBUG(post("usbhid_read");); /* int const PATH_IN[PATH_LENGTH] = { 0xffa00001, 0xffa00002, 0xffa10003 }; */ - int const PATH_OUT[2] = { 0x00010030, 0x00010031 }; - - char packet[RECEIVE_PACKET_LENGTH]; - -/* if ( !hid_is_opened(x->x_hidinterface) ) */ -/* { */ -/* usbhid_open(x); */ -/* } */ -/* else */ -/* { */ - x->x_hid_return = hid_get_input_report(x->x_hidinterface, - PATH_OUT, - 2, - packet, - RECEIVE_PACKET_LENGTH); - if (x->x_hid_return != HID_RET_SUCCESS) - error("[usbhid] hid_get_input_report failed with return code %d\n", - x->x_hid_return); -/* } */ +// int const PATH_OUT[3] = { 0x00010002, 0x00010001, 0x00010030 }; + int i; + int packet_bytes = (int)length_arg; + t_atom *temp_atom = getbytes(sizeof(t_atom)); + + char packet[packet_bytes]; + + if ( !hid_is_opened(x->x_hidinterface) ) + { +// usbhid_open(x); + return; + } + x->x_hid_return = hid_get_input_report(x->x_hidinterface, + x->x_read_elements, + x->x_read_element_count, + packet, + length_arg); + if (x->x_hid_return != HID_RET_SUCCESS) + error("[usbhid] hid_get_input_report failed with return code %d\n", + x->x_hid_return); + + reset_output(x); + for(i=0; i<packet_bytes; ++i) + { + SETFLOAT(temp_atom,packet[i]); + add_atom_to_output(x,temp_atom); + } + outlet_list(x->x_data_outlet, &s_list, x->output_count, x->output); + } @@ -351,7 +387,7 @@ static void usbhid_set_read(t_usbhid *x, int argc, t_atom *argv) t_int i; x->x_read_element_count = argc / 2; - x->x_read_elements = make_hid_packet(x->x_read_element_count, argc, argv); + x->x_read_elements = make_hid_path(x->x_read_element_count, argc, argv); post("x_read_element_count %d",x->x_read_element_count); for(i=0;i<x->x_read_element_count;++i) post("x_read_elements %d: %d",i,x->x_read_elements[i]); @@ -366,7 +402,7 @@ static void usbhid_set_write(t_usbhid *x, int argc, t_atom *argv) t_int i; x->x_write_element_count = argc / 2; - x->x_write_elements = make_hid_packet(x->x_write_element_count, argc, argv); + x->x_write_elements = make_hid_path(x->x_write_element_count, argc, argv); post("x_write_element_count %d",x->x_write_element_count); for(i=0;i<x->x_write_element_count;++i) post("x_write_elements %d: %d",i,x->x_write_elements[i]); @@ -381,11 +417,14 @@ static void usbhid_set(t_usbhid *x, t_symbol *s, int argc, t_atom *argv) DEBUG(post("usbhid_set");); t_symbol *subselector; - subselector = atom_getsymbol(&argv[0]); - if(strcmp(subselector->s_name,"read") == 0) - usbhid_set_read(x,argc-1,argv+1); - if(strcmp(subselector->s_name,"write") == 0) - usbhid_set_write(x,argc-1,argv+1); + if(argc) + { + subselector = atom_getsymbol(&argv[0]); + if(strcmp(subselector->s_name,"read") == 0) + usbhid_set_read(x,argc-1,argv+1); + if(strcmp(subselector->s_name,"write") == 0) + usbhid_set_write(x,argc-1,argv+1); + } } @@ -394,16 +433,71 @@ static void usbhid_get(t_usbhid *x, t_symbol *s, int argc, t_atom *argv) { DEBUG(post("usbhid_get");); t_symbol *subselector; - - subselector = atom_getsymbol(&argv[0]); -/* if(strcmp(subselector->s_name,"read") == 0) */ - -/* if(strcmp(subselector->s_name,"write") == 0) */ - + unsigned int i = 0; + t_atom *temp_atom = getbytes(sizeof(t_atom)); + + if (!hid_is_opened(x->x_hidinterface)) { + error("[usbget] cannot dump tree of unopened HIDinterface."); + } + else if(argc) + { + subselector = atom_getsymbol(&argv[0]); + + if(strcmp(subselector->s_name,"read") == 0) + { + post("[usbhid] parse tree of HIDInterface %s:\n", x->x_hidinterface->id); + reset_output(x); + while (HIDParse(x->x_hidinterface->hid_parser, x->x_hidinterface->hid_data)) { + switch(x->x_hidinterface->hid_data->Type) + { + case 0x80: SETSYMBOL(temp_atom, gensym("input")); break; + case 0x90: SETSYMBOL(temp_atom, gensym("output")); break; + case 0xb0: SETSYMBOL(temp_atom, gensym("feature")); break; + default: SETSYMBOL(temp_atom, gensym("UNKNOWN_TYPE")); + } + add_atom_to_output(x,temp_atom); + SETFLOAT(temp_atom, x->x_hidinterface->hid_data->Size); + add_atom_to_output(x,temp_atom); + SETFLOAT(temp_atom, x->x_hidinterface->hid_data->Offset); + add_atom_to_output(x,temp_atom); + SETSYMBOL(temp_atom, gensym("path")); + add_atom_to_output(x,temp_atom); + for (i = 0; i < x->x_hidinterface->hid_data->Path.Size; ++i) { + SETSYMBOL(temp_atom, gensym("usage")); + add_atom_to_output(x,temp_atom); + SETFLOAT(temp_atom, x->x_hidinterface->hid_data->Path.Node[i].UPage); + add_atom_to_output(x,temp_atom); + SETFLOAT(temp_atom, x->x_hidinterface->hid_data->Path.Node[i].Usage); + add_atom_to_output(x,temp_atom); + post("page: 0x%04x\t%d\t\tusage: 0x%04x\t%d", + x->x_hidinterface->hid_data->Path.Node[i].UPage, + x->x_hidinterface->hid_data->Path.Node[i].UPage, + x->x_hidinterface->hid_data->Path.Node[i].Usage, + x->x_hidinterface->hid_data->Path.Node[i].Usage); + } + post("type: 0x%02x\n", x->x_hidinterface->hid_data->Type); + SETSYMBOL(temp_atom, gensym("logical")); + add_atom_to_output(x,temp_atom); + SETFLOAT(temp_atom, x->x_hidinterface->hid_data->LogMin); + add_atom_to_output(x,temp_atom); + SETFLOAT(temp_atom, x->x_hidinterface->hid_data->LogMax); + add_atom_to_output(x,temp_atom); + } + outlet_anything(x->x_control_outlet, gensym("device"), + x->output_count, x->output); + } + + if(strcmp(subselector->s_name,"write") == 0) + { + } + } + else + { + error("[usbhid] must specify \"read\" or \"write\" as first element of %s message",s->s_name); + } } - /* -------------------------------------------------------------------------- */ static void usbhid_close(t_usbhid *x) { @@ -446,6 +540,12 @@ static void usbhid_print(t_usbhid *x) if (get_device_string(x->x_hidinterface,string_buffer)) post("%s is currently open",string_buffer); + x->x_hid_return = hid_dump_tree(stdout, x->x_hidinterface); + if (x->x_hid_return != HID_RET_SUCCESS) { + fprintf(stderr, "hid_dump_tree failed with return code %d\n", x->x_hid_return); + return; + } + /* SETSYMBOL(event_data, gensym(type)); /\* type *\/ */ /* SETSYMBOL(event_data + 1, gensym(code)); /\* code *\/ */ /* SETSYMBOL(event_data + 2, value); /\* value *\/ */ @@ -459,6 +559,8 @@ static void usbhid_reset(t_usbhid *x) DEBUG(post("usbhid_reset");); hid_reset_HIDInterface(x->x_hidinterface); + + x->x_hid_return = hid_init(); } @@ -511,6 +613,8 @@ static void *usbhid_new(t_float f) hid_set_usb_debug(0); /* data init */ + x->output = NULL; + x->output_count = 0; for (i = 0 ; i < HID_ID_MAX ; i++) hid_id[i] = NULL; @@ -563,13 +667,14 @@ void usbhid_setup(void) NULL); /* add inlet datatype methods */ - class_addbang(usbhid_class,(t_method) usbhid_read); +// class_addbang(usbhid_class,(t_method) usbhid_bang); /* add inlet message methods */ class_addmethod(usbhid_class,(t_method) usbhid_print,gensym("print"),0); class_addmethod(usbhid_class,(t_method) usbhid_reset,gensym("reset"),0); + class_addmethod(usbhid_class,(t_method) usbhid_read,gensym("read"),A_DEFFLOAT,0); class_addmethod(usbhid_class,(t_method) usbhid_set,gensym("set"),A_GIMME,0); - class_addmethod(usbhid_class,(t_method) usbhid_get,gensym("get"),A_DEFSYM,0); + class_addmethod(usbhid_class,(t_method) usbhid_get,gensym("get"),A_GIMME,0); class_addmethod(usbhid_class,(t_method) usbhid_open,gensym("open"),A_DEFFLOAT,A_DEFFLOAT,0); class_addmethod(usbhid_class,(t_method) usbhid_close,gensym("close"),0); } |