From 76c366df56ad64eae3b021304954954e663bf1df Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 4 Sep 2016 00:12:48 +1000 Subject: stmhal: Add machine.WDT class. Usage: import machine wdt = machine.WDT(0, 5000) # 5 second timeout wdt.feed() Thanks to Moritz for the initial implementation. --- stmhal/Makefile | 1 + stmhal/modmachine.c | 3 +- stmhal/wdt.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++ stmhal/wdt.h | 27 ++++++++++++++ 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 stmhal/wdt.c create mode 100644 stmhal/wdt.h diff --git a/stmhal/Makefile b/stmhal/Makefile index 2c6ea806e..e06eed1cc 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -138,6 +138,7 @@ SRC_C = \ uart.c \ can.c \ usb.c \ + wdt.c \ gccollect.c \ pybstdio.c \ help.c \ diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c index 0b01058fa..68c43d67e 100644 --- a/stmhal/modmachine.c +++ b/stmhal/modmachine.c @@ -44,6 +44,7 @@ #include "rtc.h" #include "i2c.h" #include "spi.h" +#include "wdt.h" // machine.info([dump_alloc_table]) // Print out lots of information about the board. @@ -490,10 +491,10 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { // initialize master mode on the peripheral. { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&machine_i2c_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type }, #if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type }, diff --git a/stmhal/wdt.c b/stmhal/wdt.c new file mode 100644 index 000000000..6e1172caf --- /dev/null +++ b/stmhal/wdt.c @@ -0,0 +1,102 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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 STM32_HAL_H + +#include "py/runtime.h" +#include "wdt.h" + +typedef struct _pyb_wdt_obj_t { + mp_obj_base_t base; +} pyb_wdt_obj_t; + +STATIC pyb_wdt_obj_t pyb_wdt = {{&pyb_wdt_type}}; + +STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 2, 2, false); + + mp_int_t id = mp_obj_get_int(args[0]); + if (id != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "WDT(%d) does not exist", id)); + } + + // timeout is in milliseconds + mp_int_t timeout = mp_obj_get_int(args[1]); + + // compute prescaler + uint32_t prescaler; + for (prescaler = 0; prescaler < 6 && timeout >= 512; ++prescaler, timeout /= 2) { + } + + // convert milliseconds to ticks + timeout *= 8; // 32kHz / 4 = 8 ticks per millisecond (approx) + if (timeout <= 0) { + mp_raise_ValueError("WDT timeout too short"); + } else if (timeout > 0xfff) { + mp_raise_ValueError("WDT timeout too long"); + } + timeout -= 1; + + // set the reload register + while (IWDG->SR & 2) { + } + IWDG->KR = 0x5555; + IWDG->RLR = timeout; + + // set the prescaler + while (IWDG->SR & 1) { + } + IWDG->KR = 0x5555; + IWDG->PR = prescaler; + + // start the watch dog + IWDG->KR = 0xcccc; + + return (mp_obj_t)&pyb_wdt; +} + +STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self_in) { + (void)self_in; + IWDG->KR = 0xaaaa; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_wdt_feed_obj, pyb_wdt_feed); + +STATIC const mp_map_elem_t pyb_wdt_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_feed), (mp_obj_t)&pyb_wdt_feed_obj }, +}; + +STATIC MP_DEFINE_CONST_DICT(pyb_wdt_locals_dict, pyb_wdt_locals_dict_table); + +const mp_obj_type_t pyb_wdt_type = { + { &mp_type_type }, + .name = MP_QSTR_WDT, + .make_new = pyb_wdt_make_new, + .locals_dict = (mp_obj_t)&pyb_wdt_locals_dict, +}; diff --git a/stmhal/wdt.h b/stmhal/wdt.h new file mode 100644 index 000000000..362d6ef68 --- /dev/null +++ b/stmhal/wdt.h @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 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. + */ + +extern const mp_obj_type_t pyb_wdt_type; -- cgit v1.2.3 From 4a33677c9720bd7f2ce5b0f816cc4c87220570ac Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 3 Sep 2016 20:44:24 +0300 Subject: esp8266/esp8266.ld: Move modmachinewdt to FlashROM. --- esp8266/esp8266.ld | 1 + 1 file changed, 1 insertion(+) diff --git a/esp8266/esp8266.ld b/esp8266/esp8266.ld index dec3bf5a3..853f8fb0f 100644 --- a/esp8266/esp8266.ld +++ b/esp8266/esp8266.ld @@ -142,6 +142,7 @@ SECTIONS *modpybuart.o(.literal*, .text*) *modpybi2c.o(.literal*, .text*) *modmachinespi.o(.literal*, .text*) + *modmachinewdt.o(.literal*, .text*) *modpybspi.o(.literal*, .text*) *modpybhspi.o(.literal*, .text*) *hspi.o(.literal*, .text*) -- cgit v1.2.3 From 015774a04faa50708ce3692dc3748989e19e98e9 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 3 Sep 2016 20:45:11 +0300 Subject: esp8266/modmachinewdt: Add .deinit() method. --- esp8266/esp_mphal.c | 4 ---- esp8266/etshal.h | 3 +++ esp8266/modmachinewdt.c | 11 ++++++++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/esp8266/esp_mphal.c b/esp8266/esp_mphal.c index 06049e395..dc6944fd4 100644 --- a/esp8266/esp_mphal.c +++ b/esp8266/esp_mphal.c @@ -36,10 +36,6 @@ #include "extmod/misc.h" #include "lib/utils/pyexec.h" -extern void ets_wdt_disable(void); -extern void wdt_feed(void); -extern void ets_delay_us(); - STATIC byte input_buf_array[256]; ringbuf_t input_buf = {input_buf_array, sizeof(input_buf_array)}; void mp_hal_debug_tx_strn_cooked(void *env, const char *str, uint32_t len); diff --git a/esp8266/etshal.h b/esp8266/etshal.h index dd61ddec9..e7326a43b 100644 --- a/esp8266/etshal.h +++ b/esp8266/etshal.h @@ -20,6 +20,9 @@ void ets_timer_arm_new(os_timer_t *tim, uint32_t millis, bool repeat, bool is_mi void ets_timer_setfn(os_timer_t *tim, ETSTimerFunc callback, void *cb_data); void ets_timer_disarm(os_timer_t *tim); +extern void ets_wdt_disable(void); +extern void wdt_feed(void); + // Opaque structure typedef char MD5_CTX[64]; diff --git a/esp8266/modmachinewdt.c b/esp8266/modmachinewdt.c index e0b1ff5d7..6dc4c0d18 100644 --- a/esp8266/modmachinewdt.c +++ b/esp8266/modmachinewdt.c @@ -31,6 +31,7 @@ #include "py/obj.h" #include "py/runtime.h" #include "user_interface.h" +#include "etshal.h" const mp_obj_type_t esp_wdt_type; @@ -63,8 +64,16 @@ STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed); +STATIC mp_obj_t machine_wdt_deinit(mp_obj_t self_in) { + (void)self_in; + ets_wdt_disable(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_deinit_obj, machine_wdt_deinit); + STATIC const mp_map_elem_t machine_wdt_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_feed), (mp_obj_t)&machine_wdt_feed_obj } + { MP_OBJ_NEW_QSTR(MP_QSTR_feed), (mp_obj_t)&machine_wdt_feed_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&machine_wdt_deinit_obj }, }; STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table); -- cgit v1.2.3 From 8c6856d2e76c5865d9f30cad2c51615d4a1a1418 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Sat, 3 Sep 2016 20:44:12 +1200 Subject: py/emitglue.c: provide mp_raw_code_load_file for any unix architecture Signed-off-by: Chris Packham --- py/emitglue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/emitglue.c b/py/emitglue.c index 0b5903092..f4b59df3e 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -379,7 +379,7 @@ mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len) { // here we define mp_raw_code_load_file depending on the port // TODO abstract this away properly -#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || (defined(__arm__) && (defined(__unix__))) +#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || defined(__unix__) // unix file reader #include -- cgit v1.2.3 From 47899a1ab8756c3850bb275f3756544da0e7b050 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 4 Sep 2016 16:39:28 +1000 Subject: extmod/modframebuf: Include font from stmhal directory explicitly. So that users of framebuf don't need to have stmhal directory in their path. (Eventually the font can be moved elsewhere.) --- extmod/modframebuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 84f1246fb..569b75e1c 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -33,7 +33,7 @@ #if MICROPY_PY_FRAMEBUF -#include "font_petme128_8x8.h" +#include "stmhal/font_petme128_8x8.h" // 1-bit frame buffer, each byte is a column of 8 pixels typedef struct _mp_obj_framebuf1_t { -- cgit v1.2.3 From 2d8740a4d11fbc4d147636e2161ec08eb46ecf66 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 4 Sep 2016 16:40:40 +1000 Subject: tests/extmod: Add a test for framebuf module, tested by coverage build. --- tests/extmod/framebuf1.py | 35 +++++++++++++++++++++++++++++++++++ tests/extmod/framebuf1.py.exp | 6 ++++++ unix/mpconfigport_coverage.h | 1 + 3 files changed, 42 insertions(+) create mode 100644 tests/extmod/framebuf1.py create mode 100644 tests/extmod/framebuf1.py.exp diff --git a/tests/extmod/framebuf1.py b/tests/extmod/framebuf1.py new file mode 100644 index 000000000..85555d0d2 --- /dev/null +++ b/tests/extmod/framebuf1.py @@ -0,0 +1,35 @@ +try: + import framebuf +except ImportError: + print("SKIP") + import sys + sys.exit() + +w = 5 +h = 16 +buf = bytearray(w * h // 8) +fbuf = framebuf.FrameBuffer1(buf, w, h, w) + +# fill +fbuf.fill(1) +print(buf) +fbuf.fill(0) +print(buf) + +# put pixel +fbuf.pixel(0, 0, 1) +fbuf.pixel(4, 0, 1) +fbuf.pixel(0, 15, 1) +fbuf.pixel(4, 15, 1) +print(buf) + +# get pixel +print(fbuf.pixel(0, 0), fbuf.pixel(1, 1)) + +# scroll +fbuf.fill(0) +fbuf.pixel(2, 7, 1) +fbuf.scroll(0, 1) +print(buf) +fbuf.scroll(0, -2) +print(buf) diff --git a/tests/extmod/framebuf1.py.exp b/tests/extmod/framebuf1.py.exp new file mode 100644 index 000000000..5aca19461 --- /dev/null +++ b/tests/extmod/framebuf1.py.exp @@ -0,0 +1,6 @@ +bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x01\x00\x00\x00\x01\x80\x00\x00\x00\x80') +1 0 +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00') +bytearray(b'\x00\x00@\x00\x00\x00\x00\x00\x00\x00') diff --git a/unix/mpconfigport_coverage.h b/unix/mpconfigport_coverage.h index f9a6fbd9d..5fd5b82c1 100644 --- a/unix/mpconfigport_coverage.h +++ b/unix/mpconfigport_coverage.h @@ -35,3 +35,4 @@ #undef MICROPY_VFS_FAT #define MICROPY_FSUSERMOUNT (1) #define MICROPY_VFS_FAT (1) +#define MICROPY_PY_FRAMEBUF (1) -- cgit v1.2.3 From fedab995ee60d94d708ba27d7d903ccfb2b0919f Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Fri, 2 Sep 2016 13:22:49 -0700 Subject: stmhal: Set STM32F7DISC CPU Frequency to 216 MHz This set the CPU frequency to 216 MHz (the max) and leaves the USB Frequency at 48 MHz. These settings were copied from one of the HAL examples. --- stmhal/boards/STM32F7DISC/mpconfigboard.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/stmhal/boards/STM32F7DISC/mpconfigboard.h b/stmhal/boards/STM32F7DISC/mpconfigboard.h index c0e47c3ce..a1dbc0f46 100644 --- a/stmhal/boards/STM32F7DISC/mpconfigboard.h +++ b/stmhal/boards/STM32F7DISC/mpconfigboard.h @@ -20,12 +20,19 @@ void STM32F7DISC_board_early_init(void); // HSE is 25MHz +// VCOClock = HSE * PLLN / PLLM = 25 MHz * 432 / 25 = 432 MHz +// SYSCLK = VCOClock / PLLP = 432 MHz / 2 = 216 MHz +// USB/SDMMC/RNG Clock = VCOClock / PLLQ = 432 MHz / 9 = 48 MHz #define MICROPY_HW_CLK_PLLM (25) -#define MICROPY_HW_CLK_PLLN (336) +#define MICROPY_HW_CLK_PLLN (432) #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) -#define MICROPY_HW_CLK_PLLQ (7) +#define MICROPY_HW_CLK_PLLQ (9) -#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_6 +// From the reference manual, for 2.7V to 3.6V +// 151-180 MHz => 5 wait states +// 181-210 MHz => 6 wait states +// 211-216 MHz => 7 wait states +#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_7 // 210-216 MHz needs 7 wait states // UART config #define MICROPY_HW_UART1_TX_PORT (GPIOA) -- cgit v1.2.3 From 1bc5cb4312cae9702ab5fe5412b16156a08b8280 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 4 Sep 2016 14:44:12 +0300 Subject: extmod/moduzlib: Support wbits arg to DecompIO. --- extmod/moduzlib.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index dbf513527..65cbc5eb0 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -67,17 +67,31 @@ STATIC unsigned char read_src_stream(TINF_DATA *data) { return c; } -#define DICT_SIZE 32768 - STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_arg_check_num(n_args, n_kw, 1, 2, false); mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t); o->base.type = type; memset(&o->decomp, 0, sizeof(o->decomp)); - uzlib_uncompress_init(&o->decomp, m_new(byte, DICT_SIZE), DICT_SIZE); o->decomp.readSource = read_src_stream; o->src_stream = args[0]; o->eof = false; + + mp_int_t dict_opt = 0; + int dict_sz; + if (n_args > 1) { + dict_opt = mp_obj_get_int(args[1]); + } + if (dict_opt >= 0) { + dict_opt = uzlib_zlib_parse_header(&o->decomp); + if (dict_opt < 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "zlib header")); + } + dict_sz = 1 << dict_opt; + } else { + dict_sz = 1 << -dict_opt; + } + + uzlib_uncompress_init(&o->decomp, m_new(byte, dict_sz), dict_sz); return MP_OBJ_FROM_PTR(o); } -- cgit v1.2.3 From 61e2dfd97dde31c6f6f1005aa0c0a1f616963f7a Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 4 Sep 2016 14:45:27 +0300 Subject: tests/extmod/uzlib_decompio: Add zlib bitstream testcases. --- tests/extmod/uzlib_decompio.py | 15 ++++++++++++++- tests/extmod/uzlib_decompio.py.exp | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/extmod/uzlib_decompio.py b/tests/extmod/uzlib_decompio.py index ee3204d07..75a6df0ca 100644 --- a/tests/extmod/uzlib_decompio.py +++ b/tests/extmod/uzlib_decompio.py @@ -7,7 +7,7 @@ import uio as io # Raw DEFLATE bitstream buf = io.BytesIO(b'\xcbH\xcd\xc9\xc9\x07\x00') -inp = zlib.DecompIO(buf) +inp = zlib.DecompIO(buf, -8) print(buf.seek(0, 1)) print(inp.read(1)) print(buf.seek(0, 1)) @@ -17,3 +17,16 @@ print(buf.seek(0, 1)) print(inp.read(1)) print(inp.read()) print(buf.seek(0, 1)) + + +# zlib bitstream +inp = zlib.DecompIO(io.BytesIO(b'x\x9c30\xa0=\x00\x00\xb3q\x12\xc1')) +print(inp.read(10)) +print(inp.read()) + +# zlib bitstream, wrong checksum +inp = zlib.DecompIO(io.BytesIO(b'x\x9c30\xa0=\x00\x00\xb3q\x12\xc0')) +try: + print(inp.read()) +except OSError as e: + print(repr(e)) diff --git a/tests/extmod/uzlib_decompio.py.exp b/tests/extmod/uzlib_decompio.py.exp index 6ef811d7d..3f5f360fa 100644 --- a/tests/extmod/uzlib_decompio.py.exp +++ b/tests/extmod/uzlib_decompio.py.exp @@ -7,3 +7,6 @@ b'lo' b'' b'' 7 +b'0000000000' +b'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' +OSError(22,) -- cgit v1.2.3 From 1708fe3cc719aec15b9f6d5a39cb0181b4547161 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 4 Sep 2016 19:45:58 +0300 Subject: esp8266/modmachine: Add WDT_RESET and SOFT_RESET constants. Both tested to work. (WDT_RESET can be seen by issuing machine.disable_irq() and waiting for WDT reset, SOFT_RESET - by machine.reset()). --- esp8266/modmachine.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index 0972ce29f..e7d91c237 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -265,6 +265,8 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PWR_ON_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) }, { MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) }, { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(REASON_DEEP_SLEEP_AWAKE) }, + { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(REASON_WDT_RST) }, + { MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(REASON_SOFT_RESTART) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); -- cgit v1.2.3 From 7ddd1a58f6ec90a35e2ca815f62358acfb801c52 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 4 Sep 2016 19:57:16 +0300 Subject: esp8266/modmachine: Don't expose internal SoftSPI and HSPI classes. There functionality is available via standard SPI class. --- esp8266/modmachine.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index e7d91c237..a6d5fc3db 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -254,8 +254,6 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, - { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&pyb_spi_type) }, - { MP_ROM_QSTR(MP_QSTR_HSPI), MP_ROM_PTR(&pyb_hspi_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, // wake abilities -- cgit v1.2.3 From dba40afa706a1ac4b102dceba217844dc1540ce7 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 4 Sep 2016 20:33:11 +0300 Subject: esp8266/modmachine: Simplify SPI class implementation multiplexing. modpybhspi now does the needed multiplexing, calling out to modpybspi (bitbanging SPI) for suitable peripheral ID's. modmachinespi (previous multiplexer class) thus not needed and removed. modpybhspi also updated to following standard SPI peripheral naming: SPI0 is used for FlashROM and thus not supported so far. SPI1 is available for users, and thus needs to be instantiated as: spi = machine.SPI(1, ...) --- esp8266/Makefile | 1 - esp8266/esp8266.ld | 1 - esp8266/modmachine.c | 2 +- esp8266/modmachinespi.c | 71 ------------------------------------------------- esp8266/modpybhspi.c | 27 ++++++++++++++++--- 5 files changed, 25 insertions(+), 77 deletions(-) delete mode 100644 esp8266/modmachinespi.c diff --git a/esp8266/Makefile b/esp8266/Makefile index 278651038..521cbb472 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -79,7 +79,6 @@ SRC_C = \ modpybadc.c \ modpybuart.c \ modmachinewdt.c \ - modmachinespi.c \ modpybspi.c \ modpybhspi.c \ modesp.c \ diff --git a/esp8266/esp8266.ld b/esp8266/esp8266.ld index 853f8fb0f..c726790d3 100644 --- a/esp8266/esp8266.ld +++ b/esp8266/esp8266.ld @@ -141,7 +141,6 @@ SECTIONS *modpybadc.o(.literal*, .text*) *modpybuart.o(.literal*, .text*) *modpybi2c.o(.literal*, .text*) - *modmachinespi.o(.literal*, .text*) *modmachinewdt.o(.literal*, .text*) *modpybspi.o(.literal*, .text*) *modpybhspi.o(.literal*, .text*) diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index a6d5fc3db..df1ae0fcf 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -254,7 +254,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&pyb_hspi_type) }, // wake abilities { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) }, diff --git a/esp8266/modmachinespi.c b/esp8266/modmachinespi.c deleted file mode 100644 index 1c6a37369..000000000 --- a/esp8266/modmachinespi.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 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 -#include - -#include "ets_sys.h" -#include "etshal.h" -#include "ets_alt_task.h" - -#include "py/runtime.h" -#include "py/stream.h" -#include "py/mphal.h" - - -mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args); -mp_obj_t pyb_hspi_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args); - - -STATIC mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - switch (mp_obj_get_int(args[0])) { - case -1: - return pyb_spi_make_new(type, n_args - 1, n_kw, args + 1); - case 0: - return pyb_hspi_make_new(type, n_args - 1, n_kw, args + 1); - default: - nlr_raise(mp_obj_new_exception_msg_varg( - &mp_type_ValueError, "no such SPI peripheral")); - } -} - - -STATIC const mp_rom_map_elem_t machine_spi_locals_dict_table[] = {}; - -STATIC MP_DEFINE_CONST_DICT(machine_spi_locals_dict, - machine_spi_locals_dict_table); - -const mp_obj_type_t machine_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .make_new = machine_spi_make_new, - .locals_dict = (mp_obj_dict_t*)&machine_spi_locals_dict, -}; diff --git a/esp8266/modpybhspi.c b/esp8266/modpybhspi.c index c4d4dcee8..c1cd7f662 100644 --- a/esp8266/modpybhspi.c +++ b/esp8266/modpybhspi.c @@ -39,6 +39,8 @@ #include "hspi.h" +mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *args); typedef struct _pyb_hspi_obj_t { mp_obj_base_t base; @@ -105,13 +107,14 @@ STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t src_len, const uint8_t STATIC void pyb_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pyb_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "HSPI(baudrate=%u, polarity=%u, phase=%u)", + mp_printf(print, "HSPI(id=1, baudrate=%u, polarity=%u, phase=%u)", self->baudrate, self->polarity, self->phase); } STATIC void pyb_hspi_init_helper(pyb_hspi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_baudrate, ARG_polarity, ARG_phase }; + enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} }, @@ -160,7 +163,25 @@ STATIC void pyb_hspi_init_helper(pyb_hspi_obj_t *self, size_t n_args, const mp_o } mp_obj_t pyb_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); + mp_arg_check_num(n_args, n_kw, 0, 1, true); + mp_int_t id = -1; + if (n_args > 0) { + id = mp_obj_get_int(args[0]); + } + + if (id == -1) { + // Multiplex to bitbanging SPI + if (n_args > 0) { + args++; + } + return pyb_spi_make_new(type, 0, n_kw, args); + } + + if (id != 1) { + // FlashROM is on SPI0, so far we don't support its usage + mp_raise_ValueError(""); + } + pyb_hspi_obj_t *self = m_new_obj(pyb_hspi_obj_t); self->base.type = &pyb_hspi_type; // set defaults -- cgit v1.2.3 From 20da9064d7492b2f37a2140c17e468fb5785a593 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 4 Sep 2016 21:13:55 +0300 Subject: docs/esp8266/quickref: Update information on SPI classes. SPI(1) is not used for hardware SPI. Few more details are provided. --- docs/esp8266/quickref.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst index d20987136..ae7a8f724 100644 --- a/docs/esp8266/quickref.rst +++ b/docs/esp8266/quickref.rst @@ -165,7 +165,8 @@ Use the ``machine.ADC`` class:: SPI bus ------- -There are two SPI drivers. One is implemented in software and works on all pins:: +There are two SPI drivers. One is implemented in software (bit-banging) +and works on all pins:: from machine import Pin, SPI @@ -194,14 +195,15 @@ Hardware SPI ------------ The hardware SPI is faster (up to 80Mhz), but only works on following pins: -``MISO`` is gpio12, ``MOSI`` is gpio13, and ``SCK`` is gpio14. It has the same +``MISO`` is GPIO12, ``MOSI`` is GPIO13, and ``SCK`` is GPIO14. It has the same methods as SPI, except for the pin parameters for the constructor and init (as those are fixed). from machine import Pin, SPI - hspi = SPI(0, baudrate=80000000, polarity=0, phase=0) + hspi = SPI(1, baudrate=80000000, polarity=0, phase=0) +(SPI(0) is used for FlashROM and not available to users.) I2C bus ------- -- cgit v1.2.3 From b4df3e74e15ac1658c125b13bbaca5203bab5505 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 4 Sep 2016 23:31:05 +0300 Subject: docs/esp8266/quickref: Further improvements for SPI subsections. Consistency and formatting. --- docs/esp8266/quickref.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst index ae7a8f724..d06fe5a6f 100644 --- a/docs/esp8266/quickref.rst +++ b/docs/esp8266/quickref.rst @@ -162,8 +162,8 @@ Use the ``machine.ADC`` class:: adc = ADC(0) # create ADC object on ADC pin adc.read() # read value, 0-1024 -SPI bus -------- +Software SPI bus +---------------- There are two SPI drivers. One is implemented in software (bit-banging) and works on all pins:: @@ -191,19 +191,19 @@ and works on all pins:: spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf -Hardware SPI ------------- +Hardware SPI bus +---------------- The hardware SPI is faster (up to 80Mhz), but only works on following pins: ``MISO`` is GPIO12, ``MOSI`` is GPIO13, and ``SCK`` is GPIO14. It has the same -methods as SPI, except for the pin parameters for the constructor and init -(as those are fixed). +methods as the bitbanging SPI class above, except for the pin parameters for the +constructor and init (as those are fixed):: from machine import Pin, SPI hspi = SPI(1, baudrate=80000000, polarity=0, phase=0) -(SPI(0) is used for FlashROM and not available to users.) +(``SPI(0)`` is used for FlashROM and not available to users.) I2C bus ------- -- cgit v1.2.3 From 778729c5977633978aef2ec302472505973a657e Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Fri, 2 Sep 2016 16:15:37 +0200 Subject: extmod/framebuf: Add the xstep!=0 case to scroll() method. Adds horizontal scrolling. Right now, I'm just leaving the margins created by the scrolling as they were -- so they will repeat the edge of the framebuf. This is fast, and the user can always fill the margins themselves. --- extmod/modframebuf.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c index 569b75e1c..3c884c689 100644 --- a/extmod/modframebuf.c +++ b/extmod/modframebuf.c @@ -103,7 +103,7 @@ STATIC mp_obj_t framebuf1_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t y mp_int_t xstep = mp_obj_get_int(xstep_in); mp_int_t ystep = mp_obj_get_int(ystep_in); int end = (self->height + 7) >> 3; - if (xstep == 0 && ystep > 0) { + if (ystep > 0) { for (int y = end; y > 0;) { --y; for (int x = 0; x < self->width; ++x) { @@ -114,7 +114,7 @@ STATIC mp_obj_t framebuf1_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t y self->buf[y * self->stride + x] = (self->buf[y * self->stride + x] << ystep) | prev; } } - } else if (xstep == 0 && ystep < 0) { + } else if (ystep < 0) { for (int y = 0; y < end; ++y) { for (int x = 0; x < self->width; ++x) { int prev = 0; @@ -125,7 +125,20 @@ STATIC mp_obj_t framebuf1_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t y } } } - // TODO xstep!=0 + if (xstep < 0) { + for (int y = 0; y < end; ++y) { + for (int x = 0; x < self->width + xstep; ++x) { + self->buf[y * self->stride + x] = self->buf[y * self->stride + x - xstep]; + } + } + } else if (xstep > 0) { + for (int y = 0; y < end; ++y) { + for (int x = self->width - 1; x >= xstep; --x) { + self->buf[y * self->stride + x] = self->buf[y * self->stride + x - xstep]; + } + } + } + // TODO: Should we clear the margin created by scrolling? return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf1_scroll_obj, framebuf1_scroll); -- cgit v1.2.3 From cac8dc34149686679b67037d393d3ea1c6aff779 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 5 Sep 2016 12:08:25 +1000 Subject: tests/extmod/framebuf1: Add tests for scrolling in the x-direction. --- tests/extmod/framebuf1.py | 6 ++++++ tests/extmod/framebuf1.py.exp | 3 +++ 2 files changed, 9 insertions(+) diff --git a/tests/extmod/framebuf1.py b/tests/extmod/framebuf1.py index 85555d0d2..f550b6b4f 100644 --- a/tests/extmod/framebuf1.py +++ b/tests/extmod/framebuf1.py @@ -33,3 +33,9 @@ fbuf.scroll(0, 1) print(buf) fbuf.scroll(0, -2) print(buf) +fbuf.scroll(1, 0) +print(buf) +fbuf.scroll(-1, 0) +print(buf) +fbuf.scroll(2, 2) +print(buf) diff --git a/tests/extmod/framebuf1.py.exp b/tests/extmod/framebuf1.py.exp index 5aca19461..8fd8c3709 100644 --- a/tests/extmod/framebuf1.py.exp +++ b/tests/extmod/framebuf1.py.exp @@ -4,3 +4,6 @@ bytearray(b'\x01\x00\x00\x00\x01\x80\x00\x00\x00\x80') 1 0 bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00') bytearray(b'\x00\x00@\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00@\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00@\x00\x00\x00\x00\x00\x00\x00') +bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01') -- cgit v1.2.3 From e2ac8bb3f14b076a29244022865e3b47c6c0800a Mon Sep 17 00:00:00 2001 From: Delio Brignoli Date: Sun, 21 Aug 2016 11:33:37 +0200 Subject: py: Add MICROPY_USE_INTERNAL_PRINTF option, defaults to enabled. This new config option allows to control whether MicroPython uses its own internal printf or not (if not, an external one should be linked in). Accompanying this new option is the inclusion of lib/utils/printf.c in the core list of source files, so that ports no longer need to include it themselves. --- bare-arm/mpconfigport.h | 1 + cc3200/application.mk | 1 - esp8266/Makefile | 1 - lib/utils/printf.c | 6 ++++++ minimal/Makefile | 1 - py/mpconfig.h | 5 +++++ py/py.mk | 1 + qemu-arm/mpconfigport.h | 1 + stmhal/Makefile | 1 - teensy/Makefile | 1 - unix/Makefile | 1 - 11 files changed, 14 insertions(+), 6 deletions(-) diff --git a/bare-arm/mpconfigport.h b/bare-arm/mpconfigport.h index 7c448d13c..79b2b7328 100644 --- a/bare-arm/mpconfigport.h +++ b/bare-arm/mpconfigport.h @@ -42,6 +42,7 @@ #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) +#define MICROPY_USE_INTERNAL_PRINTF (0) // type definitions for the specific machine diff --git a/cc3200/application.mk b/cc3200/application.mk index dca6fcbc6..300262c97 100644 --- a/cc3200/application.mk +++ b/cc3200/application.mk @@ -154,7 +154,6 @@ APP_LIB_SRC_C = $(addprefix lib/,\ timeutils/timeutils.c \ utils/pyexec.c \ utils/pyhelp.c \ - utils/printf.c \ ) APP_STM_SRC_C = $(addprefix stmhal/,\ diff --git a/esp8266/Makefile b/esp8266/Makefile index 521cbb472..1dfcec809 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -128,7 +128,6 @@ LIB_SRC_C = $(addprefix lib/,\ timeutils/timeutils.c \ utils/pyexec.c \ utils/pyhelp.c \ - utils/printf.c \ fatfs/ff.c \ fatfs/option/ccsbcs.c \ ) diff --git a/lib/utils/printf.c b/lib/utils/printf.c index 308525b6e..303edfcca 100644 --- a/lib/utils/printf.c +++ b/lib/utils/printf.c @@ -24,6 +24,10 @@ * THE SOFTWARE. */ +#include "py/mpconfig.h" + +#if MICROPY_USE_INTERNAL_PRINTF + #include #include #include @@ -127,3 +131,5 @@ int snprintf(char *str, size_t size, const char *fmt, ...) { va_end(ap); return ret; } + +#endif //MICROPY_USE_INTERNAL_PRINTF diff --git a/minimal/Makefile b/minimal/Makefile index 02096f9f0..0cecd1c0f 100644 --- a/minimal/Makefile +++ b/minimal/Makefile @@ -46,7 +46,6 @@ SRC_C = \ main.c \ uart_core.c \ lib/utils/stdout_helpers.c \ - lib/utils/printf.c \ lib/utils/pyexec.c \ lib/libc/string0.c \ lib/mp-readline/readline.c \ diff --git a/py/mpconfig.h b/py/mpconfig.h index 455f870ac..e33a41f7a 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -581,6 +581,11 @@ typedef double mp_float_t; #define MICROPY_USE_INTERNAL_ERRNO (0) #endif +// Whether to use internally defined *printf() functions (otherwise external ones) +#ifndef MICROPY_USE_INTERNAL_PRINTF +#define MICROPY_USE_INTERNAL_PRINTF (1) +#endif + // Support for user-space VFS mount (selected ports) #ifndef MICROPY_FSUSERMOUNT #define MICROPY_FSUSERMOUNT (0) diff --git a/py/py.mk b/py/py.mk index abea7215b..37b98de92 100644 --- a/py/py.mk +++ b/py/py.mk @@ -223,6 +223,7 @@ PY_O_BASENAME = \ ../extmod/vfs_fat_misc.o \ ../extmod/moduos_dupterm.o \ ../lib/embed/abort_.o \ + ../lib/utils/printf.o \ # prepend the build destination prefix to the py object files PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME)) diff --git a/qemu-arm/mpconfigport.h b/qemu-arm/mpconfigport.h index 57277b156..1f23148c2 100644 --- a/qemu-arm/mpconfigport.h +++ b/qemu-arm/mpconfigport.h @@ -23,6 +23,7 @@ #define MICROPY_PY_IO (0) #define MICROPY_PY_SYS_EXIT (1) #define MICROPY_PY_SYS_MAXSIZE (1) +#define MICROPY_USE_INTERNAL_PRINTF (0) // type definitions for the specific machine diff --git a/stmhal/Makefile b/stmhal/Makefile index e06eed1cc..881c073f1 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -111,7 +111,6 @@ SRC_LIB = $(addprefix lib/,\ timeutils/timeutils.c \ utils/pyexec.c \ utils/pyhelp.c \ - utils/printf.c \ ) SRC_C = \ diff --git a/teensy/Makefile b/teensy/Makefile index 7b34ba90e..0ab07121c 100644 --- a/teensy/Makefile +++ b/teensy/Makefile @@ -110,7 +110,6 @@ LIB_SRC_C = $(addprefix lib/,\ mp-readline/readline.c \ utils/pyexec.c \ utils/pyhelp.c \ - utils/printf.c \ ) SRC_TEENSY = $(addprefix core/,\ diff --git a/unix/Makefile b/unix/Makefile index 3afa80dfa..49b605f12 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -157,7 +157,6 @@ endif LIB_SRC_C = $(addprefix lib/,\ $(LIB_SRC_C_EXTRA) \ - utils/printf.c \ timeutils/timeutils.c \ ) -- cgit v1.2.3 From 9526e24234bba06fcbf42c590743087bc8527319 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 5 Sep 2016 12:35:05 +1000 Subject: unix,stmhal,esp8266: When find'ing frozen files follow symbolic links. It's useful to be able to use symbolic links to add files and directories to the set of scripts to be frozen. --- esp8266/Makefile | 2 +- stmhal/Makefile | 2 +- unix/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/esp8266/Makefile b/esp8266/Makefile index 1dfcec809..433b41ecf 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -139,7 +139,7 @@ DRIVERS_SRC_C = $(addprefix drivers/,\ SRC_S = \ gchelper.s \ -FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR) -type f -name '*.py') +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) OBJ = diff --git a/stmhal/Makefile b/stmhal/Makefile index 881c073f1..b320e0c89 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -284,7 +284,7 @@ endif ifneq ($(FROZEN_MPY_DIR),) # To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and # then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch). -FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR) -type f -name '*.py') +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY diff --git a/unix/Makefile b/unix/Makefile index 49b605f12..956b1daef 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -182,7 +182,7 @@ ifneq ($(FROZEN_MPY_DIR),) # then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch). MPY_CROSS = ../mpy-cross/mpy-cross MPY_TOOL = ../tools/mpy-tool.py -FROZEN_MPY_PY_FILES := $(shell find $(FROZEN_MPY_DIR) -type f -name '*.py') +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY -- cgit v1.2.3 From ef47a67cf42246bbcf3c81e5f89e0e25db9dff74 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Mon, 13 Jun 2016 08:54:57 +0100 Subject: stmhal/dac: Fix DAC (re-)initialisation by resetting DMA. Fixes issue #2176. --- stmhal/dac.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/stmhal/dac.c b/stmhal/dac.c index 7493bb59a..a9b1b9eca 100644 --- a/stmhal/dac.c +++ b/stmhal/dac.c @@ -171,6 +171,14 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, mp_uint_t n_args, const #endif // stop anything already going on + __DMA1_CLK_ENABLE(); + DMA_HandleTypeDef DMA_Handle; + /* Get currently configured dma */ + dma_init_handle(&DMA_Handle, self->tx_dma_descr, (void*)NULL); + // Need to deinit DMA first + DMA_Handle.State = HAL_DMA_STATE_READY; + HAL_DMA_DeInit(&DMA_Handle); + HAL_DAC_Stop(&DAC_Handle, self->dac_channel); if ((self->dac_channel == DAC_CHANNEL_1 && DAC_Handle.DMA_Handle1 != NULL) || (self->dac_channel == DAC_CHANNEL_2 && DAC_Handle.DMA_Handle2 != NULL)) { -- cgit v1.2.3 From 2b882e9acaecd92cf3107a597c9aba99f23b794e Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 5 Sep 2016 17:30:24 +1000 Subject: mpy-cross: Don't use the internal printf functions. They require mp_hal_stdout_tx_strn_cooked, which requires extra work to add to mpy-cross. --- mpy-cross/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index c919e4291..c0a404103 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -59,6 +59,7 @@ #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE) #define MICROPY_CPYTHON_COMPAT (1) +#define MICROPY_USE_INTERNAL_PRINTF (0) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) -- cgit v1.2.3 From e4d6a10dc91f8af8b4ba3647c94e6ce730671864 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 5 Sep 2016 17:33:56 +1000 Subject: travis: Build mpy-cross as part of the Travis process. It's built first in case any ports need to use it. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f9ee2ab0f..99d8b8f0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,7 @@ before_script: - python3 --version script: + - make -C mpy-cross - make -C minimal test - make -C unix deplibs - make -C unix -- cgit v1.2.3 From 69768c97c060d1b6160e2abcd2fda9c63ce65a2d Mon Sep 17 00:00:00 2001 From: Torsten Wagner Date: Thu, 30 Jun 2016 11:11:56 +0200 Subject: esp8266/espneopixel: Disable IRQs during eps.neopixel_write. Interrupts during neopixel_write causes timing problems and therefore wrong light patterns. Switching off IRQs should help to keep the strict timing schedule. --- esp8266/espneopixel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp8266/espneopixel.c b/esp8266/espneopixel.c index 0f12f4c82..e16c874f2 100644 --- a/esp8266/espneopixel.c +++ b/esp8266/espneopixel.c @@ -41,6 +41,7 @@ void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32 } #endif + uint32_t irq_state = mp_hal_quiet_timing_enter(); for(t = time0;; t = time0) { if(pix & mask) t = time1; // Bit high duration while(((c = mp_hal_ticks_cpu()) - startTime) < period); // Wait for bit start @@ -55,4 +56,5 @@ void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32 } } while((mp_hal_ticks_cpu() - startTime) < period); // Wait for last bit + mp_hal_quiet_timing_exit(irq_state); } -- cgit v1.2.3 From b88bf6c76b9105110b7b2befe77ad58b90be8097 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 6 Sep 2016 14:19:40 +1000 Subject: stmhal/wdt: Implement keyword args to WDT constructor. --- stmhal/wdt.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/stmhal/wdt.c b/stmhal/wdt.c index 6e1172caf..d9a089d01 100644 --- a/stmhal/wdt.c +++ b/stmhal/wdt.c @@ -37,17 +37,23 @@ typedef struct _pyb_wdt_obj_t { STATIC pyb_wdt_obj_t pyb_wdt = {{&pyb_wdt_type}}; -STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 2, 2, false); - - mp_int_t id = mp_obj_get_int(args[0]); +STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + // parse arguments + enum { ARG_id, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_INT, {.u_int = 5000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t id = args[ARG_id].u_int; if (id != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "WDT(%d) does not exist", id)); } // timeout is in milliseconds - mp_int_t timeout = mp_obj_get_int(args[1]); + mp_int_t timeout = args[ARG_timeout].u_int; // compute prescaler uint32_t prescaler; -- cgit v1.2.3 From 9103cbe36629b121b1a8a927b3fa199c6ee5ddf3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 6 Sep 2016 14:20:19 +1000 Subject: stmhal/modmachine: Implement machine.reset_cause() function, and consts. --- stmhal/main.c | 3 +++ stmhal/modmachine.c | 62 ++++++++++++++++++++++++++++++++++++++++++++--------- stmhal/modmachine.h | 2 ++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/stmhal/main.c b/stmhal/main.c index 32baae532..244622503 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -44,6 +44,7 @@ #include "pendsv.h" #include "gccollect.h" #include "readline.h" +#include "modmachine.h" #include "i2c.h" #include "spi.h" #include "uart.h" @@ -410,6 +411,8 @@ soft_reset: led_state(4, 0); uint reset_mode = update_reset_mode(1); + machine_init(); + #if MICROPY_HW_ENABLE_RTC if (first_soft_reset) { rtc_init_start(false); diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c index 68c43d67e..dbeabec55 100644 --- a/stmhal/modmachine.c +++ b/stmhal/modmachine.c @@ -46,6 +46,49 @@ #include "spi.h" #include "wdt.h" +#if defined(MCU_SERIES_F4) +// the HAL does not define these constants +#define RCC_CSR_IWDGRSTF (0x20000000) +#define RCC_CSR_PINRSTF (0x04000000) +#elif defined(MCU_SERIES_L4) +// L4 does not have a POR, so use BOR instead +#define RCC_CSR_PORRSTF RCC_CSR_BORRSTF +#endif + +#define PYB_RESET_SOFT (0) +#define PYB_RESET_POWER_ON (1) +#define PYB_RESET_HARD (2) +#define PYB_RESET_WDT (3) +#define PYB_RESET_DEEPSLEEP (4) + +STATIC uint32_t reset_cause; + +void machine_init(void) { + #if defined(MCU_SERIES_F4) + if (PWR->CSR & PWR_CSR_SBF) { + // came out of standby + reset_cause = PYB_RESET_DEEPSLEEP; + PWR->CR = PWR_CR_CSBF; + } else + #endif + { + // get reset cause from RCC flags + uint32_t state = RCC->CSR; + if (state & RCC_CSR_IWDGRSTF || state & RCC_CSR_WWDGRSTF) { + reset_cause = PYB_RESET_WDT; + } else if (state & RCC_CSR_PORRSTF || state & RCC_CSR_BORRSTF) { + reset_cause = PYB_RESET_POWER_ON; + } else if (state & RCC_CSR_PINRSTF) { + reset_cause = PYB_RESET_HARD; + } else { + // default is soft reset + reset_cause = PYB_RESET_SOFT; + } + } + // clear RCC reset flags + RCC->CSR = RCC_CSR_RMVF; +} + // machine.info([dump_alloc_table]) // Print out lots of information about the board. STATIC mp_obj_t machine_info(mp_uint_t n_args, const mp_obj_t *args) { @@ -448,13 +491,10 @@ STATIC mp_obj_t machine_deepsleep(void) { } MP_DEFINE_CONST_FUN_OBJ_0(machine_deepsleep_obj, machine_deepsleep); -#if 0 STATIC mp_obj_t machine_reset_cause(void) { - return mp_obj_new_int(0); - //return mp_obj_new_int(pyb_sleep_get_reset_cause()); + return MP_OBJ_NEW_SMALL_INT(reset_cause); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause); -#endif STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_umachine) }, @@ -469,8 +509,8 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&pyb_wfi_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&machine_sleep_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_deepsleep), (mp_obj_t)&machine_deepsleep_obj }, -#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&machine_reset_cause_obj }, +#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&machine_wake_reason_obj }, #endif @@ -502,11 +542,13 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_IDLE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) }, { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HARD_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WDT_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_SOFT_RESET) }, +#endif + { MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_RESET_POWER_ON) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_HARD) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_WDT) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_DEEPSLEEP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_SOFT) }, +#if 0 { MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_GPIO) }, { MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) }, diff --git a/stmhal/modmachine.h b/stmhal/modmachine.h index 981728c27..042afb850 100644 --- a/stmhal/modmachine.h +++ b/stmhal/modmachine.h @@ -31,6 +31,8 @@ #include "py/nlr.h" #include "py/obj.h" +void machine_init(void); + MP_DECLARE_CONST_FUN_OBJ(machine_info_obj); MP_DECLARE_CONST_FUN_OBJ(machine_unique_id_obj); MP_DECLARE_CONST_FUN_OBJ(machine_reset_obj); -- cgit v1.2.3 From 4a9542c0c0319ac268d227ea8daf4c36ac7e870d Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 6 Sep 2016 14:20:52 +1000 Subject: docs/library/machine.WDT: Add that WDT is available on pyboard. --- docs/library/machine.WDT.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/library/machine.WDT.rst b/docs/library/machine.WDT.rst index ff534fd9b..1d79b4c4e 100644 --- a/docs/library/machine.WDT.rst +++ b/docs/library/machine.WDT.rst @@ -14,7 +14,7 @@ Example usage:: wdt = WDT(timeout=2000) # enable it with a timeout of 2s wdt.feed() -Availability of this class: WiPy. +Availability of this class: pyboard, WiPy. Constructors ------------ -- cgit v1.2.3 From b4be5a8f3499ca19bdc9ac3ef94625529141b0ff Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 6 Sep 2016 15:30:39 +1000 Subject: esp8266/modnetwork: Fix wlan.scan() method so it returns all networks. According to the Arduino ESP8266 implementation the first argument to the wifi scan callback is actually a bss_info pointer. This patch fixes the iteration over this data so the first 2 entries are no longer skipped. Fixes issue #2372. --- esp8266/modnetwork.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/esp8266/modnetwork.c b/esp8266/modnetwork.c index 7cfa3ff77..7031197fa 100644 --- a/esp8266/modnetwork.c +++ b/esp8266/modnetwork.c @@ -130,17 +130,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_status_obj, esp_status); STATIC mp_obj_t *esp_scan_list = NULL; -STATIC void esp_scan_cb(scaninfo *si, STATUS status) { +STATIC void esp_scan_cb(void *result, STATUS status) { if (esp_scan_list == NULL) { // called unexpectedly return; } - if (si->pbss && status == 0) { + if (result && status == 0) { // we need to catch any memory errors nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - struct bss_info *bs; - STAILQ_FOREACH(bs, si->pbss, next) { + for (struct bss_info *bs = result; bs; bs = STAILQ_NEXT(bs, next)) { mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL); #if 1 // struct bss_info::ssid_len is not documented in SDK API Guide, -- cgit v1.2.3 From 742d8bdbe46274401aa261881d14dee50a7618d5 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 7 Sep 2016 00:59:02 +0300 Subject: esp8266/modmachine: Map PWR_ON_RESET to vendor's REASON_DEFAULT_RST. When dealing with a board which controls chip reset with UART's DTR/RTS, we never see REASON_DEFAULT_RST (0), only REASON_EXT_SYS_RST (6). However, trying a "raw" module with with just TXD/RXD UART connection, on power up it has REASON_DEFAULT_RST as a reset reason. --- esp8266/modmachine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index df1ae0fcf..a8d2de8bb 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -260,7 +260,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) }, // reset causes - { MP_ROM_QSTR(MP_QSTR_PWR_ON_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) }, + { MP_ROM_QSTR(MP_QSTR_PWR_ON_RESET), MP_ROM_INT(REASON_DEFAULT_RST) }, { MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) }, { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(REASON_DEEP_SLEEP_AWAKE) }, { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(REASON_WDT_RST) }, -- cgit v1.2.3 From dab0f316d26f4c77c94d9e51c35d5f63ed118d3c Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Tue, 6 Sep 2016 11:20:22 +0100 Subject: docs/reference/isr_rules.rst: Two minor additions to docs for using ISR. - Refers to the technique of instantiating an object for use in an ISR by specifying it as a default argument. - Footnote detailing the fact that interrupt handlers continue to be executed at the REPL. --- docs/reference/isr_rules.rst | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/reference/isr_rules.rst b/docs/reference/isr_rules.rst index b33e4dd6f..23dcfd01f 100644 --- a/docs/reference/isr_rules.rst +++ b/docs/reference/isr_rules.rst @@ -110,6 +110,19 @@ the flag. The memory allocation occurs in the main program code when the object The MicroPython library I/O methods usually provide an option to use a pre-allocated buffer. For example ``pyb.i2c.recv()`` can accept a mutable buffer as its first argument: this enables its use in an ISR. +A means of creating an object without employing a class or globals is as follows: + +.. code:: python + + def set_volume(t, buf=bytearray(3)): + buf[0] = 0xa5 + buf[1] = t >> 4 + buf[2] = 0x5a + return buf + +The compiler instantiates the default ``buf`` argument when the function is +loaded for the first time (usually when the module it's in is imported). + Use of Python objects ~~~~~~~~~~~~~~~~~~~~~ @@ -300,3 +313,20 @@ that access to the critical variables is denied. A simple example of a mutex may but only for the duration of eight machine instructions: the benefit of this approach is that other interrupts are virtually unaffected. +Interrupts and the REPL +~~~~~~~~~~~~~~~~~~~~~~~ + +Interrupt handlers, such as those associated with timers, can continue to run +after a program terminates. This may produce unexpected results where you might +have expected the object raising the callback to have gone out of scope. For +example on the Pyboard: + +.. code:: python + + def bar(): + foo = pyb.Timer(2, freq=4, callback=lambda t: print('.', end='')) + + bar() + +This continues to run until the timer is explicitly disabled or the board is +reset with ``ctrl D``. -- cgit v1.2.3 From f3b5480be7243684e31e4631e3da49c725fa7234 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 8 Sep 2016 12:50:38 +1000 Subject: stmhal,cc3200,esp8266: Consistently use PWRON_RESET constant. machine.POWER_ON is renamed to machine.PWRON_RESET to match other reset-cause constants that all end in _RESET. The cc3200 port keeps a legacy definition of POWER_ON for backwards compatibility. --- cc3200/mods/modmachine.c | 3 ++- docs/library/machine.rst | 2 +- esp8266/modmachine.c | 2 +- stmhal/modmachine.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cc3200/mods/modmachine.c b/cc3200/mods/modmachine.c index 704defb33..410d5b944 100644 --- a/cc3200/mods/modmachine.c +++ b/cc3200/mods/modmachine.c @@ -198,7 +198,8 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_IDLE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) }, { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) }, // legacy constant + { MP_OBJ_NEW_QSTR(MP_QSTR_PWRON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) }, { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HARD_RESET) }, { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WDT_RESET) }, { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) }, diff --git a/docs/library/machine.rst b/docs/library/machine.rst index 0f361a7cb..46d8eea71 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -125,7 +125,7 @@ Constants irq wake values -.. data:: machine.POWER_ON +.. data:: machine.PWRON_RESET .. data:: machine.HARD_RESET .. data:: machine.WDT_RESET .. data:: machine.DEEPSLEEP_RESET diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index a8d2de8bb..b0b7f3a1a 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -260,7 +260,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) }, // reset causes - { MP_ROM_QSTR(MP_QSTR_PWR_ON_RESET), MP_ROM_INT(REASON_DEFAULT_RST) }, + { MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(REASON_DEFAULT_RST) }, { MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) }, { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(REASON_DEEP_SLEEP_AWAKE) }, { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(REASON_WDT_RST) }, diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c index dbeabec55..ca17eff80 100644 --- a/stmhal/modmachine.c +++ b/stmhal/modmachine.c @@ -543,7 +543,7 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) }, { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) }, #endif - { MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_RESET_POWER_ON) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PWRON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_POWER_ON) }, { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_HARD) }, { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_WDT) }, { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_DEEPSLEEP) }, -- cgit v1.2.3 From 763e04bba57c45589b75bc9210fbb8272d358c89 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 8 Sep 2016 13:06:29 +1000 Subject: tests/run-tests: Disable thread/stress_recurse.py test on Travis. It has reliability issues (cause unknown at this time). --- tests/run-tests | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run-tests b/tests/run-tests index 5e8819729..059e4e910 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -203,6 +203,7 @@ def run_tests(pyb, tests, args): skip_tests.add('thread/thread_gc1.py') # has reliability issues skip_tests.add('thread/thread_lock4.py') # has reliability issues skip_tests.add('thread/stress_heap.py') # has reliability issues + skip_tests.add('thread/stress_recurse.py') # has reliability issues if not has_complex: skip_tests.add('float/complex1.py') -- cgit v1.2.3 From 3611dcc260cef08eaa497cea4e3ca17977848b6c Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 9 Sep 2016 14:07:09 +1000 Subject: docs: Bump version to 1.8.4. --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index fbc89afc6..a737e43ef 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -99,7 +99,7 @@ copyright = '2014-2016, Damien P. George and contributors' # The short X.Y version. version = '1.8' # The full version, including alpha/beta/rc tags. -release = '1.8.3' +release = '1.8.4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -- cgit v1.2.3 From f3b19ef6347f41b073b27c7a83a12cfc1c7267b8 Mon Sep 17 00:00:00 2001 From: Antonin ENFRUN Date: Thu, 8 Sep 2016 00:02:17 +0200 Subject: py/asmthumb: Flush D-cache, and invalidate I-cache on STM32F7. Tested on a STM32F7DISCO at 216MHz. All tests generating code (inlineasm, native, viper) now pass, except pybnative/while.py, but that's because there is no LED(2). --- py/asmthumb.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/py/asmthumb.c b/py/asmthumb.c index 8341c958e..1aae3d38e 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -90,6 +90,15 @@ void asm_thumb_start_pass(asm_thumb_t *as, uint pass) { void asm_thumb_end_pass(asm_thumb_t *as) { (void)as; // could check labels are resolved... + + #if defined(MCU_SERIES_F7) + if (as->pass == ASM_THUMB_PASS_EMIT) { + // flush D-cache, so the code emited is stored in memory + SCB_CleanDCache_by_Addr((uint32_t*)as->code_base, as->code_size); + // invalidate I-cache + SCB_InvalidateICache(); + } + #endif } // all functions must go through this one to emit bytes -- cgit v1.2.3 From d89de18f4035996ba2e1f244d6c4e1e2c8f0cc98 Mon Sep 17 00:00:00 2001 From: Tom Soulanille Date: Sat, 16 Jul 2016 18:20:08 -0700 Subject: stmhal/lcd: De-assert chip select after completing SPI transmission. The LCD interface library fails to deassert the chip select of the LCD after an SPI transmission. Consequently using the SPI with other peripherals disturbs the state of the LCD. This patch changes lcd.lcd_out() to deassert CS after each transmission to the LCD. --- stmhal/lcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stmhal/lcd.c b/stmhal/lcd.c index 143ef9bbd..74a29a151 100644 --- a/stmhal/lcd.c +++ b/stmhal/lcd.c @@ -121,6 +121,8 @@ STATIC void lcd_out(pyb_lcd_obj_t *lcd, int instr_data, uint8_t i) { } lcd_delay(); HAL_SPI_Transmit(lcd->spi, &i, 1, 1000); + lcd_delay(); + lcd->pin_cs1->gpio->BSRRL = lcd->pin_cs1->pin_mask; // CS=1; disable } // write a string to the LCD at the current cursor location -- cgit v1.2.3 From 06a1194300fd65723a60bf8cc6702d60659089fa Mon Sep 17 00:00:00 2001 From: Krzysztof Blazewicz Date: Tue, 6 Sep 2016 17:56:41 +0200 Subject: stmhal/{accel,lcd}: use GPIO_{set,clear}_pin different HAL versions implement GPIO differently (BSRR vs BSRRH+BSRRL), this way both drivers are portable between different HAL's --- stmhal/accel.c | 9 ++++----- stmhal/lcd.c | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/stmhal/accel.c b/stmhal/accel.c index 34e9d8e0e..e75f1c994 100644 --- a/stmhal/accel.c +++ b/stmhal/accel.c @@ -27,8 +27,7 @@ #include #include -#include STM32_HAL_H - +#include "py/mphal.h" #include "py/nlr.h" #include "py/runtime.h" #include "pin.h" @@ -61,7 +60,7 @@ void accel_init(void) { GPIO_InitTypeDef GPIO_InitStructure; // PB5 is connected to AVDD; pull high to enable MMA accel device - MICROPY_HW_MMA_AVDD_PIN.gpio->BSRRH = MICROPY_HW_MMA_AVDD_PIN.pin_mask; // turn off AVDD + GPIO_clear_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn off AVDD GPIO_InitStructure.Pin = MICROPY_HW_MMA_AVDD_PIN.pin_mask; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_LOW; @@ -82,9 +81,9 @@ STATIC void accel_start(void) { i2c_init(&I2CHandle1); // turn off AVDD, wait 30ms, turn on AVDD, wait 30ms again - MICROPY_HW_MMA_AVDD_PIN.gpio->BSRRH = MICROPY_HW_MMA_AVDD_PIN.pin_mask; // turn off + GPIO_clear_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn off HAL_Delay(30); - MICROPY_HW_MMA_AVDD_PIN.gpio->BSRRL = MICROPY_HW_MMA_AVDD_PIN.pin_mask; // turn on + GPIO_set_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn on HAL_Delay(30); HAL_StatusTypeDef status; diff --git a/stmhal/lcd.c b/stmhal/lcd.c index 74a29a151..92f19b818 100644 --- a/stmhal/lcd.c +++ b/stmhal/lcd.c @@ -26,8 +26,8 @@ #include #include -#include STM32_HAL_H +#include "py/mphal.h" #include "py/nlr.h" #include "py/runtime.h" @@ -113,16 +113,16 @@ STATIC void lcd_delay(void) { STATIC void lcd_out(pyb_lcd_obj_t *lcd, int instr_data, uint8_t i) { lcd_delay(); - lcd->pin_cs1->gpio->BSRRH = lcd->pin_cs1->pin_mask; // CS=0; enable + GPIO_clear_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); // CS=0; enable if (instr_data == LCD_INSTR) { - lcd->pin_a0->gpio->BSRRH = lcd->pin_a0->pin_mask; // A0=0; select instr reg + GPIO_clear_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); // A0=0; select instr reg } else { - lcd->pin_a0->gpio->BSRRL = lcd->pin_a0->pin_mask; // A0=1; select data reg + GPIO_set_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); // A0=1; select data reg } lcd_delay(); HAL_SPI_Transmit(lcd->spi, &i, 1, 1000); lcd_delay(); - lcd->pin_cs1->gpio->BSRRL = lcd->pin_cs1->pin_mask; // CS=1; disable + GPIO_set_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); // CS=1; disable } // write a string to the LCD at the current cursor location @@ -262,10 +262,10 @@ STATIC mp_obj_t pyb_lcd_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp spi_init(lcd->spi, false); // set the pins to default values - lcd->pin_cs1->gpio->BSRRL = lcd->pin_cs1->pin_mask; - lcd->pin_rst->gpio->BSRRL = lcd->pin_rst->pin_mask; - lcd->pin_a0->gpio->BSRRL = lcd->pin_a0->pin_mask; - lcd->pin_bl->gpio->BSRRH = lcd->pin_bl->pin_mask; + GPIO_set_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); + GPIO_set_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); + GPIO_set_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); + GPIO_clear_pin(lcd->pin_bl->gpio, lcd->pin_bl->pin_mask); // init the pins to be push/pull outputs GPIO_InitTypeDef GPIO_InitStructure; @@ -287,9 +287,9 @@ STATIC mp_obj_t pyb_lcd_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp // init the LCD HAL_Delay(1); // wait a bit - lcd->pin_rst->gpio->BSRRH = lcd->pin_rst->pin_mask; // RST=0; reset + GPIO_clear_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); // RST=0; reset HAL_Delay(1); // wait for reset; 2us min - lcd->pin_rst->gpio->BSRRL = lcd->pin_rst->pin_mask; // RST=1; enable + GPIO_set_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); // RST=1; enable HAL_Delay(1); // wait for reset; 2us min lcd_out(lcd, LCD_INSTR, 0xa0); // ADC select, normal lcd_out(lcd, LCD_INSTR, 0xc0); // common output mode select, normal (this flips the display) @@ -372,9 +372,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_lcd_contrast_obj, pyb_lcd_contrast); STATIC mp_obj_t pyb_lcd_light(mp_obj_t self_in, mp_obj_t value) { pyb_lcd_obj_t *self = self_in; if (mp_obj_is_true(value)) { - self->pin_bl->gpio->BSRRL = self->pin_bl->pin_mask; // set pin high to turn backlight on + GPIO_set_pin(self->pin_bl->gpio, self->pin_bl->pin_mask); // set pin high to turn backlight on } else { - self->pin_bl->gpio->BSRRH = self->pin_bl->pin_mask; // set pin low to turn backlight off + GPIO_clear_pin(self->pin_bl->gpio, self->pin_bl->pin_mask); // set pin low to turn backlight off } return mp_const_none; } -- cgit v1.2.3 From 1ba516f4758508f2657d1c68d31055c3c8e21b28 Mon Sep 17 00:00:00 2001 From: Krzysztof Blazewicz Date: Tue, 6 Sep 2016 17:22:43 +0200 Subject: stmhal/extint: Force 0 to 1 transition on swint(). If a user tries to call `swint()` while interrupt is disabled the flag in SWIER is set but the interrupt is not triggered and therefore the SWIER bit is not cleared. When the interrupt is again enabled the next call to `swint()` won't trigger the IRQ because a 0 to 1 transition will not occur. --- stmhal/extint.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/stmhal/extint.c b/stmhal/extint.c index c0471719b..02b06fde5 100644 --- a/stmhal/extint.c +++ b/stmhal/extint.c @@ -251,10 +251,13 @@ void extint_swint(uint line) { if (line >= EXTI_NUM_VECTORS) { return; } + // we need 0 to 1 transition to trigger the interrupt #if defined(MCU_SERIES_L4) - EXTI->SWIER1 = (1 << line); + EXTI->SWIER1 &= ~(1 << line); + EXTI->SWIER1 |= (1 << line); #else - EXTI->SWIER = (1 << line); + EXTI->SWIER &= ~(1 << line); + EXTI->SWIER |= (1 << line); #endif } -- cgit v1.2.3 From 2f02960607b75e74a757ded1e2472a5fb8585d4f Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 9 Sep 2016 19:33:50 +1000 Subject: tests/pyb: Add test for ExtInt when doing swint while disabled. --- tests/pyb/extint.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/pyb/extint.py b/tests/pyb/extint.py index 47d84c8b5..a8ba484b1 100644 --- a/tests/pyb/extint.py +++ b/tests/pyb/extint.py @@ -1,8 +1,17 @@ import pyb +# test basic functionality ext = pyb.ExtInt('X1', pyb.ExtInt.IRQ_RISING, pyb.Pin.PULL_DOWN, lambda l:print('line:', l)) ext.disable() ext.enable() print(ext.line()) ext.swint() + +# test swint while disabled, then again after re-enabled +ext.disable() +ext.swint() +ext.enable() +ext.swint() + +# disable now that the test is finished ext.disable() -- cgit v1.2.3 From b236b1974bf7da5ee833e4752d81103a348a7421 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 9 Sep 2016 19:37:45 +1000 Subject: tests/pyb: Update exp file for previously updated extint test. --- tests/pyb/extint.py.exp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/pyb/extint.py.exp b/tests/pyb/extint.py.exp index 28019d75c..daed01c7f 100644 --- a/tests/pyb/extint.py.exp +++ b/tests/pyb/extint.py.exp @@ -1,2 +1,3 @@ 0 line: 0 +line: 0 -- cgit v1.2.3 From a50b26e4b00ed094aa1ac74eac2fc2d8eb9ea1ed Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Thu, 8 Sep 2016 20:34:34 +1200 Subject: py/makeqstrdefs.py: Use python 2.6 syntax for set creation. py/makeqstrdefs.py declares that it works with python 2.6 however the syntax used to initialise of a set with values was only added in python 2.7. This leads to build failures when the host system doesn't have python 2.7 or newer. Instead of using the new syntax pass a list of initial values through set() to achieve the same result. This should work for python versions from at least 2.6 onwards. Helped-by: Thomas Petazzoni Signed-off-by: Chris Packham --- py/makeqstrdefs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py index 69aaefb3e..92a19c392 100644 --- a/py/makeqstrdefs.py +++ b/py/makeqstrdefs.py @@ -11,7 +11,7 @@ import os # Blacklist of qstrings that are specially handled in further # processing and should be ignored -QSTRING_BLACK_LIST = {'NULL', 'number_of', } +QSTRING_BLACK_LIST = set(['NULL', 'number_of']) def write_out(fname, output): -- cgit v1.2.3 From d14d4cdb8bc55b5937014f7a63932fdc1c50fdb0 Mon Sep 17 00:00:00 2001 From: stijn Date: Fri, 9 Sep 2016 14:26:27 +0200 Subject: windows: Enable MICROPY_PY_UERRNO This also fixes the test failure for vfs_fat_ramdisk.py --- windows/mpconfigport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/windows/mpconfigport.h b/windows/mpconfigport.h index ccf8768bf..da49bc0dc 100644 --- a/windows/mpconfigport.h +++ b/windows/mpconfigport.h @@ -82,6 +82,7 @@ #define MICROPY_STACKLESS (0) #define MICROPY_STACKLESS_STRICT (0) +#define MICROPY_PY_UERRNO (1) #define MICROPY_PY_UCTYPES (1) #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_UJSON (1) -- cgit v1.2.3 From dd0e6ddfeb8fe07eb6164f8ca51dc83da355fb3e Mon Sep 17 00:00:00 2001 From: stijn Date: Fri, 9 Sep 2016 16:14:16 +0200 Subject: travis: Abandon mingw32 in favour of mingw-w64 This is actually long overdue: the README in the windows directory has been updated once to indicate mingw32 is abandoned and not ok to use with uPy, but we forgot travis builds were still using it. As a bonus the travis build will succeed again since moduerrno.c now compiles. (see https://github.com/micropython/micropython/pull/2399) --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99d8b8f0f..8f164598e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_script: - sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded - sudo dpkg --add-architecture i386 - sudo apt-get update -qq || true - - sudo apt-get install -y python3 gcc-multilib pkg-config libffi-dev libffi-dev:i386 qemu-system mingw32 + - sudo apt-get install -y python3 gcc-multilib pkg-config libffi-dev libffi-dev:i386 qemu-system gcc-mingw-w64 - sudo apt-get install -y --force-yes gcc-arm-none-eabi # For teensy build - sudo apt-get install realpath @@ -36,7 +36,7 @@ script: - make -C teensy - make -C cc3200 BTARGET=application BTYPE=release - make -C cc3200 BTARGET=bootloader BTYPE=release - - make -C windows CROSS_COMPILE=i586-mingw32msvc- + - make -C windows CROSS_COMPILE=i686-w64-mingw32- # run tests without coverage info #- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests) -- cgit v1.2.3 From 081c0648ecf3f291cb8669d74f4f59ea0191e34e Mon Sep 17 00:00:00 2001 From: Renato Aguiar Date: Thu, 8 Sep 2016 15:13:58 -0700 Subject: unix: Fix build for when MICROPY_PY_SOCKET=0. --- unix/moduselect.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/unix/moduselect.c b/unix/moduselect.c index 38f8d11ed..e670c3814 100644 --- a/unix/moduselect.c +++ b/unix/moduselect.c @@ -40,7 +40,9 @@ #include "py/mphal.h" #include "fdfile.h" +#if MICROPY_PY_SOCKET extern const mp_obj_type_t mp_type_socket; +#endif // Flags for poll() #define FLAG_ONESHOT (1) @@ -57,7 +59,11 @@ typedef struct _mp_obj_poll_t { STATIC int get_fd(mp_obj_t fdlike) { int fd; // Shortcut for fdfile compatible types - if (MP_OBJ_IS_TYPE(fdlike, &mp_type_fileio) || MP_OBJ_IS_TYPE(fdlike, &mp_type_socket)) { + if (MP_OBJ_IS_TYPE(fdlike, &mp_type_fileio) + #if MICROPY_PY_SOCKET + || MP_OBJ_IS_TYPE(fdlike, &mp_type_socket) + #endif + ) { mp_obj_fdfile_t *fdfile = MP_OBJ_TO_PTR(fdlike); fd = fdfile->fd; } else { -- cgit v1.2.3 From 0fd3d8d19fe63e1ddbe6bcf86efef53406c21844 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 14 Sep 2016 13:00:27 +1000 Subject: stmhal/boards: Add pllvalues.py script to compute PLL values for sysclk. The algorithm here should mirror that in the machine.freq() function. --- stmhal/boards/pllvalues.py | 115 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 stmhal/boards/pllvalues.py diff --git a/stmhal/boards/pllvalues.py b/stmhal/boards/pllvalues.py new file mode 100644 index 000000000..183313f30 --- /dev/null +++ b/stmhal/boards/pllvalues.py @@ -0,0 +1,115 @@ +""" +This is an auxiliary script that is used to compute valid PLL values to set +the CPU frequency to a given value. The algorithm here appears as C code +for the machine.freq() function. +""" + +def close_int(x): + return abs(x - round(x)) < 0.01 + +# original version that requires N/M to be an integer (for simplicity) +def compute_pll(hse, sys): + for P in (2, 4, 6, 8): # allowed values of P + Q = sys * P / 48 + NbyM = sys * P / hse + # N/M and Q must be integers + if not (close_int(NbyM) and close_int(Q)): + continue + # VCO_OUT must be between 192MHz and 432MHz + if not (192 <= hse * NbyM <= 432): + continue + # compute M + M = int(192 // NbyM) + while hse > 2 * M or NbyM * M < 192: + M += 1 + # VCO_IN must be between 1MHz and 2MHz (2MHz recommended) + if not (M <= hse): + continue + # compute N + N = NbyM * M + # N and Q are restricted + if not (192 <= N <= 432 and 2 <= Q <= 15): + continue + # found valid values + assert NbyM == N // M + return (M, N, P, Q) + # no valid values found + return None + +# improved version that doesn't require N/M to be an integer +def compute_pll2(hse, sys): + for P in (2, 4, 6, 8): # allowed values of P + Q = sys * P / 48 + # Q must be an integer in a set range + if not (close_int(Q) and 2 <= Q <= 15): + continue + NbyM = sys * P / hse + # VCO_OUT must be between 192MHz and 432MHz + if not (192 <= hse * NbyM <= 432): + continue + # compute M + M = 192 // NbyM # starting value + while hse > 2 * M or NbyM * M < 192 or not close_int(NbyM * M): + M += 1 + # VCO_IN must be between 1MHz and 2MHz (2MHz recommended) + if not (M <= hse): + continue + # compute N + N = NbyM * M + # N must be an integer + if not close_int(N): + continue + # N is restricted + if not (192 <= N <= 432): + continue + # found valid values + return (M, N, P, Q) + # no valid values found + return None + +def verify_and_print_pll(hse, sys, pll): + M, N, P, Q = pll + + # compute derived quantities + vco_in = hse / M + vco_out = hse * N / M + pllck = hse / M * N / P + pll48ck = hse / M * N / Q + + # verify ints + assert close_int(M) + assert close_int(N) + assert close_int(P) + assert close_int(Q) + + # verify range + assert 2 <= M <= 63 + assert 192 <= N <= 432 + assert P in (2, 4, 6, 8) + assert 2 <= Q <= 15 + assert 1 <= vco_in <= 2 + assert 192 <= vco_out <= 432 + + # print out values + print(out_format % (sys, M, N, P, Q, vco_in, vco_out, pllck, pll48ck)) + +def main(): + global out_format + import sys + if len(sys.argv) != 2: + print("usage: pllvalues.py ") + sys.exit(1) + hse_value = int(sys.argv[1]) + print("HSE =", hse_value, "MHz") + print("sys : M N P Q : VCO_IN VCO_OUT PLLCK PLL48CK") + out_format = "%3u : %2u %.1f %.2f %.2f : %5.2f %6.2f %6.2f %6.2f" + n_valid = 0 + for sysclk in range(1, 217): + pll = compute_pll2(hse_value, sysclk) + if pll is not None: + n_valid += 1 + verify_and_print_pll(hse_value, sysclk, pll) + print("found %u valid configurations" % n_valid) + +if __name__ == "__main__": + main() -- cgit v1.2.3 From 3fea1f014c949a1268baad175b767177552e4b00 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 16 Sep 2016 00:59:48 +0300 Subject: unix/modjni: Implement subscription for object arrays. --- unix/modjni.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/unix/modjni.c b/unix/modjni.c index 20804e5a5..789b3139a 100644 --- a/unix/modjni.c +++ b/unix/modjni.c @@ -65,6 +65,7 @@ STATIC const mp_obj_type_t jmethod_type; STATIC mp_obj_t new_jobject(jobject jo); STATIC mp_obj_t new_jclass(jclass jc); STATIC mp_obj_t call_method(jobject obj, const char *name, jarray methods, bool is_constr, mp_uint_t n_args, const mp_obj_t *args); +STATIC bool py2jvalue(const char **jtypesig, mp_obj_t arg, jvalue *out); typedef struct _mp_obj_jclass_t { mp_obj_base_t base; @@ -244,11 +245,36 @@ STATIC void get_jclass_name(jobject obj, char *buf) { STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_jobject_t *self = self_in; + mp_uint_t idx = mp_obj_get_int(index); + char class_name[64]; + get_jclass_name(self->obj, class_name); + //printf("class: %s\n", class_name); + + if (class_name[0] == '[') { + if (class_name[1] == 'L' || class_name[1] == '[') { + if (value == MP_OBJ_NULL) { + // delete + assert(0); + } else if (value == MP_OBJ_SENTINEL) { + // load + jobject el = JJ(GetObjectArrayElement, self->obj, idx); + return new_jobject(el); + } else { + // store + jvalue jval; + const char *t = class_name + 1; + py2jvalue(&t, value, &jval); + JJ(SetObjectArrayElement, self->obj, idx, jval.l); + return mp_const_none; + } + } + mp_not_implemented(""); + } + if (!JJ(IsInstanceOf, self->obj, List_class)) { return MP_OBJ_NULL; } - mp_uint_t idx = mp_obj_get_int(index); if (value == MP_OBJ_NULL) { // delete -- cgit v1.2.3 From f84b3416187c8144fd92e52d97a655a133d725b2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 16 Sep 2016 12:30:09 +1000 Subject: py/objnone: Remove unnecessary handling of MP_UNARY_OP_BOOL. bool(None) has a fast path in mp_obj_is_true so doesn't need to be handled in none_unary_op. The only caveat is that subclassing may bypass the mp_obj_is_true function, but actually you aren't allowed to subclass classes that have singleton instances like NoneType (see https://mail.python.org/pipermail/python-dev/2002-March/020822.html for reference on this point). --- py/objnone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/objnone.c b/py/objnone.c index 69eab03fe..74c02e4d2 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -46,7 +46,7 @@ STATIC void none_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ STATIC mp_obj_t none_unary_op(mp_uint_t op, mp_obj_t o_in) { (void)o_in; switch (op) { - case MP_UNARY_OP_BOOL: return mp_const_false; + // MP_UNARY_OP_BOOL is handled by a fast-path in mp_obj_is_true case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT((mp_uint_t)o_in); default: return MP_OBJ_NULL; // op not supported } -- cgit v1.2.3 From 67a481360106e3dd45334b81471629defd4a9380 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 16 Sep 2016 12:49:15 +1000 Subject: tests/extmod/urandom: Add urandom tests for error cases. --- tests/extmod/urandom_basic.py | 6 ++++++ tests/extmod/urandom_extra.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/tests/extmod/urandom_basic.py b/tests/extmod/urandom_basic.py index 7e4d8bf34..bf00035bd 100644 --- a/tests/extmod/urandom_basic.py +++ b/tests/extmod/urandom_basic.py @@ -17,3 +17,9 @@ random.seed(1) r = random.getrandbits(16) random.seed(1) print(random.getrandbits(16) == r) + +# check that it throws an error for zero bits +try: + random.getrandbits(0) +except ValueError: + print('ValueError') diff --git a/tests/extmod/urandom_extra.py b/tests/extmod/urandom_extra.py index a9ecd881d..004fb10cc 100644 --- a/tests/extmod/urandom_extra.py +++ b/tests/extmod/urandom_extra.py @@ -16,6 +16,31 @@ for i in range(50): assert 2 <= random.randrange(2, 6) < 6 assert -2 <= random.randrange(-2, 2) < 2 assert random.randrange(1, 9, 2) in (1, 3, 5, 7) + assert random.randrange(2, 1, -1) in (1, 2) + +# empty range +try: + random.randrange(0) +except ValueError: + print('ValueError') + +# empty range +try: + random.randrange(2, 1) +except ValueError: + print('ValueError') + +# zero step +try: + random.randrange(2, 1, 0) +except ValueError: + print('ValueError') + +# empty range +try: + random.randrange(2, 1, 1) +except ValueError: + print('ValueError') print('randint') for i in range(50): @@ -23,11 +48,23 @@ for i in range(50): assert 2 <= random.randint(2, 6) <= 6 assert -2 <= random.randint(-2, 2) <= 2 +# empty range +try: + random.randint(2, 1) +except ValueError: + print('ValueError') + print('choice') lst = [1, 2, 5, 6] for i in range(50): assert random.choice(lst) in lst +# empty sequence +try: + random.choice([]) +except IndexError: + print('IndexError') + print('random') for i in range(50): assert 0 <= random.random() < 1 -- cgit v1.2.3 From 2b7c4a18784d93d2daee0cd34a7751c6fe29088d Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 16 Sep 2016 15:33:51 +1000 Subject: tests/basics: Add errno1 test, to check basics of uerrno module. --- tests/basics/errno1.py | 15 +++++++++++++++ tests/basics/errno1.py.exp | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 tests/basics/errno1.py create mode 100644 tests/basics/errno1.py.exp diff --git a/tests/basics/errno1.py b/tests/basics/errno1.py new file mode 100644 index 000000000..680104481 --- /dev/null +++ b/tests/basics/errno1.py @@ -0,0 +1,15 @@ +# test errno's and uerrno module + +try: + import uerrno +except ImportError: + print("SKIP") + import sys + sys.exit() + +# check that constants exist and are integers +print(type(uerrno.EIO)) + +# check that errors are rendered in a nice way +msg = str(OSError(uerrno.EIO)) +print(msg[:7], msg[-5:]) diff --git a/tests/basics/errno1.py.exp b/tests/basics/errno1.py.exp new file mode 100644 index 000000000..e60fdf049 --- /dev/null +++ b/tests/basics/errno1.py.exp @@ -0,0 +1,2 @@ + +[Errno ] EIO -- cgit v1.2.3 From b9672bcbe8dd29b61326af8eb026df4d10a8f0ce Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 16 Sep 2016 23:31:02 +1000 Subject: tests/extmod: Add test for machine.time_pulse_us(). --- tests/extmod/machine_pulse.py | 54 +++++++++++++++++++++++++++++++++++++++ tests/extmod/machine_pulse.py.exp | 9 +++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/extmod/machine_pulse.py create mode 100644 tests/extmod/machine_pulse.py.exp diff --git a/tests/extmod/machine_pulse.py b/tests/extmod/machine_pulse.py new file mode 100644 index 000000000..b6e126435 --- /dev/null +++ b/tests/extmod/machine_pulse.py @@ -0,0 +1,54 @@ +try: + import umachine as machine +except ImportError: + import machine +try: + machine.PinBase + machine.time_pulse_us +except AttributeError: + print("SKIP") + import sys + sys.exit() + + +class ConstPin(machine.PinBase): + + def __init__(self, value): + self.v = value + + def value(self, v=None): + if v is None: + return self.v + else: + self.v = v + + +class TogglePin(machine.PinBase): + + def __init__(self): + self.v = 0 + + def value(self, v=None): + if v is None: + self.v = 1 - self.v + print("value:", self.v) + return self.v + + +p = TogglePin() + +t = machine.time_pulse_us(p, 1) +print(type(t)) +t = machine.time_pulse_us(p, 0) +print(type(t)) + +p = ConstPin(0) +try: + machine.time_pulse_us(p, 1, 10) +except OSError: + print("OSError") + +try: + machine.time_pulse_us(p, 0, 10) +except OSError: + print("OSError") diff --git a/tests/extmod/machine_pulse.py.exp b/tests/extmod/machine_pulse.py.exp new file mode 100644 index 000000000..f9a474218 --- /dev/null +++ b/tests/extmod/machine_pulse.py.exp @@ -0,0 +1,9 @@ +value: 1 +value: 0 + +value: 1 +value: 0 +value: 1 + +OSError +OSError -- cgit v1.2.3 From ee324c501eee738bedf917123abae4eb613268f8 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 17 Sep 2016 16:14:02 +0300 Subject: unix/modjni: Add array() top-level function to create Java array. Takes element primitive type encoded as a char per standard JNI encoding, and array size. TODO: Support object arrays. --- unix/modjni.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/unix/modjni.c b/unix/modjni.c index 789b3139a..5d1de17f5 100644 --- a/unix/modjni.c +++ b/unix/modjni.c @@ -654,6 +654,46 @@ STATIC mp_obj_t mod_jni_cls(mp_obj_t cls_name_in) { } MP_DEFINE_CONST_FUN_OBJ_1(mod_jni_cls_obj, mod_jni_cls); +STATIC mp_obj_t mod_jni_array(mp_obj_t type_in, mp_obj_t size_in) { + const char *type = mp_obj_str_get_str(type_in); + mp_int_t size = mp_obj_get_int(size_in); + if (!env) { + create_jvm(); + } + + jobject res = NULL; + switch (*type) { + case 'Z': + res = JJ(NewBooleanArray, size); + break; + case 'B': + res = JJ(NewByteArray, size); + break; + case 'C': + res = JJ(NewCharArray, size); + break; + case 'S': + res = JJ(NewShortArray, size); + break; + case 'I': + res = JJ(NewIntArray, size); + break; + case 'J': + res = JJ(NewLongArray, size); + break; + case 'F': + res = JJ(NewFloatArray, size); + break; + case 'D': + res = JJ(NewDoubleArray, size); + break; + } + + return new_jobject(res); +} +MP_DEFINE_CONST_FUN_OBJ_2(mod_jni_array_obj, mod_jni_array); + + STATIC mp_obj_t mod_jni_env() { return mp_obj_new_int((mp_int_t)env); } @@ -662,6 +702,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(mod_jni_env_obj, mod_jni_env); STATIC const mp_map_elem_t mp_module_jni_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_jni) }, { MP_OBJ_NEW_QSTR(MP_QSTR_cls), (mp_obj_t)&mod_jni_cls_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&mod_jni_array_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_env), (mp_obj_t)&mod_jni_env_obj }, }; -- cgit v1.2.3 From 8ae885a0c6dc67aca0adc880b7b61bb3795a7682 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 17 Sep 2016 20:24:28 +0300 Subject: esp8266/Makefile: Rename SCRIPTDIR to FROZEN_DIR for consistency. With FROZEN_MPY_DIR. --- esp8266/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/esp8266/Makefile b/esp8266/Makefile index 433b41ecf..e13082e18 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -14,7 +14,7 @@ MPY_CROSS = ../mpy-cross/mpy-cross MPY_TOOL = ../tools/mpy-tool.py MAKE_FROZEN = ../tools/make-frozen.py -SCRIPTDIR = scripts +FROZEN_DIR = scripts FROZEN_MPY_DIR = modules PORT ?= /dev/ttyACM0 BAUD ?= 115200 @@ -164,16 +164,16 @@ CONFVARS_FILE = $(BUILD)/confvars ifeq ($(wildcard $(CONFVARS_FILE)),) $(shell $(MKDIR) -p $(BUILD)) -$(shell echo $(SCRIPTDIR) $(UART_OS) > $(CONFVARS_FILE)) -else ifneq ($(shell cat $(CONFVARS_FILE)), $(SCRIPTDIR) $(UART_OS)) -$(shell echo $(SCRIPTDIR) $(UART_OS) > $(CONFVARS_FILE)) +$(shell echo $(FROZEN_DIR) $(UART_OS) > $(CONFVARS_FILE)) +else ifneq ($(shell cat $(CONFVARS_FILE)), $(FROZEN_DIR) $(UART_OS)) +$(shell echo $(FROZEN_DIR) $(UART_OS) > $(CONFVARS_FILE)) endif $(BUILD)/uart.o: $(CONFVARS_FILE) -$(BUILD)/frozen.c: $(wildcard $(SCRIPTDIR)/*) $(CONFVARS_FILE) +$(BUILD)/frozen.c: $(wildcard $(FROZEN_DIR)/*) $(CONFVARS_FILE) $(ECHO) "Generating $@" - $(Q)$(MAKE_FROZEN) $(SCRIPTDIR) > $@ + $(Q)$(MAKE_FROZEN) $(FROZEN_DIR) > $@ # to build .mpy files from .py files $(BUILD)/$(FROZEN_MPY_DIR)/%.mpy: $(FROZEN_MPY_DIR)/%.py -- cgit v1.2.3 From f28efa19713977a61395b19fec1fe501aeee4c0e Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 17 Sep 2016 20:57:43 +0300 Subject: py: Move frozen modules rules from esp8266 port for reuse across ports. A port now just needs to define FROZEN_DIR var and add $(BUILD)/frozen.c to SRC_C to support frozen modules. --- esp8266/Makefile | 4 +--- py/mkenv.mk | 2 ++ py/mkrules.mk | 6 ++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/esp8266/Makefile b/esp8266/Makefile index e13082e18..26b5e8626 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -171,9 +171,7 @@ endif $(BUILD)/uart.o: $(CONFVARS_FILE) -$(BUILD)/frozen.c: $(wildcard $(FROZEN_DIR)/*) $(CONFVARS_FILE) - $(ECHO) "Generating $@" - $(Q)$(MAKE_FROZEN) $(FROZEN_DIR) > $@ +FROZEN_EXTRA_DEPS = $(CONFVARS_FILE) # to build .mpy files from .py files $(BUILD)/$(FROZEN_MPY_DIR)/%.mpy: $(FROZEN_MPY_DIR)/%.py diff --git a/py/mkenv.mk b/py/mkenv.mk index b7f8c2aff..e7262907c 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -58,6 +58,8 @@ CXX += -m32 LD += -m32 endif +MAKE_FROZEN = ../tools/make-frozen.py + all: .PHONY: all diff --git a/py/mkrules.mk b/py/mkrules.mk index a3a408dc8..26e4aeab3 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -100,6 +100,12 @@ $(OBJ_DIRS): $(HEADER_BUILD): $(MKDIR) -p $@ +ifneq ($(FROZEN_DIR),) +$(BUILD)/frozen.c: $(wildcard $(FROZEN_DIR)/*) $(HEADER_BUILD) $(FROZEN_EXTRA_DEPS) + $(ECHO) "Generating $@" + $(Q)$(MAKE_FROZEN) $(FROZEN_DIR) > $@ +endif + ifneq ($(PROG),) # Build a standalone executable (unix does this) -- cgit v1.2.3 From d08c9d342fe864679bab04891f4b8907a4c659d0 Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Sat, 17 Sep 2016 12:55:11 -0700 Subject: Updated FROZEN_DIR support as per f28efa19713977a61395b19fec1fe501aeee4c0e --- teensy/Makefile | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/teensy/Makefile b/teensy/Makefile index 0ab07121c..5eb871661 100644 --- a/teensy/Makefile +++ b/teensy/Makefile @@ -154,24 +154,15 @@ endif # USE_MEMZIP ifeq ($(USE_FROZEN),1) -CFLAGS += -DMICROPY_MODULE_FROZEN_STR - -SRC_C += \ - lexerfrozen.c - -OBJ += $(BUILD)/frozen-files.o - -MAKE_FROZEN = ../tools/make-frozen.py ifeq ($(FROZEN_DIR),) FROZEN_DIR = memzip_files endif -$(BUILD)/frozen-files.o: $(BUILD)/frozen-files.c - $(call compile_c) +CFLAGS += -DMICROPY_MODULE_FROZEN_STR -$(BUILD)/frozen-files.c: $(shell find ${FROZEN_DIR} -type f) - @$(ECHO) "Creating $@" - $(Q)$(PYTHON) $(MAKE_FROZEN) $(FROZEN_DIR) > $@ +SRC_C += \ + lexerfrozen.c \ + $(BUILD)/frozen.c endif # USE_FROZEN -- cgit v1.2.3 From 5bf1b4e9d9d563887d10c5ee9dceef9567679819 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 18 Sep 2016 13:37:40 +0300 Subject: unix/modjni: array(): Support creation of object arrays. --- unix/modjni.c | 64 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/unix/modjni.c b/unix/modjni.c index 5d1de17f5..c06e68eaa 100644 --- a/unix/modjni.c +++ b/unix/modjni.c @@ -655,38 +655,46 @@ STATIC mp_obj_t mod_jni_cls(mp_obj_t cls_name_in) { MP_DEFINE_CONST_FUN_OBJ_1(mod_jni_cls_obj, mod_jni_cls); STATIC mp_obj_t mod_jni_array(mp_obj_t type_in, mp_obj_t size_in) { - const char *type = mp_obj_str_get_str(type_in); - mp_int_t size = mp_obj_get_int(size_in); if (!env) { create_jvm(); } - + mp_int_t size = mp_obj_get_int(size_in); jobject res = NULL; - switch (*type) { - case 'Z': - res = JJ(NewBooleanArray, size); - break; - case 'B': - res = JJ(NewByteArray, size); - break; - case 'C': - res = JJ(NewCharArray, size); - break; - case 'S': - res = JJ(NewShortArray, size); - break; - case 'I': - res = JJ(NewIntArray, size); - break; - case 'J': - res = JJ(NewLongArray, size); - break; - case 'F': - res = JJ(NewFloatArray, size); - break; - case 'D': - res = JJ(NewDoubleArray, size); - break; + + if (MP_OBJ_IS_TYPE(type_in, &jclass_type)) { + + mp_obj_jclass_t *jcls = type_in; + res = JJ(NewObjectArray, size, jcls->cls, NULL); + + } else if (MP_OBJ_IS_STR(type_in)) { + const char *type = mp_obj_str_get_str(type_in); + switch (*type) { + case 'Z': + res = JJ(NewBooleanArray, size); + break; + case 'B': + res = JJ(NewByteArray, size); + break; + case 'C': + res = JJ(NewCharArray, size); + break; + case 'S': + res = JJ(NewShortArray, size); + break; + case 'I': + res = JJ(NewIntArray, size); + break; + case 'J': + res = JJ(NewLongArray, size); + break; + case 'F': + res = JJ(NewFloatArray, size); + break; + case 'D': + res = JJ(NewDoubleArray, size); + break; + } + } return new_jobject(res); -- cgit v1.2.3 From a2391b5a74ff771e2bfc7529aed2f7717309c448 Mon Sep 17 00:00:00 2001 From: juhasch Date: Mon, 22 Aug 2016 20:59:31 +0200 Subject: Small WiPy doc fixes --- docs/wipy/quickref.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst index 3ce7e0132..ac7eec132 100644 --- a/docs/wipy/quickref.rst +++ b/docs/wipy/quickref.rst @@ -51,11 +51,10 @@ See :ref:`machine.Timer ` and :ref:`machine.Pin `. : tim = Timer(0, mode=Timer.PERIODIC) tim_a = tim.channel(Timer.A, freq=1000) - tim_a.time() # get the value in microseconds tim_a.freq(5) # 5 Hz p_out = Pin('GP2', mode=Pin.OUT) - tim_a.irq(handler=lambda t: p_out.toggle()) + tim_a.irq(trigger=Timer.TIMEOUT, handler=lambda t: p_out.toggle()) PWM (pulse width modulation) ---------------------------- @@ -135,10 +134,9 @@ Real time clock (RTC) See :ref:`machine.RTC ` :: - import machine from machine import RTC - rtc = machine.RTC() # init with default time and date + rtc = RTC() # init with default time and date rtc = RTC(datetime=(2015, 8, 29, 9, 0, 0, 0, None)) # init with a specific time and date print(rtc.now()) -- cgit v1.2.3 From 4ab3eef8d77c436e1ba27d6690cb9b505dd1c8ad Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 18 Sep 2016 21:41:21 +0300 Subject: docs/library/pyb.SPI: init(): Describe "bits" argument. Based on https://github.com/micropython/micropython/pull/2210 . --- docs/library/pyb.SPI.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/library/pyb.SPI.rst b/docs/library/pyb.SPI.rst index 54ecc65b6..fd110be19 100644 --- a/docs/library/pyb.SPI.rst +++ b/docs/library/pyb.SPI.rst @@ -68,6 +68,7 @@ Methods - ``polarity`` can be 0 or 1, and is the level the idle clock line sits at. - ``phase`` can be 0 or 1 to sample data on the first or second clock edge respectively. + - ``bits`` can be 8 or 16, and is the number of bits in each transferred word. - ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``. - ``crc`` can be None for no CRC, or a polynomial specifier. -- cgit v1.2.3 From 3fe047f08f12ac922e5486284a2f2254670cd9a9 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 18 Sep 2016 23:01:58 +0300 Subject: esp8266/ets_alt_task: ets_post: Should return 0 on success, !0 - failure. --- esp8266/ets_alt_task.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp8266/ets_alt_task.c b/esp8266/ets_alt_task.c index 62872affb..ef1d8aaed 100644 --- a/esp8266/ets_alt_task.c +++ b/esp8266/ets_alt_task.c @@ -87,7 +87,7 @@ bool ets_post(uint8 prio, os_signal_t sig, os_param_t param) { if (emu_tasks[id].i_put == -1) { // queue is full printf("ets_post: task %d queue full\n", prio); - return false; + return 1; } q = &q[emu_tasks[id].i_put++]; q->sig = sig; @@ -104,7 +104,7 @@ bool ets_post(uint8 prio, os_signal_t sig, os_param_t param) { ets_intr_unlock(); - return true; + return 0; #endif } -- cgit v1.2.3 From 4b3f1d712b845a44a0d2680197cfb6c3fe4478bd Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 19 Sep 2016 00:23:38 +0300 Subject: esp8266/esp_mphal: Add tentative change to mp_hal_stdin_rx_chr() to wait IRQ. Instead of busy-looping waiting for UART input. Not enabled by default, needs more testing. --- esp8266/esp_mphal.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/esp8266/esp_mphal.c b/esp8266/esp_mphal.c index dc6944fd4..7c9590ab6 100644 --- a/esp8266/esp_mphal.c +++ b/esp8266/esp_mphal.c @@ -60,7 +60,14 @@ int mp_hal_stdin_rx_chr(void) { if (c != -1) { return c; } + #if 0 + // Idles CPU but need more testing before enabling + if (!ets_loop_iter()) { + asm("waiti 0"); + } + #else mp_hal_delay_us(1); + #endif } } -- cgit v1.2.3 From a5624bf3818c573611b2b7bfc755e27de97f64e4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 18 Sep 2016 23:59:47 +1000 Subject: py: Combine 3 comprehension emit functions (list/dict/set) into 1. The 3 kinds of comprehensions are similar enough that merging their emit functions reduces code size. Decreases in code size in bytes are: bare-arm:24, minimal:96, unix(NDEBUG,x86-64):328, stmhal:80, esp8266:76. --- py/compile.c | 12 +++-------- py/emit.h | 8 ++----- py/emitbc.c | 37 +++++++++++++++---------------- py/emitnative.c | 67 ++++++++++++++++++++++++++------------------------------- 4 files changed, 54 insertions(+), 70 deletions(-) diff --git a/py/compile.c b/py/compile.c index c8b4e5470..7207ac2e0 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2869,17 +2869,11 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn if (MP_PARSE_NODE_IS_NULL(pn_iter)) { // no more nested if/for; compile inner expression compile_node(comp, pn_inner_expr); - if (comp->scope_cur->kind == SCOPE_LIST_COMP) { - EMIT_ARG(list_append, for_depth + 2); - } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) { - EMIT_ARG(map_add, for_depth + 2); - #if MICROPY_PY_BUILTINS_SET - } else if (comp->scope_cur->kind == SCOPE_SET_COMP) { - EMIT_ARG(set_add, for_depth + 2); - #endif - } else { + if (comp->scope_cur->kind == SCOPE_GEN_EXPR) { EMIT(yield_value); EMIT(pop_top); + } else { + EMIT_ARG(store_comp, comp->scope_cur->kind, for_depth + 2); } } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) { // if condition diff --git a/py/emit.h b/py/emit.h index 9121e719f..2b87e2c77 100644 --- a/py/emit.h +++ b/py/emit.h @@ -119,17 +119,15 @@ typedef struct _emit_method_table_t { void (*binary_op)(emit_t *emit, mp_binary_op_t op); void (*build_tuple)(emit_t *emit, mp_uint_t n_args); void (*build_list)(emit_t *emit, mp_uint_t n_args); - void (*list_append)(emit_t *emit, mp_uint_t list_stack_index); void (*build_map)(emit_t *emit, mp_uint_t n_args); void (*store_map)(emit_t *emit); - void (*map_add)(emit_t *emit, mp_uint_t map_stack_index); #if MICROPY_PY_BUILTINS_SET void (*build_set)(emit_t *emit, mp_uint_t n_args); - void (*set_add)(emit_t *emit, mp_uint_t set_stack_index); #endif #if MICROPY_PY_BUILTINS_SLICE void (*build_slice)(emit_t *emit, mp_uint_t n_args); #endif + void (*store_comp)(emit_t *emit, scope_kind_t kind, mp_uint_t set_stack_index); void (*unpack_sequence)(emit_t *emit, mp_uint_t n_args); void (*unpack_ex)(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right); void (*make_function)(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults); @@ -240,17 +238,15 @@ void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op); void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op); void mp_emit_bc_build_tuple(emit_t *emit, mp_uint_t n_args); void mp_emit_bc_build_list(emit_t *emit, mp_uint_t n_args); -void mp_emit_bc_list_append(emit_t *emit, mp_uint_t list_stack_index); void mp_emit_bc_build_map(emit_t *emit, mp_uint_t n_args); void mp_emit_bc_store_map(emit_t *emit); -void mp_emit_bc_map_add(emit_t *emit, mp_uint_t map_stack_index); #if MICROPY_PY_BUILTINS_SET void mp_emit_bc_build_set(emit_t *emit, mp_uint_t n_args); -void mp_emit_bc_set_add(emit_t *emit, mp_uint_t set_stack_index); #endif #if MICROPY_PY_BUILTINS_SLICE void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args); #endif +void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t list_stack_index); void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args); void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right); void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults); diff --git a/py/emitbc.c b/py/emitbc.c index d871aa4ce..11d04c511 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -837,11 +837,6 @@ void mp_emit_bc_build_list(emit_t *emit, mp_uint_t n_args) { emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_LIST, n_args); } -void mp_emit_bc_list_append(emit_t *emit, mp_uint_t list_stack_index) { - emit_bc_pre(emit, -1); - emit_write_bytecode_byte_uint(emit, MP_BC_LIST_APPEND, list_stack_index); -} - void mp_emit_bc_build_map(emit_t *emit, mp_uint_t n_args) { emit_bc_pre(emit, 1); emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_MAP, n_args); @@ -852,21 +847,11 @@ void mp_emit_bc_store_map(emit_t *emit) { emit_write_bytecode_byte(emit, MP_BC_STORE_MAP); } -void mp_emit_bc_map_add(emit_t *emit, mp_uint_t map_stack_index) { - emit_bc_pre(emit, -2); - emit_write_bytecode_byte_uint(emit, MP_BC_MAP_ADD, map_stack_index); -} - #if MICROPY_PY_BUILTINS_SET void mp_emit_bc_build_set(emit_t *emit, mp_uint_t n_args) { emit_bc_pre(emit, 1 - n_args); emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_SET, n_args); } - -void mp_emit_bc_set_add(emit_t *emit, mp_uint_t set_stack_index) { - emit_bc_pre(emit, -1); - emit_write_bytecode_byte_uint(emit, MP_BC_SET_ADD, set_stack_index); -} #endif #if MICROPY_PY_BUILTINS_SLICE @@ -876,6 +861,24 @@ void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) { } #endif +void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) { + int n; + byte opcode; + if (kind == SCOPE_LIST_COMP) { + n = -1; + opcode = MP_BC_LIST_APPEND; + } else if (MICROPY_PY_BUILTINS_SET && kind == SCOPE_SET_COMP) { + n = -1; + opcode = MP_BC_SET_ADD; + } else { + // scope == SCOPE_DICT_COMP + n = -2; + opcode = MP_BC_MAP_ADD; + } + emit_bc_pre(emit, n); + emit_write_bytecode_byte_uint(emit, opcode, collection_stack_index); +} + void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) { emit_bc_pre(emit, -1 + n_args); emit_write_bytecode_byte_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args); @@ -1028,17 +1031,15 @@ const emit_method_table_t emit_bc_method_table = { mp_emit_bc_binary_op, mp_emit_bc_build_tuple, mp_emit_bc_build_list, - mp_emit_bc_list_append, mp_emit_bc_build_map, mp_emit_bc_store_map, - mp_emit_bc_map_add, #if MICROPY_PY_BUILTINS_SET mp_emit_bc_build_set, - mp_emit_bc_set_add, #endif #if MICROPY_PY_BUILTINS_SLICE mp_emit_bc_build_slice, #endif + mp_emit_bc_store_comp, mp_emit_bc_unpack_sequence, mp_emit_bc_unpack_ex, mp_emit_bc_make_function, diff --git a/py/emitnative.c b/py/emitnative.c index 2cf4711fe..b54f263d6 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -2344,17 +2344,6 @@ STATIC void emit_native_build_list(emit_t *emit, mp_uint_t n_args) { emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new list } -STATIC void emit_native_list_append(emit_t *emit, mp_uint_t list_index) { - // only used in list comprehension - vtype_kind_t vtype_list, vtype_item; - emit_pre_pop_reg(emit, &vtype_item, REG_ARG_2); - emit_access_stack(emit, list_index, &vtype_list, REG_ARG_1); - assert(vtype_list == VTYPE_PYOBJ); - assert(vtype_item == VTYPE_PYOBJ); - emit_call(emit, MP_F_LIST_APPEND); - emit_post(emit); -} - STATIC void emit_native_build_map(emit_t *emit, mp_uint_t n_args) { emit_native_pre(emit); emit_call_with_imm_arg(emit, MP_F_BUILD_MAP, n_args, REG_ARG_1); @@ -2371,18 +2360,6 @@ STATIC void emit_native_store_map(emit_t *emit) { emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // map } -STATIC void emit_native_map_add(emit_t *emit, mp_uint_t map_index) { - // only used in list comprehension - vtype_kind_t vtype_map, vtype_key, vtype_value; - emit_pre_pop_reg_reg(emit, &vtype_key, REG_ARG_2, &vtype_value, REG_ARG_3); - emit_access_stack(emit, map_index, &vtype_map, REG_ARG_1); - assert(vtype_map == VTYPE_PYOBJ); - assert(vtype_key == VTYPE_PYOBJ); - assert(vtype_value == VTYPE_PYOBJ); - emit_call(emit, MP_F_STORE_MAP); - emit_post(emit); -} - #if MICROPY_PY_BUILTINS_SET STATIC void emit_native_build_set(emit_t *emit, mp_uint_t n_args) { emit_native_pre(emit); @@ -2390,17 +2367,6 @@ STATIC void emit_native_build_set(emit_t *emit, mp_uint_t n_args) { emit_call_with_imm_arg(emit, MP_F_BUILD_SET, n_args, REG_ARG_1); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new set } - -STATIC void emit_native_set_add(emit_t *emit, mp_uint_t set_index) { - // only used in set comprehension - vtype_kind_t vtype_set, vtype_item; - emit_pre_pop_reg(emit, &vtype_item, REG_ARG_2); - emit_access_stack(emit, set_index, &vtype_set, REG_ARG_1); - assert(vtype_set == VTYPE_PYOBJ); - assert(vtype_item == VTYPE_PYOBJ); - emit_call(emit, MP_F_STORE_SET); - emit_post(emit); -} #endif #if MICROPY_PY_BUILTINS_SLICE @@ -2426,6 +2392,35 @@ STATIC void emit_native_build_slice(emit_t *emit, mp_uint_t n_args) { } #endif +STATIC void emit_native_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_index) { + mp_fun_kind_t f; + if (kind == SCOPE_LIST_COMP) { + vtype_kind_t vtype_item; + emit_pre_pop_reg(emit, &vtype_item, REG_ARG_2); + assert(vtype_item == VTYPE_PYOBJ); + f = MP_F_LIST_APPEND; + #if MICROPY_PY_BUILTINS_SET + } else if (kind == SCOPE_SET_COMP) { + vtype_kind_t vtype_item; + emit_pre_pop_reg(emit, &vtype_item, REG_ARG_2); + assert(vtype_item == VTYPE_PYOBJ); + f = MP_F_STORE_SET; + #endif + } else { + // SCOPE_DICT_COMP + vtype_kind_t vtype_key, vtype_value; + emit_pre_pop_reg_reg(emit, &vtype_key, REG_ARG_2, &vtype_value, REG_ARG_3); + assert(vtype_key == VTYPE_PYOBJ); + assert(vtype_value == VTYPE_PYOBJ); + f = MP_F_STORE_MAP; + } + vtype_kind_t vtype_collection; + emit_access_stack(emit, collection_index, &vtype_collection, REG_ARG_1); + assert(vtype_collection == VTYPE_PYOBJ); + emit_call(emit, f); + emit_post(emit); +} + STATIC void emit_native_unpack_sequence(emit_t *emit, mp_uint_t n_args) { DEBUG_printf("unpack_sequence %d\n", n_args); vtype_kind_t vtype_base; @@ -2674,17 +2669,15 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_binary_op, emit_native_build_tuple, emit_native_build_list, - emit_native_list_append, emit_native_build_map, emit_native_store_map, - emit_native_map_add, #if MICROPY_PY_BUILTINS_SET emit_native_build_set, - emit_native_set_add, #endif #if MICROPY_PY_BUILTINS_SLICE emit_native_build_slice, #endif + emit_native_store_comp, emit_native_unpack_sequence, emit_native_unpack_ex, emit_native_make_function, -- cgit v1.2.3 From adaf0d865cd6c81fb352751566460506392ed55f Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 19 Sep 2016 08:46:01 +1000 Subject: py: Combine 3 comprehension opcodes (list/dict/set) into 1. With the previous patch combining 3 emit functions into 1, it now makes sense to also combine the corresponding VM opcodes, which is what this patch does. This eliminates 2 opcodes which simplifies the VM and reduces code size, in bytes: bare-arm:44, minimal:64, unix(NDEBUG,x86-64):272, stmhal:92, esp8266:200. Profiling (with a simple script that creates many list/dict/set comprehensions) shows no measurable change in performance. --- py/bc0.h | 4 +--- py/emitbc.c | 24 ++++++++++++------------ py/showbc.c | 20 +++++--------------- py/vm.c | 46 +++++++++++++++++++--------------------------- py/vmentrytable.h | 4 +--- 5 files changed, 38 insertions(+), 60 deletions(-) diff --git a/py/bc0.h b/py/bc0.h index b0b7d5c79..5ff9e50a8 100644 --- a/py/bc0.h +++ b/py/bc0.h @@ -82,13 +82,11 @@ #define MP_BC_BUILD_TUPLE (0x50) // uint #define MP_BC_BUILD_LIST (0x51) // uint -#define MP_BC_LIST_APPEND (0x52) // uint #define MP_BC_BUILD_MAP (0x53) // uint #define MP_BC_STORE_MAP (0x54) -#define MP_BC_MAP_ADD (0x55) // uint #define MP_BC_BUILD_SET (0x56) // uint -#define MP_BC_SET_ADD (0x57) // uint #define MP_BC_BUILD_SLICE (0x58) // uint +#define MP_BC_STORE_COMP (0x57) // uint #define MP_BC_UNPACK_SEQUENCE (0x59) // uint #define MP_BC_UNPACK_EX (0x5a) // uint diff --git a/py/emitbc.c b/py/emitbc.c index 11d04c511..8c712e1fd 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -862,21 +862,21 @@ void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) { #endif void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) { + int t; int n; - byte opcode; if (kind == SCOPE_LIST_COMP) { - n = -1; - opcode = MP_BC_LIST_APPEND; - } else if (MICROPY_PY_BUILTINS_SET && kind == SCOPE_SET_COMP) { - n = -1; - opcode = MP_BC_SET_ADD; - } else { - // scope == SCOPE_DICT_COMP - n = -2; - opcode = MP_BC_MAP_ADD; + n = 0; + t = 0; + } else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) { + n = 1; + t = 1; + } else if (MICROPY_PY_BUILTINS_SET) { + n = 0; + t = 2; } - emit_bc_pre(emit, n); - emit_write_bytecode_byte_uint(emit, opcode, collection_stack_index); + emit_bc_pre(emit, -1 - n); + // the lower 2 bits of the opcode argument indicate the collection type + emit_write_bytecode_byte_uint(emit, MP_BC_STORE_COMP, ((collection_stack_index + n) << 2) | t); } void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) { diff --git a/py/showbc.c b/py/showbc.c index dd5959f4a..0f335ffef 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -409,11 +409,6 @@ const byte *mp_bytecode_print_str(const byte *ip) { printf("BUILD_LIST " UINT_FMT, unum); break; - case MP_BC_LIST_APPEND: - DECODE_UINT; - printf("LIST_APPEND " UINT_FMT, unum); - break; - case MP_BC_BUILD_MAP: DECODE_UINT; printf("BUILD_MAP " UINT_FMT, unum); @@ -423,21 +418,11 @@ const byte *mp_bytecode_print_str(const byte *ip) { printf("STORE_MAP"); break; - case MP_BC_MAP_ADD: - DECODE_UINT; - printf("MAP_ADD " UINT_FMT, unum); - break; - case MP_BC_BUILD_SET: DECODE_UINT; printf("BUILD_SET " UINT_FMT, unum); break; - case MP_BC_SET_ADD: - DECODE_UINT; - printf("SET_ADD " UINT_FMT, unum); - break; - #if MICROPY_PY_BUILTINS_SLICE case MP_BC_BUILD_SLICE: DECODE_UINT; @@ -445,6 +430,11 @@ const byte *mp_bytecode_print_str(const byte *ip) { break; #endif + case MP_BC_STORE_COMP: + DECODE_UINT; + printf("STORE_COMP " UINT_FMT, unum); + break; + case MP_BC_UNPACK_SEQUENCE: DECODE_UINT; printf("UNPACK_SEQUENCE " UINT_FMT, unum); diff --git a/py/vm.c b/py/vm.c index f9bdedff8..da8697fad 100644 --- a/py/vm.c +++ b/py/vm.c @@ -777,15 +777,6 @@ unwind_jump:; DISPATCH(); } - ENTRY(MP_BC_LIST_APPEND): { - MARK_EXC_IP_SELECTIVE(); - DECODE_UINT; - // I think it's guaranteed by the compiler that sp[unum] is a list - mp_obj_list_append(sp[-unum], sp[0]); - sp--; - DISPATCH(); - } - ENTRY(MP_BC_BUILD_MAP): { MARK_EXC_IP_SELECTIVE(); DECODE_UINT; @@ -799,15 +790,6 @@ unwind_jump:; mp_obj_dict_store(sp[0], sp[2], sp[1]); DISPATCH(); - ENTRY(MP_BC_MAP_ADD): { - MARK_EXC_IP_SELECTIVE(); - DECODE_UINT; - // I think it's guaranteed by the compiler that sp[-unum - 1] is a map - mp_obj_dict_store(sp[-unum - 1], sp[0], sp[-1]); - sp -= 2; - DISPATCH(); - } - #if MICROPY_PY_BUILTINS_SET ENTRY(MP_BC_BUILD_SET): { MARK_EXC_IP_SELECTIVE(); @@ -816,15 +798,6 @@ unwind_jump:; SET_TOP(mp_obj_new_set(unum, sp)); DISPATCH(); } - - ENTRY(MP_BC_SET_ADD): { - MARK_EXC_IP_SELECTIVE(); - DECODE_UINT; - // I think it's guaranteed by the compiler that sp[-unum] is a set - mp_obj_set_store(sp[-unum], sp[0]); - sp--; - DISPATCH(); - } #endif #if MICROPY_PY_BUILTINS_SLICE @@ -845,6 +818,25 @@ unwind_jump:; } #endif + ENTRY(MP_BC_STORE_COMP): { + MARK_EXC_IP_SELECTIVE(); + DECODE_UINT; + mp_obj_t obj = sp[-(unum >> 2)]; + if ((unum & 3) == 0) { + mp_obj_list_append(obj, sp[0]); + sp--; + } else if (!MICROPY_PY_BUILTINS_SET || (unum & 3) == 1) { + mp_obj_dict_store(obj, sp[0], sp[-1]); + sp -= 2; + #if MICROPY_PY_BUILTINS_SET + } else { + mp_obj_set_store(obj, sp[0]); + sp--; + #endif + } + DISPATCH(); + } + ENTRY(MP_BC_UNPACK_SEQUENCE): { MARK_EXC_IP_SELECTIVE(); DECODE_UINT; diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 9df1e40a3..dd30dd7a5 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -78,17 +78,15 @@ static const void *const entry_table[256] = { [MP_BC_POP_EXCEPT] = &&entry_MP_BC_POP_EXCEPT, [MP_BC_BUILD_TUPLE] = &&entry_MP_BC_BUILD_TUPLE, [MP_BC_BUILD_LIST] = &&entry_MP_BC_BUILD_LIST, - [MP_BC_LIST_APPEND] = &&entry_MP_BC_LIST_APPEND, [MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP, [MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP, - [MP_BC_MAP_ADD] = &&entry_MP_BC_MAP_ADD, #if MICROPY_PY_BUILTINS_SET [MP_BC_BUILD_SET] = &&entry_MP_BC_BUILD_SET, - [MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD, #endif #if MICROPY_PY_BUILTINS_SLICE [MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE, #endif + [MP_BC_STORE_COMP] = &&entry_MP_BC_STORE_COMP, [MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE, [MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX, [MP_BC_MAKE_FUNCTION] = &&entry_MP_BC_MAKE_FUNCTION, -- cgit v1.2.3 From 5da0d29d3cefa6a3cac52e0db96e9ede820d6a51 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 19 Sep 2016 11:17:02 +1000 Subject: py/vstr: Remove vstr.had_error flag and inline basic vstr functions. The vstr.had_error flag was a relic from the very early days which assumed that the malloc functions (eg m_new, m_renew) returned NULL if they failed to allocate. But that's no longer the case: these functions will raise an exception if they fail. Since it was impossible for had_error to be set, this patch introduces no change in behaviour. An alternative option would be to change the malloc calls to the _maybe variants, which return NULL instead of raising, but then a lot of code will need to explicitly check if the vstr had an error and raise if it did. The code-size savings for this patch are, in bytes: bare-arm:188, minimal:456, unix(NDEBUG,x86-64):368, stmhal:228, esp8266:360. --- py/lexer.c | 3 ++- py/misc.h | 8 +++----- py/vstr.c | 55 +++---------------------------------------------------- 3 files changed, 8 insertions(+), 58 deletions(-) diff --git a/py/lexer.c b/py/lexer.c index 820f91be7..b2c9c5ff7 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -723,7 +723,8 @@ mp_lexer_t *mp_lexer_new(qstr src_name, void *stream_data, mp_lexer_stream_next_ vstr_init(&lex->vstr, 32); // check for memory allocation error - if (lex->indent_level == NULL || vstr_had_error(&lex->vstr)) { + // note: vstr_init above may fail on malloc, but so may mp_lexer_next_token_into below + if (lex->indent_level == NULL) { mp_lexer_free(lex); return NULL; } diff --git a/py/misc.h b/py/misc.h index 79a4c1c6e..3ed227a35 100644 --- a/py/misc.h +++ b/py/misc.h @@ -139,7 +139,6 @@ typedef struct _vstr_t { size_t alloc; size_t len; char *buf; - bool had_error : 1; bool fixed_buf : 1; } vstr_t; @@ -155,10 +154,9 @@ void vstr_clear(vstr_t *vstr); vstr_t *vstr_new(void); vstr_t *vstr_new_size(size_t alloc); void vstr_free(vstr_t *vstr); -void vstr_reset(vstr_t *vstr); -bool vstr_had_error(vstr_t *vstr); -char *vstr_str(vstr_t *vstr); -size_t vstr_len(vstr_t *vstr); +static inline void vstr_reset(vstr_t *vstr) { vstr->len = 0; } +static inline char *vstr_str(vstr_t *vstr) { return vstr->buf; } +static inline size_t vstr_len(vstr_t *vstr) { return vstr->len; } void vstr_hint_size(vstr_t *vstr, size_t size); char *vstr_extend(vstr_t *vstr, size_t size); char *vstr_add_len(vstr_t *vstr, size_t len); diff --git a/py/vstr.c b/py/vstr.c index cf10f8471..5096475f1 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -44,11 +44,6 @@ void vstr_init(vstr_t *vstr, size_t alloc) { vstr->alloc = alloc; vstr->len = 0; vstr->buf = m_new(char, vstr->alloc); - if (vstr->buf == NULL) { - vstr->had_error = true; - return; - } - vstr->had_error = false; vstr->fixed_buf = false; } @@ -63,7 +58,6 @@ void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf) { vstr->alloc = alloc; vstr->len = 0; vstr->buf = buf; - vstr->had_error = false; vstr->fixed_buf = true; } @@ -107,39 +101,12 @@ void vstr_free(vstr_t *vstr) { } } -void vstr_reset(vstr_t *vstr) { - vstr->len = 0; - vstr->had_error = false; -} - -bool vstr_had_error(vstr_t *vstr) { - return vstr->had_error; -} - -char *vstr_str(vstr_t *vstr) { - if (vstr->had_error) { - return NULL; - } - return vstr->buf; -} - -size_t vstr_len(vstr_t *vstr) { - if (vstr->had_error) { - return 0; - } - return vstr->len; -} - // Extend vstr strictly by requested size, return pointer to newly added chunk. char *vstr_extend(vstr_t *vstr, size_t size) { if (vstr->fixed_buf) { return NULL; } char *new_buf = m_renew(char, vstr->buf, vstr->alloc, vstr->alloc + size); - if (new_buf == NULL) { - vstr->had_error = true; - return NULL; - } char *p = new_buf + vstr->alloc; vstr->alloc += size; vstr->buf = new_buf; @@ -153,10 +120,6 @@ STATIC bool vstr_ensure_extra(vstr_t *vstr, size_t size) { } size_t new_alloc = ROUND_ALLOC((vstr->len + size) + 16); char *new_buf = m_renew(char, vstr->buf, vstr->alloc, new_alloc); - if (new_buf == NULL) { - vstr->had_error = true; - return false; - } vstr->alloc = new_alloc; vstr->buf = new_buf; } @@ -164,14 +127,11 @@ STATIC bool vstr_ensure_extra(vstr_t *vstr, size_t size) { } void vstr_hint_size(vstr_t *vstr, size_t size) { - // it's not an error if we fail to allocate for the size hint - bool er = vstr->had_error; vstr_ensure_extra(vstr, size); - vstr->had_error = er; } char *vstr_add_len(vstr_t *vstr, size_t len) { - if (vstr->had_error || !vstr_ensure_extra(vstr, len)) { + if (!vstr_ensure_extra(vstr, len)) { return NULL; } char *buf = vstr->buf + vstr->len; @@ -181,9 +141,6 @@ char *vstr_add_len(vstr_t *vstr, size_t len) { // Doesn't increase len, just makes sure there is a null byte at the end char *vstr_null_terminated_str(vstr_t *vstr) { - if (vstr->had_error) { - return NULL; - } // If there's no more room, add single byte if (vstr->alloc == vstr->len) { if (vstr_extend(vstr, 1) == NULL) { @@ -248,7 +205,7 @@ void vstr_add_str(vstr_t *vstr, const char *str) { } void vstr_add_strn(vstr_t *vstr, const char *str, size_t len) { - if (vstr->had_error || !vstr_ensure_extra(vstr, len)) { + if (!vstr_ensure_extra(vstr, len)) { // if buf is fixed, we got here because there isn't enough room left // so just try to copy as much as we can, with room for a possible null byte if (vstr->fixed_buf && vstr->len < vstr->alloc) { @@ -263,9 +220,6 @@ copy: } STATIC char *vstr_ins_blank_bytes(vstr_t *vstr, size_t byte_pos, size_t byte_len) { - if (vstr->had_error) { - return NULL; - } size_t l = vstr->len; if (byte_pos > l) { byte_pos = l; @@ -303,9 +257,6 @@ void vstr_cut_head_bytes(vstr_t *vstr, size_t bytes_to_cut) { } void vstr_cut_tail_bytes(vstr_t *vstr, size_t len) { - if (vstr->had_error) { - return; - } if (len > vstr->len) { vstr->len = 0; } else { @@ -314,7 +265,7 @@ void vstr_cut_tail_bytes(vstr_t *vstr, size_t len) { } void vstr_cut_out_bytes(vstr_t *vstr, size_t byte_pos, size_t bytes_to_cut) { - if (vstr->had_error || byte_pos >= vstr->len) { + if (byte_pos >= vstr->len) { return; } else if (byte_pos + bytes_to_cut >= vstr->len) { vstr->len = byte_pos; -- cgit v1.2.3 From 8dd5960ac0853ca2a73dd394511f80f3dd3d38cb Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 19 Sep 2016 12:20:41 +1000 Subject: py/objnone: Use mp_generic_unary_op instead of custom one. --- py/objnone.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/py/objnone.c b/py/objnone.c index 74c02e4d2..5d5b83540 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -43,20 +43,11 @@ STATIC void none_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ } } -STATIC mp_obj_t none_unary_op(mp_uint_t op, mp_obj_t o_in) { - (void)o_in; - switch (op) { - // MP_UNARY_OP_BOOL is handled by a fast-path in mp_obj_is_true - case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT((mp_uint_t)o_in); - default: return MP_OBJ_NULL; // op not supported - } -} - const mp_obj_type_t mp_type_NoneType = { { &mp_type_type }, .name = MP_QSTR_NoneType, .print = none_print, - .unary_op = none_unary_op, + .unary_op = mp_generic_unary_op, }; const mp_obj_none_t mp_const_none_obj = {{&mp_type_NoneType}}; -- cgit v1.2.3 From 4874bde10428302eac848b3130e5076e685c7774 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 19 Sep 2016 13:00:15 +1000 Subject: stmhal/boards: For OLIMEX_E407, enable UART1 and fix I2C1 mapping. UART1 can be used even if the switch is enabled. The schematics for this board make I2C1 available on PB8/PB9, even though it can also be mapped to PB6/PB7. See #2396 and #2427. --- stmhal/boards/OLIMEX_E407/mpconfigboard.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/stmhal/boards/OLIMEX_E407/mpconfigboard.h b/stmhal/boards/OLIMEX_E407/mpconfigboard.h index 4d1f7ff83..c9241fe63 100644 --- a/stmhal/boards/OLIMEX_E407/mpconfigboard.h +++ b/stmhal/boards/OLIMEX_E407/mpconfigboard.h @@ -23,10 +23,8 @@ #define MICROPY_HW_CLK_PLLQ (7) // UART config -#if MICROPY_HW_HAS_SWITCH == 0 #define MICROPY_HW_UART1_PORT (GPIOB) #define MICROPY_HW_UART1_PINS (GPIO_PIN_6 | GPIO_PIN_7) -#endif #define MICROPY_HW_UART2_PORT (GPIOA) #define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3) @@ -50,8 +48,8 @@ #define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7) // I2C busses -#define MICROPY_HW_I2C1_SCL (pin_B6) -#define MICROPY_HW_I2C1_SDA (pin_B7) +#define MICROPY_HW_I2C1_SCL (pin_B8) +#define MICROPY_HW_I2C1_SDA (pin_B9) #define MICROPY_HW_I2C2_SCL (pin_B10) #define MICROPY_HW_I2C2_SDA (pin_B11) -- cgit v1.2.3 From e60835bac5336c8e0123443b427c6db48b5060df Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 19 Sep 2016 13:18:54 +1000 Subject: py/qstr: Remove a comment. qstrs are always null terminated so qstr_str will stay as part of the API. --- py/qstr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/py/qstr.c b/py/qstr.c index 079b2a8e7..28df06ca3 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -275,7 +275,6 @@ size_t qstr_len(qstr q) { return Q_GET_LENGTH(qd); } -// XXX to remove! const char *qstr_str(qstr q) { const byte *qd = find_qstr(q); return (const char*)Q_GET_DATA(qd); -- cgit v1.2.3 From b85bcd671c5dced62fa00f2e3c0c5541b0d16593 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 19 Sep 2016 16:59:49 +0300 Subject: tests/struct1: Test "l" specifier to improve coverage. --- tests/basics/struct1.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index 857e171c1..1abe34b4c 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -10,6 +10,8 @@ print(struct.unpack(">bI", b"\x80\0\0\x01\0")) # 32-bit little-endian specific #print(struct.unpack("bI", b"\x80\xaa\x55\xaa\0\0\x01\0")) +print(struct.pack("l", 1)) print(struct.pack("i", 1)) print(struct.pack(" Date: Mon, 19 Sep 2016 17:20:41 +0300 Subject: tests/array1: Add tests for "l", "L" array types to improve coverage. --- tests/basics/array1.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/basics/array1.py b/tests/basics/array1.py index bce22cc57..e5ea6683c 100644 --- a/tests/basics/array1.py +++ b/tests/basics/array1.py @@ -6,6 +6,12 @@ i = array.array('I', [1, 2, 3]) print(i, len(i)) print(a[0]) print(i[-1]) +a = array.array('l', [-1]) +print(len(a), a[0]) +a1 = array.array('l', [1, 2, 3]) +a2 = array.array('L', [1, 2, 3]) +print(a2[1]) +print(a1 == a2) # Empty arrays print(len(array.array('h'))) -- cgit v1.2.3