-
Notifications
You must be signed in to change notification settings - Fork 60
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