stk500-esm
Version:
A modern, ESM-compatible, TypeScript implementation of the STK500v1 protocol for programming Arduino boards directly from Node.js or the browser.
63 lines (62 loc) • 2.26 kB
JavaScript
import receiveData from "./receiveData.js";
import Constants from "./constants.js";
/**
* Sends a command to the device and waits for a response.
*
* @param stream - The read/write stream for communication with the device.
* @param opt - Options for the command, including the command itself and response expectations.
* @returns A promise that resolves with the response data as a Uint8Array.
* @throws Will throw an error if sending fails, if the response doesn't match expectations, or if a timeout occurs.
*/
export default async function sendCommand(stream, opt) {
const timeout = opt.timeout ?? 0;
let responseData = null;
let responseLength = 0;
if (opt.responseData && opt.responseData.length > 0) {
responseData = opt.responseData;
}
if (responseData) {
responseLength = responseData.length;
}
if (opt.responseLength) {
responseLength = opt.responseLength;
}
let cmd;
if (Array.isArray(opt.cmd)) {
cmd = new Uint8Array([...opt.cmd, Constants.Sync_CRC_EOP]);
}
else {
cmd = opt.cmd;
}
try {
await new Promise((resolve, reject) => {
stream.write(cmd, (err) => {
if (err) {
reject(new Error(`Sending ${Array.from(cmd)
.map((b) => b.toString(16))
.join("")}: ${err.message}`));
}
else {
resolve();
}
});
});
const data = await receiveData(stream, timeout, responseLength);
if (responseData &&
!data.every((value, index) => value === responseData[index])) {
throw new Error(`${Array.from(cmd)
.map((b) => b.toString(16))
.join("")} response mismatch: ${Array.from(data)
.map((b) => b.toString(16))
.join("")}, ${Array.from(responseData)
.map((b) => b.toString(16))
.join("")}`);
}
return data;
}
catch (error) {
throw new Error(`Sending ${Array.from(cmd)
.map((b) => b.toString(16))
.join("")}: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}