From 3c0da6a3592c715fa901e100a6d5ad256f19f67f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 12 Nov 2016 00:09:20 +0300 Subject: examples/hwapi: button_led: Add GPIO pin read example. Requires BUTTON defined in hwconfig, so far tested on DragonBoard 410c. --- examples/hwapi/button_led.py | 9 +++++++++ examples/hwapi/hwconfig_dragonboard410c.py | 7 +++++++ 2 files changed, 16 insertions(+) create mode 100644 examples/hwapi/button_led.py (limited to 'examples') diff --git a/examples/hwapi/button_led.py b/examples/hwapi/button_led.py new file mode 100644 index 000000000..bd6fe0172 --- /dev/null +++ b/examples/hwapi/button_led.py @@ -0,0 +1,9 @@ +import utime +from hwconfig import LED, BUTTON + +# Light LED when (and while) a BUTTON is pressed + +while 1: + LED.value(BUTTON.value()) + # Don't burn CPU + utime.sleep_ms(10) diff --git a/examples/hwapi/hwconfig_dragonboard410c.py b/examples/hwapi/hwconfig_dragonboard410c.py index 00f21a658..32fdb9dd6 100644 --- a/examples/hwapi/hwconfig_dragonboard410c.py +++ b/examples/hwapi/hwconfig_dragonboard410c.py @@ -1,12 +1,19 @@ from machine import Pin # 96Boards/Qualcomm DragonBoard 410c +# # By default, on-board LEDs are controlled by kernel LED driver. # To make corresponding pins be available as normal GPIO, # corresponding driver needs to be unbound first (as root): # echo -n "soc:leds" >/sys/class/leds/apq8016-sbc:green:user1/device/driver/unbind # Note that application also either should be run as root, or # /sys/class/gpio ownership needs to be changed. +# Likewise, onboard buttons are controlled by gpio_keys driver. +# To release corresponding GPIOs: +# echo -n "gpio_keys" >/sys/class/input/input1/device/driver/unbind # User LED 1 on gpio21 LED = Pin(21, Pin.OUT) + +# Button S3 on gpio107 +BUTTON = Pin(107, Pin.IN) -- cgit v1.2.3 From 99e5badeb1e2e6aeffd3b3d56902d4257e168326 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 13 Nov 2016 17:00:24 +0300 Subject: examples/hwapi: Add soft_pwm example converted to uasyncio. --- examples/hwapi/soft_pwm_uasyncio.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 examples/hwapi/soft_pwm_uasyncio.py (limited to 'examples') diff --git a/examples/hwapi/soft_pwm_uasyncio.py b/examples/hwapi/soft_pwm_uasyncio.py new file mode 100644 index 000000000..8d7ad8c9e --- /dev/null +++ b/examples/hwapi/soft_pwm_uasyncio.py @@ -0,0 +1,28 @@ +# See original soft_pwm.py for detailed comments. +import uasyncio +from hwconfig import LED + + +async def pwm_cycle(led, duty, cycles): + duty_off = 20 - duty + for i in range(cycles): + if duty: + led.value(1) + await uasyncio.sleep_ms(duty) + if duty_off: + led.value(0) + await uasyncio.sleep_ms(duty_off) + + +async def fade_in_out(LED): + while True: + # Fade in + for i in range(1, 21): + await pwm_cycle(LED, i, 2) + # Fade out + for i in range(20, 0, -1): + await pwm_cycle(LED, i, 2) + + +loop = uasyncio.get_event_loop() +loop.run_until_complete(fade_in_out(LED)) -- cgit v1.2.3 From 00a9590e3a27c8784a9d3a95c669142aad4a025f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 14 Nov 2016 00:24:45 +0300 Subject: examples/http_client: Use read() instead of readall(). --- examples/network/http_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/network/http_client.py b/examples/network/http_client.py index b245a721a..0791c8066 100644 --- a/examples/network/http_client.py +++ b/examples/network/http_client.py @@ -19,7 +19,7 @@ def main(use_stream=False): # directly, but the line below is needed for CPython. s = s.makefile("rwb", 0) s.write(b"GET / HTTP/1.0\r\n\r\n") - print(s.readall()) + print(s.read()) else: s.send(b"GET / HTTP/1.0\r\n\r\n") print(s.recv(4096)) -- cgit v1.2.3 From bf318801d2fafa2786e74693d19a3c2fdb50ddda Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 14 Nov 2016 01:30:51 +0300 Subject: examples/hwapi: Add uasyncio example of fading 2 LEDs in parallel. --- examples/hwapi/hwconfig_dragonboard410c.py | 3 +++ examples/hwapi/soft_pwm2_uasyncio.py | 31 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 examples/hwapi/soft_pwm2_uasyncio.py (limited to 'examples') diff --git a/examples/hwapi/hwconfig_dragonboard410c.py b/examples/hwapi/hwconfig_dragonboard410c.py index 32fdb9dd6..8061d7b74 100644 --- a/examples/hwapi/hwconfig_dragonboard410c.py +++ b/examples/hwapi/hwconfig_dragonboard410c.py @@ -15,5 +15,8 @@ from machine import Pin # User LED 1 on gpio21 LED = Pin(21, Pin.OUT) +# User LED 2 on gpio120 +LED2 = Pin(120, Pin.OUT) + # Button S3 on gpio107 BUTTON = Pin(107, Pin.IN) diff --git a/examples/hwapi/soft_pwm2_uasyncio.py b/examples/hwapi/soft_pwm2_uasyncio.py new file mode 100644 index 000000000..abeb4b1bf --- /dev/null +++ b/examples/hwapi/soft_pwm2_uasyncio.py @@ -0,0 +1,31 @@ +# Like soft_pwm_uasyncio.py, but fading 2 LEDs with different phase. +# Also see original soft_pwm.py. +import uasyncio +from hwconfig import LED, LED2 + + +async def pwm_cycle(led, duty, cycles): + duty_off = 20 - duty + for i in range(cycles): + if duty: + led.value(1) + await uasyncio.sleep_ms(duty) + if duty_off: + led.value(0) + await uasyncio.sleep_ms(duty_off) + + +async def fade_in_out(LED): + while True: + # Fade in + for i in range(1, 21): + await pwm_cycle(LED, i, 2) + # Fade out + for i in range(20, 0, -1): + await pwm_cycle(LED, i, 2) + + +loop = uasyncio.get_event_loop() +loop.create_task(fade_in_out(LED)) +loop.call_later_ms_(800, fade_in_out(LED2)) +loop.run_forever() -- cgit v1.2.3 From 6b239c271c9c7041f9741c2a0f348f350808ad8a Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 16 Nov 2016 16:04:57 +1100 Subject: py: Factor out persistent-code reader into separate files. Implementations of persistent-code reader are provided for POSIX systems and systems using FatFS. Macros to use these are MICROPY_READER_POSIX and MICROPY_READER_FATFS respectively. If an alternative implementation is needed then a port can define the function mp_reader_new_file. --- cc3200/mpconfigport.h | 1 + esp8266/esp8266.ld | 1 + esp8266/esp8266_512k.ld | 1 + esp8266/mpconfigport.h | 1 + examples/embedding/mpconfigport_minimal.h | 1 + extmod/vfs_fat_reader.c | 88 ++++++++++++++++++ py/mpconfig.h | 10 ++ py/persistentcode.c | 129 +++----------------------- py/persistentcode.h | 10 +- py/py.mk | 2 + py/reader.c | 146 ++++++++++++++++++++++++++++++ py/reader.h | 45 +++++++++ stmhal/mpconfigport.h | 1 + unix/mpconfigport.h | 1 + 14 files changed, 316 insertions(+), 121 deletions(-) create mode 100644 extmod/vfs_fat_reader.c create mode 100644 py/reader.c create mode 100644 py/reader.h (limited to 'examples') diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h index bf3e691bd..08f926f40 100644 --- a/cc3200/mpconfigport.h +++ b/cc3200/mpconfigport.h @@ -55,6 +55,7 @@ #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) #define MICROPY_OPT_COMPUTED_GOTO (0) #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) +#define MICROPY_READER_FATFS (1) #ifndef DEBUG // we need ram on the launchxl while debugging #define MICROPY_CPYTHON_COMPAT (1) #else diff --git a/esp8266/esp8266.ld b/esp8266/esp8266.ld index 546ffd8c5..a6a4b930b 100644 --- a/esp8266/esp8266.ld +++ b/esp8266/esp8266.ld @@ -92,6 +92,7 @@ SECTIONS *py/formatfloat.o*(.literal* .text*) *py/frozenmod.o*(.literal* .text*) *py/gc.o*(.literal* .text*) + *py/reader*.o*(.literal* .text*) *py/lexer*.o*(.literal* .text*) *py/malloc*.o*(.literal* .text*) *py/map*.o*(.literal* .text*) diff --git a/esp8266/esp8266_512k.ld b/esp8266/esp8266_512k.ld index e744d0f46..2bffcab80 100644 --- a/esp8266/esp8266_512k.ld +++ b/esp8266/esp8266_512k.ld @@ -92,6 +92,7 @@ SECTIONS *py/formatfloat.o*(.literal* .text*) *py/frozenmod.o*(.literal* .text*) *py/gc.o*(.literal* .text*) + *py/reader*.o*(.literal* .text*) *py/lexer*.o*(.literal* .text*) *py/malloc*.o*(.literal* .text*) *py/map*.o*(.literal* .text*) diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index 602b3e9c8..adbec5d0d 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -16,6 +16,7 @@ #define MICROPY_MEM_STATS (0) #define MICROPY_DEBUG_PRINTERS (1) #define MICROPY_DEBUG_PRINTER_DEST mp_debug_print +#define MICROPY_READER_FATFS (1) #define MICROPY_ENABLE_GC (1) #define MICROPY_STACK_CHECK (1) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) diff --git a/examples/embedding/mpconfigport_minimal.h b/examples/embedding/mpconfigport_minimal.h index 90011b3f8..48d200858 100644 --- a/examples/embedding/mpconfigport_minimal.h +++ b/examples/embedding/mpconfigport_minimal.h @@ -33,6 +33,7 @@ #define MICROPY_COMP_CONST (0) #define MICROPY_MEM_STATS (0) #define MICROPY_DEBUG_PRINTERS (0) +#define MICROPY_READER_POSIX (1) #define MICROPY_HELPER_REPL (1) #define MICROPY_HELPER_LEXER_UNIX (1) #define MICROPY_ENABLE_SOURCE_LINE (0) diff --git a/extmod/vfs_fat_reader.c b/extmod/vfs_fat_reader.c new file mode 100644 index 000000000..7a00f18de --- /dev/null +++ b/extmod/vfs_fat_reader.c @@ -0,0 +1,88 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-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 "py/mperrno.h" +#include "py/reader.h" + +#if MICROPY_READER_FATFS + +#include "lib/fatfs/ff.h" +#include "extmod/vfs_fat_file.h" + +typedef struct _mp_reader_fatfs_t { + FIL fp; + uint16_t len; + uint16_t pos; + byte buf[20]; +} mp_reader_fatfs_t; + +STATIC mp_uint_t mp_reader_fatfs_readbyte(void *data) { + mp_reader_fatfs_t *reader = (mp_reader_fatfs_t*)data; + if (reader->pos >= reader->len) { + if (reader->len < sizeof(reader->buf)) { + return MP_READER_EOF; + } else { + UINT n; + f_read(&reader->fp, reader->buf, sizeof(reader->buf), &n); + if (n == 0) { + return MP_READER_EOF; + } + reader->len = n; + reader->pos = 0; + } + } + return reader->buf[reader->pos++]; +} + +STATIC void mp_reader_fatfs_close(void *data) { + mp_reader_fatfs_t *reader = (mp_reader_fatfs_t*)data; + f_close(&reader->fp); + m_del_obj(mp_reader_fatfs_t, reader); +} + +int mp_reader_new_file(mp_reader_t *reader, const char *filename) { + mp_reader_fatfs_t *rf = m_new_obj_maybe(mp_reader_fatfs_t); + if (rf == NULL) { + return MP_ENOMEM; + } + FRESULT res = f_open(&rf->fp, filename, FA_READ); + if (res != FR_OK) { + return fresult_to_errno_table[res]; + } + UINT n; + f_read(&rf->fp, rf->buf, sizeof(rf->buf), &n); + rf->len = n; + rf->pos = 0; + reader->data = rf; + reader->readbyte = mp_reader_fatfs_readbyte; + reader->close = mp_reader_fatfs_close; + return 0; // success +} + +#endif diff --git a/py/mpconfig.h b/py/mpconfig.h index 3945a1a5a..1980e649c 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -381,6 +381,16 @@ /*****************************************************************************/ /* Python internal features */ +// Whether to use the POSIX reader for importing files +#ifndef MICROPY_READER_POSIX +#define MICROPY_READER_POSIX (0) +#endif + +// Whether to use the FatFS reader for importing files +#ifndef MICROPY_READER_FATFS +#define MICROPY_READER_FATFS (0) +#endif + // Hook for the VM at the start of the opcode loop (can contain variable // definitions usable by the other hook functions) #ifndef MICROPY_VM_HOOK_INIT diff --git a/py/persistentcode.c b/py/persistentcode.c index 31f147a09..99b01f8e2 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -29,6 +29,7 @@ #include #include +#include "py/reader.h" #include "py/emitglue.h" #include "py/persistentcode.h" #include "py/bc.h" @@ -98,19 +99,19 @@ STATIC void extract_prelude(const byte **ip, const byte **ip2, bytecode_prelude_ #include "py/bc0.h" STATIC int read_byte(mp_reader_t *reader) { - return reader->read_byte(reader->data); + return reader->readbyte(reader->data); } STATIC void read_bytes(mp_reader_t *reader, byte *buf, size_t len) { while (len-- > 0) { - *buf++ = reader->read_byte(reader->data); + *buf++ = reader->readbyte(reader->data); } } STATIC mp_uint_t read_uint(mp_reader_t *reader) { mp_uint_t unum = 0; for (;;) { - byte b = reader->read_byte(reader->data); + byte b = reader->readbyte(reader->data); unum = (unum << 7) | (b & 0x7f); if ((b & 0x80) == 0) { break; @@ -214,128 +215,28 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) { if (header[2] != MPY_FEATURE_FLAGS || header[3] > mp_small_int_bits()) { mp_raise_ValueError("incompatible .mpy file"); } - return load_raw_code(reader); -} - -typedef struct _mp_mem_reader_t { - const byte *cur; - const byte *end; -} mp_mem_reader_t; - -STATIC mp_uint_t mp_mem_reader_next_byte(void *br_in) { - mp_mem_reader_t *br = br_in; - if (br->cur < br->end) { - return *br->cur++; - } else { - return (mp_uint_t)-1; - } + mp_raw_code_t *rc = load_raw_code(reader); + reader->close(reader->data); + return rc; } mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len) { - mp_mem_reader_t mr = {buf, buf + len}; - mp_reader_t reader = {&mr, mp_mem_reader_next_byte}; - return mp_raw_code_load(&reader); -} - -// 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(__unix__) -// unix file reader - -#include -#include -#include - -typedef struct _mp_lexer_file_buf_t { - int fd; - byte buf[20]; - mp_uint_t len; - mp_uint_t pos; -} mp_lexer_file_buf_t; - -STATIC mp_uint_t file_buf_next_byte(void *fb_in) { - mp_lexer_file_buf_t *fb = fb_in; - if (fb->pos >= fb->len) { - if (fb->len == 0) { - return (mp_uint_t)-1; - } else { - int n = read(fb->fd, fb->buf, sizeof(fb->buf)); - if (n <= 0) { - fb->len = 0; - return (mp_uint_t)-1; - } - fb->len = n; - fb->pos = 0; - } - } - return fb->buf[fb->pos++]; -} - -mp_raw_code_t *mp_raw_code_load_file(const char *filename) { - mp_lexer_file_buf_t fb; - fb.fd = open(filename, O_RDONLY, 0644); - int n = read(fb.fd, fb.buf, sizeof(fb.buf)); - fb.len = n; - fb.pos = 0; mp_reader_t reader; - reader.data = &fb; - reader.read_byte = file_buf_next_byte; - mp_raw_code_t *rc = mp_raw_code_load(&reader); - close(fb.fd); - return rc; -} - -#elif defined(__thumb2__) || defined(__xtensa__) -// fatfs file reader (assume thumb2 arch uses fatfs...) - -#include "lib/fatfs/ff.h" - -typedef struct _mp_lexer_file_buf_t { - FIL fp; - byte buf[20]; - uint16_t len; - uint16_t pos; -} mp_lexer_file_buf_t; - -STATIC mp_uint_t file_buf_next_byte(void *fb_in) { - mp_lexer_file_buf_t *fb = fb_in; - if (fb->pos >= fb->len) { - if (fb->len < sizeof(fb->buf)) { - return (mp_uint_t)-1; - } else { - UINT n; - f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n); - if (n == 0) { - return (mp_uint_t)-1; - } - fb->len = n; - fb->pos = 0; - } + if (!mp_reader_new_mem(&reader, buf, len, 0)) { + m_malloc_fail(BYTES_PER_WORD); // we need to raise a MemoryError } - return fb->buf[fb->pos++]; + return mp_raw_code_load(&reader); } mp_raw_code_t *mp_raw_code_load_file(const char *filename) { - mp_lexer_file_buf_t fb; - /*FRESULT res =*/ f_open(&fb.fp, filename, FA_READ); - UINT n; - f_read(&fb.fp, fb.buf, sizeof(fb.buf), &n); - fb.len = n; - fb.pos = 0; - mp_reader_t reader; - reader.data = &fb; - reader.read_byte = file_buf_next_byte; - mp_raw_code_t *rc = mp_raw_code_load(&reader); - - f_close(&fb.fp); - - return rc; + int ret = mp_reader_new_file(&reader, filename); + if (ret != 0) { + mp_raise_OSError(ret); + } + return mp_raw_code_load(&reader); } -#endif - #endif // MICROPY_PERSISTENT_CODE_LOAD #if MICROPY_PERSISTENT_CODE_SAVE diff --git a/py/persistentcode.h b/py/persistentcode.h index 8859bc577..d04e0b633 100644 --- a/py/persistentcode.h +++ b/py/persistentcode.h @@ -26,13 +26,9 @@ #ifndef MICROPY_INCLUDED_PY_PERSISTENTCODE_H #define MICROPY_INCLUDED_PY_PERSISTENTCODE_H -#include "py/obj.h" - -typedef struct _mp_reader_t { - void *data; - mp_uint_t (*read_byte)(void *data); - void (*close)(void *data); -} mp_reader_t; +#include "py/mpprint.h" +#include "py/reader.h" +#include "py/emitglue.h" mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader); mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len); diff --git a/py/py.mk b/py/py.mk index b0962d178..4630c21a9 100644 --- a/py/py.mk +++ b/py/py.mk @@ -113,6 +113,7 @@ PY_O_BASENAME = \ mpprint.o \ unicode.o \ mpz.o \ + reader.o \ lexer.o \ lexerstr.o \ lexerunix.o \ @@ -228,6 +229,7 @@ PY_O_BASENAME = \ ../extmod/vfs_fat_ffconf.o \ ../extmod/vfs_fat_diskio.o \ ../extmod/vfs_fat_file.o \ + ../extmod/vfs_fat_reader.o \ ../extmod/vfs_fat_lexer.o \ ../extmod/vfs_fat_misc.o \ ../extmod/utime_mphal.o \ diff --git a/py/reader.c b/py/reader.c new file mode 100644 index 000000000..d14fc416c --- /dev/null +++ b/py/reader.c @@ -0,0 +1,146 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-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 "py/mperrno.h" +#include "py/reader.h" + +typedef struct _mp_reader_mem_t { + size_t free_len; // if >0 mem is freed on close by: m_free(beg, free_len) + const byte *beg; + const byte *cur; + const byte *end; +} mp_reader_mem_t; + +STATIC mp_uint_t mp_reader_mem_readbyte(void *data) { + mp_reader_mem_t *reader = (mp_reader_mem_t*)data; + if (reader->cur < reader->end) { + return *reader->cur++; + } else { + return MP_READER_EOF; + } +} + +STATIC void mp_reader_mem_close(void *data) { + mp_reader_mem_t *reader = (mp_reader_mem_t*)data; + if (reader->free_len > 0) { + m_del(char, (char*)reader->beg, reader->free_len); + } + m_del_obj(mp_reader_mem_t, reader); +} + +bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len) { + mp_reader_mem_t *rm = m_new_obj_maybe(mp_reader_mem_t); + if (rm == NULL) { + return false; + } + rm->free_len = free_len; + rm->beg = buf; + rm->cur = buf; + rm->end = buf + len; + reader->data = rm; + reader->readbyte = mp_reader_mem_readbyte; + reader->close = mp_reader_mem_close; + return true; +} + +#if MICROPY_READER_POSIX + +#include +#include +#include +#include + +typedef struct _mp_reader_posix_t { + bool close_fd; + int fd; + size_t len; + size_t pos; + byte buf[20]; +} mp_reader_posix_t; + +STATIC mp_uint_t mp_reader_posix_readbyte(void *data) { + mp_reader_posix_t *reader = (mp_reader_posix_t*)data; + if (reader->pos >= reader->len) { + if (reader->len == 0) { + return MP_READER_EOF; + } else { + int n = read(reader->fd, reader->buf, sizeof(reader->buf)); + if (n <= 0) { + reader->len = 0; + return MP_READER_EOF; + } + reader->len = n; + reader->pos = 0; + } + } + return reader->buf[reader->pos++]; +} + +STATIC void mp_reader_posix_close(void *data) { + mp_reader_posix_t *reader = (mp_reader_posix_t*)data; + if (reader->close_fd) { + close(reader->fd); + } + m_del_obj(mp_reader_posix_t, reader); +} + +STATIC int mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) { + mp_reader_posix_t *rp = m_new_obj_maybe(mp_reader_posix_t); + if (rp == NULL) { + if (close_fd) { + close(fd); + } + return MP_ENOMEM; + } + rp->close_fd = close_fd; + rp->fd = fd; + int n = read(rp->fd, rp->buf, sizeof(rp->buf)); + if (n == -1) { + if (close_fd) { + close(fd); + } + return errno; + } + rp->len = n; + rp->pos = 0; + reader->data = rp; + reader->readbyte = mp_reader_posix_readbyte; + reader->close = mp_reader_posix_close; + return 0; // success +} + +int mp_reader_new_file(mp_reader_t *reader, const char *filename) { + int fd = open(filename, O_RDONLY, 0644); + if (fd < 0) { + return errno; + } + return mp_reader_new_file_from_fd(reader, fd, true); +} + +#endif diff --git a/py/reader.h b/py/reader.h new file mode 100644 index 000000000..f39cc90f8 --- /dev/null +++ b/py/reader.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-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. + */ +#ifndef MICROPY_INCLUDED_PY_READER_H +#define MICROPY_INCLUDED_PY_READER_H + +#include "py/obj.h" + +// the readbyte function must return the next byte in the input stream +// it must return MP_READER_EOF if end of stream +// it can be called again after returning MP_READER_EOF, and in that case must return MP_READER_EOF +#define MP_READER_EOF ((mp_uint_t)(-1)) + +typedef struct _mp_reader_t { + void *data; + mp_uint_t (*readbyte)(void *data); + void (*close)(void *data); +} mp_reader_t; + +bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len); +int mp_reader_new_file(mp_reader_t *reader, const char *filename); + +#endif // MICROPY_INCLUDED_PY_READER_H diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h index 264db3029..3eec0fcce 100644 --- a/stmhal/mpconfigport.h +++ b/stmhal/mpconfigport.h @@ -51,6 +51,7 @@ #define MICROPY_OPT_COMPUTED_GOTO (1) #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0) #define MICROPY_OPT_MPZ_BITWISE (1) +#define MICROPY_READER_FATFS (1) // fatfs configuration used in ffconf.h #define MICROPY_FATFS_ENABLE_LFN (1) diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index f4f8d2d20..86e460566 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -54,6 +54,7 @@ // Printing debug to stderr may give tests which // check stdout a chance to pass, etc. #define MICROPY_DEBUG_PRINTER_DEST mp_stderr_print +#define MICROPY_READER_POSIX (1) #define MICROPY_USE_READLINE_HISTORY (1) #define MICROPY_HELPER_REPL (1) #define MICROPY_REPL_EMACS_KEYS (1) -- cgit v1.2.3 From b188d6e9db1842f9f66976ef1d67746239c8006c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 17 Nov 2016 01:10:00 +0300 Subject: examples/hwapi: Add example for machine.time_pulse_us(). --- examples/hwapi/button_reaction.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 examples/hwapi/button_reaction.py (limited to 'examples') diff --git a/examples/hwapi/button_reaction.py b/examples/hwapi/button_reaction.py new file mode 100644 index 000000000..5e1890d5a --- /dev/null +++ b/examples/hwapi/button_reaction.py @@ -0,0 +1,19 @@ +import utime +import machine +from hwconfig import LED, BUTTON + +# machine.time_pulse_us() function demo + +print("""\ +Let's play an interesting game: +You click button as fast as you can, and I tell you how slow you are. +Ready? Cliiiiick! +""") + +while 1: + try: + delay = machine.time_pulse_us(BUTTON, 1, 10*1000*1000) + print("You are as slow as %d microseconds!" % delay) + except OSError: + print("Well, you're *really* slow") + utime.sleep_ms(10) -- cgit v1.2.3 From 00d6f99cf1f94babb237bff00364497ec30f475c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 18 Nov 2016 07:20:26 +0300 Subject: examples/hwapi: Add hwconfig for console tracing of LED operations. --- examples/hwapi/hwconfig_console.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 examples/hwapi/hwconfig_console.py (limited to 'examples') diff --git a/examples/hwapi/hwconfig_console.py b/examples/hwapi/hwconfig_console.py new file mode 100644 index 000000000..7355571a1 --- /dev/null +++ b/examples/hwapi/hwconfig_console.py @@ -0,0 +1,13 @@ +# This is hwconfig for "emulation" for cases when there's no real hardware. +# It just prints information to console. +class LEDClass: + + def __init__(self, id): + self.id = id + + def value(self, v): + print("LED(%d):" % self.id, v) + + +LED = LEDClass(1) +LED2 = LEDClass(12) -- cgit v1.2.3 From c28fed6b64248adbd6c1b429a85d4d9e00cd9e36 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 18 Nov 2016 17:00:54 +1100 Subject: examples/accellog.py: Change 1: to /sd/, and update comment about FS. --- examples/accellog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/accellog.py b/examples/accellog.py index bb711b05f..b1f289f8a 100644 --- a/examples/accellog.py +++ b/examples/accellog.py @@ -5,7 +5,7 @@ import pyb accel = pyb.Accel() # create object of accelerometer blue = pyb.LED(4) # create object of blue LED -log = open('1:/log.csv', 'w') # open file to write data - 1:/ ist the SD-card, 0:/ the internal memory +log = open('/sd/log.csv', 'w') # open file to write data - /sd/ is the SD-card, /flash/ the internal memory blue.on() # turn on blue LED for i in range(100): # do 100 times (if the board is connected via USB, you can't write longer because the PC tries to open the filesystem which messes up your file.) -- cgit v1.2.3 From 1e9093f8cbe117d50451a204f513fea78ef6abfb Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 23 Dec 2016 17:24:24 +0300 Subject: examples/hwapi/hwconfig_console: Don't alloc memory in value(). --- examples/hwapi/hwconfig_console.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/hwapi/hwconfig_console.py b/examples/hwapi/hwconfig_console.py index 7355571a1..4b0b0d79b 100644 --- a/examples/hwapi/hwconfig_console.py +++ b/examples/hwapi/hwconfig_console.py @@ -3,10 +3,10 @@ class LEDClass: def __init__(self, id): - self.id = id + self.id = "LED(%d):" % id def value(self, v): - print("LED(%d):" % self.id, v) + print(self.id, v) LED = LEDClass(1) -- cgit v1.2.3