diff --git a/docs/reference/music/built-in-melody.md b/docs/reference/music/built-in-melody.md new file mode 100644 index 000000000..62c7994eb --- /dev/null +++ b/docs/reference/music/built-in-melody.md @@ -0,0 +1,51 @@ +# built In Melody + +Get a melody string for a built-in melody. + +```sig +music.builtInMelody(Melodies.Dadadadum) +``` + +A collection of built-in melodies are available. You choose one by selecting the name of the melody. + +## Parameters + +* **melody**: A melody name. The available melodies are: + +>* `dadadum` +>* `entertainer` +>* `prelude` +>* `ode` +>* `nyan` +>* `ringtone` +>* `funk` +>* `blues` +>* `birthday` +>* `wedding` +>* `funeral` +>* `punchline` +>* `baddy` +>* `chase` +>* `ba ding` +>* `wawawawaa` +>* `jump up` +>* `jump down` +>* `power up` +>* `power down` + +## Returns + +* a [string](/types/string) that contains the melody. + +## Example + +Play the built-in melody for **blues**. + +```blocks +music.startMelody(music.builtInMelody(Melodies.Blues), MelodyOptions.Once) +``` + +## See also + +[start melody](/reference/music/start-melody), +[built-in sound effect](/reference/music/builtin-sound-effect) \ No newline at end of file diff --git a/docs/reference/music/built-in-playable-melody.md b/docs/reference/music/built-in-playable-melody.md new file mode 100644 index 000000000..320d32f9a --- /dev/null +++ b/docs/reference/music/built-in-playable-melody.md @@ -0,0 +1,50 @@ +# built In Playable Melody + +Get a playable sound object for a built-in melody. + +```sig +music.builtInPlayableMelody(Melodies.Dadadadum) +``` + +A collection of built-in melodies are available as [playable](/types/playable) sound objects. You choose one by selecting the name of the melody. + +## Parameters + +* **melody**: A melody name. The available melodies are: + +>* `dadadum` +>* `entertainer` +>* `prelude` +>* `ode` +>* `nyan` +>* `ringtone` +>* `funk` +>* `blues` +>* `birthday` +>* `wedding` +>* `funeral` +>* `punchline` +>* `baddy` +>* `chase` +>* `ba ding` +>* `wawawawaa` +>* `jump up` +>* `jump down` +>* `power up` +>* `power down` + +## Returns + +* a [playable](/types/playable) object that contains the melody. + +## Example + +Play the built-in melody for **blues**. + +```blocks +music.play(music.builtInPlayableMelody(Melodies.Blues), music.PlaybackMode.InBackground) +``` + +## See also + +[built-in sound effect](/reference/music/builtin-sound-effect) \ No newline at end of file diff --git a/docs/reference/music/is-sound-playing.md b/docs/reference/music/is-sound-playing.md new file mode 100644 index 000000000..d61d49b86 --- /dev/null +++ b/docs/reference/music/is-sound-playing.md @@ -0,0 +1,38 @@ +# is Sound Playing + +Check if sound is playing at any sound output. + +```sig +music.isSoundPlaying() +``` + +### ~ reminder + +This function requires the Calliope mini 3 hardware. If you use this function with a Calliope mini 1 or 2 board, you will see the **927** error code on the screen. + +### ~ + +Sound is played at the built-in speaker or at the selected audio output pin. You can check if any sound is currently being played at any of these outputs. + +## Returns + +* a [boolean](/types/boolean) value that is `true` if sound is being played at the built-in speaker or at the audio pin. The value is `false` otherwise. + +## Example #example + +Stop all sounds if any are currently playing. + +```blocks +if (music.isSoundPlaying()) { + music.stopAllSounds() +} +``` + +## See also + +[set built-in speaker enabled](/reference/music/set-built-in-speaker-enabled), +[set audio pin](/reference/pins/set-audio-pin) + +```package +music +``` diff --git a/docs/reference/pins/analog-pin.md b/docs/reference/pins/analog-pin.md new file mode 100644 index 000000000..01f7b6c6d --- /dev/null +++ b/docs/reference/pins/analog-pin.md @@ -0,0 +1,32 @@ +# analog Pin + +Get an analog pin number for a pin identifier. + +```sig +pins._analogPin(AnalogPin.P0) +``` + +## Parameters + +* **pin**: a pin identifier for an analog pin (`P0` through `P20`). + +## Returns + +* a pin [number](/types/number) for the pin identifier. + +## Example + +Set an analog pin variable for `P1`, read pin `P1`, and show the input value on the LED screen. + +```blocks +let myPin = AnalogPin.P1 +basic.forever(function() { + let value = pins.analogReadPin(myPin) + basic.showNumber(value) +}) +``` + +## See also + +[analog read pin](/reference/pins/analog-read-pin), +[analog write pin](/reference/pins/analog-write-pin) \ No newline at end of file diff --git a/docs/reference/pins/digital-pin.md b/docs/reference/pins/digital-pin.md new file mode 100644 index 000000000..f58c57e00 --- /dev/null +++ b/docs/reference/pins/digital-pin.md @@ -0,0 +1,43 @@ +# digital Pin + +Get an digital pin number for a pin identifier. + +```sig +pins._digitalPin(DigitalPin.P3) +``` + +## Parameters + +* **pin**: a pin identifier for an digital pin (`P0` through `P20`). + +## Returns + +* a pin [number](/types/number) for the pin identifier. + +## Example: football score keeper + +This program reads pin `P0` to find when a goal is scored. When `P0` +is `1`, the program makes the score bigger and plays a buzzer sound +through `P2` with ``||pins:digital write pin||``. Use pin variables +to set the read and write pin numbers. + +```blocks +let score = 0 +let readPin = DigitalPin.P0 +let writePin = DigitalPin.P2 +basic.showNumber(score) +basic.forever(() => { + if (pins.digitalReadPin(readPin) == 1) { + score++; + pins.digitalWritePin(writePin, 1) + basic.showNumber(score) + basic.pause(1000) + pins.digitalWritePin(writePin, 0) + } +}) +``` + +## See also + +[digital read pin](/reference/pins/digital-read-pin), +[digital write pin](/reference/pins/digital-write-pin) diff --git a/docs/static/download/full-reset.gif b/docs/static/download/full-reset.gif new file mode 100644 index 000000000..96b30a047 Binary files /dev/null and b/docs/static/download/full-reset.gif differ diff --git a/docs/teachertool/catalog.json b/docs/teachertool/catalog.json index 12481b5a0..2dfb2f16a 100644 --- a/docs/teachertool/catalog.json +++ b/docs/teachertool/catalog.json @@ -3,7 +3,7 @@ { "id": "35610CA0-38F8-4CCE-BAB9-99593DB3358A", "use": "responds_to_events", - "template": "Responds to at least ${count} different events", + "template": "Responds to at least ${count} different event(s)", "description": "At least the specified number of event blocks are present.", "docPath": "/teachertool", "maxCount": 1, @@ -38,7 +38,7 @@ { "id": "2CA4A5DA-4690-4514-97F5-2FE145AB3A59", "use": "uses_led_coordinates", - "template": "Uses LED coordinates at least ${count} times", + "template": "Uses LED coordinates at least ${count} time(s)", "description": "Uses blocks with LED coordinate inputs at least the specified number of times.", "docPath": "/teachertool", "maxCount": 1, diff --git a/editor/flash.ts b/editor/flash.ts index b1c37aaa6..705f71cca 100644 --- a/editor/flash.ts +++ b/editor/flash.ts @@ -6,6 +6,8 @@ const dataAddr = 0x20002000; const stackAddr = 0x20001000; const FULL_FLASH_TIMEOUT = 100000; // 100s const PARTIAL_FLASH_TIMEOUT = 60000; // 60s +const CONNECTION_CHECK_TIMEOUT = 2000; // 2s +const RETRY_DAP_CMD_TIMEOUT = 50; // .05s const flashPageBIN = new Uint32Array([ 0xbe00be00, // bkpt - LR is set to this @@ -270,7 +272,7 @@ class DAPWrapper implements pxt.packetio.PacketIOWrapper { private async getBaudRate() { const readSerialSettings = new Uint8Array([0x81]) // get serial settings const serialSettings = await this.dapCmd(readSerialSettings) - const baud = (serialSettings[4] << 24)+ (serialSettings[3] << 16) + (serialSettings[2] << 8) + serialSettings[1] + const baud = (serialSettings[4] << 24) + (serialSettings[3] << 16) + (serialSettings[2] << 8) + serialSettings[1] return baud } @@ -334,7 +336,7 @@ class DAPWrapper implements pxt.packetio.PacketIOWrapper { await this.setBaudRate() // only init after setting baud rate, in case we got reset await this.cortexM.init() - if (resetOnConnection){ + if (resetOnConnection) { log(`reset cortex`) await this.cortexM.reset(true) } @@ -351,12 +353,20 @@ class DAPWrapper implements pxt.packetio.PacketIOWrapper { } private async clearCommandsAsync() { - // before calling into dapjs, push through a few commands to make sure the responses - // to commands from previous sessions (if any) are flushed. Count of 5 is arbitrary. - for (let i = 0; i < 5; i++) { - try { - await this.getDaplinkVersionAsync(); - } catch (e) {} + try { + await pxt.Util.promiseTimeout(CONNECTION_CHECK_TIMEOUT, (async () => { + // before calling into dapjs, push through a few commands to make sure the responses + // to commands from previous sessions (if any) are flushed. Count of 5 is arbitrary. + for (let i = 0; i < 5; i++) { + try { + await this.getDaplinkVersionAsync(); + } catch (e) { } + } + })()); + } catch (e) { + const errOut = new Error(e); + (errOut as any).type = "inittimeout"; + throw errOut; } } @@ -407,8 +417,8 @@ class DAPWrapper implements pxt.packetio.PacketIOWrapper { await this.io.reconnectAsync(); } - await this.clearCommandsAsync() await this.stopReadersAsync(); + await this.clearCommandsAsync() await this.cortexM.init(); await this.cortexM.reset(true); await this.checkStateAsync(); @@ -438,11 +448,11 @@ class DAPWrapper implements pxt.packetio.PacketIOWrapper { // via the webusb events } - private recvPacketAsync() { + private recvPacketAsync(timeout?: number) { if (this.io.recvPacketAsync) - return this.io.recvPacketAsync() + return this.io.recvPacketAsync(timeout); else - return this.pbuf.shiftAsync() + return this.pbuf.shiftAsync(timeout); } private async dapCmd(buf: Uint8Array) { @@ -456,12 +466,14 @@ class DAPWrapper implements pxt.packetio.PacketIOWrapper { // response is a left-over from previous communications log(msg + "; retrying"); try { - const secondTryResp = await this.recvPacketAsync(); + // Add in a timeout, as this can stall if device thinks communication is complete. + const secondTryResp = await this.recvPacketAsync(RETRY_DAP_CMD_TIMEOUT); if (secondTryResp[0] === buf[0]) { log(msg + "; retry success"); return secondTryResp; } } catch (e) { + pxt.tickEvent('hid.flash.cmderror.retryfailed', { req: buf[0], resp: resp[0] }); log(e); } throw new Error(`retry failed ${msg}`); diff --git a/editor/patch.ts b/editor/patch.ts index 0edb9133f..b63fb8d57 100644 --- a/editor/patch.ts +++ b/editor/patch.ts @@ -25,7 +25,6 @@ export function patchBlocks(pkgTargetVersion: string, dom: Element) { .concat(pxt.U.toArray(dom.querySelectorAll("shadow[type=device_get_analog_pin]"))) .concat(pxt.U.toArray(dom.querySelectorAll("block[type=device_set_analog_pin]"))) .concat(pxt.U.toArray(dom.querySelectorAll("block[type=device_set_analog_period]"))) - .concat(pxt.U.toArray(dom.querySelectorAll("block[type=pins_on_pulsed]"))) .concat(pxt.U.toArray(dom.querySelectorAll("block[type=pins_pulse_in]"))) .concat(pxt.U.toArray(dom.querySelectorAll("shadow[type=pins_pulse_in]"))) .concat(pxt.U.toArray(dom.querySelectorAll("block[type=device_set_servo_pin]"))) @@ -52,7 +51,6 @@ export function patchBlocks(pkgTargetVersion: string, dom: Element) { case "pin_set_audio_pin": return oldPinNode.getAttribute("name") === "name"; case "device_set_analog_period": - case "pins_on_pulsed": case "device_set_pull": case "device_set_pin_events": case "pin_neopixel_matrix_width": @@ -68,9 +66,12 @@ export function patchBlocks(pkgTargetVersion: string, dom: Element) { const valueNode = node.ownerDocument.createElement("value"); valueNode.setAttribute("name", oldPinNode.getAttribute("name")); + let nodeText = oldPinNode.textContent; const pinShadowNode = node.ownerDocument.createElement("shadow"); + const [enumName, pinName] = nodeText.split("."); + let pinBlockType; - switch (oldPinNode.textContent.split(".")[0]) { + switch (enumName) { case "DigitalPin": pinBlockType = "digital_pin_shadow"; break; @@ -79,11 +80,33 @@ export function patchBlocks(pkgTargetVersion: string, dom: Element) { break; } if (!pinBlockType) return; + + // If this is one of the read/write pins, narrow to the read write shadow + if (blockType === "device_get_analog_pin") { + switch (pinName) { + case "P0": + case "P1": + case "P2": + case "P4": + case "C4": + case "P10": + case "C10": + case "P16": + case "C16": + case "A1_RX": + case "P18": + case "C18": + pinBlockType = "analog_read_write_pin_shadow"; + nodeText = `AnalogReadWritePin.${pinName}`; + break; + } + } + pinShadowNode.setAttribute("type", pinBlockType); const fieldNode = node.ownerDocument.createElement("field"); fieldNode.setAttribute("name", "pin"); - fieldNode.textContent = oldPinNode.textContent; + fieldNode.textContent = nodeText; pinShadowNode.appendChild(fieldNode); valueNode.appendChild(pinShadowNode); diff --git a/libs/core-mini-codal/music.cpp b/libs/core-mini-codal/music.cpp index fb61d4c8c..bc5253345 100644 --- a/libs/core-mini-codal/music.cpp +++ b/libs/core-mini-codal/music.cpp @@ -71,7 +71,7 @@ void setBuiltInSpeakerEnabled(bool enabled) { */ //% blockId=music_sound_is_playing block="sound is playing" //% group="State" -//% help=music/volume +//% help=music/is-sound-playing //% weight=0 bool isSoundPlaying() { #if MICROBIT_CODAL diff --git a/libs/core-mini-codal/music.ts b/libs/core-mini-codal/music.ts index d667ba792..5f824d334 100644 --- a/libs/core-mini-codal/music.ts +++ b/libs/core-mini-codal/music.ts @@ -12,13 +12,12 @@ namespace music { * Gets the melody array of a built-in melody. * @param melody the melody name */ - //% weight=60 help=music/builtin-melody + //% weight=60 help=music/built-in-playable-melody //% blockId=device_builtin_melody_playable block="melody $melody" //% toolboxParent=music_playable_play_default_bkg //% toolboxParentArgument=toPlay //% duplicateShadowOnDrag //% group="Melody Advanced" - //% advanced=true export function builtInPlayableMelody(melody: Melodies): StringArrayPlayable { return new StringArrayPlayable(getMelody(melody), undefined); } @@ -28,7 +27,7 @@ namespace music { */ //% blockId=melody_on_event block="music on %value" //% help=music/on-event weight=59 blockGap=32 - //% group="State" + //% group="Melody Advanced" export function onEvent(value: MusicEvent, handler: () => void) { control.onEvent(MICROBIT_MELODY_ID, value, handler); } diff --git a/libs/core-mini-codal/pxt.json b/libs/core-mini-codal/pxt.json index f153769c4..610b7597e 100644 --- a/libs/core-mini-codal/pxt.json +++ b/libs/core-mini-codal/pxt.json @@ -3,8 +3,7 @@ "description": "The mini codal core library", "dependencies": { "core": "file:../core", - "microphone": "file:../microphone", - "one-time-pairing": "file:../one-time-pairing" + "microphone": "file:../microphone" }, "disablesVariants": [ "minidal" @@ -24,6 +23,15 @@ "touchmode.cpp" ], "yotta": { + "optionalConfig": { + "microbit-dal": { + "bluetooth": { + "open": 0, + "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM", + "whitelist": 1 + } + } + }, "userConfigs": [ { "description": "Project compatible with Calliope mini 3", diff --git a/libs/core-mini-codal/shims.d.ts b/libs/core-mini-codal/shims.d.ts index b0462d7d0..1419a06f3 100644 --- a/libs/core-mini-codal/shims.d.ts +++ b/libs/core-mini-codal/shims.d.ts @@ -42,7 +42,7 @@ declare namespace music { */ //% blockId=music_sound_is_playing block="sound is playing" //% group="State" - //% help=music/volume + //% help=music/is-sound-playing //% weight=0 shim=music::isSoundPlaying function isSoundPlaying(): boolean; diff --git a/libs/core/enums.d.ts b/libs/core/enums.d.ts index 5c8ad093c..f273ca108 100644 --- a/libs/core/enums.d.ts +++ b/libs/core/enums.d.ts @@ -696,10 +696,15 @@ declare namespace input { //% blockIdentity="pins._analogPin" //% block="C19 (A0 SCL)" blockHidden=true A0_SCL = 119, // MICROBIT_ID_IO_A0_SCL + //% blockHidden=true + P19 = 119, // MICROBIT_ID_IO_A0_SCL //% blockIdentity="pins._analogPin" //% block="C20 (A0 SDA)" blockHidden=true A0_SDA = 120, // MICROBIT_ID_IO_A0_SDA + //% blockHidden=true + P20 = 120, // MICROBIT_ID_IO_A0_SDA + //% blockIdentity="pins._analogPin" //% //% block="Motor Mode" blockHidden=true diff --git a/libs/core/music.ts b/libs/core/music.ts index 5c805d039..35e82d550 100644 --- a/libs/core/music.ts +++ b/libs/core/music.ts @@ -322,7 +322,7 @@ namespace music { * Gets the melody array of a built-in melody. * @param name the note name, eg: Note.C */ - //% weight=50 help=music/builtin-melody + //% weight=50 help=music/built-in-melody //% blockId=device_builtin_melody block="%melody" //% blockHidden=true //% group="Melody Advanced" diff --git a/libs/core/pins.cpp b/libs/core/pins.cpp index 85b88c6b4..859d13c9b 100644 --- a/libs/core/pins.cpp +++ b/libs/core/pins.cpp @@ -265,10 +265,15 @@ enum class AnalogPin { //% blockIdentity="pins._analogPin" //% block="C19 (A0 SCL)" blockHidden=true A0_SCL = MICROBIT_ID_IO_A0_SCL, // SCL + //% blockHidden=true + P19 = MICROBIT_ID_IO_A0_SCL, //% blockIdentity="pins._analogPin" //% block="C20 (A0 SDA)" blockHidden=true A0_SDA = MICROBIT_ID_IO_A0_SDA, // SDA + //% blockHidden=true + P20 = MICROBIT_ID_IO_A0_SDA, // SDA + //% blockIdentity="pins._analogPin" //% //% block="Motor Mode" blockHidden=true @@ -464,11 +469,12 @@ namespace pins { */ //% help=pins/on-pulsed weight=22 blockGap=16 advanced=true //% blockId=pins_on_pulsed block="on|pin %pin|pulsed %pulse" - //% pin.shadow=digital_pin_shadow + //% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4 + //% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250" //% group="Pulse" //% weight=25 //% blockGap=8 - void onPulsed(int name, PulseValue pulse, Action body) { + void onPulsed(DigitalPin name, PulseValue pulse, Action body) { MicroBitPin* pin = getPin((int)name); if (!pin) return; @@ -806,7 +812,7 @@ namespace pins { */ //% help=pins/spi-write weight=5 advanced=true //% blockId=spi_write block="spi write %value" - //% group="spi" + //% group="SPI" int spiWrite(int value) { auto p = allocSPI(); return p->write(value); @@ -818,7 +824,7 @@ namespace pins { * @param response Data received from the SPI slave (can be null) */ //% help=pins/spi-transfer argsNullable - //% group="spi" + //% group="SPI" void spiTransfer(Buffer command, Buffer response) { if (!command && !response) target_panic(PANIC_INVALID_ARGUMENT); @@ -843,7 +849,7 @@ namespace pins { */ //% help=pins/spi-frequency weight=4 advanced=true //% blockId=spi_frequency block="spi frequency %frequency" - //% group="spi" + //% group="SPI" void spiFrequency(int frequency) { auto p = allocSPI(); p->frequency(frequency); @@ -856,7 +862,7 @@ namespace pins { */ //% help=pins/spi-format weight=3 advanced=true //% blockId=spi_format block="spi format|bits %bits|mode %mode" - //% group="spi" + //% group="SPI" void spiFormat(int bits, int mode) { auto p = allocSPI(); p->format(bits, mode); diff --git a/libs/core/pins.ts b/libs/core/pins.ts index b02490574..4a6366053 100644 --- a/libs/core/pins.ts +++ b/libs/core/pins.ts @@ -1,9 +1,9 @@ /** - * Control currents in Pins for analog/digital signals, servos, i2c, ... + * Control currents in Pins for analog/digital signals, servos, I²C, ... */ //% color=#A80000 weight=30 icon="\uf140" //% advanced=true -//% groups=['Analog', 'Digital', 'Servos', 'Pulse', 'Pitch', 'i2c', 'spi'] +//% groups=['Analog', 'Digital', 'Servos', 'Pitch', 'I²C', 'SPI', 'Pulse'] namespace pins { /** @@ -20,6 +20,7 @@ namespace pins { //% weight=17 //% blockGap=8 //% advanced=true + //% decompilerShadowAlias=digital_pin_shadow export function _digitalPin(pin: DigitalPin): number { return pin; } @@ -34,8 +35,11 @@ namespace pins { //% pin.fieldEditor=pinpicker //% pin.fieldOptions.columns=4 //% pin.fieldOptions.tooltips="false" + //% group="Pins" + //% weight=16 //% blockGap=8 //% advanced=true + //% decompilerShadowAlias=analog_pin_shadow export function _analogPin(pin: AnalogPin): number { return pin; } @@ -101,22 +105,22 @@ namespace pins { } /** - * Read one number from 7-bit I2C address. + * Read one number from 7-bit I²C address. */ //% help=pins/i2c-read-number blockGap=8 advanced=true - //% blockId=pins_i2c_readnumber block="i2c read number|at address %address|of format %format|repeated %repeat" weight=7 - //% group="i2c" + //% blockId=pins_i2c_readnumber block="I²C read number|at address %address|of format %format|repeated %repeat" weight=7 + //% group="I²C" export function i2cReadNumber(address: number, format: NumberFormat, repeated?: boolean): number { let buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeated) return buf.getNumber(format, 0) } /** - * Write one number to a 7-bit I2C address. + * Write one number to a 7-bit I²C address. */ //% help=pins/i2c-write-number blockGap=8 advanced=true - //% blockId=i2c_writenumber block="i2c write number|at address %address|with value %value|of format %format|repeated %repeat" weight=6 - //% group="i2c" + //% blockId=i2c_writenumber block="I²C write number|at address %address|with value %value|of format %format|repeated %repeat" weight=6 + //% group="I²C" export function i2cWriteNumber(address: number, value: number, format: NumberFormat, repeated?: boolean): void { let buf = createBuffer(pins.sizeOf(format)) buf.setNumber(format, 0, value) diff --git a/libs/core/shims.d.ts b/libs/core/shims.d.ts index f748c4167..0f9d277f5 100644 --- a/libs/core/shims.d.ts +++ b/libs/core/shims.d.ts @@ -788,11 +788,12 @@ declare namespace pins { */ //% help=pins/on-pulsed weight=22 blockGap=16 advanced=true //% blockId=pins_on_pulsed block="on|pin %pin|pulsed %pulse" - //% pin.shadow=digital_pin_shadow + //% pin.fieldEditor="gridpicker" pin.fieldOptions.columns=4 + //% pin.fieldOptions.tooltips="false" pin.fieldOptions.width="250" //% group="Pulse" //% weight=25 //% blockGap=8 shim=pins::onPulsed - function onPulsed(name: int32, pulse: PulseValue, body: () => void): void; + function onPulsed(name: DigitalPin, pulse: PulseValue, body: () => void): void; /** * Get the duration of the last pulse in microseconds. This function should be called from a ``onPulsed`` handler. @@ -962,7 +963,7 @@ declare namespace pins { */ //% help=pins/spi-write weight=5 advanced=true //% blockId=spi_write block="spi write %value" - //% group="spi" shim=pins::spiWrite + //% group="SPI" shim=pins::spiWrite function spiWrite(value: int32): int32; /** @@ -971,7 +972,7 @@ declare namespace pins { * @param response Data received from the SPI slave (can be null) */ //% help=pins/spi-transfer argsNullable - //% group="spi" shim=pins::spiTransfer + //% group="SPI" shim=pins::spiTransfer function spiTransfer(command: Buffer, response: Buffer): void; /** @@ -980,7 +981,7 @@ declare namespace pins { */ //% help=pins/spi-frequency weight=4 advanced=true //% blockId=spi_frequency block="spi frequency %frequency" - //% group="spi" shim=pins::spiFrequency + //% group="SPI" shim=pins::spiFrequency function spiFrequency(frequency: int32): void; /** @@ -990,7 +991,7 @@ declare namespace pins { */ //% help=pins/spi-format weight=3 advanced=true //% blockId=spi_format block="spi format|bits %bits|mode %mode" - //% group="spi" shim=pins::spiFormat + //% group="SPI" shim=pins::spiFormat function spiFormat(bits: int32, mode: int32): void; /** diff --git a/package.json b/package.json index be61ef5f0..b3dd04bcd 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "typescript": "4.8.3" }, "dependencies": { - "pxt-common-packages": "12.0.3", - "pxt-core": "10.2.16" + "pxt-common-packages": "12.0.4", + "pxt-core": "10.2.39" } } diff --git a/pxtarget.json b/pxtarget.json index 9d2b074d4..3203c24a2 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -22,7 +22,6 @@ "libs/settings", "libs/flashlog", "libs/datalogger", - "libs/fonts", "libs/audio-recording" ], "cloud": { @@ -207,7 +206,7 @@ "codalTarget": { "name": "codal-microbit-v2", "url": "https://github.com/calliope-edu/codal-microbit-v2", - "branch": "v0.2.67-calliope-rc1", + "branch": "v0.2.68-calliope-rc1", "type": "git" }, "codalBinary": "MICROBIT", @@ -602,6 +601,7 @@ "dragFileImage": "/static/download/transfer.png", "connectDeviceImage": "/static/download/connect.png", + "disconnectDeviceImage": "/static/download/full-reset.gif", "selectDeviceImage": "/static/download/pair.png", "connectionSuccessImage": "/static/download/connected.png", "checkFirmwareVersionImage": "/static/download/firmware.png", @@ -679,7 +679,8 @@ "teachertool=1": { "appTheme": { "hideMenuBar": true, - "workspaceSearch": true + "workspaceSearch": true, + "noReloadOnUpdate": true } } }, diff --git a/targetconfig.json b/targetconfig.json index 8b3606038..08ca1eeaa 100644 --- a/targetconfig.json +++ b/targetconfig.json @@ -375,6 +375,9 @@ "RGB" ] }, + "microsoft/pxt-apa102": {}, + "microsoft/pxt-radio-firefly": {}, + "microsoft/pxt-ml": {}, "tinkertanker/pxt-alphanumeric-ht16k33": {}, "tinkertanker/pxt-continuous-servo": { "tags": [ diff --git a/theme/style.less b/theme/style.less index c976f3b2c..9683f6b26 100644 --- a/theme/style.less +++ b/theme/style.less @@ -83,6 +83,36 @@ } } } + +.time-machine-header { + background-color: @blue; +} + +.time-machine-preview { + // Loading div that appears while projects are importing + & > div { + background: #e8e8e8 + } +} + +#root:not(.hc) .tutorial-menu { + .ui.circular.label.selected { + background-color: @purple !important; + color: #e8e8e8 !important; + border: 1px solid #e8e8e8 !important; + + &:focus, &:hover { + background-color: darken(@purple, 20%) !important; + } + } +} + +.menubar { + .ui.menu .brand .ui.logo { + height: 1.1rem; + } +} + // Safari Only for iPad and iPhone second rule @supports (-webkit-touch-callout: none) { #mainmenu .right.menu {