Changeset 247

Show
Ignore:
Timestamp:
09/03/08 15:32:38 (5 years ago)
Author:
telle
Message:

merge r230:237 of /branches/behrens/mfiles (libusb support for windows)

Location:
branches/telle/RWTHMindstormsNXT
Files:
8 modified
2 copied

Legend:

Unmodified
Added
Removed
  • branches/telle/RWTHMindstormsNXT/COM_CloseNXT.m

    r201 r247  
    6363% 
    6464% Signature 
    65 %   Author: Linus Atorf (see AUTHORS) 
    66 %   Date: 2008/07/09 
     65%   Author: Linus Atorf, Alexander Behrens (see AUTHORS) 
     66%   Date: 2008/08/15 
    6767%   Copyright: 2007-2008, RWTH Aachen University 
    6868% 
     
    137137            textOut(sprintf('Closing handle (USB) with MAC = %s (handle was %.1f minutes old)\n', h.NXTMAC, etime(clock, h.CreationTime) / 60)); 
    138138            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 
    140146            else % linux 
    141                 USB_CloseHandle_Linux(h); 
     147                USB_CloseHandle_libusb(h); 
    142148            end%if 
    143149        else % BT 
     
    360366 
    361367 
     368%% --- FUNCTION USB_CloseHandle_libusb 
     369function 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 
     411end%function 
     412 
     413 
     414%% --- FUNCTION USB_CloseHandle_Windows_libusb 
     415function 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 
     454end%function 
     455 
    362456 
    363457%% --- FUNCTION USB_CloseHandle_Linux 
     
    369463    textOut(sprintf('  - Releasing interface... ')); 
    370464    ret = calllib('libusb', 'usb_release_interface', h.Handle, LIBUSB_Interface); 
    371     displayLibusbStatus(ret); 
     465    displayLibusbStatus(ret, h); 
    372466 
    373467 
    374468    textOut(sprintf('  - Closing device... ')); 
    375469    ret = calllib('libusb', 'usb_close', h.Handle); 
    376     displayLibusbStatus(ret); 
     470    displayLibusbStatus(ret, h); 
    377471 
    378472    % we don't unload libusb now, but if we did: 
     
    386480 
    387481 
    388 %% --- FUNCTION displayUSBWinStatus(status) 
     482%% --- FUNCTION displayUSBWinStatus 
    389483function displayUSBWinStatus(status) 
    390484    if status 
     
    397491 
    398492 
    399 %% --- FUNCTION displayLibusbStatus(status) 
    400 function displayLibusbStatus(status) 
     493%% --- FUNCTION displayLibusbStatus 
     494function displayLibusbStatus(status, h) 
    401495    if isnumeric(status) && (status < 0) 
    402496        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'])) 
    404498    else 
    405499        textOut(sprintf('done.\n')); 
  • branches/telle/RWTHMindstormsNXT/COM_CollectPacket.m

    r201 r247  
    9292    if handle.ConnectionTypeValue == 1 % USB 
    9393        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 
    95101        else % Linux 
    96             [type cmd statusbyte content] = USB_CollectPacket_Linux(handle); 
     102            [type cmd statusbyte content] = USB_CollectPacket_libusb(handle); 
    97103        end%if 
    98104    else % BT 
     
    395401 
    396402 
    397 %% --- FUNCTION USB_CollectPacket_Linux 
    398 function [type cmd statusbyte content] = USB_CollectPacket_Linux(h) 
     403%% --- FUNCTION USB_CollectPacket_libusb 
     404function [type cmd statusbyte content] = USB_CollectPacket_libusb(h) 
    399405 
    400406%% Libusb params 
     
    427433       
    428434    %[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 
     478end%function 
     479 
     480 
     481%% --- FUNCTION USB_CollectPacket_Linux 
     482function [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);     
    429513    [status something reply] = calllib('libusb', 'usb_bulk_read', h.Handle, receivingEndpoint, buffer, length(buffer), timeout);     
    430514    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)]; 
    432516        warning('MATLAB:RWTHMindstormsNXT:USB:Windows:libusbErrorWhileReceivingData', msg); 
    433517    end%if 
  • branches/telle/RWTHMindstormsNXT/COM_OpenNXTEx.m

    r201 r247  
    33% 
    44% 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')| 
    1010% 
    1111% Description 
    1212%   This function establishes a connection to an NXT brick and returns the 
    1313%   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). 
    1515% 
    1616%   For a more convenient way to open an NXT handle with less parameters, the 
    17 %   function COM_OpenNXT is provided. 
     17%   function |COM_OpenNXT| is provided. 
    1818% 
    1919%   Different types of connection modes are supported. In all modes, you can 
    20 %   set UseThisNXTMAC to a string with the NXT's MAC address (serial number). 
     20%   set |UseThisNXTMAC| to a string with the NXT's MAC address (serial number). 
    2121%   A connection will then only be estabslished to a matching NXT brick. This can be 
    2222%   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). 
    2424%    
    2525% 
    26 %   handle = COM_OpenNXTEx('USB', UseThisNXTMAC) 
     26%   |handle = COM_OpenNXTEx('USB', UseThisNXTMAC)| 
    2727%   This will try to open a connection via USB. Device drivers (Fantom on 
    2828%   Windows, libusb on Linux) have to be installed. 
    2929% 
    3030% 
    31 %   handle = COM_OpenNXTEx('Bluetooth', UseThisNXTMAC, inifilename, 'check') 
     31%   |handle = COM_OpenNXTEx('Bluetooth', UseThisNXTMAC, inifilename, 'check')| 
    3232%   Uses Bluetooth as communication method. A valid inifile containing 
    33 %   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 
     33%   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 
    3535%   new Bluetooth connection is working bi-directional). Leave it out if 
    3636%   your hardware does only support sending data (depends on the Bluetooth 
     
    3939%   motor control). 
    4040%   To create an inifile with Bluetooth settings, the function 
    41 %   COM_MakeBTConfigFile is available. 
     41%   |COM_MakeBTConfigFile| is available. 
    4242%     
    43 %   Note that as of right now, the parameter UseThisNXTMAC will be 
     43%   Note that as of right now, the parameter |UseThisNXTMAC| will be 
    4444%   ignored for Bluetooth connections until implemented in a future version. 
    4545% 
    4646% 
    47 %   handle = COM_OpenNXTEx('Any', UseThisNXTMAC, inifilename, 'check') 
     47%   |handle = COM_OpenNXTEx('Any', UseThisNXTMAC, inifilename, 'check')| 
    4848%   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. 
    5050%   The function will try to locate an NXT device on the USB bus first. If 
    5151%   this fails for some reason (no USB connection to the NXT available, no 
     
    5858%    
    5959% 
    60 % Limitations of COM_CloseNXT 
    61 %   If you call COM_CloseNXT('all') after a clear all command has been 
     60% Limitations of |COM_CloseNXT| 
     61%   If you call |COM_CloseNXT('all')| after a |clear all| command has been 
    6262%   issued, the function will not be able to close all remaining open USB 
    6363%   handles, since they have been cleared out of memory. This is a problem 
    6464%   on Linux systems. You will not be able to use the NXT device without 
    6565%   rebooting it. 
    66 %   Solution: Either use only clear in your programs, or you use the 
    67 %   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|. 
    6868%   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!% 
    7070% 
    7171% 
    7272% 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 USB 
    76 %   % device found), a connection via Bluetooth will be established, using 
    77 %   % 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. 
    7878%  
    7979% 
     
    8585%   Copyright: 2007-2008, RWTH Aachen University 
    8686% 
     87; %#ok<NOSEM> 
    8788% 
    8889% *********************************************************************************************** 
     
    244245%     handle.IniFilename           = h.IniFilename; 
    245246%     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; 
    249250%  
    250 %     handle.SendSendPause               = h.SendSendPause; 
     251%     handle.SendSendPause         = h.SendSendPause; 
    251252%     handle.SendReceivePause      = h.SendReceivePause; 
    252253%  
    253254%     handle.NXTMAC                = h.NXTMAC; 
    254 %     handle.CreationTime               = h.CreationTime;   
     255%     handle.CreationTime         = h.CreationTime;   
    255256%     handle.Index                 = h.Index; 
    256257     
     
    390391     
    391392    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);         
    393415    elseif hIn.OSValue == 2 
    394         hOut = USB_OpenHandle_Linux(hIn, SuppressErrors); 
     416        hOut = USB_OpenHandle_libusb(hIn, SuppressErrors); 
    395417    end%if 
    396418     
     
    427449    hOut.ConnectionTypeValue    = 1; 
    428450    hOut.ConnectionTypeName     = 'USB'; 
     451 
    429452     
    430453     
     
    447470        textOut(sprintf('  - Library "fantom" already loaded.\n')); 
    448471    end%if 
    449          
     472 
     473    hOut.ConnectionLibraryName = 'fantom';  % String, 'fantom' or 'libusb' / 'libusb0' 
     474    hOut.ConnectionLibraryValue = 1; % fantom = 1, libusb = 2 
    450475     
    451476     
     
    567592 
    568593 
    569 %% --- FUNCTION displayLibusbStatus(status) 
     594%% --- FUNCTION displayLibusbStatus 
    570595% little convenient helper to save some lines of code with textOut 
    571 function displayLibusbStatus(status) 
     596function displayLibusbStatus(status, h) 
    572597% little convenient helper to save some lines of code with textOut 
    573598    if isnumeric(status) && (status < 0) 
    574599        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'])) 
    576601    else 
    577602        textOut(sprintf('done.\n')); 
     
    657682    textOut(sprintf('    . finding busses... ')) 
    658683    ret = calllib('libusb', 'usb_find_busses'); 
    659     displayLibusbStatus(ret); 
     684    displayLibusbStatus(ret, hIn); 
    660685     
    661686    textOut(sprintf('    . finding devices... ')) 
    662687    ret = calllib('libusb', 'usb_find_devices'); 
    663     displayLibusbStatus(ret); 
     688    displayLibusbStatus(ret, hIn); 
    664689 
    665690%% Get main root bus 
     
    668693    p = calllib('libusb', 'usb_get_busses'); 
    669694    bus = libstruct('usb_bus', p); 
    670     displayLibusbStatus(p); 
     695    displayLibusbStatus(p, hIn); 
    671696     
    672697 
     
    747772                textOut(sprintf('    . opening device... ')); 
    748773                DevHandle = calllib('libusb', 'usb_open', dev); 
    749                 displayLibusbStatus(DevHandle); 
     774                displayLibusbStatus(DevHandle, hIn); 
    750775 
    751776                textOut(sprintf('    . reading serial number... ')); 
     
    754779                buffer = blanks(255); 
    755780                [bytesRead newHandleOrWhat SerialNo] = calllib('libusb', 'usb_get_string_simple', DevHandle, dev.descriptor.iSerialNumber,  buffer, length(buffer)); 
    756                 displayLibusbStatus(bytesRead); 
     781                displayLibusbStatus(bytesRead, hIn); 
    757782                                 
    758783                SerialNo = strtrim(SerialNo); % just to be safe 
     
    770795                    textOut(sprintf('    . closing device... ')); 
    771796                    status = calllib('libusb', 'usb_close', DevHandle); 
    772                     displayLibusbStatus(status); 
     797                    displayLibusbStatus(status, hIn); 
    773798                end%if 
    774799                 
     
    837862    %calllib('libusb', 'usb_set_configuration', DevHandle, dev.config.bConfigurationValue); 
    838863    ret = calllib('libusb', 'usb_set_configuration', DevHandle, LIBUSB_Configuration); 
    839     displayLibusbStatus(ret); 
     864    displayLibusbStatus(ret, hIn); 
    840865    if (ret < 0) 
    841866        ErrorWhileOpening = true; 
     
    847872    %calllib('libusb', 'usb_claim_interface', DevHandle, dev.config.interface.altsetting.bInterfaceNumber); 
    848873    ret = calllib('libusb', 'usb_claim_interface', DevHandle, LIBUSB_Interface); 
    849     displayLibusbStatus(ret); 
     874    displayLibusbStatus(ret, hIn); 
    850875    if (ret < 0) 
    851876        ErrorWhileOpening = true; 
     
    866891    textOut(sprintf('    . resetting device... ')); 
    867892    ret = calllib('libusb', 'usb_reset', DevHandle); 
    868     displayLibusbStatus(ret); 
     893    displayLibusbStatus(ret, hIn); 
    869894    if (ret < 0) 
    870895        ErrorWhileOpening = true; 
     
    899924end%function 
    900925 
     926 
     927%% --- FUNCTION USB_OpenHandle_libusb 
     928function 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 
     1284end%function 
     1285 
  • branches/telle/RWTHMindstormsNXT/COM_SendPacket.m

    r201 r247  
    3232% 
    3333% Signature 
    34 %   Author: Linus Atorf (see AUTHORS) 
    35 %   Date: 2008/07/09 
     34%   Author: Linus Atorf, Alexander Behrens (see AUTHORS) 
     35%   Date: 2008/08/15 
    3636%   Copyright: 2007-2008, RWTH Aachen University 
    3737% 
     
    7373         
    7474        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 
    7682        else % Linux 
    77             USB_SendPacket_Linux(Packet(3:end), handle); 
     83            USB_SendPacket_libusb(Packet(3:end), handle); 
    7884        end%if 
    7985         
     
    197203 
    198204 
    199 %% --- FUNCTION USB_SendPacket_Linux 
    200 function USB_SendPacket_Linux(packet, h) 
     205%% --- FUNCTION USB_SendPacket_libusb 
     206function USB_SendPacket_libusb(packet, h) 
    201207 
    202208 
     
    207213 
    208214    % 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 
     227end%function 
     228 
     229 
     230%% --- FUNCTION USB_SendPacket_Linux 
     231function 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) !!!!!! 
    209240    ret = calllib('libusb', 'usb_bulk_write', h.Handle, sendingEndpoint, uint8(packet), length(packet), timeout); 
    210241     
    211242    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)]; 
    213244        warning('MATLAB:RWTHMindstormsNXT:USB:Linux:libusbErrorWhileSendingData', msg); 
    214245    else % success 
  • branches/telle/RWTHMindstormsNXT/ResetMotorAngle.m

    r201 r247  
    4747% *********************************************************************************************** 
    4848 
     49%% Parameter check 
     50% check if NXT handle is given; if not use default one 
     51if nargin > 2 
     52        handle = varargin{1}; 
     53else 
     54    handle = COM_GetDefaultNXT; 
     55end%if 
     56 
    4957% as we can see, just a little wrapper that maps the following NXT function and 
    5058% parameter combination to a more obvious name 
  • branches/telle/RWTHMindstormsNXT/private/checkHandleStruct.m

    r201 r247  
    5252            if h.OSValue == 1 % Windows 
    5353                if h.ConnectionTypeValue == 1 % USB 
    54                     if isfloat(h.Handle) 
     54                    if isfloat(h.Handle) || ~isnumeric(h.Handle) % libusb0 
    5555                        valid = true; 
    5656                    end%if 
  • branches/telle/RWTHMindstormsNXT/private/createHandleStruct.m

    r201 r247  
    8282    h.ConnectionTypeName    = '';  % String, 'USB' or 'Bluetooth' 
    8383    h.ConnectionTypeValue       = NaN; % USB = 1, Bluetooth = 2 
     84    h.ConnectionLibraryName = '';  % String, 'fantom' or 'libusb' / 'libusb0' 
     85    h.ConnectionLibraryValue = NaN; % fantom = 1, libusb = 2 
    8486 
    8587    h.Handle                = [];  % actual handle to driver / serial ... 
  • branches/telle/RWTHMindstormsNXT/private/getLibusbErrorString.m

    r201 r247  
    1 function msg = getLibusbErrorString(errNo) 
     1function msg = getLibusbErrorString(errNo, h) 
    22% Returns description to the last error from libusb 
    33% 
    44% Syntax 
    5 %   msg = getLibusbErrorString(errNo) 
     5%   |msg = getLibusbErrorString(errNo, h)| 
    66% 
    77% Description 
     
    1313%   Copyright: 2007-2008, RWTH Aachen University 
    1414% 
     15; 
    1516% 
    1617% *********************************************************************************************** 
     
    3637    if  errNo < 0 
    3738        %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'); 
    3940 
    4041    % basically taht was it, leave the other strings below just in case...