Changeset 247
- Timestamp:
- 09/03/08 15:32:38 (5 years ago)
- Location:
- branches/telle/RWTHMindstormsNXT
- Files:
-
- 8 modified
- 2 copied
-
COM_CloseNXT.m (modified) (6 diffs)
-
COM_CollectPacket.m (modified) (3 diffs)
-
COM_OpenNXTEx.m (modified) (18 diffs)
-
COM_SendPacket.m (modified) (4 diffs)
-
ChooseLibrary.m (copied) (copied from branches/behrens/mfiles/ChooseLibrary.m)
-
ResetMotorAngle.m (modified) (1 diff)
-
private/checkHandleStruct.m (modified) (1 diff)
-
private/createHandleStruct.m (modified) (1 diff)
-
private/getLibusbErrorString.m (modified) (3 diffs)
-
private/libusb_win_proto.m (copied) (copied from branches/behrens/mfiles/private/libusb_win_proto.m)
Legend:
- Unmodified
- Added
- Removed
-
branches/telle/RWTHMindstormsNXT/COM_CloseNXT.m
r201 r247 63 63 % 64 64 % Signature 65 % Author: Linus Atorf (see AUTHORS)66 % Date: 2008/0 7/0965 % Author: Linus Atorf, Alexander Behrens (see AUTHORS) 66 % Date: 2008/08/15 67 67 % Copyright: 2007-2008, RWTH Aachen University 68 68 % … … 137 137 textOut(sprintf('Closing handle (USB) with MAC = %s (handle was %.1f minutes old)\n', h.NXTMAC, etime(clock, h.CreationTime) / 60)); 138 138 if h.OSValue == 1 % win 139 USB_CloseHandle_Windows(h); 139 switch (h.ConnectionLibraryValue) 140 case 1 % fantom library 141 USB_CloseHandle_Windows(h); 142 case 2 % libusb library 143 USB_CloseHandle_libusb(h); 144 otherwise 145 end 140 146 else % linux 141 USB_CloseHandle_ Linux(h);147 USB_CloseHandle_libusb(h); 142 148 end%if 143 149 else % BT … … 360 366 361 367 368 %% --- FUNCTION USB_CloseHandle_libusb 369 function USB_CloseHandle_libusb(h) 370 371 LIBUSB_Interface = 0; 372 373 374 if h.ConnectionLibraryValue == 1 % fantom library 375 % // Send EOF marker, a zero length packet 376 % usb_bulk_write(nxt->hdl, 0x1, buf, 0, 1000); 377 buffer = uint8(zeros(64,1)); 378 textOut(sprintf(' - Sending a zero length packet... ')); 379 ret = calllib(h.ConnectionLibraryName, 'usb_bulk_read', h.Handle, 1, buffer, LIBUSB_Interface, 1000); 380 displayLibusbStatus(ret, h); 381 382 % // Turn off stream mode 383 % usb_control_msg(nxt->hdl, 0x41, 0x1, 0, 0, NULL, 0, 5000); 384 buffer = blanks(64); 385 textOut(sprintf(' - Turn off the stream mode... ')); 386 ret = calllib(h.ConnectionLibraryName, 'usb_control_msg', h.Handle, 65, 1, 0, 0, buffer, LIBUSB_Interface, 5000); 387 displayLibusbStatus(ret, h); 388 389 % // Discard any data that is left in the buffer 390 % while (usb_bulk_read(nxt->hdl, 0x82, buf, sizeof(buf), 1) > 0) 391 % ; 392 textOut(sprintf(' - Discard any data that is left in the buffer... ')); 393 ret = 1; 394 while ret > 0 395 buffer = uint8(zeros(64,1)); 396 ret = calllib(h.ConnectionLibraryName, 'usb_bulk_read', h.Handle, 130, buffer, 64, 1); 397 end 398 end % end if fantom 399 400 401 % interface number is hardcoded, should it be that way? 402 textOut(sprintf(' - Releasing interface... ')); 403 ret = calllib(h.ConnectionLibraryName, 'usb_release_interface', h.Handle, LIBUSB_Interface); 404 displayLibusbStatus(ret, h); 405 406 407 textOut(sprintf(' - Closing device... ')); 408 ret = calllib(h.ConnectionLibraryName, 'usb_close', h.Handle); 409 displayLibusbStatus(ret, h); 410 411 end%function 412 413 414 %% --- FUNCTION USB_CloseHandle_Windows_libusb 415 function USB_CloseHandle_Windows_libusb(h) 416 417 LIBUSB_Interface = 0; 418 419 420 % // Send EOF marker, a zero length packet 421 % usb_bulk_write(nxt->hdl, 0x1, buf, 0, 1000); 422 buffer = uint8(zeros(64,1)); 423 textOut(sprintf(' - Sending a zero length packet... ')); 424 ret = calllib('libusb0', 'usb_bulk_read', h.Handle, 1, buffer, LIBUSB_Interface, 1000); 425 displayLibusbStatus(ret, h); 426 427 % // Turn off stream mode 428 % usb_control_msg(nxt->hdl, 0x41, 0x1, 0, 0, NULL, 0, 5000); 429 buffer = blanks(64); 430 textOut(sprintf(' - Turn off the stream mode... ')); 431 ret = calllib('libusb0', 'usb_control_msg', h.Handle, 65, 1, 0, 0, buffer, LIBUSB_Interface, 5000); 432 displayLibusbStatus(ret, h); 433 434 % // Discard any data that is left in the buffer 435 % while (usb_bulk_read(nxt->hdl, 0x82, buf, sizeof(buf), 1) > 0) 436 % ; 437 ret = 1; 438 while ret > 0 439 buffer = uint8(zeros(64,1)); 440 ret = calllib('libusb0', 'usb_bulk_read', h.Handle, 130, buffer, 64, 1); 441 end 442 443 444 % interface number is hardcoded, should it be that way? 445 textOut(sprintf(' - Releasing interface... ')); 446 ret = calllib('libusb0', 'usb_release_interface', h.Handle, LIBUSB_Interface); 447 displayLibusbStatus(ret, h); 448 449 450 textOut(sprintf(' - Closing device... ')); 451 ret = calllib('libusb0', 'usb_close', h.Handle); 452 displayLibusbStatus(ret, h); 453 454 end%function 455 362 456 363 457 %% --- FUNCTION USB_CloseHandle_Linux … … 369 463 textOut(sprintf(' - Releasing interface... ')); 370 464 ret = calllib('libusb', 'usb_release_interface', h.Handle, LIBUSB_Interface); 371 displayLibusbStatus(ret );465 displayLibusbStatus(ret, h); 372 466 373 467 374 468 textOut(sprintf(' - Closing device... ')); 375 469 ret = calllib('libusb', 'usb_close', h.Handle); 376 displayLibusbStatus(ret );470 displayLibusbStatus(ret, h); 377 471 378 472 % we don't unload libusb now, but if we did: … … 386 480 387 481 388 %% --- FUNCTION displayUSBWinStatus (status)482 %% --- FUNCTION displayUSBWinStatus 389 483 function displayUSBWinStatus(status) 390 484 if status … … 397 491 398 492 399 %% --- FUNCTION displayLibusbStatus (status)400 function displayLibusbStatus(status )493 %% --- FUNCTION displayLibusbStatus 494 function displayLibusbStatus(status, h) 401 495 if isnumeric(status) && (status < 0) 402 496 textOut(sprintf('failed.\n')); 403 textOut(sprintf(['Libusb error ' num2str(status) ': ' getLibusbErrorString(status ) '\n']))497 textOut(sprintf(['Libusb error ' num2str(status) ': ' getLibusbErrorString(status, h) '\n'])) 404 498 else 405 499 textOut(sprintf('done.\n')); -
branches/telle/RWTHMindstormsNXT/COM_CollectPacket.m
r201 r247 92 92 if handle.ConnectionTypeValue == 1 % USB 93 93 if handle.OSValue == 1 % Windows 94 [type cmd statusbyte content] = USB_CollectPacket_Windows(handle); 94 switch (handle.ConnectionLibraryValue) 95 case 1 % fantom library 96 [type cmd statusbyte content] = USB_CollectPacket_Windows(handle); 97 case 2 % libusb library 98 [type cmd statusbyte content] = USB_CollectPacket_libusb(handle); 99 otherwise 100 end 95 101 else % Linux 96 [type cmd statusbyte content] = USB_CollectPacket_ Linux(handle);102 [type cmd statusbyte content] = USB_CollectPacket_libusb(handle); 97 103 end%if 98 104 else % BT … … 395 401 396 402 397 %% --- FUNCTION USB_CollectPacket_ Linux398 function [type cmd statusbyte content] = USB_CollectPacket_ Linux(h)403 %% --- FUNCTION USB_CollectPacket_libusb 404 function [type cmd statusbyte content] = USB_CollectPacket_libusb(h) 399 405 400 406 %% Libusb params … … 427 433 428 434 %[ret something reply] = calllib('libusb', 'usb_bulk_read', hNXT, receivingEndpoint, char(buffer'), length(buffer), timeout); 435 [status something reply] = calllib(h.ConnectionLibraryName, 'usb_bulk_read', h.Handle, receivingEndpoint, buffer, length(buffer), timeout); 436 if status < 0 437 msg = ['Libusb error ' num2str(status) ' while receiving data: ' getLibusbErrorString(status, h)]; 438 warning('MATLAB:RWTHMindstormsNXT:USB:libusbErrorWhileReceivingData', msg); 439 end%if 440 441 442 %% Interpret content 443 444 if length(reply) < 2 445 % basically we've lost, nothing we can do anymore... 446 warning('MATLAB:RWTHMindstormsNXT:USB:receivedPacketIncomplete', 'The received packet does not contain enough data. Current packet seems incomplete...') 447 return 448 end%if 449 450 cmd = reply(2); 451 len = getReplyLengthFromCmdByte(cmd) + 1; 452 453 if length(reply) < len 454 % this won't end good, but let's try to continue 455 len = length(reply); 456 warning('MATLAB:RWTHMindstormsNXT:USB:receivedPacketIncomplete', 'The received packet does not contain enough data. Current packet seems incomplete...') 457 end%if 458 459 % extract packet from reply (which might be padded) 460 packet = reply(1:len); 461 462 % statistics 463 h.PacketsReceived(1); 464 h.BytesReceived(len); 465 466 467 %% Interpret content 468 469 % note that we return uint8, NOT double! 470 % this is what the other functions (BT, fantom) do as well! 471 472 type = packet(1); 473 cmd = packet(2); 474 statusbyte = packet(3); 475 476 content = packet(4:end); 477 478 end%function 479 480 481 %% --- FUNCTION USB_CollectPacket_Linux 482 function [type cmd statusbyte content] = USB_CollectPacket_Linux(h) 483 484 %% Libusb params 485 %sendingEndpoint = 1; 486 receivingEndpoint = 130; % hex2dec('82') 487 timeout = 1000; % ms 488 maxPacketSize = 64; 489 490 491 %% Initalize Variables 492 type = 0; cmd = 0; statusbyte = 1; content = []; 493 494 %% Retrieve data 495 % Various tests were necessary to find out how exactly data retrieval works 496 % with usb_bulk_read from libusb in MATLAB. The problem is that this libusb 497 % function uses a zero-terminated "string" (char-array) as data type for real 498 % binary data. Now MATLAB is very nice and converts this for us, back to a 499 % real string data type in MATLAB. But, only until the first 0 gets 500 % discovered, after all it's a zero-terminated string. So, after the first 0 501 % inside the packet, we don't get any data. I've worked around this at the 502 % moment by changing the datatype in the original .h header file, which is the 503 % template / master for the prototype m-file. 504 505 %buffer = blanks(maxPacketSize); 506 %buffer = uint8(zeros(getReplyLengthFromCmdByte(packet(2)), 1)); 507 %buffer = [blanks(maxPacketSize - 1) 0]; 508 %buffer = uint8(zeros(maxPacketSize, 1)); 509 buffer = uint8(zeros(maxPacketSize, 1)); 510 511 512 %[ret something reply] = calllib('libusb', 'usb_bulk_read', hNXT, receivingEndpoint, char(buffer'), length(buffer), timeout); 429 513 [status something reply] = calllib('libusb', 'usb_bulk_read', h.Handle, receivingEndpoint, buffer, length(buffer), timeout); 430 514 if status < 0 431 msg = ['Libusb error ' num2str(status) ' while receiving data: ' getLibusbErrorString(status )];515 msg = ['Libusb error ' num2str(status) ' while receiving data: ' getLibusbErrorString(status, h)]; 432 516 warning('MATLAB:RWTHMindstormsNXT:USB:Windows:libusbErrorWhileReceivingData', msg); 433 517 end%if -
branches/telle/RWTHMindstormsNXT/COM_OpenNXTEx.m
r201 r247 3 3 % 4 4 % Syntax 5 % handle = COM_OpenNXTEx('USB', UseThisNXTMAC)6 % 7 % handle = COM_OpenNXTEx('Bluetooth', UseThisNXTMAC, inifilename, 'check')8 % 9 % handle = COM_OpenNXTEx('Any', UseThisNXTMAC, inifilename, 'check')5 % |handle = COM_OpenNXTEx('USB', UseThisNXTMAC)| 6 % 7 % |handle = COM_OpenNXTEx('Bluetooth', UseThisNXTMAC, inifilename, 'check')| 8 % 9 % |handle = COM_OpenNXTEx('Any', UseThisNXTMAC, inifilename, 'check')| 10 10 % 11 11 % Description 12 12 % This function establishes a connection to an NXT brick and returns the 13 13 % handle structure that has to be used with NXT-functions (you can call 14 % COM_SetDefaultNXT(handle)afterwards for easier use).14 % |COM_SetDefaultNXT(handle)| afterwards for easier use). 15 15 % 16 16 % For a more convenient way to open an NXT handle with less parameters, the 17 % function COM_OpenNXTis provided.17 % function |COM_OpenNXT| is provided. 18 18 % 19 19 % Different types of connection modes are supported. In all modes, you can 20 % set UseThisNXTMACto a string with the NXT's MAC address (serial number).20 % set |UseThisNXTMAC| to a string with the NXT's MAC address (serial number). 21 21 % A connection will then only be estabslished to a matching NXT brick. This can be 22 22 % useful for programs with multiple NXT devices. Set it to an empty string 23 % ''to use any NXT available (usually the first one found).23 % |''| to use any NXT available (usually the first one found). 24 24 % 25 25 % 26 % handle = COM_OpenNXTEx('USB', UseThisNXTMAC)26 % |handle = COM_OpenNXTEx('USB', UseThisNXTMAC)| 27 27 % This will try to open a connection via USB. Device drivers (Fantom on 28 28 % Windows, libusb on Linux) have to be installed. 29 29 % 30 30 % 31 % handle = COM_OpenNXTEx('Bluetooth', UseThisNXTMAC, inifilename, 'check')31 % |handle = COM_OpenNXTEx('Bluetooth', UseThisNXTMAC, inifilename, 'check')| 32 32 % Uses Bluetooth as communication method. A valid inifile containing 33 % parameters like the COM-Port has to be specified in inifilename. The34 % optional paramter 'check'can be omitted (it will nake sure that the33 % parameters like the COM-Port has to be specified in |inifilename|. The 34 % optional paramter |'check'| can be omitted (it will nake sure that the 35 35 % new Bluetooth connection is working bi-directional). Leave it out if 36 36 % your hardware does only support sending data (depends on the Bluetooth … … 39 39 % motor control). 40 40 % To create an inifile with Bluetooth settings, the function 41 % COM_MakeBTConfigFileis available.41 % |COM_MakeBTConfigFile| is available. 42 42 % 43 % Note that as of right now, the parameter UseThisNXTMACwill be43 % Note that as of right now, the parameter |UseThisNXTMAC| will be 44 44 % ignored for Bluetooth connections until implemented in a future version. 45 45 % 46 46 % 47 % handle = COM_OpenNXTEx('Any', UseThisNXTMAC, inifilename, 'check')47 % |handle = COM_OpenNXTEx('Any', UseThisNXTMAC, inifilename, 'check')| 48 48 % This syntax combines the two parameter settings from above. 49 % inifilename has to be given, the optional 'check'can be omitted.49 % |inifilename| has to be given, the optional |'check'| can be omitted. 50 50 % The function will try to locate an NXT device on the USB bus first. If 51 51 % this fails for some reason (no USB connection to the NXT available, no … … 58 58 % 59 59 % 60 % Limitations of COM_CloseNXT61 % If you call COM_CloseNXT('all') after a clear allcommand has been60 % Limitations of |COM_CloseNXT| 61 % If you call |COM_CloseNXT('all')| after a |clear all| command has been 62 62 % issued, the function will not be able to close all remaining open USB 63 63 % handles, since they have been cleared out of memory. This is a problem 64 64 % on Linux systems. You will not be able to use the NXT device without 65 65 % rebooting it. 66 % Solution: Either use only clearin your programs, or you use the67 % COM_CloseNXT('all') statement before clear all.66 % Solution: Either use only |clear| in your programs, or you use the 67 % |COM_CloseNXT('all')| statement before |clear all|. 68 68 % The best way however is to track your handles carefully and close them 69 % manually ( COM_CloseNXT(handle)) before exiting whenever possible!%69 % manually (|COM_CloseNXT(handle)|) before exiting whenever possible!% 70 70 % 71 71 % 72 72 % Example 73 % myNXT = COM_OpenNXTEx('Any', '001612345678', 'bluetooth.ini', 'check');74 % % This will connect to an NXT device with the MAC/serial number 001612345678,75 % % first trying via USB. If this fails (no drivers installed or no matching USB76 % % device found), a connection via Bluetooth will be established, using77 % % the paramters found in the given config file.73 %+ myNXT = COM_OpenNXTEx('Any', '001612345678', 'bluetooth.ini', 'check'); 74 %+ % This will connect to an NXT device with the MAC/serial number 001612345678, 75 %+ % first trying via USB. If this fails (no drivers installed or no matching USB 76 %+ % device found), a connection via Bluetooth will be established, using 77 %+ % the paramters found in the given config file. 78 78 % 79 79 % … … 85 85 % Copyright: 2007-2008, RWTH Aachen University 86 86 % 87 ; %#ok<NOSEM> 87 88 % 88 89 % *********************************************************************************************** … … 244 245 % handle.IniFilename = h.IniFilename; 245 246 % handle.ComPort = h.ComPort; 246 % handle.BaudRate = h.BaudRate;247 % handle.DataBits = h.DataBits;248 % handle.Timeout = h.Timeout;247 % handle.BaudRate = h.BaudRate; 248 % handle.DataBits = h.DataBits; 249 % handle.Timeout = h.Timeout; 249 250 % 250 % handle.SendSendPause = h.SendSendPause;251 % handle.SendSendPause = h.SendSendPause; 251 252 % handle.SendReceivePause = h.SendReceivePause; 252 253 % 253 254 % handle.NXTMAC = h.NXTMAC; 254 % handle.CreationTime = h.CreationTime;255 % handle.CreationTime = h.CreationTime; 255 256 % handle.Index = h.Index; 256 257 … … 390 391 391 392 if hIn.OSValue == 1 392 hOut = USB_OpenHandle_Windows(hIn, SuppressErrors); 393 394 hIn = ChooseLibrary(hIn); 395 396 switch (hIn.ConnectionLibraryValue) 397 case 1 % fantom library 398 hOut = USB_OpenHandle_Windows(hIn, SuppressErrors); 399 case 2 % libusb library 400 hOut = USB_OpenHandle_libusb(hIn, SuppressErrors); 401 otherwise 402 % use libusb0 as default 403 unknownLibrary = hIn.ConnectionLibraryValue; 404 if isnan(unknownLibrary) 405 unknownLibrary = num2str(unknownLibrary); 406 end 407 hIn.ConnectionLibraryName = 'libusb0'; 408 hIn.ConnectionLibraryValue = 2; 409 msg = ['Unkown library ' unknownLibrary '. Use as default: ' hIn.ConnectionLibraryName]; 410 warning('MATLAB:RWTHMindstormsNXT:USB:UnknownNXTDriverLibrary', msg); 411 hOut = USB_OpenHandle_libusb(hIn, SuppressErrors); 412 end 413 % hOut = USB_OpenHandle_Windows(hIn, SuppressErrors); 414 % hOut = USB_OpenHandle_libusb(hIn, false); 393 415 elseif hIn.OSValue == 2 394 hOut = USB_OpenHandle_ Linux(hIn, SuppressErrors);416 hOut = USB_OpenHandle_libusb(hIn, SuppressErrors); 395 417 end%if 396 418 … … 427 449 hOut.ConnectionTypeValue = 1; 428 450 hOut.ConnectionTypeName = 'USB'; 451 429 452 430 453 … … 447 470 textOut(sprintf(' - Library "fantom" already loaded.\n')); 448 471 end%if 449 472 473 hOut.ConnectionLibraryName = 'fantom'; % String, 'fantom' or 'libusb' / 'libusb0' 474 hOut.ConnectionLibraryValue = 1; % fantom = 1, libusb = 2 450 475 451 476 … … 567 592 568 593 569 %% --- FUNCTION displayLibusbStatus (status)594 %% --- FUNCTION displayLibusbStatus 570 595 % little convenient helper to save some lines of code with textOut 571 function displayLibusbStatus(status )596 function displayLibusbStatus(status, h) 572 597 % little convenient helper to save some lines of code with textOut 573 598 if isnumeric(status) && (status < 0) 574 599 textOut(sprintf('failed.\n')); 575 textOut(sprintf(['Libusb error ' num2str(status) ': ' getLibusbErrorString(status ) '\n']))600 textOut(sprintf(['Libusb error ' num2str(status) ': ' getLibusbErrorString(status, h) '\n'])) 576 601 else 577 602 textOut(sprintf('done.\n')); … … 657 682 textOut(sprintf(' . finding busses... ')) 658 683 ret = calllib('libusb', 'usb_find_busses'); 659 displayLibusbStatus(ret );684 displayLibusbStatus(ret, hIn); 660 685 661 686 textOut(sprintf(' . finding devices... ')) 662 687 ret = calllib('libusb', 'usb_find_devices'); 663 displayLibusbStatus(ret );688 displayLibusbStatus(ret, hIn); 664 689 665 690 %% Get main root bus … … 668 693 p = calllib('libusb', 'usb_get_busses'); 669 694 bus = libstruct('usb_bus', p); 670 displayLibusbStatus(p );695 displayLibusbStatus(p, hIn); 671 696 672 697 … … 747 772 textOut(sprintf(' . opening device... ')); 748 773 DevHandle = calllib('libusb', 'usb_open', dev); 749 displayLibusbStatus(DevHandle );774 displayLibusbStatus(DevHandle, hIn); 750 775 751 776 textOut(sprintf(' . reading serial number... ')); … … 754 779 buffer = blanks(255); 755 780 [bytesRead newHandleOrWhat SerialNo] = calllib('libusb', 'usb_get_string_simple', DevHandle, dev.descriptor.iSerialNumber, buffer, length(buffer)); 756 displayLibusbStatus(bytesRead );781 displayLibusbStatus(bytesRead, hIn); 757 782 758 783 SerialNo = strtrim(SerialNo); % just to be safe … … 770 795 textOut(sprintf(' . closing device... ')); 771 796 status = calllib('libusb', 'usb_close', DevHandle); 772 displayLibusbStatus(status );797 displayLibusbStatus(status, hIn); 773 798 end%if 774 799 … … 837 862 %calllib('libusb', 'usb_set_configuration', DevHandle, dev.config.bConfigurationValue); 838 863 ret = calllib('libusb', 'usb_set_configuration', DevHandle, LIBUSB_Configuration); 839 displayLibusbStatus(ret );864 displayLibusbStatus(ret, hIn); 840 865 if (ret < 0) 841 866 ErrorWhileOpening = true; … … 847 872 %calllib('libusb', 'usb_claim_interface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); 848 873 ret = calllib('libusb', 'usb_claim_interface', DevHandle, LIBUSB_Interface); 849 displayLibusbStatus(ret );874 displayLibusbStatus(ret, hIn); 850 875 if (ret < 0) 851 876 ErrorWhileOpening = true; … … 866 891 textOut(sprintf(' . resetting device... ')); 867 892 ret = calllib('libusb', 'usb_reset', DevHandle); 868 displayLibusbStatus(ret );893 displayLibusbStatus(ret, hIn); 869 894 if (ret < 0) 870 895 ErrorWhileOpening = true; … … 899 924 end%function 900 925 926 927 %% --- FUNCTION USB_OpenHandle_libusb 928 function hOut = USB_OpenHandle_libusb(hIn, SuppressErrors) 929 % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 930 % Temporary USB construction site for the RWTH - Mindstorms NXT Toolbox 931 % http://www.mindstorms.rwth-aachen.de 932 % 933 % Linus Atorf, Alexander Behrens, 15.08.2008 934 % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 935 936 % Basic structure of this function: 937 % Load library libusb, initialize it, get root bus object, loop through all 938 % busses, for each bus loop through all devices, see if vendor and product id 939 % match with lego NXT, try to open device, read serial no (which is = MAC), if it 940 % matches, keep it open. then do basic USB device initialization (set config, 941 % claim interface, reset device). dev should be ready then. 942 943 %TODO There is still one big problem with Multi-NXT: If the first one that is 944 %connected is also the first that was opened (and is now in use), the usb_open_dev 945 %might fail when looping through all devs (since the dev is busy). Careful testing 946 %is necessary to see wether opening an "NXT in use" fails, or if it is possible 947 %and only fails when claiming its interface (I think that's the case actually, so 948 %this would not be an issue after all). 949 950 951 952 %% initialize etc... 953 ID_VENDOR_LEGO = 1684; % hex2dec('0694'); 954 ID_PRODUCT_NXT = 2; % hex2dec('0002'); 955 956 LIBUSB_Configuration = 1; 957 LIBUSB_Interface = 0; 958 959 960 hOut = hIn; 961 hOut.Connected(false); 962 963 hOut.ConnectionTypeValue = 1; 964 hOut.ConnectionTypeName = 'USB'; 965 966 967 %% Load libusb library (only if necessary) 968 if ~libisloaded(hIn.ConnectionLibraryName) 969 textOut(sprintf(' - Loading library "%s"... ', hIn.ConnectionLibraryName)); 970 try 971 % use "our" wrapper file... 972 loadlibrary(hIn.ConnectionLibraryName, @libusb_win_proto) 973 textOut(sprintf('done.\n')); 974 catch 975 textOut(sprintf('failed.\n')); 976 if ~SuppressErrors 977 error('MATLAB:RWTHMindstormsNXT:USB:couldNotLoadLibraryLibusb', 'The "libusb" library could not be loaded. Make sure it is installed and paths are set correctly!') 978 else 979 return 980 end%if 981 end%try 982 else 983 textOut(sprintf(' - Library "%s" already loaded.\n',hIn.ConnectionLibraryName)); 984 end%if 985 986 textOut(sprintf(' - Initializing and browsing USB busses\n')); 987 988 %% Init libusb 989 textOut(sprintf(' . initializing %s.\n',hIn.ConnectionLibraryName)) 990 calllib(hIn.ConnectionLibraryName, 'usb_init'); 991 992 % > - insert usb_set_debug(255) in pyusb.c right behind usb_init() 993 % > - recompile and reinstall the module 994 % > - hook up DebugView from www.sysinternals.com 995 % > - rerun your application 996 % so if we want debug mode, this needs to be uncommented! 997 %calllib('libusb', 'usb_set_debug', 255); 998 999 1000 % these functions return the number of changes made to the busses and 1001 % devices since last call, don't neet it... 1002 textOut(sprintf(' . finding busses... ')) 1003 ret = calllib(hIn.ConnectionLibraryName, 'usb_find_busses'); 1004 displayLibusbStatus(ret, hIn); 1005 1006 textOut(sprintf(' . finding devices... ')) 1007 ret = calllib(hIn.ConnectionLibraryName, 'usb_find_devices'); 1008 displayLibusbStatus(ret, hIn); 1009 1010 %% Get main root bus 1011 1012 textOut(sprintf(' . getting root bus object... ')) 1013 p = calllib(hIn.ConnectionLibraryName, 'usb_get_busses'); 1014 bus = libstruct('usb_bus', p); 1015 displayLibusbStatus(p, hIn); 1016 1017 1018 textOut(sprintf(' - Enumerating busses and devices\n')); 1019 1020 %% Cycle through all busses and devices: enumerate... 1021 foundNXT = false; 1022 while ~foundNXT % for all busses 1023 1024 % we want to save some debug-lines (already got too many), so we don't 1025 % care what USB devices the user has. remove comment for advanced debug 1026 % mode 1027 %textOut(sprintf(' . current bus: %s\n', strtrim(char(bus.dirname)))) 1028 1029 dev = libstruct('usb_device', bus.devices); 1030 1031 % ------------------------------------- 1032 while true % for all devices! sorry for endless-loop, but we break later down 1033 1034 % if no devs at all 1035 if isempty(dev) 1036 break 1037 end%if 1038 1039 1040 % we want to save some debug-lines (already got too many), so we don't 1041 % care what USB devices the user has. remove comment for advanced debug 1042 % mode 1043 %textOut(sprintf(' . current device: %s\n', strtrim(char(dev.filename)))) 1044 1045 1046 % try a little string reading.... 1047 1048 % THIS DOESN'T WORK UNDER LINUX MOST OF THE TIME 1049 % APPARENTLY, WE CANNOT OPEN ALL PRESENT DEVICES 1050 % Since we don't want to try to open a device now, we keep this 1051 % working code (at least for public devices on Linux and for 1052 % alle devices on Windows) commented, maybe someone else can 1053 % use it to improve this function later on... 1054 % It's debug-info only anyway 1055 1056 1057 if hIn.OSValue == 1 % windows 1058 % open device to get a handle 1059 DevHandle = calllib(hIn.ConnectionLibraryName, 'usb_open', dev); 1060 1061 % now the string stuff 1062 buffer = blanks(255); 1063 % we don't need a real buffer or pointer, matlab seems to do this 1064 % for us, so we pass that buffer variable, without really needing 1065 % it. it seems like matlab "knows" how strings get written by 1066 % reference and returns the new value from the function. if you 1067 % compare the matlab-returnvalues of usb_get_string_simple using 1068 % libfunctionsview libusb, you'll find that they don't match whats 1069 % written inside usb.h. very nice and handy, thank you matlab :-) 1070 %pBuffer = libpointer('cstring', buffer); not needed, see above 1071 1072 % now the actual call: 1073 [bytesRead newHandleOrWhat ManufacturerName] = calllib(hIn.ConnectionLibraryName, 'usb_get_string_simple', ... 1074 DevHandle, dev.descriptor.iManufacturer, buffer, length(buffer)); 1075 % again: 1076 [bytesRead newHandleOrWhat ProductName] = calllib(hIn.ConnectionLibraryName, 'usb_get_string_simple', ... 1077 DevHandle, dev.descriptor.iProduct, buffer, length(buffer)); 1078 1079 disp(sprintf(' Manufacturer: %s', ManufacturerName)) 1080 disp(sprintf(' Product: %s', ProductName)) 1081 1082 % close device again 1083 ret = calllib(hIn.ConnectionLibraryName, 'usb_close', DevHandle); 1084 displayLibusbStatus(ret, hIn); 1085 clear DevHandle %better doing it now than forgetting it later 1086 end % end if windows 1087 1088 1089 % note at this point that we only try to open a device if it's one 1090 % from LEGO! 1091 1092 % check if it's LEGO and NXT 1093 if (dev.descriptor.idVendor == ID_VENDOR_LEGO) && (dev.descriptor.idProduct == ID_PRODUCT_NXT) 1094 textOut(sprintf(' . found NXT device\n')); 1095 1096 textOut(sprintf(' . opening device... ')); 1097 DevHandle = calllib(hIn.ConnectionLibraryName, 'usb_open', dev); 1098 displayLibusbStatus(DevHandle, hIn); 1099 1100 textOut(sprintf(' . reading serial number... ')); 1101 % c-syntax from documentation so we know whats going on: 1102 % int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen); 1103 buffer = blanks(255); 1104 [bytesRead newHandleOrWhat SerialNo] = calllib(hIn.ConnectionLibraryName, 'usb_get_string_simple', DevHandle, dev.descriptor.iSerialNumber, buffer, length(buffer)); 1105 displayLibusbStatus(bytesRead, hIn); 1106 1107 SerialNo = strtrim(SerialNo); % just to be safe 1108 textOut(sprintf(' . MAC = %s ', SerialNo)) 1109 1110 % is it the right one? 1111 if isempty(hIn.NXTMAC) || strcmpi(hIn.NXTMAC, SerialNo) 1112 foundNXT = true; 1113 textOut(sprintf('(MAC matches, this is our desired NXT)\n')); 1114 break % search came to an end 1115 else 1116 foundNXT = false; 1117 textOut(sprintf('(no match, not using this NXT)\n')); 1118 % don't forget to close the opened NXT that didnt match... 1119 textOut(sprintf(' . closing device... ')); 1120 status = calllib(hIn.ConnectionLibraryName, 'usb_close', DevHandle); 1121 displayLibusbStatus(status, hIn); 1122 end%if 1123 1124 end%if 1125 1126 1127 % we are at the end of our "pointer-queue" 1128 if isempty(dev.next) 1129 break 1130 else 1131 % get next device, not that easy, but it works now \o/ 1132 ptr = dev.next; 1133 ptr.setdatatype('usb_device'); 1134 dev = ptr.Value; 1135 clear ptr % to be sure, don't want to risk memory leaks 1136 end%if 1137 1138 end%while (for all devices) 1139 % ------------------------------------- 1140 1141 1142 % no need to scan other busses if already found 1143 if foundNXT 1144 break 1145 end%if 1146 1147 % jump to next bus - same procedure as for devices, see above 1148 if isempty(bus.next) 1149 break 1150 else 1151 ptr = bus.next; 1152 ptr.setdatatype('usb_bus'); 1153 bus = ptr.Value; 1154 clear ptr 1155 end%if 1156 1157 end%while (for all busses) 1158 1159 1160 %% check if NXT present 1161 if ~foundNXT 1162 if ~SuppressErrors 1163 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!') 1164 error('MATLAB:RWTHMindstormsNXT:USB: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!') 1165 else 1166 % well, no NXT, exit silently 1167 return 1168 end%if 1169 end%if 1170 1171 1172 %% NXT found, open connection 1173 1174 % DevHandle is now the NXT we want 1175 1176 % the following commands are standard procedure for USB devices, similar usage 1177 % can be found in the open source packages Python_NXT and LEGO::NXT (Perl) 1178 1179 % flag to remember 1180 ErrorWhileOpening = false; 1181 1182 % if the following fails with error -16, the NXT is probably already in 1183 % use (opened in another handle!) 1184 textOut(sprintf(' . setting active configuration... ')); 1185 % somehow this doesn't work, so we use the hardcoded configuration 1! 1186 %calllib('libusb', 'usb_set_configuration', DevHandle, dev.config.bConfigurationValue); 1187 ret = calllib(hIn.ConnectionLibraryName, 'usb_set_configuration', DevHandle, LIBUSB_Configuration); 1188 displayLibusbStatus(ret, hIn); 1189 if (ret < 0) 1190 ErrorWhileOpening = true; 1191 end%if 1192 1193 textOut(sprintf(' . claiming interface... ')); 1194 % again, interface is hardcoded (compare implementations in python and 1195 % perl, they do it the same way) 1196 %calllib('libusb', 'usb_claim_interface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); 1197 ret = calllib(hIn.ConnectionLibraryName, 'usb_claim_interface', DevHandle, LIBUSB_Interface); 1198 displayLibusbStatus(ret, hIn); 1199 if (ret < 0) 1200 ErrorWhileOpening = true; 1201 end%if 1202 1203 1204 % we don't need an alternative interface, whatever that is. 1205 % but from debugging experience (also with Windows), you never know 1206 % when you might need this, so we keep it in here! 1207 1208 % disp(' . set altinterface') 1209 % % %[int32, usb_dev_handlePtr] usb_set_altinterface(usb_dev_handlePtr, int32) 1210 % ret = calllib('libusb', 'usb_set_altinterface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); 1211 % disp(sprintf('usb_strerror: %s', calllib('libusb', 'usb_strerror'))) 1212 1213 if hIn.OSValue == 2 % linux 1214 % is this necessary? but found it in perl and python versions... 1215 % the main point: never touch a running system 1216 textOut(sprintf(' . resetting device... ')); 1217 ret = calllib(hIn.ConnectionLibraryName, 'usb_reset', DevHandle); 1218 displayLibusbStatus(ret, hIn); 1219 if (ret < 0) 1220 ErrorWhileOpening = true; 1221 end%if 1222 end % end if linux 1223 1224 1225 if hIn.OSValue == 1 % windows 1226 % NOTE: really necessary? 1227 % % // Discard any data that is left in the buffer 1228 % % while (usb_bulk_read(nxt->hdl, 0x82, buf, sizeof(buf), 1) > 0); 1229 % textOut(sprintf(' . discarding any data... ')); 1230 % buffer = uint8(zeros(64,1)); 1231 % ret = 1; 1232 % while ret > 0 1233 % ret = calllib(hIn.ConnectionLibraryName, 'usb_bulk_read', DevHandle, uint8(130), buffer, 5, 1); 1234 % displayLibusbStatus(ret, hIn); 1235 % end 1236 % % displayLibusbStatus(ret, hIn); 1237 1238 % // try to set the stream I/O feature 1239 % ret = usb_control_msg(nxt->hdl, 0x41, 0x3, 0, 0, NULL, 0, 1000); 1240 % if (ret >= 0) 1241 % { 1242 % nxt->stream_mode = 1; 1243 % } 1244 textOut(sprintf(' . open stream modus... ')); 1245 buffer = char(uint8(blanks(64))); 1246 ret = calllib(hIn.ConnectionLibraryName, 'usb_control_msg', DevHandle, 65, 3, 0, 0, buffer, 0, 1000); 1247 displayLibusbStatus(ret, hIn); 1248 if (ret < 0) 1249 ErrorWhileOpening = true; 1250 end%if 1251 % if ret < 0 1252 % msg = ['Libusb error ' num2str(ret) ' while open stream mode: ' getLibusbErrorString(ret, hIn)]; 1253 % warning('MATLAB:RWTHMindstormsNXT:USB:libusbErrorWhileOpenStreamMode', msg); 1254 % end%if 1255 end % end if windows 1256 1257 1258 % now it's time to decide: 1259 if ErrorWhileOpening || isnumeric(DevHandle) 1260 if ~SuppressErrors 1261 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'')!') 1262 error('MATLAB:RWTHMindstormsNXT:USB: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'')!') 1263 else 1264 % again, exit silently when no success 1265 return 1266 end%if 1267 end%if 1268 1269 % finally, we're good to go! 1270 hOut.Handle = DevHandle; 1271 hOut.NXTMAC = SerialNo; 1272 1273 % and, important: 1274 hOut.Connected(true); 1275 1276 1277 %% clean up 1278 1279 % is this needed? or will matlab destroy this private vars anyway after 1280 % finishing this function? just to be sure with pointers... 1281 clear p v bus dev newHandleOrWhat DevHandle 1282 1283 1284 end%function 1285 -
branches/telle/RWTHMindstormsNXT/COM_SendPacket.m
r201 r247 32 32 % 33 33 % Signature 34 % Author: Linus Atorf (see AUTHORS)35 % Date: 2008/0 7/0934 % Author: Linus Atorf, Alexander Behrens (see AUTHORS) 35 % Date: 2008/08/15 36 36 % Copyright: 2007-2008, RWTH Aachen University 37 37 % … … 73 73 74 74 if handle.OSValue == 1 % Windows 75 USB_SendAndCollectPacket_Windows(Packet(3:end), handle); 75 switch (handle.ConnectionLibraryValue) 76 case 1 % fantom library 77 USB_SendAndCollectPacket_Windows(Packet(3:end), handle); 78 case 2 % libusb library 79 USB_SendPacket_libusb(Packet(3:end), handle); 80 otherwise 81 end 76 82 else % Linux 77 USB_SendPacket_ Linux(Packet(3:end), handle);83 USB_SendPacket_libusb(Packet(3:end), handle); 78 84 end%if 79 85 … … 197 203 198 204 199 %% --- FUNCTION USB_SendPacket_ Linux200 function USB_SendPacket_ Linux(packet, h)205 %% --- FUNCTION USB_SendPacket_libusb 206 function USB_SendPacket_libusb(packet, h) 201 207 202 208 … … 207 213 208 214 % be very careful to send uint8(packet) !!!!!! 215 ret = calllib(h.ConnectionLibraryName, 'usb_bulk_write', h.Handle, sendingEndpoint, uint8(packet), length(packet), timeout); 216 217 if ret < 0 218 msg = ['Libusb error ' num2str(ret) ' while sending data: ' getLibusbErrorString(ret, h)]; 219 warning('MATLAB:RWTHMindstormsNXT:USB:libusbErrorWhileSendingData', msg); 220 else % success 221 h.PacketsSent(1); 222 h.BytesSent(length(packet)); 223 end%if 224 225 226 227 end%function 228 229 230 %% --- FUNCTION USB_SendPacket_Linux 231 function USB_SendPacket_Linux(packet, h) 232 233 234 sendingEndpoint = 1; 235 %receivingEndpoint = 130; % hex2dec('82') 236 timeout = 1000; % ms 237 %maxPacketSize = 64; 238 239 % be very careful to send uint8(packet) !!!!!! 209 240 ret = calllib('libusb', 'usb_bulk_write', h.Handle, sendingEndpoint, uint8(packet), length(packet), timeout); 210 241 211 242 if ret < 0 212 msg = ['Libusb error ' num2str(ret) ' while sending data: ' getLibusbErrorString(ret )];243 msg = ['Libusb error ' num2str(ret) ' while sending data: ' getLibusbErrorString(ret, h)]; 213 244 warning('MATLAB:RWTHMindstormsNXT:USB:Linux:libusbErrorWhileSendingData', msg); 214 245 else % success -
branches/telle/RWTHMindstormsNXT/ResetMotorAngle.m
r201 r247 47 47 % *********************************************************************************************** 48 48 49 %% Parameter check 50 % check if NXT handle is given; if not use default one 51 if nargin > 2 52 handle = varargin{1}; 53 else 54 handle = COM_GetDefaultNXT; 55 end%if 56 49 57 % as we can see, just a little wrapper that maps the following NXT function and 50 58 % parameter combination to a more obvious name -
branches/telle/RWTHMindstormsNXT/private/checkHandleStruct.m
r201 r247 52 52 if h.OSValue == 1 % Windows 53 53 if h.ConnectionTypeValue == 1 % USB 54 if isfloat(h.Handle) 54 if isfloat(h.Handle) || ~isnumeric(h.Handle) % libusb0 55 55 valid = true; 56 56 end%if -
branches/telle/RWTHMindstormsNXT/private/createHandleStruct.m
r201 r247 82 82 h.ConnectionTypeName = ''; % String, 'USB' or 'Bluetooth' 83 83 h.ConnectionTypeValue = NaN; % USB = 1, Bluetooth = 2 84 h.ConnectionLibraryName = ''; % String, 'fantom' or 'libusb' / 'libusb0' 85 h.ConnectionLibraryValue = NaN; % fantom = 1, libusb = 2 84 86 85 87 h.Handle = []; % actual handle to driver / serial ... -
branches/telle/RWTHMindstormsNXT/private/getLibusbErrorString.m
r201 r247 1 function msg = getLibusbErrorString(errNo )1 function msg = getLibusbErrorString(errNo, h) 2 2 % Returns description to the last error from libusb 3 3 % 4 4 % Syntax 5 % msg = getLibusbErrorString(errNo)5 % |msg = getLibusbErrorString(errNo, h)| 6 6 % 7 7 % Description … … 13 13 % Copyright: 2007-2008, RWTH Aachen University 14 14 % 15 ; 15 16 % 16 17 % *********************************************************************************************** … … 36 37 if errNo < 0 37 38 %msg = sprintf('Error %d in libusb: %s', errNo, calllib('libusb', 'usb_strerror')); 38 msg = calllib( 'libusb', 'usb_strerror');39 msg = calllib(h.ConnectionLibraryName, 'usb_strerror'); 39 40 40 41 % basically taht was it, leave the other strings below just in case...
