diff --git a/pxt-steami/editor/tsconfig.json b/pxt-steami/editor/tsconfig.json index ed1b92a..c3a4f1f 100644 --- a/pxt-steami/editor/tsconfig.json +++ b/pxt-steami/editor/tsconfig.json @@ -1,18 +1,18 @@ { - "compilerOptions": { - "target": "es2017", - "noImplicitAny": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "declaration": true, - "module": "commonjs", - "moduleResolution": "node", - "isolatedModules": false, - "outDir": "../built/editor", - "rootDir": ".", - "newLine": "LF", - "sourceMap": true, - "jsx": "react", - "lib": ["dom", "dom.iterable", "scripthost", "es2017", "ES2018.Promise"] - } + "compilerOptions": { + "target": "es2017", + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "declaration": true, + "module": "commonjs", + "moduleResolution": "node", + "isolatedModules": false, + "outDir": "../built/editor", + "rootDir": ".", + "newLine": "LF", + "sourceMap": true, + "jsx": "react", + "lib": ["dom", "dom.iterable", "scripthost", "es2017", "ES2018.Promise"] + } } diff --git a/pxt-steami/libs/core/enums.d.ts b/pxt-steami/libs/core/enums.d.ts index 8b82158..f3d708e 100644 --- a/pxt-steami/libs/core/enums.d.ts +++ b/pxt-steami/libs/core/enums.d.ts @@ -36,4 +36,24 @@ Reentrant = 8, // MESSAGE_BUS_LISTENER_REENTRANT } + + declare const enum AllColors { + //% block="Red" color=#ff0000 + Red = 0, + //% block="Green" color=#00ff00 + Green = 1, + //% block="Blue" color=#0000ff + Blue = 2, + //% block="Yellow" color=#ffff00 + Yellow = 3, + //% block="Magenta" color=#ff00ff + Magenta = 4, + //% block="Cyan" color=#00ffff + Cyan = 5, + //% block="White" color=#ffffff + White = 6, + } +declare namespace leds { +} + // Auto-generated. Do not edit. Really. diff --git a/pxt-steami/libs/core/leds.cpp b/pxt-steami/libs/core/leds.cpp new file mode 100644 index 0000000..a6bcd33 --- /dev/null +++ b/pxt-steami/libs/core/leds.cpp @@ -0,0 +1,95 @@ +#include "pxt.h" +#include "STeaMi.h" + +enum class AllColors { + //% block="Red" color=#ff0000 + Red, + //% block="Green" color=#00ff00 + Green, + //% block="Blue" color=#0000ff + Blue, + //% block="Yellow" color=#ffff00 + Yellow, + //% block="Magenta" color=#ff00ff + Magenta, + //% block="Cyan" color=#00ffff + Cyan, + //% block="White" color=#ffffff + White +}; + +//% block="leds" weight=100 color=#4287f5 icon="" +namespace leds { +/** + * @brief Set LED RGB off + */ +//% block="set led RGB off" weight=80 group="LED RGB" +//% help=leds/leds_setLedRGBOff +//% blockId="leds_setLedRGBOff" blockGap=8 +void setLedRGBOff() { + STM32Pin *led_b = getPin(LED_RGB_Blue); // BLUE + STM32Pin *led_g = getPin(LED_RGB_Green); // GREEN + STM32Pin *led_r = getPin(LED_RGB_Red); // RED + led_b->setDigitalValue(0); + led_g->setDigitalValue(0); + led_r->setDigitalValue(0); +} + +/** + * @brief Set LED RGB to color + * @param color Color to set + */ +//% block="set led RGB to %color" weight=80 group="LED RGB" +//% help=leds/leds_setLedRGB +//% blockId="leds_setLedRGB" blockGap=8 +void setLedRGB(AllColors color) { + STM32Pin *led_b = getPin(LED_RGB_Blue); // BLUE + STM32Pin *led_g = getPin(LED_RGB_Green); // GREEN + STM32Pin *led_r = getPin(LED_RGB_Red); // RED + + switch (color) { + case AllColors::Red: + led_r->setDigitalValue(1); + led_g->setDigitalValue(0); + led_b->setDigitalValue(0); + break; + case AllColors::Green: + led_r->setDigitalValue(0); + led_g->setDigitalValue(1); + led_b->setDigitalValue(0); + break; + case AllColors::Blue: + led_r->setDigitalValue(0); + led_g->setDigitalValue(0); + led_b->setDigitalValue(1); + break; + case AllColors::Yellow: + led_r->setDigitalValue(1); + led_g->setDigitalValue(1); + led_b->setDigitalValue(0); + break; + case AllColors::Magenta: + led_r->setDigitalValue(1); + led_g->setDigitalValue(0); + led_b->setDigitalValue(1); + break; + case AllColors::Cyan: + led_r->setDigitalValue(0); + led_g->setDigitalValue(1); + led_b->setDigitalValue(1); + break; + case AllColors::White: + led_r->setDigitalValue(1); + led_g->setDigitalValue(1); + led_b->setDigitalValue(1); + break; + default: + led_r->setDigitalValue(0); + led_g->setDigitalValue(0); + led_b->setDigitalValue(0); + break; + } + target_wait_us(300); +}; + +}; // namespace leds \ No newline at end of file diff --git a/pxt-steami/libs/core/pins.h b/pxt-steami/libs/core/pins.h index 5cf2510..b9727fb 100644 --- a/pxt-steami/libs/core/pins.h +++ b/pxt-steami/libs/core/pins.h @@ -1,66 +1,13 @@ #ifndef __PXT_PINS_H #define __PXT_PINS_H -#define CFG_PIN_BTN_USER 94 -#define CFG_PIN_RESET 95 +#define LED_RGB_Blue 42 +#define LED_RGB_Green 43 +#define LED_RGB_Red 44 -#define CFG_PIN_HTS221_SDA 96 -#define CFG_PIN_HTS221_SCL 97 - -#define CFG_PIN_LPS22HB_SDA 98 -#define CFG_PIN_LPS22HB_SCL 99 - -#define CFG_PIN_VL53L0X_SDA 132 -#define CFG_PIN_VL53L0X_SCL 133 -#define CFG_PIN_VL53L0X_SHUT 134 - -#define CFG_PIN_LSM6DSL_SDA 135 -#define CFG_PIN_LSM6DSL_SCL 136 - -#define CFG_PIN_BLE_SPI_MISO 137 -#define CFG_PIN_BLE_SPI_MOSI 138 -#define CFG_PIN_BLE_SPI_SCLK 139 -#define CFG_PIN_BLE_SPI_CS 140 -#define CFG_PIN_BLE_SPI_IRQ 141 -#define CFG_PIN_BLE_RST 142 - -#define CFG_PIN_WIFI_ISM43362_MOSI 224 -#define CFG_PIN_WIFI_ISM43362_MISO 225 -#define CFG_PIN_WIFI_ISM43362_SCK 226 -#define CFG_PIN_WIFI_ISM43362_CS 227 -#define CFG_PIN_WIFI_ISM43362_COMMAND_DATA_READY 228 -#define CFG_PIN_WIFI_ISM43362_RESET 229 -#define CFG_PIN_WIFI_ISM43362_WAKE_UP 230 - -#define CFG_PIN_UART1_TX 231 -#define CFG_PIN_UART1_RX 232 - -#define CFG_PIN_UART2_TX 234 -#define CFG_PIN_UART2_RX 235 - -#define CFG_PIN_UART3_TX 236 -#define CFG_PIN_UART3_RX 237 - -#define CFG_PIN_UART4_TX 289 -#define CFG_PIN_UART4_RX 290 - -#define CFG_PIN_SPI1_MISO 291 -#define CFG_PIN_SPI1_MOSI 292 -#define CFG_PIN_SPI1_SCK 293 - -#define CFG_PIN_SPI2_MISO 294 -#define CFG_PIN_SPI2_MOSI 295 -#define CFG_PIN_SPI2_SCK 296 - -#define CFG_PIN_SPI3_MISO 297 -#define CFG_PIN_SPI3_MOSI 298 -#define CFG_PIN_SPI3_SCK 299 - -#define CFG_PIN_I2C1_SCL 332 -#define CFG_PIN_I2C1_SDA 333 - -#define CFG_PIN_I2C2_SCL 334 -#define CFG_PIN_I2C2_SDA 335 +#define BUTTON_A 7 +#define BUTTON_B 8 +#define BUTTON_MENU 0 #define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10) #define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20) @@ -114,4 +61,4 @@ CodalComponent *lookupComponent(int id); #define PINOP(op) name->op -#endif +#endif \ No newline at end of file diff --git a/pxt-steami/libs/core/pxt.json b/pxt-steami/libs/core/pxt.json index 224758f..f0bc0f7 100644 --- a/pxt-steami/libs/core/pxt.json +++ b/pxt-steami/libs/core/pxt.json @@ -49,7 +49,8 @@ "loops.cpp", "pause.ts", "forever.ts", - "usb.cpp" + "usb.cpp", + "leds.cpp" ], "dependencies": {}, diff --git a/pxt-steami/libs/core/shims.d.ts b/pxt-steami/libs/core/shims.d.ts index 7f144ad..49462df 100644 --- a/pxt-steami/libs/core/shims.d.ts +++ b/pxt-steami/libs/core/shims.d.ts @@ -284,4 +284,27 @@ declare namespace control { function isUSBInitialized(): boolean; } + + + //% block="leds" weight=100 color=#4287f5 icon="" +declare namespace leds { + + /** + * @brief Set LED RGB off + */ + //% block="set led RGB off" weight=80 group="LED RGB" + //% help=leds/leds_setLedRGBOff + //% blockId="leds_setLedRGBOff" blockGap=8 shim=leds::setLedRGBOff + function setLedRGBOff(): void; + + /** + * @brief Set LED RGB to color + * @param color Color to set + */ + //% block="set led RGB to %color" weight=80 group="LED RGB" + //% help=leds/leds_setLedRGB + //% blockId="leds_setLedRGB" blockGap=8 shim=leds::setLedRGB + function setLedRGB(color: AllColors): void; +} + // Auto-generated. Do not edit. Really. diff --git a/pxt-steami/libs/leds/sim/leds.ts b/pxt-steami/libs/leds/sim/leds.ts new file mode 100644 index 0000000..eaf6452 --- /dev/null +++ b/pxt-steami/libs/leds/sim/leds.ts @@ -0,0 +1,44 @@ +namespace pxsim.leds { + enum AllColors { + RED = 0, + GREEN = 1, + BLUE = 2, + YELLOW = 3, + MAGENTA = 4, + CYAN = 5, + WHITE = 6, + } + + function getHexColor(color: AllColors): string { + switch (color) { + case AllColors.RED: + return '#ff0000'; + case AllColors.GREEN: + return '#00ff00'; + case AllColors.BLUE: + return '#0000ff'; + case AllColors.YELLOW: + return '#ffff00'; + case AllColors.MAGENTA: + return '#ff00ff'; + case AllColors.CYAN: + return '#00ffff'; + case AllColors.WHITE: + return '#ffffff'; + default: + return '#000000'; + } + } + + export function setLedRGBOff(): void { + let ledState = pxsim.ledState(); + ledState.setState(6, false, '#000000', 0); + runtime.queueDisplayUpdate(); + } + + export function setLedRGB(color: AllColors): void { + let ledState = pxsim.ledState(); + ledState.setState(6, true, getHexColor(color), 7); + runtime.queueDisplayUpdate(); + } +} diff --git a/pxt-steami/libs/leds/sim/ledsBoard.ts b/pxt-steami/libs/leds/sim/ledsBoard.ts new file mode 100644 index 0000000..45ab94e --- /dev/null +++ b/pxt-steami/libs/leds/sim/ledsBoard.ts @@ -0,0 +1,64 @@ +namespace pxsim { + export class LedState { + states: { + pin: number; + on: boolean; + color: string; + intensity: number; + }[] = []; + + constructor( + states: { + pin: number; + on: boolean; + color: string; + intensity: number; + }[], + ) { + this.states = states; + } + + setState( + pin: number, + on: boolean, + color: string, + intensity: number, + ): void { + const state = this.states.find(s => s.pin === pin); + if (state) { + state.on = on; + state.color = color; + state.intensity = intensity; + } else { + this.states.push({ pin, on, color, intensity }); + } + } + + getState(pin: number): { + pin: number; + on: boolean; + color: string; + intensity: number; + } { + const state = this.states.find(s => s.pin === pin); + return state; + } + + getAllStates(): { + pin: number; + on: boolean; + color: string; + intensity: number; + }[] { + return this.states; + } + } + + export interface LedBoard extends CommonBoard { + ledState: LedState; + } + + export function ledState(): LedState { + return (board() as LedBoard).ledState; + } +} diff --git a/pxt-steami/libs/leds/sim/tsconfig.json b/pxt-steami/libs/leds/sim/tsconfig.json new file mode 100644 index 0000000..7e8727c --- /dev/null +++ b/pxt-steami/libs/leds/sim/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es5", + "noImplicitAny": true, + "noImplicitReturns": true, + "rootDir": ".", + "newLine": "LF", + "sourceMap": true + } +} diff --git a/pxt-steami/sim/dalboard.ts b/pxt-steami/sim/dalboard.ts index 447f2d6..0055662 100644 --- a/pxt-steami/sim/dalboard.ts +++ b/pxt-steami/sim/dalboard.ts @@ -41,7 +41,11 @@ namespace pxsim { } } - export class DalBoard extends CoreBoard { + export class DalBoard extends CoreBoard implements LedBoard { + ledState: LedState; + buttonState: CommonButtonState; + edgeConnectorState: EdgeConnectorState; + viewHost: visuals.BoardHost; view: SVGSVGElement; @@ -51,6 +55,9 @@ namespace pxsim { SteamiPinName.init(); this.bus.setNotify(DAL.DEVICE_ID_NOTIFY, DAL.DEVICE_ID_NOTIFY_ONE); + + //LEDs + this.builtinParts['leds'] = this.ledState = new LedState([]); } receiveMessage(msg: SimulatorMessage) { @@ -115,7 +122,7 @@ namespace pxsim { let b = new DalBoard(); runtime.board = b; runtime.postError = e => { - // TODO implement this in the simulator to display the error + // TODO runtime.updateDisplay(); }; } diff --git a/pxt-steami/sim/visuals/board.svg b/pxt-steami/sim/visuals/board.svg index 043008f..afed8db 100644 --- a/pxt-steami/sim/visuals/board.svg +++ b/pxt-steami/sim/visuals/board.svg @@ -4547,4 +4547,4 @@ - + \ No newline at end of file diff --git a/pxt-steami/sim/visuals/board.ts b/pxt-steami/sim/visuals/board.ts index 4d8f97a..cff1b5e 100644 --- a/pxt-steami/sim/visuals/board.ts +++ b/pxt-steami/sim/visuals/board.ts @@ -460,6 +460,8 @@ namespace pxsim.visuals { let state = this.board; if (!state) return; + this.UpdateLeds(); + if (!runtime || runtime.dead) pxsim.U.addClass(this.element, 'grayscale'); else pxsim.U.removeClass(this.element, 'grayscale'); @@ -510,6 +512,73 @@ namespace pxsim.visuals { } } + private UpdateLeds() { + const leds = this.board.ledState.getAllStates(); + leds.forEach((state, i) => { + if (state.on) { + this.makeLedGlow( + this.element.getElementById( + 'LED' + state.pin, + ) as SVGElement, + state.color, + state.intensity, + ); + } else { + this.makeLedGlow( + this.element.getElementById( + 'LED' + state.pin, + ) as SVGElement, + '#ffffff', + state.intensity, + ); + } + }); + } + + private makeLedGlow(led: SVGElement, color: string, intensity: number) { + const filterId = `glow-${color.replace('#', '')}-${intensity}`; + let glowFilter = this.element.getElementById(filterId); + + if (!glowFilter) { + glowFilter = svg.child(this.defs, 'filter', { + id: filterId, + x: '-50%', + y: '-50%', + width: '200%', + height: '200%', + }); + + svg.child(glowFilter, 'feGaussianBlur', { + stdDeviation: (intensity / 2).toString(), + result: 'blur', + }); + + svg.child(glowFilter, 'feFlood', { + 'flood-color': color, + 'flood-opacity': '1', + result: 'color', + }); + + svg.child(glowFilter, 'feComposite', { + in: 'color', + in2: 'blur', + operator: 'in', + result: 'coloredBlur', + }); + + let merge = svg.child(glowFilter, 'feMerge', {}); + for (let i = 0; i < Math.max(2, intensity); i++) { + svg.child(merge, 'feMergeNode', { in: 'coloredBlur' }); + } + svg.child(merge, 'feMergeNode', { in: 'SourceGraphic' }); + } + + const elements = led.querySelectorAll('*'); + Array.from(elements).forEach(element => { + element.setAttribute('filter', `url(#${filterId})`); + }); + } + private buildDom() { this.element = new DOMParser() .parseFromString(BOARD_SVG, 'image/svg+xml')