-
Notifications
You must be signed in to change notification settings - Fork 848
Expand file tree
/
Copy pathdesktop_comms_handler.dart
More file actions
114 lines (99 loc) · 3.15 KB
/
Copy pathdesktop_comms_handler.dart
File metadata and controls
114 lines (99 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import 'dart:typed_data';
import 'package:flusbserial/flusbserial.dart';
import 'package:pslab/communication/handler/base.dart';
import 'package:pslab/others/logger_service.dart';
class DesktopUSBCommunicationHandler implements CommunicationHandler {
static const int pslabVendorIdV5 = 1240;
static const int pslabProductIdV5 = 223;
static const int pslabVendorIdV6 = 0x10C4;
static const int pslabProductIdV6 = 0xEA60;
UsbSerialDevice? mDevice;
@override
bool connected = false;
@override
bool deviceFound = false;
@override
void close() {
if (!connected || mDevice == null) return;
mDevice?.close();
connected = false;
}
@override
Future<void> initialize() async {
UsbSerialDevice.init();
List<UsbDevice> availableDevices = await UsbSerialDevice.listDevices();
for (final device in availableDevices) {
if ((device.vendorId == pslabVendorIdV5 &&
device.productId == pslabProductIdV5) ||
(device.vendorId == pslabVendorIdV6 &&
device.productId == pslabProductIdV6)) {
deviceFound = true;
mDevice = UsbSerialDevice.createDevice(device);
break;
}
}
if (deviceFound) {
logger.d("Found PSLab device");
} else {
logger.d("No drivers found");
}
}
@override
bool isConnected() {
return connected;
}
@override
bool isDeviceFound() {
return deviceFound;
}
@override
Future<void> open() async {
if (!deviceFound) {
throw Exception("Device not connected");
}
UsbSerialDevice.setAutoDetachKernelDriver(true);
if (await mDevice?.open() == false) {
logger.e("Failed to open device");
return;
}
await mDevice?.setBaudRate(1000000);
await mDevice?.setDataBits(UsbSerialInterface.dataBits8);
await mDevice?.setStopBits(UsbSerialInterface.stopBits1);
await mDevice?.setParity(UsbSerialInterface.parityNone);
connected = true;
}
@override
Future<int> read(Uint8List dest, int bytesToRead, int timeoutMillis) async {
int numBytesRead = 0;
int bytesToBeReadTemp = bytesToRead;
try {
while (numBytesRead < bytesToRead) {
Uint8List? receivedData =
await mDevice?.read(bytesToBeReadTemp, timeoutMillis);
int? readNow = receivedData?.length;
if (readNow == null || readNow == 0) {
// If we read nothing and timeout, stop trying to avoid an infinite hang
break;
} else {
int readLength = readNow.clamp(0, bytesToBeReadTemp);
dest.setRange(numBytesRead, numBytesRead + readLength, receivedData!);
numBytesRead += readLength;
bytesToBeReadTemp -= readLength;
}
}
} catch (e) {
// If we hit a LIBUSB_ERROR_TIMEOUT but we already have data, it's just a partial read.
if (numBytesRead > 0) {
logger.d(
"Partial read completed before timeout. Read: $numBytesRead/$bytesToRead bytes.");
} else {
logger.w("USB Read Timeout: Expected $bytesToRead bytes but got 0.");
}
}
return numBytesRead;
}
@override
void write(Uint8List src, int timeoutMillis) {
mDevice?.write(src, timeoutMillis);
}
}