We have abstractions of the Port
and Serial
classes.
The Serial
class handles:
- Getting a list of available ports (WebUSB devices)
- Requesting access to one of those ports
Connecting to a WebUSB device means passing the WebUSBPlinky
constructor that extends Port
to Serial.requestPort()
:
let port;
try {
port = await Serial.requestPort(WebUSBPlinky);
await port.connect();
}
catch(err) {
console.error(err);
}
The Port
superclass, in the connect()
function, handles:
- Defining the read loop
- Opening the device
- Setting the endpoint
- Selecting the device configuration
- Getting the endpoint alternates so they can be accessed via shared pointers
- Claiming the device
- Starting the read loop
Whenever the read loop receives data, it calls the onReceive
function, which is implemented in the WebUSBPlinky.js
file. If there is an error, it calls the onReceiveError
function.
State machine to interface with Plinky through WebUSBPlinky
. It is used to wire up the UI to the machine.
PlinkyMachine
has these states:
- disconnected
- connecting
- connected
- loadPatch
- savePatch
- error
They should be pretty self-explanatory. The loadPatch
and savePatch
states invoke their own child machines, so you can keep track of the overall state easier in the UI.
This file contains the child machines for patch loading and saving.
This machine will send the header to get a whole patch from Plinky, process the header, check how many bytes it needs to read, then loops through the input data until it's satisfied.
This machine will send the header to save a patch to Plinky, then sends the data in 2*8 byte chunks.
The WebUSBPlinky
class implements:
onReceive
onReceiveError
Both will try to advance the PlinkyMachine
directly through a data
event. If the state is currently processing a child machine (in the loadPatch
and savePatch
state), it will try to advance the child machine.