Skip to content

Commit 5ac4442

Browse files
committed
More browser support & port forwarding noopkat#227 changes added
1 parent 4c88107 commit 5ac4442

3 files changed

Lines changed: 132 additions & 36 deletions

File tree

avrgirl-arduino.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var injectDependencies = function(boards, Connection, protocols) {
1515
megaDebug: opts.megaDebug || false,
1616
board: opts.board || 'uno',
1717
port: opts.port || '',
18+
serialPort: opts.serialPort || null,
1819
manualReset: opts.manualReset || false,
1920
disableVerify: opts.disableVerify || false
2021
};
@@ -148,4 +149,3 @@ var injectDependencies = function(boards, Connection, protocols) {
148149
};
149150

150151
module.exports = injectDependencies;
151-

lib/browser-serialport.js

Lines changed: 115 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ class SerialPort extends EventEmitter {
99
this.browser = true;
1010
this.path = this.options.path;
1111
this.isOpen = false;
12-
this.port = null;
12+
this.port = port || null;
1313
this.writer = null;
1414
this.reader = null;
15+
this.isUpdating = false;
16+
this.pausePromise = Promise.resolve();
17+
this.pauseResolve = () => {};
18+
this.closeReadPromise = null;
19+
this.closeReadResolve = () => {};
1520
this.baudRate = this.options.baudRate;
1621
this.requestOptions = this.options.requestOptions || {};
1722

@@ -24,45 +29,74 @@ class SerialPort extends EventEmitter {
2429
.catch((error) => {if (callback) {return callback(error)}});
2530
}
2631

32+
async _getPort() {
33+
if (this.port && !this.options.forceRequest) return this.port;
34+
return window.navigator.serial.requestPort(this.requestOptions)
35+
}
36+
2737
open(callback) {
28-
window.navigator.serial.requestPort(this.requestOptions)
29-
.then(serialPort => {
30-
this.port = serialPort;
31-
if (this.isOpen) return;
32-
return this.port.open({ baudRate: this.baudRate || 57600 });
33-
})
34-
.then(() => this.writer = this.port.writable.getWriter())
35-
.then(() => this.reader = this.port.readable.getReader())
36-
.then(async () => {
37-
this.emit('open');
38-
this.isOpen = true;
39-
callback(null);
40-
while (this.port.readable.locked) {
41-
try {
42-
const { value, done } = await this.reader.read();
43-
if (done) {
44-
break;
38+
return new Promise((resolve, reject) => {
39+
this._getPort()
40+
.then(serialPort => {
41+
this.port = serialPort;
42+
if (this.isOpen) return;
43+
return this.port.open({ baudRate: this.baudRate || 57600 });
44+
})
45+
.then(() => this.writer = this.port.writable.getWriter())
46+
.then(() => this.reader = this.port.readable.getReader())
47+
.then(async () => {
48+
if (!this.isUpdating) this.emit('open');
49+
this.isOpen = true;
50+
if (callback) callback(null);
51+
resolve(null);
52+
while (this.port.readable.locked) {
53+
try {
54+
await this.pausePromise;
55+
const { value, done } = await this.reader.read();
56+
if (done || this.closeReadPromise) {
57+
break;
58+
}
59+
this.emit('data', Buffer.from(value));
60+
} catch (e) {
61+
console.error(e);
4562
}
46-
this.emit('data', Buffer.from(value));
47-
} catch (e) {
48-
console.error(e);
4963
}
50-
}
51-
})
52-
.catch(error => {callback(error)});
64+
this.closeReadResolve();
65+
})
66+
.catch(error => {
67+
if (callback) callback(error);
68+
reject(error);
69+
});
70+
});
5371
}
5472

5573
async close(callback) {
74+
if (!this.isOpen) {
75+
if (callback) callback(null);
76+
return;
77+
}
78+
if (this.port.readable.locked) {
79+
this.closeReadPromise = new Promise((resolve) => {
80+
this.closeReadResolve = resolve;
81+
});
82+
this.pauseResolve();
83+
try {
84+
await this.reader.cancel();
85+
} catch (err) { console.error(err); }
86+
await this.closeReadPromise;
87+
this.closeReadPromise = null;
88+
}
5689
try {
5790
await this.reader.releaseLock();
5891
await this.writer.releaseLock();
5992
await this.port.close();
93+
if (!this.isUpdating) this.emit('close');
6094
this.isOpen = false;
6195
} catch (error) {
6296
if (callback) return callback(error);
6397
throw error;
6498
}
65-
callback && callback(null);
99+
if (callback) callback(null);
66100
}
67101

68102
async set(props = {}, callback) {
@@ -87,6 +121,27 @@ class SerialPort extends EventEmitter {
87121
if (callback) return callback(null);
88122
}
89123

124+
async get(callback) {
125+
const props = {};
126+
try {
127+
const signals = await this.port.getSignals();
128+
if (Object.prototype.hasOwnProperty.call(signals, 'dataCarrierDetect')) {
129+
props.dcd = signals.dataCarrierDetect;
130+
}
131+
if (Object.prototype.hasOwnProperty.call(signals, 'clearToSend')) {
132+
props.cts = signals.clearToSend;
133+
}
134+
if (Object.prototype.hasOwnProperty.call(signals, 'dataSetReady')) {
135+
props.dsr = signals.dataSetReady;
136+
}
137+
} catch (error) {
138+
if (callback) return callback(error);
139+
throw error;
140+
}
141+
if (callback) return callback(props);
142+
return props;
143+
}
144+
90145
write(buffer, callback) {
91146
this.writer.write(buffer);
92147
if (callback) return callback(null);
@@ -103,6 +158,40 @@ class SerialPort extends EventEmitter {
103158
if (callback) callback(null, buffer);
104159
}
105160

161+
async update (options, callback) {
162+
try {
163+
if (
164+
Object.prototype.hasOwnProperty.call(options, 'baudRate')
165+
&& this.baudRate !== options.baudRate
166+
) {
167+
if (this.isOpen) {
168+
// try to quietly close then open the port with the new baudRate
169+
this.isUpdating = true;
170+
await this.close();
171+
this.baudRate = options.baudRate;
172+
await this.open();
173+
this.isUpdating = false;
174+
} else {
175+
this.baudRate = options.baudRate;
176+
}
177+
}
178+
} catch (error) {
179+
if (callback) return callback(error);
180+
throw error;
181+
}
182+
if (callback) callback(null);
183+
}
184+
185+
pause() {
186+
this.pausePromise = new Promise((resolve) => {
187+
this.pauseResolve = resolve;
188+
});
189+
}
190+
191+
resume() {
192+
this.pauseResolve();
193+
}
194+
106195
// TODO: is this correct?
107196
flush(callback) {
108197
//this.port.flush(); // is this sync or a promise?
@@ -118,4 +207,4 @@ class SerialPort extends EventEmitter {
118207
}
119208
}
120209

121-
module.exports = SerialPort;
210+
module.exports = SerialPort;

lib/connection-browser.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,21 @@ Connection.prototype._init = function(callback) {
2525
* Create new serialport instance for the Arduino board, but do not immediately connect.
2626
*/
2727
Connection.prototype._setUpSerial = function(callback) {
28-
this.serialPort = new Serialport('', {
29-
baudRate: this.board.baud,
30-
autoOpen: false
31-
});
32-
this.serialPort.on('open', function() {
33-
// _this.emit('connection:open');
34-
})
35-
return callback(null);
28+
if (this.options.serialPort) {
29+
this.serialPort = this.options.serialPort;
30+
this.serialPort.update({ baudRate: this.board.baud }, function(error) {
31+
return callback(error);
32+
});
33+
} else {
34+
this.serialPort = new Serialport(this.options.port, {
35+
baudRate: this.board.baud,
36+
autoOpen: false
37+
});
38+
this.serialPort.on('open', function() {
39+
// _this.emit('connection:open');
40+
})
41+
return callback(null);
42+
}
3643
};
3744

3845
/**
@@ -198,4 +205,4 @@ Connection.prototype._listPorts = function(callback) {
198205
});
199206
};
200207

201-
module.exports = Connection;
208+
module.exports = Connection;

0 commit comments

Comments
 (0)