| | 634 | if ~libisloaded('libusb') |
| | 635 | textOut(sprintf(' - Loading library "libusb"... ')); |
| | 636 | try |
| | 637 | % use "our" wrapper file... |
| | 638 | loadlibrary('libusb', @libusb_proto) |
| | 639 | textOut(sprintf('done.\n')); |
| | 640 | catch |
| | 641 | textOut(sprintf('failed.\n')); |
| | 642 | if ~SuppressErrors |
| | 643 | error('MATLAB:RWTHMindstormsNXT:USB:Linux:couldNotLoadLibraryLibusb', 'The "libusb" library could not be loaded (file "libusb" or "libusb.so"). Make sure it is installed and paths are set correctly!') |
| | 644 | else |
| | 645 | return |
| | 646 | end%if |
| | 647 | end%try |
| | 648 | else |
| | 649 | textOut(sprintf(' - Library "libusb" already loaded.\n')); |
| | 650 | end%if |
| | 651 | |
| | 652 | |
| | 653 | textOut(sprintf(' - Initializing and browsing USB busses\n')); |
| | 654 | |
| | 655 | %% Init libusb |
| | 656 | textOut(sprintf(' . initializing libusb.\n')) |
| | 657 | calllib('libusb', 'usb_init'); |
| | 658 | |
| | 659 | % > - insert usb_set_debug(255) in pyusb.c right behind usb_init() |
| | 660 | % > - recompile and reinstall the module |
| | 661 | % > - hook up DebugView from www.sysinternals.com |
| | 662 | % > - rerun your application |
| | 663 | % so if we want debug mode, this needs to be uncommented! |
| | 664 | %calllib('libusb', 'usb_set_debug', 255); |
| | 665 | |
| | 666 | |
| | 667 | % these functions return the number of changes made to the busses and |
| | 668 | % devices since last call, don't neet it... |
| | 669 | textOut(sprintf(' . finding busses... ')) |
| | 670 | ret = calllib('libusb', 'usb_find_busses'); |
| | 671 | displayLibusbStatus(ret); |
| | 672 | |
| | 673 | textOut(sprintf(' . finding devices... ')) |
| | 674 | ret = calllib('libusb', 'usb_find_devices'); |
| | 675 | displayLibusbStatus(ret); |
| | 676 | |
| | 677 | %% Get main root bus |
| | 678 | |
| | 679 | textOut(sprintf(' . getting root bus object... ')) |
| | 680 | p = calllib('libusb', 'usb_get_busses'); |
| | 681 | bus = libstruct('usb_bus', p); |
| | 682 | displayLibusbStatus(p); |
| | 683 | |
| | 684 | |
| | 685 | textOut(sprintf(' - Enumerating busses and devices\n')); |
| | 686 | |
| | 687 | %% Cycle through all busses and devices: enumerate... |
| | 688 | foundNXT = false; |
| | 689 | while ~foundNXT % for all busses |
| | 690 | |
| | 691 | % we want to save some debug-lines (already got too many), so we don't |
| | 692 | % care what USB devices the user has. remove comment for advanced debug |
| | 693 | % mode |
| | 694 | %textOut(sprintf(' . current bus: %s\n', strtrim(char(bus.dirname)))) |
| | 695 | |
| | 696 | dev = libstruct('usb_device', bus.devices); |
| | 697 | |
| | 698 | % ------------------------------------- |
| | 699 | while true % for all devices! sorry for endless-loop, but we break later down |
| | 700 | |
| | 701 | % if no devs at all |
| | 702 | if isempty(dev) |
| | 703 | break |
| | 704 | end%if |
| | 705 | |
| | 706 | |
| | 707 | % we want to save some debug-lines (already got too many), so we don't |
| | 708 | % care what USB devices the user has. remove comment for advanced debug |
| | 709 | % mode |
| | 710 | %textOut(sprintf(' . current device: %s\n', strtrim(char(dev.filename)))) |
| | 711 | |
| | 712 | |
| | 713 | % try a little string reading.... |
| | 714 | |
| | 715 | % THIS DOESN'T WORK UNDER LINUX MOST OF THE TIME |
| | 716 | % APPARENTLY, WE CANNOT OPEN ALL PRESENT DEVICES |
| | 717 | % Since we don't want to try to open a device now, we keep this |
| | 718 | % working code (at least for public devices on Linux and for |
| | 719 | % alle devices on Windows) commented, maybe someone else can |
| | 720 | % use it to improve this function later on... |
| | 721 | % It's debug-info only anyway |
| | 722 | |
| | 723 | % % open device to get a handle |
| | 724 | % DevHandle = calllib('libusb', 'usb_open', dev); |
| | 725 | % |
| | 726 | % % now the string stuff |
| | 727 | % buffer = blanks(255); |
| | 728 | % % we don't need a real buffer or pointer, matlab seems to do this |
| | 729 | % % for us, so we pass that buffer variable, without really needing |
| | 730 | % % it. it seems like matlab "knows" how strings get written by |
| | 731 | % % reference and returns the new value from the function. if you |
| | 732 | % % compare the matlab-returnvalues of usb_get_string_simple using |
| | 733 | % % libfunctionsview libusb, you'll find that they don't match whats |
| | 734 | % % written inside usb.h. very nice and handy, thank you matlab :-) |
| | 735 | % %pBuffer = libpointer('cstring', buffer); not needed, see above |
| | 736 | % |
| | 737 | % % now the actual call: |
| | 738 | % [bytesRead newHandleOrWhat ManufacturerName] = calllib('libusb', 'usb_get_string_simple', ... |
| | 739 | % DevHandle, dev.descriptor.iManufacturer, buffer, length(buffer)); |
| | 740 | % % again: |
| | 741 | % [bytesRead newHandleOrWhat ProductName] = calllib('libusb', 'usb_get_string_simple', ... |
| | 742 | % DevHandle, dev.descriptor.iProduct, buffer, length(buffer)); |
| | 743 | % |
| | 744 | % disp(sprintf(' Manufacturer: %s', ManufacturerName)) |
| | 745 | % disp(sprintf(' Product: %s', ProductName)) |
| | 746 | % |
| | 747 | % % close device again |
| | 748 | % ret = calllib('libusb', 'usb_close', DevHandle); |
| | 749 | % clear DevHandle %better doing it now than forgetting it later |
| | 750 | |
| | 751 | |
| | 752 | % note at this point that we only try to open a device if it's one |
| | 753 | % from LEGO! |
| | 754 | |
| | 755 | % check if it's LEGO and NXT |
| | 756 | if (dev.descriptor.idVendor == ID_VENDOR_LEGO) && (dev.descriptor.idProduct == ID_PRODUCT_NXT) |
| | 757 | textOut(sprintf(' . found NXT device\n')); |
| | 758 | |
| | 759 | textOut(sprintf(' . opening device... ')); |
| | 760 | DevHandle = calllib('libusb', 'usb_open', dev); |
| | 761 | displayLibusbStatus(DevHandle); |
| | 762 | |
| | 763 | textOut(sprintf(' . reading serial number... ')); |
| | 764 | % c-syntax from documentation so we know whats going on: |
| | 765 | % int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen); |
| | 766 | buffer = blanks(255); |
| | 767 | [bytesRead newHandleOrWhat SerialNo] = calllib('libusb', 'usb_get_string_simple', DevHandle, dev.descriptor.iSerialNumber, buffer, length(buffer)); |
| | 768 | displayLibusbStatus(bytesRead); |
| | 769 | |
| | 770 | SerialNo = strtrim(SerialNo); % just to be safe |
| | 771 | textOut(sprintf(' . MAC = %s ', SerialNo)) |
| | 772 | |
| | 773 | % is it the right one? |
| | 774 | if isempty(hIn.NXTMAC) || strcmpi(hIn.NXTMAC, SerialNo) |
| | 775 | foundNXT = true; |
| | 776 | textOut(sprintf('(MAC matches, this is our desired NXT)\n')); |
| | 777 | break % search came to an end |
| | 778 | else |
| | 779 | foundNXT = false; |
| | 780 | textOut(sprintf('(no match, not using this NXT)\n')); |
| | 781 | % don't forget to close the opened NXT that didnt match... |
| | 782 | textOut(sprintf(' . closing device... ')); |
| | 783 | status = calllib('libusb', 'usb_close', DevHandle); |
| | 784 | displayLibusbStatus(status); |
| | 785 | end%if |
| | 786 | |
| | 787 | end%if |
| | 788 | |
| | 789 | |
| | 790 | % we are at the end of our "pointer-queue" |
| | 791 | if isempty(dev.next) |
| | 792 | break |
| | 793 | else |
| | 794 | % get next device, not that easy, but it works now \o/ |
| | 795 | ptr = dev.next; |
| | 796 | ptr.setdatatype('usb_device'); |
| | 797 | dev = ptr.Value; |
| | 798 | clear ptr % to be sure, don't want to risk memory leaks |
| | 799 | end%if |
| | 800 | |
| | 801 | end%while (for all devices) |
| | 802 | % ------------------------------------- |
| | 803 | |
| | 804 | |
| | 805 | % no need to scan other busses if already found |
| | 806 | if foundNXT |
| | 807 | break |
| | 808 | end%if |
| | 809 | |
| | 810 | % jump to next bus - same procedure as for devices, see above |
| | 811 | if isempty(bus.next) |
| | 812 | break |
| | 813 | else |
| | 814 | ptr = bus.next; |
| | 815 | ptr.setdatatype('usb_bus'); |
| | 816 | bus = ptr.Value; |
| | 817 | clear ptr |
| | 818 | end%if |
| | 819 | |
| | 820 | end%while (for all busses) |
| | 821 | |
| | 822 | |
| | 823 | %% check if NXT present |
| | 824 | if ~foundNXT |
| | 825 | if ~SuppressErrors |
| | 826 | errordlg('No NXT found on USB bus! Make sure the NXT is turned on and access rights in /dev/ are properly set. Rebooting your NXT might help!') |
| | 827 | error('MATLAB:RWTHMindstormsNXT:USB:Linux:noNXTfound', 'No NXT found on USB bus! Make sure the NXT is turned on and access rights in /dev/ are properly set. Rebooting your NXT might help!') |
| | 828 | else |
| | 829 | % well, no NXT, exit silently |
| | 830 | return |
| | 831 | end%if |
| | 832 | end%if |
| | 833 | |
| | 834 | |
| | 835 | %% NXT found, open connection |
| | 836 | |
| | 837 | % DevHandle is now the NXT we want |
| | 838 | |
| | 839 | % the following commands are standard procedure for USB devices, similar usage |
| | 840 | % can be found in the open source packages Python_NXT and LEGO::NXT (Perl) |
| | 841 | |
| | 842 | % flag to remember |
| | 843 | ErrorWhileOpening = false; |
| | 844 | |
| | 845 | % if the following fails with error -16, the NXT is probably already in |
| | 846 | % use (opened in another handle!) |
| | 847 | textOut(sprintf(' . setting active configuration... ')); |
| | 848 | % somehow this doesn't work, so we use the hardcoded configuration 1! |
| | 849 | %calllib('libusb', 'usb_set_configuration', DevHandle, dev.config.bConfigurationValue); |
| | 850 | ret = calllib('libusb', 'usb_set_configuration', DevHandle, LIBUSB_Configuration); |
| | 851 | displayLibusbStatus(ret); |
| | 852 | if (ret < 0) |
| | 853 | ErrorWhileOpening = true; |
| | 854 | end%if |
| | 855 | |
| | 856 | textOut(sprintf(' . claiming interface... ')); |
| | 857 | % again, interface is hardcoded (compare implementations in python and |
| | 858 | % perl, they do it the same way) |
| | 859 | %calllib('libusb', 'usb_claim_interface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| | 860 | ret = calllib('libusb', 'usb_claim_interface', DevHandle, LIBUSB_Interface); |
| | 861 | displayLibusbStatus(ret); |
| | 862 | if (ret < 0) |
| | 863 | ErrorWhileOpening = true; |
| | 864 | end%if |
| | 865 | |
| | 866 | |
| | 867 | % we don't need an alternative interface, whatever that is. |
| | 868 | % but from debugging experience (also with Windows), you never know |
| | 869 | % when you might need this, so we keep it in here! |
| | 870 | |
| | 871 | % disp(' . set altinterface') |
| | 872 | % % %[int32, usb_dev_handlePtr] usb_set_altinterface(usb_dev_handlePtr, int32) |
| | 873 | % ret = calllib('libusb', 'usb_set_altinterface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| | 874 | % disp(sprintf('usb_strerror: %s', calllib('libusb', 'usb_strerror'))) |
| | 875 | |
| | 876 | % is this necessary? but found it in perl and python versions... |
| | 877 | % the main point: never touch a running system |
| | 878 | textOut(sprintf(' . resetting device... ')); |
| | 879 | ret = calllib('libusb', 'usb_reset', DevHandle); |
| | 880 | displayLibusbStatus(ret); |
| | 881 | if (ret < 0) |
| | 882 | ErrorWhileOpening = true; |
| | 883 | end%if |
| | 884 | |
| | 885 | % now it's time to decide: |
| | 886 | if ErrorWhileOpening || isnumeric(DevHandle) |
| | 887 | if ~SuppressErrors |
| | 888 | errordlg('Something went wrong while opening the NXT device via USB (is it already open in another handle?). Please try to reboot the NXT or call COM_CloseNXT(''all'')!') |
| | 889 | error('MATLAB:RWTHMindstormsNXT:USB:Linux:couldNotOpenNXT', 'Something went wrong while opening the NXT device via USB (is it already open in another handle?). Please try to reboot the NXT or call COM_CloseNXT(''all'')!') |
| | 890 | else |
| | 891 | % again, exit silently when no success |
| | 892 | return |
| | 893 | end%if |
| | 894 | end%if |
| | 895 | |
| | 896 | % finally, we're good to go! |
| | 897 | hOut.Handle = DevHandle; |
| | 898 | hOut.NXTMAC = SerialNo; |
| | 899 | |
| | 900 | % and, important: |
| | 901 | hOut.Connected(true); |
| | 902 | |
| | 903 | |
| | 904 | %% clean up |
| | 905 | |
| | 906 | % is this needed? or will matlab destroy this private vars anyway after |
| | 907 | % finishing this function? just to be sure with pointers... |
| | 908 | clear p v bus dev newHandleOrWhat DevHandle |
| | 909 | |
| | 910 | |
| | 911 | end%function |
| | 912 | |
| | 913 | |
| | 914 | %% --- FUNCTION USB_OpenHandle_Linux |
| | 915 | function hOut = USB_OpenHandle_Windows_libusb(hIn, SuppressErrors) |
| | 916 | % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % |
| | 917 | % Temporary USB construction site for the RWTH - Mindstorms NXT Toolbox |
| | 918 | % http://www.mindstorms.rwth-aachen.de |
| | 919 | % |
| | 920 | % Alexander Behrens, 15.08.2008 |
| | 921 | % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % |
| | 922 | |
| | 923 | % Basic structure of this function: |
| | 924 | % Load library libusb, initialize it, get root bus object, loop through all |
| | 925 | % busses, for each bus loop through all devices, see if vendor and product id |
| | 926 | % match with lego NXT, try to open device, read serial no (which is = MAC), if it |
| | 927 | % matches, keep it open. then do basic USB device initialization (set config, |
| | 928 | % claim interface, reset device). dev should be ready then. |
| | 929 | |
| | 930 | %TODO There is still one big problem with Multi-NXT: If the first one that is |
| | 931 | %connected is also the first that was opened (and is now in use), the usb_open_dev |
| | 932 | %might fail when looping through all devs (since the dev is busy). Careful testing |
| | 933 | %is necessary to see wether opening an "NXT in use" fails, or if it is possible |
| | 934 | %and only fails when claiming its interface (I think that's the case actually, so |
| | 935 | %this would not be an issue after all). |
| | 936 | |
| | 937 | |
| | 938 | |
| | 939 | %% initialize etc... |
| | 940 | ID_VENDOR_LEGO = 1684; % hex2dec('0694'); |
| | 941 | ID_PRODUCT_NXT = 2; % hex2dec('0002'); |
| | 942 | |
| | 943 | LIBUSB_Configuration = 1; |
| | 944 | LIBUSB_Interface = 0; |
| | 945 | |
| | 946 | |
| | 947 | hOut = hIn; |
| | 948 | hOut.Connected(false); |
| | 949 | |
| | 950 | hOut.ConnectionTypeValue = 1; |
| | 951 | hOut.ConnectionTypeName = 'USB'; |
| | 952 | |
| | 953 | |
| | 954 | %% Load libusb library (only if necessary) |
| 748 | | % textOut(sprintf(' . opening device... ')); |
| 749 | | % DevHandle = calllib('libusb', 'usb_open', dev); |
| 750 | | % displayLibusbStatus(DevHandle); |
| 751 | | % |
| 752 | | % textOut(sprintf(' . reading serial number... ')); |
| 753 | | % % c-syntax from documentation so we know whats going on: |
| 754 | | % % int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen); |
| 755 | | % buffer = blanks(255); |
| 756 | | % [bytesRead newHandleOrWhat SerialNo] = calllib('libusb', 'usb_get_string_simple', DevHandle, dev.descriptor.iSerialNumber, buffer, length(buffer)); |
| 757 | | % displayLibusbStatus(bytesRead); |
| 758 | | % |
| 759 | | % SerialNo = strtrim(SerialNo); % just to be safe |
| 760 | | % textOut(sprintf(' . MAC = %s ', SerialNo)) |
| 761 | | % |
| 762 | | % % is it the right one? |
| 763 | | % if isempty(hIn.NXTMAC) || strcmpi(hIn.NXTMAC, SerialNo) |
| 764 | | % foundNXT = true; |
| 765 | | % textOut(sprintf('(MAC matches, this is our desired NXT)\n')); |
| 766 | | % break % search came to an end |
| 767 | | % else |
| 768 | | % foundNXT = false; |
| 769 | | % textOut(sprintf('(no match, not using this NXT)\n')); |
| 770 | | % % don't forget to close the opened NXT that didnt match... |
| 771 | | % textOut(sprintf(' . closing device... ')); |
| 772 | | % status = calllib('libusb', 'usb_close', DevHandle); |
| 773 | | % displayLibusbStatus(status); |
| 774 | | % end%if |
| | 1082 | textOut(sprintf(' . opening device... ')); |
| | 1083 | DevHandle = calllib('libusb0', 'usb_open', dev); |
| | 1084 | displayLibusbStatus(DevHandle); |
| | 1085 | |
| | 1086 | textOut(sprintf(' . reading serial number... ')); |
| | 1087 | % c-syntax from documentation so we know whats going on: |
| | 1088 | % int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen); |
| | 1089 | buffer = blanks(255); |
| | 1090 | [bytesRead newHandleOrWhat SerialNo] = calllib('libusb0', 'usb_get_string_simple', DevHandle, dev.descriptor.iSerialNumber, buffer, length(buffer)); |
| | 1091 | displayLibusbStatus(bytesRead); |
| | 1092 | |
| | 1093 | SerialNo = strtrim(SerialNo); % just to be safe |
| | 1094 | textOut(sprintf(' . MAC = %s ', SerialNo)) |
| | 1095 | |
| | 1096 | % is it the right one? |
| | 1097 | if isempty(hIn.NXTMAC) || strcmpi(hIn.NXTMAC, SerialNo) |
| | 1098 | foundNXT = true; |
| | 1099 | textOut(sprintf('(MAC matches, this is our desired NXT)\n')); |
| | 1100 | break % search came to an end |
| | 1101 | else |
| | 1102 | foundNXT = false; |
| | 1103 | textOut(sprintf('(no match, not using this NXT)\n')); |
| | 1104 | % don't forget to close the opened NXT that didnt match... |
| | 1105 | textOut(sprintf(' . closing device... ')); |
| | 1106 | status = calllib('libusb0', 'usb_close', DevHandle); |
| | 1107 | displayLibusbStatus(status); |
| | 1108 | end%if |
| 824 | | % %% NXT found, open connection |
| 825 | | % |
| 826 | | % % DevHandle is now the NXT we want |
| 827 | | % |
| 828 | | % % the following commands are standard procedure for USB devices, similar usage |
| 829 | | % % can be found in the open source packages Python_NXT and LEGO::NXT (Perl) |
| 830 | | % |
| 831 | | % % flag to remember |
| 832 | | % ErrorWhileOpening = false; |
| 833 | | % |
| 834 | | % % if the following fails with error -16, the NXT is probably already in |
| 835 | | % % use (opened in another handle!) |
| 836 | | % textOut(sprintf(' . setting active configuration... ')); |
| 837 | | % % somehow this doesn't work, so we use the hardcoded configuration 1! |
| 838 | | % %calllib('libusb', 'usb_set_configuration', DevHandle, dev.config.bConfigurationValue); |
| 839 | | % ret = calllib('libusb', 'usb_set_configuration', DevHandle, LIBUSB_Configuration); |
| | 1158 | %% NXT found, open connection |
| | 1159 | |
| | 1160 | % DevHandle is now the NXT we want |
| | 1161 | |
| | 1162 | % the following commands are standard procedure for USB devices, similar usage |
| | 1163 | % can be found in the open source packages Python_NXT and LEGO::NXT (Perl) |
| | 1164 | |
| | 1165 | % flag to remember |
| | 1166 | ErrorWhileOpening = false; |
| | 1167 | |
| | 1168 | % if the following fails with error -16, the NXT is probably already in |
| | 1169 | % use (opened in another handle!) |
| | 1170 | textOut(sprintf(' . setting active configuration... ')); |
| | 1171 | % somehow this doesn't work, so we use the hardcoded configuration 1! |
| | 1172 | %calllib('libusb', 'usb_set_configuration', DevHandle, dev.config.bConfigurationValue); |
| | 1173 | ret = calllib('libusb0', 'usb_set_configuration', DevHandle, LIBUSB_Configuration); |
| | 1174 | displayLibusbStatus(ret); |
| | 1175 | if (ret < 0) |
| | 1176 | ErrorWhileOpening = true; |
| | 1177 | end%if |
| | 1178 | |
| | 1179 | textOut(sprintf(' . claiming interface... ')); |
| | 1180 | % again, interface is hardcoded (compare implementations in python and |
| | 1181 | % perl, they do it the same way) |
| | 1182 | %calllib('libusb', 'usb_claim_interface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| | 1183 | ret = calllib('libusb0', 'usb_claim_interface', DevHandle, LIBUSB_Interface); |
| | 1184 | displayLibusbStatus(ret); |
| | 1185 | if (ret < 0) |
| | 1186 | ErrorWhileOpening = true; |
| | 1187 | end%if |
| | 1188 | |
| | 1189 | |
| | 1190 | % we don't need an alternative interface, whatever that is. |
| | 1191 | % but from debugging experience (also with Windows), you never know |
| | 1192 | % when you might need this, so we keep it in here! |
| | 1193 | |
| | 1194 | % disp(' . set altinterface') |
| | 1195 | % % %[int32, usb_dev_handlePtr] usb_set_altinterface(usb_dev_handlePtr, int32) |
| | 1196 | % ret = calllib('libusb', 'usb_set_altinterface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| | 1197 | % disp(sprintf('usb_strerror: %s', calllib('libusb', 'usb_strerror'))) |
| | 1198 | |
| | 1199 | % % is this necessary? but found it in perl and python versions... |
| | 1200 | % % the main point: never touch a running system |
| | 1201 | % textOut(sprintf(' . resetting device... ')); |
| | 1202 | % ret = calllib('libusb0', 'usb_reset', DevHandle); |
| 844 | | % |
| 845 | | % textOut(sprintf(' . claiming interface... ')); |
| 846 | | % % again, interface is hardcoded (compare implementations in python and |
| 847 | | % % perl, they do it the same way) |
| 848 | | % %calllib('libusb', 'usb_claim_interface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| 849 | | % ret = calllib('libusb', 'usb_claim_interface', DevHandle, LIBUSB_Interface); |
| 850 | | % displayLibusbStatus(ret); |
| 851 | | % if (ret < 0) |
| 852 | | % ErrorWhileOpening = true; |
| 853 | | % end%if |
| 854 | | % |
| 855 | | % |
| 856 | | % % we don't need an alternative interface, whatever that is. |
| 857 | | % % but from debugging experience (also with Windows), you never know |
| 858 | | % % when you might need this, so we keep it in here! |
| 859 | | % |
| 860 | | % % disp(' . set altinterface') |
| 861 | | % % % %[int32, usb_dev_handlePtr] usb_set_altinterface(usb_dev_handlePtr, int32) |
| 862 | | % % ret = calllib('libusb', 'usb_set_altinterface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| 863 | | % % disp(sprintf('usb_strerror: %s', calllib('libusb', 'usb_strerror'))) |
| 864 | | % |
| 865 | | % % is this necessary? but found it in perl and python versions... |
| 866 | | % % the main point: never touch a running system |
| 867 | | % textOut(sprintf(' . resetting device... ')); |
| 868 | | % ret = calllib('libusb', 'usb_reset', DevHandle); |
| 869 | | % displayLibusbStatus(ret); |
| 870 | | % if (ret < 0) |
| 871 | | % ErrorWhileOpening = true; |
| 872 | | % end%if |
| 873 | | % |
| 874 | | % % now it's time to decide: |
| 875 | | % if ErrorWhileOpening || isnumeric(DevHandle) |
| 876 | | % if ~SuppressErrors |
| 877 | | % errordlg('Something went wrong while opening the NXT device via USB (is it already open in another handle?). Please try to reboot the NXT or call COM_CloseNXT(''all'')!') |
| 878 | | % error('MATLAB:RWTHMindstormsNXT:USB:Linux:couldNotOpenNXT', 'Something went wrong while opening the NXT device via USB (is it already open in another handle?). Please try to reboot the NXT or call COM_CloseNXT(''all'')!') |
| 879 | | % else |
| 880 | | % % again, exit silently when no success |
| 881 | | % return |
| 882 | | % end%if |
| 883 | | % end%if |
| 884 | | % |
| 885 | | % % finally, we're good to go! |
| 886 | | % hOut.Handle = DevHandle; |
| 887 | | % hOut.NXTMAC = SerialNo; |
| 888 | | % |
| 889 | | % % and, important: |
| 890 | | % hOut.Connected(true); |
| 891 | | % |
| 892 | | % |
| 893 | | % %% clean up |
| 894 | | % |
| 895 | | % % is this needed? or will matlab destroy this private vars anyway after |
| 896 | | % % finishing this function? just to be sure with pointers... |
| 897 | | % clear p v bus dev newHandleOrWhat DevHandle |
| 898 | | %% NXT found, open connection |
| 899 | | |
| 900 | | % dev should now be our NXT |
| 901 | | |
| 902 | | disp('*** Opening USB connection') |
| 903 | | |
| 904 | | disp(' . getting device handle') |
| 905 | | DevHandle = calllib('libusb0', 'usb_open', dev); |
| 906 | | if isnumeric(DevHandle) |
| 907 | | ret = DevHandle; |
| | 1207 | |
| | 1208 | |
| | 1209 | % // Discard any data that is left in the buffer |
| | 1210 | % while (usb_bulk_read(nxt->hdl, 0x82, buf, sizeof(buf), 1) > 0) |
| | 1211 | % ; |
| | 1212 | disp(' . discarding any data') |
| | 1213 | buffer = char(uint8(blanks(64))); |
| | 1214 | buffer = uint8(zeros(64,1)); |
| | 1215 | ret = 1; |
| | 1216 | while ret > 0 |
| | 1217 | ret = calllib('libusb0', 'usb_bulk_read', DevHandle, uint8(130), buffer, 5, 1); |
| | 1218 | end |
| | 1219 | |
| | 1220 | % // try to set the stream I/O feature |
| | 1221 | % ret = usb_control_msg(nxt->hdl, 0x41, 0x3, 0, 0, NULL, 0, 1000); |
| | 1222 | % if (ret >= 0) |
| | 1223 | % { |
| | 1224 | % nxt->stream_mode = 1; |
| | 1225 | % } |
| | 1226 | disp(' . open stream modus') |
| | 1227 | buffer = char(uint8(blanks(64))); |
| | 1228 | ret = calllib('libusb0', 'usb_control_msg', DevHandle, 65, 3, 0, 0, buffer, 0, 1000); |
| 909 | | disp(getLibusbErrorString(ret)) |
| 910 | | end%if |
| 911 | | end%if |
| 912 | | |
| 913 | | disp(' . reading serial number:') |
| 914 | | % int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen); |
| 915 | | buffer = blanks(255); |
| 916 | | [bytesRead newHandleOrWhat SerialNo] = calllib('libusb0', 'usb_get_string_simple', DevHandle, dev.descriptor.iSerialNumber, buffer, length(buffer)); |
| 917 | | disp(sprintf(' %s', SerialNo)) |
| 918 | | |
| 919 | | disp(' . setting active configuration') |
| 920 | | %calllib(USBLIB, 'usb_set_configuration', DevHandle, dev.config.bConfigurationValue); |
| 921 | | ret = calllib('libusb0', 'usb_set_configuration', DevHandle, 1); |
| 922 | | if ret < 0 |
| 923 | | disp(getLibusbErrorString(ret)) |
| 924 | | end%if |
| 925 | | |
| 926 | | disp(' . claiming interface') |
| 927 | | %calllib(USBLIB, 'usb_claim_interface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| 928 | | ret = calllib('libusb0', 'usb_claim_interface', DevHandle, 0); |
| 929 | | if ret < 0 |
| 930 | | disp(getLibusbErrorString(ret)) |
| 931 | | end%if |
| 932 | | |
| 933 | | |
| 934 | | % disp(' . set altinterface') |
| 935 | | % % %[int32, usb_dev_handlePtr] usb_set_altinterface(usb_dev_handlePtr, int32) |
| 936 | | % ret = calllib('libusb0', 'usb_set_altinterface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); |
| 937 | | % disp(sprintf('usb_strerror: %s', calllib('libusb0', 'usb_strerror'))) |
| 938 | | % |
| 939 | | |
| 940 | | % disp(' . resetting device') |
| 941 | | % ret = calllib(USBLIB, 'usb_reset', DevHandle); |
| 942 | | % if ret < 0 |
| 943 | | % disp(getLibusbErrorString(ret)) |
| 944 | | % end%if |
| 945 | | |
| 946 | | % // Discard any data that is left in the buffer |
| 947 | | % while (usb_bulk_read(nxt->hdl, 0x82, buf, sizeof(buf), 1) > 0) |
| 948 | | % ; |
| 949 | | disp(' . discarding any data') |
| 950 | | buffer = char(uint8(blanks(64))); |
| 951 | | buffer = uint8(zeros(64,1)); |
| 952 | | ret = 1; |
| 953 | | while ret > 0 |
| 954 | | ret = calllib('libusb0', 'usb_bulk_read', DevHandle, uint8(130), buffer, 5, 1); |
| 955 | | end |
| 956 | | |
| 957 | | % // try to set the stream I/O feature |
| 958 | | % ret = usb_control_msg(nxt->hdl, 0x41, 0x3, 0, 0, NULL, 0, 1000); |
| 959 | | % if (ret >= 0) |
| 960 | | % { |
| 961 | | % nxt->stream_mode = 1; |
| 962 | | % } |
| 963 | | disp(' . open stream modus') |
| 964 | | buffer = char(uint8(blanks(64))); |
| 965 | | ret = calllib('libusb0', 'usb_control_msg', DevHandle, 65, 3, 0, 0, buffer, 0, 1000); |
| 966 | | if ret < 0 |
| 967 | | msg = ['Libusb error ' num2str(ret) ' while open stream mode: ' getLibusbErrorString(ret)]; |
| 968 | | warning('MATLAB:RWTHMindstormsNXT:USB:Linux:libusbErrorWhileOpenStreamMode', msg); |
| 969 | | end%if |
| 970 | | |
| 971 | | hNXT = DevHandle; |
| 972 | | |
| 973 | | % finally, we're good to go! |
| | 1230 | msg = ['Libusb error ' num2str(ret) ' while open stream mode: ' getLibusbErrorString(ret)]; |
| | 1231 | warning('MATLAB:RWTHMindstormsNXT:USB:Linux:libusbErrorWhileOpenStreamMode', msg); |
| | 1232 | end%if |
| | 1233 | |
| | 1234 | |
| | 1235 | |
| | 1236 | % now it's time to decide: |
| | 1237 | if ErrorWhileOpening || isnumeric(DevHandle) |
| | 1238 | if ~SuppressErrors |
| | 1239 | errordlg('Something went wrong while opening the NXT device via USB (is it already open in another handle?). Please try to reboot the NXT or call COM_CloseNXT(''all'')!') |
| | 1240 | error('MATLAB:RWTHMindstormsNXT:USB:Linux:couldNotOpenNXT', 'Something went wrong while opening the NXT device via USB (is it already open in another handle?). Please try to reboot the NXT or call COM_CloseNXT(''all'')!') |
| | 1241 | else |
| | 1242 | % again, exit silently when no success |
| | 1243 | return |
| | 1244 | end%if |
| | 1245 | end%if |
| | 1246 | |
| | 1247 | % finally, we're good to go! |