diff --git a/ports/stm32/boards/LEGO_HUB_NO6/README.md b/ports/stm32/boards/LEGO_HUB_NO6/README.md new file mode 100644 index 0000000000..c566ada9d0 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/README.md @@ -0,0 +1,79 @@ +LEGO Hub No.6 +============= + +This board definition is for the LEGO Hub No. 6, a LEGO control unit with a 5x5 +LED display, 6 Powered Up ports, speaker, 6-DOF sensor, Bluetooth, external SPI +flash storage, and a rechargeable battery. The Hub can work without the battery if +it is plugged in to, and powered by, its USB port. But without the battery the LEDs +and power on the Powered Up ports will not function. + +Features that are currently supported: +- standard MicroPython +- machine and bluetooth modules +- filesystem +- USB VCP, MSC and HID + +The Hub has a bootloader preinstalled at 0x08000000 (which is 32kiB in size) which +cannot be erased. This bootloader is entered by holding down the Bluetooth button, +plugging in USB to power it up, then releasing the Bluetooth button after 5 seconds, +at which point the USB DFU device appears. If the battery is installed then the +Bluetooth button's RGB LED will cycle colours. When this bootloader is active, the +flash from 0x08008000 and up can be erased and programmed via USB DFU. + +The built-in bootloader has some drawbacks: it cannot be entered programmatically, +and it does not keep the Hub powered up when running from battery (which requires +keeping BAT_PWR_EN high). As such, this board is configured to work with mboot as +a secondary bootloader: mboot is placed at 0x08008000 and the main application +firmware at 0x08010000. When mboot is installed it can be entered programatically +via machine.bootloader(), or by holding down the left arrow button when powering +on the Hub and waiting until the display says "B" before releasing the button. + +Installing MicroPython +---------------------- + +You first need to build and install mboot, which only needs to be done once. From +the root of this repository run: + + $ cd ports/stm32/mboot + $ make BOARD=LEGO_HUB_NO6 + +Now enter the built-in bootloader by holding down the Bluetooth button for 5 +seconds while powering up the Hub via USB. Then run: + + $ make BOARD=LEGO_HUB_NO6 deploy + +mboot should now be installed. Enter mboot by holding down the left arrow +button when powering up the Hub. The display will cycle the letters: N, S, F, B. +When it gets to "B" release the left arrow and it will start mboot. The Hub then +blinks the centre button red once per second, and appears as a USB DFU device. + +Now build MicroPython (start at the root of this repository): + + $ cd mpy-cross + $ make + $ cd ../ports/stm32 + $ make submodules + $ make BOARD=LEGO_HUB_NO6 + +And deploy to the Hub (making sure mboot is active, the centre button is blinking +red): + + $ make BOARD=LEGO_HUB_NO6 deploy + +If successful, the Hub should now appear as a USB serial and mass storage device. + +Using MicroPython on the Hub +---------------------------- + +Access the MicroPython REPL using mpremote (pip install mpremote), or with any +serial terminal program. + +To scan for BLE devices: + + >>> import bluetooth + >>> ble = bluetooth.BLE() + >>> ble.irq(lambda *x: print(*x)) + >>> ble.active(1) + >>> ble.gap_scan(2000, 625, 625) + +Use help("modules") to see available built-in modules. \ No newline at end of file diff --git a/ports/stm32/boards/LEGO_HUB_NO6/bdev.c b/ports/stm32/boards/LEGO_HUB_NO6/bdev.c new file mode 100644 index 0000000000..44671edb15 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/bdev.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "storage.h" + +#define CMD_EXIT_4_BYTE_ADDRESS_MODE (0xE9) + +STATIC const mp_soft_spi_obj_t soft_spi_bus = { + .delay_half = MICROPY_HW_SOFTSPI_MIN_DELAY, + .polarity = 0, + .phase = 0, + .sck = MICROPY_HW_SPIFLASH_SCK, + .mosi = MICROPY_HW_SPIFLASH_MOSI, + .miso = MICROPY_HW_SPIFLASH_MISO, +}; + +STATIC mp_spiflash_cache_t spi_bdev_cache; + +const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_SPI, + .bus.u_spi.cs = MICROPY_HW_SPIFLASH_NSS, + .bus.u_spi.data = (void *)&soft_spi_bus, + .bus.u_spi.proto = &mp_soft_spi_proto, + .cache = &spi_bdev_cache, +}; + +spi_bdev_t spi_bdev; + +int32_t board_bdev_ioctl(void) { + int32_t ret = spi_bdev_ioctl(&spi_bdev, BDEV_IOCTL_INIT, (uint32_t)&spiflash_config); + + // Exit 4-byte address mode + uint8_t cmd = CMD_EXIT_4_BYTE_ADDRESS_MODE; + mp_hal_pin_write(MICROPY_HW_SPIFLASH_NSS, 0); + mp_soft_spi_proto.transfer(MP_OBJ_FROM_PTR(&soft_spi_bus), 1, &cmd, NULL); + mp_hal_pin_write(MICROPY_HW_SPIFLASH_NSS, 1); + + return ret; +} diff --git a/ports/stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c b/ports/stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c new file mode 100644 index 0000000000..ec41fdfeef --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/bluetooth_init_cc2564C_1.5.c @@ -0,0 +1,616 @@ +// This file contains CC256x initialisation code, and was generated by BTstack via: +// $ cd chipset/cc256x +// $ make -f Makefile.inc BTSTACK_ROOT=../.. bluetooth_init_cc2564C_1.4.c +#if !BUILDING_MBOOT + + // init script created from +// - /Users/dktobthy/Downloads/cc256xc_bt_spv1.5/CC256XC_BT_SP/v1.5/initscripts-TIInit_6.12.26.bts +// - AKA TIInit_6.12.26.bts +// - /Users/dktobthy/Downloads/cc256xc_bt_spv1.5/CC256XC_BT_SP/v1.5/initscripts-TIInit_6.12.26_ble_add-on.bts +#include +#include "lib/btstack/chipset/cc256x/btstack_chipset_cc256x.h" + + +const uint16_t cc256x_init_script_lmp_subversion = 0x9a1a; + +uint16_t btstack_chipset_cc256x_lmp_subversion(void){ + return cc256x_init_script_lmp_subversion; +} + +#if defined(__GNUC__) && defined(__MSP430X__) && (__MSP430X__ > 0) +__attribute__((section (".fartext"))) +#endif +#ifdef __AVR__ +__attribute__((__progmem__)) +#endif +const uint8_t cc256x_init_script[] = { + + // #-------------------------------------------------------------------------------- + // # Description : Orca C ROM Initialization Script + // # + // # Compatibility: Orca, 12.0.26 ROM + // # + // # Last Updated: 17-May-2021 10:31:30.07 + // # + // # Version : 12_26.24 + // # + // # + // # + // # + // # Notes : Use this script on Orca C, 12.0.26 ROM device only (FW v12.0.26) + // #-------------------------------------------------------------------------------- + // ################################################################# + // ## START of CC256x Add-On + // ################################################################# + // + // ## Change UART baudrate + // + // ################################################################# + // ## END of CC256x Add-On + // ################################################################# + // + 0x01, 0x37, 0xfe, 0x02, 0x0c, 0x1a, + + // + // + 0x01, 0x05, 0xff, 0xff, 0xd0, 0x65, 0x08, 0x00, 0xfa, 0x0c, 0x1a, 0x09, 0x18, 0x01, 0x6a, + 0xc8, 0x7b, 0x00, 0x02, 0x89, 0x7b, 0x01, 0x43, 0x09, 0x48, 0x51, 0x30, 0x02, 0x88, 0x06, + 0x48, 0x91, 0x42, 0x03, 0xd1, 0x04, 0x49, 0x09, 0x78, 0x01, 0x29, 0x01, 0xd0, 0x5d, 0x30, + 0xf7, 0x46, 0xff, 0x30, 0xd8, 0x30, 0xf7, 0x46, 0x76, 0x24, 0x08, 0x00, 0xbd, 0x28, 0x02, + 0x00, 0x69, 0x53, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x00, + 0x69, 0xff, 0x21, 0x02, 0x31, 0x09, 0x5c, 0x09, 0x29, 0x05, 0xd1, 0x01, 0x21, 0x00, 0x22, + 0x8e, 0x46, 0x6d, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0xbd, 0x6c, 0x4a, 0x11, 0x88, 0x01, + 0x20, 0x40, 0x03, 0x08, 0x43, 0x10, 0x80, 0xf7, 0x46, 0x30, 0xb5, 0x00, 0x69, 0xf4, 0x21, + 0x08, 0x5c, 0x01, 0x28, 0x16, 0xd1, 0xea, 0x48, 0x00, 0x78, 0x03, 0x28, 0x12, 0xd0, 0x00, + 0x25, 0x28, 0x1c, 0xe8, 0x49, 0x01, 0x24, 0xa6, 0x46, 0xe7, 0x4a, 0xfe, 0x44, 0x10, 0x47, + 0x00, 0x28, 0x08, 0xd0, + + 0x01, 0x05, 0xff, 0xff, 0xca, 0x66, 0x08, 0x00, 0xfa, 0xe6, 0x49, 0xe6, 0x4a, 0xbb, 0x32, + 0x20, 0x20, 0x2b, 0x1c, 0xa6, 0x46, 0xe5, 0x4c, 0xfe, 0x44, 0x20, 0x47, 0x30, 0xbd, 0x70, + 0xb5, 0x85, 0x69, 0x00, 0x7d, 0x80, 0x1f, 0x11, 0xd0, 0x47, 0x38, 0x2e, 0xd1, 0xa9, 0x79, + 0x28, 0x20, 0x48, 0x43, 0xdf, 0x4a, 0x10, 0x18, 0x23, 0x22, 0x12, 0x5c, 0x01, 0x2a, 0x25, + 0xd1, 0x80, 0x7b, 0x00, 0x28, 0x22, 0xd0, 0xdb, 0x4a, 0x00, 0x20, 0x50, 0x54, 0x70, 0xbd, + 0x01, 0x24, 0xa6, 0x46, 0xd9, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x01, 0x28, 0x05, 0xd0, 0xa6, + 0x46, 0xd6, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x04, 0x28, 0x11, 0xd1, 0xe8, 0x78, 0x00, 0x28, + 0x0e, 0xd1, 0x0e, 0x26, 0x31, 0x1c, 0xd3, 0x4d, 0x28, 0x1c, 0x14, 0x38, 0xa6, 0x46, 0xd0, + 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x28, 0x1c, 0x31, 0x1c, 0xa6, 0x46, 0xcd, 0x4a, 0xfe, 0x44, + 0x10, 0x47, 0x70, 0xbd, 0x70, 0xb5, 0x01, 0x1c, 0x88, 0x69, 0x89, 0x8a, 0xcb, 0x4a, 0x89, + 0x1a, 0x1c, 0xd0, 0x1c, 0x39, 0x20, 0xd1, 0xc5, 0x7a, 0x01, 0x21, 0x0c, 0x1c, 0x8e, 0x46, + 0xc8, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x06, 0x1c, 0x10, 0x20, 0xa6, 0x46, 0xc6, 0x49, 0xfe, + 0x44, 0x08, 0x47, 0x00, 0x2d, 0x11, 0xd0, 0x02, 0x2e, 0x0f, 0xd0, 0xc3, 0x49, 0xc4, 0x4a, + 0xd9, 0x32, 0x20, 0x20, 0x00, 0x23, 0xa6, 0x46, 0xb7, 0x4c, 0xfe, 0x44, 0x20, 0x47, 0x70, + 0xbd, 0xc0, 0x7a, 0x00, 0x28, 0x02, 0xd1, 0x00, 0x20, 0xbe, 0x49, 0x08, 0x70, 0x70, 0xbd, + 0x00, 0xb5, 0x00, 0x69, 0xff, 0x21, 0x04, 0x31, 0x09, 0x5c, 0x06, 0x29, 0x06, 0xd1, 0xff, + 0x21, 0x05, 0x31, 0x0a, 0x5c, 0x2c, 0x2a, 0x01, 0xd1, 0x2d, 0x22, 0x0a, 0x54, 0xff, 0x21, + 0x05, 0x31, 0x09, 0x5c, + + 0x01, 0x05, 0xff, 0xff, 0xc4, 0x67, 0x08, 0x00, 0xfa, 0x34, 0x29, 0x11, 0xd1, 0xff, 0x21, + 0x0b, 0x31, 0x09, 0x5c, 0x91, 0x29, 0x0c, 0xd1, 0xf1, 0x21, 0x09, 0x5c, 0x60, 0x22, 0x4a, + 0x43, 0xeb, 0x4b, 0x00, 0x21, 0x99, 0x54, 0x06, 0x21, 0x01, 0x22, 0x96, 0x46, 0xe9, 0x4a, + 0xfe, 0x44, 0x10, 0x47, 0x00, 0xbd, 0xf0, 0xb5, 0x06, 0x1c, 0xf7, 0x69, 0x08, 0x20, 0xc0, + 0x19, 0x01, 0x24, 0xa6, 0x46, 0xe4, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xc1, 0x7b, 0x09, 0x02, + 0x80, 0x7b, 0x08, 0x43, 0x05, 0x04, 0x2d, 0x0c, 0x02, 0x2d, 0x12, 0xd0, 0xef, 0x48, 0x00, + 0x88, 0xa8, 0x42, 0x0e, 0xd1, 0xee, 0x48, 0x00, 0x78, 0x01, 0x28, 0x0a, 0xd1, 0xed, 0x48, + 0x82, 0x8f, 0x81, 0x6b, 0x08, 0x1c, 0x10, 0x43, 0x04, 0xd0, 0x38, 0x1c, 0xa6, 0x46, 0xea, + 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x35, 0x60, 0xe9, 0x48, 0x24, 0x30, 0x30, 0x62, 0xf0, 0xbd, + 0xc0, 0x46, 0xdd, 0x9d, 0x00, 0x00, 0x3e, 0xa6, 0x1b, 0x00, 0xf0, 0xb5, 0x86, 0xb0, 0x04, + 0x90, 0x81, 0x69, 0x05, 0x91, 0x81, 0x8a, 0xe2, 0x48, 0x09, 0x1a, 0xdc, 0x4d, 0x00, 0xd1, + 0xba, 0xe0, 0xe1, 0x4a, 0x89, 0x1a, 0x00, 0xd1, 0xaf, 0xe0, 0x07, 0x38, 0x09, 0x1a, 0x35, + 0xd0, 0xde, 0x48, 0x09, 0x1a, 0x28, 0xd0, 0x05, 0x39, 0x26, 0xd0, 0x13, 0x39, 0x33, 0xd1, + 0xdc, 0x48, 0x05, 0x1c, 0x84, 0x3d, 0x00, 0x78, 0x02, 0x28, 0x2d, 0xd1, 0x01, 0x24, 0xa6, + 0x46, 0xd9, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x00, 0x28, 0x26, 0xd1, 0xa6, 0x46, 0xd7, 0x48, + 0xfe, 0x44, 0x00, 0x47, 0x00, 0x28, 0x20, 0xd1, 0xa6, 0x46, 0xd5, 0x48, 0xfe, 0x44, 0x00, + 0x47, 0x00, 0x28, 0x1a, 0xd1, 0x28, 0x78, 0x00, 0x28, 0x17, 0xd1, 0xa8, 0x78, 0x00, 0x28, + 0x14, 0xd1, 0xa6, 0x20, + + 0x01, 0x05, 0xff, 0xff, 0xbe, 0x68, 0x08, 0x00, 0xfa, 0xa6, 0x46, 0xcf, 0x49, 0xfe, 0x44, + 0x08, 0x47, 0xc4, 0xe0, 0x05, 0x98, 0x81, 0x88, 0x41, 0x18, 0x08, 0x7c, 0x02, 0x28, 0x00, + 0xda, 0xbd, 0xe0, 0x80, 0x1e, 0x08, 0x74, 0xba, 0xe0, 0x51, 0x3d, 0x28, 0x78, 0x2a, 0x28, + 0x02, 0xd0, 0x33, 0x28, 0x00, 0xd0, 0xb3, 0xe0, 0x0e, 0x21, 0x05, 0x98, 0x0f, 0x18, 0x44, + 0x20, 0x0c, 0x21, 0x1a, 0x22, 0x01, 0x24, 0xa6, 0x46, 0xc2, 0x4b, 0xfe, 0x44, 0x18, 0x47, + 0xc1, 0x4e, 0xb1, 0x78, 0xf2, 0x78, 0xc1, 0x48, 0xa6, 0x46, 0xc1, 0x4b, 0xfe, 0x44, 0x18, + 0x47, 0x06, 0x21, 0x05, 0x98, 0x81, 0x80, 0x28, 0x78, 0xbf, 0x4d, 0x2a, 0x28, 0x26, 0xd0, + 0x0a, 0x26, 0x3e, 0x70, 0x01, 0x37, 0x38, 0x1c, 0x00, 0x21, 0xa6, 0x46, 0xba, 0x4a, 0xfe, + 0x44, 0x10, 0x47, 0x07, 0x1c, 0x3e, 0x70, 0x01, 0x37, 0x38, 0x1c, 0x0d, 0x21, 0xa6, 0x46, + 0xb5, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x07, 0x1c, 0xa6, 0x46, 0xb5, 0x48, 0xfe, 0x44, 0x00, + 0x47, 0x81, 0x02, 0xae, 0x48, 0xc0, 0x78, 0x40, 0x06, 0x40, 0x0e, 0x08, 0x43, 0x05, 0x43, + 0x29, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xa6, 0x46, 0xac, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x08, + 0x26, 0x24, 0xe0, 0x08, 0x26, 0x3e, 0x70, 0x01, 0x37, 0x38, 0x1c, 0x00, 0x21, 0xa6, 0x46, + 0xa6, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x07, 0x1c, 0x3e, 0x70, 0x01, 0x37, 0x38, 0x1c, 0x0d, + 0x21, 0xa6, 0x46, 0xa2, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x07, 0x1c, 0xa6, 0x46, 0xa1, 0x48, + 0xfe, 0x44, 0x00, 0x47, 0x81, 0x02, 0x9a, 0x48, 0xc0, 0x78, 0x40, 0x06, 0x40, 0x0e, 0x08, + 0x43, 0x05, 0x43, 0x29, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xa6, 0x46, 0x98, 0x4a, 0xfe, 0x44, + 0x10, 0x47, 0x05, 0x98, + + 0x01, 0x05, 0xff, 0xff, 0xb8, 0x69, 0x08, 0x00, 0xfa, 0x46, 0x80, 0xff, 0x21, 0x02, 0x31, + 0x00, 0x22, 0xa6, 0x46, 0xed, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x3f, 0xe0, 0xec, 0x49, 0x00, + 0x20, 0x08, 0x70, 0x08, 0x74, 0xeb, 0x49, 0x08, 0x70, 0x3c, 0xe0, 0x05, 0x98, 0x00, 0x21, + 0x6a, 0x46, 0x01, 0x24, 0xa6, 0x46, 0xe8, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x02, 0xa8, 0x00, + 0x21, 0x06, 0x22, 0xa6, 0x46, 0xe5, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x26, 0x02, 0xe0, + 0x70, 0x1c, 0x06, 0x04, 0x36, 0x0c, 0x28, 0x1c, 0x4f, 0x38, 0x00, 0x78, 0x86, 0x42, 0x23, + 0xda, 0x11, 0x20, 0x40, 0x01, 0x70, 0x43, 0xea, 0x49, 0x0f, 0x18, 0x10, 0x20, 0xc0, 0x19, + 0x69, 0x46, 0xa6, 0x46, 0xe8, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0xe9, 0xd1, 0x68, + 0x46, 0x02, 0xa9, 0xa6, 0x46, 0xe4, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0xe1, 0xd0, + 0xb8, 0x78, 0x01, 0x28, 0xde, 0xd0, 0x05, 0x98, 0x69, 0x49, 0x3a, 0x22, 0xa6, 0x46, 0xdf, + 0x4b, 0xfe, 0x44, 0x18, 0x47, 0xec, 0x49, 0xe2, 0x31, 0x04, 0x98, 0x01, 0x62, 0x06, 0xb0, + 0xf0, 0xbd, 0xc0, 0x46, 0x18, 0x32, 0x08, 0x00, 0xce, 0x04, 0x00, 0x00, 0x23, 0xb9, 0x02, + 0x00, 0x85, 0x71, 0x08, 0x00, 0xfd, 0x79, 0x00, 0x00, 0xc9, 0x70, 0x08, 0x00, 0xd4, 0x1d, + 0x08, 0x00, 0x94, 0x54, 0x08, 0x00, 0x8f, 0x8d, 0x01, 0x00, 0xfd, 0x06, 0x05, 0x00, 0x14, + 0x05, 0x1a, 0x00, 0xa2, 0xfd, 0x00, 0x00, 0x65, 0x2d, 0x00, 0x00, 0x7d, 0xca, 0x03, 0x00, + 0xc5, 0x71, 0x08, 0x00, 0x79, 0x47, 0x00, 0x00, 0x78, 0x24, 0x08, 0x00, 0xf0, 0xb5, 0x07, + 0x1c, 0xba, 0x69, 0x50, 0x78, 0xfe, 0x69, 0x25, 0x21, 0x43, 0x1a, 0xe4, 0x49, 0x32, 0xd0, + 0x01, 0x3b, 0x68, 0xd1, + + 0x01, 0x05, 0xff, 0xff, 0xb2, 0x6a, 0x08, 0x00, 0xfa, 0x04, 0x23, 0xb3, 0x80, 0x0c, 0x23, + 0x9d, 0x19, 0x40, 0x00, 0x12, 0x78, 0x02, 0x43, 0x2a, 0x70, 0x01, 0x35, 0x08, 0x78, 0x2a, + 0x28, 0x05, 0xd0, 0x33, 0x28, 0x01, 0xd1, 0x0a, 0x20, 0x02, 0xe0, 0x07, 0x20, 0x00, 0xe0, + 0x08, 0x20, 0x28, 0x70, 0x01, 0x35, 0x28, 0x1c, 0x0d, 0x21, 0x01, 0x24, 0xa6, 0x46, 0x4b, + 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x05, 0x1c, 0xa6, 0x46, 0x4b, 0x48, 0xfe, 0x44, 0x00, 0x47, + 0x82, 0x02, 0xd2, 0x48, 0x00, 0x78, 0x40, 0x06, 0x41, 0x0e, 0x11, 0x43, 0x45, 0x48, 0x08, + 0x43, 0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, 0xa6, 0x46, 0x41, 0x4a, 0xfe, 0x44, 0x10, 0x47, + 0x2f, 0xe0, 0x04, 0x23, 0xb3, 0x80, 0x0c, 0x23, 0x9d, 0x19, 0x40, 0x00, 0x12, 0x78, 0x02, + 0x43, 0x2a, 0x70, 0x01, 0x35, 0x08, 0x78, 0x2a, 0x28, 0x05, 0xd0, 0x33, 0x28, 0x01, 0xd1, + 0x0a, 0x20, 0x02, 0xe0, 0x07, 0x20, 0x00, 0xe0, 0x08, 0x20, 0x28, 0x70, 0x01, 0x35, 0x28, + 0x1c, 0x0d, 0x21, 0x01, 0x24, 0xa6, 0x46, 0x33, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x05, 0x1c, + 0xa6, 0x46, 0x32, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x82, 0x02, 0xb9, 0x48, 0x00, 0x78, 0x40, + 0x06, 0x41, 0x0e, 0x11, 0x43, 0x2d, 0x48, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, + 0xa6, 0x46, 0x29, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x06, 0x20, 0x70, 0x80, 0x03, 0x20, 0x30, + 0x80, 0xe3, 0x48, 0xe2, 0x49, 0x08, 0x18, 0x38, 0x62, 0xf0, 0xbd, 0xc0, 0x46, 0x76, 0xa0, + 0x1b, 0x00, 0xc5, 0x8e, 0x00, 0x00, 0x5b, 0x19, 0x04, 0x00, 0x10, 0xb5, 0xde, 0x48, 0x00, + 0x21, 0x01, 0x24, 0xa6, 0x46, 0xdd, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0xdc, 0x49, 0x01, 0x28, + 0x01, 0xd0, 0x00, 0x20, + + 0x01, 0x05, 0xff, 0xff, 0xac, 0x6b, 0x08, 0x00, 0xfa, 0x01, 0xe0, 0x08, 0x68, 0x01, 0x30, + 0x08, 0x60, 0xa6, 0x46, 0xd9, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x00, 0x28, 0x06, 0xd0, 0x0b, + 0x48, 0x00, 0x78, 0x02, 0x28, 0x02, 0xd1, 0x02, 0x20, 0xd5, 0x49, 0x08, 0x80, 0x10, 0xbd, + 0xba, 0x53, 0x08, 0x00, 0x90, 0xa1, 0x1b, 0x00, 0xa8, 0x59, 0x08, 0x00, 0x25, 0x6f, 0x04, + 0x00, 0x79, 0x6c, 0x04, 0x00, 0x05, 0x04, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x05, 0x10, + 0x00, 0x00, 0x45, 0x10, 0x08, 0x00, 0xc1, 0x72, 0x03, 0x00, 0x1b, 0x5f, 0x03, 0x00, 0x53, + 0x38, 0x02, 0x00, 0x21, 0xf0, 0x04, 0x00, 0xdb, 0x8e, 0x04, 0x00, 0xfc, 0x53, 0x08, 0x00, + 0xc6, 0x02, 0x00, 0x00, 0x8d, 0x8f, 0x04, 0x00, 0xf9, 0x2d, 0x00, 0x00, 0x00, 0x82, 0xff, + 0xff, 0xa9, 0x57, 0x05, 0x00, 0xf8, 0xb5, 0x80, 0x8a, 0xff, 0x21, 0x0b, 0x31, 0x88, 0x42, + 0x5c, 0xd0, 0xff, 0x21, 0x45, 0x31, 0x88, 0x42, 0x16, 0xd1, 0xc1, 0x48, 0x00, 0x78, 0x02, + 0x28, 0x12, 0xd1, 0xb9, 0x49, 0xff, 0x20, 0x41, 0x30, 0x40, 0x18, 0x00, 0x90, 0xb8, 0x48, + 0x40, 0x5c, 0x00, 0x26, 0x86, 0x42, 0x10, 0xd3, 0x51, 0x25, 0xad, 0x00, 0x28, 0x1c, 0x01, + 0x24, 0xa6, 0x46, 0xb4, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x00, 0x28, 0x6d, 0xd1, 0x28, 0x1c, + 0xb2, 0x49, 0xa6, 0x46, 0xb2, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0xf8, 0xbd, 0xb1, 0x00, 0x00, + 0x98, 0x45, 0x58, 0x00, 0x2d, 0x30, 0xd0, 0xfe, 0x20, 0x40, 0x5d, 0x00, 0x28, 0x2c, 0xd0, + 0xf2, 0x20, 0x41, 0x5d, 0x00, 0x29, 0x28, 0xd1, 0xff, 0x20, 0x02, 0x30, 0x40, 0x5d, 0x01, + 0x28, 0x23, 0xd0, 0x24, 0x20, 0x01, 0x24, 0xa6, 0x46, 0xa6, 0x4a, 0xfe, 0x44, 0x10, 0x47, + 0x00, 0x06, 0x00, 0x0e, + + 0x01, 0x05, 0xff, 0xff, 0xa6, 0x6c, 0x08, 0x00, 0xfa, 0xf3, 0x22, 0x51, 0x5d, 0x81, 0x42, + 0x17, 0xd0, 0x50, 0x55, 0x00, 0x28, 0x14, 0xd1, 0x2f, 0x8d, 0x39, 0x1c, 0xe7, 0x48, 0xa6, + 0x46, 0xe7, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x29, 0x8e, 0x79, 0x18, 0x08, 0x1a, 0x40, 0x1e, + 0x39, 0x1c, 0xa6, 0x46, 0xe3, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x40, 0x00, 0x28, 0x86, 0x28, + 0x8e, 0x40, 0x08, 0x28, 0x86, 0x01, 0x36, 0xdf, 0x48, 0x00, 0x78, 0xb2, 0xe7, 0x00, 0x20, + 0x01, 0x24, 0xa6, 0x46, 0xdd, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x01, 0x1c, 0x00, 0x90, 0xdc, + 0x4d, 0x28, 0x68, 0x01, 0x30, 0x28, 0x60, 0x0b, 0x27, 0x7f, 0x01, 0xda, 0x4e, 0xda, 0x48, + 0x00, 0x8d, 0x32, 0x68, 0x10, 0x18, 0x80, 0x01, 0x80, 0x09, 0xa6, 0x46, 0xd8, 0x4a, 0xfe, + 0x44, 0x10, 0x47, 0x00, 0x28, 0x11, 0xdd, 0x00, 0x98, 0x30, 0x60, 0x28, 0x68, 0x03, 0x28, + 0x0a, 0xd9, 0x00, 0x20, 0xa6, 0x46, 0xd3, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xcf, 0x48, 0x38, + 0x5c, 0xa6, 0x46, 0xd0, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x00, 0x20, 0x28, 0x60, 0xf8, 0xbd, + 0x30, 0xb5, 0x05, 0x69, 0x24, 0x20, 0x00, 0x21, 0x01, 0x24, 0xa6, 0x46, 0x7a, 0x4a, 0xfe, + 0x44, 0x10, 0x47, 0xf3, 0x21, 0x48, 0x55, 0x51, 0x25, 0xad, 0x00, 0x28, 0x1c, 0xa6, 0x46, + 0x72, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x00, 0x28, 0x05, 0xd1, 0x28, 0x1c, 0x70, 0x49, 0xa6, + 0x46, 0x70, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x30, 0xbd, 0xed, 0x49, 0x02, 0x00, 0xab, 0x11, + 0x08, 0x00, 0x63, 0x66, 0x08, 0x00, 0x99, 0x2d, 0x00, 0x00, 0xe9, 0x63, 0x05, 0x00, 0x41, + 0x69, 0x00, 0x7e, 0x00, 0x28, 0x11, 0xd1, 0xff, 0x22, 0x04, 0x32, 0x50, 0x5c, 0x01, 0x28, + 0x0c, 0xd1, 0xff, 0x20, + + 0x01, 0x05, 0xff, 0xff, 0xa0, 0x6d, 0x08, 0x00, 0xfa, 0x05, 0x30, 0x43, 0x5c, 0x1b, 0x2b, + 0x07, 0xd1, 0xff, 0x23, 0x0a, 0x33, 0x5b, 0x5c, 0x01, 0x2b, 0x02, 0xd1, 0x00, 0x23, 0x53, + 0x54, 0x43, 0x54, 0xf7, 0x46, 0xc0, 0x46, 0x00, 0x00, 0x08, 0x00, 0x49, 0x8f, 0x03, 0x00, + 0x85, 0x48, 0x02, 0x00, 0x10, 0xb5, 0x80, 0x69, 0x00, 0x88, 0x02, 0x28, 0x13, 0xd1, 0x54, + 0x48, 0x9c, 0x30, 0x01, 0x79, 0xff, 0x29, 0x0e, 0xd0, 0x00, 0x78, 0x03, 0x28, 0x03, 0xd0, + 0x01, 0x28, 0x01, 0xd0, 0x02, 0x28, 0x07, 0xd1, 0x01, 0x20, 0x04, 0x1c, 0x86, 0x46, 0xa2, + 0x49, 0xfe, 0x44, 0x08, 0x47, 0xa2, 0x48, 0x04, 0x70, 0x10, 0xbd, 0x25, 0x00, 0x00, 0x00, + 0x10, 0xb5, 0xc0, 0x69, 0x80, 0x78, 0x80, 0x38, 0x00, 0x06, 0x00, 0x0e, 0x02, 0x28, 0x13, + 0xd1, 0x44, 0x48, 0x9c, 0x30, 0x01, 0x79, 0xff, 0x29, 0x0e, 0xd0, 0x00, 0x78, 0x03, 0x28, + 0x03, 0xd0, 0x01, 0x28, 0x01, 0xd0, 0x02, 0x28, 0x07, 0xd1, 0x01, 0x20, 0x04, 0x1c, 0x86, + 0x46, 0x93, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x92, 0x48, 0x04, 0x70, 0x10, 0xbd, 0xc0, 0x46, + 0x69, 0x53, 0x08, 0x00, 0xff, 0x53, 0x08, 0x00, 0x10, 0xb5, 0x00, 0x69, 0xfe, 0x21, 0x09, + 0x5c, 0x02, 0x29, 0x06, 0xd0, 0xd0, 0x21, 0x09, 0x58, 0x82, 0x8d, 0xd2, 0x00, 0x54, 0x23, + 0x1b, 0x18, 0x05, 0xe0, 0x54, 0x21, 0x0b, 0x18, 0x02, 0x8d, 0x06, 0x20, 0x42, 0x43, 0xd9, + 0x6f, 0x50, 0x18, 0x80, 0x01, 0x81, 0x09, 0xd8, 0x6d, 0x01, 0x24, 0xa6, 0x46, 0x7f, 0x4a, + 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0x12, 0xdc, 0x28, 0x48, 0x9c, 0x30, 0x01, 0x79, 0xff, + 0x29, 0x0d, 0xd0, 0x00, 0x78, 0x03, 0x28, 0x03, 0xd0, 0x01, 0x28, 0x01, 0xd0, 0x02, 0x28, + 0x06, 0xd1, 0x20, 0x1c, + + 0x01, 0x05, 0xff, 0xff, 0x9a, 0x6e, 0x08, 0x00, 0xfa, 0xa6, 0x46, 0x77, 0x49, 0xfe, 0x44, + 0x08, 0x47, 0x77, 0x48, 0x04, 0x70, 0x10, 0xbd, 0x10, 0xb5, 0x1b, 0x48, 0x00, 0x68, 0x50, + 0x28, 0x06, 0xd9, 0x17, 0x48, 0x00, 0x21, 0x01, 0x22, 0x96, 0x46, 0x78, 0x4a, 0xfe, 0x44, + 0x10, 0x47, 0x71, 0x48, 0x00, 0x78, 0xff, 0x21, 0x21, 0x31, 0x41, 0x43, 0x6e, 0x48, 0x41, + 0x18, 0x6f, 0x4c, 0x20, 0x78, 0x14, 0x28, 0x0d, 0xda, 0x00, 0x28, 0x14, 0xd0, 0x6d, 0x49, + 0x09, 0x78, 0xc9, 0x08, 0x05, 0xd3, 0x01, 0x20, 0x86, 0x46, 0x6b, 0x49, 0xfe, 0x44, 0x08, + 0x47, 0x20, 0x78, 0x40, 0x1c, 0x07, 0xe0, 0xff, 0x20, 0x08, 0x70, 0x01, 0x20, 0x86, 0x46, + 0x67, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x00, 0x20, 0x20, 0x70, 0x10, 0xbd, 0xc0, 0x46, 0x4e, + 0x05, 0x00, 0x00, 0xb5, 0xcc, 0x00, 0x00, 0xf8, 0x21, 0x19, 0x00, 0xb3, 0x08, 0x05, 0x00, + 0x5c, 0x66, 0x08, 0x00, 0x71, 0xcd, 0x01, 0x00, 0x4a, 0x24, 0x19, 0x00, 0x54, 0x24, 0x08, + 0x00, 0x07, 0x0e, 0x00, 0x00, 0x21, 0xcb, 0x03, 0x00, 0x00, 0x66, 0xe3, 0x01, 0x0b, 0xc9, + 0x03, 0x00, 0x2b, 0xf0, 0x04, 0x00, 0x45, 0x10, 0x08, 0x00, 0xf0, 0xb5, 0x06, 0x1c, 0x74, + 0x69, 0x30, 0x69, 0x5d, 0x4d, 0x29, 0x78, 0x33, 0x7e, 0x0a, 0x22, 0x9b, 0x1a, 0x6d, 0xd0, + 0x06, 0x3b, 0x53, 0xd0, 0x31, 0x3b, 0x2e, 0xd0, 0x3b, 0x3b, 0x03, 0x2b, 0x78, 0xd8, 0xff, + 0x21, 0x7d, 0x31, 0x09, 0x5d, 0x02, 0x29, 0x73, 0xd1, 0xff, 0x22, 0x81, 0x32, 0x01, 0x78, + 0x11, 0x55, 0xff, 0x21, 0x82, 0x31, 0x09, 0x19, 0x42, 0x78, 0x01, 0x30, 0x0a, 0x70, 0xff, + 0x22, 0x83, 0x32, 0x12, 0x19, 0x43, 0x78, 0x13, 0x70, 0x40, 0x78, 0xff, 0x23, 0x25, 0x33, + 0x18, 0x55, 0x08, 0x78, + + 0x01, 0x05, 0xff, 0xff, 0x94, 0x6f, 0x08, 0x00, 0xfa, 0x19, 0x28, 0x5d, 0xd1, 0x10, 0x78, + 0x37, 0x28, 0x5a, 0xd1, 0x20, 0x1c, 0x05, 0x21, 0x00, 0x22, 0x01, 0x25, 0xae, 0x46, 0x3d, + 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x20, 0x1c, 0xae, 0x46, 0x3c, 0x49, 0xfe, 0x44, 0x08, 0x47, + 0x48, 0xe0, 0x00, 0x29, 0x0a, 0xd1, 0x8a, 0x20, 0x00, 0x19, 0x3b, 0x49, 0x30, 0x22, 0x01, + 0x23, 0x9e, 0x46, 0x3a, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x3f, 0xd1, 0xff, 0x20, + 0x5d, 0x30, 0x01, 0x5d, 0x05, 0x20, 0x03, 0x1c, 0x20, 0x1c, 0x41, 0x22, 0x01, 0x27, 0xbe, + 0x46, 0x34, 0x4f, 0xfe, 0x44, 0x38, 0x47, 0x20, 0x1c, 0x05, 0x21, 0x01, 0x22, 0x96, 0x46, + 0x2a, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x20, 0x28, 0x70, 0x25, 0xe0, 0xff, 0x21, 0x7d, + 0x31, 0x00, 0x78, 0x08, 0x55, 0x2c, 0x4a, 0x20, 0x1c, 0x09, 0x5c, 0x53, 0x78, 0x99, 0x42, + 0x02, 0xdb, 0x12, 0x78, 0x91, 0x42, 0x1c, 0xdd, 0xff, 0x21, 0x79, 0x31, 0x09, 0x5c, 0x10, + 0x22, 0x20, 0x23, 0x01, 0x24, 0xa6, 0x46, 0x23, 0x4c, 0xfe, 0x44, 0x20, 0x47, 0x0d, 0xe0, + 0x24, 0x48, 0x00, 0x78, 0x33, 0x28, 0x0d, 0xdb, 0xff, 0x20, 0x79, 0x30, 0x01, 0x5d, 0x20, + 0x1c, 0x29, 0x23, 0x01, 0x24, 0xa6, 0x46, 0x1c, 0x4c, 0xfe, 0x44, 0x20, 0x47, 0x17, 0x48, + 0x16, 0x49, 0x08, 0x18, 0x30, 0x62, 0xf0, 0xbd, 0xc0, 0x46, 0xff, 0xff, 0xff, 0x01, 0x95, + 0x49, 0x05, 0x00, 0x5b, 0x32, 0x08, 0x00, 0xd1, 0xa1, 0x04, 0x00, 0x50, 0x66, 0x08, 0x00, + 0x54, 0x66, 0x08, 0x00, 0x48, 0x10, 0x08, 0x00, 0x3f, 0xa2, 0x04, 0x00, 0xab, 0xea, 0x01, + 0x00, 0x3d, 0x1d, 0x03, 0x00, 0x58, 0x66, 0x08, 0x00, 0xb9, 0x26, 0x08, 0x00, 0x61, 0x66, + 0x08, 0x00, 0x60, 0x66, + + 0x01, 0x05, 0xff, 0xff, 0x8e, 0x70, 0x08, 0x00, 0xfa, 0x08, 0x00, 0x35, 0x57, 0x08, 0x00, + 0x5d, 0x9a, 0x03, 0x00, 0x43, 0x1c, 0x03, 0x00, 0xfd, 0x06, 0x05, 0x00, 0x7f, 0xa6, 0x01, + 0x00, 0xb3, 0x53, 0x04, 0x00, 0xa4, 0x0f, 0x00, 0x00, 0xf9, 0xd2, 0x00, 0x00, 0xdc, 0x0f, + 0x08, 0x00, 0x5f, 0x6a, 0x05, 0x00, 0xed, 0xe7, 0x00, 0x00, 0xb2, 0x11, 0x08, 0x00, 0x63, + 0x66, 0x08, 0x00, 0x69, 0x53, 0x08, 0x00, 0x40, 0x1e, 0x80, 0x00, 0x8c, 0x4b, 0x19, 0x50, + 0x8a, 0x49, 0x0a, 0x50, 0xf7, 0x46, 0xf0, 0xb5, 0x01, 0x1c, 0x88, 0x69, 0x82, 0x88, 0x53, + 0x04, 0x5b, 0x0c, 0x88, 0x4e, 0x88, 0x4f, 0x89, 0x4d, 0x03, 0xd0, 0x60, 0x2b, 0x01, 0xdc, + 0xb2, 0x42, 0x14, 0xd0, 0x82, 0x88, 0x01, 0x23, 0x1b, 0x03, 0x54, 0x04, 0x64, 0x0f, 0x24, + 0x03, 0x9c, 0x42, 0x08, 0xdb, 0x3b, 0x1c, 0x01, 0x33, 0x54, 0x04, 0x24, 0x0d, 0xe4, 0x00, + 0x9c, 0x42, 0x01, 0xda, 0xba, 0x42, 0x03, 0xd0, 0xff, 0x20, 0x88, 0x60, 0xe8, 0x1d, 0xf0, + 0xbd, 0x01, 0x24, 0xa6, 0x46, 0x7b, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x38, 0x1c, 0xa6, 0x46, + 0x7a, 0x49, 0xfe, 0x44, 0x08, 0x47, 0x30, 0x1c, 0xa6, 0x46, 0x77, 0x49, 0xfe, 0x44, 0x08, + 0x47, 0xa6, 0x46, 0x76, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x38, 0x1c, 0xa6, 0x46, 0x73, 0x49, + 0xfe, 0x44, 0x08, 0x47, 0xe8, 0x48, 0x01, 0x68, 0x30, 0x1c, 0xa6, 0x46, 0x71, 0x4a, 0xfe, + 0x44, 0x10, 0x47, 0x71, 0x48, 0x40, 0x19, 0xf0, 0xbd, 0x01, 0x1c, 0x0a, 0x7d, 0x6f, 0x48, + 0x00, 0x2a, 0x02, 0xd0, 0xc9, 0x68, 0x01, 0x29, 0x01, 0xd0, 0x4f, 0x30, 0xf7, 0x46, 0x31, + 0x30, 0xf7, 0x46, 0x41, 0x68, 0x02, 0x39, 0x41, 0x60, 0xe9, 0x48, 0x3f, 0x30, 0xf7, 0x46, + 0x1c, 0xb5, 0x41, 0x68, + + 0x01, 0x05, 0xff, 0xff, 0x88, 0x71, 0x08, 0x00, 0xfa, 0xe8, 0x4c, 0x00, 0x29, 0x17, 0xd0, + 0x41, 0x69, 0xb0, 0x20, 0x40, 0x18, 0xb8, 0x31, 0x6a, 0x46, 0x01, 0x23, 0x9e, 0x46, 0xe2, + 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x99, 0xe2, 0x48, 0xe4, 0x38, 0x41, 0x43, 0x68, 0x46, + 0x80, 0x88, 0x41, 0x18, 0xff, 0x20, 0xae, 0x30, 0x81, 0x42, 0x02, 0xd9, 0x20, 0x1c, 0xbf, + 0x30, 0x1c, 0xbd, 0x20, 0x1c, 0xdf, 0x30, 0x1c, 0xbd, 0x10, 0xb5, 0x04, 0x1c, 0xc8, 0x68, + 0x0a, 0x21, 0x01, 0x22, 0x96, 0x46, 0xe0, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0x00, + 0xd1, 0x8c, 0x20, 0xa0, 0x60, 0xde, 0x48, 0xdb, 0x30, 0x10, 0xbd, 0xde, 0x49, 0x04, 0x39, + 0x09, 0x78, 0x00, 0x29, 0x01, 0xd1, 0x00, 0x21, 0x41, 0x60, 0x41, 0x68, 0x42, 0x69, 0x51, + 0x1a, 0x41, 0x60, 0xd8, 0x48, 0x55, 0x30, 0xf7, 0x46, 0xd8, 0x49, 0x09, 0x78, 0x00, 0x29, + 0x04, 0xd1, 0x01, 0x7d, 0xd5, 0x48, 0x02, 0x30, 0xff, 0x22, 0x42, 0x54, 0xd5, 0x48, 0x4f, + 0x30, 0xf7, 0x46, 0x01, 0x1c, 0x8a, 0x69, 0x4b, 0x68, 0xd3, 0x48, 0x9a, 0x42, 0x01, 0xd9, + 0x3b, 0x30, 0xf7, 0x46, 0xca, 0x60, 0x79, 0x30, 0xf7, 0x46, 0xd1, 0x48, 0xcf, 0x49, 0x08, + 0x80, 0xd0, 0x48, 0xff, 0x30, 0xde, 0x30, 0xf7, 0x46, 0xc2, 0x69, 0xff, 0x21, 0x11, 0x31, + 0x8b, 0x5c, 0xcd, 0x49, 0x5b, 0x08, 0x08, 0xd3, 0xff, 0x23, 0x02, 0x33, 0x9a, 0x5c, 0x02, + 0x2a, 0x03, 0xd0, 0x01, 0x2a, 0x01, 0xd0, 0x03, 0x2a, 0x02, 0xd1, 0x08, 0x1c, 0x5b, 0x30, + 0xf7, 0x46, 0xff, 0x22, 0x42, 0x60, 0x08, 0x1c, 0x39, 0x30, 0xf7, 0x46, 0x00, 0xb5, 0x40, + 0x68, 0x01, 0x21, 0x8e, 0x46, 0xc2, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xc2, 0x48, 0x57, 0x30, + 0x00, 0xbd, 0x02, 0x8a, + + 0x01, 0x05, 0xff, 0xff, 0x82, 0x72, 0x08, 0x00, 0xfa, 0x01, 0x79, 0x0a, 0x29, 0x00, 0xdb, + 0x0a, 0x21, 0xe8, 0x48, 0x8a, 0x42, 0x01, 0xdd, 0x5f, 0x30, 0xf7, 0x46, 0x5b, 0x30, 0xf7, + 0x46, 0xf0, 0xb5, 0x01, 0x24, 0xa6, 0x46, 0xe4, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x01, 0x28, + 0x05, 0xd0, 0xa6, 0x46, 0xe1, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x04, 0x28, 0x19, 0xd1, 0x02, + 0x26, 0xdf, 0x4d, 0x28, 0x79, 0x00, 0x28, 0x11, 0xd0, 0xe8, 0x7a, 0x06, 0x28, 0x0e, 0xd1, + 0x0e, 0x20, 0x01, 0x1c, 0xea, 0x4f, 0x38, 0x1c, 0x14, 0x38, 0xa6, 0x46, 0xe7, 0x4a, 0xfe, + 0x44, 0x10, 0x47, 0x38, 0x1c, 0x0e, 0x21, 0xa6, 0x46, 0xe4, 0x4a, 0xfe, 0x44, 0x10, 0x47, + 0x70, 0x35, 0x01, 0x3e, 0xe7, 0xd1, 0xa6, 0x46, 0xe3, 0x48, 0xfe, 0x44, 0x00, 0x47, 0xe2, + 0x49, 0x0b, 0x48, 0x54, 0x30, 0x40, 0x18, 0xf0, 0xbd, 0xc0, 0x46, 0x04, 0xf3, 0x1a, 0x00, + 0x80, 0x7b, 0x08, 0x00, 0x03, 0x80, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0xc9, 0xfb, 0x04, + 0x00, 0xbb, 0x15, 0x04, 0x00, 0x7d, 0xca, 0x03, 0x00, 0x05, 0x43, 0x02, 0x00, 0x0b, 0xc9, + 0x03, 0x00, 0xab, 0x02, 0x00, 0x00, 0xb1, 0x33, 0x02, 0x00, 0xf0, 0xb5, 0x8d, 0xb0, 0x01, + 0x90, 0x81, 0x69, 0x02, 0x91, 0x01, 0x7d, 0x03, 0x91, 0x42, 0x68, 0x00, 0x92, 0x80, 0x8b, + 0x40, 0x00, 0x04, 0x90, 0x6b, 0x48, 0x83, 0x30, 0x00, 0x78, 0x40, 0x00, 0x05, 0x90, 0x00, + 0x29, 0x01, 0xd1, 0x00, 0x20, 0xe1, 0xe0, 0x04, 0x98, 0x02, 0x04, 0x12, 0x0c, 0x06, 0x92, + 0x02, 0x98, 0x03, 0x99, 0x6b, 0x46, 0x01, 0x24, 0xa6, 0x46, 0xc6, 0x4d, 0xfe, 0x44, 0x28, + 0x47, 0x07, 0x90, 0x00, 0x9e, 0x00, 0x20, 0x08, 0x90, 0x80, 0x48, 0x09, 0x90, 0x0a, 0x90, + 0x7f, 0xe0, 0x09, 0x98, + + 0x01, 0x05, 0xff, 0xff, 0x7c, 0x73, 0x08, 0x00, 0xfa, 0x00, 0x28, 0x2b, 0xd0, 0x0b, 0x98, + 0x09, 0x90, 0x28, 0xe0, 0x05, 0x98, 0x87, 0x42, 0x25, 0xdb, 0x90, 0x79, 0x03, 0x28, 0x01, + 0xd0, 0x01, 0x28, 0x20, 0xd1, 0x79, 0x19, 0x05, 0x98, 0x08, 0x1a, 0x07, 0x99, 0xa6, 0x46, + 0xb8, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x07, 0x1c, 0x28, 0x1c, 0x07, 0x99, 0xa6, 0x46, 0xb5, + 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x01, 0x04, 0x09, 0x0c, 0x3a, 0x04, 0x12, 0x0c, 0x00, 0x20, + 0xa6, 0x46, 0xb1, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x04, 0xd1, 0x0a, 0x98, 0x00, + 0x28, 0x03, 0xd0, 0x0a, 0x97, 0x01, 0xe0, 0x00, 0x20, 0x0a, 0x90, 0xb6, 0x68, 0x00, 0x2e, + 0x03, 0xd0, 0x30, 0x88, 0x07, 0x99, 0x88, 0x42, 0x49, 0xdb, 0x08, 0x98, 0x00, 0x28, 0x46, + 0xd1, 0x61, 0x49, 0x09, 0x98, 0x88, 0x42, 0x42, 0xd1, 0x0a, 0x98, 0x88, 0x42, 0x3f, 0xd1, + 0x03, 0x98, 0x00, 0x28, 0x2c, 0xd0, 0x02, 0x9d, 0x03, 0x98, 0x0c, 0x90, 0x00, 0x27, 0x28, + 0x88, 0x0b, 0x90, 0x04, 0x99, 0xa6, 0x46, 0x9c, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, + 0x07, 0xd0, 0x0b, 0x99, 0x04, 0x98, 0xa6, 0x46, 0x98, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, + 0x28, 0x11, 0xd1, 0x08, 0x98, 0xb8, 0x42, 0x09, 0xd0, 0x08, 0x98, 0xc1, 0x00, 0x02, 0x98, + 0x40, 0x18, 0x29, 0x1c, 0x08, 0x22, 0xa6, 0x46, 0xef, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x08, + 0x98, 0x40, 0x1c, 0x00, 0x06, 0x00, 0x0e, 0x08, 0x90, 0x08, 0x35, 0x01, 0x37, 0x0c, 0x98, + 0x01, 0x38, 0x0c, 0x90, 0xd6, 0xd1, 0x08, 0x98, 0x00, 0x28, 0x0c, 0xd0, 0x02, 0x98, 0x08, + 0x99, 0x06, 0x9a, 0x6b, 0x46, 0xa6, 0x46, 0x85, 0x4d, 0xfe, 0x44, 0x28, 0x47, 0x07, 0x90, + 0x00, 0x9e, 0x3f, 0x48, + + 0x01, 0x05, 0xff, 0xff, 0x76, 0x74, 0x08, 0x00, 0xfa, 0x09, 0x90, 0x0a, 0x90, 0x00, 0x2e, + 0x3a, 0xd0, 0x35, 0x88, 0x07, 0x98, 0x85, 0x42, 0x36, 0xda, 0xb0, 0x68, 0x00, 0x28, 0x05, + 0xd0, 0x00, 0x88, 0x07, 0x99, 0x88, 0x42, 0x01, 0xdc, 0x47, 0x1b, 0x04, 0xe0, 0x07, 0x98, + 0x40, 0x1b, 0x00, 0x99, 0x09, 0x88, 0x0f, 0x18, 0x72, 0x68, 0x91, 0x88, 0x05, 0x98, 0x40, + 0x18, 0x87, 0x42, 0x00, 0xda, 0x6a, 0xe7, 0x48, 0x19, 0x07, 0x99, 0xa6, 0x46, 0x73, 0x4a, + 0xfe, 0x44, 0x10, 0x47, 0x0b, 0x90, 0x79, 0x19, 0x05, 0x98, 0x08, 0x1a, 0x07, 0x99, 0xa6, + 0x46, 0x6e, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x0b, 0x98, 0x01, 0x04, + 0x09, 0x0c, 0x00, 0x20, 0xa6, 0x46, 0x6a, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x00, + 0xd1, 0x48, 0xe7, 0x00, 0x20, 0x09, 0x90, 0x06, 0xe0, 0xc0, 0x46, 0xe0, 0x31, 0x08, 0x00, + 0x1f, 0x48, 0x09, 0x99, 0x81, 0x42, 0x02, 0xd0, 0x09, 0x98, 0x0a, 0x90, 0x02, 0xe0, 0x0a, + 0x99, 0x81, 0x42, 0x01, 0xd0, 0x0a, 0x98, 0x04, 0xe0, 0x06, 0x98, 0xa6, 0x46, 0xe8, 0x49, + 0xfe, 0x44, 0x08, 0x47, 0x01, 0x99, 0x48, 0x60, 0xe5, 0x48, 0xff, 0x30, 0x10, 0x30, 0x0d, + 0xb0, 0xf0, 0xbd, 0xb7, 0x4b, 0x04, 0x00, 0x4f, 0x81, 0x03, 0x00, 0xfd, 0x79, 0x00, 0x00, + 0xc6, 0x05, 0x00, 0x00, 0xe0, 0x49, 0x09, 0x78, 0x2a, 0x29, 0x05, 0xd0, 0x33, 0x29, 0x01, + 0xd1, 0x0a, 0x21, 0x02, 0xe0, 0x06, 0x21, 0x00, 0xe0, 0x08, 0x21, 0x41, 0x60, 0xf1, 0x48, + 0x43, 0x30, 0xf7, 0x46, 0xc0, 0x46, 0x65, 0x2d, 0x00, 0x00, 0x79, 0x47, 0x00, 0x00, 0x0d, + 0x13, 0x02, 0x00, 0x76, 0x24, 0x08, 0x00, 0xe0, 0xa0, 0x1b, 0x00, 0x89, 0x28, 0x05, 0x00, + 0x3d, 0x39, 0x02, 0x00, + + 0x01, 0x05, 0xff, 0xff, 0x70, 0x75, 0x08, 0x00, 0xfa, 0x60, 0x5b, 0x08, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xd9, 0xaa, 0x00, 0x00, 0xd5, 0x75, 0x00, 0x00, 0x23, 0x01, 0x05, 0x00, 0xb3, + 0x09, 0x02, 0x00, 0xfc, 0xb5, 0x00, 0x90, 0xe2, 0x48, 0x00, 0x78, 0x02, 0x28, 0x43, 0xd1, + 0xe1, 0x49, 0xff, 0x20, 0x41, 0x30, 0x40, 0x18, 0x01, 0x90, 0xe0, 0x48, 0x40, 0x5c, 0x00, + 0x26, 0x38, 0xe0, 0xb1, 0x00, 0x01, 0x98, 0x45, 0x58, 0x00, 0x2d, 0x30, 0xd0, 0xfe, 0x20, + 0x40, 0x5d, 0x00, 0x28, 0x2c, 0xd0, 0xf2, 0x20, 0x41, 0x5d, 0x00, 0x29, 0x28, 0xd1, 0xff, + 0x20, 0x02, 0x30, 0x40, 0x5d, 0x01, 0x28, 0x23, 0xd0, 0x24, 0x20, 0x01, 0x24, 0xa6, 0x46, + 0xe7, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x06, 0x00, 0x0e, 0xf3, 0x22, 0x51, 0x5d, 0x81, + 0x42, 0x17, 0xd0, 0x50, 0x55, 0x00, 0x28, 0x14, 0xd1, 0x2f, 0x8d, 0x39, 0x1c, 0xe1, 0x48, + 0xa6, 0x46, 0x24, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x29, 0x8e, 0x79, 0x18, 0x08, 0x1a, 0x40, + 0x1e, 0x39, 0x1c, 0xa6, 0x46, 0x20, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x40, 0x00, 0x28, 0x86, + 0x28, 0x8e, 0x40, 0x08, 0x28, 0x86, 0x01, 0x36, 0xd8, 0x48, 0x00, 0x78, 0x86, 0x42, 0xc4, + 0xd3, 0xff, 0x21, 0x41, 0x31, 0x00, 0x98, 0x41, 0x60, 0xd6, 0x48, 0xd5, 0x49, 0x08, 0x18, + 0xfc, 0xbd, 0xf9, 0x97, 0x00, 0x00, 0x8f, 0x8d, 0x01, 0x00, 0xa4, 0x13, 0x08, 0x00, 0x10, + 0xb5, 0x00, 0x79, 0x01, 0x28, 0x06, 0xd1, 0x88, 0x8b, 0x09, 0x7d, 0x01, 0x22, 0x96, 0x46, + 0xce, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0xce, 0x4c, 0x20, 0x78, 0x01, 0x28, 0x04, 0xd1, 0x01, + 0x20, 0x86, 0x46, 0xcc, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x00, 0x20, 0x20, 0x70, 0xca, 0x49, + 0xc5, 0x48, 0x88, 0x38, + + 0x01, 0x05, 0xff, 0xff, 0x6a, 0x76, 0x08, 0x00, 0xfa, 0x40, 0x18, 0x10, 0xbd, 0xc0, 0x46, + 0xe5, 0x06, 0x05, 0x00, 0x14, 0x05, 0x1a, 0x00, 0x77, 0xc5, 0x01, 0x00, 0xb9, 0xc5, 0x01, + 0x00, 0xa1, 0x95, 0x01, 0x00, 0x95, 0x49, 0x05, 0x00, 0x21, 0x96, 0x01, 0x00, 0xf0, 0xb5, + 0x86, 0xb0, 0x01, 0x92, 0x02, 0x91, 0x06, 0x1c, 0x88, 0x68, 0x00, 0x6a, 0x03, 0x90, 0x80, + 0x00, 0x01, 0x99, 0x44, 0x18, 0x04, 0x94, 0x04, 0x19, 0x05, 0x94, 0x04, 0x19, 0x01, 0x98, + 0x03, 0x99, 0x01, 0x25, 0xae, 0x46, 0xb8, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x04, 0x98, 0x03, + 0x99, 0xae, 0x46, 0xb5, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x05, 0x98, 0x03, 0x99, 0xae, 0x46, + 0xb2, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x02, 0x98, 0x80, 0x68, 0xc7, 0x69, 0x70, 0x68, 0x03, + 0x99, 0xae, 0x46, 0xae, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x00, 0x28, 0x50, 0xd1, 0x30, 0x68, + 0x39, 0x1c, 0x03, 0x9a, 0xae, 0x46, 0xab, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x47, + 0xd5, 0x70, 0x68, 0x39, 0x1c, 0x03, 0x9a, 0xae, 0x46, 0xa6, 0x4b, 0xfe, 0x44, 0x18, 0x47, + 0x00, 0x28, 0x3e, 0xd5, 0x30, 0x68, 0x01, 0x99, 0x02, 0x9a, 0x23, 0x1c, 0xae, 0x46, 0xa2, + 0x4f, 0xfe, 0x44, 0x38, 0x47, 0x00, 0x94, 0x30, 0x68, 0x01, 0x99, 0x04, 0x9a, 0x02, 0x9b, + 0xae, 0x46, 0x9f, 0x4f, 0xfe, 0x44, 0x38, 0x47, 0x00, 0x94, 0x30, 0x68, 0x02, 0x99, 0x89, + 0x68, 0xc9, 0x6a, 0x01, 0x9a, 0x02, 0x9b, 0xae, 0x46, 0x99, 0x4f, 0xfe, 0x44, 0x38, 0x47, + 0x01, 0x98, 0x04, 0x99, 0x05, 0x9a, 0x02, 0x9b, 0xae, 0x46, 0x96, 0x4f, 0xfe, 0x44, 0x38, + 0x47, 0x02, 0x98, 0x80, 0x68, 0x01, 0x6b, 0x05, 0x98, 0x01, 0x9a, 0x02, 0x9b, 0xae, 0x46, + 0x91, 0x4f, 0xfe, 0x44, + + 0x01, 0x05, 0xff, 0xff, 0x64, 0x77, 0x08, 0x00, 0xfa, 0x38, 0x47, 0x70, 0x68, 0x04, 0x99, + 0x02, 0x9a, 0x23, 0x1c, 0xae, 0x46, 0x8b, 0x4c, 0xfe, 0x44, 0x20, 0x47, 0x01, 0x98, 0x04, + 0x99, 0x03, 0x9a, 0xae, 0x46, 0x87, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x02, 0xd0, + 0x00, 0x20, 0xc0, 0x43, 0x00, 0xe0, 0x00, 0x20, 0x06, 0xb0, 0xf0, 0xbd, 0xf0, 0xb5, 0x85, + 0xb0, 0x45, 0x69, 0x86, 0x69, 0xc0, 0x69, 0x02, 0x90, 0x0f, 0x6a, 0x48, 0x6a, 0x03, 0x90, + 0x88, 0x6b, 0x04, 0x90, 0x28, 0x1c, 0x00, 0x95, 0x31, 0x6a, 0x89, 0x00, 0x4d, 0x19, 0x01, + 0x95, 0x4d, 0x19, 0x31, 0x68, 0x01, 0x29, 0x0d, 0xd1, 0x72, 0x69, 0x39, 0x1c, 0x01, 0x24, + 0xa6, 0x46, 0x0d, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x72, 0x69, 0x01, 0x98, 0xb9, 0x18, 0xa6, + 0x46, 0x09, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x68, 0x46, 0x02, 0x99, 0x2a, 0x1c, 0x01, 0x24, + 0xa6, 0x46, 0x71, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x73, 0x49, 0x70, 0x4d, 0x00, 0x28, 0x06, + 0xd0, 0x0c, 0x70, 0x28, 0x1c, 0x21, 0x30, 0x0d, 0xe0, 0xc0, 0x46, 0x5d, 0x5f, 0x05, 0x00, + 0x00, 0x20, 0x08, 0x70, 0xb2, 0x69, 0x03, 0x98, 0x04, 0x99, 0xa6, 0x46, 0x69, 0x4b, 0xfe, + 0x44, 0x18, 0x47, 0x28, 0x1c, 0xa9, 0x30, 0x05, 0xb0, 0xf0, 0xbd, 0x69, 0x48, 0x00, 0x78, + 0x00, 0x07, 0x40, 0x0e, 0x89, 0x6b, 0x49, 0x06, 0x89, 0x0c, 0x08, 0x18, 0x64, 0x49, 0x08, + 0x80, 0x65, 0x48, 0xc5, 0x30, 0xf7, 0x46, 0x01, 0x1c, 0x0a, 0x79, 0x63, 0x48, 0x06, 0x2a, + 0x03, 0xdb, 0x92, 0x1f, 0x4a, 0x60, 0x2f, 0x30, 0xf7, 0x46, 0x79, 0x30, 0xf7, 0x46, 0x01, + 0x1c, 0x88, 0x69, 0x43, 0x78, 0x3e, 0x22, 0x1a, 0x40, 0x5d, 0x48, 0x06, 0x2a, 0x05, 0xdb, + 0x9a, 0x06, 0x92, 0x0e, + + 0x01, 0x05, 0xff, 0xff, 0x5e, 0x78, 0x08, 0x00, 0xfa, 0x06, 0x3a, 0x4a, 0x60, 0x23, 0x30, + 0xf7, 0x46, 0x49, 0x30, 0xf7, 0x46, 0x30, 0xb5, 0x45, 0x68, 0xff, 0x20, 0x11, 0x30, 0x40, + 0x5d, 0x80, 0x09, 0x0c, 0xd3, 0x11, 0x21, 0x09, 0x01, 0x4a, 0x5d, 0xdf, 0x20, 0x10, 0x40, + 0x48, 0x55, 0x28, 0x1c, 0x00, 0x21, 0x01, 0x22, 0x96, 0x46, 0x50, 0x4a, 0xfe, 0x44, 0x10, + 0x47, 0x01, 0x20, 0x04, 0x1c, 0x86, 0x46, 0x4e, 0x49, 0xfe, 0x44, 0x08, 0x47, 0xa9, 0x8b, + 0x28, 0x1c, 0xa6, 0x46, 0x4c, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0x4c, 0x48, 0x9b, 0x30, 0x30, + 0xbd, 0x6d, 0x95, 0x00, 0x00, 0x4d, 0x96, 0x01, 0x00, 0x69, 0x53, 0x08, 0x00, 0x10, 0xb5, + 0x02, 0x1c, 0x4c, 0x20, 0x43, 0x5a, 0x46, 0x48, 0x06, 0x2b, 0x0d, 0xdb, 0x19, 0x24, 0xe4, + 0x01, 0xa3, 0x42, 0x09, 0xdc, 0x54, 0x23, 0x59, 0x5a, 0x0a, 0x29, 0x05, 0xdb, 0xa1, 0x42, + 0x03, 0xdc, 0x00, 0x21, 0x51, 0x60, 0x99, 0x30, 0x10, 0xbd, 0x3f, 0x4a, 0x00, 0x21, 0xff, + 0x23, 0x21, 0x33, 0x4b, 0x43, 0xd3, 0x5c, 0xff, 0x2b, 0x04, 0xd0, 0x49, 0x1c, 0x09, 0x06, + 0x09, 0x0e, 0x0a, 0x29, 0xf4, 0xdb, 0x49, 0x1e, 0x39, 0x4a, 0x11, 0x70, 0x01, 0x21, 0x38, + 0x4a, 0x11, 0x70, 0xff, 0x30, 0x26, 0x30, 0x10, 0xbd, 0xc0, 0x46, 0x7b, 0x5e, 0x02, 0x00, + 0x45, 0x10, 0x08, 0x00, 0x54, 0x24, 0x08, 0x00, 0x07, 0x0e, 0x00, 0x00, 0x7f, 0xb5, 0x45, + 0x69, 0x10, 0x26, 0x32, 0x1c, 0x68, 0x46, 0x00, 0x21, 0x01, 0x24, 0xa6, 0x46, 0x2e, 0x4b, + 0xfe, 0x44, 0x18, 0x47, 0xff, 0x20, 0x31, 0x30, 0x40, 0x19, 0x69, 0x46, 0x32, 0x1c, 0xa6, + 0x46, 0x2b, 0x4b, 0xfe, 0x44, 0x18, 0x47, 0x00, 0x28, 0x08, 0xd1, 0xff, 0x20, 0x25, 0x30, + 0x05, 0x21, 0x41, 0x55, + + 0x01, 0x05, 0xff, 0xff, 0x58, 0x79, 0x08, 0x00, 0xfa, 0x28, 0x1c, 0xa6, 0x46, 0x26, 0x49, + 0xfe, 0x44, 0x08, 0x47, 0x26, 0x48, 0x6f, 0x30, 0x00, 0x90, 0x7f, 0xbd, 0x25, 0x48, 0xa5, + 0x30, 0xf7, 0x46, 0x2b, 0xf0, 0x04, 0x00, 0xff, 0xff, 0xff, 0x01, 0x5b, 0x32, 0x08, 0x00, + 0x8f, 0x02, 0x00, 0x00, 0xcd, 0x92, 0x01, 0x00, 0x6f, 0x4b, 0x02, 0x00, 0x58, 0x66, 0x08, + 0x00, 0x43, 0x1c, 0x03, 0x00, 0xf5, 0x70, 0x00, 0x00, 0x21, 0x37, 0x05, 0x00, 0xe9, 0x36, + 0x05, 0x00, 0xa9, 0x36, 0x05, 0x00, 0xc3, 0x6c, 0x05, 0x00, 0xa5, 0x6c, 0x05, 0x00, 0xd1, + 0x1c, 0x05, 0x00, 0x8d, 0x76, 0x08, 0x00, 0x91, 0x48, 0x05, 0x00, 0x47, 0x37, 0x05, 0x00, + 0x63, 0x66, 0x08, 0x00, 0x1c, 0x30, 0x19, 0x00, 0x96, 0xa5, 0x1b, 0x00, 0x61, 0x61, 0x03, + 0x00, 0xe1, 0x72, 0x03, 0x00, 0x5f, 0x73, 0x03, 0x00, 0xf5, 0x56, 0x02, 0x00, 0xbb, 0x88, + 0x03, 0x00, 0x3b, 0x3b, 0x02, 0x00, 0x9d, 0xcf, 0x02, 0x00, 0x6d, 0x23, 0x03, 0x00, 0xb9, + 0x26, 0x08, 0x00, 0x61, 0x66, 0x08, 0x00, 0x60, 0x66, 0x08, 0x00, 0xe9, 0x63, 0x05, 0x00, + 0x5f, 0x6a, 0x05, 0x00, 0xd5, 0x12, 0x04, 0x00, 0x5f, 0xde, 0x04, 0x00, 0xbd, 0x65, 0x01, + 0x00, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xc0, 0xf9, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, + 0xff, 0xf7, 0xd9, 0xf9, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0x00, 0xf9, 0xff, + 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xb5, 0xf8, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, + 0xff, 0xf7, 0x3a, 0xfa, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0x81, 0xfa, 0xff, + 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0xdc, 0xf9, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, + 0xff, 0xf7, 0xf9, 0xf9, + + 0x01, 0x05, 0xff, 0x6b, 0x52, 0x7a, 0x08, 0x00, 0x66, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, + 0xfe, 0xf7, 0x41, 0xfe, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xfe, 0xf7, 0x73, 0xfe, 0xff, + 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xfe, 0xf7, 0x19, 0xfe, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, + 0xfe, 0xf7, 0xff, 0xfd, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xfe, 0xf7, 0x08, 0xfe, 0xff, + 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xff, 0xf7, 0x07, 0xf8, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, + 0xff, 0xf7, 0x55, 0xf9, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xfe, 0xf7, 0xd5, 0xfe, 0xff, + 0xbd, 0xff, 0xb5, 0x68, 0x46, 0xfe, 0xf7, 0x7b, 0xfe, 0xff, 0xbd, 0xff, 0xb5, 0x68, 0x46, + 0xfe, 0xf7, 0x9c, 0xfe, 0xff, 0xbd, + + 0x01, 0x05, 0xff, 0x8d, 0x78, 0x7b, 0x08, 0x00, 0x88, 0x00, 0xb5, 0xf8, 0xf0, 0xe3, 0xfa, + 0x00, 0xbd, 0xd7, 0x70, 0x08, 0x00, 0x79, 0x71, 0x08, 0x00, 0x3d, 0x72, 0x08, 0x00, 0x6d, + 0x72, 0x08, 0x00, 0x81, 0x72, 0x08, 0x00, 0x99, 0x72, 0x08, 0x00, 0x35, 0x75, 0x08, 0x00, + 0x89, 0x75, 0x08, 0x00, 0x95, 0x77, 0x08, 0x00, 0x61, 0x71, 0x08, 0x00, 0xd5, 0x65, 0x08, + 0x00, 0xe5, 0x71, 0x08, 0x00, 0x01, 0x72, 0x08, 0x00, 0x19, 0x72, 0x08, 0x00, 0x2f, 0x72, + 0x08, 0x00, 0x29, 0x73, 0x08, 0x00, 0x39, 0x76, 0x08, 0x00, 0x1b, 0x78, 0x08, 0x00, 0x35, + 0x78, 0x08, 0x00, 0x4b, 0x78, 0x08, 0x00, 0x6b, 0x78, 0x08, 0x00, 0xc5, 0x71, 0x08, 0x00, + 0xbd, 0x78, 0x08, 0x00, 0x25, 0x79, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x79, 0x08, 0x00, + + 0x01, 0x05, 0xff, 0x85, 0x04, 0xf3, 0x1a, 0x00, 0x80, 0xce, 0xfb, 0x04, 0x00, 0xf4, 0x4b, + 0x04, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x06, 0x0a, 0x02, 0x00, 0x50, 0x98, 0x00, 0x00, 0xb4, + 0xc6, 0x01, 0x00, 0xb8, 0x5e, 0x02, 0x00, 0x58, 0x95, 0x01, 0x00, 0x2e, 0x49, 0x05, 0x00, + 0xde, 0x33, 0x02, 0x00, 0x14, 0x29, 0x02, 0x00, 0x60, 0x13, 0x02, 0x00, 0xd6, 0x28, 0x05, + 0x00, 0x74, 0x39, 0x02, 0x00, 0x88, 0xac, 0x00, 0x00, 0x7a, 0x95, 0x00, 0x00, 0xe8, 0x72, + 0x00, 0x00, 0x1c, 0x62, 0x03, 0x00, 0x0e, 0x73, 0x03, 0x00, 0x7e, 0x73, 0x03, 0x00, 0x34, + 0xd0, 0x02, 0x00, 0x52, 0x48, 0x00, 0x00, 0x04, 0x24, 0x03, 0x00, 0xa0, 0xde, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5a, 0x66, + 0x01, 0x00, + + 0x01, 0x05, 0xff, 0xff, 0x00, 0x00, 0x18, 0x00, 0xfa, 0x70, 0xb5, 0x3a, 0x4d, 0xae, 0x7f, + 0x01, 0x24, 0xa6, 0x46, 0x36, 0x48, 0xfe, 0x44, 0x00, 0x47, 0xb0, 0x42, 0xf8, 0xd1, 0x03, + 0x20, 0x17, 0x21, 0x89, 0x01, 0xa6, 0x46, 0x32, 0x4a, 0xfe, 0x44, 0x10, 0x47, 0xad, 0x7f, + 0xa6, 0x46, 0x2f, 0x48, 0xfe, 0x44, 0x00, 0x47, 0xa8, 0x42, 0xf9, 0xd1, 0xfe, 0xe7, 0x30, + 0xb5, 0x2e, 0x49, 0x08, 0x1f, 0x2e, 0x4a, 0x10, 0x60, 0x31, 0x48, 0x02, 0x1c, 0x71, 0x3a, + 0x93, 0x24, 0x01, 0x23, 0xa3, 0x54, 0x2b, 0x4b, 0x0b, 0x60, 0x02, 0x23, 0x13, 0x71, 0x2a, + 0x4b, 0x4b, 0x60, 0x03, 0x23, 0x53, 0x71, 0x29, 0x4b, 0x8b, 0x60, 0x04, 0x23, 0x03, 0x70, + 0x29, 0x4b, 0xcb, 0x60, 0x05, 0x23, 0x83, 0x73, 0x28, 0x4b, 0x0b, 0x61, 0x06, 0x23, 0x03, + 0x73, 0x27, 0x4b, 0x4b, 0x61, 0x07, 0x23, 0x43, 0x71, 0x26, 0x4b, 0x8b, 0x61, 0x08, 0x24, + 0x03, 0x1c, 0x33, 0x3b, 0x1c, 0x70, 0x24, 0x4b, 0xcb, 0x61, 0x09, 0x23, 0xd3, 0x74, 0x23, + 0x4b, 0x0b, 0x62, 0x0a, 0x23, 0xd3, 0x71, 0xd3, 0x1d, 0x22, 0x4c, 0x4c, 0x62, 0x0b, 0x24, + 0x44, 0x77, 0x21, 0x4c, 0x8c, 0x62, 0x0c, 0x25, 0x04, 0x1c, 0x3d, 0x3c, 0x25, 0x70, 0x1f, + 0x4c, 0xcc, 0x62, 0x0f, 0x38, 0x0d, 0x24, 0x04, 0x70, 0x1d, 0x4c, 0x0c, 0x63, 0x0e, 0x24, + 0x04, 0x73, 0x1c, 0x4c, 0x4c, 0x63, 0x0f, 0x24, 0x44, 0x73, 0x1b, 0x4c, 0x8c, 0x63, 0x10, + 0x24, 0x04, 0x77, 0x1a, 0x48, 0xc8, 0x63, 0x11, 0x20, 0x10, 0x70, 0x19, 0x48, 0x08, 0x64, + 0x12, 0x20, 0x98, 0x76, 0x18, 0x48, 0x48, 0x64, 0x30, 0xbd, 0xc0, 0x46, 0x25, 0x86, 0x04, + 0x00, 0x1b, 0x90, 0x04, 0x00, 0x6c, 0x52, 0x08, 0x00, 0x08, 0x66, 0x08, 0x00, 0x20, 0x55, + 0x08, 0x00, 0x73, 0x7a, + + 0x01, 0x05, 0xff, 0xff, 0xfa, 0x00, 0x18, 0x00, 0xfa, 0x08, 0x00, 0x5f, 0x7a, 0x08, 0x00, + 0x55, 0x7a, 0x08, 0x00, 0x95, 0x55, 0x08, 0x00, 0xa5, 0x7a, 0x08, 0x00, 0x7d, 0x7a, 0x08, + 0x00, 0x69, 0x7a, 0x08, 0x00, 0xaf, 0x7a, 0x08, 0x00, 0x9b, 0x7a, 0x08, 0x00, 0x87, 0x7a, + 0x08, 0x00, 0x19, 0x7a, 0x08, 0x00, 0x91, 0x7a, 0x08, 0x00, 0x23, 0x7a, 0x08, 0x00, 0x05, + 0x7a, 0x08, 0x00, 0x0f, 0x7a, 0x08, 0x00, 0x41, 0x7a, 0x08, 0x00, 0x4b, 0x7a, 0x08, 0x00, + 0x2d, 0x7a, 0x08, 0x00, 0x37, 0x7a, 0x08, 0x00, 0xf0, 0xb5, 0x31, 0x4e, 0x0c, 0x22, 0x32, + 0x70, 0x1a, 0x23, 0x73, 0x70, 0x09, 0x20, 0xb0, 0x70, 0x18, 0x20, 0xf0, 0x70, 0x03, 0x20, + 0x2e, 0x4d, 0x29, 0x1c, 0x01, 0x39, 0x01, 0x24, 0xa6, 0x46, 0x2a, 0x4f, 0xfe, 0x44, 0x38, + 0x47, 0xb2, 0x78, 0xf3, 0x78, 0x03, 0x20, 0x29, 0x1c, 0xa6, 0x46, 0x26, 0x4e, 0xfe, 0x44, + 0x30, 0x47, 0x03, 0x20, 0x29, 0x1c, 0x01, 0x31, 0xa6, 0x46, 0x25, 0x4a, 0xfe, 0x44, 0x10, + 0x47, 0xa6, 0x46, 0x24, 0x48, 0xfe, 0x44, 0x00, 0x47, 0x23, 0x4b, 0x00, 0x21, 0x08, 0x1c, + 0x1a, 0x68, 0x00, 0x2a, 0x04, 0xd0, 0x02, 0x07, 0x15, 0x0f, 0x22, 0x1c, 0xaa, 0x40, 0x11, + 0x43, 0x02, 0x07, 0x12, 0x0f, 0x0f, 0x2a, 0x05, 0xd1, 0xc5, 0x08, 0x06, 0x22, 0x2a, 0x40, + 0x1b, 0x4d, 0xa9, 0x52, 0x00, 0x21, 0x04, 0x33, 0x01, 0x30, 0x20, 0x28, 0xe9, 0xd3, 0x1a, + 0x48, 0x01, 0x1c, 0x50, 0x31, 0x0c, 0x70, 0x0a, 0x21, 0x16, 0x4a, 0x11, 0x70, 0x33, 0x21, + 0x01, 0x70, 0x00, 0x25, 0x16, 0x48, 0x05, 0x60, 0x28, 0x1c, 0xa6, 0x46, 0x16, 0x49, 0xfe, + 0x44, 0x08, 0x47, 0x13, 0x49, 0x08, 0x60, 0x14, 0x48, 0x05, 0x60, 0x07, 0x20, 0x14, 0x49, + 0x08, 0x70, 0x14, 0x4a, + + 0x01, 0x05, 0xff, 0x65, 0xf4, 0x01, 0x18, 0x00, 0x60, 0x91, 0x78, 0x02, 0x20, 0x08, 0x43, + 0x90, 0x70, 0x12, 0x48, 0x05, 0x70, 0x12, 0x48, 0x05, 0x70, 0x12, 0x48, 0x05, 0x70, 0xf0, + 0xbd, 0xc0, 0x46, 0xfc, 0x53, 0x08, 0x00, 0x31, 0x90, 0x04, 0x00, 0xc6, 0x05, 0x00, 0x00, + 0x1b, 0x90, 0x04, 0x00, 0x33, 0x00, 0x18, 0x00, 0x80, 0x7b, 0x08, 0x00, 0x84, 0xf3, 0x1a, + 0x00, 0x6d, 0x22, 0x08, 0x00, 0x69, 0x53, 0x08, 0x00, 0x50, 0x66, 0x08, 0x00, 0x54, 0x66, + 0x08, 0x00, 0xd1, 0xa1, 0x04, 0x00, 0x5c, 0x66, 0x08, 0x00, 0xb3, 0x11, 0x08, 0x00, 0xe4, + 0x15, 0x08, 0x00, 0x63, 0x66, 0x08, 0x00, 0x60, 0x66, 0x08, 0x00, 0x61, 0x66, 0x08, 0x00, + + + 0x01, 0x83, 0xff, 0x14, 0x79, 0x7b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + // + // ###### + // ### Set the BT Core spec to 4.2 for Bluetopia stack compatibility + // ### Remove below VS command for default BT core spec 5.1 + 0x01, 0x09, 0xfd, 0x08, 0x68, 0x53, 0x08, 0x00, 0x00, 0x2a, 0x00, 0xff, + + // ###### + // + 0x01, 0x0c, 0xfd, 0x09, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x64, 0x00, + + 0x01, 0x09, 0xfd, 0x08, 0x58, 0x60, 0x1a, 0x00, 0x00, 0x10, 0x00, 0x10, + + 0x01, 0x09, 0xfd, 0x08, 0x10, 0x60, 0x1a, 0x00, 0x10, 0x00, 0x10, 0x00, + + 0x01, 0x1c, 0xfd, 0x14, 0xff, 0x88, 0x13, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xfa, 0x00, 0xff, 0xff, 0x00, + + // + // + // ##-------------------------------------------------------------------------------- + // ## Description: ORCA_C Commercial PHY FW Initialization Script + // ##-------------------------------------------------------------------------------- + 0x01, 0x76, 0xfd, 0x31, 0x01, 0x21, 0x54, 0x00, 0x00, 0x61, 0x57, 0x00, 0x00, 0x14, 0x05, + 0x0a, 0x05, 0x00, 0x07, 0x06, 0x0a, 0x04, 0x05, 0x08, 0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + + // BTstack: added HCI_VS_SET_POWER_VECTOR(GFSK) 0xFD82 template + 0x01, 0x82, 0xfd, 0x14, 0x00, 0x9c, 0x18, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xdc, + 0xe6, 0xf0, 0xfa, 0x04, 0x0e, 0x18, 0xff, 0x00, 0x00, + + // BTstack: added HCI_VS_SET_POWER_VECTOR(EDR2) 0xFD82 template + 0x01, 0x82, 0xfd, 0x14, 0x01, 0x9c, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xd8, + 0xe2, 0xec, 0xf6, 0x00, 0x0a, 0x14, 0xff, 0x00, 0x00, + + // BTstack: added HCI_VS_SET_POWER_VECTOR(EDR3) 0xFD82 for EDR3 template + 0x01, 0x82, 0xfd, 0x14, 0x02, 0x9c, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xd8, + 0xe2, 0xec, 0xf6, 0x00, 0x0a, 0x14, 0xff, 0x00, 0x00, + + // BTstack: added HCI_VS_SET_CLASS2_SINGLE_POWER 0xFD87 template + 0x01, 0x87, 0xfd, 0x03, 0x0d, 0x0d, 0x0d, + + 0x01, 0x80, 0xfd, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + + 0x01, 0x80, 0xfd, 0x06, 0x3c, 0xf0, 0x5f, 0x00, 0x00, 0x00, + + // + // + // + 0x01, 0x38, 0xfe, 0x00, + + // + // ################################################################# + // ## START of CC2564 Adds-On + // ################################################################# + // + // ## Enable fast clock XTAL support + 0x01, 0x1c, 0xfd, 0x14, 0x01, 0x88, 0x13, 0x00, 0x00, 0xd0, 0x07, 0x00, 0x00, 0xff, 0xff, + 0x04, 0xff, 0xff, 0xff, 0xfa, 0x00, 0x00, 0x00, 0x00, + + // + // ## Enable eHCILL + 0x01, 0x2b, 0xfd, 0x05, 0x10, 0x00, 0x50, 0x00, 0x96, + + // + 0x01, 0x0c, 0xfd, 0x09, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0x64, 0x00, + + // + // ################################################################# + // ## END of CC2564 Adds-On + // ################################################################# + 0x01, 0x5b, 0xfd, 0x02, 0x01, 0x01, + + // + 0x01, 0xdd, 0xfd, 0x01, 0x01, + +}; + +const uint32_t cc256x_init_script_size = 6771; + +#endif \ No newline at end of file diff --git a/ports/stm32/boards/LEGO_HUB_NO6/board_init.c b/ports/stm32/boards/LEGO_HUB_NO6/board_init.c new file mode 100644 index 0000000000..3f22bfc8fc --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/board_init.c @@ -0,0 +1,170 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mphal.h" +#include "irq.h" + +void board_init(void) { + if (query_irq() == IRQ_STATE_DISABLED) { + enable_irq(IRQ_STATE_ENABLED); + } + + // Enable 3V3 for all ports + mp_hal_pin_output(pyb_pin_PORT_3V3_EN); + mp_hal_pin_high(pyb_pin_PORT_3V3_EN); + + // Port A + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTA_EN); + mp_hal_pin_low(pyb_pin_PORTA_EN); + + // Port B + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTB_EN); + mp_hal_pin_low(pyb_pin_PORTB_EN); + + // Port C + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTC_EN); + mp_hal_pin_low(pyb_pin_PORTC_EN); + + // Port D + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTD_EN); + mp_hal_pin_low(pyb_pin_PORTD_EN); + + // Port E + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTE_EN); + mp_hal_pin_low(pyb_pin_PORTE_EN); + // Disable RS485 driver + mp_hal_pin_output(pyb_pin_PORTE_RTS); + mp_hal_pin_low(pyb_pin_PORTE_RTS); + + // Port F + // Enable RX/TX buffer + mp_hal_pin_output(pyb_pin_PORTF_EN); + mp_hal_pin_low(pyb_pin_PORTF_EN); + // Disable RS485 driver + mp_hal_pin_output(pyb_pin_PORTF_RTS); + mp_hal_pin_low(pyb_pin_PORTF_RTS); +} + +#if BUILDING_MBOOT + +#include "mboot/mboot.h" +#include "boardctrl.h" +#include "adc.h" +#include "hub_display.h" + +#define RESET_MODE_NUM_STATES (4) +#define RESET_MODE_TIMEOUT_CYCLES (8) + +#define PATTERN_B (0x00651946) +#define PATTERN_F (0x0021184e) +#define PATTERN_N (0x01296ad2) +#define PATTERN_S (0x0064104c) + +static void board_led_pattern(int reset_mode, uint16_t brightness) { + static const uint32_t pixels[] = { + 0, + PATTERN_N, + PATTERN_S, + PATTERN_F, + PATTERN_B, + }; + uint32_t pixel = pixels[reset_mode]; + for (int i = 0; i < 25; ++i) { + hub_display_set(i, brightness * ((pixel >> i) & 1)); + } + hub_display_update(); +} + +static void board_button_init(void) { + mp_hal_pin_config(pin_A1, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0); + adc_config(ADC1, 12); +} + +static int board_button_state(void) { + uint16_t value = adc_config_and_read_u16(ADC1, 1, ADC_SAMPLETIME_15CYCLES); + return value < 44000; +} + +void board_mboot_cleanup(int reset_mode) { + board_led_pattern(0, 0); + hub_display_off(); +} + +void board_mboot_led_init(void) { + hub_display_on(); +} + +void board_mboot_led_state(int led, int state) { + if (state) { + hub_display_set(28, 0x7fff); + hub_display_set(31, 0x7fff); + } else { + hub_display_set(28, 0); + hub_display_set(31, 0); + } + hub_display_update(); +} + +int board_mboot_get_reset_mode(void) { + board_button_init(); + int reset_mode = BOARDCTRL_RESET_MODE_NORMAL; + if (board_button_state()) { + // Cycle through reset modes while USR is held. + // Timeout is roughly 20s, where reset_mode=1. + systick_init(); + hub_display_on(); + reset_mode = 0; + for (int i = 0; i < (RESET_MODE_NUM_STATES * RESET_MODE_TIMEOUT_CYCLES + 1) * 32; i++) { + if (i % 32 == 0) { + if (++reset_mode > RESET_MODE_NUM_STATES) { + reset_mode = BOARDCTRL_RESET_MODE_NORMAL; + } + board_led_pattern(reset_mode, 0x7fff); + } + if (!board_button_state()) { + break; + } + mp_hal_delay_ms(19); + } + // Flash the selected reset mode. + for (int i = 0; i < 6; i++) { + board_led_pattern(reset_mode, 0x0fff); + mp_hal_delay_ms(50); + board_led_pattern(reset_mode, 0x7fff); + mp_hal_delay_ms(50); + } + mp_hal_delay_ms(300); + } + board_led_pattern(0, 0); + return reset_mode; +} + +#endif diff --git a/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c b/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c new file mode 100644 index 0000000000..c54daf3002 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/cc2564.c @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/runtime.h" +#include "py/mphal.h" +#include "timer.h" +#include "extmod/mpbthci.h" + +#if !BUILDING_MBOOT + +#define CC2564_PIN_CTS (pyb_pin_BT_CTS) +#define CC2564_PIN_RTS (pyb_pin_BT_RTS) +#define CC2564_PIN_BT_SLOWCLK (pyb_pin_BT_SLOWCLK) +#define CC2564_PIN_BT_ENABLE (pyb_pin_BT_ENABLE) + +STATIC void cc2564_wait_cts_low(mp_hal_pin_obj_t cts, uint32_t timeout_ms) { + for (int i = 0; i < timeout_ms; ++i) { + if (mp_hal_pin_read(cts) == 0) { + break; + } + mp_hal_delay_ms(1); + } +} + +int mp_bluetooth_hci_controller_init(void) { + // Pull BTNSHUTD low to disable chip. + mp_hal_pin_output(CC2564_PIN_BT_ENABLE); + mp_hal_pin_low(CC2564_PIN_BT_ENABLE); + + // Output a 32768Hz signal on BTSLOWCLK. + // tim8 = pyb.Timer(8, freq=32768) + // tim8_ch4 = tim8.channel(4, pyb.Timer.PWM, pin=btclk) + // tim8_ch4.pulse_width_percent(50) + mp_obj_t args[6] = { MP_OBJ_NEW_SMALL_INT(8), MP_OBJ_NEW_QSTR(MP_QSTR_freq), MP_OBJ_NEW_SMALL_INT(32768), MP_OBJ_NULL }; + mp_obj_t tim8 = pyb_timer_type.make_new(&pyb_timer_type, 1, 1, args); + mp_load_method(tim8, MP_QSTR_channel, args); + args[2] = MP_OBJ_NEW_SMALL_INT(4); + args[3] = MP_OBJ_NEW_SMALL_INT(0); // CHANNEL_MODE_PWM_NORMAL + args[4] = MP_OBJ_NEW_QSTR(MP_QSTR_pin); + args[5] = (mp_obj_t)CC2564_PIN_BT_SLOWCLK; + mp_obj_t tim8_ch4 = mp_call_method_n_kw(2, 1, args); + mp_load_method(tim8_ch4, MP_QSTR_pulse_width_percent, args); + args[2] = MP_OBJ_NEW_SMALL_INT(50); + mp_call_method_n_kw(1, 0, args); + + // Pull BTNSHUTD high to enable chip and wait for CTS to go low to indicate ready. + mp_hal_pin_high(CC2564_PIN_BT_ENABLE); + cc2564_wait_cts_low(CC2564_PIN_CTS, 500); + + return 0; +} + +int mp_bluetooth_hci_controller_deinit(void) { + // Pull BTNSHUTD low to disable chip. + mp_hal_pin_low(CC2564_PIN_BT_ENABLE); + + return 0; +} + +#endif diff --git a/ports/stm32/boards/LEGO_HUB_NO6/hub_display.c b/ports/stm32/boards/LEGO_HUB_NO6/hub_display.c new file mode 100644 index 0000000000..1efc388c77 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/hub_display.c @@ -0,0 +1,180 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mphal.h" +#include "hub_display.h" + +// Map pixel number 0-24, and 25-36 to TLC bit number. +static const uint8_t hub_display_pixel_map[] = { + // 5x5 display + 9, 11, 6, 1, 14, + 10, 19, 8, 0, 26, + 23, 18, 3, 2, 24, + 21, 20, 15, 13, 25, + 22, 7, 17, 12, 38, + // RGB Bluetooth button + 27, 28, 29, + // RGB middle button (left and right) + 39, 40, 41, 42, 43, 44, + // RGB battery indicator + 45, 46, 47, +}; + +static bool hub_display_init; +static uint8_t hub_display_gs_state[96]; + +static void hub_display_tim_init(void) { + // TLC maximum GSCLK freq: 33MHz + + // tim12, ch2, pwm + + TIM_TypeDef *tim = TIM12; + + __HAL_RCC_TIM12_CLK_ENABLE(); + tim->CR1 = TIM_CR1_ARPE; + + // Configure PWM mode. + uint32_t ch = 1; // ch2 + uint32_t reg = 6 << TIM_CCMR1_OC1M_Pos // PWM1 mode + | 1 << TIM_CCMR1_OC1PE_Pos // preload enabled + | 0 << TIM_CCMR1_CC1S_Pos // output mode + ; + uint32_t shift = 8 * (ch & 1); + tim->CCMR1 = (tim->CCMR1 & ~(0xff << shift)) | reg << shift; + + // Enable output on pin, active high for normal channel. + reg = TIM_CCER_CC1E; + shift = 4 * ch; + tim->CCER = (tim->CCER & ~(0xf << shift)) | reg << shift; + + // Enable the timer if it's not already running. + tim->CR1 |= TIM_CR1_CEN; + + // fast + tim->PSC = 0; + tim->ARR = 2; + + // 50% duty + tim->CCR2 = 2; + tim->EGR = 1; // UG + + mp_hal_pin_config(pin_B15, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 9); +} + +static void hub_display_spi_init(void) { + // TLC maximum SPI freq: 25MHz + + SPI_TypeDef *spi = SPI1; + + __HAL_RCC_SPI1_CLK_ENABLE(); + spi->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | 0 << SPI_CR1_BR_Pos | SPI_CR1_MSTR; + spi->CR1 |= SPI_CR1_SPE; + + mp_hal_pin_config(pin_A5, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); + mp_hal_pin_config(pin_A6, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); + mp_hal_pin_config(pin_A7, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, 5); +} + +static void hub_display_spi_write(uint8_t value) { + SPI_TypeDef *spi = SPI1; + spi->DR = value; + while (!(spi->SR & SPI_SR_TXE)) { + } +} + +// dc: dot control +// mc: maximum current +// bc: global brightness control +// fc: function control +static void hub_display_latch_ctrl(uint8_t dc, uint32_t mc, uint32_t bc, uint8_t fc) { + hub_display_spi_write(1); // bit 768 + hub_display_spi_write(0x96); // bits 760-767 + for (int i = 0; i < 48; ++i) { + hub_display_spi_write(0); + } + hub_display_spi_write(fc >> 2); // bits 368-375 + hub_display_spi_write(fc << 6 | bc >> 15); // bits 360-367 + hub_display_spi_write(bc >> 7); // bits 352-359 + hub_display_spi_write(bc << 1 | mc >> 8); // bits 344-351 + hub_display_spi_write(mc); // bits 336-343 + for (int i = 0; i < 42; ++i) { + hub_display_spi_write(dc); + } + mp_hal_pin_high(pin_A15); + mp_hal_delay_us(1); + mp_hal_pin_low(pin_A15); +} + +void hub_display_set(uint8_t led, uint16_t value) { + led = hub_display_pixel_map[led]; + hub_display_gs_state[led * 2] = value; + hub_display_gs_state[led * 2 + 1] = value >> 8; +} + +void hub_display_update(void) { + if (!hub_display_init) { + return; + } + hub_display_spi_write(0); + for (int i = 0; i < 96; ++i) { + hub_display_spi_write(hub_display_gs_state[95 - i]); + } + mp_hal_pin_high(pin_A15); + mp_hal_delay_us(1); + mp_hal_pin_low(pin_A15); +} + +void hub_display_on(void) { + if (hub_display_init) { + return; + } + mp_hal_pin_output(pin_A15); + mp_hal_pin_low(pin_A15); + hub_display_spi_init(); + for (int i = 0; i < 2; ++i) { + hub_display_latch_ctrl(0xff, 0, 0x1fffff, 0x11); + } + hub_display_tim_init(); + hub_display_init = true; +} + +void hub_display_off(void) { + if (!hub_display_init) { + return; + } + __HAL_RCC_TIM12_CLK_DISABLE(); + __HAL_RCC_TIM12_FORCE_RESET(); + __HAL_RCC_TIM12_RELEASE_RESET(); + __HAL_RCC_SPI1_CLK_DISABLE(); + __HAL_RCC_SPI1_FORCE_RESET(); + __HAL_RCC_SPI1_RELEASE_RESET(); + mp_hal_pin_config(pin_A5, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pin_A6, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pin_A7, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pin_A15, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config(pin_B15, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); + hub_display_init = false; +} diff --git a/ports/stm32/boards/LEGO_HUB_NO6/hub_display.h b/ports/stm32/boards/LEGO_HUB_NO6/hub_display.h new file mode 100644 index 0000000000..7623e128a8 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/hub_display.h @@ -0,0 +1,4 @@ +void hub_display_on(void); +void hub_display_off(void); +void hub_display_update(void); +void hub_display_set(uint8_t led, uint16_t value); diff --git a/ports/stm32/boards/LEGO_HUB_NO6/mboot_memory.ld b/ports/stm32/boards/LEGO_HUB_NO6/mboot_memory.ld new file mode 100644 index 0000000000..dd914c8e88 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/mboot_memory.ld @@ -0,0 +1,10 @@ +/* + Linker script fragment for mboot on an STM32xxx MCU. + This defines the memory sections for the bootloader to use. +*/ +MEMORY +{ + FLASH_BL (rx) : ORIGIN = 0x08008000, LENGTH = 32K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 120K +} + diff --git a/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h new file mode 100644 index 0000000000..a0869fda7a --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.h @@ -0,0 +1,122 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2021 Damien P. George + */ + +#include + +#define MICROPY_HW_BOARD_NAME "LEGO Technic Hub No.6" +#define MICROPY_HW_MCU_NAME "STM32F413" + +#define MICROPY_HW_HAS_SWITCH (0) +#define MICROPY_HW_HAS_FLASH (0) +#define MICROPY_PY_PYB_LEGACY (0) +#define MICROPY_HW_ENTER_BOOTLOADER_VIA_RESET (0) +#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0) +#define MICROPY_HW_ENABLE_RTC (1) +#define MICROPY_HW_ENABLE_RNG (1) +#define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (1) + +// HSE is 16MHz, CPU freq set to 100MHz, buses at maximum freq +#define MICROPY_HW_CLK_PLLM (16) +#define MICROPY_HW_CLK_PLLN (200) +#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) +#define MICROPY_HW_CLK_PLLQ (4) +#define MICROPY_HW_CLK_AHB_DIV (RCC_SYSCLK_DIV1) +#define MICROPY_HW_CLK_APB1_DIV (RCC_HCLK_DIV2) +#define MICROPY_HW_CLK_APB2_DIV (RCC_HCLK_DIV1) + +// For 2.7 to 3.6 V, 75 to 100 MHz: 3 wait states. +#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_3 + +// UART buses +// Bluetooth HCI +#define MICROPY_HW_UART2_CTS (pin_D3) +#define MICROPY_HW_UART2_RTS (pin_D4) +#define MICROPY_HW_UART2_TX (pin_D5) +#define MICROPY_HW_UART2_RX (pin_D6) +// Port B +#define MICROPY_HW_UART4_TX (pin_D1) +#define MICROPY_HW_UART4_RX (pin_D0) +// Port D +#define MICROPY_HW_UART5_TX (pin_C12) +#define MICROPY_HW_UART5_RX (pin_D2) +// Port A +#define MICROPY_HW_UART7_TX (pin_E8) +#define MICROPY_HW_UART7_RX (pin_E7) +// Port C +#define MICROPY_HW_UART8_TX (pin_E1) +#define MICROPY_HW_UART8_RX (pin_E0) +// Port F +#define MICROPY_HW_UART9_TX (pin_D15) +#define MICROPY_HW_UART9_RX (pin_D14) +// Port E +#define MICROPY_HW_UART10_TX (pin_E3) +#define MICROPY_HW_UART10_RX (pin_E2) + +// SPI buses +#define MICROPY_HW_SPI1_NSS (pin_A4) // shared with DAC +#define MICROPY_HW_SPI1_SCK (pin_A5) // shared with DAC +#define MICROPY_HW_SPI1_MISO (pin_A6) +#define MICROPY_HW_SPI1_MOSI (pin_A7) + +// USB config +#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9) +#define MICROPY_HW_USB_FS (1) +#define MICROPY_HW_USB_MSC (1) + +// Bluetooth config +#define MICROPY_HW_BLE_UART_ID (PYB_UART_2) +#define MICROPY_HW_BLE_UART_BAUDRATE (115200) +#define MICROPY_HW_BLE_UART_BAUDRATE_SECONDARY (921600) +#define MICROPY_HW_BLE_BTSTACK_CHIPSET_INSTANCE btstack_chipset_cc256x_instance() + +// SPI flash, for R/W storage +#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1) +#define MICROPY_HW_SPIFLASH_SIZE_BITS (256 * 1024 * 1024) +#define MICROPY_HW_SPIFLASH_NSS (pin_B12) +#define MICROPY_HW_SPIFLASH_SCK (pin_B13) +#define MICROPY_HW_SPIFLASH_MISO (pin_C2) +#define MICROPY_HW_SPIFLASH_MOSI (pin_C3) + +// SPI flash, block device config +extern int32_t board_bdev_ioctl(void); +extern struct _spi_bdev_t spi_bdev; +#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \ + (op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE - 1) : \ + (op) == BDEV_IOCTL_INIT ? board_bdev_ioctl() : \ + spi_bdev_ioctl(&spi_bdev, (op), (arg)) \ + ) + +// Jump over first block (bl + 1) as it is cleared by bootloader +#define MICROPY_HW_BDEV_READBLOCKS(dest, bl, n) spi_bdev_readblocks(&spi_bdev, (dest), (bl + 1), (n)) +#define MICROPY_HW_BDEV_WRITEBLOCKS(src, bl, n) spi_bdev_writeblocks(&spi_bdev, (src), (bl + 1), (n)) +#define MICROPY_HW_BDEV_SPIFLASH_EXTENDED (&spi_bdev) // for extended block protocol + +// Board control config +#define MICROPY_BOARD_STARTUP board_init + +/******************************************************************************/ +// Bootloader configuration + +#define MBOOT_LEAVE_BOOTLOADER_VIA_RESET (0) + +#define MBOOT_LED1 0 +#define MBOOT_BOARD_LED_INIT board_mboot_led_init +#define MBOOT_BOARD_LED_STATE board_mboot_led_state + +#define MBOOT_BOARD_EARLY_INIT board_init +#define MBOOT_BOARD_CLEANUP board_mboot_cleanup +#define MBOOT_BOARD_GET_RESET_MODE board_mboot_get_reset_mode + +/******************************************************************************/ +// Function declarations + +void board_init(void); +void board_mboot_cleanup(int reset_mode); +void board_mboot_led_init(void); +void board_mboot_led_state(int led, int state); +int board_mboot_get_reset_mode(void); +void *btstack_chipset_cc256x_instance(void); diff --git a/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.mk b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.mk new file mode 100644 index 0000000000..56527af7d3 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/mpconfigboard.mk @@ -0,0 +1,22 @@ +MCU_SERIES = f4 +CMSIS_MCU = STM32F413xx +AF_FILE = boards/stm32f413_af.csv +LD_FILES = boards/LEGO_HUB_NO6/stm32f413xg.ld boards/common_bl.ld +TEXT0_ADDR = 0x08010000 + +BOOTLOADER_DFU_USB_VID ?= 0x0694 +BOOTLOADER_DFU_USB_PID ?= 0x0008 + +# MicroPython settings +MICROPY_PY_BLUETOOTH ?= 1 +MICROPY_BLUETOOTH_NIMBLE ?= 0 +MICROPY_BLUETOOTH_BTSTACK ?= 1 +MICROPY_VFS_LFS2 ?= 1 + +ifneq ($(BUILDING_MBOOT),1) +LIB_SRC_C += lib/btstack/chipset/cc256x/btstack_chipset_cc256x.c +endif + +# Bootloader settings +MBOOT_TEXT0_ADDR = 0x08008000 +MBOOT_LD_FILES = ../boards/LEGO_HUB_NO6/mboot_memory.ld stm32_sections.ld diff --git a/ports/stm32/boards/LEGO_HUB_NO6/pins.csv b/ports/stm32/boards/LEGO_HUB_NO6/pins.csv new file mode 100644 index 0000000000..9e56e2c79d --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/pins.csv @@ -0,0 +1,114 @@ +CHG_ISET_PWM,PA0 +BUTTONS_ADC,PA1 +BT_ENABLE,PA2 +CHG_IMON_ADC,PA3 +SND_DAC,PA4 +TLC_SCLK,PA5 +TLC_SOUT,PA6 +TLC_SIN,PA7 +PORTB_EN,PA8 +USB_VBUS,PA9 +PORTA_EN,PA10 +USB_DM,PA11 +USB_DP,PA12 +BAT_PWR_EN,PA13 +PORT_3V3_EN,PA14 +TLC_LAT,PA15 +BAT_NTC,PB0 +PORTF_M2,PB1 +PORTD_EN,PB2 +LSM6_SDA,PB3 +LSM6_INT1,PB4 +PORTE_EN,PB5 +PORTC_M1,PB6 +PORTC_M2,PB7 +PORTD_M1,PB8 +PORTD_M2,PB9 +LSM6_SCL,PB10 +,PB11 +,PB12 +,PB13 +,PB14 +TLC_GS_CLK,PB15 +BAT_IMON_ADC,PC0 +BAT_VMON_ADC,PC1 +,PC2 +,PC3 +CHGOK_CENBTN_3V3OK_ADC,PC4 +PORTF_EN,PC5 +PORTE_M1,PC6 +PORTE_M2,PC7 +PORTF_M1,PC8 +BT_SLOWCLK,PC9 +SND_AMP_EN,PC10 +,PC11 +PORTD_TX,PC12 +,PC13 +,PC14 +,PC15 +PORTB_RX,PD0 +PORTB_TX,PD1 +PORTD_RX,PD2 +BT_CTS,PD3 +BT_RTS,PD4 +BT_TX,PD5 +BT_RX,PD6 +,PD7 +,PD8 +,PD9 +,PD10 +,PD11 +,PD12 +,PD13 +PORTF_RX,PD14 +PORTF_TX,PD15 +PORTC_RX,PE0 +PORTC_TX,PE1 +PORTE_RX,PE2 +PORTE_TX,PE3 +,PE4 +PORTC_EN,PE5 +,PE6 +PORTA_RX,PE7 +PORTA_TX,PE8 +PORTA_M1,PE9 +PORTE_RTS,PE10 +PORTA_M2,PE11 +,PE12 +PORTB_M1,PE13 +PORTB_M2,PE14 +PORTF_RTS,PE15 +,PF0 +,PF1 +,PF2 +,PF3 +,PF4 +,PF5 +,PF6 +,PF7 +,PF8 +,PF9 +,PF10 +,PF11 +,PF12 +,PF13 +,PF14 +,PF15 +,PG0 +,PG1 +,PG2 +,PG3 +,PG4 +,PG5 +,PG6 +,PG7 +,PG8 +,PG9 +,PG10 +,PG11 +,PG12 +,PG13 +,PG14 +,PG15 +,PH0 +,PH1 diff --git a/ports/stm32/boards/LEGO_HUB_NO6/stm32f413xg.ld b/ports/stm32/boards/LEGO_HUB_NO6/stm32f413xg.ld new file mode 100644 index 0000000000..d3c43a6948 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/stm32f413xg.ld @@ -0,0 +1,27 @@ +/* + GNU linker script for STM32F413xg (1MB flash, 320kB RAM) +*/ + +/* Specify the memory areas */ +/* FLASH_FS2 is placed before FLASH_TEXT to support 1MB and 1.5MB FLASH with common code in flashbdev.c */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */ + FLASH_APP (rx) : ORIGIN = 0x08010000, LENGTH = 976K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K /* SRAM1 + SRAM2 */ +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 16K; + +/* Define the stack. The stack is full descending so begins just above last byte + of RAM. Note that EABI requires the stack to be 8-byte aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM) - _estack_reserve; +_sstack = _estack - 12K; /* tunable */ + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); +_heap_start = _ebss; /* heap starts just after statically allocated memory */ +_heap_end = _sstack; diff --git a/ports/stm32/boards/LEGO_HUB_NO6/stm32f4xx_hal_conf.h b/ports/stm32/boards/LEGO_HUB_NO6/stm32f4xx_hal_conf.h new file mode 100644 index 0000000000..7d6344f0a2 --- /dev/null +++ b/ports/stm32/boards/LEGO_HUB_NO6/stm32f4xx_hal_conf.h @@ -0,0 +1,19 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2019 Damien P. George + */ +#ifndef MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H +#define MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H + +#include "boards/stm32f4xx_hal_conf_base.h" + +// Oscillator values in Hz +#define HSE_VALUE (16000000) +#define LSE_VALUE (32768) +#define EXTERNAL_CLOCK_VALUE (12288000) + +// Oscillator timeouts in ms +#define HSE_STARTUP_TIMEOUT (100) +#define LSE_STARTUP_TIMEOUT (5000) + +#endif // MICROPY_INCLUDED_STM32F4XX_HAL_CONF_H