From 9ba6990228438aad958934ea6f996debfb21334b Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 5 Jun 2018 18:21:47 -0400 Subject: Feather M0 Express build with Crickit libraries --- .../boards/feather_m0_express_crickit/board.c | 38 ++++++++++++++ .../feather_m0_express_crickit/mpconfigboard.h | 60 ++++++++++++++++++++++ .../feather_m0_express_crickit/mpconfigboard.mk | 17 ++++++ .../boards/feather_m0_express_crickit/pins.c | 33 ++++++++++++ tools/build_adafruit_bins.sh | 2 +- 5 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 ports/atmel-samd/boards/feather_m0_express_crickit/board.c create mode 100644 ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h create mode 100644 ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk create mode 100644 ports/atmel-samd/boards/feather_m0_express_crickit/pins.c diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/board.c b/ports/atmel-samd/boards/feather_m0_express_crickit/board.c new file mode 100644 index 000000000..c8e20206a --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * 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 "boards/board.h" + +void board_init(void) +{ +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h new file mode 100644 index 000000000..756462013 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.h @@ -0,0 +1,60 @@ +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M0 Express with Crickit libraries" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_NEOPIXEL (&pin_PA06) + +// Clock rates are off: Salae reads 12MHz which is the limit even though we set it to the safer 8MHz. +#define SPI_FLASH_BAUDRATE (8000000) + +#define SPI_FLASH_MOSI_PIN PIN_PA08 +#define SPI_FLASH_MISO_PIN PIN_PA14 +#define SPI_FLASH_SCK_PIN PIN_PA09 +#define SPI_FLASH_CS_PIN PIN_PA13 +#define SPI_FLASH_MOSI_PIN_FUNCTION PINMUX_PA08D_SERCOM2_PAD0 +#define SPI_FLASH_MISO_PIN_FUNCTION PINMUX_PA14C_SERCOM2_PAD2 +#define SPI_FLASH_SCK_PIN_FUNCTION PINMUX_PA09D_SERCOM2_PAD1 +#define SPI_FLASH_SERCOM SERCOM2 +#define SPI_FLASH_SERCOM_INDEX 2 +#define SPI_FLASH_MOSI_PAD 0 +#define SPI_FLASH_MISO_PAD 2 +#define SPI_FLASH_SCK_PAD 1 +// Transmit Data Pinout +// <0x0=>PAD[0,1]_DO_SCK +// <0x1=>PAD[2,3]_DO_SCK +// <0x2=>PAD[3,1]_DO_SCK +// <0x3=>PAD[0,3]_DO_SCK +#define SPI_FLASH_DOPO 0 +#define SPI_FLASH_DIPO 2 // same as MISO pad + +// These are pins not to reset. +#define MICROPY_PORT_A (PORT_PA06 | PORT_PA08 | PORT_PA09 | PORT_PA13 | PORT_PA14 | PORT_PA24 | PORT_PA25) +#define MICROPY_PORT_B ( 0 ) +#define MICROPY_PORT_C ( 0 ) + +#include "external_flash/external_flash.h" + +// If you change this, then make sure to update the linker scripts as well to +// make sure you don't overwrite code. +#define CIRCUITPY_INTERNAL_NVM_SIZE 256 + +#define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) + +#include "external_flash/devices.h" + +#define EXTERNAL_FLASH_DEVICE_COUNT 2 +#define EXTERNAL_FLASH_DEVICES S25FL216K, \ + GD25Q16C + +#include "external_flash/external_flash.h" + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PA23) +#define DEFAULT_I2C_BUS_SDA (&pin_PA22) + +#define DEFAULT_SPI_BUS_SCK (&pin_PB11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB10) +#define DEFAULT_SPI_BUS_MISO (&pin_PA12) + +#define DEFAULT_UART_BUS_RX (&pin_PA11) +#define DEFAULT_UART_BUS_TX (&pin_PA10) diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk new file mode 100644 index 000000000..4096560c2 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/mpconfigboard.mk @@ -0,0 +1,17 @@ +LD_FILE = boards/samd21x18-bootloader-external-flash.ld +USB_VID = 0x239A +USB_PID = 0x8023 +USB_PRODUCT = "Feather M0 Express" +USB_MANUFACTURER = "Adafruit Industries LLC" + +SPI_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c new file mode 100644 index 000000000..68666c273 --- /dev/null +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c @@ -0,0 +1,33 @@ +#include "shared-bindings/board/__init__.h" + +#include "board_busses.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 4d0854a10..6ad085827 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -2,7 +2,7 @@ rm -rf ports/atmel-samd/build* rm -rf ports/esp8266/build* rm -rf ports/nrf/build* -ATMEL_BOARDS="arduino_zero circuitplayground_express circuitplayground_express_crickit feather_m0_basic feather_m0_adalogger itsybitsy_m0_express itsybitsy_m4_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express feather_m4_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52" +ATMEL_BOARDS="arduino_zero circuitplayground_express circuitplayground_express_crickit feather_m0_basic feather_m0_adalogger itsybitsy_m0_express itsybitsy_m4_express feather_m0_rfm69 feather_m0_rfm9x feather_m0_express feather_m0_express_crickit feather_m4_express metro_m0_express metro_m4_express pirkey_m0 trinket_m0 gemma_m0 feather52" ROSIE_SETUPS="rosie-ci" PARALLEL="-j 5" -- cgit v1.2.3 From 36a7ebe88e03bafa7e8163607a93135580249fff Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 5 Jun 2018 18:24:55 -0400 Subject: add feather_m0_express_crickit to .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c7a45ea80..986e32cc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ env: - TRAVIS_BOARD=feather_m0_rfm69 - TRAVIS_BOARD=feather_m0_rfm9x - TRAVIS_BOARD=feather_m0_express + - TRAVIS_BOARD=feather_m0_express_crickit - TRAVIS_BOARD=feather_m4_express - TRAVIS_BOARD=itsybitsy_m0_express - TRAVIS_BOARD=itsybitsy_m4_express -- cgit v1.2.3 From a4e06bd998a1fb2d2dd209524d8ccd69b18712e6 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 5 Jun 2018 22:04:30 -0500 Subject: main: Explicitly set the stack top based on _estack .. setting it based on the ad-hoc stack pointer calculation of mp_stack_ctrl_init() meant that the stack used above main() counts against the 1KiB safety factor that the mp_stack_set_limit call tries to establish. It turns out, at least on M4, that over half of the safety factor is used up by stack-above-main()! In the case of the basics/gen_stack_overflow.py test, which blows the stack on purpose, it turns out that gc would be called while handling the "maximum recursion depth exceeded" error, and this needed more stack than was left. Closes: #900 --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 4402ebe32..4ed4f5d7c 100644 --- a/main.c +++ b/main.c @@ -241,7 +241,7 @@ int __attribute__((used)) main(void) { // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. (Limit is measured in bytes.) - mp_stack_ctrl_init(); + mp_stack_set_top((char*)&_estack); mp_stack_set_limit((char*)&_estack - (char*)&_ebss - 1024); #if MICROPY_MAX_STACK_USAGE -- cgit v1.2.3 From 654591e11f45075b0a7534fd52c98fef6082c703 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 6 Jun 2018 08:01:09 -0500 Subject: main: move code pertaining to boot.py out of line .. this reduces stack usage in main() substantially, because the 512 byte stack allocation will only exist during the new run_boot_py function's duration. Closes: #904 --- main.c | 72 +++++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/main.c b/main.c index 4ed4f5d7c..fb1a9e90f 100644 --- a/main.c +++ b/main.c @@ -233,40 +233,7 @@ bool start_mp(safe_mode_t safe_mode) { } } -int __attribute__((used)) main(void) { - // initialise the cpu and peripherals - safe_mode_t safe_mode = port_init(); - - rgb_led_status_init(); - - // Stack limit should be less than real stack size, so we have a chance - // to recover from limit hit. (Limit is measured in bytes.) - mp_stack_set_top((char*)&_estack); - mp_stack_set_limit((char*)&_estack - (char*)&_ebss - 1024); - -#if MICROPY_MAX_STACK_USAGE - // _ezero (same as _ebss) is an int, so start 4 bytes above it. - mp_stack_set_bottom(&_ezero + 1); - mp_stack_fill_with_sentinel(); -#endif - - // Create a new filesystem only if we're not in a safe mode. - // A power brownout here could make it appear as if there's - // no SPI flash filesystem, and we might erase the existing one. - filesystem_init(safe_mode == NO_SAFE_MODE, false); - - // Reset everything and prep MicroPython to run boot.py. - reset_port(); - reset_board(); - reset_mp(); - - // Turn on autoreload by default but before boot.py in case it wants to change it. - autoreload_enable(); - - // By default our internal flash is readonly to local python code and - // writable over USB. Set it here so that boot.py can change it. - filesystem_writable_by_python(false); - +void run_boot_py(safe_mode_t safe_mode) { // If not in safe mode, run boot before initing USB and capture output in a // file. if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) { @@ -338,6 +305,43 @@ int __attribute__((used)) main(void) { reset_port(); reset_mp(); } +} + +int __attribute__((used)) main(void) { + // initialise the cpu and peripherals + safe_mode_t safe_mode = port_init(); + + rgb_led_status_init(); + + // Stack limit should be less than real stack size, so we have a chance + // to recover from limit hit. (Limit is measured in bytes.) + mp_stack_set_top((char*)&_estack); + mp_stack_set_limit((char*)&_estack - (char*)&_ebss - 1024); + +#if MICROPY_MAX_STACK_USAGE + // _ezero (same as _ebss) is an int, so start 4 bytes above it. + mp_stack_set_bottom(&_ezero + 1); + mp_stack_fill_with_sentinel(); +#endif + + // Create a new filesystem only if we're not in a safe mode. + // A power brownout here could make it appear as if there's + // no SPI flash filesystem, and we might erase the existing one. + filesystem_init(safe_mode == NO_SAFE_MODE, false); + + // Reset everything and prep MicroPython to run boot.py. + reset_port(); + reset_board(); + reset_mp(); + + // Turn on autoreload by default but before boot.py in case it wants to change it. + autoreload_enable(); + + // By default our internal flash is readonly to local python code and + // writable over USB. Set it here so that boot.py can change it. + filesystem_writable_by_python(false); + + run_boot_py(safe_mode); // Start serial and HID after giving boot.py a chance to tweak behavior. serial_init(); -- cgit v1.2.3 From 3a3817262788a6b6812564815c46fdf1bd59667b Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Wed, 6 Jun 2018 18:28:01 -0400 Subject: Fixed documentation formatting for RTD --- shared-bindings/rotaryio/IncrementalEncoder.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index b2609f4a8..65d4ba98b 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -50,19 +50,19 @@ //| :param ~microcontroller.Pin pin_a: First pin to read pulses from. //| :param ~microcontroller.Pin pin_b: Second pin to read pulses from. //| -//| For example:: -//| -//| import rotaryio -//| import time -//| from board import * -//| -//| enc = rotaryio.IncrementalEncoder(D1, D2) -//| last_position = None -//| while True; -//| position = enc.position -//| if last_position == None or position != last_position: -//| print(position) -//| last_position = position +//| For example:: +//| +//| import rotaryio +//| import time +//| from board import * +//| +//| enc = rotaryio.IncrementalEncoder(D1, D2) +//| last_position = None +//| while True: +//| position = enc.position +//| if last_position == None or position != last_position: +//| print(position) +//| last_position = position //| STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 2, 2, true); -- cgit v1.2.3 From 0ab2a60dcd9ae809addd936f5ce20dc000d37e00 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Thu, 7 Jun 2018 13:12:44 -0400 Subject: Update ItsyBitsy board name to one word --- ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h | 2 +- ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h index be59bc5d4..3adcb7f16 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h @@ -1,4 +1,4 @@ -#define MICROPY_HW_BOARD_NAME "Adafruit Itsy Bitsy M0 Express" +#define MICROPY_HW_BOARD_NAME "Adafruit ItsyBitsy M0 Express" #define MICROPY_HW_MCU_NAME "samd21g18" #define CIRCUITPY_BITBANG_APA102 diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk index 66586b611..9f62ae839 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.mk @@ -1,7 +1,7 @@ LD_FILE = boards/samd21x18-bootloader-external-flash-crystalless.ld USB_VID = 0x239A USB_PID = 0x8012 -USB_PRODUCT = "Itsy Bitsy M0 Express" +USB_PRODUCT = "ItsyBitsy M0 Express" USB_MANUFACTURER = "Adafruit Industries LLC" SPI_FLASH_FILESYSTEM = 1 -- cgit v1.2.3 From 7b2875d54a3a770eb97c7c2c760a4d307bd76fd7 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Thu, 7 Jun 2018 13:33:13 -0400 Subject: Add Adafruit to board name string --- ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h index faa0d6e75..116d4dac6 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h @@ -1,4 +1,4 @@ -#define MICROPY_HW_BOARD_NAME "ItsyBitsy M4 Express" +#define MICROPY_HW_BOARD_NAME "Adafruit ItsyBitsy M4 Express" #define MICROPY_HW_MCU_NAME "samd51g19" #define CIRCUITPY_MCU_FAMILY samd51 -- cgit v1.2.3 From ba7e0e2f86c8691a5664550db37233a705793756 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Thu, 7 Jun 2018 13:39:04 -0400 Subject: Add Adafruit to other M4 board name strings --- ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h | 2 +- ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h index b5af61ba6..bb5c0ddcc 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h @@ -1,4 +1,4 @@ -#define MICROPY_HW_BOARD_NAME "Feather M4 Express" +#define MICROPY_HW_BOARD_NAME "Adafruit Feather M4 Express" #define MICROPY_HW_MCU_NAME "samd51j19" #define CIRCUITPY_MCU_FAMILY samd51 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h index 7aef929f7..4d206a4c8 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h @@ -1,4 +1,4 @@ -#define MICROPY_HW_BOARD_NAME "Metro M4 Express" +#define MICROPY_HW_BOARD_NAME "Adafruit Metro M4 Express" #define MICROPY_HW_MCU_NAME "samd51j19" #define CIRCUITPY_MCU_FAMILY samd51 -- cgit v1.2.3 From f36fa308e753bf38c3e575b3262b5a3c1a91f987 Mon Sep 17 00:00:00 2001 From: Steven Conaway Date: Thu, 7 Jun 2018 12:15:15 -0700 Subject: Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index a1b90fa02..c8ae33e8f 100644 --- a/README.rst +++ b/README.rst @@ -104,7 +104,7 @@ Differences from `MicroPython `__ CircuitPython: - includes a ports for MicroChip SAMD21 (Commonly known as M0 in Adafruit - product names and SAMD51 (M4). + product names) and SAMD51 (M4). - supports only SAMD21, SAMD51, and ESP8266 ports. An nRF port is under development. - tracks MicroPython's releases (not master). -- cgit v1.2.3 From 218930d18b5d6c4fbe67c87cec4771b39cc69d1f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 7 Jun 2018 21:37:09 -0400 Subject: Check for PDMIn DMA getting stuck. --- ports/atmel-samd/common-hal/audiobusio/PDMIn.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c index 5502fcd81..f16b17770 100644 --- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -392,7 +392,18 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t* se break; } // Wait for the next buffer to fill + uint32_t wait_counts = 0; + #ifdef SAMD21 + #define MAX_WAIT_COUNTS 1000 + #endif + #ifdef SAMD51 + #define MAX_WAIT_COUNTS 6000 + #endif while (!event_interrupt_active(event_channel)) { + if (wait_counts++ > MAX_WAIT_COUNTS) { + // Buffer has stopped filling; DMA may have missed an I2S trigger event. + break; + } #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif -- cgit v1.2.3 From 2fbab8067afcb008bc92d9c155dfef360fbc10f9 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 5 Jun 2018 12:38:31 -0700 Subject: Prevent freezing USB during high frequency PulseIn. We now track the last time the background task ran and bail on the PulseIn if it starves the background work. In practice, this happens after the numbers from pulsein are no longer accurate. This also adjusts interrupt priorities so most are the lowest level except for the tick and USB interrupts. Fixes #516 and #876 --- ports/atmel-samd/background.c | 8 ++++++++ ports/atmel-samd/background.h | 3 +++ .../common-hal/microcontroller/__init__.c | 14 +++---------- ports/atmel-samd/common-hal/pulseio/PulseIn.c | 16 +++++++++++++++ ports/atmel-samd/common-hal/pulseio/PulseIn.h | 1 + ports/atmel-samd/tick.c | 7 +++++++ shared-bindings/pulseio/PulseIn.c | 23 ++++++++++++++++++++++ shared-bindings/pulseio/PulseIn.h | 1 + 8 files changed, 62 insertions(+), 11 deletions(-) diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 92648f42e..4cba7a110 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -26,11 +26,19 @@ #include "background.h" #include "audio_dma.h" +#include "tick.h" #include "usb.h" #include "usb_mass_storage.h" +volatile uint64_t last_finished_tick = 0; + void run_background_tasks(void) { audio_dma_background(); usb_msc_background(); usb_cdc_background(); + last_finished_tick = ticks_ms; +} + +bool background_tasks_ok(void) { + return ticks_ms - last_finished_tick < 1000; } diff --git a/ports/atmel-samd/background.h b/ports/atmel-samd/background.h index f7fb10a1f..e841049a4 100644 --- a/ports/atmel-samd/background.h +++ b/ports/atmel-samd/background.h @@ -27,6 +27,9 @@ #ifndef MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H #define MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H +#include + void run_background_tasks(void); +bool background_tasks_ok(void); #endif // MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index c57b6939c..ad4d81ddd 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -40,18 +40,10 @@ void common_hal_mcu_delay_us(uint32_t delay) { mp_hal_delay_us(delay); } -// Interrupt flags that will be saved and restored during disable/Enable -// interrupt functions below. - -// ASF4's interrupt disable doesn't handle duplicate calls -volatile uint32_t interrupt_flags; volatile uint32_t nesting_count = 0; void common_hal_mcu_disable_interrupts(void) { - if (nesting_count == 0) { - interrupt_flags = __get_PRIMASK(); - __disable_irq(); - __DMB(); - } + __disable_irq(); + __DMB(); nesting_count++; } @@ -66,7 +58,7 @@ void common_hal_mcu_enable_interrupts(void) { return; } __DMB(); - __set_PRIMASK(interrupt_flags); + __enable_irq(); } extern uint32_t _ezero; diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index 99a60a829..dee32bbec 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -31,6 +31,7 @@ #include "atmel_start_pins.h" #include "hal/include/hal_gpio.h" +#include "background.h" #include "mpconfigport.h" #include "py/gc.h" #include "py/runtime.h" @@ -60,10 +61,16 @@ void pulsein_interrupt_handler(uint8_t channel) { uint32_t current_us; uint64_t current_ms; current_tick(¤t_ms, ¤t_us); + // current_tick gives us the remaining us until the next tick but we want the number since the // last ms. current_us = 1000 - current_us; pulseio_pulsein_obj_t* self = get_eic_channel_data(channel); + if (!background_tasks_ok() || self->errored_too_fast) { + self->errored_too_fast = true; + common_hal_pulseio_pulsein_pause(self); + return; + } if (self->first_edge) { self->first_edge = false; pulsein_set_config(self, false); @@ -118,6 +125,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, self->first_edge = true; self->last_us = 0; self->last_ms = 0; + self->errored_too_fast = 0; set_eic_channel_data(pin->extint_channel, (void*) self); @@ -157,6 +165,9 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, // Make sure we're paused. common_hal_pulseio_pulsein_pause(self); + // Reset erroring + self->errored_too_fast = false; + // Send the trigger pulse. if (trigger_duration > 0) { gpio_set_pin_pull_mode(self->pin, GPIO_PULL_OFF); @@ -207,6 +218,11 @@ uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { return self->len; } +bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { + uint32_t mask = 1 << self->channel; + return (EIC->INTENSET.reg & (mask << EIC_INTENSET_EXTINT_Pos)) == 0; +} + uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) { common_hal_mcu_disable_interrupts(); diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.h b/ports/atmel-samd/common-hal/pulseio/PulseIn.h index 3d79b50c3..f5326d9e5 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.h +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.h @@ -43,6 +43,7 @@ typedef struct { volatile bool first_edge; volatile uint64_t last_ms; volatile uint16_t last_us; + volatile bool errored_too_fast; } pulseio_pulsein_obj_t; void pulsein_reset(void); diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c index 6cd7c7833..81841c4af 100644 --- a/ports/atmel-samd/tick.c +++ b/ports/atmel-samd/tick.c @@ -60,6 +60,13 @@ void tick_init() { uint32_t ticks_per_ms = common_hal_mcu_processor_get_frequency() / 1000; SysTick_Config(ticks_per_ms-1); NVIC_EnableIRQ(SysTick_IRQn); + // Set all peripheral interrupt priorities to the lowest priority by default. + for (uint16_t i = 0; i < PERIPH_COUNT_IRQn; i++) { + NVIC_SetPriority(i, (1UL << __NVIC_PRIO_BITS) - 1UL); + } + // Bump up the systick interrupt. + NVIC_SetPriority(SysTick_IRQn, 1); + NVIC_SetPriority(USB_IRQn, 1); } void tick_delay(uint32_t us) { diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 736441c74..862dbd99d 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -219,6 +219,26 @@ const mp_obj_property_t pulseio_pulsein_maxlen_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: paused +//| +//| True when pulse capture is paused as a result of :py:func:`pause` or an error during capture +//| such as a signal that is too fast. +//| +STATIC mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self)); + + return mp_obj_new_bool(common_hal_pulseio_pulsein_get_paused(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_get_paused_obj, pulseio_pulsein_obj_get_paused); + +const mp_obj_property_t pulseio_pulsein_paused_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pulsein_get_paused_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| .. method:: __len__() //| //| Returns the current pulse length @@ -285,7 +305,10 @@ STATIC const mp_rom_map_elem_t pulseio_pulsein_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&pulseio_pulsein_resume_obj) }, { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&pulseio_pulsein_clear_obj) }, { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&pulseio_pulsein_popleft_obj) }, + + // Properties { MP_ROM_QSTR(MP_QSTR_maxlen), MP_ROM_PTR(&pulseio_pulsein_maxlen_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&pulseio_pulsein_paused_obj) }, }; STATIC MP_DEFINE_CONST_DICT(pulseio_pulsein_locals_dict, pulseio_pulsein_locals_dict_table); diff --git a/shared-bindings/pulseio/PulseIn.h b/shared-bindings/pulseio/PulseIn.h index 88b6f356e..e28a3c2df 100644 --- a/shared-bindings/pulseio/PulseIn.h +++ b/shared-bindings/pulseio/PulseIn.h @@ -41,6 +41,7 @@ extern void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint1 extern void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self); extern uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self); extern uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self); +extern bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self); extern uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self); extern uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index); -- cgit v1.2.3 From 07a8899c726a53011ead19d4e92cd8ccc09c1e03 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 5 Jun 2018 13:43:55 -0700 Subject: Support M4 --- ports/atmel-samd/tick.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c index 81841c4af..9753a1a0c 100644 --- a/ports/atmel-samd/tick.c +++ b/ports/atmel-samd/tick.c @@ -66,7 +66,16 @@ void tick_init() { } // Bump up the systick interrupt. NVIC_SetPriority(SysTick_IRQn, 1); + #ifdef SAMD21 NVIC_SetPriority(USB_IRQn, 1); + #endif + + #ifdef SAMD51 + NVIC_SetPriority(USB_0_IRQn, 1); + NVIC_SetPriority(USB_1_IRQn, 1); + NVIC_SetPriority(USB_2_IRQn, 1); + NVIC_SetPriority(USB_3_IRQn, 1); + #endif } void tick_delay(uint32_t us) { -- cgit v1.2.3 From 383bf9a59e1672684169b4afe57671a639fe12ad Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 6 Jun 2018 12:02:17 -0700 Subject: Wait for the DFLL to be stable. --- ports/atmel-samd/peripherals/samd21/clocks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/atmel-samd/peripherals/samd21/clocks.c b/ports/atmel-samd/peripherals/samd21/clocks.c index 51b7ad993..422290e8b 100644 --- a/ports/atmel-samd/peripherals/samd21/clocks.c +++ b/ports/atmel-samd/peripherals/samd21/clocks.c @@ -130,6 +130,9 @@ static void init_clock_source_dfll48m_xosc(void) { SYSCTRL_DFLLCTRL_ENABLE; while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {} while (GCLK->STATUS.bit.SYNCBUSY) {} + + // Wait for the fine lock on the DFLL. + while (!SYSCTRL->PCLKSR.bit.DFLLLCKC || !SYSCTRL->PCLKSR.bit.DFLLLCKF) {} } static void init_clock_source_dfll48m_usb(void) { -- cgit v1.2.3 From 769788d3c78558521c2ccb4146d1d3d114e230f6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 6 Jun 2018 12:07:28 -0700 Subject: Turn off USB pin objects since they are always used for USB. --- ports/atmel-samd/boards/arduino_zero/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h | 4 ++++ .../boards/circuitplayground_express_crickit/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/gemma_m0/mpconfigboard.h | 3 +++ ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/trinket_m0/mpconfigboard.h | 3 +++ ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h | 4 ++++ ports/atmel-samd/boards/ugame10/mpconfigboard.h | 4 ++++ 18 files changed, 70 insertions(+) diff --git a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h index a32f128f5..1382d4736 100644 --- a/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_zero/mpconfigboard.h @@ -24,3 +24,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h index 3d97e2cb1..5077840cb 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h @@ -68,3 +68,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PB09) #define DEFAULT_UART_BUS_TX (&pin_PB08) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h index 83cc19d9f..638a6646c 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h @@ -71,3 +71,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PB09) #define DEFAULT_UART_BUS_TX (&pin_PB08) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h index 94caa7d04..c8b5c56ee 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h @@ -22,3 +22,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h index 34de8e166..dcac9749d 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h @@ -23,3 +23,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h index bfa8c642a..108d67d9f 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h @@ -58,3 +58,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h index 4f4ea2ffe..4a530ed29 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h @@ -23,3 +23,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h index a9d586c2e..3a6f28c12 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h @@ -23,3 +23,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h index c8118e48b..a7a2d7de0 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h @@ -57,3 +57,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h index bb5c0ddcc..c82395baf 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h @@ -43,3 +43,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PB17) #define DEFAULT_UART_BUS_TX (&pin_PB16) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h index 53e802f17..1ec217096 100644 --- a/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/gemma_m0/mpconfigboard.h @@ -40,6 +40,9 @@ #define IGNORE_PIN_PA20 1 #define IGNORE_PIN_PA21 1 #define IGNORE_PIN_PA22 1 +// USB is always used. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 #define IGNORE_PIN_PA27 1 #define IGNORE_PIN_PA28 1 #define IGNORE_PIN_PA30 1 diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h index 3adcb7f16..f56f57c46 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h @@ -56,3 +56,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h index 116d4dac6..e47d5390d 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h @@ -41,3 +41,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA16) #define DEFAULT_UART_BUS_TX (&pin_PA17) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h index f798c5d36..135d6ae92 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h @@ -59,3 +59,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA11) #define DEFAULT_UART_BUS_TX (&pin_PA10) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h index 4d206a4c8..050f678dd 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h @@ -44,3 +44,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA23) #define DEFAULT_UART_BUS_TX (&pin_PA22) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h index d561947e3..9036f8e7b 100644 --- a/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0/mpconfigboard.h @@ -30,6 +30,9 @@ #define IGNORE_PIN_PA21 1 #define IGNORE_PIN_PA22 1 #define IGNORE_PIN_PA23 1 +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 #define IGNORE_PIN_PA27 1 #define IGNORE_PIN_PA28 1 #define IGNORE_PIN_PA30 1 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h index 3377d1b7e..8e3fdd7a8 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h @@ -64,3 +64,7 @@ #define DEFAULT_UART_BUS_RX (&pin_PA07) #define DEFAULT_UART_BUS_TX (&pin_PA06) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.h b/ports/atmel-samd/boards/ugame10/mpconfigboard.h index 4e5e88569..ed822952d 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.h +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.h @@ -52,3 +52,7 @@ { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module } + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 -- cgit v1.2.3 From 66b79723b6d238f93908a029ed7a1c4619842b52 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 8 Jun 2018 12:55:40 -0700 Subject: Add code size analysis tool and shrink samd.clock a smidge. --- ports/atmel-samd/bindings/samd/Clock.c | 10 +- ports/atmel-samd/bindings/samd/Clock.h | 10 +- tools/chart_code_size.py | 454 +++++++++++++++++++++++++++++++++ 3 files changed, 460 insertions(+), 14 deletions(-) create mode 100644 tools/chart_code_size.py diff --git a/ports/atmel-samd/bindings/samd/Clock.c b/ports/atmel-samd/bindings/samd/Clock.c index 3c87177a4..e09cc0bd8 100644 --- a/ports/atmel-samd/bindings/samd/Clock.c +++ b/ports/atmel-samd/bindings/samd/Clock.c @@ -47,15 +47,7 @@ STATIC void samd_clock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "%q.%q.%s(", MP_QSTR_samd, MP_QSTR_clock, self->name); - if (clock_get_enabled(self->type, self->index)) { - mp_printf(print, "frequency=%u", clock_get_frequency(self->type, self->index)); - uint32_t calibration = clock_get_calibration(self->type, self->index); - if (calibration) { - mp_printf(print, ", calibration=%u", calibration); - } - } - mp_printf(print, ")"); + mp_printf(print, "%q.%q.%q", MP_QSTR_samd, MP_QSTR_clock, self->name); } //| .. attribute:: enabled diff --git a/ports/atmel-samd/bindings/samd/Clock.h b/ports/atmel-samd/bindings/samd/Clock.h index 0d13ae253..ccc8f10d1 100644 --- a/ports/atmel-samd/bindings/samd/Clock.h +++ b/ports/atmel-samd/bindings/samd/Clock.h @@ -31,7 +31,7 @@ typedef struct { mp_obj_base_t base; - const char *name; + qstr name; uint8_t type; uint8_t index; } samd_clock_obj_t; @@ -39,7 +39,7 @@ typedef struct { #define CLOCK(_name, _type, _index) \ const samd_clock_obj_t clock_ ## _name = { \ { &samd_clock_type }, \ - .name = #_name, \ + .name = MP_QSTR_ ## _name, \ .type = _type, \ .index = _index, \ } @@ -47,7 +47,7 @@ const samd_clock_obj_t clock_ ## _name = { \ #define CLOCK_SOURCE(_name) \ const samd_clock_obj_t clock_ ## _name = { \ { &samd_clock_type }, \ - .name = #_name, \ + .name = MP_QSTR_ ## _name, \ .type = 0, \ .index = GCLK_SOURCE_ ## _name, \ } @@ -55,7 +55,7 @@ const samd_clock_obj_t clock_ ## _name = { \ #define CLOCK_GCLK(_name) \ const samd_clock_obj_t clock_ ## _name = { \ { &samd_clock_type }, \ - .name = #_name, \ + .name = MP_QSTR_ ## _name, \ .type = 1, \ .index = _name ## _GCLK_ID, \ } @@ -63,7 +63,7 @@ const samd_clock_obj_t clock_ ## _name = { \ #define CLOCK_GCLK_(_name, _extra) \ const samd_clock_obj_t clock_ ## _name ## _ ## _extra = { \ { &samd_clock_type }, \ - .name = #_name "_" #_extra, \ + .name = MP_QSTR_ ## _name ## _ ## _extra, \ .type = 1, \ .index = _name ## _GCLK_ID_ ## _extra, \ } diff --git a/tools/chart_code_size.py b/tools/chart_code_size.py new file mode 100644 index 000000000..0b55787fa --- /dev/null +++ b/tools/chart_code_size.py @@ -0,0 +1,454 @@ +# This script renders a graph of the CircuitPython rom image. +# It takes the single elf file and uses objdump to get its contents. + +import pygraphviz as pgv +import click +import sh + +# Replace dashes with underscores +objdump = sh.arm_none_eabi_objdump + +def parse_hex(h): + return int("0x" + h, 0) + +BAD_JUMPS = ["UNPREDICTABLE", "_etext"] + +SPECIAL_NODE_COLORS = { + "main": "pink", + "exception_table": "green" +} + +@click.command() +@click.argument("elf_filename") +def do_all_the_things(elf_filename): + symbol = None + last_address = 0 + all_symbols = {} + symbols_by_debug_address = {} + symbols_by_memory_address = {} + symbols_by_linkage_name = {} + # Gather type info so we know how to treat the disassembly + debug_dump = objdump("--dwarf=info", elf_filename) + debug_dump_lines = debug_dump.stdout.decode("utf-8").split("\n") + symbol_stack = [] + symbol = None + ignore = False + min_call_site_param = 0x20000000 + for line in debug_dump_lines: + if not line: + continue + parts = line.split() + if line[1] == "<": + if parts[-1] == "0": + symbol = symbol_stack.pop() + continue + debug_type = parts[-1].strip("()") + ignore = False + # skip info about function parameters + if debug_type == "DW_TAG_formal_parameter": + ignore = True + depth = int(parts[0].split(">")[0].strip("<")) + if len(symbol_stack) == (depth - 1) and depth > 0: + symbol_stack.append(symbol) + elif symbol and "name" in symbol: + if symbol["debug_type"] == "DW_TAG_variable": + if "start_address" not in symbol: + pass + else: + symbols_by_memory_address[symbol["start_address"]] = symbol + elif symbol["debug_type"] in ["DW_TAG_member", "DW_TAG_label", "DW_TAG_typedef", "DW_TAG_enumerator", "DW_TAG_enumeration_type", "DW_TAG_base_type", "DW_TAG_structure_type", "DW_TAG_compile_unit", "DW_TAG_union_type"]: + # skip symbols that don't end up in memory. the type info is available through the debug address map + pass + else: + if symbol["name"] in all_symbols: + # print(depth, symbol["name"]) + # print(symbol) + # print(all_symbols[symbol["name"]]) + # print() + pass + all_symbols[symbol["name"]] = symbol + elif symbol and symbol["debug_type"] == "DW_TAG_GNU_call_site_parameter" and "call_site_value" in symbol: + parent = -1 + while symbol_stack[parent]["debug_type"] != "DW_TAG_subprogram": + parent -= 1 + parent = symbol_stack[parent] + + # Only point to ROM + addr = symbol["call_site_value"] + if 0x2000 <= addr < 0x20000000: + if "outgoing_pointers" not in parent: + parent["outgoing_pointers"] = set() + parent["outgoing_pointers"].add(addr) + if addr not in symbols_by_memory_address: + symbols_by_memory_address[addr] = symbol + min_call_site_param = min(addr, min_call_site_param) + symbol["name"] = "name{:x}".format(addr) + address = parse_hex(parts[0].split("<")[-1].strip(">:")) + symbol = {"debug_address": address, "debug_type": debug_type, "other": []} + if debug_type == "DW_TAG_structure_type": + symbol["struct"] = {} + elif debug_type == "DW_TAG_array_type": + symbol["subtype"] = None + symbol["bound_count"] = 0 + symbol["maxlen"] = 0 + elif debug_type == "DW_TAG_subrange_type": + symbol_stack[-1]["subtype"] = symbol + symbols_by_debug_address[address] = symbol + elif ignore: + continue + elif line[:4] == " ": + tag = parts[1].strip(":") + if tag == "DW_AT_name": + symbol["name"] = parts[-1] + elif tag == "DW_AT_type": + symbol["type"] = int(parts[-1].strip("<>"), 0) + if symbol["debug_type"] == "DW_TAG_subrange_type": + if not symbol_stack[-1]["subtype"]: + symbol_stack[-1]["subtype"] = symbol + elif symbol_stack[-1]["subtype"]["type"] == symbol["type"]: + second_subtype = True + else: + raise RuntimeError() + elif tag == "DW_AT_upper_bound": + # Skip arrays with length defined by other variables + if parts[-1][0] != "<": + upper_bound = int(parts[-1]) + if symbol_stack[-1]["bound_count"] > 0: + symbol_stack[-1]["maxlen"] *= upper_bound + 1 + else: + symbol_stack[-1]["maxlen"] = upper_bound + 1 + symbol_stack[-1]["bound_count"] += 1 + elif tag == "DW_AT_byte_size": + symbol["size"] = int(parts[-1]) + elif tag == "DW_AT_inline": + symbol["inlined"] = True + elif tag == "DW_AT_low_pc": + addr = int(parts[-1], 0) + symbols_by_memory_address[addr] = symbol + elif tag == "DW_AT_location": + if parts[-2] == "(DW_OP_addr:": + addr = parse_hex(parts[-1].strip(")")) + if addr > 0: + symbol["start_address"] = addr + elif tag == "DW_AT_linkage_name": + symbol["linkage_name"] = parts[-1] + symbols_by_linkage_name[symbol["linkage_name"]] = symbol + elif tag == "DW_AT_data_member_location": + symbol_stack[-1]["struct"][int(parts[-1])] = symbol + elif tag == "DW_AT_GNU_call_site_value": + if parts[-2] == "(DW_OP_addr:": + symbol["call_site_value"] = parse_hex(parts[-1].strip(")")) + else: + symbol["other"].append(line) + #print(parts) + pass + else: + #print(line) + pass + + MEMORY_NONE = 0 + MEMORY_POINTER = 1 + MEMORY_PY_OBJECT = 2 + + def get_size(t): + if "size" in t: + return t["size"] + return get_size(symbols_by_debug_address[t["type"]]) + + def get_pointer_map(t, depth=0): + if t["debug_type"] == "DW_TAG_pointer_type": + return {0: MEMORY_POINTER} + elif t["debug_type"] in ["DW_TAG_const_type", "DW_TAG_typedef", "DW_TAG_member", "DW_TAG_subrange_type", "DW_TAG_volatile_type"]: + if "name" in t and t["name"] == "mp_rom_obj_t": + return {0: MEMORY_PY_OBJECT} + return get_pointer_map(symbols_by_debug_address[t["type"]], depth+1) + elif t["debug_type"] in ["DW_TAG_base_type", "DW_TAG_enumeration_type"]: + return {} + elif t["debug_type"] == "DW_TAG_union_type": + # skip for now + return {} + elif "struct" in t: + combined_map = {} + for offset in t["struct"]: + member = t["struct"][offset] + submap = get_pointer_map(member) + for suboffset in submap: + combined_map[offset + suboffset] = submap[suboffset] + return combined_map + elif "subtype" in t: + subtype = symbols_by_debug_address[t["type"]] + pmap = get_pointer_map(subtype, depth+1) + size = get_size(subtype) + expanded_map = {} + for i in range(t["maxlen"]): + for offset in pmap: + expanded_map[size * i + offset] = pmap[offset] + return expanded_map + else: + print("no recurse", t) + pass + return {} + + # Do a second pass to dereference the types + for symbol_address in symbols_by_memory_address: + symbol = symbols_by_memory_address[symbol_address] + if "type" in symbol: + if symbol["debug_type"] == "DW_TAG_variable": + symbol["pointer_map"] = get_pointer_map(symbols_by_debug_address[symbol["type"]]) + type_string = [] + t = symbol["type"] + offset = [] + while t != None: + t_symbol = symbols_by_debug_address[t] + t = t_symbol.get("type", None) + if "name" in t_symbol: + type_string.append(t_symbol["name"]) + elif t_symbol["debug_type"] == "DW_TAG_array_type": + type_string.append("[]") + elif t_symbol["debug_type"] == "DW_TAG_pointer_type": + type_string.append("*") + elif t_symbol["debug_type"] == "DW_TAG_const_type": + type_string.append("const") + elif t_symbol["debug_type"] == "DW_TAG_volatile_type": + type_string.append("volatile") + else: + #print(" ", t_symbol) + pass + type_string.reverse() + symbol["type_string"] = " ".join(type_string) + #print(symbol_name, symbol["debug_type"], symbol.get("type_string", "")) + + # print() + # print() + # print(all_symbols["mp_builtin_module_table"]) + # return + + # Gather size and call info + text_dump = objdump("-Dz", "-j", ".text", elf_filename) + text_dump_lines = text_dump.stdout.decode("utf-8").split("\n") + section = None + symbol = None + symbol_type = None + for line in text_dump_lines[4:]: + if line.startswith("Disassembly of section"): + section = line.split()[-1].strip(":") + elif not line: + if symbol and "end_address" not in symbol: + symbol["end_address"] = last_address + symbol["size"] = last_address - symbol["start_address"] + symbol = None + continue + elif line[0].isnumeric(): + symbol_address, symbol_name = line.split() + symbol_address = parse_hex(symbol_address) + symbol_name = symbol_name.strip("<>:") + if symbol_name in symbols_by_linkage_name: + linked_name = symbol_name + symbol = symbols_by_linkage_name[symbol_name] + if "name" in symbol: + non_linkage = symbol["name"] + if not non_linkage.startswith("__builtin"): + symbol_name = non_linkage + all_symbols[symbol_name] = symbol + if "name" not in symbol: + symbol["name"] = symbol_name + elif symbol_address in symbols_by_memory_address: + all_symbols[symbol_name] = symbols_by_memory_address[symbol_address] + if "name" not in all_symbols[symbol_name]: + all_symbols[symbol_name]["name"] = symbol_name + elif symbol_name not in all_symbols: + if symbol_name == "nlr_push_tail_var": + fake_type = all_symbols["mp_obj_get_type"]["type"] + symbol = {"debug_type": "DW_TAG_variable", "name": symbol_name, "type": fake_type} + else: + print(line) + print(symbol_name, symbol_address) + symbol = {"debug_type": "DW_TAG_subprogram", "name": symbol_name} + all_symbols[symbol_name] = symbol + #raise RuntimeError() + + symbol = all_symbols[symbol_name] + symbol["start_address"] = symbol_address + symbols_by_memory_address[symbol_address] = symbol + symbol["section"] = section + + if symbol["debug_type"] == "DW_TAG_subprogram": + symbol["outgoing_jumps"] = set() + symbol["incoming_jumps"] = set() + symbol_type = None + elif symbol["debug_type"] == "DW_TAG_variable": + symbol["outgoing_pointers"] = set() + symbol_type = symbols_by_debug_address[symbol["type"]] + all_symbols[symbol_name] = symbol + + elif line[0] == " ": + parts = line.strip().split() + last_address = parse_hex(parts[0].strip(":")) + + offset = last_address - symbol["start_address"] + if "pointer_map" in symbol: + if offset not in symbol["pointer_map"]: + #print(offset, symbol) + pass + else: + ref = parse_hex(parts[1]) + pointer_style = symbol["pointer_map"][offset] + if pointer_style == MEMORY_POINTER: + symbol["outgoing_pointers"].add(ref & 0xfffffffe) + elif pointer_style == MEMORY_PY_OBJECT and ref & 0x3 == 0: + symbol["outgoing_pointers"].add(ref) + if len(parts[1]) == 8 and parts[1][0] == "0": + addr = parse_hex(parts[1]) + if 0x2000 <= addr < 0x20000000: + if "outgoing_pointers" not in symbol: + symbol["outgoing_pointers"] = set() + symbol["outgoing_pointers"].add(addr) + elif "<" in line and symbol["debug_type"] == "DW_TAG_subprogram": + if line[-1] == ">": + jump_to = parts[-1].strip("<>").split("+")[0] + if "name" not in symbol: + print(jump_to) + print(symbol) + if jump_to != symbol["name"] and jump_to not in BAD_JUMPS: + symbol["outgoing_jumps"].add(jump_to) + #print(symbol_name, jump_to) + if jump_to == "_etext": + print(line) + elif "UNDEFINED" in line: + continue + elif parts[2] == "ldr": + continue + else: + print(line) + else: + #print(line) + pass + + # print() + print(hex(min_call_site_param)) + print(all_symbols["exception_table"]) + # return + + print("converting outgoing pointers to names") + + # Convert outgoing pointers to names from addresses + for symbol_name in all_symbols: + symbol = all_symbols[symbol_name] + if "outgoing_pointers" not in symbol: + continue + converted = set() + for outgoing in symbol["outgoing_pointers"]: + if outgoing in symbols_by_memory_address: + outgoing = symbols_by_memory_address[outgoing] + #print(outgoing) + if outgoing["debug_type"] in ["DW_TAG_GNU_call_site", "DW_TAG_lexical_block"]: + continue + if outgoing["name"] == "audioio_wavefile_type": + print(outgoing) + converted.add(outgoing["name"]) + symbol["outgoing_pointers"] = converted + + print("linking back") + # Link back + for symbol_name in all_symbols: + symbol = all_symbols[symbol_name] + if "outgoing_jumps" in symbol: + for outgoing in symbol["outgoing_jumps"]: + if outgoing not in all_symbols: + #print(outgoing, symbol_name) + continue + #print(all_symbols[outgoing], symbol_name) + + referenced_symbol = all_symbols[outgoing] + if "incoming_jumps" not in referenced_symbol: + #print(symbol_name, "->", outgoing) + referenced_symbol["incoming_jumps"] = set() + referenced_symbol["incoming_jumps"].add(symbol_name) + if "outgoing_pointers" in symbol: + for outgoing in symbol["outgoing_pointers"]: + if outgoing not in all_symbols: + #print(outgoing, symbol_name) + continue + #print(all_symbols[outgoing], symbol_name) + + referenced_symbol = all_symbols[outgoing] + if "incoming_pointers" not in referenced_symbol: + #print(symbol_name, "->", outgoing) + referenced_symbol["incoming_pointers"] = set() + referenced_symbol["incoming_pointers"].add(symbol_name) + + print(all_symbols["exception_table"]) + + # Chart it all + print("charting {} symbols".format(len(all_symbols))) + callgraph = pgv.AGraph(directed=True) + for i, symbol_name in enumerate(all_symbols): + symbol = all_symbols[symbol_name] + # print(i, symbol_name) + # if "outgoing_jumps" in symbol: + # print(" ", len(symbol["outgoing_jumps"]), "jumps") + # if "outgoing_pointers" in symbol: + # print(" ", len(symbol["outgoing_pointers"]), "ptrs") + # if i > 3000: + # break + if ("incoming_jumps" not in symbol or len(symbol["incoming_jumps"]) == 0) and ("incoming_pointers" not in symbol or len(symbol["incoming_pointers"]) == 0): + #print(symbol_name) + continue + if "start_address" not in symbol: + continue + callgraph.add_node(symbol_name) + if "outgoing_jumps" in symbol: + for outgoing in symbol["outgoing_jumps"]: + callgraph.add_edge(symbol_name, outgoing) + if "outgoing_pointers" in symbol: + for outgoing in symbol["outgoing_pointers"]: + callgraph.add_edge(symbol_name, outgoing, color="red") + #print(symbol_name, symbol) + + # Style all of the nodes + print("styling") + for node in callgraph.iternodes(): + if node.name not in all_symbols: + continue + symbol = all_symbols[node.name] + node.attr["shape"] = "box" + text_width_ish = len(node.name) * 0.1 + if "size" not in symbol: + print(symbol) + size = symbol["size"] / 8 + square_size = size ** 0.5 + if text_width_ish > square_size: + w = text_width_ish + h = size / text_width_ish + else: + w = square_size + h = square_size + node.attr["width"] = w + node.attr["height"] = h + node.attr["label"] = node.name + "\r\n" + str(symbol["size"]) + " bytes" + node.attr["style"] = "filled" + + incoming = 0 + if "incoming_jumps" in symbol: + incoming += len(symbol["incoming_jumps"]) + if "incoming_pointers" in symbol: + incoming += len(symbol["incoming_pointers"]) + + if node.name in SPECIAL_NODE_COLORS: + node.attr["color"] = SPECIAL_NODE_COLORS[node.name] + elif incoming == 1: + node.attr["color"] = "lightblue" + elif incoming > 25: + print("delete", node.name, "because it has {} incoming".format(incoming)) + callgraph.delete_node(node.name) + elif incoming > 15: + node.attr["color"] = "red" + + print("drawing") + callgraph.layout(prog="dot") + fn = "callgraph.svg" + print(fn) + callgraph.draw(fn) + +if __name__ == "__main__": + do_all_the_things() -- cgit v1.2.3 From 8195df1b550522e4da32319d73b88702f638d6fe Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 8 Jun 2018 14:01:54 -0700 Subject: Stub out get_paused in nrf builds. --- ports/nrf/common-hal/pulseio/PulseIn.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c index aa6bb8665..e759ac3a3 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -71,6 +71,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { return 0xadaf; } +bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) { + return true; +} + uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { return 0xadaf; } -- cgit v1.2.3 From 8fb34a584664c800a4ea4d2d4c351c822bb03a98 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 8 Jun 2018 14:57:20 -0700 Subject: Use bool not int. --- ports/atmel-samd/common-hal/pulseio/PulseIn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index dee32bbec..d16bbf9d2 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -125,7 +125,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, self->first_edge = true; self->last_us = 0; self->last_ms = 0; - self->errored_too_fast = 0; + self->errored_too_fast = false; set_eic_channel_data(pin->extint_channel, (void*) self); -- cgit v1.2.3