WinUsbPy is a python wrapper over WinUsblibrary
It contains two different layers:
- A 1:1 wrapper over WinUsb which allows calling C++ functions directly from involved dlls.
- A high level api which simplifies a lot of C++/windll/ctypes messy interactions offering just a bunch of easy methods.
python setup.py install
Low level api offers three methods for invoking functions from three different dlls.
#args: arguments of the C++ function called
def exec_function_winusb(self, function_name, *args):
def exec_function_kernel32(self, function_name, *args):
def exec_function_setupapi(self, function_name, *args):
if we need to call SetupDiGetClassDevs which presents this prototype:
HDEVINFO SetupDiGetClassDevs(_In_opt_ const GUID *ClassGuid,_In_opt_ PCTSTR Enumerator,_In_opt_ HWND hwndParent,_In_ DWORD Flags);
from winusbpy import *
from ctypes import *
from ctypes.wintypes import *
from winusbclasses import DIGCF_DEVICE_INTERFACE, DIGCF_PRESENT
api = WinUSBApi()
byte_array = c_byte * 8
guid = GUID(0xA5DCBF10L, 0x6530, 0x11D2, byte_array(0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED))
flags = DWORD(DIGCF_DEVICE_INTERFACE | DIGCF_PRESENT)
hdev_info = api.exec_function_setupapi("SetupDiGetClassDevs", byref(guid), None, None, flags)
Good resources of WinUsb if you develop using this low level layer
Built on top of the low level wrapper is a more usable api to perform common USB operations. Here it is list of defined functions:
# Possible keyword arguments: default, present, allclasses, profile, deviceinterface (Boolean), Usually called as follows list_usb_devices(deviceinterface=True, present=True)
def list_usb_devices(self, **kwargs):
# vid and pid must be str, returns True if device was correctly initialized and False otherwise
def init_winusb_device(self, vid, pid):
# Returns True if device was correctly closed and False otherwise.
def close_winusb_device(self):
# Returns last error code. See http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382%28v=vs.85%29.aspx
def get_last_error_code(self):
# Returns information for a open device (0x03:High Speed, 0x01:full-speed or lower), query=1 in order to get USB speed.
def query_device_info(self, query=1):
# Returns a UsbInterfaceDescriptor object with information about a specified interface
def query_interface_settings(self, index):
# Change current interface, Winusb opens first interface (0 index) when a device is initialized
def change_interface(self, index):
# Returns a PipeInfo object with information of a specified pipe within current interface
def query_pipe(self, pipe_index):
# Send a control requesto to open device, setup_packet is a UsbSetupPacket object.
# buff = None implies no data is going to be transferred besides setup packet
# buff = [0] create a buffer of length 1. Buffer could be IN or OUT, direction is defined in setup packet
# it returns a dict with the response and with the buffer under the keywords 'result' and 'buffer'
def control_transfer(self, setup_packet, buff=None):
#Send Bulk data to the Usb device, write_buffer must be a str buffer
def write(self, pipe_id, write_buffer):
#Read Bulk data from the Usb device, Returns of a buffer not greater than length_buffer length
def read(self, pipe_id, length_buffer):
Let's say hello to our device:
from winusbpy import *
vid = "vid_device" # for example: VID:067b PID:2303
pid = "pid_device"
api = WinUsbPy()
result = api.list_usb_devices(deviceinterface=True, present=True)
if result:
if api.init_winusb_device(pl2303_vid, pl2303_pid):
api.write(0x02, "hello")
In "Examples" folder there are two real examples configuring a PL2303 serial usb device, listing characteristics and sending data. Using Low Level Api