From 1fe25d2569a19513ba9cdd459190b9409a2dd299 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Tue, 4 Oct 2022 14:59:25 +0100 Subject: [PATCH 1/2] Improve pin stub so servo code doesn't explode. See https://github.com/microbit-foundation/micropython-microbit-v2-simulator/issues/76 --- src/board/index.ts | 43 +++++++++++++++++++++++++++---- src/board/pins.ts | 60 +++++++++++++++++++++++++++++++++++++++++--- src/jshal.h | 2 ++ src/jshal.js | 8 ++++++ src/microbithal_js.c | 30 ++-------------------- 5 files changed, 107 insertions(+), 36 deletions(-) diff --git a/src/board/index.ts b/src/board/index.ts index 1a454ced..9cf57b4c 100644 --- a/src/board/index.ts +++ b/src/board/index.ts @@ -8,13 +8,29 @@ import { MICROBIT_HAL_PIN_P0, MICROBIT_HAL_PIN_P1, MICROBIT_HAL_PIN_P2, + MICROBIT_HAL_PIN_P3, + MICROBIT_HAL_PIN_P4, + MICROBIT_HAL_PIN_P5, + MICROBIT_HAL_PIN_P6, + MICROBIT_HAL_PIN_P7, + MICROBIT_HAL_PIN_P8, + MICROBIT_HAL_PIN_P9, + MICROBIT_HAL_PIN_P10, + MICROBIT_HAL_PIN_P11, + MICROBIT_HAL_PIN_P12, + MICROBIT_HAL_PIN_P13, + MICROBIT_HAL_PIN_P14, + MICROBIT_HAL_PIN_P15, + MICROBIT_HAL_PIN_P16, + MICROBIT_HAL_PIN_P19, + MICROBIT_HAL_PIN_P20, } from "./constants"; import * as conversions from "./conversions"; import { DataLogging } from "./data-logging"; import { Display } from "./display"; import { FileSystem } from "./fs"; import { Microphone } from "./microphone"; -import { Pin } from "./pins"; +import { Pin, StubPin, TouchPin } from "./pins"; import { Radio } from "./radio"; import { RangeSensor, State } from "./state"; import { ModuleWrapper } from "./wasm"; @@ -121,7 +137,7 @@ export class Board { ), ]; this.pins = Array(33); - this.pins[MICROBIT_HAL_PIN_FACE] = new Pin( + this.pins[MICROBIT_HAL_PIN_FACE] = new TouchPin( "pinLogo", { element: this.svg.querySelector("#Logo")!, @@ -129,9 +145,26 @@ export class Board { }, onChange ); - this.pins[MICROBIT_HAL_PIN_P0] = new Pin("pin0", null, onChange); - this.pins[MICROBIT_HAL_PIN_P1] = new Pin("pin1", null, onChange); - this.pins[MICROBIT_HAL_PIN_P2] = new Pin("pin2", null, onChange); + this.pins[MICROBIT_HAL_PIN_P0] = new TouchPin("pin0", null, onChange); + this.pins[MICROBIT_HAL_PIN_P1] = new TouchPin("pin1", null, onChange); + this.pins[MICROBIT_HAL_PIN_P2] = new TouchPin("pin2", null, onChange); + this.pins[MICROBIT_HAL_PIN_P3] = new StubPin("pin3"); + this.pins[MICROBIT_HAL_PIN_P4] = new StubPin("pin4"); + this.pins[MICROBIT_HAL_PIN_P5] = new StubPin("pin5"); + this.pins[MICROBIT_HAL_PIN_P6] = new StubPin("pin6"); + this.pins[MICROBIT_HAL_PIN_P7] = new StubPin("pin7"); + this.pins[MICROBIT_HAL_PIN_P8] = new StubPin("pin8"); + this.pins[MICROBIT_HAL_PIN_P9] = new StubPin("pin9"); + this.pins[MICROBIT_HAL_PIN_P10] = new StubPin("pin10"); + this.pins[MICROBIT_HAL_PIN_P11] = new StubPin("pin11"); + this.pins[MICROBIT_HAL_PIN_P12] = new StubPin("pin12"); + this.pins[MICROBIT_HAL_PIN_P13] = new StubPin("pin13"); + this.pins[MICROBIT_HAL_PIN_P14] = new StubPin("pin14"); + this.pins[MICROBIT_HAL_PIN_P15] = new StubPin("pin15"); + this.pins[MICROBIT_HAL_PIN_P16] = new StubPin("pin16"); + this.pins[MICROBIT_HAL_PIN_P19] = new StubPin("pin19"); + this.pins[MICROBIT_HAL_PIN_P20] = new StubPin("pin20"); + this.audio = new Audio(); this.temperature = new RangeSensor("temperature", -5, 50, 21, "°C"); this.accelerometer = new Accelerometer(onChange); diff --git a/src/board/pins.ts b/src/board/pins.ts index 2b399a4b..b8ee3fa8 100644 --- a/src/board/pins.ts +++ b/src/board/pins.ts @@ -1,8 +1,61 @@ import { RangeSensor, State } from "./state"; -export class Pin { +export interface Pin { state: RangeSensor; + updateTranslations(): void; + + setValue(value: any): void; + + isTouched(): boolean; + + boardStopped(): void; + + setAnalogPeriodUs(period: number): number; + + getAnalogPeriodUs(): number; +} + +const initialAnalogPeriodUs = -1; + +abstract class BasePin implements Pin { + state: RangeSensor; + + // For now we just allow get/set of this value + // but don't do anything with it. + private analogPeriodUs: number = initialAnalogPeriodUs; + + constructor(id: string) { + this.state = new RangeSensor(id, 0, 1, 0, undefined); + } + + updateTranslations() {} + + setValue(value: any): void { + this.state.value = value; + } + + setAnalogPeriodUs(period: number) { + this.analogPeriodUs = period; + return 0; + } + + getAnalogPeriodUs() { + return this.analogPeriodUs; + } + + isTouched(): boolean { + return false; + } + + boardStopped() { + this.analogPeriodUs = initialAnalogPeriodUs; + } +} + +export class StubPin extends BasePin {} + +export class TouchPin extends BasePin { private _mouseDown: boolean = false; private keyListener: (e: KeyboardEvent) => void; @@ -16,7 +69,7 @@ export class Pin { private ui: { element: SVGElement; label: () => string } | null, private onChange: (changes: Partial) => void ) { - this.state = new RangeSensor(id, 0, 1, 0, undefined); + super(id); if (this.ui) { const { element, label } = this.ui; @@ -76,7 +129,8 @@ export class Pin { } private setValueInternal(value: any, internalChange: boolean) { - this.state.setValue(value); + super.setValue(value); + if (internalChange) { this.onChange({ [this.id]: this.state, diff --git a/src/jshal.h b/src/jshal.h index 29811063..d0ca73e3 100644 --- a/src/jshal.h +++ b/src/jshal.h @@ -48,6 +48,8 @@ int mp_js_hal_button_get_presses(int button); bool mp_js_hal_button_is_pressed(int button); bool mp_js_hal_pin_is_touched(int pin); +int mp_js_hal_pin_get_analog_period_us(int pin); +int mp_js_hal_pin_set_analog_period_us(int pin, int period); int mp_js_hal_display_get_pixel(int x, int y); void mp_js_hal_display_set_pixel(int x, int y, int value); diff --git a/src/jshal.js b/src/jshal.js index 54f699ca..c4cec674 100644 --- a/src/jshal.js +++ b/src/jshal.js @@ -127,6 +127,14 @@ mergeInto(LibraryManager.library, { return Module.board.pins[pin].isTouched(); }, + mp_js_hal_pin_get_analog_period_us: function (/** @type {number} */ pin) { + return Module.board.pins[pin].getAnalogPeriodUs(); + }, + + mp_js_hal_pin_set_analog_period_us: function (/** @type {number} */ pin, /** @type {number} */ period) { + return Module.board.pins[pin].setAnalogPeriodUs(period); + }, + mp_js_hal_display_get_pixel: function ( /** @type {number} */ x, /** @type {number} */ y diff --git a/src/microbithal_js.c b/src/microbithal_js.c index 27b8ad78..f9d2460f 100644 --- a/src/microbithal_js.c +++ b/src/microbithal_js.c @@ -113,37 +113,11 @@ int microbit_hal_pin_set_analog_period_us(int pin, int period) { mp_js_hal_audio_period_us(period); return 0; } - - /* - // Calling setAnalogPeriodUs requires the pin to be in analog-out mode. So - // test for this mode by first calling getAnalogPeriodUs, and if it fails then - // attempt to configure the pin in analog-out mode by calling setAnalogValue. - if ((ErrorCode)pin_obj[pin]->getAnalogPeriodUs() == DEVICE_NOT_SUPPORTED) { - if (pin_obj[pin]->setAnalogValue(0) != DEVICE_OK) { - return -1; - } - } - - // Set the analog period. - if (pin_obj[pin]->setAnalogPeriodUs(period) == DEVICE_OK) { - return 0; - } else { - return -1; - } - */ - return -1; + return mp_js_hal_pin_set_analog_period_us(pin, period); } int microbit_hal_pin_get_analog_period_us(int pin) { - /* - int period = pin_obj[pin]->getAnalogPeriodUs(); - if (period != DEVICE_NOT_SUPPORTED) { - return period; - } else { - return -1; - } - */ - return -1; + return mp_js_hal_pin_get_analog_period_us(pin); } void microbit_hal_pin_set_touch_mode(int pin, int mode) { From 9170221a8dc3457174be1f1ae55b78f6309d5b4f Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Tue, 4 Oct 2022 16:23:22 +0100 Subject: [PATCH 2/2] Use setter as previously. --- src/board/pins.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/board/pins.ts b/src/board/pins.ts index b8ee3fa8..da5d4435 100644 --- a/src/board/pins.ts +++ b/src/board/pins.ts @@ -32,7 +32,7 @@ abstract class BasePin implements Pin { updateTranslations() {} setValue(value: any): void { - this.state.value = value; + this.state.setValue(value); } setAnalogPeriodUs(period: number) {