Skip to content

Commit

Permalink
Merge pull request #30 from CorvusPrudens/dev
Browse files Browse the repository at this point in the history
Improved Daisy error recovery
  • Loading branch information
CorvusPrudens authored Oct 13, 2023
2 parents 5dd699a + a1291b7 commit cd72c46
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 78 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jspatcher/jspatcher",
"version": "0.3.6",
"version": "0.3.7",
"description": "patcher js",
"scripts": {
"prebuild": "node ./src/scripts/patchSemanticUICss.js",
Expand Down
96 changes: 32 additions & 64 deletions src/components/topmenu/FlashMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ export default class FlashMenu extends React.PureComponent<P, S> {

const data = await this.props.env.activeEditor.instance.serialize();
const url = `${process.env.WS_DOMAIN}/ws/download/`;

try {

const webSocket = new WebSocket(url);

const filename = this.props.env.activeEditor.instance.file?.name.replace("/", "_").replace(".bell", ".zip") || "project.zip";
Expand Down Expand Up @@ -112,11 +115,13 @@ export default class FlashMenu extends React.PureComponent<P, S> {

this.setState({ building: false });
};
} catch (e) {
this.setState({ build_message: "Unexpected error occurred. Please try again.", building: false, build_error: true })
};
}

handleErrorResponse = (event: MessageEvent<any>) => {
try {
// console.log(event.data);
if (typeof event.data === 'string') {
let json = JSON.parse(event.data.toString('utf-8'));
this.state.build_error = true;
const error = json.Err;
Expand All @@ -143,7 +148,7 @@ export default class FlashMenu extends React.PureComponent<P, S> {
}
}
return null;
} catch (error) {
} else {
return event.data;
}
}
Expand All @@ -161,74 +166,37 @@ export default class FlashMenu extends React.PureComponent<P, S> {

const data = await this.props.env.activeEditor.instance.serialize();
const url = `${process.env.WS_DOMAIN}/ws/compile/`;
const webSocket = new WebSocket(url);

webSocket.onopen = (event) => {
this.setState({ build_message: "Building program...", building: true, build_error: false, progress: null });
webSocket.send(data);
};
try {

// For now, we'll simply assume the connection ends here
webSocket.onmessage = async (event) => {
const webSocket = new WebSocket(url);

try {
// console.log(event.data);
let json = JSON.parse(event.data.toString('utf-8'));
this.state.build_error = true;
const error = json.Err;
webSocket.onopen = (event) => {
this.setState({ build_message: "Building program...", building: true, build_error: false, progress: null });
webSocket.send(data);
};

if (typeof error === 'string') {
this.state.error_message = `Encountered "${error}" error!`;
} else {
const key = Object.keys(error)[0];

// Error reporting
if (key === 'InternalError') {
const inner_key = Object.keys(error[key])[0];
this.state.error_message = `Encountered internal "${inner_key}" error!`;
if (inner_key === 'CompileError') {
this.props.env.newLog("none", inner_key, error[key][inner_key].program.makefile);
this.props.env.newLog("none", inner_key, error[key][inner_key].program.cpp);
this.props.env.newLog("none", inner_key, error[key][inner_key].stderr);
} else {
this.props.env.newLog("none", inner_key, JSON.stringify(error[key][inner_key]));
}
} else {
this.state.error_message = `Encountered "${key}" error!`;
this.props.env.newLog("none", key, JSON.stringify(error[key]));
}
// For now, we'll simply assume the connection ends here
webSocket.onmessage = async (event) => {

const data = this.handleErrorResponse(event);
console.log(data);
if (data) {
let blob = data as Blob;
const buffer = await blob.arrayBuffer();
this.props.env.newLog("none", "USB", `Flashing ${buffer.byteLength} bytes to device.`);
await this.doDownload(buffer);
}
} catch (error) {
// var saveData = (function () {
// var a = document.createElement("a");
// document.body.appendChild(a);

// a.style.display = "none";
// return function (data: BinaryData, fileName: string) {
// var blob = new Blob([data], { type: "octet/stream" });
// var url = window.URL.createObjectURL(blob);
// a.href = url;
// a.download = fileName;
// a.click();
// window.URL.revokeObjectURL(url);
// };
// }());

// saveData(event.data, "patcher.bin");
let data = event.data as Blob;
const buffer = await data.arrayBuffer();
this.props.env.newLog("none", "USB", `Flashing ${buffer.byteLength} bytes to device.`);
await this.doDownload(buffer);
}

// this.state.building = false;
// this.forceUpdate();
this.setState({ building: false });
};
this.setState({ building: false });
};

webSocket.onerror = () => {
this.setState({ build_message: "Error connecting to server. Please try again.", building: false, build_error: true });
};
webSocket.onerror = () => {
this.setState({ build_message: "Error connecting to server. Please try again.", building: false, build_error: true });
};
} catch (e) {
this.setState({ build_message: "Unexpected error occurred. Please try again.", building: false, build_error: true })
}
};
onDisconnect(reason?: string) {
if (reason) {
Expand Down
42 changes: 31 additions & 11 deletions src/core/hardware/Compatibility.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
import { BasePin, USBBus } from "./types";
import { BasePin, I2CBus, USBBus } from "./types";

export function compatibleBus(pins: BasePin[]) {
// USB Compatibility Check
function compatibleI2c(pins: BasePin[]) {
let sdaCount = 0;
let sclCount = 0;

pins.forEach((pin) => {
if (pin.busCapabilities) {
for (const busType in pin.busCapabilities) {
const bus = pin.busCapabilities[busType] as I2CBus;
if (bus.i2c) {
// Increment counters based on I2C capabilities
if (bus.sda) sdaCount++;
if (bus.scl) sclCount++;
}
}
}
});

return sdaCount > 1 || sclCount > 1;
}

function compatibleUsb(pins: BasePin[]) {
let dplusCount = 0;
let dminusCount = 0;
let idCount = 0;
Expand Down Expand Up @@ -36,11 +55,16 @@ export function compatibleBus(pins: BasePin[]) {
return true;
}

// Continue with other bus checks (SPI, I2C, etc.) here when you want to expand compatibility checks.
return false;
}

export function compatibleDigital(pins: BasePin[]) {
function compatibleBus(pins: BasePin[]) {
let compatibilities = [compatibleUsb, compatibleI2c];

return compatibilities.some((f) => f(pins));
}

function compatibleDigital(pins: BasePin[]) {
let num_outputs = pins.filter((p) => p.digitalOutput && !p.digitalInput).length;

if (num_outputs > 1) {
Expand All @@ -65,7 +89,7 @@ export function compatibleDigital(pins: BasePin[]) {
return some_valid_config;
}

export function compatibleAnalog(pins: BasePin[]) {
function compatibleAnalog(pins: BasePin[]) {
let num_outputs = pins.filter((p) => p.analogOutput && !p.analogInput).length;

if (num_outputs > 1) {
Expand Down Expand Up @@ -95,9 +119,5 @@ export function compatiblePins(pins: BasePin[]) {

// If any of the compatibilities are true, then the pins are compatible
// TODO -- this should probably return exactly which aspects are compatible
if (compatibilities.some((f) => f(pins))) {
return true;
}

return false;
return compatibilities.some((f) => f(pins));
}
2 changes: 2 additions & 0 deletions src/core/hardware/objects/hardware/HardwareObjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import AMux from "./Mux";
import Button from "./Button";
import Cv from "./Cv";
import UsbMidi from "./UsbMidi";
import Mpr121 from "./Mpr121";

export default {
knob: Knob,
Expand All @@ -14,4 +15,5 @@ export default {
button: Button,
cv: Cv,
usbmidi: UsbMidi,
mpr121: Mpr121,
};
72 changes: 72 additions & 0 deletions src/core/hardware/objects/hardware/Mpr121.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { IInletsMeta, IOutletsMeta } from "../../../objects/base/AbstractObject";
import type { IIosMeta, IPropsMeta, THardwareMetaType } from "../base/AbstractHardwareObject";
import DefaultObject from "../base/DefaultHardwareObject";

export default class Mpr121 extends DefaultObject<{}, {}, any[], any[], []> {
static author = "Corvus Prudens";
static version = "v1.0.0";
static description = "MPR121 Capacitive Touch Sensor";
static ios: IIosMeta = [
{
pin: {
pinName: "sda",
busCapabilities: { I2C: { i2c: true, sda: true, scl: false } },
},
type: "anything",
description: "I2C Data Pin",
},
{
pin: {
pinName: "scl",
busCapabilities: { I2C: { i2c: true, sda: false, scl: true } },
},
type: "anything",
description: "I2C Clock Pin",
},
];

static patcherOutlets: IOutletsMeta = [
{
type: "anything",
description: "Button index and state pair (0 = no touch, 1 = touch)",
},
];

static props: IPropsMeta = {
address: {
type: "number",
default: 90,
description: "The I2C address of the device",
alwaysSerialize: true,
},
touchThreshold: {
type: "number",
default: 12,
description: "sets the touch detection threshold (0-255)",
alwaysSerialize: true,
},
releaseThreshold: {
type: "number",
default: 6,
description: "sets the release detection threshold (0-255)",
alwaysSerialize: true,
},
};

subscribe() {
super.subscribe();

this.on("preInit", () => {
this.ios = [
{
edge: "T",
position: 0.25,
},
{
edge: "T",
position: 0.75,
},
];
});
}
}

0 comments on commit cd72c46

Please sign in to comment.