Maintainer | Bas van Dijk <v.dijk.bas@gmail.com> |
---|
The module provides functionality for opening, closing and configuring USB devices.
- data DeviceHandle
- openDevice :: Device -> IO DeviceHandle
- closeDevice :: DeviceHandle -> IO ()
- withDeviceHandle :: Device -> (DeviceHandle -> IO α) -> IO α
- getDevice :: DeviceHandle -> Device
- type ConfigValue = Word8
- getConfig :: DeviceHandle -> IO (Maybe ConfigValue)
- setConfig :: DeviceHandle -> Maybe ConfigValue -> IO ()
- type InterfaceNumber = Word8
- claimInterface :: DeviceHandle -> InterfaceNumber -> IO ()
- releaseInterface :: DeviceHandle -> InterfaceNumber -> IO ()
- withClaimedInterface :: DeviceHandle -> InterfaceNumber -> IO α -> IO α
- type InterfaceAltSetting = Word8
- setInterfaceAltSetting :: DeviceHandle -> InterfaceNumber -> InterfaceAltSetting -> IO ()
- clearHalt :: DeviceHandle -> EndpointAddress -> IO ()
- resetDevice :: DeviceHandle -> IO ()
- kernelDriverActive :: DeviceHandle -> InterfaceNumber -> IO Bool
- detachKernelDriver :: DeviceHandle -> InterfaceNumber -> IO ()
- attachKernelDriver :: DeviceHandle -> InterfaceNumber -> IO ()
- withDetachedKernelDriver :: DeviceHandle -> InterfaceNumber -> IO α -> IO α
Opening & closing devices
data DeviceHandle Source
Abstract type representing a handle of a USB device.
You can acquire a handle from openDevice
.
A device handle is used to perform I/O and other operations. When finished with
a device handle you should close it by applying closeDevice
to it.
openDevice :: Device -> IO DeviceHandleSource
Open a device and obtain a device handle.
A handle allows you to perform I/O on the device in question.
This is a non-blocking function; no requests are sent over the bus.
It is advisable to use withDeviceHandle
because it automatically closes the
device when the computation terminates.
Exceptions:
-
NoMemException
if there is a memory allocation failure. -
AccessException
if the user has insufficient permissions. -
NoDeviceException
if the device has been disconnected. - Another
USBException
.
closeDevice :: DeviceHandle -> IO ()Source
Close a device handle.
Should be called on all open handles before your application exits.
This is a non-blocking function; no requests are sent over the bus.
withDeviceHandle :: Device -> (DeviceHandle -> IO α) -> IO αSource
withDeviceHandle dev act
opens the Device
dev
and passes
the resulting handle to the computation act
. The handle will be closed on exit
from withDeviceHandle
whether by normal termination or by raising an
exception.
getDevice :: DeviceHandle -> DeviceSource
Retrieve the Device
from the DeviceHandle
.
Getting & setting the configuration
type ConfigValue = Word8Source
Identifier for configurations.
Can be retrieved by getConfig
or by configValue
.
getConfig :: DeviceHandle -> IO (Maybe ConfigValue)Source
Determine the value of the currently active configuration.
You could formulate your own control request to obtain this information, but this function has the advantage that it may be able to retrieve the information from operating system caches (no I/O involved).
If the OS does not cache this information, then this function will block while a control transfer is submitted to retrieve the information.
This function returns Nothing
if the device is in unconfigured state.
Exceptions:
-
NoDeviceException
if the device has been disconnected. - Another
USBException
.
setConfig :: DeviceHandle -> Maybe ConfigValue -> IO ()Source
Set the active configuration for a device.
The operating system may or may not have already set an active configuration on the device. It is up to your application to ensure the correct configuration is selected before you attempt to claim interfaces and perform other operations.
If you call this function on a device already configured with the selected configuration, then this function will act as a lightweight device reset: it will issue a SET_CONFIGURATION request using the current configuration, causing most USB-related device state to be reset (altsetting reset to zero, endpoint halts cleared, toggles reset).
You cannot change/reset configuration if your application has claimed interfaces
- you should free them with releaseInterface
first. You cannot change/reset
configuration if other applications or drivers have claimed interfaces.
A configuration value of Nothing
will put the device in an unconfigured
state. The USB specification states that a configuration value of 0 does this,
however buggy devices exist which actually have a configuration 0.
You should always use this function rather than formulating your own SET_CONFIGURATION control request. This is because the underlying operating system needs to know when such changes happen.
This is a blocking function.
Exceptions:
-
NotFoundException
if the requested configuration does not exist. -
BusyException
if interfaces are currently claimed. -
NoDeviceException
if the device has been disconnected - Another
USBException
.
Claiming & releasing interfaces
type InterfaceNumber = Word8Source
Identifier for interfaces.
Can be retrieved by interfaceNumber
.
claimInterface :: DeviceHandle -> InterfaceNumber -> IO ()Source
Claim an interface on a given device handle.
You must claim the interface you wish to use before you can perform I/O on any of its endpoints.
It is legal to attempt to claim an already-claimed interface, in which case this function just returns without doing anything.
Claiming of interfaces is a purely logical operation; it does not cause any requests to be sent over the bus. Interface claiming is used to instruct the underlying operating system that your application wishes to take ownership of the interface.
This is a non-blocking function.
Exceptions:
-
NotFoundException
if the requested interface does not exist. -
BusyException
if the interface is already claimed. -
NoDeviceException
if the device has been disconnected. - Another
USBException
.
releaseInterface :: DeviceHandle -> InterfaceNumber -> IO ()Source
Release an interface previously claimed with claimInterface
.
You should release all claimed interfaces before closing a device handle.
This is a blocking function. A SET_INTERFACE control request will be sent to the device, resetting interface state to the first alternate setting.
Exceptions:
-
NotFoundException
if the interface was not claimed. -
NoDeviceException
if the device has been disconnected - Another
USBException
.
withClaimedInterface :: DeviceHandle -> InterfaceNumber -> IO α -> IO αSource
withClaimedInterface
claims the interface on the given device handle then
executes the given computation. On exit from withClaimedInterface
, the
interface is released whether by normal termination or by raising an exception.
Setting interface alternate settings
type InterfaceAltSetting = Word8Source
Identifier for interface alternate settings.
Can be retrieved by interfaceAltSetting
.
setInterfaceAltSetting :: DeviceHandle -> InterfaceNumber -> InterfaceAltSetting -> IO ()Source
Activate an alternate setting for an interface.
The interface must have been previously claimed with claimInterface
or
withInterfaceHandle
.
You should always use this function rather than formulating your own SET_INTERFACE control request. This is because the underlying operating system needs to know when such changes happen.
This is a blocking function.
Exceptions:
-
NotFoundException
if the interface was not claimed or the requested alternate setting does not exist. -
NoDeviceException
if the device has been disconnected. - Another
USBException
.
Clearing & Resetting devices
clearHalt :: DeviceHandle -> EndpointAddress -> IO ()Source
Clear the halt/stall condition for an endpoint.
Endpoints with halt status are unable to receive or transmit data until the halt condition is stalled.
You should cancel all pending transfers before attempting to clear the halt condition.
This is a blocking function.
Exceptions:
-
NotFoundException
if the endpoint does not exist. -
NoDeviceException
if the device has been disconnected. - Another
USBException
.
resetDevice :: DeviceHandle -> IO ()Source
Perform a USB port reset to reinitialize a device.
The system will attempt to restore the previous configuration and alternate settings after the reset has completed.
If the reset fails, the descriptors change, or the previous state cannot be
restored, the device will appear to be disconnected and reconnected. This means
that the device handle is no longer valid (you should close it) and rediscover
the device. A NotFoundException
is raised to indicate that this is the
case.
This is a blocking function which usually incurs a noticeable delay.
Exceptions:
-
NotFoundException
if re-enumeration is required, or if the device has been disconnected. - Another
USBException
.
USB kernel drivers
kernelDriverActive :: DeviceHandle -> InterfaceNumber -> IO BoolSource
Determine if a kernel driver is active on an interface.
If a kernel driver is active, you cannot claim the interface, and libusb will be unable to perform I/O.
Exceptions:
-
NoDeviceException
if the device has been disconnected. - Another
USBException
.
detachKernelDriver :: DeviceHandle -> InterfaceNumber -> IO ()Source
Detach a kernel driver from an interface.
If successful, you will then be able to claim the interface and perform I/O.
Exceptions:
-
NotFoundException
if no kernel driver was active. -
InvalidParamException
if the interface does not exist. -
NoDeviceException
if the device has been disconnected. - Another
USBException
.
attachKernelDriver :: DeviceHandle -> InterfaceNumber -> IO ()Source
Re-attach an interface's kernel driver, which was previously
detached using detachKernelDriver
.
Exceptions:
-
NotFoundException
if no kernel driver was active. -
InvalidParamException
if the interface does not exist. -
NoDeviceException
if the device has been disconnected. -
BusyException
if the driver cannot be attached because the interface is claimed by a program or driver. - Another
USBException
.
withDetachedKernelDriver :: DeviceHandle -> InterfaceNumber -> IO α -> IO αSource
If a kernel driver is active on the specified interface the driver is detached and the given action is executed. If the action terminates, whether by normal termination or by raising an exception, the kernel driver is attached again. If a kernel driver is not active on the specified interface the action is just executed.
Exceptions:
-
NoDeviceException
if the device has been disconnected. - Another
USBException
.