-
Notifications
You must be signed in to change notification settings - Fork 57
USB device communication
Create USBDeviceMonitor
object globally, set vid
and pid
of devices that you need to listen and run monitor in new thread for listen USB devices
import Cocoa
import USBDeviceSwift
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
//make sure that stm32DeviceMonitor always exist
let stm32DeviceMonitor = USBDeviceMonitor([
VIDPID(vendorId: 0x0483, productId: 0xdf11)
])
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
let stm32DeviceDaemon = Thread(target: stm32DeviceMonitor, selector:#selector(stm32DeviceMonitor.start), object: nil)
stm32DeviceDaemon.start()
}
}
note - start
function using RunLoop
that blocks thread don't run monitor in Main
thread
There are two global notifications:
USBDeviceConnected
USBDeviceDisconnected
Listen them in our ViewController:
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
NotificationCenter.default.addObserver(self, selector: #selector(self.usbConnected), name: .USBDeviceConnected, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.usbDisconnected), name: .USBDeviceDisconnected, object: nil)
}
// getting connected device data
func usbConnected(notification: NSNotification) {
guard let nobj = notification.object as? NSDictionary else {
return
}
guard let deviceInfo:USBDevice = nobj["device"] as? USBDevice else {
return
}
}
// getting disconnected device id
func usbDisconnected(notification: NSNotification) {
guard let nobj = notification.object as? NSDictionary else {
return
}
guard let deviceInfo:USBDevice = nobj["id"] as? UInt64 else {
return
}
}
}
USBDeviceConnected
notification - returns USBDevice
with all basic info
-
id - returns id from IORegistryEntryGetRegistryEntryID
-
vendorId - Vendor ID from GetDeviceVendor
-
productId - Product ID from GetDeviceProduct
-
name - Name from IORegistryEntryGetName
-
deviceInterfacePtrPtr - Pointer to IOUSBDeviceInterface
-
plugInInterfacePtrPtr - Pointer to IOCFPlugInInterface
USBDeviceDisconnected
notification - returns id from IORegistryEntryGetRegistryEntryID
enum STM32DeviceError: Error {
case DeviceInterfaceNotFound
case InvalidData(desc:String)
case RequestError(desc:String)
}
func getStatus() throws -> [UInt8] {
//Getting device interface from our pointer
guard let deviceInterface = self.deviceInfo.deviceInterfacePtrPtr?.pointee?.pointee else {
throw STM32DeviceError.DeviceInterfaceNotFound
}
var kr:Int32 = 0
let length:Int = 6
var requestPtr:[UInt8] = [UInt8](repeating: 0, count: length)
// Creating request
var request = IOUSBDevRequest(bmRequestType: 161,
bRequest: 0x03,
wValue: 0,
wIndex: 0,
wLength: UInt16(length),
pData: &requestPtr,
wLenDone: 255)
kr = deviceInterface.DeviceRequest(self.deviceInfo.deviceInterfacePtrPtr, &request)
if (kr != kIOReturnSuccess) {
throw STM32DeviceError.RequestError(desc: "Get device status request error: \(kr)")
}
// Getting our data
return requestPtr
}
See full example in STM32DeviceExample
folder