pxt-microbit 5.1.1 → 5.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/built/editor.js +36 -2
- package/built/hexcache/{523847a64a39d936972bb116ae62f3572fc68bbfaab239b9668a73843129f62d.hex → 21042ee1697f41e753f07ae4ed65b74e0d06c4cfd9e81c98522e5081cc22b22f.hex} +10923 -10920
- package/built/hexcache/{b3453e568175cf180eacd9bc7dbb01b5c8a3d08a615bc1f9c1da7291cd084375.hex → 3bd7683da9b220e850488838efa19f4472733744a11e01c17e4930cc48b4e0fa.hex} +10345 -10342
- package/built/hexcache/{104bed2beca960d761185d436978a3436467a15b22c67b375bcd19c41f329866.hex → 41b0eca0c15b68f1bb003a9857f7a3b6e54a9c073d9757bfe8d4b4a0396d5586.hex} +0 -0
- package/built/hexcache/{2b2b36e6358c0084c241a1cb9e35fa02042257df3c415d242d9b736c24743a0f.hex → ffda7a967870cc1be0cd9aa712c3d86444b9073804b3e2c0914c1b8ac3ca18ab.hex} +0 -0
- package/built/target-strings.json +5 -0
- package/built/target.js +50 -37
- package/built/target.json +50 -37
- package/built/targetlight.json +5 -5
- package/built/theme.json +14 -0
- package/built/web/blockly.css +1 -1
- package/built/web/react-common-authcode.css +6 -2
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlblockly.css +1 -1
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/docs/SUMMARY.md +2 -0
- package/docs/device/pins.md +72 -40
- package/docs/extensions.md +8 -0
- package/docs/jacdac.md +60 -0
- package/docs/projects/SUMMARY.md +10 -0
- package/docs/projects/games.md +6 -0
- package/docs/projects/magic-button-trick.md +0 -2
- package/docs/projects/rock-paper-scissors-v2.md +201 -0
- package/docs/projects/v2-cat-napping.md +219 -0
- package/docs/projects.md +6 -0
- package/docs/reference/input/logo-is-pressed.md +1 -1
- package/docs/reference/input/on-logo-event.md +1 -1
- package/docs/reference/serial/on-data-received.md +1 -1
- package/docs/reference/serial/read-buffer.md +8 -7
- package/docs/reference/serial/read-line.md +8 -6
- package/docs/reference/serial/read-string.md +4 -4
- package/docs/reference/serial/read-until.md +4 -4
- package/docs/reference/serial/redirect.md +8 -7
- package/docs/reference/serial/set-baud-rate.md +56 -0
- package/docs/reference/serial/set-write-line-padding.md +51 -0
- package/docs/reference/serial/write-buffer.md +4 -4
- package/docs/reference/serial/write-line.md +6 -6
- package/docs/reference/serial/write-number.md +6 -6
- package/docs/reference/serial/write-numbers.md +6 -6
- package/docs/reference/serial/write-string.md +5 -5
- package/docs/reference/serial/write-value.md +3 -3
- package/docs/reference/serial.md +4 -1
- package/docs/tutorials-v2.md +6 -0
- package/package.json +2 -2
- package/pxtarget.json +4 -0
- package/targetconfig.json +9 -4
package/built/target.js
CHANGED
|
@@ -527,6 +527,7 @@ var pxtTargetBundle = {
|
|
|
527
527
|
"en",
|
|
528
528
|
"ar",
|
|
529
529
|
"bg",
|
|
530
|
+
"ca",
|
|
530
531
|
"cs",
|
|
531
532
|
"cy",
|
|
532
533
|
"da",
|
|
@@ -560,6 +561,9 @@ var pxtTargetBundle = {
|
|
|
560
561
|
"monacoColors": {
|
|
561
562
|
"editor.background": "#ecf0f1"
|
|
562
563
|
},
|
|
564
|
+
"monacoFieldEditors": [
|
|
565
|
+
"soundeffect-editor"
|
|
566
|
+
],
|
|
563
567
|
"browserDbPrefixes": {
|
|
564
568
|
"1": "v1",
|
|
565
569
|
"2": "v2",
|
|
@@ -1857,6 +1861,16 @@ var pxtTargetBundle = {
|
|
|
1857
1861
|
"path": "/reference/serial/redirect-to-usb",
|
|
1858
1862
|
"subitems": []
|
|
1859
1863
|
},
|
|
1864
|
+
{
|
|
1865
|
+
"name": "set baud rate",
|
|
1866
|
+
"path": "/reference/serial/set-baud-rate",
|
|
1867
|
+
"subitems": []
|
|
1868
|
+
},
|
|
1869
|
+
{
|
|
1870
|
+
"name": "set write line padding",
|
|
1871
|
+
"path": "/reference/serial/set-write-line-padding",
|
|
1872
|
+
"subitems": []
|
|
1873
|
+
},
|
|
1860
1874
|
{
|
|
1861
1875
|
"name": "write buffer",
|
|
1862
1876
|
"path": "/reference/serial/write-buffer",
|
|
@@ -2666,11 +2680,11 @@ var pxtTargetBundle = {
|
|
|
2666
2680
|
},
|
|
2667
2681
|
"uploadDocs": true,
|
|
2668
2682
|
"versions": {
|
|
2669
|
-
"branch": "v5.1.
|
|
2670
|
-
"tag": "v5.1.
|
|
2671
|
-
"commits": "https://github.com/microsoft/pxt-microbit/commits/
|
|
2672
|
-
"target": "5.1.
|
|
2673
|
-
"pxt": "8.
|
|
2683
|
+
"branch": "v5.1.2",
|
|
2684
|
+
"tag": "v5.1.2",
|
|
2685
|
+
"commits": "https://github.com/microsoft/pxt-microbit/commits/30d31b061c2663d60b169b922e3794a20aed2d5c",
|
|
2686
|
+
"target": "5.1.2",
|
|
2687
|
+
"pxt": "8.2.6"
|
|
2674
2688
|
},
|
|
2675
2689
|
"blocksprj": {
|
|
2676
2690
|
"id": "blocksprj",
|
|
@@ -2727,7 +2741,7 @@ var pxtTargetBundle = {
|
|
|
2727
2741
|
"codal.cpp": "#include \"pxt.h\"\n#include <stdarg.h>\n\nPXT_ABI(__aeabi_dadd)\nPXT_ABI(__aeabi_dcmplt)\nPXT_ABI(__aeabi_dcmpgt)\nPXT_ABI(__aeabi_dsub)\nPXT_ABI(__aeabi_ddiv)\nPXT_ABI(__aeabi_dmul)\n\n#if MICROBIT_CODAL\nnamespace codal {\nint list_fibers(Fiber **dest) {\n int i = 0;\n for (Fiber *fib = codal::get_fiber_list(); fib; fib = fib->next) {\n if (dest)\n dest[i] = fib;\n i++;\n }\n return i;\n}\n\n} // namespace codal\n#endif\n\nextern \"C\" void target_panic(int error_code) {\n#if MICROBIT_CODAL\n target_disable_irq();\n DMESG(\"PANIC %d\", error_code);\n pxt::dumpDmesg();\n#else\n // wait for serial to flush\n sleep_us(300000);\n#endif\n microbit_panic(error_code);\n}\n\n#if !MICROBIT_CODAL\nextern \"C\" void target_reset() {\n microbit_reset();\n}\n#endif\n\nuint32_t device_heap_size(uint8_t heap_index); // defined in microbit-dal\n\nnamespace pxt {\n\nMicroBit uBit;\nMicroBitEvent lastEvent;\nbool serialLoggingDisabled;\n\nvoid platform_init() {\n microbit_seed_random();\n int seed = microbit_random(0x7fffffff);\n DMESG(\"random seed: %d\", seed);\n seedRandom(seed);\n}\n\nvoid initMicrobitGC() {\n uBit.init();\n if (device_heap_size(1) > NON_GC_HEAP_RESERVATION + 4)\n gcPreAllocateBlock(device_heap_size(1) - NON_GC_HEAP_RESERVATION);\n}\n\nvoid platform_init();\nvoid usb_init();\n\nstruct FreeList {\n FreeList *next;\n};\n\nvoid dispatchForeground(MicroBitEvent e, void *action) {\n lastEvent = e;\n auto value = fromInt(e.value);\n runAction1((Action)action, value);\n}\n\nvoid deleteListener(MicroBitListener *l) {\n if (l->cb_param == (void (*)(MicroBitEvent, void *))dispatchForeground) {\n decr((Action)(l->cb_arg));\n unregisterGCPtr((Action)(l->cb_arg));\n }\n}\n\nstatic void initCodal() {\n // TODO!!!\n#ifndef MICROBIT_CODAL\n uBit.messageBus.setListenerDeletionCallback(deleteListener);\n#endif\n\n // repeat error 4 times and restart as needed\n microbit_panic_timeout(4);\n}\n\n// ---------------------------------------------------------------------------\n// An adapter for the API expected by the run-time.\n// ---------------------------------------------------------------------------\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n uBit.messageBus.ignore(id, event, dispatchForeground);\n uBit.messageBus.listen(id, event, dispatchForeground, a);\n incr(a);\n registerGCPtr(a);\n}\n\nvoid fiberDone(void *a) {\n decr((Action)a);\n unregisterGCPtr((Action)a);\n release_fiber();\n}\n\nvoid releaseFiber() {\n release_fiber();\n}\n\nvoid sleep_ms(unsigned ms) {\n fiber_sleep(ms);\n}\n\nvoid sleep_us(uint64_t us) {\n#if MICROBIT_CODAL\n target_wait_us(us);\n#else\n wait_us(us);\n#endif\n}\n\nvoid forever_stub(void *a) {\n while (true) {\n runAction0((Action)a);\n fiber_sleep(20);\n }\n}\n\nvoid runForever(Action a) {\n if (a != 0) {\n incr(a);\n registerGCPtr(a);\n create_fiber(forever_stub, (void *)a);\n }\n}\n\nvoid runInParallel(Action a) {\n if (a != 0) {\n incr(a);\n registerGCPtr(a);\n create_fiber((void (*)(void *))runAction0, (void *)a, fiberDone);\n }\n}\n\nvoid waitForEvent(int id, int event) {\n fiber_wait_for_event(id, event);\n}\n\nvoid initRuntime() {\n initCodal();\n platform_init();\n}\n\n//%\nunsigned afterProgramPage() {\n unsigned ptr = (unsigned)&bytecode[0];\n ptr += programSize();\n ptr = (ptr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);\n return ptr;\n}\n\nint current_time_ms() {\n return system_timer_current_time();\n}\n\nstatic void logwriten(const char *msg, int l) {\n if (!serialLoggingDisabled)\n uBit.serial.send((uint8_t *)msg, l);\n}\n\nstatic void logwrite(const char *msg) {\n logwriten(msg, strlen(msg));\n}\n\nstatic void writeNum(char *buf, uint32_t n, bool full) {\n int i = 0;\n int sh = 28;\n while (sh >= 0) {\n int d = (n >> sh) & 0xf;\n if (full || d || sh == 0 || i) {\n buf[i++] = d > 9 ? 'A' + d - 10 : '0' + d;\n }\n sh -= 4;\n }\n buf[i] = 0;\n}\n\nstatic void logwritenum(uint32_t n, bool full, bool hex) {\n char buff[20];\n\n if (hex) {\n writeNum(buff, n, full);\n logwrite(\"0x\");\n } else {\n itoa(n, buff);\n }\n\n logwrite(buff);\n}\n\nvoid vdebuglog(const char *format, va_list ap) {\n const char *end = format;\n\n while (*end) {\n if (*end++ == '%') {\n logwriten(format, end - format - 1);\n uint32_t val = va_arg(ap, uint32_t);\n switch (*end++) {\n case 'c':\n logwriten((const char *)&val, 1);\n break;\n case 'd':\n logwritenum(val, false, false);\n break;\n case 'x':\n logwritenum(val, false, true);\n break;\n case 'p':\n case 'X':\n logwritenum(val, true, true);\n break;\n case 's':\n logwrite((char *)(void *)val);\n break;\n case '%':\n logwrite(\"%\");\n break;\n default:\n logwrite(\"???\");\n break;\n }\n format = end;\n }\n }\n logwriten(format, end - format);\n logwrite(\"\\n\");\n}\n\nvoid debuglog(const char *format, ...) {\n va_list arg;\n va_start(arg, format);\n vdebuglog(format, arg);\n va_end(arg);\n}\n\nvoid sendSerial(const char *data, int len) {\n logwriten(data, len);\n}\n\nThreadContext *getThreadContext() {\n if (!currentFiber)\n return NULL;\n return (ThreadContext *)currentFiber->user_data;\n}\n\nvoid setThreadContext(ThreadContext *ctx) {\n currentFiber->user_data = ctx;\n}\n\n#if !MICROBIT_CODAL\n#define tcb_get_stack_base(tcb) (tcb).stack_base\n#endif\n\nstatic void *threadAddressFor(Fiber *fib, void *sp) {\n if (fib == currentFiber)\n return sp;\n\n return (uint8_t *)sp + ((uint8_t *)fib->stack_top - (uint8_t *)tcb_get_stack_base(fib->tcb));\n}\n\nvoid gcProcessStacks(int flags) {\n // check scheduler is initialized\n if (!currentFiber) {\n // make sure we allocate something to at least initalize the memory allocator\n void *volatile p = xmalloc(1);\n xfree(p);\n return;\n }\n\n#ifdef MICROBIT_GET_FIBER_LIST_SUPPORTED\n for (Fiber *fib = get_fiber_list(); fib; fib = fib->next) {\n auto ctx = (ThreadContext *)fib->user_data;\n if (!ctx)\n continue;\n for (auto seg = &ctx->stack; seg; seg = seg->next) {\n auto ptr = (TValue *)threadAddressFor(fib, seg->top);\n auto end = (TValue *)threadAddressFor(fib, seg->bottom);\n if (flags & 2)\n DMESG(\"RS%d:%p/%d\", cnt++, ptr, end - ptr);\n // VLOG(\"mark: %p - %p\", ptr, end);\n while (ptr < end) {\n gcProcess(*ptr++);\n }\n }\n }\n#else\n int numFibers = list_fibers(NULL);\n Fiber **fibers = (Fiber **)xmalloc(sizeof(Fiber *) * numFibers);\n int num2 = list_fibers(fibers);\n if (numFibers != num2)\n oops(12);\n int cnt = 0;\n\n for (int i = 0; i < numFibers; ++i) {\n auto fib = fibers[i];\n auto ctx = (ThreadContext *)fib->user_data;\n if (!ctx)\n continue;\n for (auto seg = &ctx->stack; seg; seg = seg->next) {\n auto ptr = (TValue *)threadAddressFor(fib, seg->top);\n auto end = (TValue *)threadAddressFor(fib, seg->bottom);\n if (flags & 2) {\n DMESG(\"RS%d:%p/%d\", cnt, ptr, end - ptr);\n cnt++;\n }\n // VLOG(\"mark: %p - %p\", ptr, end);\n while (ptr < end) {\n gcProcess(*ptr++);\n }\n }\n }\n xfree(fibers);\n#endif\n}\n\n} // namespace pxt\n",
|
|
2728
2742
|
"configkeys.h": "#ifndef __PXT_CONFIGKEYS_H\n#define __PXT_CONFIGKEYS_H\n\n// used by pins.cpp to mask off the pin name from any config\n// lower 16 pins of value are the pin name\n#define CFG_PIN_NAME_MSK 0x0000ffff\n// upper 16 bits of value is any configuration of the pin.\n#define CFG_PIN_CONFIG_MSK 0xffff0000\n\n// begin optional pin configurations\n#define CFG_PIN_CONFIG_ACTIVE_LO 0x10000\n\n\n#define CFG_MAGIC0 0x1e9e10f1\n#define CFG_MAGIC1 0x20227a79\n\n// these define keys for getConfig() function\n#define CFG_PIN_ACCELEROMETER_INT 1\n#define CFG_PIN_ACCELEROMETER_SCL 2\n#define CFG_PIN_ACCELEROMETER_SDA 3\n#define CFG_PIN_BTN_A 4\n#define CFG_PIN_BTN_B 5\n#define CFG_PIN_BTN_SLIDE 6\n#define CFG_PIN_DOTSTAR_CLOCK 7\n#define CFG_PIN_DOTSTAR_DATA 8\n#define CFG_PIN_FLASH_CS 9\n#define CFG_PIN_FLASH_MISO 10\n#define CFG_PIN_FLASH_MOSI 11\n#define CFG_PIN_FLASH_SCK 12\n#define CFG_PIN_LED 13\n#define CFG_PIN_LIGHT 14\n#define CFG_PIN_MICROPHONE 15\n#define CFG_PIN_MIC_CLOCK 16\n#define CFG_PIN_MIC_DATA 17\n#define CFG_PIN_MISO 18\n#define CFG_PIN_MOSI 19\n// the preferred pin to drive an external neopixel strip\n#define CFG_PIN_NEOPIXEL 20\n#define CFG_PIN_RX 21\n#define CFG_PIN_RXLED 22\n#define CFG_PIN_SCK 23\n#define CFG_PIN_SCL 24\n#define CFG_PIN_SDA 25\n#define CFG_PIN_SPEAKER_AMP 26\n#define CFG_PIN_TEMPERATURE 27\n#define CFG_PIN_TX 28\n#define CFG_PIN_TXLED 29\n#define CFG_PIN_IR_OUT 30\n#define CFG_PIN_IR_IN 31\n#define CFG_PIN_DISPLAY_SCK 32\n#define CFG_PIN_DISPLAY_MISO 33\n#define CFG_PIN_DISPLAY_MOSI 34\n#define CFG_PIN_DISPLAY_CS 35\n#define CFG_PIN_DISPLAY_DC 36\n#define CFG_DISPLAY_WIDTH 37\n#define CFG_DISPLAY_HEIGHT 38\n#define CFG_DISPLAY_CFG0 39\n#define CFG_DISPLAY_CFG1 40\n#define CFG_DISPLAY_CFG2 41\n#define CFG_DISPLAY_CFG3 42\n#define CFG_PIN_DISPLAY_RST 43\n#define CFG_PIN_DISPLAY_BL 44\n#define CFG_PIN_SERVO_1 45\n#define CFG_PIN_SERVO_2 46\n#define CFG_PIN_BTN_LEFT 47\n#define CFG_PIN_BTN_RIGHT 48\n#define CFG_PIN_BTN_UP 49\n#define CFG_PIN_BTN_DOWN 50\n#define CFG_PIN_BTN_MENU 51\n#define CFG_PIN_LED_R 52\n#define CFG_PIN_LED_G 53\n#define CFG_PIN_LED_B 54\n#define CFG_PIN_LED1 55\n#define CFG_PIN_LED2 56\n#define CFG_PIN_LED3 57\n#define CFG_PIN_LED4 58\n#define CFG_SPEAKER_VOLUME 59\n\n#define CFG_PIN_JACK_TX 60\n#define CFG_PIN_JACK_SENSE 61\n#define CFG_PIN_JACK_HPEN 62\n#define CFG_PIN_JACK_BZEN 63\n#define CFG_PIN_JACK_PWREN 64\n#define CFG_PIN_JACK_SND 65\n#define CFG_PIN_JACK_BUSLED 66\n#define CFG_PIN_JACK_COMMLED 67\n\n#define CFG_PIN_BTN_SOFT_RESET 69\n#define CFG_ACCELEROMETER_TYPE 70\n#define CFG_PIN_BTNMX_LATCH 71\n#define CFG_PIN_BTNMX_CLOCK 72\n#define CFG_PIN_BTNMX_DATA 73\n#define CFG_PIN_BTN_MENU2 74\n#define CFG_PIN_BATTSENSE 75\n#define CFG_PIN_VIBRATION 76\n#define CFG_PIN_PWREN 77\n#define CFG_DISPLAY_TYPE 78\n\n#define CFG_PIN_ROTARY_ENCODER_A 79\n#define CFG_PIN_ROTARY_ENCODER_B 80\n\n#define CFG_ACCELEROMETER_SPACE 81\n\n#define CFG_PIN_WIFI_MOSI 82\n#define CFG_PIN_WIFI_MISO 83\n#define CFG_PIN_WIFI_SCK 84\n#define CFG_PIN_WIFI_TX 85\n#define CFG_PIN_WIFI_RX 86\n#define CFG_PIN_WIFI_CS 87\n#define CFG_PIN_WIFI_BUSY 88\n#define CFG_PIN_WIFI_RESET 89\n#define CFG_PIN_WIFI_GPIO0 90\n#define CFG_PIN_WIFI_AT_TX 91\n#define CFG_PIN_WIFI_AT_RX 92\n\n#define CFG_PIN_USB_POWER 93\n\n// default I2C address\n#define ACCELEROMETER_TYPE_LIS3DH 0x32\n#define ACCELEROMETER_TYPE_LIS3DH_ALT 0x30\n#define ACCELEROMETER_TYPE_MMA8453 0x38\n#define ACCELEROMETER_TYPE_FXOS8700 0x3C\n#define ACCELEROMETER_TYPE_MMA8653 0x3A\n#define ACCELEROMETER_TYPE_MSA300 0x4C\n#define ACCELEROMETER_TYPE_MPU6050 0x68\n\n#define DISPLAY_TYPE_ST7735 7735\n#define DISPLAY_TYPE_ILI9341 9341\n#define DISPLAY_TYPE_SMART 4242\n\n#define CFG_PIN_A0 100\n#define CFG_PIN_A1 101\n#define CFG_PIN_A2 102\n#define CFG_PIN_A3 103\n#define CFG_PIN_A4 104\n#define CFG_PIN_A5 105\n#define CFG_PIN_A6 106\n#define CFG_PIN_A7 107\n#define CFG_PIN_A8 108\n#define CFG_PIN_A9 109\n#define CFG_PIN_A10 110\n#define CFG_PIN_A11 111\n#define CFG_PIN_A12 112\n#define CFG_PIN_A13 113\n#define CFG_PIN_A14 114\n#define CFG_PIN_A15 115\n#define CFG_PIN_A16 116\n#define CFG_PIN_A17 117\n#define CFG_PIN_A18 118\n#define CFG_PIN_A19 119\n#define CFG_PIN_A20 120\n#define CFG_PIN_A21 121\n#define CFG_PIN_A22 122\n#define CFG_PIN_A23 123\n#define CFG_PIN_A24 124\n#define CFG_PIN_A25 125\n#define CFG_PIN_A26 126\n#define CFG_PIN_A27 127\n#define CFG_PIN_A28 128\n#define CFG_PIN_A29 129\n#define CFG_PIN_A30 130\n#define CFG_PIN_A31 131\n\n#define CFG_PIN_D0 150\n#define CFG_PIN_D1 151\n#define CFG_PIN_D2 152\n#define CFG_PIN_D3 153\n#define CFG_PIN_D4 154\n#define CFG_PIN_D5 155\n#define CFG_PIN_D6 156\n#define CFG_PIN_D7 157\n#define CFG_PIN_D8 158\n#define CFG_PIN_D9 159\n#define CFG_PIN_D10 160\n#define CFG_PIN_D11 161\n#define CFG_PIN_D12 162\n#define CFG_PIN_D13 163\n#define CFG_PIN_D14 164\n#define CFG_PIN_D15 165\n#define CFG_PIN_D16 166\n#define CFG_PIN_D17 167\n#define CFG_PIN_D18 168\n#define CFG_PIN_D19 169\n#define CFG_PIN_D20 170\n#define CFG_PIN_D21 171\n#define CFG_PIN_D22 172\n#define CFG_PIN_D23 173\n#define CFG_PIN_D24 174\n#define CFG_PIN_D25 175\n#define CFG_PIN_D26 176\n#define CFG_PIN_D27 177\n#define CFG_PIN_D28 178\n#define CFG_PIN_D29 179\n#define CFG_PIN_D30 180\n#define CFG_PIN_D31 181\n\n#define CFG_NUM_NEOPIXELS 200\n#define CFG_NUM_DOTSTARS 201\n#define CFG_DEFAULT_BUTTON_MODE 202\n#define CFG_SWD_ENABLED 203\n#define CFG_FLASH_BYTES 204\n#define CFG_RAM_BYTES 205\n#define CFG_SYSTEM_HEAP_BYTES 206\n#define CFG_LOW_MEM_SIMULATION_KB 207\n#define CFG_BOOTLOADER_BOARD_ID 208\n#define CFG_UF2_FAMILY 209\n#define CFG_PINS_PORT_SIZE 210\n#define CFG_BOOTLOADER_PROTECTION 211\n#define CFG_POWER_DEEPSLEEP_TIMEOUT 212\n#define CFG_ANALOG_BUTTON_THRESHOLD 213\n#define CFG_CPU_MHZ 214\n#define CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS 215\n#define CFG_ANALOG_JOYSTICK_MIN 216\n#define CFG_ANALOG_JOYSTICK_MAX 217\n#define CFG_TIMERS_TO_USE 218\n// configs to specify the onboard (built-in) dotstar or neopixel strips\n// some boards have a combination of dotstar, neopixel strips like neotrellis\n#define CFG_PIN_ONBOARD_DOTSTAR_CLOCK 219\n#define CFG_PIN_ONBOARD_DOTSTAR_DATA 220\n#define CFG_NUM_ONBOARD_DOTSTARS 221\n#define CFG_PIN_ONBOARD_NEOPIXEL 222\n#define CFG_NUM_ONBOARD_NEOPIXELS 223\n\n#define CFG_MATRIX_KEYPAD_MESSAGE_ID 239\n#define CFG_NUM_MATRIX_KEYPAD_ROWS 240\n#define CFG_PIN_MATRIX_KEYPAD_ROW0 241\n#define CFG_PIN_MATRIX_KEYPAD_ROW1 242\n#define CFG_PIN_MATRIX_KEYPAD_ROW2 243\n#define CFG_PIN_MATRIX_KEYPAD_ROW3 244\n#define CFG_PIN_MATRIX_KEYPAD_ROW4 245\n#define CFG_PIN_MATRIX_KEYPAD_ROW5 246\n#define CFG_PIN_MATRIX_KEYPAD_ROW6 247\n#define CFG_PIN_MATRIX_KEYPAD_ROW7 248\n#define CFG_NUM_MATRIX_KEYPAD_COLS 250\n#define CFG_PIN_MATRIX_KEYPAD_COL0 251\n#define CFG_PIN_MATRIX_KEYPAD_COL1 252\n#define CFG_PIN_MATRIX_KEYPAD_COL2 253\n#define CFG_PIN_MATRIX_KEYPAD_COL3 254\n#define CFG_PIN_MATRIX_KEYPAD_COL4 255\n#define CFG_PIN_MATRIX_KEYPAD_COL5 256\n#define CFG_PIN_MATRIX_KEYPAD_COL6 257\n#define CFG_PIN_MATRIX_KEYPAD_COL7 258\n\n#define CFG_PIN_B0 300\n#define CFG_PIN_B1 301\n#define CFG_PIN_B2 302\n#define CFG_PIN_B3 303\n#define CFG_PIN_B4 304\n#define CFG_PIN_B5 305\n#define CFG_PIN_B6 306\n#define CFG_PIN_B7 307\n#define CFG_PIN_B8 308\n#define CFG_PIN_B9 309\n#define CFG_PIN_B10 310\n#define CFG_PIN_B11 311\n#define CFG_PIN_B12 312\n#define CFG_PIN_B13 313\n#define CFG_PIN_B14 314\n#define CFG_PIN_B15 315\n#define CFG_PIN_B16 316\n#define CFG_PIN_B17 317\n#define CFG_PIN_B18 318\n#define CFG_PIN_B19 319\n#define CFG_PIN_B20 320\n#define CFG_PIN_B21 321\n#define CFG_PIN_B22 322\n#define CFG_PIN_B23 323\n#define CFG_PIN_B24 324\n#define CFG_PIN_B25 325\n#define CFG_PIN_B26 326\n#define CFG_PIN_B27 327\n#define CFG_PIN_B28 328\n#define CFG_PIN_B29 329\n#define CFG_PIN_B30 330\n#define CFG_PIN_B31 331\n\n#define CFG_PIN_C0 350\n#define CFG_PIN_C1 351\n#define CFG_PIN_C2 352\n#define CFG_PIN_C3 353\n#define CFG_PIN_C4 354\n#define CFG_PIN_C5 355\n#define CFG_PIN_C6 356\n#define CFG_PIN_C7 357\n#define CFG_PIN_C8 358\n#define CFG_PIN_C9 359\n#define CFG_PIN_C10 360\n#define CFG_PIN_C11 361\n#define CFG_PIN_C12 362\n#define CFG_PIN_C13 363\n#define CFG_PIN_C14 364\n#define CFG_PIN_C15 365\n#define CFG_PIN_C16 366\n#define CFG_PIN_C17 367\n#define CFG_PIN_C18 368\n#define CFG_PIN_C19 369\n#define CFG_PIN_C20 370\n#define CFG_PIN_C21 371\n#define CFG_PIN_C22 372\n#define CFG_PIN_C23 373\n#define CFG_PIN_C24 374\n#define CFG_PIN_C25 375\n#define CFG_PIN_C26 376\n#define CFG_PIN_C27 377\n#define CFG_PIN_C28 378\n#define CFG_PIN_C29 379\n#define CFG_PIN_C30 380\n#define CFG_PIN_C31 381\n\n#define CFG_PIN_P0 400\n#define CFG_PIN_P1 401\n#define CFG_PIN_P2 402\n#define CFG_PIN_P3 403\n#define CFG_PIN_P4 404\n#define CFG_PIN_P5 405\n#define CFG_PIN_P6 406\n#define CFG_PIN_P7 407\n#define CFG_PIN_P8 408\n#define CFG_PIN_P9 409\n#define CFG_PIN_P10 410\n#define CFG_PIN_P11 411\n#define CFG_PIN_P12 412\n#define CFG_PIN_P13 413\n#define CFG_PIN_P14 414\n#define CFG_PIN_P15 415\n#define CFG_PIN_P16 416\n#define CFG_PIN_P17 417\n#define CFG_PIN_P18 418\n#define CFG_PIN_P19 419\n#define CFG_PIN_P20 420\n#define CFG_PIN_P21 421\n#define CFG_PIN_P22 422\n#define CFG_PIN_P23 423\n#define CFG_PIN_P24 424\n#define CFG_PIN_P25 425\n#define CFG_PIN_P26 426\n#define CFG_PIN_P27 427\n#define CFG_PIN_P28 428\n#define CFG_PIN_P29 429\n#define CFG_PIN_P30 430\n#define CFG_PIN_P31 431\n#define CFG_PIN_P32 432\n#define CFG_PIN_P33 433\n#define CFG_PIN_P34 434\n#define CFG_PIN_P35 435\n#define CFG_PIN_P36 436\n#define CFG_PIN_P37 437\n#define CFG_PIN_P38 438\n#define CFG_PIN_P39 439\n#define CFG_PIN_P40 440\n#define CFG_PIN_P41 441\n#define CFG_PIN_P42 442\n#define CFG_PIN_P43 443\n#define CFG_PIN_P44 444\n#define CFG_PIN_P45 445\n#define CFG_PIN_P46 446\n#define CFG_PIN_P47 447\n#define CFG_PIN_P48 448\n#define CFG_PIN_P49 449\n#define CFG_PIN_P50 450\n#define CFG_PIN_P51 451\n#define CFG_PIN_P52 452\n#define CFG_PIN_P53 453\n#define CFG_PIN_P54 454\n#define CFG_PIN_P55 455\n#define CFG_PIN_P56 456\n#define CFG_PIN_P57 457\n#define CFG_PIN_P58 458\n#define CFG_PIN_P59 459\n#define CFG_PIN_P60 460\n#define CFG_PIN_P61 461\n#define CFG_PIN_P62 462\n#define CFG_PIN_P63 463\n\n#define CFG_PIN_LORA_MISO 1001\n#define CFG_PIN_LORA_MOSI 1002\n#define CFG_PIN_LORA_SCK 1003\n#define CFG_PIN_LORA_CS 1004\n#define CFG_PIN_LORA_BOOT 1005\n#define CFG_PIN_LORA_RESET 1006\n#define CFG_PIN_IRRXLED 1007\n#define CFG_PIN_IRTXLED 1008\n#define CFG_PIN_LCD_RESET 1009\n#define CFG_PIN_LCD_ENABLE 1010\n#define CFG_PIN_LCD_DATALINE4 1011\n#define CFG_PIN_LCD_DATALINE5 1012\n#define CFG_PIN_LCD_DATALINE6 1013\n#define CFG_PIN_LCD_DATALINE7 1014\n#define CFG_NUM_LCD_COLUMNS 1015\n#define CFG_NUM_LCD_ROWS 1016\n\n//RoboHAT MM1 pinout\n#define CFG_PIN_RCC0 1017\n#define CFG_PIN_RCC1 1018\n#define CFG_PIN_RCC2 1019\n#define CFG_PIN_RCC3 1020\n#define CFG_PIN_RCC4 1021\n#define CFG_PIN_RCC5 1022\n#define CFG_PIN_RCC6 1023\n#define CFG_PIN_RCC7 1024\n#define CFG_PIN_SERVO0 1025\n#define CFG_PIN_SERVO1 1026\n#define CFG_PIN_SERVO2 1027\n#define CFG_PIN_SERVO3 1028\n#define CFG_PIN_SERVO4 1029\n#define CFG_PIN_SERVO5 1030\n#define CFG_PIN_SERVO6 1031\n#define CFG_PIN_SERVO7 1032\n#define CFG_PIN_SERVO8 1033\n#define CFG_PIN_PI_TX 1034\n#define CFG_PIN_PI_RX 1035\n#define CFG_PIN_GPS_SDA 1036\n#define CFG_PIN_GPS_SCL 1037\n#define CFG_PIN_GPS_TX 1038\n#define CFG_PIN_GPS_RX 1039\n#define CFG_PIN_GROVE0 1040\n#define CFG_PIN_GROVE1 1041\n#define CFG_PIN_SS 1042\n\n// Adafruit Grand Central M4\n#define CFG_PIN_D33 183\n#define CFG_PIN_D34 184\n#define CFG_PIN_D35 185\n#define CFG_PIN_D36 186\n#define CFG_PIN_D37 187\n#define CFG_PIN_D38 188\n#define CFG_PIN_D39 189\n#define CFG_PIN_D40 190\n#define CFG_PIN_D41 191\n#define CFG_PIN_D42 192\n#define CFG_PIN_D43 193\n#define CFG_PIN_D44 194\n#define CFG_PIN_D45 195\n#define CFG_PIN_D46 196\n#define CFG_PIN_D47 197\n#define CFG_PIN_D48 198\n#define CFG_PIN_D49 199\n#define CFG_PIN_D50 259\n#define CFG_PIN_D51 260\n#define CFG_PIN_D52 261\n#define CFG_PIN_D53 262\n\n#define CFG_PIN_TX1 263\n#define CFG_PIN_TX2 264\n#define CFG_PIN_TX3 265\n#define CFG_PIN_RX1 266\n#define CFG_PIN_RX2 267\n#define CFG_PIN_RX3 268\n#define CFG_PIN_SCL1 269\n#define CFG_PIN_SDA1 270\n#define CFG_PIN_PCC_D0 271\n#define CFG_PIN_PCC_D1 272\n#define CFG_PIN_PCC_D2 273\n#define CFG_PIN_PCC_D3 274\n#define CFG_PIN_PCC_D4 275\n#define CFG_PIN_PCC_D5 276\n#define CFG_PIN_PCC_D6 277\n#define CFG_PIN_PCC_D7 278\n#define CFG_PIN_PCC_D8 279\n#define CFG_PIN_PCC_D9 280\n#define CFG_PIN_PCC_D10 281\n#define CFG_PIN_PCC_D11 282\n#define CFG_PIN_PCC_D12 283\n#define CFG_PIN_PCC_D13 284\n#define CFG_PIN_CC_DEN1 285\n#define CFG_PIN_CC_DEN2 286\n#define CFG_PIN_CC_CLK 287\n#define CFG_PIN_XCC_CLK 288\n\n\n#define CFG_PIN_JDPWR_PRE_SENSE 1100\n#define CFG_PIN_JDPWR_GND_SENSE 1101\n#define CFG_PIN_JDPWR_PULSE 1102\n#define CFG_PIN_JDPWR_OVERLOAD_LED 1103\n#define CFG_PIN_JDPWR_ENABLE 1104\n#define CFG_PIN_JDPWR_FAULT 1105\n\n#endif\n",
|
|
2729
2743
|
"console.ts": "/// <reference no-default-lib=\"true\"/>\n\nenum ConsolePriority {\n Debug = 0,\n Log = 1,\n Warning = 2,\n Error = 3,\n Silent = 4\n}\n\n/**\n * Reading and writing data to the console output.\n */\n//% weight=12 color=#002050 icon=\"\\uf120\"\n//% advanced=true\nnamespace console {\n type Listener = (priority: ConsolePriority, text: string) => void;\n\n /**\n * Minimum priority to send messages to listeners\n */\n export let minPriority = ConsolePriority.Log;\n\n let listeners: Listener[]\n\n export function add(priority: ConsolePriority, message: any) {\n if (priority < minPriority) return;\n let text = inspect(message);\n // add new line\n text += \"\\n\";\n control.__log(priority, text)\n // send to listeners\n if (listeners)\n for (let i = 0; i < listeners.length; ++i)\n listeners[i](priority, text);\n }\n\n export function debug(text: any) {\n add(ConsolePriority.Debug, text);\n }\n\n export function warn(text: any) {\n add(ConsolePriority.Warning, text);\n }\n\n export function error(text: any) {\n add(ConsolePriority.Error, text);\n }\n\n /**\n * Write a line of text to the console output.\n * @param value to send\n */\n //% weight=90\n //% help=console/log blockGap=8\n export function log(value: any): void {\n add(ConsolePriority.Log, value);\n }\n\n /**\n * Write a name:value pair as a line of text to the console output.\n * @param name name of the value stream, eg: \"x\"\n * @param value to write\n */\n //% weight=88 blockGap=8\n //% help=console/log-value\n export function logValue(name: any, value: any): void {\n log(name ? `${inspect(name)}: ${inspect(value)}` : `${inspect(value)}`)\n }\n\n /**\n * Convert any object or value to a string representation\n * @param obj value to be converted to a string\n * @param maxElements [optional] max number values in an object to include in output\n */\n export function inspect(obj: any, maxElements = 20): string {\n if (typeof obj == \"string\") {\n return obj;\n } else if (typeof obj == \"number\") {\n return \"\" + obj;\n } else if (Array.isArray(obj)) {\n const asArr = (obj as Array<string>);\n if (asArr.length <= maxElements) {\n return asArr.join(\",\");\n } else {\n return `${asArr.slice(0, maxElements).join(\",\")}...`;\n }\n } else {\n const asString = obj + \"\";\n if (asString != \"[object Object]\"\n && asString != \"[Object]\") { // on arcade at least, default toString is [Object] on hardware instead of standard\n return asString;\n }\n\n let keys = Object.keys(obj);\n const snipped = keys.length > maxElements;\n if (snipped) {\n keys = keys.slice(0, maxElements);\n }\n\n return `{${keys.reduce(\n (prev, currKey) => prev + `\\n ${currKey}: ${obj[currKey]}`,\n \"\"\n ) + (snipped ? \"\\n ...\" : \"\")\n }\n}`;\n }\n }\n\n /**\n * Adds a listener for the log messages\n * @param listener\n */\n //%\n export function addListener(listener: (priority: ConsolePriority, text: string) => void) {\n if (!listeners) listeners = []\n if (!listener || listeners.indexOf(listener) > -1) return;\n listeners.push(listener);\n }\n\n /**\n * Removes a listener\n * @param listener\n */\n //%\n export function removeListener(listener: (priority: ConsolePriority, text: string) => void) {\n if (!listener || !listeners) return;\n const i = listeners.indexOf(listener);\n if (i > -1)\n listeners.splice(i, 1);\n }\n}",
|
|
2730
|
-
"control.cpp": "#include \"pxt.h\"\n\nextern uint32_t __StackTop;\n\n/**\n * How to create the event.\n */\nenum class EventCreationMode {\n /**\n * MicroBitEvent is initialised, and no further processing takes place.\n */\n CreateOnly = CREATE_ONLY,\n /**\n * MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).\n */\n CreateAndFire = CREATE_AND_FIRE,\n};\n\nconst char *MICROBIT_BOARD_VERSION[2] = { \"2.0\", \"2.X\" };\n\n// note the trailing '_' in names - otherwise we get conflict with the pre-processor\n// this trailing underscore is removed by enums.d.ts generation process\n\n// TODO shouldn't these be renamed to something more sensible anyways?\n\nenum EventBusSource {\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_BUTTON_A_ = MICROBIT_ID_BUTTON_A,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_BUTTON_B_ = MICROBIT_ID_BUTTON_B,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_BUTTON_AB_ = MICROBIT_ID_BUTTON_AB,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_RADIO_ = MICROBIT_ID_RADIO,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_GESTURE_ = MICROBIT_ID_GESTURE,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_ACCELEROMETER_ = MICROBIT_ID_ACCELEROMETER,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P0_ = MICROBIT_ID_IO_P0,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P1_ = MICROBIT_ID_IO_P1,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P2_ = MICROBIT_ID_IO_P2,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P3_ = MICROBIT_ID_IO_P3,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P4_ = MICROBIT_ID_IO_P4,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P5_ = MICROBIT_ID_IO_P5,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P6_ = MICROBIT_ID_IO_P6,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P7_ = MICROBIT_ID_IO_P7,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P8_ = MICROBIT_ID_IO_P8,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P9_ = MICROBIT_ID_IO_P9,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P10_ = MICROBIT_ID_IO_P10,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P11_ = MICROBIT_ID_IO_P11,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P12_ = MICROBIT_ID_IO_P12,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P13_ = MICROBIT_ID_IO_P13,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P14_ = MICROBIT_ID_IO_P14,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P15_ = MICROBIT_ID_IO_P15,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P16_ = MICROBIT_ID_IO_P16,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P19_ = MICROBIT_ID_IO_P19,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P20_ = MICROBIT_ID_IO_P20,\n //% blockIdentity=\"control.eventSourceId\"\n MES_DEVICE_INFO_ID_ = MES_DEVICE_INFO_ID,\n //% blockIdentity=\"control.eventSourceId\"\n MES_SIGNAL_STRENGTH_ID_ = MES_SIGNAL_STRENGTH_ID,\n //% blockIdentity=\"control.eventSourceId\"\n MES_DPAD_CONTROLLER_ID_ = MES_DPAD_CONTROLLER_ID,\n //% blockIdentity=\"control.eventSourceId\"\n MES_BROADCAST_GENERAL_ID_ = MES_BROADCAST_GENERAL_ID,\n};\n\nenum EventBusValue {\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_EVT_ANY_ = MICROBIT_EVT_ANY,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_BUTTON_EVT_DOWN_ = MICROBIT_BUTTON_EVT_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_BUTTON_EVT_UP_ = MICROBIT_BUTTON_EVT_UP,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_BUTTON_EVT_CLICK_ = MICROBIT_BUTTON_EVT_CLICK,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_RADIO_EVT_DATAGRAM_ = MICROBIT_RADIO_EVT_DATAGRAM,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE_ = MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_RISE_ = MICROBIT_PIN_EVT_RISE,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_FALL_ = MICROBIT_PIN_EVT_FALL,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_PULSE_HI_ = MICROBIT_PIN_EVT_PULSE_HI,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_PULSE_LO_ = MICROBIT_PIN_EVT_PULSE_LO,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM1_ = MES_ALERT_EVT_ALARM1,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM2_ = MES_ALERT_EVT_ALARM2,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM3_ = MES_ALERT_EVT_ALARM3,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM4_ = MES_ALERT_EVT_ALARM4,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM5_ = MES_ALERT_EVT_ALARM5,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM6_ = MES_ALERT_EVT_ALARM6,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_DISPLAY_TOAST_ = MES_ALERT_EVT_DISPLAY_TOAST,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_FIND_MY_PHONE_ = MES_ALERT_EVT_FIND_MY_PHONE,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_PLAY_RINGTONE_ = MES_ALERT_EVT_PLAY_RINGTONE,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_PLAY_SOUND_ = MES_ALERT_EVT_PLAY_SOUND,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_VIBRATE_ = MES_ALERT_EVT_VIBRATE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_LAUNCH_PHOTO_MODE_ = MES_CAMERA_EVT_LAUNCH_PHOTO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_LAUNCH_VIDEO_MODE_ = MES_CAMERA_EVT_LAUNCH_VIDEO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_START_VIDEO_CAPTURE_ = MES_CAMERA_EVT_START_VIDEO_CAPTURE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_STOP_PHOTO_MODE_ = MES_CAMERA_EVT_STOP_PHOTO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_STOP_VIDEO_CAPTURE_ = MES_CAMERA_EVT_STOP_VIDEO_CAPTURE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_STOP_VIDEO_MODE_ = MES_CAMERA_EVT_STOP_VIDEO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_TAKE_PHOTO_ = MES_CAMERA_EVT_TAKE_PHOTO,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_TOGGLE_FRONT_REAR_ = MES_CAMERA_EVT_TOGGLE_FRONT_REAR,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_DISPLAY_OFF_ = MES_DEVICE_DISPLAY_OFF,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_DISPLAY_ON_ = MES_DEVICE_DISPLAY_ON,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_GESTURE_DEVICE_SHAKEN_ = MES_DEVICE_GESTURE_DEVICE_SHAKEN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_INCOMING_CALL_ = MES_DEVICE_INCOMING_CALL,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_INCOMING_MESSAGE_ = MES_DEVICE_INCOMING_MESSAGE,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_ORIENTATION_LANDSCAPE_ = MES_DEVICE_ORIENTATION_LANDSCAPE,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_ORIENTATION_PORTRAIT_ = MES_DEVICE_ORIENTATION_PORTRAIT,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_1_DOWN_ = MES_DPAD_BUTTON_1_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_1_UP_ = MES_DPAD_BUTTON_1_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_2_DOWN_ = MES_DPAD_BUTTON_2_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_2_UP_ = MES_DPAD_BUTTON_2_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_3_DOWN_ = MES_DPAD_BUTTON_3_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_3_UP_ = MES_DPAD_BUTTON_3_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_4_DOWN_ = MES_DPAD_BUTTON_4_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_4_UP_ = MES_DPAD_BUTTON_4_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_A_DOWN_ = MES_DPAD_BUTTON_A_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_A_UP_ = MES_DPAD_BUTTON_A_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_B_DOWN_ = MES_DPAD_BUTTON_B_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_B_UP_ = MES_DPAD_BUTTON_B_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_C_DOWN_ = MES_DPAD_BUTTON_C_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_C_UP_ = MES_DPAD_BUTTON_C_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_D_DOWN_ = MES_DPAD_BUTTON_D_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_D_UP_ = MES_DPAD_BUTTON_D_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_FORWARD_ = MES_REMOTE_CONTROL_EVT_FORWARD,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_NEXTTRACK_ = MES_REMOTE_CONTROL_EVT_NEXTTRACK,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_PAUSE_ = MES_REMOTE_CONTROL_EVT_PAUSE,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_PLAY_ = MES_REMOTE_CONTROL_EVT_PLAY,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_PREVTRACK_ = MES_REMOTE_CONTROL_EVT_PREVTRACK,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_REWIND_ = MES_REMOTE_CONTROL_EVT_REWIND,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_STOP_ = MES_REMOTE_CONTROL_EVT_STOP,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_VOLUMEDOWN_ = MES_REMOTE_CONTROL_EVT_VOLUMEDOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_VOLUMEUP_ = MES_REMOTE_CONTROL_EVT_VOLUMEUP,\n};\n\nenum EventFlags {\n //%\n QueueIfBusy = MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY,\n //%\n DropIfBusy = MESSAGE_BUS_LISTENER_DROP_IF_BUSY,\n //%\n Reentrant = MESSAGE_BUS_LISTENER_REENTRANT\n};\n\n//% weight=1 color=\"#333333\"\n//% advanced=true\nnamespace control {\n void fiberDone(void *a)\n {\n decr((Action)a);\n release_fiber();\n }\n\n /**\n * Gets the number of milliseconds elapsed since power on.\n */\n //% help=control/millis weight=50\n //% blockId=control_running_time block=\"millis (ms)\"\n int millis() {\n return system_timer_current_time();\n }\n\n /**\n * Gets current time in microseconds. Overflows every ~18 minutes.\n */\n //%\n int micros() {\n return system_timer_current_time_us() & 0x3fffffff;\n }\n\n /**\n * Schedules code that run in the background.\n */\n //% help=control/in-background blockAllowMultiple=1 afterOnStart=true\n //% blockId=\"control_in_background\" block=\"run in background\" blockGap=8\n void inBackground(Action a) {\n runInParallel(a);\n }\n\n /**\n * Blocks the calling thread until the specified event is raised.\n */\n //% help=control/wait-for-event async\n //% blockId=control_wait_for_event block=\"wait for event|from %src|with value %value\"\n void waitForEvent(int src, int value) {\n pxt::waitForEvent(src, value);\n }\n\n /**\n * Resets the BBC micro:bit.\n */\n //% weight=30 async help=control/reset blockGap=8\n //% blockId=\"control_reset\" block=\"reset\"\n void reset() {\n microbit_reset();\n }\n\n /**\n * Blocks the current fiber for the given microseconds\n * @param micros number of micro-seconds to wait. eg: 4\n */\n //% help=control/wait-micros weight=29 async\n //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\"\n //% micros.min=0 micros.max=6000\n void waitMicros(int micros) {\n sleep_us(micros);\n }\n\n /**\n * Raises an event in the event bus.\n * @param src ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.\n * @param value Component specific code indicating the cause of the event.\n * @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_FIRE).\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\" block=\"raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\" blockExternalInputs=1\n //% help=control/raise-event\n //% mode.defl=CREATE_AND_FIRE\n void raiseEvent(int src, int value, EventCreationMode mode) {\n MicroBitEvent evt(src, value, (MicroBitEventLaunchMode)mode);\n }\n\n /**\n * Registers an event handler.\n */\n //% weight=20 blockGap=8 blockId=\"control_on_event\" block=\"on event|from %src=control_event_source_id|with value %value=control_event_value_id\"\n //% help=control/on-event\n //% blockExternalInputs=1\n void onEvent(int src, int value, Action handler, int flags = 0) {\n if (!flags) flags = ::EventFlags::QueueIfBusy;\n registerWithDal(src, value, handler, (int)flags);\n }\n\n /**\n * Gets the value of the last event executed on the bus\n */\n //% blockId=control_event_value\" block=\"event value\"\n //% help=control/event-value\n //% weight=18\n int eventValue() {\n return pxt::lastEvent.value;\n }\n\n /**\n * Gets the timestamp of the last event executed on the bus\n */\n //% blockId=control_event_timestamp\" block=\"event timestamp\"\n //% help=control/event-timestamp\n //% weight=19 blockGap=8\n int eventTimestamp() {\n return pxt::lastEvent.timestamp;\n }\n\n /**\n * Make a friendly name for the device based on its serial number\n */\n //% blockId=\"control_device_name\" block=\"device name\" weight=10 blockGap=8\n //% help=control/device-name\n //% advanced=true\n String deviceName() {\n return mkString(microbit_friendly_name(), -1);\n }\n\n /**\n * Returns the major version of the microbit\n */\n //% help=control/hardware-version\n String _hardwareVersion() {\n #if MICROBIT_CODAL\n MicroBitVersion v = uBit.power.getVersion();\n int versionIdx;\n switch (v.board) {\n case 0x9903:\n case 0x9904:\n versionIdx = 0;\n break;\n default:\n versionIdx = 1;\n break;\n }\n return mkString(MICROBIT_BOARD_VERSION[versionIdx], -1);\n #else\n return mkString(\"1.X\", 1);\n #endif\n }\n\n /**\n * Derive a unique, consistent serial number of this device from internal data.\n */\n //% blockId=\"control_device_serial_number\" block=\"device serial number\" weight=9\n //% help=control/device-serial-number\n //% advanced=true\n int deviceSerialNumber() {\n return microbit_serial_number();\n }\n\n /**\n * Derive a unique, consistent 64-bit serial number of this device from internal data.\n */\n //% help=control/device-long-serial-number\n //% advanced=true\n Buffer deviceLongSerialNumber() {\n return mkBuffer((uint8_t*)&NRF_FICR->DEVICEID[0], sizeof(uint64_t));\n }\n\n /**\n * Informs simulator/runtime of a MIDI message\n * Internal function to support the simulator.\n */\n //% part=midioutput blockHidden=1\n void __midiSend(Buffer buffer) {\n // this is a stub to support the simulator\n }\n\n /**\n *\n */\n //%\n void __log(int priority, String text) {\n if (NULL == text) return;\n pxt::sendSerial(text->getUTF8Data(), text->getUTF8Size());\n }\n\n\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n#if MICROBIT_CODAL\n return ::allocateNotifyEvent();\n#else\n static int notifyEv = 1024;\n return ++notifyEv;\n#endif\n}\n\n/** Write a message to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n // this is no-op on v1\n DMESG(\"# %s\", s->getUTF8Data());\n}\n\n/** Write a message and value (pointer) to DMESG debugging buffer. */\n//%\nvoid dmesgPtr(String str, Object_ ptr) {\n // this is no-op on v1\n DMESG(\"# %s: %p\", str->getUTF8Data(), ptr);\n}\n\n//%\nuint32_t _ramSize()\n{\n return (uint32_t)&__StackTop & 0x1fffffff;\n}\n\n}\n",
|
|
2744
|
+
"control.cpp": "#include \"pxt.h\"\n\nextern uint32_t __StackTop;\n\n/**\n * How to create the event.\n */\nenum class EventCreationMode {\n /**\n * MicroBitEvent is initialised, and no further processing takes place.\n */\n CreateOnly = CREATE_ONLY,\n /**\n * MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).\n */\n CreateAndFire = CREATE_AND_FIRE,\n};\n\nconst char *MICROBIT_BOARD_VERSION[3] = { \"2.0\", \"2.2\", \"2.X\" };\n\n// note the trailing '_' in names - otherwise we get conflict with the pre-processor\n// this trailing underscore is removed by enums.d.ts generation process\n\n// TODO shouldn't these be renamed to something more sensible anyways?\n\nenum EventBusSource {\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_BUTTON_A_ = MICROBIT_ID_BUTTON_A,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_BUTTON_B_ = MICROBIT_ID_BUTTON_B,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_BUTTON_AB_ = MICROBIT_ID_BUTTON_AB,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_RADIO_ = MICROBIT_ID_RADIO,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_GESTURE_ = MICROBIT_ID_GESTURE,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_ACCELEROMETER_ = MICROBIT_ID_ACCELEROMETER,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P0_ = MICROBIT_ID_IO_P0,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P1_ = MICROBIT_ID_IO_P1,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P2_ = MICROBIT_ID_IO_P2,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P3_ = MICROBIT_ID_IO_P3,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P4_ = MICROBIT_ID_IO_P4,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P5_ = MICROBIT_ID_IO_P5,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P6_ = MICROBIT_ID_IO_P6,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P7_ = MICROBIT_ID_IO_P7,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P8_ = MICROBIT_ID_IO_P8,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P9_ = MICROBIT_ID_IO_P9,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P10_ = MICROBIT_ID_IO_P10,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P11_ = MICROBIT_ID_IO_P11,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P12_ = MICROBIT_ID_IO_P12,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P13_ = MICROBIT_ID_IO_P13,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P14_ = MICROBIT_ID_IO_P14,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P15_ = MICROBIT_ID_IO_P15,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P16_ = MICROBIT_ID_IO_P16,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P19_ = MICROBIT_ID_IO_P19,\n //% blockIdentity=\"control.eventSourceId\"\n MICROBIT_ID_IO_P20_ = MICROBIT_ID_IO_P20,\n //% blockIdentity=\"control.eventSourceId\"\n MES_DEVICE_INFO_ID_ = MES_DEVICE_INFO_ID,\n //% blockIdentity=\"control.eventSourceId\"\n MES_SIGNAL_STRENGTH_ID_ = MES_SIGNAL_STRENGTH_ID,\n //% blockIdentity=\"control.eventSourceId\"\n MES_DPAD_CONTROLLER_ID_ = MES_DPAD_CONTROLLER_ID,\n //% blockIdentity=\"control.eventSourceId\"\n MES_BROADCAST_GENERAL_ID_ = MES_BROADCAST_GENERAL_ID,\n};\n\nenum EventBusValue {\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_EVT_ANY_ = MICROBIT_EVT_ANY,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_BUTTON_EVT_DOWN_ = MICROBIT_BUTTON_EVT_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_BUTTON_EVT_UP_ = MICROBIT_BUTTON_EVT_UP,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_BUTTON_EVT_CLICK_ = MICROBIT_BUTTON_EVT_CLICK,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_RADIO_EVT_DATAGRAM_ = MICROBIT_RADIO_EVT_DATAGRAM,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE_ = MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_RISE_ = MICROBIT_PIN_EVT_RISE,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_FALL_ = MICROBIT_PIN_EVT_FALL,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_PULSE_HI_ = MICROBIT_PIN_EVT_PULSE_HI,\n //% blockIdentity=\"control.eventValueId\"\n MICROBIT_PIN_EVT_PULSE_LO_ = MICROBIT_PIN_EVT_PULSE_LO,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM1_ = MES_ALERT_EVT_ALARM1,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM2_ = MES_ALERT_EVT_ALARM2,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM3_ = MES_ALERT_EVT_ALARM3,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM4_ = MES_ALERT_EVT_ALARM4,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM5_ = MES_ALERT_EVT_ALARM5,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_ALARM6_ = MES_ALERT_EVT_ALARM6,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_DISPLAY_TOAST_ = MES_ALERT_EVT_DISPLAY_TOAST,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_FIND_MY_PHONE_ = MES_ALERT_EVT_FIND_MY_PHONE,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_PLAY_RINGTONE_ = MES_ALERT_EVT_PLAY_RINGTONE,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_PLAY_SOUND_ = MES_ALERT_EVT_PLAY_SOUND,\n //% blockIdentity=\"control.eventValueId\"\n MES_ALERT_EVT_VIBRATE_ = MES_ALERT_EVT_VIBRATE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_LAUNCH_PHOTO_MODE_ = MES_CAMERA_EVT_LAUNCH_PHOTO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_LAUNCH_VIDEO_MODE_ = MES_CAMERA_EVT_LAUNCH_VIDEO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_START_VIDEO_CAPTURE_ = MES_CAMERA_EVT_START_VIDEO_CAPTURE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_STOP_PHOTO_MODE_ = MES_CAMERA_EVT_STOP_PHOTO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_STOP_VIDEO_CAPTURE_ = MES_CAMERA_EVT_STOP_VIDEO_CAPTURE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_STOP_VIDEO_MODE_ = MES_CAMERA_EVT_STOP_VIDEO_MODE,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_TAKE_PHOTO_ = MES_CAMERA_EVT_TAKE_PHOTO,\n //% blockIdentity=\"control.eventValueId\"\n MES_CAMERA_EVT_TOGGLE_FRONT_REAR_ = MES_CAMERA_EVT_TOGGLE_FRONT_REAR,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_DISPLAY_OFF_ = MES_DEVICE_DISPLAY_OFF,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_DISPLAY_ON_ = MES_DEVICE_DISPLAY_ON,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_GESTURE_DEVICE_SHAKEN_ = MES_DEVICE_GESTURE_DEVICE_SHAKEN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_INCOMING_CALL_ = MES_DEVICE_INCOMING_CALL,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_INCOMING_MESSAGE_ = MES_DEVICE_INCOMING_MESSAGE,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_ORIENTATION_LANDSCAPE_ = MES_DEVICE_ORIENTATION_LANDSCAPE,\n //% blockIdentity=\"control.eventValueId\"\n MES_DEVICE_ORIENTATION_PORTRAIT_ = MES_DEVICE_ORIENTATION_PORTRAIT,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_1_DOWN_ = MES_DPAD_BUTTON_1_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_1_UP_ = MES_DPAD_BUTTON_1_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_2_DOWN_ = MES_DPAD_BUTTON_2_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_2_UP_ = MES_DPAD_BUTTON_2_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_3_DOWN_ = MES_DPAD_BUTTON_3_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_3_UP_ = MES_DPAD_BUTTON_3_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_4_DOWN_ = MES_DPAD_BUTTON_4_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_4_UP_ = MES_DPAD_BUTTON_4_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_A_DOWN_ = MES_DPAD_BUTTON_A_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_A_UP_ = MES_DPAD_BUTTON_A_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_B_DOWN_ = MES_DPAD_BUTTON_B_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_B_UP_ = MES_DPAD_BUTTON_B_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_C_DOWN_ = MES_DPAD_BUTTON_C_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_C_UP_ = MES_DPAD_BUTTON_C_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_D_DOWN_ = MES_DPAD_BUTTON_D_DOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_DPAD_BUTTON_D_UP_ = MES_DPAD_BUTTON_D_UP,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_FORWARD_ = MES_REMOTE_CONTROL_EVT_FORWARD,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_NEXTTRACK_ = MES_REMOTE_CONTROL_EVT_NEXTTRACK,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_PAUSE_ = MES_REMOTE_CONTROL_EVT_PAUSE,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_PLAY_ = MES_REMOTE_CONTROL_EVT_PLAY,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_PREVTRACK_ = MES_REMOTE_CONTROL_EVT_PREVTRACK,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_REWIND_ = MES_REMOTE_CONTROL_EVT_REWIND,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_STOP_ = MES_REMOTE_CONTROL_EVT_STOP,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_VOLUMEDOWN_ = MES_REMOTE_CONTROL_EVT_VOLUMEDOWN,\n //% blockIdentity=\"control.eventValueId\"\n MES_REMOTE_CONTROL_EVT_VOLUMEUP_ = MES_REMOTE_CONTROL_EVT_VOLUMEUP,\n};\n\nenum EventFlags {\n //%\n QueueIfBusy = MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY,\n //%\n DropIfBusy = MESSAGE_BUS_LISTENER_DROP_IF_BUSY,\n //%\n Reentrant = MESSAGE_BUS_LISTENER_REENTRANT\n};\n\n//% weight=1 color=\"#333333\"\n//% advanced=true\nnamespace control {\n void fiberDone(void *a)\n {\n decr((Action)a);\n release_fiber();\n }\n\n /**\n * Gets the number of milliseconds elapsed since power on.\n */\n //% help=control/millis weight=50\n //% blockId=control_running_time block=\"millis (ms)\"\n int millis() {\n return system_timer_current_time();\n }\n\n /**\n * Gets current time in microseconds. Overflows every ~18 minutes.\n */\n //%\n int micros() {\n return system_timer_current_time_us() & 0x3fffffff;\n }\n\n /**\n * Schedules code that run in the background.\n */\n //% help=control/in-background blockAllowMultiple=1 afterOnStart=true\n //% blockId=\"control_in_background\" block=\"run in background\" blockGap=8\n void inBackground(Action a) {\n runInParallel(a);\n }\n\n /**\n * Blocks the calling thread until the specified event is raised.\n */\n //% help=control/wait-for-event async\n //% blockId=control_wait_for_event block=\"wait for event|from %src|with value %value\"\n void waitForEvent(int src, int value) {\n pxt::waitForEvent(src, value);\n }\n\n /**\n * Resets the BBC micro:bit.\n */\n //% weight=30 async help=control/reset blockGap=8\n //% blockId=\"control_reset\" block=\"reset\"\n void reset() {\n microbit_reset();\n }\n\n /**\n * Blocks the current fiber for the given microseconds\n * @param micros number of micro-seconds to wait. eg: 4\n */\n //% help=control/wait-micros weight=29 async\n //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\"\n //% micros.min=0 micros.max=6000\n void waitMicros(int micros) {\n sleep_us(micros);\n }\n\n /**\n * Raises an event in the event bus.\n * @param src ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.\n * @param value Component specific code indicating the cause of the event.\n * @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_FIRE).\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\" block=\"raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\" blockExternalInputs=1\n //% help=control/raise-event\n //% mode.defl=CREATE_AND_FIRE\n void raiseEvent(int src, int value, EventCreationMode mode) {\n MicroBitEvent evt(src, value, (MicroBitEventLaunchMode)mode);\n }\n\n /**\n * Registers an event handler.\n */\n //% weight=20 blockGap=8 blockId=\"control_on_event\" block=\"on event|from %src=control_event_source_id|with value %value=control_event_value_id\"\n //% help=control/on-event\n //% blockExternalInputs=1\n void onEvent(int src, int value, Action handler, int flags = 0) {\n if (!flags) flags = ::EventFlags::QueueIfBusy;\n registerWithDal(src, value, handler, (int)flags);\n }\n\n /**\n * Gets the value of the last event executed on the bus\n */\n //% blockId=control_event_value\" block=\"event value\"\n //% help=control/event-value\n //% weight=18\n int eventValue() {\n return pxt::lastEvent.value;\n }\n\n /**\n * Gets the timestamp of the last event executed on the bus\n */\n //% blockId=control_event_timestamp\" block=\"event timestamp\"\n //% help=control/event-timestamp\n //% weight=19 blockGap=8\n int eventTimestamp() {\n return pxt::lastEvent.timestamp;\n }\n\n /**\n * Make a friendly name for the device based on its serial number\n */\n //% blockId=\"control_device_name\" block=\"device name\" weight=10 blockGap=8\n //% help=control/device-name\n //% advanced=true\n String deviceName() {\n return mkString(microbit_friendly_name(), -1);\n }\n\n /**\n * Returns the major version of the microbit\n */\n //% help=control/hardware-version\n String _hardwareVersion() {\n #if MICROBIT_CODAL\n MicroBitVersion v = uBit.power.getVersion();\n int versionIdx;\n switch (v.board) {\n case 0x9903:\n case 0x9904:\n versionIdx = 0;\n break;\n case 0x9905:\n case 0x9906:\n versionIdx = 1;\n break;\n default:\n versionIdx = 2;\n break;\n }\n return mkString(MICROBIT_BOARD_VERSION[versionIdx], -1);\n #else\n return mkString(\"1.X\", 1);\n #endif\n }\n\n /**\n * Derive a unique, consistent serial number of this device from internal data.\n */\n //% blockId=\"control_device_serial_number\" block=\"device serial number\" weight=9\n //% help=control/device-serial-number\n //% advanced=true\n int deviceSerialNumber() {\n return microbit_serial_number();\n }\n\n /**\n * Derive a unique, consistent 64-bit serial number of this device from internal data.\n */\n //% help=control/device-long-serial-number\n //% advanced=true\n Buffer deviceLongSerialNumber() {\n return mkBuffer((uint8_t*)&NRF_FICR->DEVICEID[0], sizeof(uint64_t));\n }\n\n /**\n * Informs simulator/runtime of a MIDI message\n * Internal function to support the simulator.\n */\n //% part=midioutput blockHidden=1\n void __midiSend(Buffer buffer) {\n // this is a stub to support the simulator\n }\n\n /**\n *\n */\n //%\n void __log(int priority, String text) {\n if (NULL == text) return;\n pxt::sendSerial(text->getUTF8Data(), text->getUTF8Size());\n }\n\n\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n#if MICROBIT_CODAL\n return ::allocateNotifyEvent();\n#else\n static int notifyEv = 1024;\n return ++notifyEv;\n#endif\n}\n\n/** Write a message to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n // this is no-op on v1\n DMESG(\"# %s\", s->getUTF8Data());\n}\n\n/** Write a message and value (pointer) to DMESG debugging buffer. */\n//%\nvoid dmesgPtr(String str, Object_ ptr) {\n // this is no-op on v1\n DMESG(\"# %s: %p\", str->getUTF8Data(), ptr);\n}\n\n//%\nuint32_t _ramSize()\n{\n return (uint32_t)&__StackTop & 0x1fffffff;\n}\n\n}\n",
|
|
2731
2745
|
"control.ts": "/**\n* Runtime and event utilities.\n*/\n//% weight=1 color=\"#333333\" icon=\"\\uf233\"\n//% advanced=true\nnamespace control {\n /**\n * Run other code in the parallel.\n */\n //% hidden=1\n export function runInParallel(a: () => void) {\n control.inBackground(a);\n }\n\n //% hidden=1 deprecated=1\n export function runInBackground(a: () => void) {\n control.inBackground(a);\n }\n\n /**\n * Returns the value of a C++ runtime constant\n */\n //% weight=2 weight=19 blockId=\"control_event_source_id\" block=\"%id\" blockGap=8\n //% help=control/event-source-id\n //% shim=TD_ID advanced=true\n export function eventSourceId(id: EventBusSource): number {\n return id;\n }\n /**\n * Returns the value of a C++ runtime constant\n */\n //% weight=1 weight=19 blockId=\"control_event_value_id\" block=\"%id\"\n //% help=control/event-value-id\n //% shim=TD_ID advanced=true\n export function eventValueId(id: EventBusValue): number {\n return id;\n }\n\n export const enum PXT_PANIC {\n CODAL_OOM = 20,\n GC_OOM = 21,\n GC_TOO_BIG_ALLOCATION = 22,\n CODAL_HEAP_ERROR = 30,\n CODAL_NULL_DEREFERENCE = 40,\n CODAL_USB_ERROR = 50,\n CODAL_HARDWARE_CONFIGURATION_ERROR = 90,\n\n INVALID_BINARY_HEADER = 901,\n OUT_OF_BOUNDS = 902,\n REF_DELETED = 903,\n SIZE = 904,\n INVALID_VTABLE = 905,\n INTERNAL_ERROR = 906,\n NO_SUCH_CONFIG = 907,\n NO_SUCH_PIN = 908,\n INVALID_ARGUMENT = 909,\n MEMORY_LIMIT_EXCEEDED = 910,\n SCREEN_ERROR = 911,\n MISSING_PROPERTY = 912,\n INVALID_IMAGE = 913,\n CALLED_FROM_ISR = 914,\n HEAP_DUMPED = 915,\n STACK_OVERFLOW = 916,\n BLOCKING_TO_STRING = 917,\n VM_ERROR = 918,\n SETTINGS_CLEARED = 920,\n SETTINGS_OVERLOAD = 921,\n SETTINGS_SECRET_MISSING = 922,\n DELETE_ON_CLASS = 923,\n\n CAST_FIRST = 980,\n CAST_FROM_UNDEFINED = 980,\n CAST_FROM_BOOLEAN = 981,\n CAST_FROM_NUMBER = 982,\n CAST_FROM_STRING = 983,\n CAST_FROM_OBJECT = 984,\n CAST_FROM_FUNCTION = 985,\n CAST_FROM_NULL = 989,\n\n UNHANDLED_EXCEPTION = 999,\n }\n\n /**\n * Display specified error code and stop the program.\n */\n //% shim=pxtrt::panic\n export function panic(code: number) { }\n\n /**\n * If the condition is false, display msg on serial console, and panic with code 098.\n */\n export function assert(condition: boolean, msg?: string) {\n if (!condition) {\n console.log(\"ASSERTION FAILED\")\n if (msg != null) {\n console.log(msg)\n }\n panic(98)\n }\n }\n\n export function fail(message: string) {\n console.log(\"Fatal failure: \")\n console.log(message)\n panic(108)\n }\n\n let _evSource = 0x8000\n /**\n * Incrementally allocates event source identifiers.\n */\n export function allocateEventSource() {\n return ++_evSource\n } \n\n /**\n * Display warning in the simulator.\n */\n //% shim=pxtrt::runtimeWarning\n export function runtimeWarning(message: string) { }\n\n //% shim=pxt::programHash\n export declare function programHash(): number;\n\n //% shim=pxt::programName\n export declare function programName(): string;\n\n /** Returns estimated size of memory in bytes. */\n //% shim=control::_ramSize\n export function ramSize() {\n return 32 * 1024 * 1024;\n }\n\n /** Runs the function and returns run time in microseconds. */\n export function benchmark(f: () => void) {\n const t0 = micros()\n f()\n let t = micros() - t0\n if (t < 0)\n t += 0x3fffffff\n return t\n }\n\n /**\n * Given two versions, returns -1 if the first version is less than\n * the second, 1 if it's greater, and 0 if it's the same.\n */\n //%\n export function compareVersion(version1: string, version2: string): number {\n let v1Arr = version1.split(\".\");\n let v2Arr = version2.split(\".\");\n\n v1Arr = v1Arr.map((str) => {\n if (str.includes(\"x\") || str.includes(\"X\")) {\n return \"0\"\n } else {\n return str;\n }\n })\n v2Arr = v2Arr.map((str) => {\n if (str.includes(\"x\") || str.includes(\"X\")) {\n return \"0\"\n } else {\n return str;\n }\n })\n\n for (let i = v1Arr.length; i < Math.max(v1Arr.length, v2Arr.length); i++) {\n v1Arr.push(\"0\");\n }\n\n for (let i = v2Arr.length; i < Math.max(v1Arr.length, v2Arr.length); i++) {\n v2Arr.push(\"0\");\n }\n\n for (let i = 0; i < v1Arr.length; i++) {\n if (parseInt(v1Arr[i]) != parseInt(v2Arr[i])) {\n return parseInt(v1Arr[i]) - parseInt(v2Arr[i]);\n }\n }\n return 0;\n }\n\n //% shim=control::_hardwareVersion\n export function hardwareVersion(): string {\n return \"2.0\";\n }\n}\n\n/**\n * Convert any value to text\n * @param value value to be converted to text\n */\n//% help=text/convert-to-text weight=1\n//% block=\"convert $value=math_number to text\"\n//% blockId=variable_to_text blockNamespace=\"text\"\nfunction convertToText(value: any): string {\n return \"\" + value;\n}",
|
|
2732
2746
|
"controlgc.cpp": "#include \"pxtbase.h\"\n\n\nnamespace control {\n /**\n * Force GC and dump basic information about heap.\n */\n //%\n void gc() {\n pxt::gc(1);\n }\n\n /**\n * Force GC and halt waiting for debugger to do a full heap dump.\n */\n //%\n void heapDump() {\n pxt::gc(2);\n soft_panic(PANIC_HEAP_DUMPED);\n }\n\n\n /**\n * Set flags used when connecting an external debugger.\n */\n //%\n void setDebugFlags(int flags) {\n debugFlags = flags;\n }\n\n /**\n * Record a heap snapshot to debug memory leaks.\n */\n //%\n void heapSnapshot() {\n // only in JS backend for now\n }\n\n /**\n * Return true if profiling is enabled in the current build.\n */\n //%\n bool profilingEnabled() {\n#ifdef PXT_PROFILE\n return true;\n#else\n return false;\n#endif\n }\n}\n",
|
|
2733
2747
|
"controlmessage.ts": "namespace control.simmessages {\n // these events are raised by JS simulator when messages come in\n export const CONTROL_MESSAGE_EVT_ID = 2999;\n export const CONTROL_MESSAGE_RECEIVED = 1;\n\n //% shim=pxt::sendMessage\n export declare function send(channel: string, message: Buffer, parentOnly?: boolean) : void;\n\n //% shim=pxt::peekMessageChannel\n declare function peekMessageChannel(): string;\n\n //% shim=pxt::readMessageData\n declare function readMessageData(): Buffer;\n\n let handlers: { [channel: string] : (msg: Buffer) => void}\n function consumeMessages() {\n while(true) {\n // peek channel of next message\n const channel = peekMessageChannel();\n if (!channel) break;\n // read next message\n const msg = readMessageData();\n // send to handler\n const handler = handlers && handlers[channel];\n if (handler)\n handler(msg);\n }\n }\n\n /**\n * Registers the handler for a message on a given channel\n **/\n export function onReceived(channel: string, handler: (msg: Buffer) => void) {\n if (!channel) return;\n\n if (!handlers)\n handlers = {};\n handlers[channel] = handler;\n control.onEvent(CONTROL_MESSAGE_EVT_ID, CONTROL_MESSAGE_RECEIVED, consumeMessages);\n }\n}",
|
|
@@ -2765,12 +2779,12 @@ var pxtTargetBundle = {
|
|
|
2765
2779
|
"platform.h": "#include \"nrf.h\"\n\n// helpful define to handle C++ differences in package\n#define PXT_MICROBIT_TAGGED_INT 1\n#define PXT_POWI 1\n",
|
|
2766
2780
|
"poll.ts": "namespace control {\n class PollEvent {\n public eid: number;\n public vid: number;\n public start: number;\n public timeOut: number;\n public condition: () => boolean;\n public once: boolean;\n constructor(eid: number, vid: number, start: number, timeOut: number, condition: () => boolean, once: boolean) {\n this.eid = eid;\n this.vid = vid;\n this.start = start;\n this.timeOut = timeOut;\n this.condition = condition;\n this.once = once;\n }\n }\n\n let _pollEventQueue: PollEvent[] = undefined;\n\n function pollEvents() {\n while (_pollEventQueue.length > 0) {\n const now = control.millis();\n for (let i = 0; i < _pollEventQueue.length; ++i) {\n const ev = _pollEventQueue[i];\n if (ev.condition() || (ev.timeOut > 0 && now - ev.start > ev.timeOut)) {\n control.raiseEvent(ev.eid, ev.vid);\n if (ev.once) {\n _pollEventQueue.splice(i, 1);\n --i;\n }\n }\n }\n pause(50);\n }\n // release fiber\n _pollEventQueue = undefined;\n }\n\n export function __queuePollEvent(timeOut: number, condition: () => boolean, handler: () => void) {\n const ev = new PollEvent(\n DAL.DEVICE_ID_NOTIFY,\n control.allocateNotifyEvent(),\n control.millis(),\n timeOut,\n condition,\n !handler\n );\n\n // start polling fiber if needed\n if (!_pollEventQueue) {\n _pollEventQueue = [ev];\n control.runInParallel(pollEvents);\n }\n else {\n // add to the queue\n _pollEventQueue.push(ev)\n }\n\n // register event\n if (handler)\n control.onEvent(ev.eid, ev.vid, handler);\n else // or wait\n control.waitForEvent(ev.eid, ev.vid);\n } \n}\n\n/**\n * Busy wait for a condition to be true\n * @param condition condition to test for\n * @param timeOut if positive, maximum duration to wait for in milliseconds\n */\n//% blockId=\"pxt_pause_until\"\nfunction pauseUntil(condition: () => boolean, timeOut?: number): void {\n if (!condition || condition()) return; // optimistic path\n if (!timeOut) timeOut = 0;\n control.__queuePollEvent(timeOut, condition, undefined);\n}\n",
|
|
2767
2781
|
"pxt-core.d.ts": "/// <reference no-default-lib=\"true\"/>\n\ninterface Array<T> {\n /**\n * Get or set the length of an array. This number is one more than the index of the last element the array.\n */\n //% shim=Array_::length weight=84\n //% blockId=\"lists_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"arrays\"\n length: number;\n\n /**\n * Append a new element to an array.\n * @param items New elements of the Array.\n */\n //% help=arrays/push\n //% shim=Array_::push weight=50\n //% blockId=\"array_push\" block=\"%list| add value %value| to end\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n push(item: T): void;\n\n /**\n * Concatenates the values with another array.\n * @param arr The other array that is being concatenated with\n */\n //% helper=arrayConcat weight=40\n concat(arr: T[]): T[];\n\n /**\n * Remove the last element from an array and return it.\n */\n //% help=arrays/pop\n //% shim=Array_::pop weight=45\n //% blockId=\"array_pop\" block=\"get and remove last value from %list\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n pop(): T;\n\n /**\n * Reverse the elements in an array. The first array element becomes the last, and the last array element becomes the first.\n */\n //% help=arrays/reverse\n //% helper=arrayReverse weight=10\n //% blockId=\"array_reverse\" block=\"reverse %list\" blockNamespace=\"arrays\"\n //% group=\"Operations\"\n reverse(): void;\n\n /**\n * Remove the first element from an array and return it. This method changes the length of the array.\n */\n //% help=arrays/shift\n //% helper=arrayShift weight=30\n //% blockId=\"array_shift\" block=\"get and remove first value from %list\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n shift(): T;\n\n /**\n * Add one element to the beginning of an array and return the new length of the array.\n * @param element to insert at the start of the Array.\n */\n //% help=arrays/unshift\n //% helper=arrayUnshift weight=25\n //% blockId=\"array_unshift\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n //unshift(...values:T[]): number; //rest is not supported in our compiler yet.\n unshift(value: T): number;\n\n /**\n * Return a section of an array.\n * @param start The beginning of the specified portion of the array. eg: 0\n * @param end The end of the specified portion of the array. eg: 0\n */\n //% help=arrays/slice\n //% helper=arraySlice weight=41 blockNamespace=\"arrays\"\n slice(start?: number, end?: number): T[];\n\n /**\n * Remove elements from an array.\n * @param start The zero-based location in the array from which to start removing elements. eg: 0\n * @param deleteCount The number of elements to remove. eg: 0\n */\n //% helper=arraySplice weight=40\n splice(start: number, deleteCount: number): void;\n\n /**\n * joins all elements of an array into a string and returns this string.\n * @param sep the string separator\n */\n //% helper=arrayJoin weight=40\n join(sep?: string): string;\n\n /**\n * Tests whether at least one element in the array passes the test implemented by the provided function.\n * @param callbackfn A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arraySome weight=40\n some(callbackfn: (value: T, index: number) => boolean): boolean;\n\n /**\n * Tests whether all elements in the array pass the test implemented by the provided function.\n * @param callbackfn A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayEvery weight=40\n every(callbackfn: (value: T, index: number) => boolean): boolean;\n\n /**\n * Sort the elements of an array in place and returns the array. The sort is not necessarily stable.\n * @param specifies a function that defines the sort order. If omitted, the array is sorted according to the prmitive type\n */\n //% helper=arraySort weight=40\n sort(callbackfn?: (value1: T, value2: T) => number): T[];\n\n /**\n * Call a defined callback function on each element of an array, and return an array containing the results.\n * @param callbackfn A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayMap weight=40\n map<U>(callbackfn: (value: T, index: number) => U): U[];\n\n /**\n * Call a defined callback function on each element of an array.\n * @param callbackfn A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayForEach weight=40\n forEach(callbackfn: (value: T, index: number) => void): void;\n\n /**\n * Return the elements of an array that meet the condition specified in a callback function.\n * @param callbackfn A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayFilter weight=40\n filter(callbackfn: (value: T, index: number) => boolean): T[];\n\n /**\n * Fills all the elements of an array from a start index to an end index with a static value. The end index is not included.\n */\n //% helper=arrayFill weight=39\n fill(value: T, start?: number, end?: number): T[];\n\n /**\n * Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.\n * @param callbackfn\n */\n //% helper=arrayFind weight=40\n find(callbackfn: (value: T, index: number) => boolean): T;\n\n /**\n * Call the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n * @param callbackfn A function that accepts up to three arguments. The reduce method calls the callbackfn function one time for each element in the array.\n * @param initialValue Initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n */\n //% helper=arrayReduce weight=40\n reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;\n\n\n /** Remove the first occurence of an object. Returns true if removed. */\n //% shim=Array_::removeElement weight=48\n removeElement(element: T): boolean;\n\n /** Remove the element at a certain index. */\n //% help=arrays/remove-at\n //% shim=Array_::removeAt weight=47\n //% blockId=\"array_removeat\" block=\"%list| get and remove value at %index\" blockNamespace=\"arrays\"\n //% group=\"Read\"\n removeAt(index: number): T;\n\n /**\n * Insert the value at a particular index, increases length by 1\n * @param index the zero-based position in the list to insert the value, eg: 0\n * @param the value to insert, eg: 0\n */\n //% help=arrays/insert-at\n //% shim=Array_::insertAt weight=20\n //% blockId=\"array_insertAt\" block=\"%list| insert at %index| value %value\" blockNamespace=\"arrays\"\n //% group=\"Modify\"\n insertAt(index: number, value: T): void;\n\n /**\n * Return the index of the first occurrence of a value in an array.\n * @param item The value to locate in the array.\n * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\n */\n //% help=arrays/index-of\n //% shim=Array_::indexOf weight=40\n //% blockId=\"array_indexof\" block=\"%list| find index of %value\" blockNamespace=\"arrays\"\n //% group=\"Operations\"\n indexOf(item: T, fromIndex?: number): number;\n\n /**\n * Get the value at a particular index\n * @param index the zero-based position in the list of the item, eg: 0\n */\n //% help=arrays/get\n //% shim=Array_::getAt weight=85\n get(index: number): T;\n\n /**\n * Store a value at a particular index\n * @param index the zero-based position in the list to store the value, eg: 0\n * @param value the value to insert, eg: 0\n */\n //% help=arrays/set\n //% shim=Array_::setAt weight=84\n set(index: number, value: T): void;\n\n /**\n * Return a random value from the array\n */\n //% help=arrays/pick-random\n //% helper=arrayPickRandom weight=25\n //% blockId=\"array_pickRandom\" block=\"get random value from %list\"\n //% blockNamespace=\"arrays\"\n //% group=\"Read\"\n _pickRandom(): T;\n\n [n: number]: T;\n\n /**\n * Add one element to the beginning of an array and return the new length of the array.\n * @param element to insert at the start of the Array.\n */\n //% help=arrays/unshift\n //% helper=arrayUnshift weight=24\n //% blockId=\"array_unshift_statement\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.unshift\"\n //% group=\"Modify\"\n _unshiftStatement(value: T): void;\n\n /**\n * Remove the last element from an array and return it.\n */\n //% help=arrays/pop\n //% shim=Array_::pop weight=44\n //% blockId=\"array_pop_statement\" block=\"remove last value from %list\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.pop\"\n //% group=\"Modify\"\n _popStatement(): void;\n\n /**\n * Remove the first element from an array and return it. This method changes the length of the array.\n */\n //% help=arrays/shift\n //% helper=arrayShift weight=29\n //% blockId=\"array_shift_statement\" block=\"remove first value from %list\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.shift\"\n //% group=\"Modify\"\n _shiftStatement(): void;\n\n /** Remove the element at a certain index. */\n //% help=arrays/remove-at\n //% shim=Array_::removeAt weight=14\n //% blockId=\"array_removeat_statement\" block=\"%list| remove value at %index\" blockNamespace=\"arrays\"\n //% blockAliasFor=\"Array.removeAt\"\n //% group=\"Modify\"\n _removeAtStatement(index: number): void;\n}\n\ndeclare interface String {\n // This block is currently disabled in favor of the built-in Blockly \"Create text with\" block, which compiles to \"\" + \"\"\n // Add % sign back to the block annotation to re-enable\n /**\n * Returns a string that contains the concatenation of two or more strings.\n * @param other The string to append to the end of the string.\n */\n //% shim=String_::concat weight=49\n //% blockId=\"string_concat\" blockNamespace=\"text\"\n // block=\"join %list=text|%other\"\n concat(other: string): string;\n\n /**\n * Return the character at the specified index.\n * @param index The zero-based index of the desired character.\n */\n //% shim=String_::charAt weight=48\n //% help=text/char-at\n //% blockId=\"string_get\" block=\"char from %this=text|at %pos\" blockNamespace=\"text\"\n charAt(index: number): string;\n\n /** Returns the length of a String object. */\n //% property shim=String_::length weight=47\n //% blockId=\"text_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"text\"\n length: number;\n\n /**\n * Return the Unicode value of the character at the specified location.\n * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.\n */\n //% shim=String_::charCodeAt\n charCodeAt(index: number): number;\n\n /**\n * See how the order of characters in two strings is different (in ASCII encoding).\n * @param that String to compare to target string\n */\n //% shim=String_::compare\n //% help=text/compare\n //% blockId=\"string_compare\" block=\"compare %this=text| to %that\" blockNamespace=\"text\"\n compare(that: string): number;\n\n /**\n * Return a substring of the current string.\n * @param start first character index; can be negative from counting from the end, eg:0\n * @param length number of characters to extract, eg: 10\n */\n //% helper=stringSubstr\n //% help=text/substr\n //% blockId=\"string_substr\" block=\"substring of %this=text|from %start|of length %length\" blockNamespace=\"text\"\n substr(start: number, length?: number): string;\n\n /**\n * Return the current string with the first occurence of toReplace\n * replaced with the replacer\n * @param toReplace the substring to replace in the current string\n * @param replacer either the string that replaces toReplace in the current string,\n * or a function that accepts the substring and returns the replacement string.\n */\n //% helper=stringReplace\n replace(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n /**\n * Return the current string with each occurence of toReplace\n * replaced with the replacer\n * @param toReplace the substring to replace in the current string\n * @param replacer either the string that replaces toReplace in the current string,\n * or a function that accepts the substring and returns the replacement string.\n */\n //% helper=stringReplaceAll\n replaceAll(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n /**\n * Return a substring of the current string.\n * @param start first character index; can be negative from counting from the end, eg:0\n * @param end one-past-last character index\n */\n //% helper=stringSlice\n slice(start: number, end?: number): string;\n\n /** Returns a value indicating if the string is empty */\n //% helper=stringEmpty\n //% help=text/is-empty\n //% blockId=\"string_isempty\" blockNamespace=\"text\"\n //% block=\"%this=text| is empty\"\n isEmpty(): boolean;\n\n /**\n * Returns the position of the first occurrence of a specified value in a string.\n * @param searchValue the text to find\n * @param start optional start index for the search\n */\n //% shim=String_::indexOf\n //% help=text/index-of\n //% blockId=\"string_indexof\" blockNamespace=\"text\"\n //% block=\"%this=text|find index of %searchValue\"\n indexOf(searchValue: string, start?: number): number;\n\n /**\n * Determines whether a string contains the characters of a specified string.\n * @param searchValue the text to find\n * @param start optional start index for the search\n */\n //% shim=String_::includes\n //% help=text/includes\n //% blockId=\"string_includes\" blockNamespace=\"text\"\n //% block=\"%this=text|includes %searchValue\"\n includes(searchValue: string, start?: number): boolean;\n\n /**\n * Splits the string according to the separators\n * @param separator\n * @param limit\n */\n //% helper=stringSplit\n //% help=text/split\n //% blockId=\"string_split\" blockNamespace=\"text\"\n //% block=\"split %this=text|at %separator\"\n split(separator?: string, limit?: number): string[];\n\n /**\n * Return a substring of the current string with whitespace removed from both ends\n */\n //% helper=stringTrim\n trim(): string;\n\n /**\n * Converts the string to upper case characters.\n */\n //% helper=stringToUpperCase\n //% help=text/to-upper-case\n toUpperCase(): string;\n\n /**\n * Converts the string to lower case characters.\n */\n //% helper=stringToLowerCase\n //% help=text/to-lower-case\n toLowerCase(): string;\n\n [index: number]: string;\n}\n\n/**\n * Convert a string to a number.\n * @param s A string to convert into a number. eg: 123\n */\n//% shim=String_::toNumber\n//% help=text/parse-float\n//% blockId=\"string_parsefloat\" block=\"parse to number %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\ndeclare function parseFloat(text: string): number;\n\n/**\n * Returns a pseudorandom number between min and max included.\n * If both numbers are integral, the result is integral.\n * @param min the lower inclusive bound, eg: 0\n * @param max the upper inclusive bound, eg: 10\n */\n//% blockId=\"device_random\" block=\"pick random %min|to %limit\"\n//% blockNamespace=\"Math\"\n//% help=math/randint\n//% shim=Math_::randomRange\ndeclare function randint(min: number, max: number): number;\n\ninterface Object { }\ninterface Function {\n __assignableToFunction: Function;\n}\ninterface IArguments {\n __assignableToIArguments: IArguments;\n}\ninterface RegExp {\n __assignableToRegExp: RegExp;\n}\ntype TemplateStringsArray = Array<string>;\n\ntype uint8 = number;\ntype uint16 = number;\ntype uint32 = number;\ntype int8 = number;\ntype int16 = number;\ntype int32 = number;\n\n\ndeclare interface Boolean {\n /**\n * Returns a string representation of an object.\n */\n //% shim=numops::toString\n toString(): string;\n}\n\n/**\n * Combine, split, and search text strings.\n*/\n//% blockNamespace=\"text\"\ndeclare namespace String {\n\n /**\n * Make a string from the given ASCII character code.\n */\n //% help=math/from-char-code\n //% shim=String_::fromCharCode weight=1\n //% blockNamespace=\"text\" blockId=\"stringFromCharCode\" block=\"text from char code %code\"\n function fromCharCode(code: number): string;\n}\n\ndeclare interface Number {\n /**\n * Returns a string representation of a number.\n */\n //% shim=numops::toString\n toString(): string;\n}\n\n/**\n * Add, remove, and replace items in lists.\n*/\n//% blockNamespace=\"Arrays\"\ndeclare namespace Array {\n /**\n * Check if a given object is an array.\n */\n //% shim=Array_::isArray\n function isArray(obj: any): boolean;\n}\n\ndeclare namespace Object {\n /**\n * Return the field names in an object.\n */\n //% shim=pxtrt::keysOf\n function keys(obj: any): string[];\n}\n\n/**\n * More complex operations with numbers.\n*/\ndeclare namespace Math {\n /**\n * Returns the value of a base expression taken to a specified power.\n * @param x The base value of the expression.\n * @param y The exponent value of the expression.\n */\n //% shim=Math_::pow\n function pow(x: number, y: number): number;\n\n /**\n * Returns a pseudorandom number between 0 and 1.\n */\n //% shim=Math_::random\n //% help=math/random\n function random(): number;\n\n /**\n * Returns a pseudorandom number between min and max included.\n * If both numbers are integral, the result is integral.\n * @param min the lower inclusive bound, eg: 0\n * @param max the upper inclusive bound, eg: 10\n */\n //% blockId=\"device_random_deprecated\" block=\"pick random %min|to %limit\"\n //% help=math/random-range deprecated\n //% shim=Math_::randomRange\n function randomRange(min: number, max: number): number;\n\n /**\n * Returns the natural logarithm (base e) of a number.\n * @param x A number\n */\n //% shim=Math_::log\n //% help=math\n function log(x: number): number;\n\n /**\n * Returns returns ``e^x``.\n * @param x A number\n */\n //% shim=Math_::exp\n //% help=math\n function exp(x: number): number;\n\n /**\n * Returns the sine of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::sin\n //% help=math/trigonometry\n function sin(x: number): number;\n\n /**\n * Returns the cosine of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::cos\n //% help=math/trigonometry\n function cos(x: number): number;\n\n /**\n * Returns the tangent of a number.\n * @param x An angle in radians\n */\n //% shim=Math_::tan\n //% help=math/trigonometry\n function tan(x: number): number;\n\n /**\n * Returns the arcsine (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::asin\n //% help=math/trigonometry\n function asin(x: number): number;\n\n /**\n * Returns the arccosine (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::acos\n //% help=math/trigonometry\n function acos(x: number): number;\n\n /**\n * Returns the arctangent (in radians) of a number\n * @param x A number\n */\n //% shim=Math_::atan\n //% help=math/trigonometry\n function atan(x: number): number;\n\n /**\n * Returns the arctangent of the quotient of its arguments.\n * @param y A number\n * @param x A number\n */\n //% shim=Math_::atan2\n //% help=math/trigonometry\n function atan2(y: number, x: number): number;\n\n /**\n * Returns the square root of a number.\n * @param x A numeric expression.\n */\n //% shim=Math_::sqrt\n //% help=math\n function sqrt(x: number): number;\n\n /**\n * Returns the smallest number greater than or equal to its numeric argument.\n * @param x A numeric expression.\n */\n //% shim=Math_::ceil\n //% help=math\n function ceil(x: number): number;\n\n /**\n * Returns the greatest number less than or equal to its numeric argument.\n * @param x A numeric expression.\n */\n //% shim=Math_::floor\n //% help=math\n function floor(x: number): number;\n\n /**\n * Returns the number with the decimal part truncated.\n * @param x A numeric expression.\n */\n //% shim=Math_::trunc\n //% help=math\n function trunc(x: number): number;\n\n /**\n * Returns a supplied numeric expression rounded to the nearest number.\n * @param x The value to be rounded to the nearest number.\n */\n //% shim=Math_::round\n //% help=math\n function round(x: number): number;\n\n /**\n * Returns the value of integer signed 32 bit multiplication of two numbers.\n * @param x The first number\n * @param y The second number\n */\n //% shim=Math_::imul\n //% help=math\n function imul(x: number, y: number): number;\n\n /**\n * Returns the value of integer signed 32 bit division of two numbers.\n * @param x The first number\n * @param y The second number\n */\n //% shim=Math_::idiv\n //% help=math\n function idiv(x: number, y: number): number;\n}\n\ndeclare namespace control {\n //% shim=_control::_onCodeStart\n export function _onCodeStart(arg: any): void;\n\n //% shim=_control::_onCodeStop\n export function _onCodeStop(arg: any): void;\n}",
|
|
2768
|
-
"pxt-helpers.ts": "type Action = () => void;\n\n/**\n * Constant representing Not-A-Number.\n */\nconst NaN = 0 / 0\n\n/**\n * Constant representing positive infinity.\n */\nconst Infinity = 1 / 0\n\nfunction isNaN(x: number) {\n x = +x // convert to number\n return x !== x\n}\n\nnamespace Number {\n /**\n * Check if a given value is of type Number and it is a NaN.\n */\n export function isNaN(x: any): boolean {\n return typeof x == \"number\" && x !== x\n }\n}\n\n/**\n * A dictionary from string key to string values\n */\ninterface StringMap {\n [index: string]: string;\n}\n\n/**\n * Convert a string to an integer.\n * @param text A string to convert into an integral number. eg: \"123\"\n * @param radix optional A value between 2 and 36 that specifies the base of the number in text.\n * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\n * All other strings are considered decimal.\n */\n//% help=text/parse-int\n//% blockId=\"string_parseint\" block=\"parse to integer %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\n//% blockHidden=1\nfunction parseInt(text: string, radix?: number): number {\n // roughly based on https://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.2\n // with some consideration for avoiding unnecessary slices where easy\n if (!text || (radix != null && (radix < 2 || radix > 36)))\n return NaN;\n\n let start = 0;\n while (start < text.length && helpers.isWhitespace(text.charCodeAt(start)))\n ++start;\n\n if (start === text.length)\n return NaN;\n\n const numberOffset = 48; // 0\n const numCount = 10;\n const letterOffset = 97; // a\n const letterCount = 26;\n const lowerCaseMask = 0x20;\n\n let sign = 1;\n switch (text.charAt(start)) {\n case \"-\":\n sign = -1;\n // fallthrough\n case \"+\":\n ++start;\n }\n\n if ((!radix || radix == 16)\n && \"0\" === text[start]\n && (\"x\" === text[start + 1] || \"X\" === text[start + 1])) {\n radix = 16;\n start += 2;\n } else if (!radix) {\n radix = 10;\n }\n\n let output = 0;\n let hasDigit = false;\n for (let i = start; i < text.length; ++i) {\n const code = text.charCodeAt(i) | lowerCaseMask;\n let val: number = undefined;\n\n if (code >= numberOffset && code < numberOffset + numCount)\n val = code - numberOffset;\n else if (code >= letterOffset && code < letterOffset + letterCount)\n val = numCount + code - letterOffset;\n\n if (val == undefined || val >= radix) {\n if (!hasDigit) {\n return NaN;\n }\n break;\n }\n hasDigit = true;\n output = output * radix + val;\n }\n\n return sign * output;\n}\n\nnamespace helpers {\n export function arrayFill<T>(O: T[], value: T, start?: number, end?: number) {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill\n // Steps 3-5.\n const len = O.length >>> 0;\n\n // Steps 6-7.\n const relativeStart = start === undefined ? 0 : start >> 0;\n\n // Step 8.\n let k = relativeStart < 0 ?\n Math.max(len + relativeStart, 0) :\n Math.min(relativeStart, len);\n\n // Steps 9-10.\n const relativeEnd = end === undefined ? len : end >> 0;\n\n // Step 11.\n const final = relativeEnd < 0 ?\n Math.max(len + relativeEnd, 0) :\n Math.min(relativeEnd, len);\n\n // Step 12.\n while (k < final) {\n O[k] = value;\n k++;\n }\n\n // Step 13.\n return O;\n }\n\n export function arraySplice<T>(arr: T[], start: number, len: number) {\n if (start < 0) {\n return;\n }\n for (let i = 0; i < len; ++i) {\n arr.removeAt(start)\n }\n }\n\n export function arrayReverse<T>(arr: T[]): void {\n let len = arr.length;\n for (let i = 0; i < len / 2; i++) {\n swap(arr, i, len - i - 1);\n }\n }\n\n export function arrayShift<T>(arr: T[]): T {\n return arr.removeAt(0);\n }\n\n export function arrayJoin<T>(arr: T[], sep?: string): string {\n if (sep === undefined || sep === null) {\n sep = \",\";\n }\n\n let r = \"\";\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n if (i > 0 && sep)\n r += sep;\n r += (arr[i] === undefined || arr[i] === null) ? \"\" : arr[i];\n }\n return r;\n }\n\n /*TODO: Enable this multiple value unshift, after rest is enabled in our compiler.\n export function arrayUnshift<T>(arr: T[], ...values: T[]) : number {\n for(let i = values.length; i > 0; --i) {\n arr.insertAt(0, values[i - 1]);\n }\n return arr.length;\n }\n */\n export function arrayUnshift<T>(arr: T[], value: T): number {\n arr.insertAt(0, value);\n return arr.length;\n }\n\n function swap<T>(arr: T[], i: number, j: number): void {\n let temp: T = arr[i];\n arr[i] = arr[j];\n arr[j] = temp;\n }\n\n function sortHelper<T>(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (arr.length <= 0 || !callbackfn) {\n return arr;\n }\n let len = arr.length;\n // simple selection sort.\n for (let i = 0; i < len - 1; ++i) {\n for (let j = i + 1; j < len; ++j) {\n if (callbackfn(arr[i], arr[j]) > 0) {\n swap(arr, i, j);\n }\n }\n }\n return arr;\n }\n\n export function arraySort<T>(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (!callbackfn && arr.length > 1) {\n callbackfn = (a, b) => {\n // default is sort as if the element were a string, with null < undefined\n const aIsUndef = a === undefined;\n const bIsUndef = b === undefined;\n if (aIsUndef && bIsUndef) return 0;\n else if (aIsUndef) return 1;\n else if (bIsUndef) return -1;\n\n const aIsNull = a === null;\n const bIsNull = b === null;\n if (aIsNull && bIsNull) return 0;\n else if (aIsNull) return 1;\n else if (bIsNull) return -1;\n\n return (a + \"\").compare(b + \"\");\n }\n }\n return sortHelper(arr, callbackfn);\n }\n\n export function arrayMap<T, U>(arr: T[], callbackfn: (value: T, index: number) => U): U[] {\n let res: U[] = []\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n res.push(callbackfn(arr[i], i))\n }\n return res\n }\n\n export function arraySome<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (callbackfn(arr[i], i))\n return true;\n return false;\n }\n\n export function arrayEvery<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (!callbackfn(arr[i], i))\n return false;\n return true;\n }\n\n export function arrayForEach<T>(arr: T[], callbackfn: (value: T, index: number) => void): void {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n callbackfn(arr[i], i);\n }\n }\n\n export function arrayFilter<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): T[] {\n let res: T[] = []\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) res.push(v)\n }\n return res\n }\n\n export function arrayFind<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): T {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) return v;\n }\n return undefined;\n }\n\n export function arrayReduce<T, U>(arr: T[], callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n initialValue = callbackfn(initialValue, arr[i], i)\n }\n return initialValue\n }\n\n export function arrayConcat<T>(arr: T[], otherArr: T[]): T[] {\n let out: T[] = [];\n for (let value of arr) {\n out.push(value);\n }\n for (let value of otherArr) {\n out.push(value);\n }\n return out;\n }\n\n export function arrayPickRandom<T>(arr: T[]): T {\n return arr[Math.randomRange(0, arr.length - 1)];\n }\n\n export function arraySlice<T>(arr: T[], start?: number, end?: number): T[] {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\n const res: T[] = [];\n const len = arr.length;\n\n if (start === undefined)\n start = 0;\n else if (start < 0)\n start = Math.max(len + start, 0);\n\n if (start > len)\n return res;\n\n if (end === undefined)\n end = len;\n else if (end < 0)\n end = len + end;\n\n if (end > len)\n end = len;\n\n for (let i = start; i < end; ++i) {\n res.push(arr[i]);\n }\n return res;\n }\n\n export function stringReplace(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const ind = s.indexOf(toReplace);\n if (ind == -1)\n return s;\n\n const begin = s.slice(0, ind);\n const end = s.slice(ind + toReplace.length);\n\n if (typeof replacer == \"string\" || !replacer) {\n return begin + replacer + end;\n } else {\n return begin + replacer(toReplace) + end;\n }\n }\n\n export function stringReplaceAll(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const split = s.split(toReplace);\n const empty = toReplace.isEmpty();\n\n let output = (empty ? applyReplace(toReplace, replacer) : \"\");\n\n if (split.length) {\n output += split[0];\n }\n\n for (let i = 1; i < split.length; ++i) {\n output += applyReplace(toReplace, replacer) + split[i];\n }\n\n if (!s.isEmpty() && empty) {\n output += applyReplace(toReplace, replacer);\n }\n\n return output;\n\n function applyReplace(r: string, replacer: string | ((sub: string) => string)): string {\n if (typeof replacer == \"string\" || !replacer) {\n return replacer as string;\n } else {\n return replacer(r);\n }\n }\n }\n\n //% shim=String_::substr\n declare function stringSubstrHelper(s: string, start: number, length?: number): string;\n\n export function stringSubstr(s: string, start: number, length?: number): string {\n length = length === undefined ? s.length : length || 0;\n return stringSubstrHelper(s, start, length);\n }\n\n export function stringSlice(s: string, start: number, end?: number): string {\n const len = s.length;\n\n if (start < 0) {\n start = Math.max(len + start, 0);\n }\n\n if (end === undefined) {\n end = len;\n } else if (end === null) {\n end = 0;\n }\n\n if (end < 0) {\n end = len + end;\n }\n\n return stringSubstrHelper(s, start, end - start);\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleUpperCase())\n export function stringToUpperCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (97 <= c && c <= 122) {\n r += s.slice(prev, i) + String.fromCharCode(c - 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleLowerCase())\n export function stringToLowerCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (65 <= c && c <= 90) {\n r += s.slice(prev, i) + String.fromCharCode(c + 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n export function stringSplit(S: string, separator?: string, limit?: number): string[] {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.split\n const A: string[] = [];\n let lim = 0;\n if (limit === undefined)\n lim = (1 << 29) - 1; // spec says 1 << 53, leaving it at 29 for constant folding\n else if (limit < 0)\n lim = 0;\n else\n lim = limit | 0;\n const s = S.length;\n let p = 0;\n const R = separator;\n if (lim == 0)\n return A;\n if (separator === undefined) {\n A[0] = S;\n return A;\n }\n if (s == 0) {\n let z = splitMatch(S, 0, R);\n if (z > -1) return A;\n A[0] = S;\n return A;\n }\n let T: string;\n let q = p;\n while (q != s) {\n let e = splitMatch(S, q, R);\n if (e < 0) q++;\n else {\n if (e == p) q++;\n else {\n T = stringSlice(S, p, q);\n A.push(T);\n if (A.length == lim) return A;\n p = e;\n q = p;\n }\n }\n }\n T = stringSlice(S, p, q);\n A.push(T);\n return A;\n }\n\n function splitMatch(S: string, q: number, R: string): number {\n const r = R.length;\n const s = S.length;\n if (q + r > s) return -1;\n for (let i = 0; i < r; ++i) {\n if (S[q + i] != R[i])\n return -1;\n }\n return q + r;\n }\n\n export function stringTrim(s: string): string {\n let start = 0;\n let end = s.length - 1;\n\n while (start <= end && isWhitespace(s.charCodeAt(start)))\n ++start;\n\n while (end > start && isWhitespace(s.charCodeAt(end)))\n --end;\n return s.slice(start, end + 1);\n }\n\n export function isWhitespace(c: number): boolean {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-white-space\n switch (c) {\n case 0x0009: // character tab\n case 0x000B: // line tab\n case 0x000C: // form feed\n case 0x0020: // space\n case 0x00A0: // no-break space\n case 0xFEFF: // zero width no break space\n case 0x000A: // line feed\n case 0x000D: // carriage return\n case 0x2028: // line separator\n case 0x2029: // paragraph separator\n return true;\n default:\n return false;\n }\n }\n\n export function stringEmpty(S: string): boolean {\n return !S;\n }\n}\n\nnamespace Math {\n export function clamp(min: number, max: number, value: number): number {\n return Math.min(max, Math.max(min, value));\n }\n\n /**\n * Returns the absolute value of a number (the value without regard to whether it is positive or negative).\n * For example, the absolute value of -5 is the same as the absolute value of 5.\n * @param x A numeric expression for which the absolute value is needed.\n */\n //% help=math/abs\n export function abs(x: number): number {\n return x < 0 ? -x : x;\n }\n\n /**\n * Returns the sign of the x, indicating whether x is positive, negative or zero.\n * @param x The numeric expression to test\n */\n export function sign(x: number): number {\n if (x == 0) return 0;\n if (x > 0) return 1;\n return -1;\n }\n\n /**\n * Returns the larger of two supplied numeric expressions.\n */\n //% help=math/max\n export function max(a: number, b: number): number {\n if (a >= b) return a;\n return b;\n }\n\n /**\n * Returns the smaller of two supplied numeric expressions.\n */\n //% help=math/min\n export function min(a: number, b: number): number {\n if (a <= b) return a;\n return b;\n }\n\n /**\n * Rounds ``x`` to a number with the given number of ``digits``\n * @param x the number to round\n * @param digits the number of resulting digits\n */\n //%\n export function roundWithPrecision(x: number, digits: number): number {\n digits = digits | 0;\n // invalid digits input\n if (digits <= 0) return Math.round(x);\n if (x == 0) return 0;\n let r = 0;\n do {\n const d = Math.pow(10, digits);\n r = Math.round(x * d) / d;\n digits++;\n } while (r == 0 && digits < 21);\n return r;\n }\n}\n\n\n//% blockHidden=1\nnamespace __internal {\n /**\n * A shim to render a boolean as a down/up toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleDownUp block=\"%down\"\n //% down.fieldEditor=toggledownup\n //% down.fieldOptions.decompileLiterals=true\n export function __downUp(down: boolean): boolean {\n return down;\n }\n\n /**\n * A shim to render a boolean as a up/down toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleUpDown block=\"%up\"\n //% up.fieldEditor=toggleupdown\n //% up.fieldOptions.decompileLiterals=true\n export function __upDown(up: boolean): boolean {\n return up;\n }\n\n /**\n * A shim to render a boolean as a high/low toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleHighLow block=\"%high\"\n //% high.fieldEditor=togglehighlow\n //% high.fieldOptions.decompileLiterals=true\n export function __highLow(high: boolean): boolean {\n return high;\n }\n\n /**\n * A shim to render a boolean as a on/off toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleOnOff block=\"%on\"\n //% on.fieldEditor=toggleonoff\n //% on.fieldOptions.decompileLiterals=true\n export function __onOff(on: boolean): boolean {\n return on;\n }\n\n /**\n * A shim to render a boolean as a yes/no toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleYesNo block=\"%yes\"\n //% yes.fieldEditor=toggleyesno\n //% yes.fieldOptions.decompileLiterals=true\n export function __yesNo(yes: boolean): boolean {\n return yes;\n }\n\n /**\n * A shim to render a boolean as a win/lose toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleWinLose block=\"%win\"\n //% win.fieldEditor=togglewinlose\n //% win.fieldOptions.decompileLiterals=true\n export function __winLose(win: boolean): boolean {\n return win;\n }\n\n /**\n * Get the color wheel field editor\n * @param color color, eg: #ff0000\n */\n //% blockId=colorNumberPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colornumber\" value.fieldOptions.decompileLiterals=true\n //% value.defl='#ff0000'\n //% value.fieldOptions.colours='[\"#ff0000\",\"#ff8000\",\"#ffff00\",\"#ff9da5\",\"#00ff00\",\"#b09eff\",\"#00ffff\",\"#007fff\",\"#65471f\",\"#0000ff\",\"#7f00ff\",\"#ff0080\",\"#ff00ff\",\"#ffffff\",\"#999999\",\"#000000\"]'\n //% value.fieldOptions.columns=4 value.fieldOptions.className='rgbColorPicker'\n export function __colorNumberPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n export function __colorWheelPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor using HSV values\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelHsvPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n //% value.fieldOptions.channel=hsvfast\n export function __colorWheelHsvPicker(value: number) {\n return value;\n }\n\n /**\n * A speed picker\n * @param speed the speed, eg: 50\n */\n //% blockId=speedPicker block=\"%speed\" shim=TD_ID\n //% speed.fieldEditor=\"speed\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 speed.fieldOptions.decompileLiterals=1\n export function __speedPicker(speed: number): number {\n return speed;\n }\n\n /**\n * A turn ratio picker\n * @param turnratio the turn ratio, eg: 0\n */\n //% blockId=turnRatioPicker block=\"%turnratio\" shim=TD_ID\n //% turnratio.fieldEditor=\"turnratio\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 turnRatio.fieldOptions.decompileLiterals=1\n export function __turnRatioPicker(turnratio: number): number {\n return turnratio;\n }\n\n /**\n * A field editor that displays a protractor\n */\n //% blockId=protractorPicker block=\"%angle\"\n //% shim=TD_ID\n //% angle.fieldEditor=protractor\n //% angle.fieldOptions.decompileLiterals=1\n //% colorSecondary=\"#FFFFFF\"\n //% blockHidden=1\n export function __protractor(angle: number) {\n return angle;\n }\n\n /**\n * Get the time field editor\n * @param ms time duration in milliseconds, eg: 500, 1000\n */\n //% blockId=timePicker block=\"%ms\"\n //% blockHidden=true shim=TD_ID\n //% colorSecondary=\"#FFFFFF\"\n //% ms.fieldEditor=\"numberdropdown\" ms.fieldOptions.decompileLiterals=true\n //% ms.fieldOptions.data='[[\"100 ms\", 100], [\"200 ms\", 200], [\"500 ms\", 500], [\"1 second\", 1000], [\"2 seconds\", 2000], [\"5 seconds\", 5000]]'\n export function __timePicker(ms: number): number {\n return ms;\n }\n}\n",
|
|
2782
|
+
"pxt-helpers.ts": "type Action = () => void;\n\n/**\n * Constant representing Not-A-Number.\n */\nconst NaN = 0 / 0\n\n/**\n * Constant representing positive infinity.\n */\nconst Infinity = 1 / 0\n\nfunction isNaN(x: number) {\n x = +x // convert to number\n return x !== x\n}\n\nnamespace Number {\n /**\n * Check if a given value is of type Number and it is a NaN.\n */\n export function isNaN(x: any): boolean {\n return typeof x == \"number\" && x !== x\n }\n}\n\n/**\n * A dictionary from string key to string values\n */\ninterface StringMap {\n [index: string]: string;\n}\n\n/**\n * Convert a string to an integer.\n * @param text A string to convert into an integral number. eg: \"123\"\n * @param radix optional A value between 2 and 36 that specifies the base of the number in text.\n * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\n * All other strings are considered decimal.\n */\n//% help=text/parse-int\n//% blockId=\"string_parseint\" block=\"parse to integer %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\n//% blockHidden=1\nfunction parseInt(text: string, radix?: number): number {\n // roughly based on https://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.2\n // with some consideration for avoiding unnecessary slices where easy\n if (!text || (radix != null && (radix < 2 || radix > 36)))\n return NaN;\n\n let start = 0;\n while (start < text.length && helpers.isWhitespace(text.charCodeAt(start)))\n ++start;\n\n if (start === text.length)\n return NaN;\n\n const numberOffset = 48; // 0\n const numCount = 10;\n const letterOffset = 97; // a\n const letterCount = 26;\n const lowerCaseMask = 0x20;\n\n let sign = 1;\n switch (text.charAt(start)) {\n case \"-\":\n sign = -1;\n // fallthrough\n case \"+\":\n ++start;\n }\n\n if ((!radix || radix == 16)\n && \"0\" === text[start]\n && (\"x\" === text[start + 1] || \"X\" === text[start + 1])) {\n radix = 16;\n start += 2;\n } else if (!radix) {\n radix = 10;\n }\n\n let output = 0;\n let hasDigit = false;\n for (let i = start; i < text.length; ++i) {\n const code = text.charCodeAt(i) | lowerCaseMask;\n let val: number = undefined;\n\n if (code >= numberOffset && code < numberOffset + numCount)\n val = code - numberOffset;\n else if (code >= letterOffset && code < letterOffset + letterCount)\n val = numCount + code - letterOffset;\n\n if (val == undefined || val >= radix) {\n if (!hasDigit) {\n return NaN;\n }\n break;\n }\n hasDigit = true;\n output = output * radix + val;\n }\n\n return sign * output;\n}\n\nnamespace helpers {\n export function arrayFill<T>(O: T[], value: T, start?: number, end?: number) {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill\n // Steps 3-5.\n const len = O.length >>> 0;\n\n // Steps 6-7.\n const relativeStart = start === undefined ? 0 : start >> 0;\n\n // Step 8.\n let k = relativeStart < 0 ?\n Math.max(len + relativeStart, 0) :\n Math.min(relativeStart, len);\n\n // Steps 9-10.\n const relativeEnd = end === undefined ? len : end >> 0;\n\n // Step 11.\n const final = relativeEnd < 0 ?\n Math.max(len + relativeEnd, 0) :\n Math.min(relativeEnd, len);\n\n // Step 12.\n while (k < final) {\n O[k] = value;\n k++;\n }\n\n // Step 13.\n return O;\n }\n\n export function arraySplice<T>(arr: T[], start: number, len: number) {\n if (start < 0) {\n return;\n }\n for (let i = 0; i < len; ++i) {\n arr.removeAt(start)\n }\n }\n\n export function arrayReverse<T>(arr: T[]): void {\n let len = arr.length;\n for (let i = 0; i < len / 2; i++) {\n swap(arr, i, len - i - 1);\n }\n }\n\n export function arrayShift<T>(arr: T[]): T {\n return arr.removeAt(0);\n }\n\n export function arrayJoin<T>(arr: T[], sep?: string): string {\n if (sep === undefined || sep === null) {\n sep = \",\";\n }\n\n let r = \"\";\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n if (i > 0 && sep)\n r += sep;\n r += (arr[i] === undefined || arr[i] === null) ? \"\" : arr[i];\n }\n return r;\n }\n\n /*TODO: Enable this multiple value unshift, after rest is enabled in our compiler.\n export function arrayUnshift<T>(arr: T[], ...values: T[]) : number {\n for(let i = values.length; i > 0; --i) {\n arr.insertAt(0, values[i - 1]);\n }\n return arr.length;\n }\n */\n export function arrayUnshift<T>(arr: T[], value: T): number {\n arr.insertAt(0, value);\n return arr.length;\n }\n\n function swap<T>(arr: T[], i: number, j: number): void {\n let temp: T = arr[i];\n arr[i] = arr[j];\n arr[j] = temp;\n }\n\n function sortHelper<T>(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (arr.length <= 0 || !callbackfn) {\n return arr;\n }\n let len = arr.length;\n // simple selection sort.\n for (let i = 0; i < len - 1; ++i) {\n for (let j = i + 1; j < len; ++j) {\n if (callbackfn(arr[i], arr[j]) > 0) {\n swap(arr, i, j);\n }\n }\n }\n return arr;\n }\n\n export function arraySort<T>(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (!callbackfn && arr.length > 1) {\n callbackfn = (a, b) => {\n // default is sort as if the element were a string, with null < undefined\n const aIsUndef = a === undefined;\n const bIsUndef = b === undefined;\n if (aIsUndef && bIsUndef) return 0;\n else if (aIsUndef) return 1;\n else if (bIsUndef) return -1;\n\n const aIsNull = a === null;\n const bIsNull = b === null;\n if (aIsNull && bIsNull) return 0;\n else if (aIsNull) return 1;\n else if (bIsNull) return -1;\n\n return (a + \"\").compare(b + \"\");\n }\n }\n return sortHelper(arr, callbackfn);\n }\n\n export function arrayMap<T, U>(arr: T[], callbackfn: (value: T, index: number) => U): U[] {\n let res: U[] = []\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n res.push(callbackfn(arr[i], i))\n }\n return res\n }\n\n export function arraySome<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (callbackfn(arr[i], i))\n return true;\n return false;\n }\n\n export function arrayEvery<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i)\n if (!callbackfn(arr[i], i))\n return false;\n return true;\n }\n\n export function arrayForEach<T>(arr: T[], callbackfn: (value: T, index: number) => void): void {\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n callbackfn(arr[i], i);\n }\n }\n\n export function arrayFilter<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): T[] {\n let res: T[] = []\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) res.push(v)\n }\n return res\n }\n\n export function arrayFind<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): T {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) return v;\n }\n return undefined;\n }\n\n export function arrayReduce<T, U>(arr: T[], callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n initialValue = callbackfn(initialValue, arr[i], i)\n }\n return initialValue\n }\n\n export function arrayConcat<T>(arr: T[], otherArr: T[]): T[] {\n let out: T[] = [];\n for (let value of arr) {\n out.push(value);\n }\n for (let value of otherArr) {\n out.push(value);\n }\n return out;\n }\n\n export function arrayPickRandom<T>(arr: T[]): T {\n return arr[Math.randomRange(0, arr.length - 1)];\n }\n\n export function arraySlice<T>(arr: T[], start?: number, end?: number): T[] {\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\n const res: T[] = [];\n const len = arr.length;\n\n if (start === undefined)\n start = 0;\n else if (start < 0)\n start = Math.max(len + start, 0);\n\n if (start > len)\n return res;\n\n if (end === undefined)\n end = len;\n else if (end < 0)\n end = len + end;\n\n if (end > len)\n end = len;\n\n for (let i = start; i < end; ++i) {\n res.push(arr[i]);\n }\n return res;\n }\n\n export function stringReplace(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const ind = s.indexOf(toReplace);\n if (ind == -1)\n return s;\n\n const begin = s.slice(0, ind);\n const end = s.slice(ind + toReplace.length);\n\n if (typeof replacer == \"string\" || !replacer) {\n return begin + replacer + end;\n } else {\n return begin + replacer(toReplace) + end;\n }\n }\n\n export function stringReplaceAll(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n toReplace = toReplace + \"\";\n const split = s.split(toReplace);\n const empty = toReplace.isEmpty();\n\n let output = (empty ? applyReplace(toReplace, replacer) : \"\");\n\n if (split.length) {\n output += split[0];\n }\n\n for (let i = 1; i < split.length; ++i) {\n output += applyReplace(toReplace, replacer) + split[i];\n }\n\n if (!s.isEmpty() && empty) {\n output += applyReplace(toReplace, replacer);\n }\n\n return output;\n\n function applyReplace(r: string, replacer: string | ((sub: string) => string)): string {\n if (typeof replacer == \"string\" || !replacer) {\n return replacer as string;\n } else {\n return replacer(r);\n }\n }\n }\n\n //% shim=String_::substr\n declare function stringSubstrHelper(s: string, start: number, length?: number): string;\n\n export function stringSubstr(s: string, start: number, length?: number): string {\n length = length === undefined ? s.length : length || 0;\n return stringSubstrHelper(s, start, length);\n }\n\n export function stringSlice(s: string, start: number, end?: number): string {\n const len = s.length;\n\n if (start < 0) {\n start = Math.max(len + start, 0);\n }\n\n if (end === undefined) {\n end = len;\n } else if (end === null) {\n end = 0;\n }\n\n if (end < 0) {\n end = len + end;\n }\n\n return stringSubstrHelper(s, start, end - start);\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleUpperCase())\n export function stringToUpperCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (97 <= c && c <= 122) {\n r += s.slice(prev, i) + String.fromCharCode(c - 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n // also note this doesn't handle unicode, but neither does JS (there's toLocaleLowerCase())\n export function stringToLowerCase(s: string): string {\n let r = \"\"\n let prev = 0\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i)\n if (65 <= c && c <= 90) {\n r += s.slice(prev, i) + String.fromCharCode(c + 32)\n prev = i + 1\n }\n }\n r += s.slice(prev)\n return r\n }\n\n export function stringSplit(S: string, separator?: string, limit?: number): string[] {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.split\n const A: string[] = [];\n let lim = 0;\n if (limit === undefined)\n lim = (1 << 29) - 1; // spec says 1 << 53, leaving it at 29 for constant folding\n else if (limit < 0)\n lim = 0;\n else\n lim = limit | 0;\n const s = S.length;\n let p = 0;\n const R = separator;\n if (lim == 0)\n return A;\n if (separator === undefined) {\n A[0] = S;\n return A;\n }\n if (s == 0) {\n let z = splitMatch(S, 0, R);\n if (z > -1) return A;\n A[0] = S;\n return A;\n }\n let T: string;\n let q = p;\n while (q != s) {\n let e = splitMatch(S, q, R);\n if (e < 0) q++;\n else {\n if (e == p) q++;\n else {\n T = stringSlice(S, p, q);\n A.push(T);\n if (A.length == lim) return A;\n p = e;\n q = p;\n }\n }\n }\n T = stringSlice(S, p, q);\n A.push(T);\n return A;\n }\n\n function splitMatch(S: string, q: number, R: string): number {\n const r = R.length;\n const s = S.length;\n if (q + r > s) return -1;\n for (let i = 0; i < r; ++i) {\n if (S[q + i] != R[i])\n return -1;\n }\n return q + r;\n }\n\n export function stringTrim(s: string): string {\n let start = 0;\n let end = s.length - 1;\n\n while (start <= end && isWhitespace(s.charCodeAt(start)))\n ++start;\n\n while (end > start && isWhitespace(s.charCodeAt(end)))\n --end;\n return s.slice(start, end + 1);\n }\n\n export function isWhitespace(c: number): boolean {\n // https://www.ecma-international.org/ecma-262/6.0/#sec-white-space\n switch (c) {\n case 0x0009: // character tab\n case 0x000B: // line tab\n case 0x000C: // form feed\n case 0x0020: // space\n case 0x00A0: // no-break space\n case 0xFEFF: // zero width no break space\n case 0x000A: // line feed\n case 0x000D: // carriage return\n case 0x2028: // line separator\n case 0x2029: // paragraph separator\n return true;\n default:\n return false;\n }\n }\n\n export function stringEmpty(S: string): boolean {\n return !S;\n }\n}\n\nnamespace Math {\n export function clamp(min: number, max: number, value: number): number {\n return Math.min(max, Math.max(min, value));\n }\n\n /**\n * Returns the absolute value of a number (the value without regard to whether it is positive or negative).\n * For example, the absolute value of -5 is the same as the absolute value of 5.\n * @param x A numeric expression for which the absolute value is needed.\n */\n //% help=math/abs\n export function abs(x: number): number {\n return x < 0 ? -x : x;\n }\n\n /**\n * Returns the sign of the x, indicating whether x is positive, negative or zero.\n * @param x The numeric expression to test\n */\n export function sign(x: number): number {\n if (x == 0) return 0;\n if (x > 0) return 1;\n return -1;\n }\n\n /**\n * Returns the larger of two supplied numeric expressions.\n */\n //% help=math/max\n export function max(a: number, b: number): number {\n if (a >= b) return a;\n return b;\n }\n\n /**\n * Returns the smaller of two supplied numeric expressions.\n */\n //% help=math/min\n export function min(a: number, b: number): number {\n if (a <= b) return a;\n return b;\n }\n\n /**\n * Rounds ``x`` to a number with the given number of ``digits``\n * @param x the number to round\n * @param digits the number of resulting digits\n */\n //%\n export function roundWithPrecision(x: number, digits: number): number {\n digits = digits | 0;\n // invalid digits input\n if (digits <= 0) return Math.round(x);\n if (x == 0) return 0;\n let r = 0;\n do {\n const d = Math.pow(10, digits);\n r = Math.round(x * d) / d;\n digits++;\n } while (r == 0 && digits < 21);\n return r;\n }\n}\n\n\n//% blockHidden=1\nnamespace __internal {\n /**\n * A shim to render a boolean as a down/up toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleDownUp block=\"%down\"\n //% down.fieldEditor=toggledownup\n //% down.fieldOptions.decompileLiterals=true\n export function __downUp(down: boolean): boolean {\n return down;\n }\n\n /**\n * A shim to render a boolean as a up/down toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleUpDown block=\"%up\"\n //% up.fieldEditor=toggleupdown\n //% up.fieldOptions.decompileLiterals=true\n export function __upDown(up: boolean): boolean {\n return up;\n }\n\n /**\n * A shim to render a boolean as a high/low toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleHighLow block=\"%high\"\n //% high.fieldEditor=togglehighlow\n //% high.fieldOptions.decompileLiterals=true\n export function __highLow(high: boolean): boolean {\n return high;\n }\n\n /**\n * A shim to render a boolean as a on/off toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleOnOff block=\"%on\"\n //% on.fieldEditor=toggleonoff\n //% on.fieldOptions.decompileLiterals=true\n export function __onOff(on: boolean): boolean {\n return on;\n }\n\n /**\n * A shim to render a boolean as a yes/no toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleYesNo block=\"%yes\"\n //% yes.fieldEditor=toggleyesno\n //% yes.fieldOptions.decompileLiterals=true\n export function __yesNo(yes: boolean): boolean {\n return yes;\n }\n\n /**\n * A shim to render a boolean as a win/lose toggle\n */\n //% shim=TD_ID blockHidden=1\n //% blockId=toggleWinLose block=\"%win\"\n //% win.fieldEditor=togglewinlose\n //% win.fieldOptions.decompileLiterals=true\n export function __winLose(win: boolean): boolean {\n return win;\n }\n\n /**\n * Get the color wheel field editor\n * @param color color\n */\n //% blockId=colorNumberPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colornumber\" value.fieldOptions.decompileLiterals=true\n //% value.defl='0xff0000'\n //% value.fieldOptions.colours='[\"#ff0000\",\"#ff8000\",\"#ffff00\",\"#ff9da5\",\"#00ff00\",\"#b09eff\",\"#00ffff\",\"#007fff\",\"#65471f\",\"#0000ff\",\"#7f00ff\",\"#ff0080\",\"#ff00ff\",\"#ffffff\",\"#999999\",\"#000000\"]'\n //% value.fieldOptions.columns=4 value.fieldOptions.className='rgbColorPicker'\n export function __colorNumberPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n export function __colorWheelPicker(value: number) {\n return value;\n }\n\n /**\n * Get the color wheel field editor using HSV values\n * @param value value between 0 to 255 to get a color value, eg: 10\n */\n //% blockId=colorWheelHsvPicker block=\"%value\"\n //% blockHidden=true\n //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n //% value.fieldOptions.sliderWidth='200'\n //% value.fieldOptions.min=0 value.fieldOptions.max=255\n //% value.fieldOptions.channel=hsvfast\n export function __colorWheelHsvPicker(value: number) {\n return value;\n }\n\n /**\n * A speed picker\n * @param speed the speed, eg: 50\n */\n //% blockId=speedPicker block=\"%speed\" shim=TD_ID\n //% speed.fieldEditor=\"speed\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 speed.fieldOptions.decompileLiterals=1\n export function __speedPicker(speed: number): number {\n return speed;\n }\n\n /**\n * A turn ratio picker\n * @param turnratio the turn ratio, eg: 0\n */\n //% blockId=turnRatioPicker block=\"%turnratio\" shim=TD_ID\n //% turnratio.fieldEditor=\"turnratio\" colorSecondary=\"#FFFFFF\"\n //% weight=0 blockHidden=1 turnRatio.fieldOptions.decompileLiterals=1\n export function __turnRatioPicker(turnratio: number): number {\n return turnratio;\n }\n\n /**\n * A field editor that displays a protractor\n */\n //% blockId=protractorPicker block=\"%angle\"\n //% shim=TD_ID\n //% angle.fieldEditor=protractor\n //% angle.fieldOptions.decompileLiterals=1\n //% colorSecondary=\"#FFFFFF\"\n //% blockHidden=1\n export function __protractor(angle: number) {\n return angle;\n }\n\n /**\n * Get the time field editor\n * @param ms time duration in milliseconds, eg: 500, 1000\n */\n //% blockId=timePicker block=\"%ms\"\n //% blockHidden=true shim=TD_ID\n //% colorSecondary=\"#FFFFFF\"\n //% ms.fieldEditor=\"numberdropdown\" ms.fieldOptions.decompileLiterals=true\n //% ms.fieldOptions.data='[[\"100 ms\", 100], [\"200 ms\", 200], [\"500 ms\", 500], [\"1 second\", 1000], [\"2 seconds\", 2000], [\"5 seconds\", 5000]]'\n export function __timePicker(ms: number): number {\n return ms;\n }\n}\n",
|
|
2769
2783
|
"pxt-python-helpers.ts": "namespace _py {\n export const ATTRIBUTE_ERROR: string = \"AttributeError\";\n export const INDEX_ERROR: string = \"IndexError\";\n export const VALUE_ERROR: string = \"ValueError\";\n export const TYPE_ERROR: string = \"TypeError\";\n\n export function py_string_capitalize(str: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_casefold(str: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_center(str: string, width: number, fillChar?: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_count(str: string, sub: string, start?: number, end?: number): number {\n nullCheck(str);\n return 0;\n }\n\n export function py_string_endswith(str: string, suffix: string, start?: number, end?: number): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_find(str: string, sub: string, start?: number, end?: number): number {\n nullCheck(str);\n return 0;\n }\n\n export function py_string_index(str: string, sub: string, start?: number, end?: number): number {\n nullCheck(str);\n return 0;\n }\n\n export function py_string_isalnum(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isalpha(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isascii(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isdigit(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isnumeric(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isspace(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isdecimal(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isidentifier(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_islower(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isprintable(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_istitle(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_isupper(str: string): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_join(str: string, iterable: any[]): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_ljust(str: string, width: number, fillChar?: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_lower(str: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_rfind(str: string, sub: string, start?: number, end?: number): number {\n nullCheck(str);\n return 0;\n }\n\n export function py_string_rindex(str: string, sub: string, start?: number, end?: number): number {\n nullCheck(str);\n return 0;\n }\n\n export function py_string_rjust(str: string, width: number, fillChar?: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_rsplit(str: string, sep?: string, maxsplit?: number): string[] {\n nullCheck(str);\n\n if (sep === \"\") {\n throw VALUE_ERROR;\n }\n\n if (maxsplit === 0) return [str]\n if (!maxsplit || maxsplit < 0) maxsplit = str.length;\n\n const out: string[] = [];\n\n let currentChar: string;\n let splitEnd: number;\n let previousSplit = str.length;\n\n if (!sep) {\n for (let i = str.length - 1; i >= 0; i--) {\n currentChar = str.charAt(i);\n if (isWhitespace(currentChar)) {\n if (splitEnd === undefined) splitEnd = i;\n }\n else if (splitEnd !== undefined) {\n if (previousSplit !== splitEnd + 1) out.push(str.substr(splitEnd + 1, previousSplit - (splitEnd + 1)));\n previousSplit = i + 1;\n splitEnd = undefined;\n\n }\n\n if (out.length === maxsplit) break;\n }\n\n if (out.length < maxsplit + 1) {\n if (splitEnd !== undefined) {\n if (previousSplit !== splitEnd + 1)\n out.push(str.substr(splitEnd + 1, previousSplit - (splitEnd + 1)));\n }\n else {\n out.push(str.substr(0, previousSplit))\n }\n }\n }\n else {\n let separatorIndex = 0;\n for (let i = str.length; i >= 0; i--) {\n currentChar = str.charAt(i);\n if (currentChar === sep.charAt(sep.length - separatorIndex - 1)) {\n separatorIndex++;\n if (splitEnd === undefined) splitEnd = i;\n }\n else {\n separatorIndex = 0;\n splitEnd = undefined;\n }\n\n if (separatorIndex === sep.length) {\n out.push(str.substr(splitEnd + 1, previousSplit - (splitEnd + 1)));\n previousSplit = i;\n separatorIndex = 0;\n splitEnd = undefined;\n }\n\n if (out.length === maxsplit) break;\n }\n\n if (out.length < maxsplit + 1) {\n out.push(str.substr(0, previousSplit))\n }\n }\n\n out.reverse();\n return out;\n }\n\n export function py_string_split(str: string, sep?: string, maxsplit?: number): string[] {\n nullCheck(str);\n\n if (sep === \"\") {\n throw VALUE_ERROR;\n }\n\n if (maxsplit === 0) return [str]\n if (!maxsplit || maxsplit < 0) maxsplit = str.length;\n\n const out: string[] = [];\n\n let currentChar: string;\n let splitStart: number;\n let previousSplit = 0;\n\n if (!sep) {\n for (let i = 0; i < str.length; i++) {\n currentChar = str.charAt(i);\n if (isWhitespace(currentChar)) {\n if (splitStart === undefined) splitStart = i;\n }\n else if (splitStart !== undefined) {\n if (previousSplit !== splitStart) out.push(str.substr(previousSplit, splitStart - previousSplit));\n previousSplit = i;\n splitStart = undefined;\n\n }\n\n if (out.length === maxsplit) break;\n }\n\n if (out.length < maxsplit + 1) {\n if (splitStart !== undefined) {\n if (previousSplit !== splitStart)\n out.push(str.substr(previousSplit, splitStart - previousSplit));\n }\n else {\n out.push(str.substr(previousSplit))\n }\n }\n }\n else {\n let separatorIndex = 0;\n for (let i = 0; i < str.length; i++) {\n currentChar = str.charAt(i);\n if (currentChar === sep.charAt(separatorIndex)) {\n separatorIndex++;\n if (splitStart === undefined) splitStart = i;\n }\n else {\n separatorIndex = 0;\n splitStart = undefined;\n }\n\n if (separatorIndex === sep.length) {\n out.push(str.substr(previousSplit, splitStart - previousSplit));\n previousSplit = i + 1;\n separatorIndex = 0;\n splitStart = undefined;\n }\n\n if (out.length === maxsplit) break;\n }\n\n if (out.length < maxsplit + 1) {\n out.push(str.substr(previousSplit))\n }\n }\n\n return out;\n }\n\n\n function isWhitespace(char: string) {\n // TODO Figure out everything python considers whitespace.\n // the \\s character class in JS regexes also includes these: \\u00a0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff\n return char === \" \" || char === \"\\t\" || char === \"\\n\" || char === \"\\v\" || char === \"\\r\" || char === \"\\f\";\n }\n\n export function py_string_splitlines(str: string, keepends?: boolean): string[] {\n nullCheck(str);\n return [];\n }\n\n export function py_string_startswith(str: string, prefix: string, start?: number, end?: number): boolean {\n nullCheck(str);\n return false;\n }\n\n export function py_string_rstrip(str: string, chars?: string): string {\n nullCheck(str);\n\n for (let i = str.length - 1; i >= 0; i--) {\n if (chars != undefined) {\n if (chars.indexOf(str.charAt(i)) === -1) {\n return str.substr(0, i + 1);\n }\n }\n else if (!isWhitespace(str.charAt(i))) {\n return str.substr(0, i + 1);\n }\n }\n\n return \"\";\n }\n\n export function py_string_lstrip(str: string, chars?: string): string {\n nullCheck(str);\n\n for (let i = 0; i < str.length; i++) {\n if (chars != undefined) {\n if (chars.indexOf(str.charAt(i)) === -1) {\n return str.substr(i);\n }\n }\n else if (!isWhitespace(str.charAt(i))) {\n return str.substr(i);\n }\n }\n\n return \"\";\n }\n\n export function py_string_strip(str: string, chars?: string): string {\n return py_string_rstrip(py_string_lstrip(str, chars), chars);\n }\n\n export function py_string_swapcase(str: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_title(str: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_upper(str: string): string {\n nullCheck(str);\n return str;\n }\n\n export function py_string_zfill(str: string, width: number): string {\n nullCheck(str);\n return str;\n }\n\n export function py_array_pop(arr: any[], index?: number): any {\n nullCheck(arr);\n\n if (arr.length === 0) {\n throw INDEX_ERROR;\n }\n\n if (index == undefined) {\n return arr.pop();\n }\n else if (index > 0 && index < arr.length) {\n return arr.removeAt(index | 0);\n }\n\n throw INDEX_ERROR;\n }\n\n export function py_array_clear(arr: any[]): void {\n nullCheck(arr);\n\n arr.length = 0;\n }\n\n export function py_array_index(arr: any[], value: any, start?: number, end?: number): number {\n nullCheck(arr);\n\n start = fixIndex(arr, start);\n end = fixIndex(arr, end);\n\n if (start == null) {\n start = 0;\n }\n\n if (end == null) {\n // end is exclusive\n end = arr.length;\n }\n\n for (let i = start; i < end; i++) {\n if (arr[i] === value) {\n return i;\n }\n }\n\n throw VALUE_ERROR;\n }\n\n export function py_array_count(arr: any[], value: any): number {\n nullCheck(arr);\n\n let count = 0;\n\n for (let i = 0; i < arr.length; i++) {\n if (arr[i] === value) count++;\n }\n\n return count;\n }\n\n function nullCheck(arg: any) {\n if (arg == null) {\n throw ATTRIBUTE_ERROR;\n }\n }\n\n function fixIndex(arr: any[], index: number) {\n if (index != null && arr.length) {\n index = index | 0;\n while (index < 0) index += arr.length;\n }\n return index;\n }\n\n /**\n * Returns a sequence of numbers up to but not including the limit\n * @param first The value to end the sequence before. This value will not show up in the result.\n * If more than one argument is passed, this argument is instead used for the first value in the range\n * @param stop The value to end the sequence before. This value will not show up in the result\n * @param step The value to increase or decrease by for each step in the range. Must be a nonzero integer\n */\n export function range(first: number, stop?: number, step?: number) {\n if (step === undefined) step = 1\n // step must be a nonzero integer (can be negative)\n if (step === 0 || (step | 0) !== step) {\n throw VALUE_ERROR;\n }\n\n // If only one argument is given, then start is actually stop\n if (stop === undefined) {\n stop = first;\n first = 0;\n }\n\n const res: number[] = [];\n if (step > 0 && first >= stop || step < 0 && first <= stop) return res;\n\n let index = first;\n\n while (step < 0 ? index > stop : index < stop) {\n res.push(index);\n index += step\n }\n\n return res;\n }\n\n function sliceRange(valueLength: number, start?: number, stop?: number, step?: number) {\n if (step == null) step = 1\n\n // step must be a nonzero integer (can be negative)\n if (step === 0 || (step | 0) !== step) {\n throw _py.VALUE_ERROR;\n }\n\n if (step < 0) {\n if (start == null) {\n start = valueLength - 1;\n }\n if (stop == null) {\n stop = -1;\n }\n }\n else {\n if (start == null) {\n start = 0;\n }\n if (stop == null) {\n stop = valueLength;\n }\n }\n\n return range(start, stop, step)\n }\n\n /**\n * Returns a section of an array according to python's extended slice syntax\n */\n export function slice<U>(value: U[], start?: number, stop?: number, step?: number): U[] {\n if (value == null) {\n throw TYPE_ERROR;\n }\n return sliceRange(value.length, start, stop, step).map(index => value[index]);\n }\n\n /**\n * Returns a section of a string according to python's extended slice syntax\n */\n export function stringSlice(value: string, start?: number, stop?: number, step?: number): string {\n if (value == null) {\n throw TYPE_ERROR;\n }\n return sliceRange(value.length, start, stop, step).map(index => value.charAt(index)).join(\"\");\n }\n}",
|
|
2770
2784
|
"pxt-python.d.ts": "/// <reference no-default-lib=\"true\"/>\n\ndeclare namespace _py {\n interface Array {\n //% py2tsOverride=\"push($0)\"\n append(value: any): void;\n\n //% py2tsOverride=\"concat($0)\"\n extend(other: Array): void;\n\n //% py2tsOverride=\"insertAt($0, $1)\"\n insert(index: number, value: any): void;\n\n //% py2tsOverride=\"removeElement($0)\"\n remove(value: any): void;\n\n //% py2tsOverride=\"sort($0?)\"\n sort(sorter?: (a: any, b: any) => number): void;\n\n //% py2tsOverride=\"reverse()\"\n reverse(): void;\n\n //% py2tsOverride=\"slice()\"\n copy(): void;\n\n //% pyHelper=\"py_array_pop\"\n pop(index?: number): any;\n\n //% pyHelper=\"py_array_clear\"\n clear(): void;\n\n //% pyHelper=\"py_array_index\"\n index(value: any, start?: number, end?: number): number;\n\n //% pyHelper=\"py_array_count\"\n count(value: any): number;\n }\n\n interface String {\n //% pyHelper=\"py_string_capitalize\"\n capitalize(): string;\n\n //% pyHelper=\"py_string_casefold\"\n casefold(): string;\n\n //% pyHelper=\"py_string_center\"\n center(width: number, fillChar?: string): string;\n\n //% pyHelper=\"py_string_count\"\n count(sub: string, start?: number, end?: number): number;\n\n //% pyHelper=\"py_string_endswith\"\n endswith(suffix: string, start?: number, end?: number): boolean;\n\n //% pyHelper=\"py_string_find\"\n find(sub: string, start?: number, end?: number): number;\n\n //% pyHelper=\"py_string_index\"\n index(sub: string, start?: number, end?: number): number;\n\n //% pyHelper=\"py_string_isalnum\"\n isalnum(): boolean;\n\n //% pyHelper=\"py_string_isalpha\"\n isalpha(): boolean;\n\n //% pyHelper=\"py_string_isascii\"\n isascii(): boolean;\n\n //% pyHelper=\"py_string_isdigit\"\n isdigit(): boolean;\n\n //% pyHelper=\"py_string_isnumeric\"\n isnumeric(): boolean;\n\n //% pyHelper=\"py_string_isspace\"\n isspace(): boolean;\n\n //% pyHelper=\"py_string_isdecimal\"\n isdecimal(): boolean;\n\n //% pyHelper=\"py_string_isidentifier\"\n isidentifier(): boolean;\n\n //% pyHelper=\"py_string_islower\"\n islower(): boolean;\n\n //% pyHelper=\"py_string_isprintable\"\n isprintable(): boolean;\n\n //% pyHelper=\"py_string_istitle\"\n istitle(): boolean;\n\n //% pyHelper=\"py_string_isupper\"\n isupper(): boolean;\n\n //% pyHelper=\"py_string_join\"\n join(iterable: any[]): string;\n\n //% pyHelper=\"py_string_ljust\"\n ljust(width: number, fillChar?: string): string;\n\n //% pyHelper=\"py_string_lower\"\n lower(): string;\n\n //% pyHelper=\"py_string_lstrip\"\n lstrip(chars?: string): string;\n\n //% py2tsOverride=\"replace($0, $1)\"\n replace(oldString: string, newString: string): string;\n\n //% pyHelper=\"py_string_rfind\"\n rfind(sub: string, start?: number, end?: number): number;\n\n //% pyHelper=\"py_string_rindex\"\n rindex(sub: string, start?: number, end?: number): number;\n\n //% pyHelper=\"py_string_rjust\"\n rjust(width: number, fillChar?: string): string;\n\n //% pyHelper=\"py_string_rsplit\"\n rsplit(sep?: string, maxSplit?: number): string[];\n\n //% pyHelper=\"py_string_rstrip\"\n rstrip(chars?: string): string;\n\n //% pyHelper=\"py_string_split\"\n split(sep?: string, maxsplit?: number): string[];\n\n //% pyHelper=\"py_string_splitlines\"\n splitlines(keepends?: boolean): string[];\n\n //% pyHelper=\"py_string_startswith\"\n startswith(prefix: string, start?: number, end?: number): boolean;\n\n //% pyHelper=\"py_string_strip\"\n strip(chars?: string): string;\n\n //% pyHelper=\"py_string_swapcase\"\n swapcase(): string;\n\n //% pyHelper=\"py_string_title\"\n title(): string;\n\n //% pyHelper=\"py_string_upper\"\n upper(): string;\n\n //% pyHelper=\"py_string_zfill\"\n zfill(width: number): string;\n }\n\n interface Dict {\n clear(): void;\n copy(): void;\n get(key: string, defaultValue?: any): any;\n // items(): [string, any][];\n keys(): string[];\n pop(key: string, defaultValue?: any): any;\n // popitem(): [string, any];\n setdefault(key: string, defaultValue?: any): any;\n update(other: Dict): void;\n values(): any[];\n }\n\n interface Set {\n isdisjoint(other: Set): boolean;\n issubset(other: Set): boolean;\n issuperset(other: Set): boolean;\n union(other: Set): Set;\n intersection(other: Set): Set;\n difference(other: Set): Set;\n symmetric_difference(other: Set): Set;\n copy(): Set;\n update(other: Set): void;\n intersection_update(other: Set): void;\n difference_update(other: Set): void;\n symmetric_difference_update(other: Set): void;\n add(elem: any): void;\n remove(elem: any): void;\n discard(elem: any): void;\n pop(): any;\n clear(): void;\n }\n}",
|
|
2771
2785
|
"pxt.cpp": "#include \"pxtbase.h\"\n\nusing namespace std;\n\nnamespace pxt {\n\nAction mkAction(int totallen, RefAction *act) {\n check(getVTable(act)->classNo == BuiltInType::RefAction, PANIC_INVALID_BINARY_HEADER, 1);\n#ifdef PXT_VM\n check(act->initialLen <= totallen, PANIC_INVALID_BINARY_HEADER, 13);\n#endif\n\n if (totallen == 0) {\n return (TValue)act; // no closure needed\n }\n\n void *ptr = gcAllocate(sizeof(RefAction) + totallen * sizeof(void *));\n RefAction *r = new (ptr) RefAction();\n r->len = totallen;\n#ifdef PXT_VM\n r->numArgs = act->numArgs;\n r->initialLen = act->initialLen;\n r->flags = 0;\n#endif\n r->func = act->func;\n memset(r->fields, 0, r->len * sizeof(void *));\n\n MEMDBG(\"mkAction: start=%p => %p\", act, r);\n\n return (Action)r;\n}\n\nRefRecord *mkClassInstance(VTable *vtable) {\n intcheck(vtable->methods[0] == &RefRecord_destroy, PANIC_SIZE, 3);\n // intcheck(vtable->methods[1] == &RefRecord_print, PANIC_SIZE, 4);\n\n void *ptr = gcAllocate(vtable->numbytes);\n RefRecord *r = new (ptr) RefRecord(vtable);\n memset(r->fields, 0, vtable->numbytes - sizeof(RefRecord));\n MEMDBG(\"mkClass: vt=%p => %p\", vtable, r);\n return r;\n}\n\nTValue RefRecord::ld(int idx) {\n // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 1);\n return fields[idx];\n}\n\nTValue RefRecord::ldref(int idx) {\n // DMESG(\"LD %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 2);\n return fields[idx];\n}\n\nvoid RefRecord::st(int idx, TValue v) {\n // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 3);\n fields[idx] = v;\n}\n\nvoid RefRecord::stref(int idx, TValue v) {\n // DMESG(\"ST %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 4);\n fields[idx] = v;\n}\n\nvoid RefObject::destroyVT() {\n ((RefObjectMethod)getVTable(this)->methods[0])(this);\n}\n\n//%\nvoid deleteRefObject(RefObject *obj) {\n obj->destroyVT();\n}\n\nvoid RefObject::printVT() {\n ((RefObjectMethod)getVTable(this)->methods[1])(this);\n}\n\nvoid RefRecord_destroy(RefRecord *) {}\n\nvoid RefRecord_print(RefRecord *r) {\n DMESG(\"RefRecord %p size=%d bytes\", r, getVTable(r)->numbytes);\n}\n\nvoid Segment::set(unsigned i, TValue value) {\n if (i < size) {\n data[i] = value;\n } else if (i < Segment::MaxSize) {\n growByMin(i + 1);\n data[i] = value;\n } else {\n return;\n }\n if (length <= i) {\n length = i + 1;\n }\n\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::set\");\n this->print();\n#endif\n\n return;\n}\n\nstatic inline int growthFactor(int size) {\n if (size == 0) {\n return 4;\n }\n if (size < 64) {\n return size * 2; // Double\n }\n if (size < 512) {\n return size * 5 / 3; // Grow by 1.66 rate\n }\n // Grow by constant rate\n if ((unsigned)size + 256 < Segment::MaxSize)\n return size + 256;\n else\n return Segment::MaxSize;\n}\n\nvoid LLSegment::setLength(unsigned newLen) {\n if (newLen > Segment::MaxSize)\n return;\n\n if (newLen > size) {\n int newSize = growthFactor(size);\n if (newSize < (int)newLen)\n newSize = newLen;\n\n // this will throw if unable to allocate\n TValue *tmp = (TValue *)(xmalloc(newSize * sizeof(TValue)));\n\n // Copy existing data\n if (size) {\n memcpy(tmp, data, size * sizeof(TValue));\n }\n // fill the rest with default value\n memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n // free older segment;\n xfree(data);\n\n data = tmp;\n size = newSize;\n } else if (newLen < length) {\n memset(data + newLen, 0, (length - newLen) * sizeof(TValue));\n }\n\n length = newLen;\n}\n\nvoid LLSegment::set(unsigned idx, TValue v) {\n if (idx >= Segment::MaxSize)\n return;\n if (idx >= length)\n setLength(idx + 1);\n data[idx] = v;\n}\n\nTValue LLSegment::pop() {\n if (length > 0) {\n --length;\n TValue value = data[length];\n data[length] = 0;\n return value;\n }\n return 0;\n}\n\nvoid LLSegment::destroy() {\n length = size = 0;\n xfree(data);\n data = nullptr;\n}\n\nvoid Segment::growByMin(ramint_t minSize) {\n ramint_t newSize = max(minSize, (ramint_t)growthFactor(size));\n\n if (size < newSize) {\n // this will throw if unable to allocate\n TValue *tmp = (TValue *)(gcAllocateArray(newSize * sizeof(TValue)));\n\n // Copy existing data\n if (size)\n memcpy(tmp, data, size * sizeof(TValue));\n // fill the rest with default value\n memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n data = tmp;\n size = newSize;\n\n#ifdef DEBUG_BUILD\n DMESG(\"growBy - after reallocation\");\n this->print();\n#endif\n }\n // else { no shrinking yet; }\n return;\n}\n\nvoid Segment::ensure(ramint_t newSize) {\n if (newSize < size) {\n return;\n }\n growByMin(newSize);\n}\n\nvoid Segment::setLength(unsigned newLength) {\n if (newLength > size) {\n ensure(newLength);\n }\n length = newLength;\n return;\n}\n\nTValue Segment::pop() {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::pop\");\n this->print();\n#endif\n\n if (length > 0) {\n --length;\n TValue value = data[length];\n data[length] = Segment::DefaultValue;\n return value;\n }\n return Segment::DefaultValue;\n}\n\n// this function removes an element at index i and shifts the rest of the elements to\n// left to fill the gap\nTValue Segment::remove(unsigned i) {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::remove index:%d\", i);\n this->print();\n#endif\n if (i < length) {\n // value to return\n TValue ret = data[i];\n if (i + 1 < length) {\n // Move the rest of the elements to fill in the gap.\n memmove(data + i, data + i + 1, (length - i - 1) * sizeof(void *));\n }\n length--;\n data[length] = Segment::DefaultValue;\n#ifdef DEBUG_BUILD\n DMESG(\"After Segment::remove index:%d\", i);\n this->print();\n#endif\n return ret;\n }\n return Segment::DefaultValue;\n}\n\n// this function inserts element value at index i by shifting the rest of the elements right.\nvoid Segment::insert(unsigned i, TValue value) {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::insert index:%d value:%d\", i, value);\n this->print();\n#endif\n\n if (i < length) {\n ensure(length + 1);\n\n // Move the rest of the elements to fill in the gap.\n memmove(data + i + 1, data + i, (length - i) * sizeof(void *));\n\n data[i] = value;\n length++;\n } else {\n // This is insert beyond the length, just call set which will adjust the length\n set(i, value);\n }\n#ifdef DEBUG_BUILD\n DMESG(\"After Segment::insert index:%d\", i);\n this->print();\n#endif\n}\n\nvoid Segment::print() {\n DMESG(\"Segment: %p, length: %d, size: %d\", data, (unsigned)length, (unsigned)size);\n for (unsigned i = 0; i < size; i++) {\n DMESG(\"-> %d\", (unsigned)(uintptr_t)data[i]);\n }\n}\n\nvoid Segment::destroy() {\n#ifdef DEBUG_BUILD\n DMESG(\"In Segment::destroy\");\n this->print();\n#endif\n length = size = 0;\n data = nullptr;\n}\n\nPXT_VTABLE_CTOR(RefCollection) {}\n\nvoid RefCollection::destroy(RefCollection *t) {\n t->head.destroy();\n}\n\nvoid RefCollection::print(RefCollection *t) {\n DMESG(\"RefCollection %p size=%d\", t, t->head.getLength());\n t->head.print();\n}\n\nPXT_VTABLE(RefAction, ValType::Function)\nRefAction::RefAction() : PXT_VTABLE_INIT(RefAction) {}\n\n// fields[] contain captured locals\nvoid RefAction::destroy(RefAction *t) {}\n\nvoid RefAction::print(RefAction *t) {\n#ifdef PXT_VM\n DMESG(\"RefAction %p pc=%X size=%d\", t, (uint32_t)t->func, t->len);\n#else\n DMESG(\"RefAction %p pc=%X size=%d\", t, (const uint8_t *)t->func - (const uint8_t *)bytecode,\n t->len);\n#endif\n}\n\nPXT_VTABLE_CTOR(RefRefLocal) {\n v = 0;\n}\n\nvoid RefRefLocal::print(RefRefLocal *t) {\n DMESG(\"RefRefLocal %p v=%p\", t, (void *)t->v);\n}\n\nvoid RefRefLocal::destroy(RefRefLocal *t) {\n decr(t->v);\n}\n\nPXT_VTABLE_CTOR(RefMap) {}\n\nvoid RefMap::destroy(RefMap *t) {\n t->keys.destroy();\n t->values.destroy();\n}\n\nint RefMap::findIdx(String key) {\n auto len = keys.getLength();\n auto data = (String *)keys.getData();\n\n // fast path\n for (unsigned i = 0; i < len; ++i) {\n if (data[i] == key)\n return i;\n }\n\n // slow path\n auto keylen = key->getUTF8Size();\n auto keydata = key->getUTF8Data();\n for (unsigned i = 0; i < len; ++i) {\n auto s = data[i];\n if (s->getUTF8Size() == keylen && memcmp(keydata, s->getUTF8Data(), keylen) == 0)\n return i;\n }\n\n return -1;\n}\n\nvoid RefMap::print(RefMap *t) {\n DMESG(\"RefMap %p size=%d\", t, t->keys.getLength());\n}\n\nvoid debugMemLeaks() {}\n\nvoid error(PXT_PANIC code, int subcode) {\n DMESG(\"Error: %d [%d]\", code, subcode);\n target_panic(code);\n}\n\n#ifndef PXT_VM\nuint16_t *bytecode;\n#endif\nTValue *globals;\n\nvoid checkStr(bool cond, const char *msg) {\n if (!cond) {\n while (true) {\n // uBit.display.scroll(msg, 100);\n // uBit.sleep(100);\n }\n }\n}\n\n#ifdef PXT_VM\nint templateHash() {\n return *(int*)&vmImg->infoHeader->hexHash;\n}\n\nint programHash() {\n return *(int*)&vmImg->infoHeader->programHash;\n}\n\nint getNumGlobals() {\n return (int)vmImg->infoHeader->allocGlobals;\n}\n\nString programName() {\n return mkString((char *)vmImg->infoHeader->name);\n}\n#else\nint templateHash() {\n return ((int *)bytecode)[4];\n}\n\nint programHash() {\n return ((int *)bytecode)[6];\n}\n\nint getNumGlobals() {\n return bytecode[16];\n}\n\nString programName() {\n return ((String *)bytecode)[15];\n}\n#endif\n\n#ifndef PXT_VM\nvoid variantNotSupported(const char *v) {\n DMESG(\"variant not supported: %s\", v);\n target_panic(PANIC_VARIANT_NOT_SUPPORTED);\n}\n\nvoid exec_binary(unsigned *pc) {\n // XXX re-enable once the calibration code is fixed and [editor/embedded.ts]\n // properly prepends a call to [internal_main].\n // ::touch_develop::internal_main();\n\n // unique group for radio based on source hash\n // ::touch_develop::micro_bit::radioDefaultGroup = programHash();\n\n unsigned ver = *pc++;\n checkStr(ver == 0x4210, \":( Bad runtime version\");\n\n bytecode = *((uint16_t **)pc++); // the actual bytecode is here\n\n if (((uint32_t *)bytecode)[0] == 0x923B8E71) {\n variantNotSupported((const char *)bytecode + 16);\n return;\n }\n\n globals = (TValue *)app_alloc(sizeof(TValue) * getNumGlobals());\n memset(globals, 0, sizeof(TValue) * getNumGlobals());\n\n // can be any valid address, best in RAM for speed\n globals[0] = (TValue)&globals;\n\n // just compare the first word\n // TODO\n checkStr(((uint32_t *)bytecode)[0] == 0x923B8E70 && (unsigned)templateHash() == *pc,\n \":( Failed partial flash\");\n\n uintptr_t startptr = (uintptr_t)bytecode;\n\n startptr += 64; // header\n\n initPerfCounters();\n\n initRuntime();\n\n runAction0((Action)startptr);\n\n pxt::releaseFiber();\n}\n\nvoid start() {\n exec_binary((unsigned *)functionsAndBytecode);\n}\n#endif\n\n} // namespace pxt\n\nnamespace Array_ {\n//%\nbool isArray(TValue arr) {\n auto vt = getAnyVTable(arr);\n return vt && vt->classNo == BuiltInType::RefCollection;\n}\n} // namespace Array_\n\nnamespace pxtrt {\n//% expose\nRefCollection *keysOf(TValue v) {\n auto r = NEW_GC(RefCollection);\n MEMDBG(\"mkColl[keys]: => %p\", r);\n if (getAnyVTable(v) != &RefMap_vtable)\n return r;\n auto rm = (RefMap *)v;\n auto len = rm->keys.getLength();\n if (!len)\n return r;\n registerGCObj(r);\n r->setLength(len);\n auto dst = r->getData();\n memcpy(dst, rm->keys.getData(), len * sizeof(TValue));\n unregisterGCObj(r);\n return r;\n}\n//% expose\nTValue mapDeleteByString(RefMap *map, String key) {\n if (getAnyVTable((TValue)map) != &RefMap_vtable)\n soft_panic(PANIC_DELETE_ON_CLASS);\n int i = map->findIdx(key);\n if (i >= 0) {\n map->keys.remove(i);\n map->values.remove(i);\n }\n return TAG_TRUE;\n}\n\n} // namespace pxtrt\n",
|
|
2772
2786
|
"pxt.h": "#ifndef __PXT_H\n#define __PXT_H\n\n//#define DEBUG_MEMLEAKS 1\n\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n\n#include \"pxtbase.h\"\n\nnamespace pxt {\n\nclass RefMImage : public RefObject {\n public:\n ImageData *img;\n\n RefMImage(ImageData *d);\n void makeWritable();\n static void destroy(RefMImage *map);\n static void print(RefMImage *map);\n static void scan(RefMImage *t);\n static unsigned gcsize(RefMImage *t);\n};\n\n#define MSTR(s) ManagedString((s)->getUTF8Data(), (s)->getUTF8Size())\n\nstatic inline String PSTR(ManagedString s) {\n return mkString(s.toCharArray(), s.length());\n}\n\ntypedef uint32_t ImageLiteral_;\n\nstatic inline ImageData *imageBytes(ImageLiteral_ lit) {\n return (ImageData *)lit;\n}\n\n#if MICROBIT_CODAL\n// avoid clashes with codal-defined classes\n#define Image MImage\n#define Button MButton\n#endif\n\ntypedef MicroBitPin DevicePin;\n\ntypedef RefMImage *Image;\n\nextern MicroBit uBit;\nextern MicroBitEvent lastEvent;\nextern bool serialLoggingDisabled;\n\nMicroBitPin *getPin(int id);\n\nstatic inline int min_(int a, int b) {\n if (a < b)\n return a;\n else\n return b;\n}\n\nstatic inline int max_(int a, int b) {\n if (a > b)\n return a;\n else\n return b;\n}\n\nvoid initMicrobitGC();\n\n} // namespace pxt\n\nusing namespace pxt;\n\n#define DEVICE_EVT_ANY 0\n\n#undef PXT_MAIN\n#define PXT_MAIN \\\n int main() { \\\n pxt::initMicrobitGC(); \\\n pxt::start(); \\\n return 0; \\\n }\n\n#endif\n\n// vim: ts=2 sw=2 expandtab\n",
|
|
2773
|
-
"pxt.json": "{\n \"name\": \"core\",\n \"description\": \"The microbit core library\",\n \"dependencies\": {},\n \"files\": [\n \"README.md\",\n \"platform.h\",\n \"pxt.cpp\",\n \"pxt.h\",\n \"pxtbase.h\",\n \"pxtcore.h\",\n \"math.ts\",\n \"dal.d.ts\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"pxt-core.d.ts\",\n \"core.cpp\",\n \"pxt-helpers.ts\",\n \"helpers.ts\",\n \"pxt-python.d.ts\",\n \"pxt-python-helpers.ts\",\n \"pinscompat.ts\",\n \"configkeys.h\",\n \"gc.cpp\",\n \"codal.cpp\",\n \"images.cpp\",\n \"basic.cpp\",\n \"basic.ts\",\n \"icons.ts\",\n \"icons.jres\",\n \"input.cpp\",\n \"input.ts\",\n \"gestures.jres\",\n \"control.ts\",\n \"control.cpp\",\n \"controlgc.cpp\",\n \"perfcounters.ts\",\n \"interval.ts\",\n \"gcstats.ts\",\n \"console.ts\",\n \"game.ts\",\n \"led.cpp\",\n \"led.ts\",\n \"music.cpp\",\n \"music.ts\",\n \"melodies.ts\",\n \"pins.cpp\",\n \"pins.ts\",\n \"serial.cpp\",\n \"serial.ts\",\n \"buffer.cpp\",\n \"buffer.ts\",\n \"json.ts\",\n \"poll.ts\",\n \"controlmessage.ts\",\n \"pxtparts.json\",\n \"advmath.cpp\",\n \"trig.cpp\",\n \"fixed.ts\",\n \"templates.ts\",\n \"sendbuffer.s\",\n \"sendbuffernrf52.s\",\n \"sendbufferbrightness.s\",\n \"light.cpp\",\n \"logo.cpp\",\n \"loops.ts\",\n \"touchmode.cpp\",\n \"soundexpressions.ts\",\n \"soundexpressions.cpp\",\n \"parts/speaker.svg\",\n \"parts/headphone.svg\"\n ],\n \"testFiles\": [],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2787
|
+
"pxt.json": "{\n \"name\": \"core\",\n \"description\": \"The microbit core library\",\n \"dependencies\": {},\n \"files\": [\n \"README.md\",\n \"platform.h\",\n \"pxt.cpp\",\n \"pxt.h\",\n \"pxtbase.h\",\n \"pxtcore.h\",\n \"math.ts\",\n \"dal.d.ts\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"pxt-core.d.ts\",\n \"core.cpp\",\n \"pxt-helpers.ts\",\n \"helpers.ts\",\n \"pxt-python.d.ts\",\n \"pxt-python-helpers.ts\",\n \"pinscompat.ts\",\n \"configkeys.h\",\n \"gc.cpp\",\n \"codal.cpp\",\n \"images.cpp\",\n \"basic.cpp\",\n \"basic.ts\",\n \"icons.ts\",\n \"icons.jres\",\n \"input.cpp\",\n \"input.ts\",\n \"gestures.jres\",\n \"control.ts\",\n \"control.cpp\",\n \"controlgc.cpp\",\n \"perfcounters.ts\",\n \"interval.ts\",\n \"gcstats.ts\",\n \"console.ts\",\n \"game.ts\",\n \"led.cpp\",\n \"led.ts\",\n \"music.cpp\",\n \"music.ts\",\n \"melodies.ts\",\n \"pins.cpp\",\n \"pins.ts\",\n \"serial.cpp\",\n \"serial.ts\",\n \"buffer.cpp\",\n \"buffer.ts\",\n \"json.ts\",\n \"poll.ts\",\n \"controlmessage.ts\",\n \"pxtparts.json\",\n \"advmath.cpp\",\n \"trig.cpp\",\n \"fixed.ts\",\n \"templates.ts\",\n \"sendbuffer.s\",\n \"sendbuffernrf52.s\",\n \"sendbufferbrightness.s\",\n \"light.cpp\",\n \"logo.cpp\",\n \"loops.ts\",\n \"touchmode.cpp\",\n \"soundexpressions.ts\",\n \"soundexpressions.cpp\",\n \"parts/speaker.svg\",\n \"parts/headphone.svg\"\n ],\n \"testFiles\": [],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"dalDTS\": {\n \"compileServiceVariant\": \"mbcodal\",\n \"includeDirs\": [\n \"libraries/codal-core/inc\",\n \"libraries/codal-microbit-v2/inc\",\n \"libraries/codal-microbit-v2/model\",\n \"libraries/codal-microbit-v2/inc/compat\",\n \"pxtapp\"\n ],\n \"excludePrefix\": [\n \"USB_\",\n \"REQUEST_\",\n \"LIS3DH_\",\n \"FXOS8700_\",\n \"MMA8\",\n \"LSM303_\",\n \"MAG_\",\n \"MPU6050_\",\n \"REF_TAG_\",\n \"HF2_\",\n \"PXT_REF_TAG_\",\n \"MS_\",\n \"SCSI_\"\n ]\n },\n \"yotta\": {\n \"config\": {\n \"microbit-dal\": {\n \"fiber_user_data\": 1,\n \"pxt\": 1\n }\n },\n \"optionalConfig\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"private_addressing\": 0,\n \"advertising_timeout\": 0,\n \"tx_power\": 6,\n \"dfu_service\": 1,\n \"event_service\": 1,\n \"device_info_service\": 1,\n \"eddystone_url\": 1,\n \"eddystone_uid\": 1,\n \"open\": 0,\n \"pairing_mode\": 1,\n \"whitelist\": 1,\n \"security_level\": \"SECURITY_MODE_ENCRYPTION_NO_MITM\",\n \"partial_flashing\": 1\n }\n }\n },\n \"userConfigs\": [\n {\n \"description\": \"No Pairing Required: Anyone can connect via Bluetooth.\",\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"open\": 1,\n \"whitelist\": 0,\n \"security_level\": null\n }\n }\n }\n },\n {\n \"description\": \"JustWorks pairing (default): Pairing is automatic once the pairing is initiated.\",\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"open\": 0,\n \"whitelist\": 1,\n \"security_level\": \"SECURITY_MODE_ENCRYPTION_NO_MITM\"\n }\n }\n }\n },\n {\n \"description\": \"Passkey pairing: Pairing requires 6 digit key to pair.\",\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"open\": 0,\n \"whitelist\": 1,\n \"security_level\": \"SECURITY_MODE_ENCRYPTION_WITH_MITM\"\n }\n }\n }\n }\n ]\n },\n \"partial\": true\n}\n",
|
|
2774
2788
|
"pxtbase.h": "#ifndef __PXTBASE_H\n#define __PXTBASE_H\n\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n#pragma GCC diagnostic ignored \"-Wformat\"\n#pragma GCC diagnostic ignored \"-Warray-bounds\"\n\n// needed for gcc6; not sure why\n#undef min\n#undef max\n\n#define NOLOG(...) \\\n do { \\\n } while (0)\n\n#define MEMDBG NOLOG\n//#define MEMDBG DMESG\n#define MEMDBG2 NOLOG\n\n#include \"pxtconfig.h\"\n#include \"configkeys.h\"\n\n#ifndef PXT_UTF8\n#define PXT_UTF8 0\n#endif\n\n#if defined(PXT_VM)\n#include <stdint.h>\n#if UINTPTR_MAX == 0xffffffff\n#define PXT32 1\n#elif UINTPTR_MAX == 0xffffffffffffffff\n#define PXT64 1\n#else\n#error \"UINTPTR_MAX has invalid value\"\n#endif\n#endif\n\n#define intcheck(...) check(__VA_ARGS__)\n//#define intcheck(...) do {} while (0)\n\n#ifdef PXT_USE_FLOAT\n#define NUMBER float\n#else\n#define NUMBER double\n#endif\n\n#include <string.h>\n#include <stdint.h>\n#include <math.h>\n\n#ifdef POKY\nvoid *operator new(size_t size, void *ptr);\nvoid *operator new(size_t size);\n#else\n#include <new>\n#endif\n\n#include \"platform.h\"\n#include \"pxtcore.h\"\n\n#ifndef PXT_REGISTER_RESET\n#define PXT_REGISTER_RESET(fn) ((void)0)\n#endif\n\n#define PXT_REFCNT_FLASH 0xfffe\n\n#define CONCAT_1(a, b) a##b\n#define CONCAT_0(a, b) CONCAT_1(a, b)\n// already provided in some platforms, like mbedos\n#ifndef STATIC_ASSERT\n#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) };\n#endif\n\n#ifndef ramint_t\n// this type limits size of arrays\n#if defined(__linux__) || defined(PXT_VM)\n// TODO fix the inline array accesses to take note of this!\n#define ramint_t uint32_t\n#else\n#define ramint_t uint16_t\n#endif\n#endif\n\n#ifndef PXT_IN_ISR\n#define PXT_IN_ISR() (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)\n#endif\n\n#ifdef POKY\ninline void *operator new(size_t, void *p) {\n return p;\n}\ninline void *operator new[](size_t, void *p) {\n return p;\n}\n#endif\n\nnamespace pxt {\n\ntemplate <typename T> inline const T &max(const T &a, const T &b) {\n if (a < b)\n return b;\n return a;\n}\n\ntemplate <typename T> inline const T &min(const T &a, const T &b) {\n if (a < b)\n return a;\n return b;\n}\n\ntemplate <typename T> inline void swap(T &a, T &b) {\n T tmp = a;\n a = b;\n b = tmp;\n}\n\n//\n// Tagged values (assume 4 bytes for now, Cortex-M0)\n//\nstruct TValueStruct {};\ntypedef TValueStruct *TValue;\n\ntypedef TValue TNumber;\ntypedef TValue Action;\ntypedef TValue ImageLiteral;\n\n// To be implemented by the target\nextern \"C\" void target_panic(int error_code);\nextern \"C\" void target_reset();\nvoid sleep_ms(unsigned ms);\nvoid sleep_us(uint64_t us);\nvoid releaseFiber();\nuint64_t current_time_us();\nint current_time_ms();\nvoid initRuntime();\nvoid initSystemTimer();\nvoid sendSerial(const char *data, int len);\nvoid setSendToUART(void (*f)(const char *, int));\nuint64_t getLongSerialNumber();\nvoid registerWithDal(int id, int event, Action a, int flags = 16); // EVENT_LISTENER_DEFAULT_FLAGS\nvoid runInParallel(Action a);\nvoid runForever(Action a);\nvoid waitForEvent(int id, int event);\n//%\nunsigned afterProgramPage();\n//%\nvoid dumpDmesg();\nuint32_t hash_fnv1(const void *data, unsigned len);\n\n// also defined DMESG macro\n// end\n\n#define TAGGED_SPECIAL(n) (TValue)(void *)((n << 2) | 2)\n#define TAG_FALSE TAGGED_SPECIAL(2) // 10\n#define TAG_TRUE TAGGED_SPECIAL(16) // 66\n#define TAG_UNDEFINED (TValue)0\n#define TAG_NULL TAGGED_SPECIAL(1) // 6\n#define TAG_NAN TAGGED_SPECIAL(3) // 14\n#define TAG_NUMBER(n) (TNumber)(void *)(((uintptr_t)(uint32_t)(n) << 1) | 1)\n#define TAG_NON_VALUE TAGGED_SPECIAL(4) // 18; doesn't represent any JS value\n\n#ifdef PXT_VM\ninline bool isEncodedDouble(uint64_t v) {\n return (v >> 48) != 0;\n}\n#endif\n\ninline bool isDouble(TValue v) {\n#ifdef PXT64\n return ((uintptr_t)v >> 48) != 0;\n#else\n (void)v;\n return false;\n#endif\n}\n\ninline bool isPointer(TValue v) {\n return !isDouble(v) && v != 0 && ((intptr_t)v & 3) == 0;\n}\n\ninline bool isTagged(TValue v) {\n return (!isDouble(v) && ((intptr_t)v & 3)) || !v;\n}\n\ninline bool isInt(TValue v) {\n return !isDouble(v) && ((intptr_t)v & 1);\n}\n\ninline bool isSpecial(TValue v) {\n return !isDouble(v) && ((intptr_t)v & 2);\n}\n\ninline bool bothNumbers(TValue a, TValue b) {\n return !isDouble(a) && !isDouble(b) && ((intptr_t)a & (intptr_t)b & 1);\n}\n\ninline int numValue(TValue n) {\n return (int)((intptr_t)n >> 1);\n}\n\ninline bool canBeTagged(int v) {\n (void)v;\n#ifdef PXT_BOX_DEBUG\n return false;\n#elif defined(PXT64)\n return true;\n#else\n return (v << 1) >> 1 == v;\n#endif\n}\n\n// see https://anniecherkaev.com/the-secret-life-of-nan\n\n#define NanBoxingOffset 0x1000000000000LL\n\ntemplate <typename TO, typename FROM> TO bitwise_cast(FROM in) {\n STATIC_ASSERT(sizeof(TO) == sizeof(FROM));\n union {\n FROM from;\n TO to;\n } u;\n u.from = in;\n return u.to;\n}\n\ninline double decodeDouble(uint64_t v) {\n return bitwise_cast<double>(v - NanBoxingOffset);\n}\n\n#ifdef PXT64\nSTATIC_ASSERT(sizeof(void *) == 8);\ninline double doubleVal(TValue v) {\n return bitwise_cast<double>((uint64_t)v - NanBoxingOffset);\n}\n\ninline TValue tvalueFromDouble(double d) {\n return (TValue)(bitwise_cast<uint64_t>(d) + NanBoxingOffset);\n}\n#else\nSTATIC_ASSERT(sizeof(void *) == 4);\n#endif\n\n// keep in sym with sim/control.ts\ntypedef enum {\n PANIC_CODAL_OOM = 20,\n PANIC_GC_OOM = 21,\n PANIC_GC_TOO_BIG_ALLOCATION = 22,\n PANIC_CODAL_HEAP_ERROR = 30,\n PANIC_CODAL_NULL_DEREFERENCE = 40,\n PANIC_CODAL_USB_ERROR = 50,\n PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR = 90,\n\n PANIC_INVALID_BINARY_HEADER = 901,\n PANIC_OUT_OF_BOUNDS = 902,\n PANIC_REF_DELETED = 903,\n PANIC_SIZE = 904,\n PANIC_INVALID_VTABLE = 905,\n PANIC_INTERNAL_ERROR = 906,\n PANIC_NO_SUCH_CONFIG = 907,\n PANIC_NO_SUCH_PIN = 908,\n PANIC_INVALID_ARGUMENT = 909,\n PANIC_MEMORY_LIMIT_EXCEEDED = 910,\n PANIC_SCREEN_ERROR = 911,\n PANIC_MISSING_PROPERTY = 912,\n PANIC_INVALID_IMAGE = 913,\n PANIC_CALLED_FROM_ISR = 914,\n PANIC_HEAP_DUMPED = 915,\n PANIC_STACK_OVERFLOW = 916,\n PANIC_BLOCKING_TO_STRING = 917,\n PANIC_VM_ERROR = 918,\n PANIC_SETTINGS_CLEARED = 920,\n PANIC_SETTINGS_OVERLOAD = 921,\n PANIC_SETTINGS_SECRET_MISSING = 922,\n PANIC_DELETE_ON_CLASS = 923,\n PANIC_OUT_OF_TIMERS = 924,\n PANIC_JACDAC = 925,\n PANIC_MICROPHONE_MISSING = 926,\n PANIC_VARIANT_NOT_SUPPORTED = 927,\n\n PANIC_CAST_FIRST = 980,\n PANIC_CAST_FROM_UNDEFINED = 980,\n PANIC_CAST_FROM_BOOLEAN = 981,\n PANIC_CAST_FROM_NUMBER = 982,\n PANIC_CAST_FROM_STRING = 983,\n PANIC_CAST_FROM_OBJECT = 984,\n PANIC_CAST_FROM_FUNCTION = 985,\n PANIC_CAST_FROM_NULL = 989,\n\n PANIC_UNHANDLED_EXCEPTION = 999,\n\n} PXT_PANIC;\n\nextern const uintptr_t functionsAndBytecode[];\nextern TValue *globals;\nextern uint16_t *bytecode;\nclass RefRecord;\n\n// Utility functions\n\ntypedef TValue (*RunActionType)(Action a, TValue arg0, TValue arg1, TValue arg2);\n\n#define asmRunAction3 ((RunActionType)(((uintptr_t *)bytecode)[12]))\n\nstatic inline TValue runAction3(Action a, TValue arg0, TValue arg1, TValue arg2) {\n return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction2(Action a, TValue arg0, TValue arg1) {\n return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction1(Action a, TValue arg0) {\n return asmRunAction3(a, arg0, 0, 0);\n}\nstatic inline TValue runAction0(Action a) {\n return asmRunAction3(a, 0, 0, 0);\n}\n\nclass RefAction;\nclass BoxedString;\nstruct VTable;\n\n//%\nAction mkAction(int totallen, RefAction *act);\n//% expose\nint templateHash();\n//% expose\nint programHash();\n//% expose\nBoxedString *programName();\n//% expose\nunsigned programSize();\n//%\nint getNumGlobals();\n//%\nRefRecord *mkClassInstance(VTable *vt);\n//%\nvoid debugMemLeaks();\n//%\nvoid anyPrint(TValue v);\n\n//%\nint getConfig(int key, int defl = -1);\n\n//%\nint toInt(TNumber v);\n//%\nunsigned toUInt(TNumber v);\n//%\nNUMBER toDouble(TNumber v);\n//%\nfloat toFloat(TNumber v);\n//%\nTNumber fromDouble(NUMBER r);\n//%\nTNumber fromFloat(float r);\n\n//%\nTNumber fromInt(int v);\n//%\nTNumber fromUInt(unsigned v);\n//%\nTValue fromBool(bool v);\n//%\nbool eq_bool(TValue a, TValue b);\n//%\nbool eqq_bool(TValue a, TValue b);\n\n//%\nvoid failedCast(TValue v, void *addr = NULL);\n//%\nvoid missingProperty(TValue v);\n\nvoid error(PXT_PANIC code, int subcode = 0);\nvoid exec_binary(unsigned *pc);\nvoid start();\n\nstruct HandlerBinding {\n HandlerBinding *next;\n int source;\n int value;\n Action action;\n#ifndef PXT_CODAL\n uint32_t flags;\n struct Event *pending;\n#endif\n};\nHandlerBinding *findBinding(int source, int value);\nHandlerBinding *nextBinding(HandlerBinding *curr, int source, int value);\nvoid setBinding(int source, int value, Action act);\n\n// Legacy stuff; should no longer be used\n//%\nTValue incr(TValue e);\n//%\nvoid decr(TValue e);\n\ninline TValue incr(TValue e) {\n return e;\n}\ninline void decr(TValue e) {}\n\nclass RefObject;\n\nstatic inline RefObject *incrRC(RefObject *r) {\n return r;\n}\nstatic inline void decrRC(RefObject *) {}\n\ninline void *ptrOfLiteral(int offset) {\n return &bytecode[offset];\n}\n\n// Checks if object is ref-counted, and has a custom PXT vtable in front\n// TODO\ninline bool isRefCounted(TValue e) {\n return isPointer(e);\n}\n\ninline void check(int cond, PXT_PANIC code, int subcode = 0) {\n if (!cond)\n error(code, subcode);\n}\n\ninline void oops(int subcode = 0) {\n target_panic(800 + subcode);\n}\n\nclass RefObject;\n\ntypedef void (*RefObjectMethod)(RefObject *self);\ntypedef unsigned (*RefObjectSizeMethod)(RefObject *self);\ntypedef void *PVoid;\ntypedef void **PPVoid;\n\ntypedef void *Object_;\n\n#define VTABLE_MAGIC 0xF9\n#define VTABLE_MAGIC2 0xF8\n\nenum class ValType : uint8_t {\n Undefined,\n Boolean,\n Number,\n String,\n Object,\n Function,\n};\n\n// keep in sync with pxt-core (search for the type name)\nenum class BuiltInType : uint16_t {\n BoxedString = 1,\n BoxedNumber = 2,\n BoxedBuffer = 3,\n RefAction = 4,\n RefImage = 5,\n RefCollection = 6,\n RefRefLocal = 7,\n RefMap = 8,\n RefMImage = 9, // microbit-specific\n MMap = 10, // linux, mostly ev3\n BoxedString_SkipList = 11, // used by VM bytecode representation only\n BoxedString_ASCII = 12, // ditto\n ZPin = 13,\n User0 = 16,\n};\n\nstruct VTable {\n uint16_t numbytes;\n ValType objectType;\n uint8_t magic;\n#ifdef PXT_VM\n uint16_t ifaceHashEntries;\n BuiltInType lastClassNo;\n#else\n PVoid *ifaceTable;\n#endif\n BuiltInType classNo;\n uint16_t reserved;\n uint32_t ifaceHashMult;\n\n // we only use the first few methods here; pxt will generate more\n PVoid methods[8];\n};\n\n//%\nextern const VTable string_inline_ascii_vt;\n#if PXT_UTF8\n//%\nextern const VTable string_inline_utf8_vt;\n//%\nextern const VTable string_cons_vt;\n//%\nextern const VTable string_skiplist16_vt;\n//%\nextern const VTable string_skiplist16_packed_vt;\n#endif\n//%\nextern const VTable buffer_vt;\n//%\nextern const VTable number_vt;\n//%\nextern const VTable RefAction_vtable;\n\n#ifndef PXT_IS_READONLY\n// assume ARM - ram addresses are 0x2000_0000+; flash is either 0x0+ or 0x0800_0000+\n#define PXT_IS_READONLY(v) (isTagged(v) || !((uintptr_t)v >> 28))\n#endif\n\ninline bool isReadOnly(TValue v) {\n return PXT_IS_READONLY(v);\n}\n\n// A base abstract class for ref-counted objects.\nclass RefObject {\n public:\n const VTable *vtable;\n\n RefObject(const VTable *vt) {\n#if defined(PXT32) && defined(PXT_VM) && !defined(PXT_ESP32)\n if ((uint32_t)vt & 0xf0000000)\n target_panic(PANIC_INVALID_VTABLE);\n#endif\n vtable = vt;\n }\n\n void destroyVT();\n void printVT();\n\n inline uintptr_t vt() { return (uintptr_t)vtable; }\n inline void setVT(uintptr_t v) { vtable = (const VTable *)v; }\n\n inline void ref() {}\n inline void unref() {}\n inline bool isReadOnly() { return pxt::isReadOnly((TValue)this); }\n};\n\nclass Segment {\n private:\n TValue *data;\n ramint_t length;\n ramint_t size;\n\n // this just gives max value of ramint_t\n void growByMin(ramint_t minSize);\n void ensure(ramint_t newSize);\n\n public:\n static constexpr ramint_t MaxSize = (((1U << (8 * sizeof(ramint_t) - 1)) - 1) << 1) + 1;\n static constexpr TValue DefaultValue = TAG_UNDEFINED; // == NULL\n\n Segment() : data(nullptr), length(0), size(0) {}\n\n TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n void set(unsigned i, TValue value);\n\n unsigned getLength() { return length; };\n void setLength(unsigned newLength);\n\n void push(TValue value) { set(length, value); }\n TValue pop();\n\n TValue remove(unsigned i);\n void insert(unsigned i, TValue value);\n\n void destroy();\n\n void print();\n\n TValue *getData() { return data; }\n};\n\n// Low-Level segment using system malloc\nclass LLSegment {\n private:\n TValue *data;\n ramint_t length;\n ramint_t size;\n\n public:\n LLSegment() : data(nullptr), length(0), size(0) {}\n\n void set(unsigned idx, TValue v);\n void push(TValue value) { set(length, value); }\n TValue pop();\n void destroy();\n void setLength(unsigned newLen);\n\n TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n unsigned getLength() { return length; };\n TValue *getData() { return data; }\n};\n\n// A ref-counted collection of either primitive or ref-counted objects (String, Image,\n// user-defined record, another collection)\nclass RefCollection : public RefObject {\n public:\n Segment head;\n\n RefCollection();\n\n static void destroy(RefCollection *coll);\n static void scan(RefCollection *coll);\n static unsigned gcsize(RefCollection *coll);\n static void print(RefCollection *coll);\n\n unsigned length() { return head.getLength(); }\n void setLength(unsigned newLength) { head.setLength(newLength); }\n TValue getAt(int i) { return head.get(i); }\n TValue *getData() { return head.getData(); }\n};\n\nclass RefMap : public RefObject {\n public:\n Segment keys;\n Segment values;\n\n RefMap();\n static void destroy(RefMap *map);\n static void scan(RefMap *map);\n static unsigned gcsize(RefMap *coll);\n static void print(RefMap *map);\n int findIdx(BoxedString *key);\n};\n\n// A ref-counted, user-defined JS object.\nclass RefRecord : public RefObject {\n public:\n // The object is allocated, so that there is space at the end for the fields.\n TValue fields[];\n\n RefRecord(VTable *v) : RefObject(v) {}\n\n TValue ld(int idx);\n TValue ldref(int idx);\n void st(int idx, TValue v);\n void stref(int idx, TValue v);\n};\n\nstatic inline VTable *getVTable(RefObject *r) {\n return (VTable *)(r->vt() & ~1);\n}\n\nstatic inline VTable *getAnyVTable(TValue v) {\n if (!isRefCounted(v))\n return NULL;\n auto vt = getVTable((RefObject *)v);\n if (vt->magic == VTABLE_MAGIC)\n return vt;\n return NULL;\n}\n\n// these are needed when constructing vtables for user-defined classes\n//%\nvoid RefRecord_destroy(RefRecord *r);\n//%\nvoid RefRecord_print(RefRecord *r);\n//%\nvoid RefRecord_scan(RefRecord *r);\n//%\nunsigned RefRecord_gcsize(RefRecord *r);\n\ntypedef TValue (*ActionCB)(TValue *captured, TValue arg0, TValue arg1, TValue arg2);\n\n// Ref-counted function pointer.\nclass RefAction : public RefObject {\n public:\n uint16_t len;\n uint16_t numArgs;\n#ifdef PXT_VM\n uint16_t initialLen;\n uint16_t flags;\n uintptr_t func;\n#else\n ActionCB func; // The function pointer\n#endif\n // fields[] contain captured locals\n TValue fields[];\n\n static void destroy(RefAction *act);\n static void scan(RefAction *act);\n static unsigned gcsize(RefAction *coll);\n static void print(RefAction *act);\n\n RefAction();\n\n inline void stCore(int idx, TValue v) {\n // DMESG(\"ST [%d] = %d \", idx, v); this->print();\n intcheck(0 <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 10);\n intcheck(fields[idx] == 0, PANIC_OUT_OF_BOUNDS, 11); // only one assignment permitted\n fields[idx] = v;\n }\n};\n\n// These two are used to represent locals written from inside inline functions\nclass RefRefLocal : public RefObject {\n public:\n TValue v;\n static void destroy(RefRefLocal *l);\n static void scan(RefRefLocal *l);\n static unsigned gcsize(RefRefLocal *l);\n static void print(RefRefLocal *l);\n RefRefLocal();\n};\n\ntypedef int color;\n\n// note: this is hardcoded in PXT (hexfile.ts)\n\nclass BoxedNumber : public RefObject {\n public:\n NUMBER num;\n BoxedNumber() : RefObject(&number_vt) {}\n} __attribute__((packed));\n\nclass BoxedString : public RefObject {\n public:\n union {\n struct {\n uint16_t length; // ==size\n char data[0];\n } ascii;\n#if PXT_UTF8\n struct {\n uint16_t size;\n char data[0];\n } utf8;\n struct {\n BoxedString *left;\n BoxedString *right;\n } cons;\n struct {\n uint16_t size; // in bytes\n uint16_t length; // in characters\n uint16_t *list;\n } skip;\n struct {\n uint16_t size; // in bytes\n uint16_t length; // in characters\n uint16_t list[0];\n } skip_pack;\n#endif\n };\n\n#if PXT_UTF8\n uintptr_t runMethod(int idx) {\n return ((uintptr_t(*)(BoxedString *))vtable->methods[idx])(this);\n }\n const char *getUTF8Data() { return (const char *)runMethod(4); }\n uint32_t getUTF8Size() { return (uint32_t)runMethod(5); }\n // in characters\n uint32_t getLength() { return (uint32_t)runMethod(6); }\n const char *getUTF8DataAt(uint32_t pos) {\n auto meth = ((const char *(*)(BoxedString *, uint32_t))vtable->methods[7]);\n return meth(this, pos);\n }\n#else\n const char *getUTF8Data() { return ascii.data; }\n uint32_t getUTF8Size() { return ascii.length; }\n uint32_t getLength() { return ascii.length; }\n const char *getUTF8DataAt(uint32_t pos) { return pos < ascii.length ? ascii.data + pos : NULL; }\n#endif\n\n TNumber charCodeAt(int pos);\n\n BoxedString(const VTable *vt) : RefObject(vt) {}\n};\n\n// cross version compatible way of accessing string data\n#ifndef PXT_STRING_DATA\n#define PXT_STRING_DATA(str) str->getUTF8Data()\n#endif\n\n// cross version compatible way of accessing string length\n#ifndef PXT_STRING_DATA_LENGTH\n#define PXT_STRING_DATA_LENGTH(str) str->getUTF8Size()\n#endif\n\nclass BoxedBuffer : public RefObject {\n public:\n // data needs to be word-aligned, so we use 32 bits for length\n int length;\n uint8_t data[0];\n BoxedBuffer() : RefObject(&buffer_vt) {}\n\n static bool isInstance(TValue v);\n};\n\n// cross version compatible way of access data field\n#ifndef PXT_BUFFER_DATA\n#define PXT_BUFFER_DATA(buffer) buffer->data\n#endif\n\n// cross version compatible way of access data length\n#ifndef PXT_BUFFER_LENGTH\n#define PXT_BUFFER_LENGTH(buffer) buffer->length\n#endif\n\n#ifndef PXT_CREATE_BUFFER\n#define PXT_CREATE_BUFFER(data, len) pxt::mkBuffer(data, len)\n#endif\n\n// Legacy format:\n// the first byte of data indicates the format - currently 0xE1 or 0xE4 to 1 or 4 bit bitmaps\n// second byte indicates width in pixels\n// third byte indicates the height (which should also match the size of the buffer)\n// just like ordinary buffers, these can be layed out in flash\n\n// Current format:\n// 87 BB WW WW HH HH 00 00 DATA\n// that is: 0x87, 0x01 or 0x04 - bpp, width in little endian, height, 0x00, 0x00 followed by data\n// for 4 bpp images, rows are word-aligned (as in legacy)\n\n#define IMAGE_HEADER_MAGIC 0x87\n\nstruct ImageHeader {\n uint8_t magic;\n uint8_t bpp;\n uint16_t width;\n uint16_t height;\n uint16_t padding;\n uint8_t pixels[0];\n};\n\nclass RefImage : public RefObject {\n public:\n BoxedBuffer *buffer;\n uint32_t revision;\n\n RefImage(BoxedBuffer *buf);\n RefImage(uint32_t sz);\n\n void setBuffer(BoxedBuffer *b);\n\n uint8_t *data() { return buffer->data; }\n int length() { return (int)buffer->length; }\n\n ImageHeader *header() { return (ImageHeader *)buffer->data; }\n int pixLength() { return length() - sizeof(ImageHeader); }\n\n int width() { return header()->width; }\n int height() { return header()->height; }\n int wordHeight();\n int bpp() { return header()->bpp; }\n\n bool hasPadding() { return (height() & 0x7) != 0; }\n\n uint8_t *pix() { return header()->pixels; }\n\n int byteHeight() {\n if (bpp() == 1)\n return (height() + 7) >> 3;\n else if (bpp() == 4)\n return ((height() * 4 + 31) >> 5) << 2;\n else {\n oops(21);\n return -1;\n }\n }\n\n uint8_t *pix(int x, int y) {\n uint8_t *d = &pix()[byteHeight() * x];\n if (y) {\n if (bpp() == 1)\n d += y >> 3;\n else if (bpp() == 4)\n d += y >> 1;\n }\n return d;\n }\n\n uint8_t fillMask(color c);\n bool inRange(int x, int y);\n void clamp(int *x, int *y);\n void makeWritable();\n\n static void destroy(RefImage *t);\n static void scan(RefImage *t);\n static unsigned gcsize(RefImage *t);\n static void print(RefImage *t);\n};\n\nRefImage *mkImage(int w, int h, int bpp);\n\ntypedef BoxedBuffer *Buffer;\ntypedef BoxedString *String;\ntypedef RefImage *Image_;\n\nuint32_t toRealUTF8(String str, uint8_t *dst);\n\n// keep in sync with github/pxt/pxtsim/libgeneric.ts\nenum class NumberFormat {\n Int8LE = 1,\n UInt8LE,\n Int16LE,\n UInt16LE,\n Int32LE,\n Int8BE,\n UInt8BE,\n Int16BE,\n UInt16BE,\n Int32BE,\n\n UInt32LE,\n UInt32BE,\n Float32LE,\n Float64LE,\n Float32BE,\n Float64BE,\n};\n\n// this will, unlike mkStringCore, UTF8-canonicalize the data\nString mkString(const char *data, int len = -1);\n// data can be NULL in both cases\nBuffer mkBuffer(const void *data, int len);\nString mkStringCore(const char *data, int len = -1);\n\nTNumber getNumberCore(uint8_t *buf, int size, NumberFormat format);\nvoid setNumberCore(uint8_t *buf, int size, NumberFormat format, TNumber value);\n\nvoid seedRandom(unsigned seed);\nvoid seedAddRandom(unsigned seed);\n// max is inclusive\nunsigned getRandom(unsigned max);\n\nValType valType(TValue v);\n\n// this is equivalent to JS `throw v`; it will leave\n// the current function(s), all the way until the nearest try block and\n// ignore all destructors (think longjmp())\nvoid throwValue(TValue v);\n\nvoid registerGC(TValue *root, int numwords = 1);\nvoid unregisterGC(TValue *root, int numwords = 1);\nvoid registerGCPtr(TValue ptr);\nvoid unregisterGCPtr(TValue ptr);\nstatic inline void registerGCObj(RefObject *ptr) {\n registerGCPtr((TValue)ptr);\n}\nstatic inline void unregisterGCObj(RefObject *ptr) {\n unregisterGCPtr((TValue)ptr);\n}\nvoid gc(int flags);\n\nstruct StackSegment {\n void *top;\n void *bottom;\n StackSegment *next;\n};\n\n#define NUM_TRY_FRAME_REGS 3\nstruct TryFrame {\n TryFrame *parent;\n uintptr_t registers[NUM_TRY_FRAME_REGS];\n};\n\nstruct ThreadContext {\n TValue *globals;\n StackSegment stack;\n TryFrame *tryFrame;\n TValue thrownValue;\n#ifdef PXT_GC_THREAD_LIST\n ThreadContext *next;\n ThreadContext *prev;\n#endif\n};\n\n#ifdef PXT_GC_THREAD_LIST\nextern ThreadContext *threadContexts;\nvoid *threadAddressFor(ThreadContext *, void *sp);\n#endif\n\nvoid releaseThreadContext(ThreadContext *ctx);\nThreadContext *getThreadContext();\nvoid setThreadContext(ThreadContext *ctx);\n\n#ifndef PXT_GC_THREAD_LIST\nvoid gcProcessStacks(int flags);\n#endif\n\nvoid gcProcess(TValue v);\nvoid gcFreeze();\n\n#ifdef PXT_VM\nvoid gcStartup();\nvoid gcPreStartup();\n#endif\n\nvoid coreReset();\nvoid gcReset();\nvoid systemReset();\n\nvoid doNothing();\n\nvoid *gcAllocate(int numbytes);\nvoid *gcAllocateArray(int numbytes);\nextern \"C\" void *app_alloc(int numbytes);\nextern \"C\" void *app_free(void *ptr);\nextern \"C\" void *app_alloc_at(void *at, int numbytes);\nvoid gcPreAllocateBlock(uint32_t sz);\n\nint redirectSamples(int16_t *dst, int numsamples, int samplerate);\n\n#ifdef PXT64\n#define TOWORDS(bytes) (((bytes) + 7) >> 3)\n#else\n#define TOWORDS(bytes) (((bytes) + 3) >> 2)\n#endif\n\n#ifndef PXT_VM\n#define soft_panic target_panic\n#endif\n\nextern int debugFlags;\n\nenum class PerfCounters {\n GC,\n};\n\n#ifdef PXT_PROFILE\n#ifndef PERF_NOW\n#error \"missing platform timer support\"\n#endif\n\nstruct PerfCounter {\n uint32_t value;\n uint32_t numstops;\n uint32_t start;\n};\n\nextern struct PerfCounter *perfCounters;\n\nvoid initPerfCounters();\n//%\nvoid dumpPerfCounters();\n//%\nvoid startPerfCounter(PerfCounters n);\n//%\nvoid stopPerfCounter(PerfCounters n);\n#else\ninline void startPerfCounter(PerfCounters n) {}\ninline void stopPerfCounter(PerfCounters n) {}\ninline void initPerfCounters() {}\ninline void dumpPerfCounters() {}\n#endif\n\n// Handling of built-in string literals (like \"[Object]\", \"true\" etc.).\n\n// This has the same layout as BoxedString, but has statically allocated buffer\ntemplate <size_t N> struct BoxedStringLayout {\n const void *vtable;\n uint16_t size;\n const char data[N];\n};\n\ntemplate <size_t N> constexpr size_t _boxedStringLen(char const (&)[N]) {\n return N;\n}\n\n// strings defined here as used as (String)name\n#define PXT_DEF_STRING(name, val) \\\n const BoxedStringLayout<_boxedStringLen(val)> name[1] = { \\\n {&pxt::string_inline_ascii_vt, _boxedStringLen(val) - 1, val}};\n\n// bigger value - less memory, but slower\n// 16/20 keeps s.length and s.charCodeAt(i) at about 200 cycles (for actual unicode strings),\n// which is similar to amortized allocation time\n#define PXT_STRING_SKIP_INCR 16 // needs to be power of 2; needs to be kept in sync with compiler\n#define PXT_STRING_MIN_SKIP \\\n 20 // min. size of string to use skip list; static code has its own limit\n\n#define PXT_NUM_SKIP_ENTRIES(p) ((p)->skip.length / PXT_STRING_SKIP_INCR)\n#define PXT_SKIP_DATA_IND(p) ((const char *)(p->skip.list + PXT_NUM_SKIP_ENTRIES(p)))\n#define PXT_SKIP_DATA_PACK(p) ((const char *)(p->skip_pack.list + PXT_NUM_SKIP_ENTRIES(p)))\n\n} // namespace pxt\n\nusing namespace pxt;\n\nnamespace numops {\n//%\nString toString(TValue v);\n//%\nint toBool(TValue v);\n//%\nint toBoolDecr(TValue v);\n} // namespace numops\n\nnamespace pxt {\ninline bool toBoolQuick(TValue v) {\n if (v == TAG_TRUE)\n return true;\n if (v == TAG_FALSE || v == TAG_UNDEFINED || v == TAG_NULL)\n return false;\n return numops::toBool(v);\n}\n} // namespace pxt\n\nnamespace pxtrt {\n//%\nRefMap *mkMap();\n//%\nTValue mapGetByString(RefMap *map, String key);\n//%\nint lookupMapKey(String key);\n//%\nTValue mapGet(RefMap *map, unsigned key);\n//% expose\nvoid mapSetByString(RefMap *map, String key, TValue val);\n//%\nvoid mapSet(RefMap *map, unsigned key, TValue val);\n} // namespace pxtrt\n\nnamespace pins {\nBuffer createBuffer(int size);\n}\n\nnamespace String_ {\n//%\nint compare(String a, String b);\n} // namespace String_\n\nnamespace Array_ {\n//%\nRefCollection *mk();\n//%\nint length(RefCollection *c);\n//%\nvoid setLength(RefCollection *c, int newLength);\n//%\nvoid push(RefCollection *c, TValue x);\n//%\nTValue pop(RefCollection *c);\n//%\nTValue getAt(RefCollection *c, int x);\n//%\nvoid setAt(RefCollection *c, int x, TValue y);\n//%\nTValue removeAt(RefCollection *c, int x);\n//%\nvoid insertAt(RefCollection *c, int x, TValue value);\n//%\nint indexOf(RefCollection *c, TValue x, int start);\n//%\nbool removeElement(RefCollection *c, TValue x);\n} // namespace Array_\n\n#define NEW_GC(T, ...) new (gcAllocate(sizeof(T))) T(__VA_ARGS__)\n\n// The ARM Thumb generator in the JavaScript code is parsing\n// the hex file and looks for the magic numbers as present here.\n//\n// Then it fetches function pointer addresses from there.\n//\n// The vtable pointers are there, so that the ::emptyData for various types\n// can be patched with the right vtable.\n//\n#define PXT_SHIMS_BEGIN \\\n namespace pxt { \\\n const uintptr_t functionsAndBytecode[] \\\n __attribute__((aligned(0x20))) = {0x08010801, 0x42424242, 0x08010801, 0x8de9d83e,\n\n#define PXT_SHIMS_END \\\n } \\\n ; \\\n }\n\n#if !defined(X86_64) && !defined(PXT_VM)\n#pragma GCC diagnostic ignored \"-Wpmf-conversions\"\n#endif\n\n#ifdef PXT_VM\n#define DEF_VTABLE(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#else\n#define DEF_VTABLE(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...) \\\n const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp, \\\n 0, 0, {__VA_ARGS__}};\n#endif\n\n#define PXT_VTABLE(classname, valtp) \\\n DEF_VTABLE(classname##_vtable, classname, valtp, (void *)&classname::destroy, \\\n (void *)&classname::print, (void *)&classname::scan, (void *)&classname::gcsize)\n\n#define PXT_EXT_VTABLE(classname) \\\n static int classname##_gcsize() { return sizeof(classname); } \\\n DEF_VTABLE_EXT(classname##_vtable, classname, ValType::Object, (void *)&pxt::doNothing, \\\n (void *)&pxt::anyPrint, (void *)&pxt::doNothing, (void *)&classname##_gcsize)\n\n#define PXT_VTABLE_INIT(classname) RefObject(&classname##_vtable)\n\n#define PXT_VTABLE_CTOR(classname) \\\n PXT_VTABLE(classname, ValType::Object) \\\n classname::classname() : PXT_VTABLE_INIT(classname)\n\n#define PXT_MAIN \\\n int main() { \\\n pxt::start(); \\\n return 0; \\\n }\n\n#define PXT_FNPTR(x) (uintptr_t)(void *)(x)\n\n#define PXT_ABI(...)\n\n#define JOIN(a, b) a##b\n/// Defines getClassName() function to fetch the singleton\n#define SINGLETON(ClassName) \\\n static ClassName *JOIN(inst, ClassName); \\\n ClassName *JOIN(get, ClassName)() { \\\n if (!JOIN(inst, ClassName)) \\\n JOIN(inst, ClassName) = new ClassName(); \\\n return JOIN(inst, ClassName); \\\n }\n\n/// Defines getClassName() function to fetch the singleton if PIN present\n#define SINGLETON_IF_PIN(ClassName, pin) \\\n static ClassName *JOIN(inst, ClassName); \\\n ClassName *JOIN(get, ClassName)() { \\\n if (!JOIN(inst, ClassName) && LOOKUP_PIN(pin)) \\\n JOIN(inst, ClassName) = new ClassName(); \\\n return JOIN(inst, ClassName); \\\n }\n\n#ifdef PXT_VM\n#include \"vm.h\"\n#endif\n\n#endif\n",
|
|
2775
2789
|
"pxtcore.h": "#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"MicroBit.h\"\n#include \"MicroBitImage.h\"\n#include \"ManagedString.h\"\n#include \"ManagedType.h\"\n\nnamespace pxt {\nvoid debuglog(const char *format, ...);\n}\n\n// #define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define xmalloc malloc\n#define xfree free\n\n#define GC_MAX_ALLOC_SIZE 9000\n\n#define NON_GC_HEAP_RESERVATION 1024\n\n#ifdef CODAL_CONFIG_H\n#define MICROBIT_CODAL 1\n#else\n#define MICROBIT_CODAL 0\n#define GC_BLOCK_SIZE 256\n#endif\n\n#if !MICROBIT_CODAL\n#undef DMESG\n#define DMESG NOLOG\n#endif\n\n#undef BYTES_TO_WORDS\n\n#endif\n",
|
|
2776
2790
|
"pxtparts.json": "{\n \"buttonpair\": {\n \"simulationBehavior\": \"buttonpair\",\n \"visual\": {\n \"builtIn\": \"buttonpair\",\n \"width\": 75,\n \"height\": 45,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 30,\n \"y\": 45\n },\n {\n \"x\": 45,\n \"y\": 0\n },\n {\n \"x\": 75,\n \"y\": 45\n }\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\n \"target\": \"P14\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"P15\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n },\n {\n \"pinIndices\": [\n 2,\n 3\n ]\n }\n ]\n },\n \"microservo\": {\n \"simulationBehavior\": \"microservo\",\n \"visual\": {\n \"builtIn\": \"microservo\",\n \"width\": 74.85,\n \"height\": 200,\n \"pinDistance\": 10,\n \"pinLocations\": [\n {\n \"x\": 30,\n \"y\": 5\n },\n {\n \"x\": 37,\n \"y\": 5\n },\n {\n \"x\": 45,\n \"y\": 5\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiations\": [\n {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"pins.servoWritePin,pins.servoSetPulse,PwmOnlyPin.servoWrite,PwmOnlyPin.servoSetPulse,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"name\"\n }\n ]\n }\n ],\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"neopixel\": {\n \"simulationBehavior\": \"neopixel\",\n \"visual\": {\n \"builtIn\": \"neopixel\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\n \"x\": 10,\n \"y\": 0\n },\n {\n \"x\": 19,\n \"y\": 0\n },\n {\n \"x\": 28,\n \"y\": 0\n }\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\n \"target\": {\n \"pinInstantiationIdx\": 0\n },\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"threeVolt\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"+Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"neopixel.create\",\n \"argumentRoles\": [\n {\n \"pinInstantiationIdx\": 0,\n \"partParameter\": \"pin\"\n },\n {\n \"partParameter\": \"mode\"\n }\n ]\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 2\n ]\n },\n {\n \"pinIndices\": [\n 0,\n 1\n ]\n }\n ]\n },\n \"ledmatrix\": {\n \"visual\": {\n \"builtIn\": \"ledmatrix\",\n \"width\": 105,\n \"height\": 105,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\n \"x\": 0,\n \"y\": 0\n },\n {\n \"x\": 15,\n \"y\": 0\n },\n {\n \"x\": 30,\n \"y\": 0\n },\n {\n \"x\": 45,\n \"y\": 0\n },\n {\n \"x\": 105,\n \"y\": 105\n },\n {\n \"x\": 0,\n \"y\": 105\n },\n {\n \"x\": 15,\n \"y\": 105\n },\n {\n \"x\": 30,\n \"y\": 105\n },\n {\n \"x\": 45,\n \"y\": 105\n },\n {\n \"x\": 60,\n \"y\": 0\n }\n ]\n },\n \"simulationBehavior\": \"ledmatrix\",\n \"numberOfPins\": 10,\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"pinDefinitions\": [\n {\n \"target\": \"P6\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 0\n },\n {\n \"target\": \"P7\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 0\n },\n {\n \"target\": \"P8\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 0\n },\n {\n \"target\": \"P9\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 0\n },\n {\n \"target\": \"P10\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 0\n },\n {\n \"target\": \"P12\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 1\n },\n {\n \"target\": \"P13\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 1\n },\n {\n \"target\": \"P16\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 1\n },\n {\n \"target\": \"P19\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 1\n },\n {\n \"target\": \"P20\",\n \"style\": \"male\",\n \"orientation\": \"-Z\",\n \"colorGroup\": 1\n }\n ],\n \"assembly\": [\n {\n \"part\": true\n },\n {\n \"pinIndices\": [\n 0,\n 1,\n 2,\n 3,\n 4\n ]\n },\n {\n \"pinIndices\": [\n 5,\n 6,\n 7,\n 8,\n 9\n ]\n }\n ]\n },\n \"headphone\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"image\": \"parts/headphone.svg\",\n \"width\": 142,\n \"height\": 180,\n \"pinDistance\": 20,\n \"pinLocations\": [\n {\n \"x\": 17,\n \"y\": 11\n },\n {\n \"x\": 55,\n \"y\": 50\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"P0\",\n \"style\": \"croc\",\n \"orientation\": \"Y\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"croc\",\n \"orientation\": \"Y\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n },\n \"speaker\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"image\": \"parts/speaker.svg\",\n \"width\": 500,\n \"height\": 500,\n \"pinDistance\": 70,\n \"pinLocations\": [\n {\n \"x\": 180,\n \"y\": 135\n },\n {\n \"x\": 320,\n \"y\": 135\n }\n ]\n },\n \"pinDefinitions\": [\n {\n \"target\": \"P0\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n },\n {\n \"target\": \"ground\",\n \"style\": \"male\",\n \"orientation\": \"-Z\"\n }\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\n \"part\": true,\n \"pinIndices\": [\n 0\n ]\n },\n {\n \"pinIndices\": [\n 1\n ]\n }\n ]\n }\n}",
|
|
@@ -2789,7 +2803,7 @@ var pxtTargetBundle = {
|
|
|
2789
2803
|
"radio": {
|
|
2790
2804
|
"README.md": "# radio\n\nThe radio library.\n\n",
|
|
2791
2805
|
"enums.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace radio {\n}\n\n// Auto-generated. Do not edit. Really.\n",
|
|
2792
|
-
"pxt.json": "{\n \"name\": \"radio\",\n \"description\": \"The radio services\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"radio.cpp\",\n \"radio.ts\",\n \"targetoverrides.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2806
|
+
"pxt.json": "{\n \"name\": \"radio\",\n \"description\": \"The radio services\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"radio.cpp\",\n \"radio.ts\",\n \"targetoverrides.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"yotta\": {\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"enabled\": 0\n }\n }\n }\n },\n \"icon\": \"/static/libs/radio.png\"\n}\n",
|
|
2793
2807
|
"radio.cpp": "#include \"pxt.h\"\n\n// micro:bit dal\n#if defined(MICROBIT_H) \n\n#define CODAL_RADIO MicroBitRadio\n#define DEVICE_OK MICROBIT_OK\n#define DEVICE_NOT_SUPPORTED MICROBIT_NOT_SUPPORTED\n#define CODAL_EVENT MicroBitEvent\n#define CODAL_RADIO_MICROBIT_DAL 1\n\n// any other NRF52 board\n#elif defined(NRF52_SERIES)\n\n#include \"NRF52Radio.h\"\n#define CODAL_RADIO codal::NRF52Radio\n#define CODAL_EVENT codal::Event\n\n#endif\n\nusing namespace pxt;\n\n#ifndef MICROBIT_RADIO_MAX_PACKET_SIZE\n#define MICROBIT_RADIO_MAX_PACKET_SIZE 32\n#endif\n\n#ifndef DEVICE_RADIO_MAX_PACKET_SIZE\n#define DEVICE_RADIO_MAX_PACKET_SIZE MICROBIT_RADIO_MAX_PACKET_SIZE\n#endif\n\n#ifndef MICROBIT_ID_RADIO\n#define MICROBIT_ID_RADIO 29\n#endif\n\n#ifndef DEVICE_ID_RADIO\n#define DEVICE_ID_RADIO MICROBIT_ID_RADIO\n#endif\n\n#ifndef MICROBIT_RADIO_EVT_DATAGRAM\n#define MICROBIT_RADIO_EVT_DATAGRAM 1 // Event to signal that a new datagram has been received.\n#endif\n\n#ifndef DEVICE_RADIO_EVT_DATAGRAM\n#define DEVICE_RADIO_EVT_DATAGRAM MICROBIT_RADIO_EVT_DATAGRAM\n#endif\n\n//% color=#E3008C weight=96 icon=\"\\uf012\"\nnamespace radio {\n \n#if CODAL_RADIO_MICROBIT_DAL\n CODAL_RADIO* getRadio() {\n return &uBit.radio;\n }\n#elif defined(CODAL_RADIO)\nclass RadioWrap {\n CODAL_RADIO radio;\n public:\n RadioWrap() \n : radio()\n {}\n\n CODAL_RADIO* getRadio() {\n return &radio;\n }\n};\nSINGLETON(RadioWrap);\nCODAL_RADIO* getRadio() {\n auto wrap = getRadioWrap();\n if (NULL != wrap)\n return wrap->getRadio(); \n return NULL;\n}\n#endif // #else\n\n bool radioEnabled = false;\n bool init = false;\n int radioEnable() {\n#ifdef CODAL_RADIO\n auto radio = getRadio();\n if (NULL == radio) \n return DEVICE_NOT_SUPPORTED;\n\n if (init && !radioEnabled) {\n //If radio was explicitly disabled from a call to off API\n //We don't want to enable it here. User needs to call on API first.\n return DEVICE_NOT_SUPPORTED;\n }\n\n int r = radio->enable();\n if (r != DEVICE_OK) {\n target_panic(43);\n return r;\n }\n if (!init) {\n getRadio()->setGroup(0); //Default group zero. This used to be pxt::programHash()\n getRadio()->setTransmitPower(6); // start with high power by default\n init = true;\n }\n radioEnabled = true;\n return r;\n#else\n return DEVICE_NOT_SUPPORTED;\n#endif\n }\n\n /**\n * Disables the radio for use as a multipoint sender/receiver.\n * Disabling radio will help conserve battery power when it is not in use.\n */\n //% help=radio/off\n void off() {\n#ifdef CODAL_RADIO\n auto radio = getRadio();\n if (NULL == radio)\n return;\n\n int r = radio->disable();\n if (r != DEVICE_OK) {\n target_panic(43);\n } else {\n radioEnabled = false;\n }\n#else\n return;\n#endif\n }\n\n /**\n * Initialises the radio for use as a multipoint sender/receiver\n * Only useful when the radio.off() is used beforehand.\n */\n //% help=radio/on\n void on() {\n#ifdef CODAL_RADIO\n auto radio = getRadio();\n if (NULL == radio)\n return;\n\n int r = radio->enable();\n if (r != DEVICE_OK) {\n target_panic(43);\n } else {\n radioEnabled = true;\n }\n#else\n return;\n#endif\n }\n\n /**\n * Sends an event over radio to neigboring devices\n */\n //% blockId=radioRaiseEvent block=\"radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\"\n //% blockExternalInputs=1\n //% advanced=true\n //% weight=1\n //% help=radio/raise-event\n void raiseEvent(int src, int value) {\n#ifdef CODAL_RADIO \n if (radioEnable() != DEVICE_OK) return;\n\n getRadio()->event.eventReceived(CODAL_EVENT(src, value, CREATE_ONLY));\n#endif \n }\n\n /**\n * Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer.\n * @returns NULL if no packet available\n */\n //%\n Buffer readRawPacket() {\n#ifdef CODAL_RADIO \n if (radioEnable() != DEVICE_OK) return NULL;\n\n auto p = getRadio()->datagram.recv();\n#if CODAL_RADIO_MICROBIT_DAL\n if (p == PacketBuffer::EmptyPacket)\n return NULL;\n int rssi = p.getRSSI();\n auto length = p.length();\n auto bytes = p.getBytes();\n#else\n // TODO: RSSI support\n int rssi = -73; \n auto length = p.length();\n auto bytes = p.getBytes();\n if (length == 0)\n return NULL;\n#endif\n\n uint8_t buf[DEVICE_RADIO_MAX_PACKET_SIZE + sizeof(int)]; // packet length + rssi\n memset(buf, 0, sizeof(buf));\n memcpy(buf, bytes, length); // data\n memcpy(buf + DEVICE_RADIO_MAX_PACKET_SIZE, &rssi, sizeof(int)); // RSSi - assumes Int32LE layout\n return mkBuffer(buf, sizeof(buf));\n#else\n return NULL;\n#endif \n }\n\n /**\n * Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)\n */\n //% async\n void sendRawPacket(Buffer msg) {\n#ifdef CODAL_RADIO \n if (radioEnable() != DEVICE_OK || NULL == msg) return;\n\n // don't send RSSI data; and make sure no buffer underflow\n int len = msg->length - sizeof(int);\n if (len > 0)\n getRadio()->datagram.send(msg->data, len);\n#endif \n }\n\n /**\n * Used internally by the library.\n */\n //% help=radio/on-data-received\n //% weight=0\n //% blockId=radio_datagram_received_event block=\"radio on data received\" blockGap=8\n //% deprecated=true blockHidden=1\n void onDataReceived(Action body) {\n#ifdef CODAL_RADIO \n if (radioEnable() != DEVICE_OK) return;\n\n registerWithDal(DEVICE_ID_RADIO, DEVICE_RADIO_EVT_DATAGRAM, body);\n getRadio()->datagram.recv(); // wake up read code\n#endif \n }\n\n /**\n * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.\n * @param id the group id between ``0`` and ``255``, eg: 1\n */\n //% help=radio/set-group\n //% weight=100\n //% blockId=radio_set_group block=\"radio set group %ID\"\n //% id.min=0 id.max=255\n //% group=\"Group\"\n void setGroup(int id) {\n#ifdef CODAL_RADIO \n if (radioEnable() != DEVICE_OK) return;\n\n getRadio()->setGroup(id);\n#endif \n }\n\n /**\n * Change the output power level of the transmitter to the given value.\n * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7\n */\n //% help=radio/set-transmit-power\n //% weight=9 blockGap=8\n //% blockId=radio_set_transmit_power block=\"radio set transmit power %power\"\n //% power.min=0 power.max=7\n //% advanced=true\n void setTransmitPower(int power) {\n#ifdef CODAL_RADIO \n if (radioEnable() != DEVICE_OK) return;\n\n getRadio()->setTransmitPower(power);\n#endif \n }\n\n /**\n * Change the transmission and reception band of the radio to the given channel\n * @param band a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.\n **/\n //% help=radio/set-frequency-band\n //% weight=8 blockGap=8\n //% blockId=radio_set_frequency_band block=\"radio set frequency band %band\"\n //% band.min=0 band.max=83\n //% advanced=true\n void setFrequencyBand(int band) {\n#ifdef CODAL_RADIO \n if (radioEnable() != DEVICE_OK) return;\n getRadio()->setFrequencyBand(band);\n#endif \n }\n}\n",
|
|
2794
2808
|
"radio.ts": "\nenum RadioPacketProperty {\n //% blockIdentity=radio._packetProperty\n //% block=\"signal strength\"\n SignalStrength = 2,\n //% blockIdentity=radio._packetProperty\n //% block=\"time\"\n Time = 0,\n //% block=\"serial number\"\n //% blockIdentity=radio._packetProperty\n SerialNumber = 1\n}\n\n/**\n * Communicate data using radio packets\n */\n//% color=#E3008C weight=96 icon=\"\\uf012\" groups='[\"Group\", \"Broadcast\", \"Send\", \"Receive\"]'\nnamespace radio {\n\n // keep in sync with CODAL\n const RADIO_MAX_PACKET_SIZE = 32;\n const MAX_FIELD_DOUBLE_NAME_LENGTH = 8;\n const MAX_PAYLOAD_LENGTH = 20;\n const PACKET_PREFIX_LENGTH = 9;\n const VALUE_PACKET_NAME_LEN_OFFSET = 13;\n const DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET = 17;\n\n // Packet Spec:\n // | 0 | 1 ... 4 | 5 ... 8 | 9 ... 28\n // ----------------------------------------------------------------\n // | packet type | system time | serial number | payload\n //\n // Serial number defaults to 0 unless enabled by user\n\n // payload: number (9 ... 12)\n export const PACKET_TYPE_NUMBER = 0;\n // payload: number (9 ... 12), name length (13), name (14 ... 26)\n export const PACKET_TYPE_VALUE = 1;\n // payload: string length (9), string (10 ... 28)\n export const PACKET_TYPE_STRING = 2;\n // payload: buffer length (9), buffer (10 ... 28)\n export const PACKET_TYPE_BUFFER = 3;\n // payload: number (9 ... 16)\n export const PACKET_TYPE_DOUBLE = 4;\n // payload: number (9 ... 16), name length (17), name (18 ... 26)\n export const PACKET_TYPE_DOUBLE_VALUE = 5;\n\n let transmittingSerial: boolean;\n let initialized = false;\n\n export let lastPacket: RadioPacket;\n let onReceivedNumberHandler: (receivedNumber: number) => void;\n let onReceivedValueHandler: (name: string, value: number) => void;\n let onReceivedStringHandler: (receivedString: string) => void;\n let onReceivedBufferHandler: (receivedBuffer: Buffer) => void;\n\n function init() {\n if (initialized) return;\n initialized = true;\n onDataReceived(handleDataReceived);\n }\n\n function handleDataReceived() {\n let buffer: Buffer = readRawPacket();\n while (buffer) {\n lastPacket = RadioPacket.getPacket(buffer);\n switch (lastPacket.packetType) {\n case PACKET_TYPE_NUMBER:\n case PACKET_TYPE_DOUBLE:\n if (onReceivedNumberHandler)\n onReceivedNumberHandler(lastPacket.numberPayload);\n break;\n case PACKET_TYPE_VALUE:\n case PACKET_TYPE_DOUBLE_VALUE:\n if (onReceivedValueHandler)\n onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload);\n break;\n case PACKET_TYPE_BUFFER:\n if (onReceivedBufferHandler)\n onReceivedBufferHandler(lastPacket.bufferPayload);\n break;\n case PACKET_TYPE_STRING:\n if (onReceivedStringHandler)\n onReceivedStringHandler(lastPacket.stringPayload);\n break;\n }\n // read next packet if any\n buffer = readRawPacket();\n }\n }\n\n /**\n * Registers code to run when the radio receives a number.\n */\n //% help=radio/on-received-number\n //% blockId=radio_on_number_drag block=\"on radio received\" blockGap=16\n //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n //% group=\"Receive\"\n //% weight=20\n export function onReceivedNumber(cb: (receivedNumber: number) => void) {\n init();\n onReceivedNumberHandler = cb;\n }\n\n /**\n * Registers code to run when the radio receives a key value pair.\n */\n //% help=radio/on-received-value\n //% blockId=radio_on_value_drag block=\"on radio received\" blockGap=16\n //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n //% group=\"Receive\"\n //% weight=19\n export function onReceivedValue(cb: (name: string, value: number) => void) {\n init();\n onReceivedValueHandler = cb;\n }\n\n /**\n * Registers code to run when the radio receives a string.\n */\n //% help=radio/on-received-string\n //% blockId=radio_on_string_drag block=\"on radio received\" blockGap=16\n //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n //% group=\"Receive\"\n //% weight=18\n export function onReceivedString(cb: (receivedString: string) => void) {\n init();\n onReceivedStringHandler = cb;\n }\n\n /**\n * Registers code to run when the radio receives a buffer.\n */\n //% help=radio/on-received-buffer blockHidden=1\n //% blockId=radio_on_buffer_drag block=\"on radio received\" blockGap=16\n //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n export function onReceivedBuffer(cb: (receivedBuffer: Buffer) => void) {\n init();\n onReceivedBufferHandler = cb;\n }\n\n /**\n * Returns properties of the last radio packet received.\n * @param type the type of property to retrieve from the last packet\n */\n //% help=radio/received-packet\n //% blockGap=8\n //% blockId=radio_received_packet block=\"received packet %type=radio_packet_property\" blockGap=16\n //% group=\"Receive\"\n //% weight=16\n export function receivedPacket(type: number) {\n if (lastPacket) {\n switch (type) {\n case RadioPacketProperty.Time: return lastPacket.time;\n case RadioPacketProperty.SerialNumber: return lastPacket.serial;\n case RadioPacketProperty.SignalStrength: return lastPacket.signal;\n }\n }\n return 0;\n }\n\n /**\n * Gets a packet property.\n * @param type the packet property type, eg: PacketProperty.time\n */\n //% blockId=radio_packet_property block=\"%note\"\n //% shim=TD_ID blockHidden=1\n export function _packetProperty(type: RadioPacketProperty): number {\n return type;\n }\n\n export class RadioPacket {\n public static getPacket(data: Buffer) {\n if (!data) return undefined;\n // last 4 bytes is RSSi\n return new RadioPacket(data);\n }\n\n public static mkPacket(packetType: number) {\n const res = new RadioPacket();\n res.data[0] = packetType;\n return res;\n }\n\n private constructor(public readonly data?: Buffer) {\n if (!data) this.data = control.createBuffer(RADIO_MAX_PACKET_SIZE + 4);\n }\n\n get signal() {\n return this.data.getNumber(NumberFormat.Int32LE, this.data.length - 4);\n }\n\n get packetType() {\n return this.data[0];\n }\n\n get time() {\n return this.data.getNumber(NumberFormat.Int32LE, 1);\n }\n\n set time(val: number) {\n this.data.setNumber(NumberFormat.Int32LE, 1, val);\n }\n\n get serial() {\n return this.data.getNumber(NumberFormat.Int32LE, 5);\n }\n\n set serial(val: number) {\n this.data.setNumber(NumberFormat.Int32LE, 5, val);\n }\n\n get stringPayload() {\n const offset = getStringOffset(this.packetType) as number;\n return offset ? this.data.slice(offset + 1, this.data[offset]).toString() : undefined;\n }\n\n set stringPayload(val: string) {\n const offset = getStringOffset(this.packetType) as number;\n if (offset) {\n const buf = control.createBufferFromUTF8(truncateString(val, getMaxStringLength(this.packetType)));\n this.data[offset] = buf.length;\n this.data.write(offset + 1, buf);\n }\n }\n\n get numberPayload() {\n switch (this.packetType) {\n case PACKET_TYPE_NUMBER:\n case PACKET_TYPE_VALUE:\n return this.data.getNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH);\n case PACKET_TYPE_DOUBLE:\n case PACKET_TYPE_DOUBLE_VALUE:\n return this.data.getNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH);\n }\n return undefined;\n }\n\n set numberPayload(val: number) {\n switch (this.packetType) {\n case PACKET_TYPE_NUMBER:\n case PACKET_TYPE_VALUE:\n this.data.setNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH, val);\n break;\n case PACKET_TYPE_DOUBLE:\n case PACKET_TYPE_DOUBLE_VALUE:\n this.data.setNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH, val);\n break;\n }\n }\n\n get bufferPayload() {\n const len = this.data[PACKET_PREFIX_LENGTH];\n return this.data.slice(PACKET_PREFIX_LENGTH + 1, len);\n }\n\n set bufferPayload(b: Buffer) {\n const len = Math.min(b.length, MAX_PAYLOAD_LENGTH - 1);\n this.data[PACKET_PREFIX_LENGTH] = len;\n this.data.write(PACKET_PREFIX_LENGTH + 1, b.slice(0, len));\n }\n\n hasString() {\n return this.packetType === PACKET_TYPE_STRING ||\n this.packetType === PACKET_TYPE_VALUE ||\n this.packetType === PACKET_TYPE_DOUBLE_VALUE;\n }\n\n hasNumber() {\n return this.packetType === PACKET_TYPE_NUMBER ||\n this.packetType === PACKET_TYPE_DOUBLE ||\n this.packetType === PACKET_TYPE_VALUE ||\n this.packetType === PACKET_TYPE_DOUBLE_VALUE;\n }\n }\n\n /**\n * Broadcasts a number over radio to any connected micro:bit in the group.\n */\n //% help=radio/send-number\n //% weight=60\n //% blockId=radio_datagram_send block=\"radio send number %value\" blockGap=8\n //% group=\"Send\"\n export function sendNumber(value: number) {\n let packet: RadioPacket;\n\n if (value === (value | 0)) {\n packet = RadioPacket.mkPacket(PACKET_TYPE_NUMBER);\n }\n else {\n packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE);\n }\n\n packet.numberPayload = value;\n sendPacket(packet);\n }\n\n /**\n * Broadcasts a name / value pair along with the device serial number\n * and running time to any connected micro:bit in the group. The name can\n * include no more than 8 characters.\n * @param name the field name (max 8 characters), eg: \"name\"\n * @param value the numeric value\n */\n //% help=radio/send-value\n //% weight=59\n //% blockId=radio_datagram_send_value block=\"radio send|value %name|= %value\" blockGap=8\n //% group=\"Send\"\n export function sendValue(name: string, value: number) {\n let packet: RadioPacket;\n\n if (value === (value | 0)) {\n packet = RadioPacket.mkPacket(PACKET_TYPE_VALUE);\n }\n else {\n packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE_VALUE);\n }\n\n packet.numberPayload = value;\n packet.stringPayload = name;\n sendPacket(packet);\n }\n\n /**\n * Broadcasts a string along with the device serial number\n * and running time to any connected micro:bit in the group.\n */\n //% help=radio/send-string\n //% weight=58\n //% blockId=radio_datagram_send_string block=\"radio send string %msg\"\n //% msg.shadowOptions.toString=true\n //% group=\"Send\"\n export function sendString(value: string) {\n const packet = RadioPacket.mkPacket(PACKET_TYPE_STRING);\n packet.stringPayload = value;\n sendPacket(packet);\n }\n\n /**\n * Broadcasts a buffer (up to 19 bytes long) along with the device serial number\n * and running time to any connected micro:bit in the group.\n */\n //% help=radio/send-buffer\n //% weight=57\n //% advanced=true\n export function sendBuffer(msg: Buffer) {\n const packet = RadioPacket.mkPacket(PACKET_TYPE_BUFFER);\n packet.bufferPayload = msg;\n sendPacket(packet);\n }\n\n /**\n * Set the radio to transmit the serial number in each message.\n * @param transmit value indicating if the serial number is transmitted, eg: true\n */\n //% help=radio/set-transmit-serial-number\n //% weight=8 blockGap=8\n //% blockId=radio_set_transmit_serial_number block=\"radio set transmit serial number %transmit\"\n //% advanced=true\n export function setTransmitSerialNumber(transmit: boolean) {\n transmittingSerial = transmit;\n }\n\n function sendPacket(packet: RadioPacket) {\n packet.time = control.millis();\n packet.serial = transmittingSerial ? control.deviceSerialNumber() : 0;\n radio.sendRawPacket(packet.data);\n }\n\n function truncateString(str: string, bytes: number) {\n str = str.substr(0, bytes);\n let buff = control.createBufferFromUTF8(str);\n\n while (buff.length > bytes) {\n str = str.substr(0, str.length - 1);\n buff = control.createBufferFromUTF8(str);\n }\n\n return str;\n }\n\n function getStringOffset(packetType: number) {\n switch (packetType) {\n case PACKET_TYPE_STRING:\n return PACKET_PREFIX_LENGTH;\n case PACKET_TYPE_VALUE:\n return VALUE_PACKET_NAME_LEN_OFFSET;\n case PACKET_TYPE_DOUBLE_VALUE:\n return DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET;\n default:\n return undefined;\n }\n }\n\n function getMaxStringLength(packetType: number) {\n switch (packetType) {\n case PACKET_TYPE_STRING:\n return MAX_PAYLOAD_LENGTH - 2;\n case PACKET_TYPE_VALUE:\n case PACKET_TYPE_DOUBLE_VALUE:\n return MAX_FIELD_DOUBLE_NAME_LENGTH;\n default:\n return undefined;\n }\n }\n}",
|
|
2795
2809
|
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n\n //% color=#E3008C weight=96 icon=\"\\uf012\"\ndeclare namespace radio {\n\n /**\n * Disables the radio for use as a multipoint sender/receiver.\n * Disabling radio will help conserve battery power when it is not in use.\n */\n //% help=radio/off shim=radio::off\n function off(): void;\n\n /**\n * Initialises the radio for use as a multipoint sender/receiver\n * Only useful when the radio.off() is used beforehand.\n */\n //% help=radio/on shim=radio::on\n function on(): void;\n\n /**\n * Sends an event over radio to neigboring devices\n */\n //% blockId=radioRaiseEvent block=\"radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\"\n //% blockExternalInputs=1\n //% advanced=true\n //% weight=1\n //% help=radio/raise-event shim=radio::raiseEvent\n function raiseEvent(src: int32, value: int32): void;\n\n /**\n * Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer.\n * @returns NULL if no packet available\n */\n //% shim=radio::readRawPacket\n function readRawPacket(): Buffer;\n\n /**\n * Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)\n */\n //% async shim=radio::sendRawPacket\n function sendRawPacket(msg: Buffer): void;\n\n /**\n * Used internally by the library.\n */\n //% help=radio/on-data-received\n //% weight=0\n //% blockId=radio_datagram_received_event block=\"radio on data received\" blockGap=8\n //% deprecated=true blockHidden=1 shim=radio::onDataReceived\n function onDataReceived(body: () => void): void;\n\n /**\n * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.\n * @param id the group id between ``0`` and ``255``, eg: 1\n */\n //% help=radio/set-group\n //% weight=100\n //% blockId=radio_set_group block=\"radio set group %ID\"\n //% id.min=0 id.max=255\n //% group=\"Group\" shim=radio::setGroup\n function setGroup(id: int32): void;\n\n /**\n * Change the output power level of the transmitter to the given value.\n * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7\n */\n //% help=radio/set-transmit-power\n //% weight=9 blockGap=8\n //% blockId=radio_set_transmit_power block=\"radio set transmit power %power\"\n //% power.min=0 power.max=7\n //% advanced=true shim=radio::setTransmitPower\n function setTransmitPower(power: int32): void;\n\n /**\n * Change the transmission and reception band of the radio to the given channel\n * @param band a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.\n **/\n //% help=radio/set-frequency-band\n //% weight=8 blockGap=8\n //% blockId=radio_set_frequency_band block=\"radio set frequency band %band\"\n //% band.min=0 band.max=83\n //% advanced=true shim=radio::setFrequencyBand\n function setFrequencyBand(band: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n",
|
|
@@ -2800,7 +2814,7 @@ var pxtTargetBundle = {
|
|
|
2800
2814
|
"devices.cpp": "#include \"pxt.h\"\n#include \"MESEvents.h\"\n\nusing namespace pxt;\n\nenum class MesCameraEvent {\n //% block=\"take photo\"\n TakePhoto = MES_CAMERA_EVT_TAKE_PHOTO,\n //% block=\"start video capture\"\n StartVideoCapture = MES_CAMERA_EVT_START_VIDEO_CAPTURE,\n //% block=\"stop video capture\"\n StopVideoCapture = MES_CAMERA_EVT_STOP_VIDEO_CAPTURE,\n //% block=\"toggle front-rear\"\n ToggleFrontRear = MES_CAMERA_EVT_TOGGLE_FRONT_REAR,\n //% block=\"launch photo mode\"\n LaunchPhotoMode = MES_CAMERA_EVT_LAUNCH_PHOTO_MODE,\n //% block=\"launch video mode\"\n LaunchVideoMode = MES_CAMERA_EVT_LAUNCH_VIDEO_MODE,\n //% block=\"stop photo mode\"\n StopPhotoMode = MES_CAMERA_EVT_STOP_PHOTO_MODE,\n //% block=\"stop video mode\"\n StopVideoMode = MES_CAMERA_EVT_STOP_VIDEO_MODE,\n};\n\nenum class MesAlertEvent {\n //% block=\"display toast\"\n DisplayToast = MES_ALERT_EVT_DISPLAY_TOAST,\n //% block=\"vibrate\"\n Vibrate = MES_ALERT_EVT_VIBRATE,\n //% block=\"play sound\"\n PlaySound = MES_ALERT_EVT_PLAY_SOUND,\n //% block=\"play ring tone\"\n PlayRingtone = MES_ALERT_EVT_PLAY_RINGTONE,\n //% block=\"find my phone\"\n FindMyPhone = MES_ALERT_EVT_FIND_MY_PHONE,\n //% block=\"ring alarm\"\n RingAlarm = MES_ALERT_EVT_ALARM1,\n //% block=\"ring alarm 2\"\n RingAlarm2 = MES_ALERT_EVT_ALARM2,\n //% block=\"ring alarm 3\"\n RingAlarm3 = MES_ALERT_EVT_ALARM3,\n //% block=\"ring alarm 4\"\n RingAlarm4 = MES_ALERT_EVT_ALARM4,\n //% block=\"ring alarm 5\"\n RingAlarm5 = MES_ALERT_EVT_ALARM5,\n //% block=\"ring alarm 6\"\n RingAlarm6 = MES_ALERT_EVT_ALARM6,\n};\n\nenum class MesDeviceInfo {\n //% block=\"incoming call\"\n IncomingCall = MES_DEVICE_INCOMING_CALL,\n //% block=\"incoming message\"\n IncomingMessage = MES_DEVICE_INCOMING_MESSAGE,\n //% block=\"orientation landscape\"\n OrientationLandscape = MES_DEVICE_ORIENTATION_LANDSCAPE,\n //% block=\"orientation portrait\"\n OrientationPortrait = MES_DEVICE_ORIENTATION_PORTRAIT,\n //% block=\"shaken\"\n Shaken = MES_DEVICE_GESTURE_DEVICE_SHAKEN,\n //% block=\"display off\"\n DisplayOff = MES_DEVICE_DISPLAY_OFF,\n //% block=\"display on\"\n DisplayOn = MES_DEVICE_DISPLAY_ON,\n};\n\nenum class MesRemoteControlEvent {\n //% block=\"play\"\n play = MES_REMOTE_CONTROL_EVT_PLAY,\n //% block=\"pause\"\n pause = MES_REMOTE_CONTROL_EVT_PAUSE,\n //% block=\"stop\"\n stop = MES_REMOTE_CONTROL_EVT_STOP,\n //% block=\"next track\"\n nextTrack = MES_REMOTE_CONTROL_EVT_NEXTTRACK,\n //% block=\"previous track\"\n previousTrack = MES_REMOTE_CONTROL_EVT_PREVTRACK,\n //% block=\"forward\"\n forward = MES_REMOTE_CONTROL_EVT_FORWARD,\n //% block=\"rewind\"\n rewind = MES_REMOTE_CONTROL_EVT_REWIND,\n //% block=\"volume up\"\n volumeUp = MES_REMOTE_CONTROL_EVT_VOLUMEUP,\n //% block=\"volume down\"\n volumeDown = MES_REMOTE_CONTROL_EVT_VOLUMEDOWN,\n};\n\n/**\n * Control a phone with the BBC micro:bit via Bluetooth.\n */\n//% color=#008272 weight=80 icon=\"\\uf10b\"\nnamespace devices {\n\n static int _signalStrength = -1;\n static void signalStrengthHandler(MicroBitEvent ev) { \n // keep in sync with MESEvents.h\n _signalStrength = ev.value - 1; \n }\n static void initSignalStrength() {\n if (_signalStrength < 0) {\n _signalStrength = 0;\n uBit.messageBus.listen(MES_SIGNAL_STRENGTH_ID, MICROBIT_EVT_ANY, signalStrengthHandler);\n } \n }\n \n /**\n * Returns the last signal strength reported by the paired device.\n */\n //% help=devices/signal-strength weight=24\n //% blockId=devices_signal_strength block=\"signal strength\" blockGap=14 icon=\"\\uf012\" blockGap=14\n int signalStrength() {\n initSignalStrength();\n return _signalStrength;\n }\n\n /**\n * Registers code to run when the device notifies about a change of signal strength.\n * @param body Code run when the signal strength changes.\n */\n //% weight=23 help=devices/on-signal-strength-changed\n //% blockId=devices_signal_strength_changed_event block=\"on signal strength changed\" icon=\"\\uf012\"\n void onSignalStrengthChanged(Action body) {\n initSignalStrength(); \n registerWithDal(MES_SIGNAL_STRENGTH_ID, MICROBIT_EVT_ANY, body);\n }\n}\n",
|
|
2801
2815
|
"devices.ts": "\nnamespace devices {\n /**\n * Sends a ``camera`` command to the parent device.\n * @param event event description\n */\n //% weight=30 help=devices/tell-camera-to\n //% blockId=devices_camera icon=\"\\uf030\" block=\"tell camera to|%property\" blockGap=8\n export function tellCameraTo(event: MesCameraEvent) {\n control.raiseEvent(DAL.MES_CAMERA_ID, event);\n }\n\n /**\n * Sends a ``remote control`` command to the parent device.\n * @param event event description\n */\n //% weight=29 help=devices/tell-remote-control-to\n //% blockId=devices_remote_control block=\"tell remote control to|%property\" blockGap=14 icon=\"\\uf144\"\n export function tellRemoteControlTo(event: MesRemoteControlEvent) {\n control.raiseEvent(DAL.MES_REMOTE_CONTROL_ID, event);\n }\n\n /**\n * Sends an ``alert`` command to the parent device.\n * @param event event description\n */\n //% weight=27 help=devices/raise-alert-to\n //% blockId=devices_alert block=\"raise alert to|%property\" icon=\"\\uf0f3\"\n export function raiseAlertTo(event: MesAlertEvent) {\n control.raiseEvent(DAL.MES_ALERTS_ID, event);\n }\n\n /**\n * Registers code to run when the device notifies about a particular event.\n * @param event event description\n * @param body code handler when event is triggered\n */\n //% help=devices/on-notified weight=26\n //% blockId=devices_device_info_event block=\"on notified|%event\" icon=\"\\uf10a\"\n export function onNotified(event: MesDeviceInfo, body: () => void) {\n control.onEvent(DAL.MES_DEVICE_INFO_ID, event, body);\n }\n\n /**\n * Register code to run when the micro:bit receives a command from the paired gamepad.\n * @param name button name\n * @param body code to run when button is pressed\n */\n //% help=devices/on-gamepad-button weight=40\n //% weight=25\n //% blockId=devices_gamepad_event block=\"on gamepad button|%NAME\" icon=\"\\uf11b\"\n export function onGamepadButton(name: MesDpadButtonInfo, body: () => void) {\n control.onEvent(DAL.MES_DPAD_CONTROLLER_ID, name, body);\n }\n}",
|
|
2802
2816
|
"enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum MesCameraEvent {\n //% block=\"take photo\"\n TakePhoto = 3, // MES_CAMERA_EVT_TAKE_PHOTO\n //% block=\"start video capture\"\n StartVideoCapture = 4, // MES_CAMERA_EVT_START_VIDEO_CAPTURE\n //% block=\"stop video capture\"\n StopVideoCapture = 5, // MES_CAMERA_EVT_STOP_VIDEO_CAPTURE\n //% block=\"toggle front-rear\"\n ToggleFrontRear = 8, // MES_CAMERA_EVT_TOGGLE_FRONT_REAR\n //% block=\"launch photo mode\"\n LaunchPhotoMode = 1, // MES_CAMERA_EVT_LAUNCH_PHOTO_MODE\n //% block=\"launch video mode\"\n LaunchVideoMode = 2, // MES_CAMERA_EVT_LAUNCH_VIDEO_MODE\n //% block=\"stop photo mode\"\n StopPhotoMode = 6, // MES_CAMERA_EVT_STOP_PHOTO_MODE\n //% block=\"stop video mode\"\n StopVideoMode = 7, // MES_CAMERA_EVT_STOP_VIDEO_MODE\n }\n\n\n declare const enum MesAlertEvent {\n //% block=\"display toast\"\n DisplayToast = 1, // MES_ALERT_EVT_DISPLAY_TOAST\n //% block=\"vibrate\"\n Vibrate = 2, // MES_ALERT_EVT_VIBRATE\n //% block=\"play sound\"\n PlaySound = 3, // MES_ALERT_EVT_PLAY_SOUND\n //% block=\"play ring tone\"\n PlayRingtone = 4, // MES_ALERT_EVT_PLAY_RINGTONE\n //% block=\"find my phone\"\n FindMyPhone = 5, // MES_ALERT_EVT_FIND_MY_PHONE\n //% block=\"ring alarm\"\n RingAlarm = 6, // MES_ALERT_EVT_ALARM1\n //% block=\"ring alarm 2\"\n RingAlarm2 = 7, // MES_ALERT_EVT_ALARM2\n //% block=\"ring alarm 3\"\n RingAlarm3 = 8, // MES_ALERT_EVT_ALARM3\n //% block=\"ring alarm 4\"\n RingAlarm4 = 9, // MES_ALERT_EVT_ALARM4\n //% block=\"ring alarm 5\"\n RingAlarm5 = 10, // MES_ALERT_EVT_ALARM5\n //% block=\"ring alarm 6\"\n RingAlarm6 = 11, // MES_ALERT_EVT_ALARM6\n }\n\n\n declare const enum MesDeviceInfo {\n //% block=\"incoming call\"\n IncomingCall = 7, // MES_DEVICE_INCOMING_CALL\n //% block=\"incoming message\"\n IncomingMessage = 8, // MES_DEVICE_INCOMING_MESSAGE\n //% block=\"orientation landscape\"\n OrientationLandscape = 1, // MES_DEVICE_ORIENTATION_LANDSCAPE\n //% block=\"orientation portrait\"\n OrientationPortrait = 2, // MES_DEVICE_ORIENTATION_PORTRAIT\n //% block=\"shaken\"\n Shaken = 4, // MES_DEVICE_GESTURE_DEVICE_SHAKEN\n //% block=\"display off\"\n DisplayOff = 5, // MES_DEVICE_DISPLAY_OFF\n //% block=\"display on\"\n DisplayOn = 6, // MES_DEVICE_DISPLAY_ON\n }\n\n\n declare const enum MesRemoteControlEvent {\n //% block=\"play\"\n play = 1, // MES_REMOTE_CONTROL_EVT_PLAY\n //% block=\"pause\"\n pause = 2, // MES_REMOTE_CONTROL_EVT_PAUSE\n //% block=\"stop\"\n stop = 3, // MES_REMOTE_CONTROL_EVT_STOP\n //% block=\"next track\"\n nextTrack = 4, // MES_REMOTE_CONTROL_EVT_NEXTTRACK\n //% block=\"previous track\"\n previousTrack = 5, // MES_REMOTE_CONTROL_EVT_PREVTRACK\n //% block=\"forward\"\n forward = 6, // MES_REMOTE_CONTROL_EVT_FORWARD\n //% block=\"rewind\"\n rewind = 7, // MES_REMOTE_CONTROL_EVT_REWIND\n //% block=\"volume up\"\n volumeUp = 8, // MES_REMOTE_CONTROL_EVT_VOLUMEUP\n //% block=\"volume down\"\n volumeDown = 9, // MES_REMOTE_CONTROL_EVT_VOLUMEDOWN\n }\ndeclare namespace devices {\n}\n\n// Auto-generated. Do not edit. Really.\n",
|
|
2803
|
-
"pxt.json": "{\n \"name\": \"devices\",\n \"description\": \"BETA - Camera, remote control and other Bluetooth services. App required.\",\n \"dependencies\": {\n \"core\": \"*\",\n \"bluetooth\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"devices.cpp\",\n \"devices.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2817
|
+
"pxt.json": "{\n \"name\": \"devices\",\n \"description\": \"BETA - Camera, remote control and other Bluetooth services. App required.\",\n \"dependencies\": {\n \"core\": \"*\",\n \"bluetooth\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"devices.cpp\",\n \"devices.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"icon\": \"./static/packages/devices/icon.png\",\n \"hidden\": true\n}\n",
|
|
2804
2818
|
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Control a phone with the BBC micro:bit via Bluetooth.\n */\n //% color=#008272 weight=80 icon=\"\\uf10b\"\ndeclare namespace devices {\n\n /**\n * Returns the last signal strength reported by the paired device.\n */\n //% help=devices/signal-strength weight=24\n //% blockId=devices_signal_strength block=\"signal strength\" blockGap=14 icon=\"\\uf012\" blockGap=14 shim=devices::signalStrength\n function signalStrength(): int32;\n\n /**\n * Registers code to run when the device notifies about a change of signal strength.\n * @param body Code run when the signal strength changes.\n */\n //% weight=23 help=devices/on-signal-strength-changed\n //% blockId=devices_signal_strength_changed_event block=\"on signal strength changed\" icon=\"\\uf012\" shim=devices::onSignalStrengthChanged\n function onSignalStrengthChanged(body: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"
|
|
2805
2819
|
},
|
|
2806
2820
|
"bluetooth": {
|
|
@@ -2810,18 +2824,18 @@ var pxtTargetBundle = {
|
|
|
2810
2824
|
"bluetooth.cpp": "#include \"pxt.h\"\n#include \"MESEvents.h\"\n#include \"MicroBitUARTService.h\"\n#include \"BLEHF2Service.h\"\n\nusing namespace pxt;\n\n/**\n * Support for additional Bluetooth services.\n */\n//% color=#0082FB weight=96 icon=\"\\uf294\"\nnamespace bluetooth {\n MicroBitUARTService *uart = NULL;\n BLEHF2Service* pHF2 = NULL;\n\n //%\n void __log(int priority, String msg) {\n if (NULL == pHF2)\n pHF2 = new BLEHF2Service(*uBit.ble);\n pHF2->sendSerial(msg->getUTF8Data(), msg->getUTF8Size(), false);\n }\n\n /**\n * Starts the Bluetooth accelerometer service\n */\n //% help=bluetooth/start-accelerometer-service\n //% blockId=bluetooth_start_accelerometer_service block=\"bluetooth accelerometer service\"\n //% parts=\"bluetooth\" weight=90 blockGap=8\n void startAccelerometerService() {\n new MicroBitAccelerometerService(*uBit.ble, uBit.accelerometer); \n } \n\n /**\n * Starts the Bluetooth button service\n */\n //% help=bluetooth/start-button-service\n //% blockId=bluetooth_start_button_service block=\"bluetooth button service\" blockGap=8\n //% parts=\"bluetooth\" weight=89\n void startButtonService() {\n new MicroBitButtonService(*uBit.ble); \n }\n\n /**\n * Starts the Bluetooth IO pin service.\n */\n //% help=bluetooth/start-io-pin-service\n //% blockId=bluetooth_start_io_pin_service block=\"bluetooth io pin service\" blockGap=8\n //% parts=\"bluetooth\" weight=88\n void startIOPinService() {\n new MicroBitIOPinService(*uBit.ble, uBit.io);\n }\n\n /**\n * Starts the Bluetooth LED service\n */\n //% help=bluetooth/start-led-service\n //% blockId=bluetooth_start_led_service block=\"bluetooth led service\" blockGap=8\n //% parts=\"bluetooth\" weight=87\n void startLEDService() {\n new MicroBitLEDService(*uBit.ble, uBit.display);\n }\n\n /**\n * Starts the Bluetooth temperature service\n */\n //% help=bluetooth/start-temperature-service\n //% blockId=bluetooth_start_temperature_service block=\"bluetooth temperature service\" blockGap=8\n //% parts=\"bluetooth\" weight=86\n void startTemperatureService() { \n new MicroBitTemperatureService(*uBit.ble, uBit.thermometer); \n }\n\n /**\n * Starts the Bluetooth magnetometer service\n */\n //% help=bluetooth/start-magnetometer-service\n //% blockId=bluetooth_start_magnetometer_service block=\"bluetooth magnetometer service\"\n //% parts=\"bluetooth\" weight=85\n void startMagnetometerService() { \n new MicroBitMagnetometerService(*uBit.ble, uBit.compass); \n }\n\n\n /**\n * Starts the Bluetooth UART service\n */\n //% help=bluetooth/start-uart-service\n //% blockId=bluetooth_start_uart_service block=\"bluetooth uart service\"\n //% parts=\"bluetooth\" advanced=true\n void startUartService() {\n if (uart) return;\n // 61 octet buffer size is 3 x (MTU - 3) + 1\n // MTU on nRF51822 is 23 octets. 3 are used by Attribute Protocol header data leaving 20 octets for payload\n // So we allow a RX buffer that can contain 3 x max length messages plus one octet for a terminator character\n uart = new MicroBitUARTService(*uBit.ble, 61, 60);\n }\n \n //%\n void uartWriteString(String data) {\n startUartService();\n \tuart->send(MSTR(data));\n } \n\n //%\n String uartReadUntil(String del) {\n startUartService();\n return PSTR(uart->readUntil(MSTR(del)));\n } \n\n\n /**\n * Sends a buffer of data via Bluetooth UART\n */\n //%\n void uartWriteBuffer(Buffer buffer) {\n startUartService();\n uart->send(buffer->data, buffer->length);\n }\n\n /**\n * Reads buffered UART data into a buffer\n */\n //%\n Buffer uartReadBuffer() {\n startUartService();\n int bytes = uart->rxBufferedSize();\n auto buffer = mkBuffer(NULL, bytes);\n auto res = buffer;\n registerGCObj(buffer);\n int read = uart->read(buffer->data, buffer->length);\n // read failed\n if (read < 0) {\n res = mkBuffer(NULL, 0);\n } else if (read != buffer->length) {\n // could not fill the buffer\n res = mkBuffer(buffer->data, read); \n }\n unregisterGCObj(buffer);\n return res;\n }\n\n /**\n * Registers an event to be fired when one of the delimiter is matched.\n * @param delimiters the characters to match received characters against.\n */\n //% help=bluetooth/on-uart-data-received\n //% weight=18 blockId=bluetooth_on_data_received block=\"bluetooth|on data received %delimiters=serial_delimiter_conv\"\n void onUartDataReceived(String delimiters, Action body) {\n startUartService();\n uart->eventOn(MSTR(delimiters));\n registerWithDal(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH, body);\n }\n\n /**\n * Register code to run when the micro:bit is connected to over Bluetooth\n * @param body Code to run when a Bluetooth connection is established\n */\n //% help=bluetooth/on-bluetooth-connected weight=20\n //% blockId=bluetooth_on_connected block=\"on bluetooth connected\" blockGap=8\n //% parts=\"bluetooth\"\n void onBluetoothConnected(Action body) {\n registerWithDal(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, body);\n } \n\n /**\n * Register code to run when a bluetooth connection to the micro:bit is lost\n * @param body Code to run when a Bluetooth connection is lost\n */\n //% help=bluetooth/on-bluetooth-disconnected weight=19\n //% blockId=bluetooth_on_disconnected block=\"on bluetooth disconnected\"\n //% parts=\"bluetooth\"\n void onBluetoothDisconnected(Action body) {\n registerWithDal(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, body);\n } \n\n const int8_t CALIBRATED_POWERS[] = {-49, -37, -33, -28, -25, -20, -15, -10};\n /**\n * Advertise an Eddystone URL\n\t* @param url the url to transmit. Must be no longer than the supported eddystone url length, eg: \"https://makecode.com\"\n\t* @param power power level between 0 and 7, eg: 7\n * @param connectable true to keep bluetooth connectable for other services, false otherwise.\n */\n //% blockId=eddystone_advertise_url block=\"bluetooth advertise url %url|with power %power|connectable %connectable\"\n //% parts=bluetooth weight=11 blockGap=8\n //% help=bluetooth/advertise-url blockExternalInputs=1\n //% hidden=1 deprecated=1\n void advertiseUrl(String url, int power, bool connectable) {\n#if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_URL)\n power = min(MICROBIT_BLE_POWER_LEVELS-1, max(0, power));\n int8_t level = CALIBRATED_POWERS[power];\n uBit.bleManager.advertiseEddystoneUrl(MSTR(url), level, connectable);\n uBit.bleManager.setTransmitPower(power);\n#endif\n }\n\n /**\n * Advertise an Eddystone UID\n\t* @param nsAndInstance 16 bytes buffer of namespace (bytes 0-9) and instance (bytes 10-15)\n\t* @param power power level between 0 and 7, eg: 7\n * @param connectable true to keep bluetooth connectable for other services, false otherwise.\n */\n //% parts=bluetooth weight=12 advanced=true deprecated=1\n void advertiseUidBuffer(Buffer nsAndInstance, int power, bool connectable) {\n#if CONFIG_ENABLED(MICROBIT_BLE_EDDYSTONE_UID) \n auto buf = nsAndInstance;\n if (buf->length != 16) return;\n\n power = min(MICROBIT_BLE_POWER_LEVELS-1, max(0, power));\n int8_t level = CALIBRATED_POWERS[power];\n uBit.bleManager.advertiseEddystoneUid((const char*)buf->data, (const char*)buf->data + 10, level, connectable);\n#endif\n }\n\n /**\n * Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).\n * @param power power level between 0 (minimal) and 7 (maximum), eg: 7.\n */\n //% parts=bluetooth weight=5 help=bluetooth/set-transmit-power advanced=true\n //% blockId=bluetooth_settransmitpower block=\"bluetooth set transmit power %power\"\n void setTransmitPower(int power) {\n uBit.bleManager.setTransmitPower(min(MICROBIT_BLE_POWER_LEVELS-1, max(0, power)));\n }\n\n /**\n * Stops advertising Eddystone end points\n */\n //% blockId=eddystone_stop_advertising block=\"bluetooth stop advertising\"\n //% parts=bluetooth weight=10\n //% help=bluetooth/stop-advertising advanced=true\n //% hidden=1 deprecated=1\n void stopAdvertising() {\n uBit.bleManager.stopAdvertising();\n } \n}",
|
|
2811
2825
|
"bluetooth.ts": "/// <reference no-default-lib=\"true\"/>\n/**\n * Support for additional Bluetooth services.\n */\n//% color=#007EF4 weight=96 icon=\"\\uf294\"\nnamespace bluetooth {\n export let NEW_LINE = \"\\r\\n\";\n\n /**\n * Internal use\n */\n //% shim=bluetooth::__log\n export function __log(priority: number, msg: string) {\n return;\n }\n console.addListener(function (_pri, msg) { __log(_pri, msg) });\n\n /**\n * Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.\n */\n //% help=bluetooth/uart-write-string weight=80\n //% blockId=bluetooth_uart_write block=\"bluetooth uart|write string %data\" blockGap=8\n //% parts=\"bluetooth\" shim=bluetooth::uartWriteString advanced=true\n export function uartWriteString(data: string): void {\n console.log(data)\n }\n\n /**\n * Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.\n */\n //% help=bluetooth/uart-write-line weight=79\n //% blockId=bluetooth_uart_line block=\"bluetooth uart|write line %data\" blockGap=8\n //% parts=\"bluetooth\" advanced=true\n export function uartWriteLine(data: string): void {\n uartWriteString(data + serial.NEW_LINE);\n }\n\n /**\n * Prints a numeric value to the serial\n */\n //% help=bluetooth/uart-write-number weight=79\n //% weight=89 blockGap=8 advanced=true\n //% blockId=bluetooth_uart_writenumber block=\"bluetooth uart|write number %value\"\n export function uartWriteNumber(value: number): void {\n uartWriteString(value.toString());\n }\n\n /**\n * Writes a ``name: value`` pair line to the serial.\n * @param name name of the value stream, eg: x\n * @param value to write\n */\n //% weight=88 weight=78\n //% help=bluetooth/uart-write-value advanced=true\n //% blockId=bluetooth_uart_writevalue block=\"bluetooth uart|write value %name|= %value\"\n export function uartWriteValue(name: string, value: number): void {\n uartWriteString((name ? name + \":\" : \"\") + value + NEW_LINE);\n }\n\n /**\n * Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.\n */\n //% help=bluetooth/uart-read-until weight=75\n //% blockId=bluetooth_uart_read block=\"bluetooth uart|read until %del=serial_delimiter_conv\"\n //% parts=\"bluetooth\" shim=bluetooth::uartReadUntil advanced=true\n export function uartReadUntil(del: string): string {\n // dummy implementation for simulator\n return \"\"\n }\n\n /**\n * Advertise an Eddystone UID\n * @param ns 4 last bytes of the namespace uid\n * @param instance 4 last bytes of the instance uid\n * @param power power level between 0 and 7, eg: 7\n * @param connectable true to keep bluetooth connectable for other services, false otherwise.\n */\n //% blockId=eddystone_advertise_uid block=\"bluetooth advertise UID|namespace (bytes 6-9)%ns|instance (bytes 2-6)%instance|with power %power|connectable %connectable\"\n //% parts=bluetooth weight=12 blockGap=8\n //% help=bluetooth/advertise-uid blockExternalInputs=1\n //% hidden=1 deprecated=1\n export function advertiseUid(ns: number, instance: number, power: number, connectable: boolean) {\n const buf = pins.createBuffer(16);\n buf.setNumber(NumberFormat.Int32BE, 6, ns);\n buf.setNumber(NumberFormat.Int32BE, 12, instance);\n bluetooth.advertiseUidBuffer(buf, power, connectable);\n }\n}\n",
|
|
2812
2826
|
"enums.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace bluetooth {\n}\n\n// Auto-generated. Do not edit. Really.\n",
|
|
2813
|
-
"pxt.json": "{\n \"name\": \"bluetooth\",\n \"description\": \"Bluetooth services\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"bluetooth.ts\",\n \"bluetooth.cpp\",\n \"BLEHF2Service.h\",\n \"BLEHF2Service.cpp\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2827
|
+
"pxt.json": "{\n \"name\": \"bluetooth\",\n \"description\": \"Bluetooth services\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"bluetooth.ts\",\n \"bluetooth.cpp\",\n \"BLEHF2Service.h\",\n \"BLEHF2Service.cpp\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"weight\": 10,\n \"searchOnly\": true,\n \"icon\": \"./static/packages/bluetooth/icon.png\",\n \"yotta\": {\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"enabled\": 1\n }\n }\n },\n \"optionalConfig\": {\n \"microbit-dal\": {\n \"stack_size\": 1280,\n \"gatt_table_size\": \"0x700\"\n }\n },\n \"userConfigs\": [\n {\n \"description\": \"Disable Bluetooth Event Service\",\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"event_service\": 0\n }\n }\n }\n }\n ]\n }\n}\n",
|
|
2814
2828
|
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Support for additional Bluetooth services.\n */\n //% color=#0082FB weight=96 icon=\"\\uf294\"\ndeclare namespace bluetooth {\n\n /**\n * Starts the Bluetooth accelerometer service\n */\n //% help=bluetooth/start-accelerometer-service\n //% blockId=bluetooth_start_accelerometer_service block=\"bluetooth accelerometer service\"\n //% parts=\"bluetooth\" weight=90 blockGap=8 shim=bluetooth::startAccelerometerService\n function startAccelerometerService(): void;\n\n /**\n * Starts the Bluetooth button service\n */\n //% help=bluetooth/start-button-service\n //% blockId=bluetooth_start_button_service block=\"bluetooth button service\" blockGap=8\n //% parts=\"bluetooth\" weight=89 shim=bluetooth::startButtonService\n function startButtonService(): void;\n\n /**\n * Starts the Bluetooth IO pin service.\n */\n //% help=bluetooth/start-io-pin-service\n //% blockId=bluetooth_start_io_pin_service block=\"bluetooth io pin service\" blockGap=8\n //% parts=\"bluetooth\" weight=88 shim=bluetooth::startIOPinService\n function startIOPinService(): void;\n\n /**\n * Starts the Bluetooth LED service\n */\n //% help=bluetooth/start-led-service\n //% blockId=bluetooth_start_led_service block=\"bluetooth led service\" blockGap=8\n //% parts=\"bluetooth\" weight=87 shim=bluetooth::startLEDService\n function startLEDService(): void;\n\n /**\n * Starts the Bluetooth temperature service\n */\n //% help=bluetooth/start-temperature-service\n //% blockId=bluetooth_start_temperature_service block=\"bluetooth temperature service\" blockGap=8\n //% parts=\"bluetooth\" weight=86 shim=bluetooth::startTemperatureService\n function startTemperatureService(): void;\n\n /**\n * Starts the Bluetooth magnetometer service\n */\n //% help=bluetooth/start-magnetometer-service\n //% blockId=bluetooth_start_magnetometer_service block=\"bluetooth magnetometer service\"\n //% parts=\"bluetooth\" weight=85 shim=bluetooth::startMagnetometerService\n function startMagnetometerService(): void;\n\n /**\n * Starts the Bluetooth UART service\n */\n //% help=bluetooth/start-uart-service\n //% blockId=bluetooth_start_uart_service block=\"bluetooth uart service\"\n //% parts=\"bluetooth\" advanced=true shim=bluetooth::startUartService\n function startUartService(): void;\n\n /**\n * Sends a buffer of data via Bluetooth UART\n */\n //% shim=bluetooth::uartWriteBuffer\n function uartWriteBuffer(buffer: Buffer): void;\n\n /**\n * Reads buffered UART data into a buffer\n */\n //% shim=bluetooth::uartReadBuffer\n function uartReadBuffer(): Buffer;\n\n /**\n * Registers an event to be fired when one of the delimiter is matched.\n * @param delimiters the characters to match received characters against.\n */\n //% help=bluetooth/on-uart-data-received\n //% weight=18 blockId=bluetooth_on_data_received block=\"bluetooth|on data received %delimiters=serial_delimiter_conv\" shim=bluetooth::onUartDataReceived\n function onUartDataReceived(delimiters: string, body: () => void): void;\n\n /**\n * Register code to run when the micro:bit is connected to over Bluetooth\n * @param body Code to run when a Bluetooth connection is established\n */\n //% help=bluetooth/on-bluetooth-connected weight=20\n //% blockId=bluetooth_on_connected block=\"on bluetooth connected\" blockGap=8\n //% parts=\"bluetooth\" shim=bluetooth::onBluetoothConnected\n function onBluetoothConnected(body: () => void): void;\n\n /**\n * Register code to run when a bluetooth connection to the micro:bit is lost\n * @param body Code to run when a Bluetooth connection is lost\n */\n //% help=bluetooth/on-bluetooth-disconnected weight=19\n //% blockId=bluetooth_on_disconnected block=\"on bluetooth disconnected\"\n //% parts=\"bluetooth\" shim=bluetooth::onBluetoothDisconnected\n function onBluetoothDisconnected(body: () => void): void;\n\n /**\n * Advertise an Eddystone URL\n * @param url the url to transmit. Must be no longer than the supported eddystone url length, eg: \"https://makecode.com\"\n * @param power power level between 0 and 7, eg: 7\n * @param connectable true to keep bluetooth connectable for other services, false otherwise.\n */\n //% blockId=eddystone_advertise_url block=\"bluetooth advertise url %url|with power %power|connectable %connectable\"\n //% parts=bluetooth weight=11 blockGap=8\n //% help=bluetooth/advertise-url blockExternalInputs=1\n //% hidden=1 deprecated=1 shim=bluetooth::advertiseUrl\n function advertiseUrl(url: string, power: int32, connectable: boolean): void;\n\n /**\n * Advertise an Eddystone UID\n * @param nsAndInstance 16 bytes buffer of namespace (bytes 0-9) and instance (bytes 10-15)\n * @param power power level between 0 and 7, eg: 7\n * @param connectable true to keep bluetooth connectable for other services, false otherwise.\n */\n //% parts=bluetooth weight=12 advanced=true deprecated=1 shim=bluetooth::advertiseUidBuffer\n function advertiseUidBuffer(nsAndInstance: Buffer, power: int32, connectable: boolean): void;\n\n /**\n * Sets the bluetooth transmit power between 0 (minimal) and 7 (maximum).\n * @param power power level between 0 (minimal) and 7 (maximum), eg: 7.\n */\n //% parts=bluetooth weight=5 help=bluetooth/set-transmit-power advanced=true\n //% blockId=bluetooth_settransmitpower block=\"bluetooth set transmit power %power\" shim=bluetooth::setTransmitPower\n function setTransmitPower(power: int32): void;\n\n /**\n * Stops advertising Eddystone end points\n */\n //% blockId=eddystone_stop_advertising block=\"bluetooth stop advertising\"\n //% parts=bluetooth weight=10\n //% help=bluetooth/stop-advertising advanced=true\n //% hidden=1 deprecated=1 shim=bluetooth::stopAdvertising\n function stopAdvertising(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"
|
|
2815
2829
|
},
|
|
2816
2830
|
"servo": {
|
|
2817
2831
|
"README.md": "# Servo\n\nA small micro-servo library.",
|
|
2818
2832
|
"ns.ts": "/**\n * Control micro servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n}",
|
|
2819
|
-
"pxt.json": "{\n \"name\": \"servo\",\n \"description\": \"A micro-servo library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"servo.ts\",\n \"ns.ts\",\n \"targetoverrides.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2833
|
+
"pxt.json": "{\n \"name\": \"servo\",\n \"description\": \"A micro-servo library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"servo.ts\",\n \"ns.ts\",\n \"targetoverrides.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"icon\": \"/static/libs/servo.png\"\n}\n",
|
|
2820
2834
|
"servo.ts": "/**\n * Control micro servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\" blockGap=8\n//% groups='[\"Positional\", \"Continuous\", \"Configuration\"]'\nnamespace servos {\n //% fixedInstances\n export class Servo {\n private _minAngle: number;\n private _maxAngle: number;\n private _stopOnNeutral: boolean;\n private _angle: number;\n\n constructor() {\n this._angle = undefined;\n this._minAngle = 0;\n this._maxAngle = 180;\n this._stopOnNeutral = false;\n }\n\n private clampDegrees(degrees: number): number {\n degrees = degrees | 0;\n degrees = Math.clamp(this._minAngle, this._maxAngle, degrees);\n return degrees;\n }\n\n /**\n * Set the servo angle\n */\n //% weight=100 help=servos/set-angle\n //% blockId=servoservosetangle block=\"set %servo angle to %degrees=protractorPicker °\"\n //% degrees.defl=90\n //% servo.fieldEditor=\"gridpicker\"\n //% servo.fieldOptions.width=220\n //% servo.fieldOptions.columns=2\n //% blockGap=8\n //% parts=microservo trackArgs=0\n //% group=\"Positional\"\n setAngle(degrees: number) {\n degrees = this.clampDegrees(degrees);\n this.internalSetContinuous(false);\n this._angle = this.internalSetAngle(degrees);\n }\n\n get angle() {\n return this._angle || 90;\n }\n\n protected internalSetContinuous(continuous: boolean): void {\n\n }\n\n protected internalSetAngle(angle: number): number {\n return 0;\n }\n\n /**\n * Set the throttle on a continuous servo\n * @param speed the throttle of the motor from -100% to 100%\n */\n //% weight=99 help=servos/run\n //% blockId=servoservorun block=\"continuous %servo run at %speed=speedPicker \\\\%\"\n //% servo.fieldEditor=\"gridpicker\"\n //% servo.fieldOptions.width=220\n //% servo.fieldOptions.columns=2\n //% parts=microservo trackArgs=0\n //% group=\"Continuous\"\n //% blockGap=8\n run(speed: number): void {\n const degrees = this.clampDegrees(Math.map(speed, -100, 100, this._minAngle, this._maxAngle));\n const neutral = (this.maxAngle - this.minAngle) >> 1;\n this.internalSetContinuous(true);\n if (this._stopOnNeutral && degrees == neutral)\n this.stop();\n else\n this._angle = this.internalSetAngle(degrees);\n }\n\n /**\n * Set the pulse width to the servo in microseconds\n * @param micros the width of the pulse in microseconds\n */\n\n //% weight=10 help=servos/set-pulse\n //% blockId=servoservosetpulse block=\"set %servo pulse to %micros μs\"\n //% micros.min=500 micros.max=2500\n //% micros.defl=1500\n //% servo.fieldEditor=\"gridpicker\"\n //% servo.fieldOptions.width=220\n //% servo.fieldOptions.columns=2\n //% parts=microservo trackArgs=0\n //% group=\"Configuration\"\n //% blockGap=8\n setPulse(micros: number) {\n micros = micros | 0;\n micros = Math.clamp(500, 2500, micros);\n this.internalSetPulse(micros);\n }\n\n protected internalSetPulse(micros: number): void {\n\n }\n\n /**\n * Stop sending commands to the servo so that its rotation will stop at the current position.\n */\n // On a normal servo this will stop the servo where it is, rather than return it to neutral position.\n // It will also not provide any holding force.\n //% weight=10 help=servos/stop\n //% blockId=servoservostop block=\"stop %servo\"\n //% servo.fieldEditor=\"gridpicker\"\n //% servo.fieldOptions.width=220\n //% servo.fieldOptions.columns=2\n //% parts=microservo trackArgs=0\n //% group=\"Continuous\"\n //% blockGap=8\n stop() {\n if (this._angle !== undefined)\n this.internalStop();\n }\n\n /**\n * Gets the minimum angle for the servo\n */\n public get minAngle() {\n return this._minAngle;\n }\n\n /**\n * Gets the maximum angle for the servo\n */\n public get maxAngle() {\n return this._maxAngle;\n }\n\n /**\n * Set the possible rotation range angles for the servo between 0 and 180\n * @param minAngle the minimum angle from 0 to 90\n * @param maxAngle the maximum angle from 90 to 180\n */\n //% help=servos/set-range\n //% blockId=servosetrange block=\"set %servo range from %minAngle to %maxAngle\"\n //% minAngle.min=0 minAngle.max=90\n //% maxAngle.min=90 maxAngle.max=180 maxAngle.defl=180\n //% servo.fieldEditor=\"gridpicker\"\n //% servo.fieldOptions.width=220\n //% servo.fieldOptions.columns=2\n //% parts=microservo trackArgs=0\n //% group=\"Configuration\"\n //% blockGap=8\n public setRange(minAngle: number, maxAngle: number) {\n this._minAngle = Math.max(0, Math.min(90, minAngle | 0));\n this._maxAngle = Math.max(90, Math.min(180, maxAngle | 0));\n }\n\n /**\n * Set a servo stop mode so it will stop when the rotation angle is in the neutral position, 90 degrees.\n * @param on true to enable this mode\n */\n //% help=servos/set-stop-on-neutral\n //% blockId=servostoponneutral block=\"set %servo stop on neutral %enabled\"\n //% enabled.shadow=toggleOnOff\n //% group=\"Configuration\"\n //% blockGap=8\n //% servo.fieldEditor=\"gridpicker\"\n //% servo.fieldOptions.width=220\n //% servo.fieldOptions.columns=2\n public setStopOnNeutral(enabled: boolean) {\n this._stopOnNeutral = enabled;\n }\n\n protected internalStop() { }\n }\n\n export class PinServo extends Servo {\n private _pin: PwmOnlyPin;\n\n constructor(pin: PwmOnlyPin) {\n super();\n this._pin = pin;\n }\n\n protected internalSetAngle(angle: number): number {\n this._pin.servoWrite(angle);\n return angle;\n }\n\n protected internalSetContinuous(continuous: boolean): void {\n this._pin.servoSetContinuous(continuous);\n }\n\n protected internalSetPulse(micros: number): void {\n this._pin.servoSetPulse(micros);\n }\n\n protected internalStop() {\n this._pin.digitalRead();\n this._pin.setPull(PinPullMode.PullNone);\n }\n }\n}\n",
|
|
2821
2835
|
"targetoverrides.ts": "namespace servos {\n //% block=\"servo P0\" fixedInstance whenUsed\n export const P0 = new servos.PinServo(pins.P0);\n //% block=\"servo P1\" fixedInstance whenUsed\n export const P1 = new servos.PinServo(pins.P1);\n //% block=\"servo P2\" fixedInstance whenUsed\n export const P2 = new servos.PinServo(pins.P2);\n}"
|
|
2822
2836
|
},
|
|
2823
2837
|
"radio-broadcast": {
|
|
2824
|
-
"pxt.json": "{\n \"name\": \"radio-broadcast\",\n \"description\": \"Adds new blocks for message communication in the radio category\",\n \"dependencies\": {\n \"core\": \"*\",\n \"radio\": \"*\"\n },\n \"files\": [\n \"radio-broadcast.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2838
|
+
"pxt.json": "{\n \"name\": \"radio-broadcast\",\n \"description\": \"Adds new blocks for message communication in the radio category\",\n \"dependencies\": {\n \"core\": \"*\",\n \"radio\": \"*\"\n },\n \"files\": [\n \"radio-broadcast.ts\"\n ],\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"icon\": \"/static/libs/radio-broadcast.png\"\n}\n",
|
|
2825
2839
|
"radio-broadcast.ts": "namespace radio {\n const BROADCAST_GENERAL_ID = 2000;\n\n /**\n * Gets the message code\n */\n //% blockHidden=1 shim=ENUM_GET\n //% blockId=radioMessageCode block=\"$msg\" enumInitialMembers=\"message1\"\n //% enumName=RadioMessage enumMemberName=msg enumPromptHint=\"e.g. Start, Stop, Jump...\"\n //% enumIsHash=1\n export function __message(msg: number): number {\n return msg;\n }\n\n /**\n * Broadcasts a message over radio\n * @param msg \n */\n //% blockId=radioBroadcastMessage block=\"radio send $msg\"\n //% msg.shadow=radioMessageCode draggableParameters\n //% weight=200\n //% blockGap=8\n //% help=radio/send-message\n //% group=\"Broadcast\"\n export function sendMessage(msg: number): void {\n // 0 is MICROBIT_EVT_ANY, shifting by 1\n radio.raiseEvent(BROADCAST_GENERAL_ID, msg + 1);\n }\n\n /**\n * Registers code to run for a particular message\n * @param msg \n * @param handler \n */\n //% blockId=radioOnMessageReceived block=\"on radio $msg received\"\n //% msg.shadow=radioMessageCode draggableParameters\n //% weight=199\n //% help=radio/on-received-message\n //% group=\"Broadcast\"\n export function onReceivedMessage(msg: number, handler: () => void) {\n control.onEvent(BROADCAST_GENERAL_ID, msg + 1, handler);\n }\n}"
|
|
2826
2840
|
},
|
|
2827
2841
|
"microphone": {
|
|
@@ -2829,7 +2843,7 @@ var pxtTargetBundle = {
|
|
|
2829
2843
|
"enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum DetectedSound {\n //% block=\"loud\"\n Loud = 2,\n //% block=\"quiet\"\n Quiet = 1,\n }\n\n\n declare const enum SoundThreshold {\n //% block=\"loud\"\n Loud = 2,\n //% block=\"quiet\"\n Quiet = 1,\n }\n\n// Auto-generated. Do not edit. Really.\n",
|
|
2830
2844
|
"microphone.cpp": "#include \"pxt.h\"\n\n#if MICROBIT_CODAL\n#include \"LevelDetector.h\"\n#include \"LevelDetectorSPL.h\"\n#endif\n\n#define MICROPHONE_MIN 52.0f\n#define MICROPHONE_MAX 120.0f\n\nenum class DetectedSound {\n //% block=\"loud\"\n Loud = 2,\n //% block=\"quiet\"\n Quiet = 1\n};\n\nenum class SoundThreshold {\n //% block=\"loud\"\n Loud = 2,\n //% block=\"quiet\"\n Quiet = 1\n};\n\nnamespace pxt {\n#if MICROBIT_CODAL\n codal::LevelDetectorSPL* getMicrophoneLevel();\n#endif\n}\n\nnamespace input {\n\n/**\n* Registers an event that runs when a sound is detected\n*/\n//% help=input/on-sound\n//% blockId=input_on_sound block=\"on %sound sound\"\n//% parts=\"microphone\"\n//% weight=88 blockGap=12\n//% group=\"micro:bit (V2)\"\nvoid onSound(DetectedSound sound, Action handler) {\n#if MICROBIT_CODAL\n pxt::getMicrophoneLevel(); // wake up service\n const auto thresholdType = sound == DetectedSound::Loud ? LEVEL_THRESHOLD_HIGH : LEVEL_THRESHOLD_LOW;\n registerWithDal(DEVICE_ID_MICROPHONE, thresholdType, handler);\n#else\n target_panic(PANIC_VARIANT_NOT_SUPPORTED);\n#endif\n}\n\n/**\n* Reads the loudness through the microphone from 0 (silent) to 255 (loud)\n*/\n//% help=input/sound-level\n//% blockId=device_get_sound_level block=\"sound level\"\n//% parts=\"microphone\"\n//% weight=34 blockGap=8\n//% group=\"micro:bit (V2)\"\nint soundLevel() {\n#if MICROBIT_CODAL\n auto level = pxt::getMicrophoneLevel();\n if (NULL == level)\n return 0;\n const int micValue = level->getValue();\n const int scaled = max(MICROPHONE_MIN, min(micValue, MICROPHONE_MAX)) - MICROPHONE_MIN;\n return min(0xff, scaled * 0xff / (MICROPHONE_MAX - MICROPHONE_MIN));\n#else\n target_panic(PANIC_VARIANT_NOT_SUPPORTED);\n return 0;\n#endif\n}\n\n/**\n* Sets the threshold for a sound type.\n*/\n//% help=input/set-sound-threshold\n//% blockId=input_set_sound_threshold block=\"set %sound sound threshold to %value\"\n//% parts=\"microphone\"\n//% threshold.min=0 threshold.max=255 threshold.defl=128\n//% weight=14 blockGap=8\n//% advanced=true\n//% group=\"micro:bit (V2)\"\nvoid setSoundThreshold(SoundThreshold sound, int threshold) {\n#if MICROBIT_CODAL\n auto level = pxt::getMicrophoneLevel();\n if (NULL == level)\n return;\n\n threshold = max(0, min(0xff, threshold));\n const int scaled = MICROPHONE_MIN + threshold * (MICROPHONE_MAX - MICROPHONE_MIN) / 0xff;\n if (SoundThreshold::Loud == sound)\n level->setHighThreshold(scaled);\n else\n level->setLowThreshold(scaled);\n#else\n target_panic(PANIC_VARIANT_NOT_SUPPORTED);\n#endif\n}\n}",
|
|
2831
2845
|
"microphonehw.cpp": "// The fallback logic below still requires level detection.\n// It's only kept with a view to syncing with the common-packages in future.\n\n#include \"pxt.h\"\n\n#if MICROBIT_CODAL\n#include \"LevelDetector.h\"\n#include \"LevelDetectorSPL.h\"\n#include \"DataStream.h\"\n\n#ifndef MIC_DEVICE\n// STM?\nclass DummyDataSource : public codal::DataSource {\n public:\n DummyDataSource() {}\n};\nclass PanicPDM {\n public:\n uint8_t level;\n DummyDataSource source;\n codal::DataStream output;\n\n PanicPDM(Pin &sd, Pin &sck) : output(source) { target_panic(PANIC_MICROPHONE_MISSING); }\n void enable() {}\n void disable() {}\n};\n#define MIC_DEVICE PanicPDM\n#endif\n\n#ifndef MIC_INIT\n#define MIC_INIT \\\n : microphone(*LOOKUP_PIN(MIC_DATA), *LOOKUP_PIN(MIC_CLOCK)) \\\n , level(microphone.output, 95.0, 75.0, 9, 52, DEVICE_ID_MICROPHONE)\n#endif\n\n#ifndef MIC_ENABLE\n#define MIC_ENABLE microphone.enable()\n#endif\n\nnamespace pxt {\n\nclass WMicrophone {\n public:\n MIC_DEVICE microphone;\n LevelDetectorSPL level;\n WMicrophone() MIC_INIT { MIC_ENABLE; }\n};\nSINGLETON(WMicrophone);\n\ncodal::LevelDetectorSPL *getMicrophoneLevel() {\n auto wmic = getWMicrophone();\n return wmic ? &(wmic->level) : NULL;\n}\n\n} // namespace pxt\n#endif",
|
|
2832
|
-
"pxt.json": "{\n \"name\": \"microphone\",\n \"description\": \"The microphone library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"microphone.cpp\",\n \"microphonehw.cpp\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"targetoverrides.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2846
|
+
"pxt.json": "{\n \"name\": \"microphone\",\n \"description\": \"The microphone library\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"microphone.cpp\",\n \"microphonehw.cpp\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"targetoverrides.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"icon\": \"/static/libs/microphone.png\"\n}\n",
|
|
2833
2847
|
"shims.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace input {\n\n /**\n * Registers an event that runs when a sound is detected\n */\n //% help=input/on-sound\n //% blockId=input_on_sound block=\"on %sound sound\"\n //% parts=\"microphone\"\n //% weight=88 blockGap=12\n //% group=\"micro:bit (V2)\" shim=input::onSound\n function onSound(sound: DetectedSound, handler: () => void): void;\n\n /**\n * Reads the loudness through the microphone from 0 (silent) to 255 (loud)\n */\n //% help=input/sound-level\n //% blockId=device_get_sound_level block=\"sound level\"\n //% parts=\"microphone\"\n //% weight=34 blockGap=8\n //% group=\"micro:bit (V2)\" shim=input::soundLevel\n function soundLevel(): int32;\n\n /**\n * Sets the threshold for a sound type.\n */\n //% help=input/set-sound-threshold\n //% blockId=input_set_sound_threshold block=\"set %sound sound threshold to %value\"\n //% parts=\"microphone\"\n //% threshold.min=0 threshold.max=255\n //% weight=14 blockGap=8\n //% advanced=true\n //% group=\"micro:bit (V2)\" threshold.defl=128 shim=input::setSoundThreshold\n function setSoundThreshold(sound: SoundThreshold, threshold?: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n",
|
|
2834
2848
|
"targetoverrides.ts": "// target specific code",
|
|
2835
2849
|
"test.ts": "// tests"
|
|
@@ -2843,7 +2857,7 @@ var pxtTargetBundle = {
|
|
|
2843
2857
|
"RP2040Flash.cpp": "#include \"pxt.h\"\n#include \"Flash.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\n#ifdef PICO_BOARD\n#include \"hardware/flash.h\"\n\n#define XIP_BIAS 0x10000000\n\nnamespace codal {\n\nint ZFlash::pageSize(uintptr_t address) {\n return FLASH_SECTOR_SIZE;\n}\n\nint ZFlash::totalSize() {\n#ifndef PICO_FLASH_SIZE_BYTES\n return 2*1024*1024;\n#else\n return PICO_FLASH_SIZE_BYTES;\n#endif\n}\n\nint ZFlash::erasePage(uintptr_t address) {\n // address should be aligned to 4096\n if (address % 4096 == 0){\n target_disable_irq();\n flash_range_erase(address - XIP_BIAS, FLASH_SECTOR_SIZE); \n target_enable_irq();\n }\n return 0;\n}\n\nint ZFlash::writeBytes(uintptr_t dst, const void *src, uint32_t len) {\n if (len != FLASH_PAGE_SIZE || (dst & (FLASH_PAGE_SIZE - 1))) return -1;\n // should be aligned to 256\n target_disable_irq();\n flash_range_program(dst - XIP_BIAS, (const uint8_t*)src, FLASH_PAGE_SIZE);\n target_enable_irq();\n \n return 0;\n}\n\n\n\n\n}\n\n#endif\n",
|
|
2844
2858
|
"SAMDFlash.cpp": "#include \"pxt.h\"\n#include \"Flash.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\n#if defined(SAMD51) || defined(SAMD21)\nnamespace codal {\n\n#ifdef SAMD51\n#define waitForLast() \\\n while (NVMCTRL->STATUS.bit.READY == 0) \\\n ;\n#else\n#define waitForLast() \\\n while (NVMCTRL->INTFLAG.bit.READY == 0) \\\n ;\n#endif\n\nstatic void unlock() {\n#ifdef SAMD51\n // see errata 2.14.1\n NVMCTRL->CTRLA.bit.CACHEDIS0 = true;\n NVMCTRL->CTRLA.bit.CACHEDIS1 = true;\n\n CMCC->CTRL.bit.CEN = 0;\n while (CMCC->SR.bit.CSTS) {\n }\n CMCC->MAINT0.bit.INVALL = 1;\n#endif\n}\n\nstatic void lock() {\n#ifdef SAMD51\n // re-enable cache\n NVMCTRL->CTRLA.bit.CACHEDIS0 = false;\n NVMCTRL->CTRLA.bit.CACHEDIS1 = false;\n\n // re-enable cortex-m cache - it's a separate one\n CMCC->CTRL.bit.CEN = 0;\n while (CMCC->SR.bit.CSTS) {\n }\n CMCC->MAINT0.bit.INVALL = 1;\n CMCC->CTRL.bit.CEN = 1;\n#endif\n}\n\nint ZFlash::totalSize() {\n return (8 << NVMCTRL->PARAM.bit.PSZ) * NVMCTRL->PARAM.bit.NVMP;\n}\n\n// this returns the size of \"page\" that can be erased (\"row\" in datasheet)\nint ZFlash::pageSize(uintptr_t address) {\n#ifdef SAMD51\n if (address < (uintptr_t)totalSize())\n return NVMCTRL_BLOCK_SIZE; // 8k\n#else\n if (address < (uintptr_t)totalSize())\n return 256;\n#endif\n target_panic(DEVICE_FLASH_ERROR);\n return 0;\n}\n\n#ifdef SAMD51\n#define CMD(D21, D51) NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | D51\n#else\n#define CMD(D21, D51) NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | D21\n#endif\n\nint ZFlash::erasePage(uintptr_t address) {\n LOG(\"Erase %x\", address);\n#ifdef SAMD51\n NVMCTRL->CTRLA.bit.WMODE = NVMCTRL_CTRLA_WMODE_MAN_Val;\n#else\n NVMCTRL->CTRLB.bit.MANW = 1;\n#endif\n waitForLast();\n unlock();\n#ifdef SAMD51\n NVMCTRL->ADDR.reg = address;\n#else\n // yeah... /2\n NVMCTRL->ADDR.reg = address / 2;\n#endif\n CMD(NVMCTRL_CTRLA_CMD_ER, NVMCTRL_CTRLB_CMD_EB);\n waitForLast();\n lock();\n return 0;\n}\n\n#if 0\n#define CHECK_ECC() \\\n if (NVMCTRL->INTFLAG.bit.ECCSE || NVMCTRL->INTFLAG.bit.ECCDE) \\\n return -10\n#else\n#define CHECK_ECC() ((void)0)\n#endif\n\nint ZFlash::writeBytes(uintptr_t dst, const void *src, uint32_t len) {\n#ifdef SAMD51\n CHECK_ECC();\n\n // only allow writing double word at a time\n if (len & 7)\n return -1;\n if (dst & 7)\n return -2;\n\n // every double-word can only be written once, otherwise we get ECC errors\n // and no, ECC cannot be disabled\n for (unsigned i = 0; i < (len >> 3); ++i)\n if (((uint64_t *)dst)[i] != 0xffffffffffffffff &&\n ((uint64_t *)src)[i] != 0xffffffffffffffff)\n return -3;\n#define WRITE_SIZE 16\n#else\n if ((dst & 3) || (len & 3))\n return -1;\n\n for (unsigned i = 0; i < len; ++i)\n if (((uint8_t *)dst)[i] != 0xff && ((uint8_t *)src)[i] != 0xff)\n return -3;\n#define WRITE_SIZE 64\n#endif\n\n uint32_t writeBuf[WRITE_SIZE >> 2];\n uint32_t idx = 0;\n\n waitForLast();\n unlock();\n __DMB();\n\n while (idx < len) {\n uint32_t off = dst & (WRITE_SIZE - 1);\n uint32_t n = WRITE_SIZE - off;\n if (n > len - idx)\n n = len - idx;\n uint32_t *sp;\n volatile uint32_t *dp;\n if (n != WRITE_SIZE) {\n memset(writeBuf, 0xff, WRITE_SIZE);\n memcpy((uint8_t *)writeBuf + off, src, n);\n sp = writeBuf;\n dp = (uint32_t *)(dst - off);\n } else {\n sp = (uint32_t *)src;\n dp = (uint32_t *)dst;\n }\n\n bool need = false;\n for (unsigned i = 0; i < (WRITE_SIZE >> 2); ++i)\n if (sp[i] != 0xffffffff) {\n need = true;\n break;\n }\n\n if (need) {\n CMD(NVMCTRL_CTRLA_CMD_PBC, NVMCTRL_CTRLB_CMD_PBC);\n waitForLast();\n\n uint32_t q = WRITE_SIZE >> 2;\n\n target_disable_irq();\n while (q--) {\n auto v = *sp++;\n *dp = v;\n dp++;\n }\n\n CMD(NVMCTRL_CTRLA_CMD_WP, NVMCTRL_CTRLB_CMD_WQW);\n target_enable_irq();\n waitForLast();\n }\n\n src = (uint8_t *)src + n;\n dst += n;\n idx += n;\n }\n\n CHECK_ECC();\n\n lock();\n\n return 0;\n}\n} // namespace codal\n#endif\n",
|
|
2845
2859
|
"STM32Flash.cpp": "#include \"pxt.h\"\n#include \"Flash.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\n#ifdef STM32F4\nnamespace codal {\nstatic void waitForLast() {\n while ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)\n ;\n}\n\nstatic void unlock() {\n FLASH->CR |= FLASH_CR_LOCK;\n FLASH->KEYR = FLASH_KEY1;\n FLASH->KEYR = FLASH_KEY2;\n}\n\nstatic void lock() {\n FLASH->CR |= FLASH_CR_LOCK;\n}\n\nint ZFlash::pageSize(uintptr_t address) {\n address |= 0x08000000;\n if (address < 0x08010000)\n return 16 * 1024;\n if (address < 0x08020000)\n return 64 * 1024;\n if (address < 0x08100000)\n return 128 * 1024;\n target_panic(DEVICE_FLASH_ERROR);\n return 0;\n}\n\nint ZFlash::totalSize() {\n return *((uint16_t *)0x1FFF7A22) * 1024;\n}\n\nint ZFlash::erasePage(uintptr_t address) {\n waitForLast();\n unlock();\n\n address |= 0x08000000;\n uintptr_t ptr = 0x08000000;\n int sectNum = 0;\n while (1) {\n ptr += pageSize(ptr);\n if (ptr > address)\n break;\n sectNum++;\n }\n\n FLASH->CR = FLASH_CR_PSIZE_1 | (sectNum << FLASH_CR_SNB_Pos) | FLASH_CR_SER;\n FLASH->CR |= FLASH_CR_STRT;\n\n waitForLast();\n\n FLASH->CR = FLASH_CR_PSIZE_1;\n lock();\n\n // cache flushing only required after erase, not programming (3.5.4)\n __HAL_FLASH_DATA_CACHE_DISABLE();\n __HAL_FLASH_DATA_CACHE_RESET();\n __HAL_FLASH_DATA_CACHE_ENABLE();\n\n // we skip instruction cache, as we're not expecting to erase that\n\n return 0;\n}\n\nint ZFlash::writeBytes(uintptr_t dst, const void *src, uint32_t len) {\n LOG(\"WR flash at %p len=%d\", (void *)dst, len);\n\n if ((dst & 3) || ((uintptr_t)src & 3) || (len & 3))\n return -1;\n\n for (unsigned i = 0; i < len; ++i)\n if (((uint8_t *)dst)[i] != 0xff && ((uint8_t *)src)[i] != 0xff)\n return -3;\n\n waitForLast();\n unlock();\n\n dst |= 0x08000000;\n\n FLASH->CR = FLASH_CR_PSIZE_1 | FLASH_CR_PG;\n\n volatile uint32_t *sp = (uint32_t *)src;\n volatile uint32_t *dp = (uint32_t *)dst;\n len >>= 2;\n\n while (len-- > 0) {\n uint32_t v = *sp++;\n if (v != 0xffffffff) {\n *dp++ = v;\n waitForLast();\n } else {\n dp++;\n }\n }\n\n FLASH->CR = FLASH_CR_PSIZE_1;\n lock();\n\n LOG(\"WR flash OK\");\n\n return 0;\n}\n} // namespace codal\n#endif\n",
|
|
2846
|
-
"pxt.json": "{\n \"name\": \"settings\",\n \"description\": \"Settings storage in internal flash\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"RAFFS.cpp\",\n \"RAFFS.h\",\n \"Flash.h\",\n \"STM32Flash.cpp\",\n \"SAMDFlash.cpp\",\n \"NRF52Flash.cpp\",\n \"RP2040Flash.cpp\",\n \"settings.cpp\",\n \"settings.ts\",\n \"shims.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2860
|
+
"pxt.json": "{\n \"name\": \"settings\",\n \"description\": \"Settings storage in internal flash\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"RAFFS.cpp\",\n \"RAFFS.h\",\n \"Flash.h\",\n \"STM32Flash.cpp\",\n \"SAMDFlash.cpp\",\n \"NRF52Flash.cpp\",\n \"RP2040Flash.cpp\",\n \"settings.cpp\",\n \"settings.ts\",\n \"shims.d.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"hidden\": true,\n \"disablesVariants\": [\n \"mbdal\"\n ]\n}\n",
|
|
2847
2861
|
"settings.cpp": "\n#include \"pxt.h\"\n#include \"RAFFS.h\"\n#include \"GhostFAT.h\"\n\nusing namespace pxt::raffs;\nusing namespace codal;\n\nnamespace settings {\n\n#if defined(SAMD21)\n#define SETTINGS_SIZE (2 * 1024)\n#else\n#define SETTINGS_SIZE (32 * 1024)\n#endif\n\nclass WStorage {\n public:\n CODAL_FLASH flash;\n FS fs;\n bool isMounted;\n\n WStorage()\n : flash(),\n#if defined(STM32F4)\n fs(flash, 0x8008000, SETTINGS_SIZE),\n#elif defined(SAMD51)\n fs(flash, 512 * 1024 - SETTINGS_SIZE, SETTINGS_SIZE),\n#elif defined(SAMD21)\n fs(flash, 256 * 1024 - SETTINGS_SIZE, SETTINGS_SIZE),\n#elif defined(NRF52_SERIES)\n#define NRF_BOOTLOADER_START *(uint32_t *)0x10001014\n fs(flash,\n 128 * 1024 < NRF_BOOTLOADER_START && NRF_BOOTLOADER_START < (uint32_t)flash.totalSize()\n ? NRF_BOOTLOADER_START - SETTINGS_SIZE\n : flash.totalSize() - SETTINGS_SIZE,\n SETTINGS_SIZE),\n#elif defined(PICO_BOARD)\n // XIP bias 0x10000000\n fs(flash, 0x10000000 + flash.totalSize() - SETTINGS_SIZE, SETTINGS_SIZE),\n#else\n fs(flash),\n#endif\n isMounted(false) {\n fs.minGCSpacing = 10000;\n }\n};\nSINGLETON(WStorage);\n\nstatic WStorage *mountedStorage() {\n auto s = getWStorage();\n if (s->fs.tryMount())\n return s;\n s->fs.exists(\"foobar\"); // forces mount and possibly format\n return s;\n}\n\n// large store is area for storing large binary objects, eg ML models\n// it may be already occupied by the user program, in which case largeStoreStart() will return 0\nsize_t largeStoreSize() {\n#if defined(SAMD21)\n return 64 * 1024;\n#else\n return 128 * 1024;\n#endif\n}\n\nuintptr_t largeStoreStart() {\n auto s = getWStorage();\n uintptr_t r;\n#if defined(STM32F4)\n r = 0x08000000 + s->flash.totalSize() - largeStoreSize();\n#else\n r = s->fs.baseAddr - s->fs.bytes - largeStoreSize();\n#endif\n\n if (r < afterProgramPage())\n return 0;\n\n return r;\n}\n\nCODAL_FLASH *largeStoreFlash() {\n return &getWStorage()->flash;\n}\n\n//%\nint _set(String key, Buffer data) {\n auto s = mountedStorage();\n return s->fs.write(key->getUTF8Data(), data->data, data->length);\n}\n\n//%\nint _remove(String key) {\n auto s = mountedStorage();\n return s->fs.remove(key->getUTF8Data());\n}\n\n//%\nbool _exists(String key) {\n auto s = mountedStorage();\n return s->fs.exists(key->getUTF8Data());\n}\n\n//%\nBuffer _get(String key) {\n auto s = mountedStorage();\n auto sz = s->fs.read(key->getUTF8Data(), NULL, 0);\n if (sz < 0)\n return NULL;\n auto ret = mkBuffer(NULL, sz);\n registerGCObj(ret);\n s->fs.read(NULL, ret->data, ret->length);\n unregisterGCObj(ret);\n return ret;\n}\n\nstatic bool isSystem(const char *fn) {\n return fn[0] == '#';\n}\n\n//%\nvoid _userClean() {\n auto s = mountedStorage();\n DMESG(\"clearing user files\");\n s->fs.forceGC(isSystem);\n // if system files take more than 25% of storage size, we reformat\n // it likely means user code has written some 'system' files\n if (s->fs.freeSize() < 3 * s->fs.totalSize() / 4) {\n s->fs.format();\n }\n}\n\n//%\nRefCollection *_list(String prefix) {\n auto st = mountedStorage();\n st->fs.dirRewind();\n auto res = Array_::mk();\n registerGCObj(res);\n\n auto prefData = prefix->getUTF8Data();\n auto prefLen = prefix->getUTF8Size();\n auto wantsInternal = prefData[0] == '#';\n\n for (;;) {\n auto d = st->fs.dirRead();\n if (!d)\n break;\n if (!wantsInternal && d->name[0] == '#')\n continue;\n if (memcmp(d->name, prefData, prefLen) != 0)\n continue;\n auto str = mkString(d->name, -1);\n registerGCObj(str);\n res->head.push((TValue)str);\n unregisterGCObj(str);\n }\n unregisterGCObj(res);\n return res;\n}\n\n} // namespace settings\n",
|
|
2848
2862
|
"settings.ts": "namespace settings {\n const RUN_KEY = \"#run\";\n const SCOPE_KEY = \"#scope\";\n const DEVICE_SECRETS_KEY = \"#secrets\";\n const SECRETS_KEY = \"__secrets\";\n\n //% shim=pxt::seedAddRandom\n declare function seedAddRandom(n: number): void;\n\n //% shim=settings::_set\n declare function _set(key: string, data: Buffer): int32;\n\n //% shim=settings::_remove\n declare function _remove(key: string): int32;\n\n //% shim=settings::_exists\n declare function _exists(key: string): boolean;\n\n //% shim=settings::_get\n declare function _get(key: string): Buffer;\n\n //% shim=settings::_userClean\n declare function _userClean(): void;\n\n //% shim=settings::_list\n declare function _list(prefix: string): string[];\n\n export function runNumber() {\n return readNumber(RUN_KEY) || 0\n }\n\n function setScope(scope: string) {\n if (!scope || scope.length > 100)\n control.panic(922)\n const currScope = readString(SCOPE_KEY)\n if (currScope != scope) {\n _userClean()\n writeString(SCOPE_KEY, scope)\n }\n }\n\n function initScopes() {\n const rn = runNumber() + 1\n writeNumber(RUN_KEY, rn)\n\n seedAddRandom(control.deviceSerialNumber() & 0x7fffffff)\n seedAddRandom(rn)\n\n setScope(control.programName())\n }\n\n initScopes()\n\n /** \n * Delete all non-system settings.\n */\n export function clear(): void {\n _userClean()\n }\n\n /**\n * Set named setting to a given buffer.\n */\n export function writeBuffer(key: string, value: Buffer) {\n if (_set(key, value)) {\n // if we're out of space, clear user storage\n _userClean()\n // and panic - reset should hopefully recreate needed files\n control.panic(920)\n }\n }\n\n /**\n * Set named settings to a given string.\n */\n export function writeString(key: string, value: string) {\n writeBuffer(key, control.createBufferFromUTF8(value))\n }\n\n /**\n * Set named settings to a given JSON object.\n */\n export function writeJSON(key: string, value: any) {\n writeString(key, JSON.stringify(value))\n }\n\n /**\n * Set named settings to a given number.\n */\n export function writeNumber(key: string, value: number) {\n writeBuffer(key, msgpack.packNumberArray([value]))\n }\n\n /**\n * Set named settings to a given array of numbers.\n */\n export function writeNumberArray(key: string, value: number[]) {\n writeBuffer(key, msgpack.packNumberArray(value))\n }\n\n /**\n * Read named setting as a buffer. Returns undefined when setting not found.\n */\n export function readBuffer(key: string) {\n return _get(key)\n }\n\n /**\n * Read named setting as a string.\n */\n export function readString(key: string) {\n const buf = readBuffer(key)\n if (!buf)\n return undefined\n else\n return buf.toString()\n }\n\n /**\n * Read named setting as a JSON object.\n */\n export function readJSON(key: string) {\n const s = readString(key)\n if (s)\n return JSON.parse(s)\n return undefined\n }\n\n /**\n * Read named setting as a number.\n */\n export function readNumber(key: string) {\n const buf = readBuffer(key)\n if (!buf)\n return undefined\n else {\n const nums = msgpack.unpackNumberArray(buf)\n if (nums && nums.length >= 1)\n return nums[0]\n return undefined\n }\n }\n\n /**\n * Read named setting as a number.\n */\n export function readNumberArray(key: string) {\n const buf = readBuffer(key)\n if (!buf)\n return undefined\n else\n return msgpack.unpackNumberArray(buf)\n }\n\n /**\n * Return a list of settings starting with a given prefix.\n */\n export function list(prefix?: string) {\n if (!prefix) prefix = \"\"\n return _list(prefix)\n }\n\n /**\n * Remove named setting.\n */\n export function remove(key: string) {\n _remove(key)\n }\n\n /**\n * Check if a named setting exists.\n */\n export function exists(key: string) {\n return _exists(key)\n }\n\n function clone(v: any): any {\n if (v == null) return null\n return JSON.parse(JSON.stringify(v))\n }\n\n function isKV(v: any) {\n return !!v && typeof v === \"object\" && !Array.isArray(v)\n }\n\n function jsonMergeFrom(trg: any, src: any) {\n if (!src) return;\n const keys = Object.keys(src)\n keys.forEach(k => {\n const srck = src[k];\n if (isKV(trg[k]) && isKV(srck))\n jsonMergeFrom(trg[k], srck);\n else\n trg[k] = clone(srck);\n });\n }\n\n //% fixedInstances\n export class SecretStore {\n constructor(private key: string) { }\n\n setSecret(name: string, value: any) {\n const secrets = this.readSecrets();\n secrets[name] = value;\n writeJSON(this.key, secrets);\n }\n\n updateSecret(name: string, value: any) {\n const secrets = this.readSecrets();\n const secret = secrets[name];\n if (secret === undefined)\n secrets[name] = value;\n else jsonMergeFrom(secret, value);\n writeJSON(this.key, secrets)\n }\n\n readSecret(name: string, ensure: boolean = false): any {\n const secrets = this.readSecrets();\n const secret = secrets[name];\n if (ensure && !secret)\n throw \"missing secret \" + name;\n return secret;\n }\n\n clearSecrets() {\n writeString(this.key, \"{}\");\n }\n\n readSecrets(): any {\n try {\n return readJSON(this.key) || {}\n } catch {\n control.dmesg(\"invalid secret format\")\n return {};\n }\n }\n }\n\n /**\n * Secrets shared by any program on the device\n */\n //% fixedInstance whenUsed block=\"device secrets\"\n export const deviceSecrets = new SecretStore(DEVICE_SECRETS_KEY);\n\n /**\n * Program secrets\n */\n //% fixedInstance whenUsed block=\"program secrets\"\n export const programSecrets = new SecretStore(SECRETS_KEY);\n}\n",
|
|
2849
2863
|
"shims.d.ts": "\n"
|
|
@@ -2852,19 +2866,19 @@ var pxtTargetBundle = {
|
|
|
2852
2866
|
"README.md": "# datalog\n",
|
|
2853
2867
|
"enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare const enum FlashLogTimeStampFormat\n {\n //% block=\"none\"\n None = 0,\n //% block=\"milliseconds\"\n Milliseconds = 1,\n //% block=\"seconds\"\n Seconds = 10,\n //% block=\"minutes\"\n Minutes = 600,\n //% block=\"hours\"\n Hours = 36000,\n //% block=\"days\"\n Days = 864000,\n }\ndeclare namespace flashlog {\n}\n\n// Auto-generated. Do not edit. Really.\n",
|
|
2854
2868
|
"flashlog.cpp": "#include \"pxt.h\"\n\n#if MICROBIT_CODAL\n#include \"MicroBitLog.h\"\n#endif\n\nenum class FlashLogTimeStampFormat\n{\n //% block=\"none\"\n None = 0,\n //% block=\"milliseconds\"\n Milliseconds = 1,\n //% block=\"seconds\"\n Seconds = 10,\n //% block=\"minutes\"\n Minutes = 600,\n //% block=\"hours\"\n Hours = 36000,\n //% block=\"days\"\n Days = 864000\n};\n\n/**\n * Storing structured data in flash.\n */\n//%\nnamespace flashlog {\n\n/**\n* Creates a new row in the log, ready to be populated by logData()\n**/\n//% help=flashlog/begin-row\n//% parts=\"flashlog\"\n//% blockGap=8\n//% group=\"micro:bit (V2)\"\nint beginRow() {\n#if MICROBIT_CODAL\n return uBit.log.beginRow();\n#else\n return DEVICE_NOT_SUPPORTED;\n#endif\n}\n\n/**\n* Populates the current row with the given key/value pair.\n**/\n//% help=flashlog/log-data\n//% parts=\"flashlog\"\n//% blockGap=8\n//% group=\"micro:bit (V2)\"\nint logData(String key, String value) {\n if (NULL == key || NULL == value)\n return DEVICE_INVALID_PARAMETER;\n#if MICROBIT_CODAL\n return uBit.log.logData(MSTR(key), MSTR(value));\n#else\n return DEVICE_NOT_SUPPORTED;\n#endif\n}\n\n/**\n* Inject the given row into the log as text, ignoring key/value pairs.\n**/\n//% help=flashlog/log-string\n//% parts=\"flashlog\"\n//% blockGap=8\n//% group=\"micro:bit (V2)\"\nint logString(String value) {\n if (NULL == value)\n return DEVICE_INVALID_PARAMETER;\n#if MICROBIT_CODAL\n return uBit.log.logString(MSTR(value));\n#else\n return DEVICE_NOT_SUPPORTED;\n#endif\n}\n\n/**\n* Complete a row in the log, and pushes to persistent storage.\n**/\n//% help=flashlog/end-row\n//% parts=\"flashlog\"\n//% blockGap=8\n//% group=\"micro:bit (V2)\"\nint endRow() {\n#if MICROBIT_CODAL\n return uBit.log.endRow();\n#else\n return DEVICE_NOT_SUPPORTED;\n#endif\n}\n\n/**\n* Resets all data stored in persistent storage.\n**/\n//% help=flashlog/clear\n//% parts=\"flashlog\"\n//% blockGap=8\n//% group=\"micro:bit (V2)\"\nvoid clear(bool fullErase) {\n#if MICROBIT_CODAL\n uBit.log.clear(fullErase);\n#endif\n}\n\n/**\n* Determines the format of the timestamp data to be added (if any).\n* If requested, time stamps will be automatically added to each row of data\n* as an integer value rounded down to the unit specified.\n*\n* @param format The format of timestamp to use.\n*/\n//% help=flashlog/set-timestamp\n//% parts=\"flashlog\"\n//% blockGap=8\n//% group=\"micro:bit (V2)\"\nvoid setTimeStamp(FlashLogTimeStampFormat format) {\n#if MICROBIT_CODAL\n return uBit.log.setTimeStamp((codal::TimeStampFormat)format);\n#endif\n}\n\n/**\n * Defines if data logging should also be streamed over the serial port.\n *\n * @param enable True to enable serial port streaming, false to disable.\n*/\n//% help=flashlog/set-serial-mirroring\n//% parts=\"flashlog\"\n//% blockGap=8\n//% group=\"micro:bit (V2)\"\nvoid setSerialMirroring(bool enable) {\n#if MICROBIT_CODAL\n return uBit.log.setSerialMirroring(enable);\n#endif\n}\n\n}\n",
|
|
2855
|
-
"pxt.json": "{\n \"name\": \"flashlog\",\n \"description\": \"Data logging to flash.\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"flashlog.cpp\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2869
|
+
"pxt.json": "{\n \"name\": \"flashlog\",\n \"description\": \"Data logging to flash.\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"flashlog.cpp\",\n \"shims.d.ts\",\n \"enums.d.ts\"\n ],\n \"testFiles\": [\n \"test.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"searchOnly\": true,\n \"disablesVariants\": [\n \"mbdal\"\n ],\n \"icon\": \"/static/libs/flashlog.png\"\n}\n",
|
|
2856
2870
|
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Storing structured data in flash.\n */\n //%\ndeclare namespace flashlog {\n\n /**\n * Creates a new row in the log, ready to be populated by logData()\n **/\n //% help=flashlog/begin-row\n //% parts=\"flashlog\"\n //% blockGap=8\n //% group=\"micro:bit (V2)\" shim=flashlog::beginRow\n function beginRow(): int32;\n\n /**\n * Populates the current row with the given key/value pair.\n **/\n //% help=flashlog/log-data\n //% parts=\"flashlog\"\n //% blockGap=8\n //% group=\"micro:bit (V2)\" shim=flashlog::logData\n function logData(key: string, value: string): int32;\n\n /**\n * Inject the given row into the log as text, ignoring key/value pairs.\n **/\n //% help=flashlog/log-string\n //% parts=\"flashlog\"\n //% blockGap=8\n //% group=\"micro:bit (V2)\" shim=flashlog::logString\n function logString(value: string): int32;\n\n /**\n * Complete a row in the log, and pushes to persistent storage.\n **/\n //% help=flashlog/end-row\n //% parts=\"flashlog\"\n //% blockGap=8\n //% group=\"micro:bit (V2)\" shim=flashlog::endRow\n function endRow(): int32;\n\n /**\n * Resets all data stored in persistent storage.\n **/\n //% help=flashlog/clear\n //% parts=\"flashlog\"\n //% blockGap=8\n //% group=\"micro:bit (V2)\" shim=flashlog::clear\n function clear(fullErase: boolean): void;\n\n /**\n * Determines the format of the timestamp data to be added (if any).\n * If requested, time stamps will be automatically added to each row of data\n * as an integer value rounded down to the unit specified.\n *\n * @param format The format of timestamp to use.\n */\n //% help=flashlog/set-timestamp\n //% parts=\"flashlog\"\n //% blockGap=8\n //% group=\"micro:bit (V2)\" shim=flashlog::setTimeStamp\n function setTimeStamp(format: FlashLogTimeStampFormat): void;\n\n /**\n * Defines if data logging should also be streamed over the serial port.\n *\n * @param enable True to enable serial port streaming, false to disable.\n */\n //% help=flashlog/set-serial-mirroring\n //% parts=\"flashlog\"\n //% blockGap=8\n //% group=\"micro:bit (V2)\" shim=flashlog::setSerialMirroring\n function setSerialMirroring(enable: boolean): void;\n}\n\n// Auto-generated. Do not edit. Really.\n",
|
|
2857
2871
|
"test.ts": "input.onButtonPressed(Button.AB, function() {\n flashlog.clear()\n})\nflashlog.setTimeStamp(FlashLogTimeStampFormat.Milliseconds)\nbasic.forever(function () {\n led.toggle(0, 0)\n const ax = input.acceleration(Dimension.X)\n\tflashlog.beginRow()\n flashlog.logData(`a.x`, ax)\n flashlog.logData(`a.y`, input.acceleration(Dimension.Y))\n flashlog.endRow()\n})\n"
|
|
2858
2872
|
},
|
|
2859
2873
|
"datalogger": {
|
|
2860
2874
|
"datalogger.ts": "/**\n * Log data to flash storage\n */\n//% block=\"Data Logger\"\n//% icon=\"\\uf0ce\"\n//% color=\"#378273\"\nnamespace datalogger {\n export enum DeleteType {\n //% block=\"fast\"\n Fast,\n //% block=\"full\"\n Full\n }\n\n let onLogFullHandler: () => void;\n let _disabled = false;\n\n let initialized = false;\n function init() {\n if (initialized)\n return;\n initialized = true;\n\n includeTimestamp(FlashLogTimeStampFormat.Seconds);\n mirrorToSerial(false);\n\n control.onEvent(DAL.MICROBIT_ID_LOG, DAL.MICROBIT_LOG_EVT_LOG_FULL, () => {\n _disabled = true;\n if (onLogFullHandler) {\n onLogFullHandler();\n } else {\n basic.showLeds(`\n # . . . #\n # # . # #\n . . . . .\n . # # # .\n # . . . #\n `);\n basic.pause(1000);\n basic.clearScreen();\n basic.showString(\"928\");\n }\n });\n }\n\n\n export class ColumnValue {\n public value: string;\n constructor(\n public column: string,\n value: any\n ) {\n this.value = \"\" + value;\n }\n }\n\n /**\n * A column and value to log to flash storage\n * @param column the column to set\n * @param value the value to set.\n * @returns A new value that can be stored in flash storage using log data\n */\n //% block=\"column $column value $value\"\n //% value.shadow=math_number\n //% column.shadow=datalogger_columnfield\n //% blockId=dataloggercreatecolumnvalue\n //% group=\"micro:bit (V2)\"\n //% weight=80 help=datalogger/create-cv\n export function createCV(column: string, value: any): ColumnValue {\n return new ColumnValue(column, value);\n }\n\n //% block=\"$column\"\n //% blockId=datalogger_columnfield\n //% group=\"micro:bit (V2)\"\n //% blockHidden=true shim=TD_ID\n //% column.fieldEditor=\"autocomplete\" column.fieldOptions.decompileLiterals=true\n //% column.fieldOptions.key=\"dataloggercolumn\"\n export function _columnField(column: string) {\n return column\n }\n\n /**\n * Log data to flash storage\n * @param data Array of data to be logged to flash storage\n */\n //% block=\"log data array $data\"\n //% blockId=dataloggerlogdata\n //% data.shadow=lists_create_with\n //% data.defl=dataloggercreatecolumnvalue\n //% group=\"micro:bit (V2)\"\n //% blockHidden=true\n //% weight=100\n export function logData(data: ColumnValue[]): void {\n if (!data || !data.length)\n return;\n init();\n\n if (_disabled)\n return;\n\n flashlog.beginRow();\n for (const cv of data) {\n flashlog.logData(cv.column, cv.value);\n }\n flashlog.endRow();\n }\n\n /**\n * Log data to flash storage\n * @param data1 First column and value to be logged\n * @param data2 [optional] second column and value to be logged\n * @param data3 [optional] third column and value to be logged\n * @param data4 [optional] fourth column and value to be logged\n * @param data5 [optional] fifth column and value to be logged\n * @param data6 [optional] sixth column and value to be logged\n * @param data7 [optional] seventh column and value to be logged\n * @param data8 [optional] eighth column and value to be logged\n * @param data9 [optional] ninth column and value to be logged\n * @param data10 [optional] tenth column and value to be logged\n */\n //% block=\"log data $data1||$data2 $data3 $data4 $data5 $data6 $data7 $data8 $data9 $data10\"\n //% blockId=dataloggerlog\n //% data1.shadow=dataloggercreatecolumnvalue\n //% data2.shadow=dataloggercreatecolumnvalue\n //% data3.shadow=dataloggercreatecolumnvalue\n //% data4.shadow=dataloggercreatecolumnvalue\n //% data5.shadow=dataloggercreatecolumnvalue\n //% data6.shadow=dataloggercreatecolumnvalue\n //% data7.shadow=dataloggercreatecolumnvalue\n //% data8.shadow=dataloggercreatecolumnvalue\n //% data9.shadow=dataloggercreatecolumnvalue\n //% data10.shadow=dataloggercreatecolumnvalue\n //% inlineInputMode=\"variable\"\n //% inlineInputModeLimit=1\n //% group=\"micro:bit (V2)\"\n //% weight=100 help=datalogger/log\n export function log(\n data1: datalogger.ColumnValue,\n data2?: datalogger.ColumnValue,\n data3?: datalogger.ColumnValue,\n data4?: datalogger.ColumnValue,\n data5?: datalogger.ColumnValue,\n data6?: datalogger.ColumnValue,\n data7?: datalogger.ColumnValue,\n data8?: datalogger.ColumnValue,\n data9?: datalogger.ColumnValue,\n data10?: datalogger.ColumnValue\n ): void {\n logData(\n [\n data1,\n data2,\n data3,\n data4,\n data5,\n data6,\n data7,\n data8,\n data9,\n data10,\n ].filter(el => !!el)\n );\n }\n\n /**\n * Set the columns for future data logging\n * @param cols Array of the columns that will be logged.\n */\n //% block=\"set columns $cols\"\n //% blockId=dataloggersetcolumns\n //% data.shadow=list_create_with\n //% data.defl=datalogger_columnfield\n //% group=\"micro:bit (V2)\"\n //% blockHidden=true\n //% weight=70\n export function setColumns(cols: string[]): void {\n if (!cols)\n return;\n\n logData(cols.map(col => createCV(col, \"\")));\n }\n\n /**\n * Set the columns for future data logging\n * @param col1 Title for first column to be added\n * @param col2 Title for second column to be added\n * @param col3 Title for third column to be added\n * @param col4 Title for fourth column to be added\n * @param col5 Title for fifth column to be added\n * @param col6 Title for sixth column to be added\n * @param col7 Title for seventh column to be added\n * @param col8 Title for eighth column to be added\n * @param col9 Title for ninth column to be added\n * @param col10 Title for tenth column to be added\n */\n //% block=\"set columns $col1||$col2 $col3 $col4 $col5 $col6 $col7 $col8 $col9 $col10\"\n //% blockId=dataloggersetcolumntitles\n //% inlineInputMode=\"variable\"\n //% inlineInputModeLimit=1\n //% group=\"micro:bit (V2)\"\n //% weight=70 help=datalogger/set-column-titles\n //% col1.shadow=datalogger_columnfield\n //% col2.shadow=datalogger_columnfield\n //% col3.shadow=datalogger_columnfield\n //% col4.shadow=datalogger_columnfield\n //% col5.shadow=datalogger_columnfield\n //% col6.shadow=datalogger_columnfield\n //% col7.shadow=datalogger_columnfield\n //% col8.shadow=datalogger_columnfield\n //% col9.shadow=datalogger_columnfield\n //% col10.shadow=datalogger_columnfield\n export function setColumnTitles(\n col1: string,\n col2?: string,\n col3?: string,\n col4?: string,\n col5?: string,\n col6?: string,\n col7?: string,\n col8?: string,\n col9?: string,\n col10?: string\n ): void {\n logData(\n [col1, col2, col3, col4, col5, col6, col7, col8, col9, col10]\n .filter(el => !!el)\n .map(col => createCV(col, \"\"))\n );\n }\n\n /**\n * Delete all existing logs, including column headers. By default this only marks the log as\n * overwriteable / deletable in the future.\n * @param deleteType optional set whether a deletion will be fast or full\n */\n //% block=\"delete log||$deleteType\"\n //% blockId=dataloggerdeletelog\n //% group=\"micro:bit (V2)\"\n //% weight=60 help=datalogger/delete-log\n export function deleteLog(deleteType?: DeleteType): void {\n init();\n flashlog.clear(deleteType === DeleteType.Full);\n _disabled = false;\n }\n\n /**\n * Register an event to run when no more data can be logged.\n * @param handler code to run when the log is full and no more data can be stored.\n */\n //% block=\"on log full\"\n //% blockId=\"on log full\"\n //% group=\"micro:bit (V2)\"\n //% weight=40 help=datalogger/on-log-full\n export function onLogFull(handler: () => void): void {\n init();\n onLogFullHandler = handler;\n }\n\n /**\n * Set the format for timestamps\n * @param format Format in which to show the timestamp. Setting FlashLogTimeStampFormat.None will disable the timestamp.\n */\n //% block=\"set timestamp $format\"\n //% blockId=dataloggertoggleincludetimestamp\n //% format.defl=FlashLogTimeStampFormat.None\n //% group=\"micro:bit (V2)\"\n //% weight=30 help=datalogger/include-timestamp\n export function includeTimestamp(format: FlashLogTimeStampFormat): void {\n init();\n flashlog.setTimeStamp(format);\n }\n\n /**\n * Set whether data is mirrored to serial or not.\n * @param on if true, data that is logged will be mirrored to serial\n */\n //% block=\"mirror data to serial $on\"\n //% blockId=dataloggertogglemirrortoserial\n //% on.shadow=toggleOnOff\n //% on.defl=false\n //% weight=25 help=datalogger/mirror-to-serial\n export function mirrorToSerial(on: boolean): void {\n // TODO:/note intentionally does not have group, as having the same group for all\n // blocks in a category causes the group to be elided.\n init();\n flashlog.setSerialMirroring(on);\n }\n}\n",
|
|
2861
|
-
"pxt.json": "{\n \"name\": \"datalogger\",\n \"description\": \"Data logging to flash memory. micro:bit (V2) only.\",\n \"dependencies\": {\n \"core\": \"*\",\n \"flashlog\": \"*\"\n },\n \"files\": [\n \"datalogger.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2875
|
+
"pxt.json": "{\n \"name\": \"datalogger\",\n \"description\": \"Data logging to flash memory. micro:bit (V2) only.\",\n \"dependencies\": {\n \"core\": \"*\",\n \"flashlog\": \"*\"\n },\n \"files\": [\n \"datalogger.ts\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"disablesVariants\": [\n \"mbdal\"\n ],\n \"icon\": \"/static/libs/datalogger.png\"\n}\n"
|
|
2862
2876
|
},
|
|
2863
2877
|
"color": {
|
|
2864
2878
|
"README.md": "# Colors\n\nColor manipulation",
|
|
2865
2879
|
"colorbuffer.ts": "namespace color {\n export enum ColorBufferLayout {\n /**\n * 24bit RGB color\n */\n RGB,\n /**\n * 32bit RGB color with alpha\n */\n ARGB\n }\n\n /**\n * A buffer of colors\n */\n export class ColorBuffer {\n layout: ColorBufferLayout;\n buf: Buffer;\n\n constructor(length: number, layout?: ColorBufferLayout) {\n this.layout = layout || ColorBufferLayout.RGB;\n this.buf = control.createBuffer((length | 0) * this.stride);\n }\n\n static fromBuffer(buffer: Buffer, layout: ColorBufferLayout) {\n const b = new ColorBuffer(0, layout);\n b.buf = buffer.slice();\n return b;\n }\n\n get stride() {\n return this.layout == ColorBufferLayout.RGB ? 3 : 4;\n }\n\n get length() {\n return Math.idiv(this.buf.length, this.stride);\n }\n\n color(index: number): number {\n index = index | 0;\n if (index < 0 || index >= this.length)\n return -1;\n\n const s = this.stride;\n const start = index * s;\n let c = 0;\n for (let i = 0; i < s; ++i)\n c = (c << 8) | (this.buf[start + i] & 0xff);\n return c;\n }\n\n setColor(index: number, color: number) {\n index = index | 0;\n if (index < 0 || index >= this.length) return;\n\n const s = this.stride;\n const start = index * s;\n for (let i = s - 1; i >= 0; --i) {\n this.buf[start + i] = color & 0xff;\n color = color >> 8;\n }\n }\n\n slice(start?: number, length?: number): ColorBuffer {\n start = start | 0;\n if (start < 0)\n start = this.length - start;\n\n if (length == undefined)\n length = this.length;\n length = Math.min(length, this.length - start);\n\n const output = new ColorBuffer(length, this.layout);\n for (let i = 0; i < length; ++i) {\n output.setColor(i, this.color(start + i));\n }\n\n return output;\n }\n\n /**\n * Writes the content of the src color buffer starting at the start dstOffset in the current buffer\n * @param dstOffset\n * @param src\n */\n write(dstOffset: number, src: ColorBuffer): void {\n if (this.layout == src.layout) {\n const d = (dstOffset | 0) * this.stride;\n this.buf.write(d, src.buf);\n } else {\n // different color layout\n const n = Math.min(src.length, this.length - dstOffset);\n for (let i = 0; i < n; ++i)\n this.setColor(dstOffset + i, src.color(i));\n }\n }\n }\n\n /**\n * Converts an array of colors into a color buffer\n */\n export function createBuffer(colors: number[], layout?: ColorBufferLayout): color.ColorBuffer {\n const p = new ColorBuffer(colors.length, layout);\n const n = colors.length;\n for (let i = 0; i < n; i++) {\n p.setColor(i, colors[i]);\n }\n return p;\n }\n}",
|
|
2866
2880
|
"colors.ts": "/**\n * Well known colors\n */\nconst enum Colors {\n //% block=red\n //% blockIdentity=color.wellKnown\n Red = 0xFF0000,\n //% block=orange\n //% blockIdentity=color.wellKnown\n Orange = 0xFF7F00,\n //% block=yellow\n //% blockIdentity=color.wellKnown\n Yellow = 0xFFFF00,\n //% block=green\n //% blockIdentity=color.wellKnown\n Green = 0x00FF00,\n //% block=blue\n //% blockIdentity=color.wellKnown\n Blue = 0x0000FF,\n //% block=indigo\n //% blockIdentity=color.wellKnown\n Indigo = 0x4b0082,\n //% block=violet\n //% blockIdentity=color.wellKnown\n Violet = 0x8a2be2,\n //% block=purple\n //% blockIdentity=color.wellKnown\n Purple = 0xA033E5,\n //% block=pink\n //% blockIdentity=color.wellKnown\n Pink = 0xFF007F,\n //% block=white\n //% blockIdentity=color.wellKnown\n White = 0xFFFFFF,\n //% block=black\n //% blockIdentity=color.wellKnown\n Black = 0x000000\n}\n\n/**\n * Well known color hues\n */\nconst enum ColorHues {\n //% block=red\n Red = 0,\n //% block=orange\n Orange = 29,\n //% block=yellow\n Yellow = 43,\n //% block=green\n Green = 86,\n //% block=aqua\n Aqua = 125,\n //% block=blue\n Blue = 170,\n //% block=purple\n Purple = 191,\n //% block=magenta\n Magenta = 213,\n //% block=pink\n Pink = 234\n}\n\n/**\n * Color manipulation\n */\n//% advanced=1\nnamespace color {\n /**\n * Converts red, green, blue channels into a RGB color\n * @param red value of the red channel between 0 and 255. eg: 255\n * @param green value of the green channel between 0 and 255. eg: 255\n * @param blue value of the blue channel between 0 and 255. eg: 255\n */\n //% blockId=\"colorsrgb\" block=\"red %red|green %green|blue %blue\"\n //% red.min=0 red.max=255 green.min=0 green.max=255 blue.min=0 blue.max=255\n //% help=\"colors/rgb\"\n //% weight=19 blockGap=8\n //% blockHidden=true\n export function rgb(red: number, green: number, blue: number): number {\n return ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);\n }\n\n export function argb(alpha: number, red: number, green: number, blue: number): number {\n return ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);\n }\n\n /**\n * Get the RGB value of a known color\n */\n //% blockId=colorscolors block=\"%color\"\n //% help=\"colors/well-known\"\n //% shim=TD_ID\n //% weight=20 blockGap=8\n //% blockHidden=true\n export function wellKnown(color: Colors): number {\n return color;\n }\n\n /**\n * Convert an HSV (hue, saturation, value) color to RGB\n * @param hue value of the hue channel between 0 and 255. eg: 255\n * @param sat value of the saturation channel between 0 and 255. eg: 255\n * @param val value of the value channel between 0 and 255. eg: 255\n */\n\n //% blockId=\"colorshsv\" block=\"hue %hue|sat %sat|val %val\"\n //% hue.min=0 hue.max=255 sat.min=0 sat.max=255 val.min=0 val.max=255\n //% help=\"colors/hsv\"\n //% weight=17\n //% blockHidden=true\n export function hsv(hue: number, sat: number = 255, val: number = 255): number {\n let h = (hue % 255) >> 0;\n if (h < 0) h += 255;\n // scale down to 0..192\n h = (h * 192 / 255) >> 0;\n\n //reference: based on FastLED's hsv2rgb rainbow algorithm [https://github.com/FastLED/FastLED](MIT)\n const invsat = 255 - sat;\n const brightness_floor = ((val * invsat) / 255) >> 0;\n const color_amplitude = val - brightness_floor;\n const section = (h / 0x40) >> 0; // [0..2]\n const offset = (h % 0x40) >> 0; // [0..63]\n\n const rampup = offset;\n const rampdown = (0x40 - 1) - offset;\n\n const rampup_amp_adj = ((rampup * color_amplitude) / (255 / 4)) >> 0;\n const rampdown_amp_adj = ((rampdown * color_amplitude) / (255 / 4)) >> 0;\n\n const rampup_adj_with_floor = (rampup_amp_adj + brightness_floor);\n const rampdown_adj_with_floor = (rampdown_amp_adj + brightness_floor);\n\n let r: number;\n let g: number;\n let b: number;\n if (section) {\n if (section == 1) {\n // section 1: 0x40..0x7F\n r = brightness_floor;\n g = rampdown_adj_with_floor;\n b = rampup_adj_with_floor;\n } else {\n // section 2; 0x80..0xBF\n r = rampup_adj_with_floor;\n g = brightness_floor;\n b = rampdown_adj_with_floor;\n }\n } else {\n // section 0: 0x00..0x3F\n r = rampdown_adj_with_floor;\n g = rampup_adj_with_floor;\n b = brightness_floor;\n }\n return rgb(r, g, b);\n }\n\n /**\n * Fade the color by the brightness\n * @param color color to fade\n * @param brightness the amount of brightness to apply to the color, eg: 128\n */\n //% blockId=\"colorsfade\" block=\"fade %color=neopixel_colors|by %brightness\"\n //% brightness.min=0 brightness.max=255\n //% help=\"light/fade\"\n //% group=\"Color\" weight=18 blockGap=8\n //% blockHidden=true\n export function fade(color: number, brightness: number): number {\n brightness = Math.max(0, Math.min(255, brightness >> 0));\n if (brightness < 255) {\n let red = unpackR(color);\n let green = unpackG(color);\n let blue = unpackB(color);\n\n red = (red * brightness) >> 8;\n green = (green * brightness) >> 8;\n blue = (blue * brightness) >> 8;\n\n color = rgb(red, green, blue);\n }\n return color;\n }\n\n export function blend(color: number, alpha: number, otherColor: number) {\n alpha = Math.max(0, Math.min(0xff, alpha | 0));\n const malpha = 0xff - alpha;\n const r = (unpackR(color) * malpha + unpackR(otherColor) * alpha) >> 8;\n const g = (unpackG(color) * malpha + unpackG(otherColor) * alpha) >> 8;\n const b = (unpackB(color) * malpha + unpackB(otherColor) * alpha) >> 8;\n return rgb(r, g, b);\n }\n\n export function gradient(startColor: number, endColor: number, steps: number): ColorBuffer {\n steps = Math.max(2, steps | 0);\n const b = new ColorBuffer(steps);\n b.setColor(0, startColor);\n b.setColor(b.length - 1, endColor);\n for (let i = 1; i < steps - 1; ++i) {\n const alpha = Math.idiv(0xff * i, steps);\n const c = blend(startColor, alpha, endColor);\n b.setColor(i, c);\n }\n return b;\n }\n\n export function unpackR(rgb: number): number {\n return (rgb >> 16) & 0xFF;\n }\n export function unpackG(rgb: number): number {\n return (rgb >> 8) & 0xFF;\n }\n export function unpackB(rgb: number): number {\n return (rgb >> 0) & 0xFF;\n }\n\n export function parseColor(color: string): number {\n switch (color) {\n case \"RED\":\n case \"red\":\n return Colors.Red;\n case \"GREEN\":\n case \"green\":\n return Colors.Green;\n case \"BLUE\":\n case \"blue\":\n return Colors.Blue;\n case \"WHITE\":\n case \"white\":\n return Colors.White;\n case \"ORANGE\":\n case \"orange\":\n return Colors.Orange;\n case \"PURPLE\":\n case \"purple\":\n return Colors.Purple;\n case \"YELLOW\":\n case \"yellow\":\n return Colors.Yellow;\n case \"PINK\":\n case \"pink\":\n return Colors.Pink;\n default:\n return parseInt(color) || 0;\n }\n }\n}",
|
|
2867
|
-
"pxt.json": "{\n \"name\": \"color\",\n \"description\": \"Color manipulation\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"colors.ts\",\n \"colorbuffer.ts\",\n \"README.md\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.
|
|
2881
|
+
"pxt.json": "{\n \"name\": \"color\",\n \"description\": \"Color manipulation\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"colors.ts\",\n \"colorbuffer.ts\",\n \"README.md\"\n ],\n \"public\": true,\n \"targetVersions\": {\n \"target\": \"5.1.2\",\n \"pxt\": \"8.2.6\"\n },\n \"hidden\": true,\n \"weight\": 1,\n \"icon\": \"/static/libs/color.png\"\n}\n"
|
|
2868
2882
|
}
|
|
2869
2883
|
},
|
|
2870
2884
|
"apiInfo": {
|
|
@@ -16114,8 +16128,7 @@ var pxtTargetBundle = {
|
|
|
16114
16128
|
"retType": "number",
|
|
16115
16129
|
"attributes": {
|
|
16116
16130
|
"paramDefl": {
|
|
16117
|
-
"value": "
|
|
16118
|
-
"color": "#ff0000"
|
|
16131
|
+
"value": "0xff0000"
|
|
16119
16132
|
},
|
|
16120
16133
|
"blockId": "colorNumberPicker",
|
|
16121
16134
|
"block": "%value",
|
|
@@ -16137,7 +16150,7 @@ var pxtTargetBundle = {
|
|
|
16137
16150
|
"value"
|
|
16138
16151
|
],
|
|
16139
16152
|
"paramHelp": {
|
|
16140
|
-
"color": "color
|
|
16153
|
+
"color": "color"
|
|
16141
16154
|
},
|
|
16142
16155
|
"jsDoc": "Get the color wheel field editor",
|
|
16143
16156
|
"_def": {
|
|
@@ -16160,8 +16173,8 @@ var pxtTargetBundle = {
|
|
|
16160
16173
|
"parameters": [
|
|
16161
16174
|
{
|
|
16162
16175
|
"name": "value",
|
|
16163
|
-
"initializer": "
|
|
16164
|
-
"default": "
|
|
16176
|
+
"initializer": "0xff0000",
|
|
16177
|
+
"default": "0xff0000"
|
|
16165
16178
|
}
|
|
16166
16179
|
]
|
|
16167
16180
|
},
|
|
@@ -29455,7 +29468,7 @@ var pxtTargetBundle = {
|
|
|
29455
29468
|
}
|
|
29456
29469
|
}
|
|
29457
29470
|
},
|
|
29458
|
-
"sha": "
|
|
29471
|
+
"sha": "af66a1c2a2983cb87b596934e2e11cb82ad6a79173ca2075336c802cb08ed1f5"
|
|
29459
29472
|
},
|
|
29460
29473
|
"libs/radio": {
|
|
29461
29474
|
"apis": {
|
|
@@ -30904,7 +30917,7 @@ var pxtTargetBundle = {
|
|
|
30904
30917
|
}
|
|
30905
30918
|
}
|
|
30906
30919
|
},
|
|
30907
|
-
"sha": "
|
|
30920
|
+
"sha": "88db9c47fbe7b3d0707ce3f69a3b118a2515c4127568561674b52743fbf65a30"
|
|
30908
30921
|
},
|
|
30909
30922
|
"libs/devices": {
|
|
30910
30923
|
"apis": {
|
|
@@ -32951,7 +32964,7 @@ var pxtTargetBundle = {
|
|
|
32951
32964
|
}
|
|
32952
32965
|
}
|
|
32953
32966
|
},
|
|
32954
|
-
"sha": "
|
|
32967
|
+
"sha": "db205223b268829e5e0161c4d4ea1d1fa543fedb6e1b21367e993e8738f18cd0"
|
|
32955
32968
|
},
|
|
32956
32969
|
"libs/bluetooth": {
|
|
32957
32970
|
"apis": {
|
|
@@ -33912,7 +33925,7 @@ var pxtTargetBundle = {
|
|
|
33912
33925
|
}
|
|
33913
33926
|
}
|
|
33914
33927
|
},
|
|
33915
|
-
"sha": "
|
|
33928
|
+
"sha": "aa6ea44ff6a30be246da64d3701e69c681139d19aed83da0dc7510a2e8bbc40b"
|
|
33916
33929
|
},
|
|
33917
33930
|
"libs/servo": {
|
|
33918
33931
|
"apis": {
|
|
@@ -34554,7 +34567,7 @@ var pxtTargetBundle = {
|
|
|
34554
34567
|
}
|
|
34555
34568
|
}
|
|
34556
34569
|
},
|
|
34557
|
-
"sha": "
|
|
34570
|
+
"sha": "f8270481e584431f9438cd226453e2d74281c3fee2ccd00f5bbe7e1ebcfd4893"
|
|
34558
34571
|
},
|
|
34559
34572
|
"libs/radio-broadcast": {
|
|
34560
34573
|
"apis": {
|
|
@@ -36148,7 +36161,7 @@ var pxtTargetBundle = {
|
|
|
36148
36161
|
}
|
|
36149
36162
|
}
|
|
36150
36163
|
},
|
|
36151
|
-
"sha": "
|
|
36164
|
+
"sha": "7d10d6f12079500881ee529c5e73a571dbc15af029266f150327fe6a8301548e"
|
|
36152
36165
|
},
|
|
36153
36166
|
"libs/microphone": {
|
|
36154
36167
|
"apis": {
|
|
@@ -36426,7 +36439,7 @@ var pxtTargetBundle = {
|
|
|
36426
36439
|
}
|
|
36427
36440
|
}
|
|
36428
36441
|
},
|
|
36429
|
-
"sha": "
|
|
36442
|
+
"sha": "0e26ead50c18a5a2fb7d0399580c12287b896b2870f8a593619c6c2b45e60c60"
|
|
36430
36443
|
},
|
|
36431
36444
|
"libs/settings": {
|
|
36432
36445
|
"apis": {
|
|
@@ -36763,7 +36776,7 @@ var pxtTargetBundle = {
|
|
|
36763
36776
|
}
|
|
36764
36777
|
}
|
|
36765
36778
|
},
|
|
36766
|
-
"sha": "
|
|
36779
|
+
"sha": "318f8f63450a88dddf5137a611234e20872684e2753f07558950d3a752b13ccd"
|
|
36767
36780
|
},
|
|
36768
36781
|
"libs/flashlog": {
|
|
36769
36782
|
"apis": {
|
|
@@ -37028,7 +37041,7 @@ var pxtTargetBundle = {
|
|
|
37028
37041
|
}
|
|
37029
37042
|
}
|
|
37030
37043
|
},
|
|
37031
|
-
"sha": "
|
|
37044
|
+
"sha": "3e1d73f6436b30ab10544b7b484110ebe078e613d718029fef741f80c7903211"
|
|
37032
37045
|
},
|
|
37033
37046
|
"libs/datalogger": {
|
|
37034
37047
|
"apis": {
|
|
@@ -38352,7 +38365,7 @@ var pxtTargetBundle = {
|
|
|
38352
38365
|
}
|
|
38353
38366
|
}
|
|
38354
38367
|
},
|
|
38355
|
-
"sha": "
|
|
38368
|
+
"sha": "ed757be5cc6c4454405a3e67375aa1f21c6ae0b8f61187d9ba03af9e97a8aea5"
|
|
38356
38369
|
},
|
|
38357
38370
|
"libs/color": {
|
|
38358
38371
|
"apis": {
|
|
@@ -39464,7 +39477,7 @@ var pxtTargetBundle = {
|
|
|
39464
39477
|
}
|
|
39465
39478
|
}
|
|
39466
39479
|
},
|
|
39467
|
-
"sha": "
|
|
39480
|
+
"sha": "526ab206440159e30fe586132c434996047b9de7824cfa24c0945425198bbd2f"
|
|
39468
39481
|
},
|
|
39469
39482
|
"libs/blocksprj": {
|
|
39470
39483
|
"apis": {
|
|
@@ -41184,7 +41197,7 @@ var pxtTargetBundle = {
|
|
|
41184
41197
|
}
|
|
41185
41198
|
}
|
|
41186
41199
|
},
|
|
41187
|
-
"sha": "
|
|
41200
|
+
"sha": "8a326369562fb0cf83778c9eb1d424de3f0e71f301fe33c10d576919874fc61d"
|
|
41188
41201
|
},
|
|
41189
41202
|
"libs/bluetoothprj": {
|
|
41190
41203
|
"apis": {
|
|
@@ -42416,7 +42429,7 @@ var pxtTargetBundle = {
|
|
|
42416
42429
|
}
|
|
42417
42430
|
}
|
|
42418
42431
|
},
|
|
42419
|
-
"sha": "
|
|
42432
|
+
"sha": "7e3388c518c2283415fddbd9f51dc3d86604cf16640491ef79f15d527841c1d7"
|
|
42420
42433
|
},
|
|
42421
42434
|
"libs/tsprj": {
|
|
42422
42435
|
"apis": {
|
|
@@ -44136,7 +44149,7 @@ var pxtTargetBundle = {
|
|
|
44136
44149
|
}
|
|
44137
44150
|
}
|
|
44138
44151
|
},
|
|
44139
|
-
"sha": "
|
|
44152
|
+
"sha": "0fabdc47cc3f4e9364ab40198725a5e1c787091741719283bb05292f963f629d"
|
|
44140
44153
|
}
|
|
44141
44154
|
}
|
|
44142
44155
|
}
|