summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony DiCola <tony@tonydicola.com>2016-10-20 23:01:13 +0000
committerTony DiCola <tony@tonydicola.com>2016-10-20 23:01:13 +0000
commit00a44fa36cd1e35a438c4b89b5cef0bc82787c7a (patch)
tree4800a6984902e043e3fc437adcdfcd665f83e220
parent1f13f870b8f6554d9cd5570de221a6886e065b64 (diff)
parent3967ca7390ff8257728ef6237b93977b63bde41d (diff)
Merge remote-tracking branch 'micropython/master'
Conflicts: README.md - Kept Adafruit README.md intact. py/emitglue.c - Added xtensa architecture as an OR of the define. zephyr/README.md - Fixed spelling mistake.
-rw-r--r--cc3200/hal/cc3200_hal.c4
-rw-r--r--cc3200/hal/cc3200_hal.h1
-rw-r--r--cc3200/misc/mpirq.c2
-rw-r--r--cc3200/mods/modmachine.c2
-rw-r--r--cc3200/mods/modnetwork.c2
-rw-r--r--cc3200/mods/moduhashlib.c4
-rw-r--r--cc3200/mods/moduos.c30
-rw-r--r--cc3200/mods/modusocket.c30
-rw-r--r--cc3200/mods/modussl.c4
-rw-r--r--cc3200/mods/modutime.c4
-rw-r--r--cc3200/mods/modwlan.c34
-rw-r--r--cc3200/mods/pybadc.c14
-rw-r--r--cc3200/mods/pybi2c.c14
-rw-r--r--cc3200/mods/pybpin.c20
-rw-r--r--cc3200/mods/pybrtc.c14
-rw-r--r--cc3200/mods/pybsd.c4
-rw-r--r--cc3200/mods/pybspi.c12
-rw-r--r--cc3200/mods/pybtimer.c16
-rw-r--r--cc3200/mods/pybuart.c10
-rw-r--r--cc3200/mods/pybwdt.c6
-rw-r--r--cc3200/mpconfigport.h1
-rw-r--r--cc3200/mpthreadport.c22
-rw-r--r--cc3200/serverstask.c6
-rw-r--r--conf.py2
-rw-r--r--docs/library/machine.SPI.rst79
-rw-r--r--docs/reference/constrained.rst456
-rw-r--r--docs/reference/index.rst1
-rw-r--r--esp8266/Makefile10
-rw-r--r--esp8266/esp8266.ld8
-rw-r--r--esp8266/esp_init_data.c80
-rw-r--r--esp8266/main.c2
-rw-r--r--esp8266/modules/webrepl.py4
-rw-r--r--esp8266/modutime.c62
-rw-r--r--esp8266/mpconfigport.h7
-rw-r--r--extmod/machine_i2c.c2
-rw-r--r--extmod/modujson.c107
-rw-r--r--extmod/modussl_mbedtls.c11
-rw-r--r--extmod/utime_mphal.c89
-rw-r--r--extmod/utime_mphal.h36
-rw-r--r--extmod/uzlib/tinf.h1
-rw-r--r--extmod/uzlib/tinflate.c3
-rw-r--r--extmod/vfs_fat.c39
-rw-r--r--extmod/vfs_fat_file.c10
-rw-r--r--lib/utils/pyexec.c8
-rw-r--r--lib/utils/pyexec.h5
-rw-r--r--py/argcheck.c11
-rw-r--r--py/bc.c5
-rw-r--r--py/builtinevex.c2
-rw-r--r--py/builtinimport.c8
-rw-r--r--py/compile.c17
-rw-r--r--py/emitglue.c2
-rw-r--r--py/lexer.c12
-rw-r--r--py/misc.h3
-rw-r--r--py/modbuiltins.c9
-rw-r--r--py/modmicropython.c11
-rw-r--r--py/modthread.c2
-rw-r--r--py/mpconfig.h6
-rw-r--r--py/mphal.h4
-rw-r--r--py/mpprint.c4
-rw-r--r--py/mpz.c41
-rw-r--r--py/mpz.h1
-rw-r--r--py/obj.c31
-rw-r--r--py/objarray.c4
-rw-r--r--py/objcomplex.c4
-rw-r--r--py/objdict.c17
-rw-r--r--py/objfloat.c2
-rw-r--r--py/objgenerator.c6
-rw-r--r--py/objint.c26
-rw-r--r--py/objint.h8
-rw-r--r--py/objint_longlong.c2
-rw-r--r--py/objint_mpz.c13
-rw-r--r--py/objlist.c2
-rw-r--r--py/objnamedtuple.c2
-rw-r--r--py/objobject.c3
-rw-r--r--py/objset.c4
-rw-r--r--py/objstringio.c12
-rw-r--r--py/objstringio.h38
-rw-r--r--py/objtype.c21
-rw-r--r--py/parsenum.c4
-rw-r--r--py/py.mk5
-rw-r--r--py/runtime.c53
-rw-r--r--py/sequence.c2
-rw-r--r--py/stream.c2
-rw-r--r--py/vstr.c14
-rw-r--r--qemu-arm/Makefile9
-rw-r--r--qemu-arm/memory.h2
-rw-r--r--qemu-arm/mpconfigport.h11
-rw-r--r--qemu-arm/mphalport.h3
-rw-r--r--stmhal/Makefile11
-rw-r--r--stmhal/accel.c14
-rw-r--r--stmhal/boards/ESPRUINO_PICO/mpconfigboard.h5
-rw-r--r--stmhal/boards/HYDRABUS/mpconfigboard.h5
-rw-r--r--stmhal/boards/LIMIFROG/mpconfigboard.h5
-rw-r--r--stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h5
-rw-r--r--stmhal/boards/NUCLEO_F401RE/mpconfigboard.h5
-rw-r--r--stmhal/boards/NUCLEO_F411RE/mpconfigboard.h5
-rw-r--r--stmhal/boards/OLIMEX_E407/mpconfigboard.h5
-rw-r--r--stmhal/boards/PYBLITEV10/mpconfigboard.h5
-rw-r--r--stmhal/boards/PYBV10/mpconfigboard.h5
-rw-r--r--stmhal/boards/PYBV11/mpconfigboard.h5
-rw-r--r--stmhal/boards/PYBV3/mpconfigboard.h5
-rw-r--r--stmhal/boards/PYBV4/mpconfigboard.h5
-rw-r--r--stmhal/boards/STM32F411DISC/mpconfigboard.h5
-rw-r--r--stmhal/boards/STM32F429DISC/mpconfigboard.h5
-rw-r--r--stmhal/boards/STM32F4DISC/mpconfigboard.h5
-rw-r--r--stmhal/boards/STM32F7DISC/mpconfigboard.h5
-rw-r--r--stmhal/boards/STM32L476DISC/mpconfigboard.h5
-rw-r--r--stmhal/i2c.c4
-rw-r--r--stmhal/lcd.c44
-rw-r--r--stmhal/led.c11
-rw-r--r--stmhal/modmachine.c8
-rw-r--r--stmhal/modnwwiznet5k.c22
-rw-r--r--stmhal/modpyb.c5
-rw-r--r--stmhal/modutime.c80
-rw-r--r--stmhal/mpconfigport.h5
-rw-r--r--stmhal/mphalport.c17
-rw-r--r--stmhal/mphalport.h56
-rw-r--r--stmhal/pin.c18
-rw-r--r--stmhal/pybstdio.c2
-rw-r--r--stmhal/spi.c2
-rw-r--r--teensy/main.c2
-rw-r--r--teensy/teensy_hal.h10
-rw-r--r--tests/basics/array1.py4
-rw-r--r--tests/basics/async_def.py16
-rw-r--r--tests/basics/async_def.py.exp3
-rw-r--r--tests/basics/async_with.py4
-rw-r--r--tests/basics/async_with.py.exp1
-rw-r--r--tests/basics/builtin_range.py6
-rw-r--r--tests/basics/del_global.py5
-rw-r--r--tests/basics/dict1.py24
-rw-r--r--tests/basics/dict_views.py15
-rw-r--r--tests/basics/for_range.py5
-rw-r--r--tests/basics/int_constfolding.py5
-rw-r--r--tests/basics/slice_attrs.py9
-rw-r--r--tests/basics/syntaxerror.py4
-rw-r--r--tests/basics/unpack1.py1
-rw-r--r--tests/cmdline/cmd_showbc.py17
-rw-r--r--tests/cmdline/cmd_showbc.py.exp103
-rw-r--r--tests/cmdline/repl_basic.py1
-rw-r--r--tests/cmdline/repl_basic.py.exp2
-rw-r--r--tests/extmod/ujson_load.py11
-rw-r--r--tests/extmod/vfs_fat_ramdisk.py52
-rw-r--r--tests/extmod/vfs_fat_ramdisk.py.exp18
-rw-r--r--tests/import/import2a.py3
-rw-r--r--tests/micropython/emg_exc.py20
-rw-r--r--tests/micropython/emg_exc.py.exp1
-rw-r--r--tests/micropython/heap_lock.py14
-rw-r--r--tests/micropython/heap_lock.py.exp2
-rw-r--r--tests/micropython/heapalloc.py13
-rw-r--r--tests/micropython/opt_level.py14
-rw-r--r--tests/micropython/opt_level.py.exp4
-rw-r--r--tests/micropython/viper_args.py8
-rw-r--r--tests/misc/non_compliant.py24
-rw-r--r--tests/misc/non_compliant.py.exp4
-rwxr-xr-xtests/run-tests3
-rw-r--r--tests/unicode/unicode.py5
-rw-r--r--tools/micropython-upip-1.0.tar.gzbin4075 -> 0 bytes
-rw-r--r--tools/micropython-upip-1.1.3.tar.gzbin0 -> 4072 bytes
-rwxr-xr-xtools/tinytest-codegen.py11
-rw-r--r--unix/Makefile2
-rw-r--r--unix/coverage.c2
-rw-r--r--zephyr/Makefile8
-rw-r--r--zephyr/README.md2
-rw-r--r--zephyr/help.c56
-rw-r--r--zephyr/main.c33
-rw-r--r--zephyr/mpconfigport.h38
-rw-r--r--zephyr/mphalport.h1
-rw-r--r--zephyr/src/zephyr_getchar.c12
-rw-r--r--zephyr/src/zephyr_start.c25
-rw-r--r--zephyr/uart_core.c25
170 files changed, 1961 insertions, 787 deletions
diff --git a/cc3200/hal/cc3200_hal.c b/cc3200/hal/cc3200_hal.c
index f4d38d120..37026db14 100644
--- a/cc3200/hal/cc3200_hal.c
+++ b/cc3200/hal/cc3200_hal.c
@@ -130,10 +130,6 @@ void mp_hal_delay_ms(mp_uint_t delay) {
}
}
-NORETURN void mp_hal_raise(int errno) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, mp_obj_new_int(errno)));
-}
-
void mp_hal_set_interrupt_char (int c) {
mpexception_set_interrupt_char (c);
}
diff --git a/cc3200/hal/cc3200_hal.h b/cc3200/hal/cc3200_hal.h
index 054d5035a..9715096b6 100644
--- a/cc3200/hal/cc3200_hal.h
+++ b/cc3200/hal/cc3200_hal.h
@@ -62,7 +62,6 @@
extern void HAL_SystemInit (void);
extern void HAL_SystemDeInit (void);
extern void HAL_IncrementTick(void);
-extern NORETURN void mp_hal_raise(int errno);
extern void mp_hal_set_interrupt_char (int c);
#endif /* CC3200_LAUNCHXL_HAL_CC3200_HAL_H_ */
diff --git a/cc3200/misc/mpirq.c b/cc3200/misc/mpirq.c
index 29cc4a7bd..4389ab0c3 100644
--- a/cc3200/misc/mpirq.c
+++ b/cc3200/misc/mpirq.c
@@ -112,7 +112,7 @@ void mp_irq_remove (const mp_obj_t parent) {
uint mp_irq_translate_priority (uint priority) {
if (priority < 1 || priority > MP_ARRAY_SIZE(mp_irq_priorities)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
return mp_irq_priorities[priority - 1];
}
diff --git a/cc3200/mods/modmachine.c b/cc3200/mods/modmachine.c
index f82decda2..8a57c2eb4 100644
--- a/cc3200/mods/modmachine.c
+++ b/cc3200/mods/modmachine.c
@@ -130,7 +130,7 @@ STATIC mp_obj_t machine_main(mp_obj_t main) {
if (MP_OBJ_IS_STR(main)) {
MP_STATE_PORT(machine_config_main) = main;
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
return mp_const_none;
}
diff --git a/cc3200/mods/modnetwork.c b/cc3200/mods/modnetwork.c
index 8e086b1d2..f98d9a88a 100644
--- a/cc3200/mods/modnetwork.c
+++ b/cc3200/mods/modnetwork.c
@@ -101,7 +101,7 @@ STATIC mp_obj_t network_server_make_new(const mp_obj_type_t *type, mp_uint_t n_a
// check the server id
if (args[0].u_obj != MP_OBJ_NULL) {
if (mp_obj_get_int(args[0].u_obj) != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
}
diff --git a/cc3200/mods/moduhashlib.c b/cc3200/mods/moduhashlib.c
index 93f15540c..46f30be21 100644
--- a/cc3200/mods/moduhashlib.c
+++ b/cc3200/mods/moduhashlib.c
@@ -93,7 +93,7 @@ STATIC void hash_update_internal(mp_obj_t self_in, mp_obj_t data, bool digest) {
self->digested = false;
}
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
}
@@ -106,7 +106,7 @@ STATIC mp_obj_t hash_read (mp_obj_t self_in) {
}
} else if (self->c_size < self->b_size) {
// it's a fixed len block which is still incomplete
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
if (!self->digested) {
diff --git a/cc3200/mods/moduos.c b/cc3200/mods/moduos.c
index 8e3e0135e..d5b29336a 100644
--- a/cc3200/mods/moduos.c
+++ b/cc3200/mods/moduos.c
@@ -158,7 +158,7 @@ STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonl
#endif
// cannot mount twice or on existing paths
if (f_stat(path, &fno) == FR_OK || osmount_find_by_device(device)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
// create a new object
@@ -196,7 +196,7 @@ STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonl
if (f_mount(&self->fatfs, self->path, 1) != FR_OK) {
// remove it and raise
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), self);
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
// mount succeeded, increment the count
@@ -252,7 +252,7 @@ STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
}
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
return mp_const_none;
@@ -263,7 +263,7 @@ STATIC mp_obj_t os_getcwd(void) {
char buf[MICROPY_ALLOC_PATH_MAX + 1];
FRESULT res = f_getcwd(buf, sizeof buf);
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
return mp_obj_new_str(buf, strlen(buf), false);
}
@@ -303,7 +303,7 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
res = f_opendir(&dir, path); /* Open the directory */
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
for ( ; ; ) {
@@ -335,10 +335,10 @@ STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
case FR_OK:
return mp_const_none;
case FR_EXIST:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
break;
default:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
@@ -351,7 +351,7 @@ STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
case FR_OK:
return mp_const_none;
default:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
@@ -363,7 +363,7 @@ STATIC mp_obj_t os_remove(mp_obj_t path_o) {
case FR_OK:
return mp_const_none;
default:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
@@ -394,7 +394,7 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
fno.ftime = 0;
fno.fattrib = AM_DIR;
} else if ((res = f_stat(path, &fno)) != FR_OK) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
+ mp_raise_OSError(fresult_to_errno_table[res]);
}
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
@@ -481,7 +481,7 @@ STATIC mp_obj_t os_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *k
return mp_const_none;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
+ mp_raise_msg(&mp_type_OSError, mpexception_value_invalid_arguments);
}
MP_DEFINE_CONST_FUN_OBJ_KW(os_mount_obj, 2, os_mount);
@@ -490,7 +490,7 @@ STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
// '/flash' cannot be unmounted, also not the current working directory
if (path_equal(path, "/flash")) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
// now unmount it
@@ -498,7 +498,7 @@ STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
if ((mount_obj = osmount_find_by_path(path))) {
unmount (mount_obj);
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_msg(&mp_type_ValueError, mpexception_value_invalid_arguments);
}
return mp_const_none;
@@ -515,7 +515,7 @@ STATIC mp_obj_t os_mkfs(mp_obj_t device) {
path = mp_obj_str_get_str(device);
// otherwise the relative path check will pass...
if (path[0] != '/') {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
+ mp_raise_msg(&mp_type_OSError, mpexception_value_invalid_arguments);
}
} else {
// mount it briefly
@@ -541,7 +541,7 @@ STATIC mp_obj_t os_mkfs(mp_obj_t device) {
}
if (res != FR_OK) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
return mp_const_none;
}
diff --git a/cc3200/mods/modusocket.c b/cc3200/mods/modusocket.c
index c7b3fb203..81a4c2e19 100644
--- a/cc3200/mods/modusocket.c
+++ b/cc3200/mods/modusocket.c
@@ -156,7 +156,7 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_
// create the socket
int _errno;
if (wlan_socket_socket(s, &_errno) != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
// add the socket to the list
modusocket_socket_add(s->sock_base.sd, true);
@@ -182,7 +182,7 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
// call the NIC to bind the socket
int _errno;
if (wlan_socket_bind(self, ip, port, &_errno) != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
return mp_const_none;
}
@@ -200,7 +200,7 @@ STATIC mp_obj_t socket_listen(mp_uint_t n_args, const mp_obj_t *args) {
int _errno;
if (wlan_socket_listen(self, backlog, &_errno) != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
return mp_const_none;
}
@@ -220,7 +220,7 @@ STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
mp_uint_t port;
int _errno;
if (wlan_socket_accept(self, socket2, ip, &port, &_errno) != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
// add the socket to the list
@@ -248,7 +248,7 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
if (!self->sock_base.cert_req && _errno == SL_ESECSNOVERIFY) {
return mp_const_none;
}
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
return mp_const_none;
}
@@ -262,7 +262,7 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
int _errno;
mp_int_t ret = wlan_socket_send(self, bufinfo.buf, bufinfo.len, &_errno);
if (ret < 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
return mp_obj_new_int_from_uint(ret);
}
@@ -278,9 +278,9 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
mp_int_t ret = wlan_socket_recv(self, (byte*)vstr.buf, len, &_errno);
if (ret < 0) {
if (_errno == EAGAIN && self->sock_base.has_timeout) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
+ mp_raise_msg(&mp_type_TimeoutError, "timed out");
}
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
if (ret == 0) {
return mp_const_empty_bytes;
@@ -307,7 +307,7 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
int _errno;
mp_int_t ret = wlan_socket_sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
if (ret < 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
return mp_obj_new_int(ret);
}
@@ -324,9 +324,9 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
mp_int_t ret = wlan_socket_recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno);
if (ret < 0) {
if (_errno == EAGAIN && self->sock_base.has_timeout) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
+ mp_raise_msg(&mp_type_TimeoutError, "timed out");
}
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
mp_obj_t tuple[2];
if (ret == 0) {
@@ -364,7 +364,7 @@ STATIC mp_obj_t socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
int _errno;
if (wlan_socket_setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
return mp_const_none;
}
@@ -384,7 +384,7 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
}
int _errno;
if (wlan_socket_settimeout(self, timeout, &_errno) != 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
+ mp_raise_OSError(-_errno);
}
return mp_const_none;
}
@@ -408,7 +408,7 @@ STATIC mp_obj_t socket_makefile(mp_uint_t n_args, const mp_obj_t *args) {
if (n_args > 1) {
const char *mode = mp_obj_str_get_str(args[1]);
if (strcmp(mode, "rb") && strcmp(mode, "wb")) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
return self;
@@ -504,7 +504,7 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
int32_t result = wlan_gethostbyname(host, hlen, out_ip, AF_INET);
if (result < 0) {
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-result)));
+ mp_raise_OSError(-result);
}
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET);
diff --git a/cc3200/mods/modussl.c b/cc3200/mods/modussl.c
index 1f27bdd21..7a4787b6b 100644
--- a/cc3200/mods/modussl.c
+++ b/cc3200/mods/modussl.c
@@ -131,10 +131,10 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
return ssl_sock;
socket_error:
- nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
+ mp_raise_OSError(_errno);
arg_error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 0, mod_ssl_wrap_socket);
diff --git a/cc3200/mods/modutime.c b/cc3200/mods/modutime.c
index bef8b667f..7ea8df1ef 100644
--- a/cc3200/mods/modutime.c
+++ b/cc3200/mods/modutime.c
@@ -29,7 +29,7 @@
#include <string.h>
#include "py/mpconfig.h"
-#include "py/nlr.h"
+#include "py/runtime.h"
#include "py/obj.h"
#include "py/smallint.h"
#include "py/mphal.h"
@@ -109,7 +109,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
// localtime generates a tuple of len 8. CPython uses 9, so we accept both.
if (len < 8 || len > 9) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
+ mp_raise_TypeError(mpexception_num_type_invalid_arguments);
}
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index 2fb7ed377..4b3dd4ec3 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -603,7 +603,7 @@ STATIC void wlan_reset (void) {
STATIC void wlan_validate_mode (uint mode) {
if (mode != ROLE_STA && mode != ROLE_AP) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
@@ -614,7 +614,7 @@ STATIC void wlan_set_mode (uint mode) {
STATIC void wlan_validate_ssid_len (uint32_t len) {
if (len > MODWLAN_SSID_LEN_MAX) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
@@ -647,7 +647,7 @@ STATIC void wlan_validate_security (uint8_t auth, const char *key, uint8_t len)
return;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len) {
@@ -670,7 +670,7 @@ STATIC void wlan_set_security (uint8_t auth, const char *key, uint8_t len) {
STATIC void wlan_validate_channel (uint8_t channel) {
if (channel < 1 || channel > 11) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
@@ -682,7 +682,7 @@ STATIC void wlan_set_channel (uint8_t channel) {
#if MICROPY_HW_ANTENNA_DIVERSITY
STATIC void wlan_validate_antenna (uint8_t antenna) {
if (antenna != ANTENNA_TYPE_INTERNAL && antenna != ANTENNA_TYPE_EXTERNAL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
@@ -847,7 +847,7 @@ STATIC mp_obj_t wlan_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_ui
if (n_args > 1 || n_kw > 0) {
// check the peripheral id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// start the peripheral
wlan_init_helper(self, &args[1]);
@@ -871,7 +871,7 @@ STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
// check for correct wlan mode
if (wlan_obj.mode == ROLE_AP) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
Sl_WlanNetworkEntry_t wlanEntry;
@@ -925,7 +925,7 @@ STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
// check for the correct wlan mode
if (wlan_obj.mode == ROLE_AP) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
// parse args
@@ -973,9 +973,9 @@ STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
modwlan_Status_t status;
status = wlan_do_connect (ssid, ssid_len, bssid, auth, key, key_len, timeout);
if (status == MODWLAN_ERROR_TIMEOUT) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
} else if (status == MODWLAN_ERROR_INVALID_PARAMS) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
return mp_const_none;
}
@@ -1004,7 +1004,7 @@ STATIC mp_obj_t wlan_ifconfig (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
// check the interface id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// get the configuration
@@ -1051,7 +1051,7 @@ STATIC mp_obj_t wlan_ifconfig (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
// check for the correct string
const char *mode = mp_obj_str_get_str(args[1].u_obj);
if (strcmp("dhcp", mode)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
// only if we are not in AP mode
@@ -1165,7 +1165,7 @@ STATIC mp_obj_t wlan_mac (mp_uint_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
if (bufinfo.len != 6) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
memcpy(self->mac, bufinfo.buf, SL_MAC_ADDR_LEN);
sl_NetCfgSet(SL_MAC_ADDRESS_SET, 1, SL_MAC_ADDR_LEN, (_u8 *)self->mac);
@@ -1201,7 +1201,7 @@ STATIC mp_obj_t wlan_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *
return _irq;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
@@ -1230,18 +1230,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_irq_obj, 1, wlan_irq);
//
// // the call to sl_NetAppSet corrupts the input string URN=args[1], so we copy into a local buffer
// if (len > MAX_DEVICE_URN_LEN) {
-// nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+// mp_raise_ValueError(mpexception_value_invalid_arguments);
// }
// strcpy(urn, p);
//
// if (sl_NetAppSet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, len, (unsigned char *)urn) < 0) {
-// nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+// mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
// }
// }
// else {
// // get the URN
// if (sl_NetAppGet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, &len, (uint8_t *)urn) < 0) {
-// nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+// mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
// }
// return mp_obj_new_str(urn, (len - 1), false);
// }
diff --git a/cc3200/mods/pybadc.c b/cc3200/mods/pybadc.c
index 22a90edb0..f8c9b3da5 100644
--- a/cc3200/mods/pybadc.c
+++ b/cc3200/mods/pybadc.c
@@ -104,7 +104,7 @@ STATIC void pyb_adc_init (pyb_adc_obj_t *self) {
STATIC void pyb_adc_check_init(void) {
// not initialized
if (!pyb_adc_obj.enabled) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
}
@@ -149,12 +149,12 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uin
// check the peripheral id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// check the number of bits
if (args[1].u_int != 12) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
// setup the object
@@ -173,7 +173,7 @@ STATIC mp_obj_t adc_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *k
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_adc_init_args[1], args);
// check the number of bits
if (args[0].u_int != 12) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
pyb_adc_init(pos_args[0]);
return mp_const_none;
@@ -206,11 +206,11 @@ STATIC mp_obj_t adc_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t
if (args[0].u_obj != MP_OBJ_NULL) {
ch_id = mp_obj_get_int(args[0].u_obj);
if (ch_id >= PYB_ADC_NUM_CHANNELS) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_os_resource_not_avaliable));
+ mp_raise_ValueError(mpexception_os_resource_not_avaliable);
} else if (args[1].u_obj != mp_const_none) {
uint pin_ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0);
if (ch_id != pin_ch_id) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
} else {
@@ -277,7 +277,7 @@ STATIC mp_obj_t adc_channel_value(mp_obj_t self_in) {
// the channel must be enabled
if (!self->enabled) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
// wait until a new value is available
diff --git a/cc3200/mods/pybi2c.c b/cc3200/mods/pybi2c.c
index 5022e614f..d92782d8a 100644
--- a/cc3200/mods/pybi2c.c
+++ b/cc3200/mods/pybi2c.c
@@ -144,7 +144,7 @@ STATIC bool pyb_i2c_transaction(uint cmd) {
STATIC void pyb_i2c_check_init(pyb_i2c_obj_t *self) {
// not initialized
if (!self->baudrate) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
}
@@ -256,7 +256,7 @@ STATIC void pyb_i2c_read_into (mp_arg_val_t *args, vstr_t *vstr) {
// receive the data
if (!pyb_i2c_read(args[0].u_int, (byte *)vstr->buf, vstr->len)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
}
@@ -275,7 +275,7 @@ STATIC void pyb_i2c_readmem_into (mp_arg_val_t *args, vstr_t *vstr) {
if (pyb_i2c_mem_addr_write (i2c_addr, (byte *)&mem_addr, mem_addr_size)) {
// Read the specified length of data
if (!pyb_i2c_read (i2c_addr, (byte *)vstr->buf, vstr->len)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
}
}
@@ -323,7 +323,7 @@ STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, const mp_arg_val_t *arg
return mp_const_none;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC const mp_arg_t pyb_i2c_init_args[] = {
@@ -341,7 +341,7 @@ STATIC mp_obj_t pyb_i2c_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp
// check the peripheral id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// setup the object
@@ -445,7 +445,7 @@ STATIC mp_obj_t pyb_i2c_writeto(mp_uint_t n_args, const mp_obj_t *pos_args, mp_m
// send the data
if (!pyb_i2c_write(args[0].u_int, bufinfo.buf, bufinfo.len, args[2].u_bool)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
// return the number of bytes written
@@ -514,7 +514,7 @@ STATIC mp_obj_t pyb_i2c_writeto_mem(mp_uint_t n_args, const mp_obj_t *pos_args,
return mp_obj_new_int(bufinfo.len);
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_writeto_mem_obj, 1, pyb_i2c_writeto_mem);
diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c
index ce304404b..f59e65fc2 100644
--- a/cc3200/mods/pybpin.c
+++ b/cc3200/mods/pybpin.c
@@ -145,7 +145,7 @@ pin_obj_t *pin_find(mp_obj_t user_obj) {
return pin_obj;
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
void pin_config (pin_obj_t *self, int af, uint mode, uint pull, int value, uint strength) {
@@ -185,7 +185,7 @@ uint8_t pin_find_peripheral_unit (const mp_obj_t pin, uint8_t fn, uint8_t type)
return pin_o->af_list[i].unit;
}
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit) {
@@ -195,13 +195,13 @@ uint8_t pin_find_peripheral_type (const mp_obj_t pin, uint8_t fn, uint8_t unit)
return pin_o->af_list[i].type;
}
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
int8_t pin_find_af_index (const pin_obj_t* pin, uint8_t fn, uint8_t unit, uint8_t type) {
int8_t af = pin_obj_find_af(pin, fn, unit, type);
if (af < 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
return af;
}
@@ -426,18 +426,18 @@ STATIC void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t prio
STATIC void pin_validate_mode (uint mode) {
if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT && mode != PIN_TYPE_OD &&
mode != GPIO_DIR_MODE_ALT && mode != GPIO_DIR_MODE_ALT_OD) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
STATIC void pin_validate_pull (uint pull) {
if (pull != PIN_TYPE_STD && pull != PIN_TYPE_STD_PU && pull != PIN_TYPE_STD_PD) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
STATIC void pin_validate_drive(uint strength) {
if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
@@ -450,7 +450,7 @@ STATIC void pin_validate_af(const pin_obj_t* pin, int8_t idx, uint8_t *fn, uint8
return;
}
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC uint8_t pin_get_value (const pin_obj_t* self) {
@@ -591,7 +591,7 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_
return mp_const_none;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
@@ -905,7 +905,7 @@ STATIC mp_obj_t pin_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *k
return _irq;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_irq_obj, 1, pin_irq);
diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c
index ea9941105..4662edbe7 100644
--- a/cc3200/mods/pybrtc.c
+++ b/cc3200/mods/pybrtc.c
@@ -202,7 +202,7 @@ STATIC uint pyb_rtc_datetime_s_us(const mp_obj_t datetime, uint32_t *seconds) {
// verify the tuple
if (len < 3 || len > 8) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
tm.tm_year = mp_obj_get_int(items[0]);
@@ -294,7 +294,7 @@ STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp
// check the peripheral id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// setup the object
@@ -362,7 +362,7 @@ STATIC mp_obj_t pyb_rtc_alarm (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
// check the alarm id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
uint32_t f_seconds;
@@ -371,7 +371,7 @@ STATIC mp_obj_t pyb_rtc_alarm (mp_uint_t n_args, const mp_obj_t *pos_args, mp_ma
if (MP_OBJ_IS_TYPE(args[1].u_obj, &mp_type_tuple)) { // datetime tuple given
// repeat cannot be used with a datetime tuple
if (repeat) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
f_mseconds = pyb_rtc_datetime_s_us (args[1].u_obj, &f_seconds) / 1000;
} else { // then it must be an integer
@@ -397,7 +397,7 @@ STATIC mp_obj_t pyb_rtc_alarm_left (mp_uint_t n_args, const mp_obj_t *args) {
// only alarm id 0 is available
if (n_args > 1 && mp_obj_get_int(args[1]) != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// get the current time
@@ -415,7 +415,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_alarm_left_obj, 1, 2, pyb_rtc
STATIC mp_obj_t pyb_rtc_alarm_cancel (mp_uint_t n_args, const mp_obj_t *args) {
// only alarm id 0 is available
if (n_args > 1 && mp_obj_get_int(args[1]) != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// disable the alarm
pyb_rtc_disable_alarm();
@@ -453,7 +453,7 @@ STATIC mp_obj_t pyb_rtc_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
return _irq;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_irq_obj, 1, pyb_rtc_irq);
diff --git a/cc3200/mods/pybsd.c b/cc3200/mods/pybsd.c
index 55b797dc7..d7efbe872 100644
--- a/cc3200/mods/pybsd.c
+++ b/cc3200/mods/pybsd.c
@@ -107,7 +107,7 @@ STATIC mp_obj_t pyb_sd_init_helper (pybsd_obj_t *self, const mp_arg_val_t *args)
pyb_sd_hw_init (self);
if (sd_disk_init() != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
// register it with the sleep module
@@ -132,7 +132,7 @@ STATIC mp_obj_t pyb_sd_make_new (const mp_obj_type_t *type, mp_uint_t n_args, mp
// check the peripheral id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// setup and initialize the object
diff --git a/cc3200/mods/pybspi.c b/cc3200/mods/pybspi.c
index d4fcbe94b..5a040e3f5 100644
--- a/cc3200/mods/pybspi.c
+++ b/cc3200/mods/pybspi.c
@@ -131,7 +131,7 @@ STATIC void pybspi_rx (pyb_spi_obj_t *self, void *data) {
STATIC void pybspi_transfer (pyb_spi_obj_t *self, const char *txdata, char *rxdata, uint32_t len, uint32_t *txchar) {
if (!self->baudrate) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
// send and receive the data
MAP_SPICSEnable(GSPI_BASE);
@@ -218,7 +218,7 @@ STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, const mp_arg_val_t *arg
return mp_const_none;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
static const mp_arg_t pyb_spi_init_args[] = {
@@ -240,7 +240,7 @@ STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp
// check the peripheral id
if (args[0].u_int != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// setup the object
@@ -295,7 +295,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_write_obj, pyb_spi_write);
STATIC mp_obj_t pyb_spi_read(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_nbytes, MP_ARG_REQUIRED | MP_ARG_OBJ, },
- { MP_QSTR_write, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x00} },
+ { MP_QSTR_write, MP_ARG_INT, {.u_int = 0x00} },
};
// parse args
@@ -319,7 +319,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_read_obj, 1, pyb_spi_read);
STATIC mp_obj_t pyb_spi_readinto(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
- { MP_QSTR_write, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x00} },
+ { MP_QSTR_write, MP_ARG_INT, {.u_int = 0x00} },
};
// parse args
@@ -357,7 +357,7 @@ STATIC mp_obj_t pyb_spi_write_readinto (mp_obj_t self, mp_obj_t writebuf, mp_obj
// get the read buffer
mp_get_buffer_raise(readbuf, &bufinfo_read, MP_BUFFER_WRITE);
if (bufinfo_read.len != bufinfo_write.len) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
}
diff --git a/cc3200/mods/pybtimer.c b/cc3200/mods/pybtimer.c
index 65fc7195e..2ac71cccb 100644
--- a/cc3200/mods/pybtimer.c
+++ b/cc3200/mods/pybtimer.c
@@ -223,7 +223,7 @@ STATIC uint32_t compute_prescaler_period_and_match_value(pyb_timer_channel_obj_t
return prescaler;
error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC void timer_init (pyb_timer_obj_t *tim) {
@@ -319,7 +319,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *tim, mp_uint_t n_args, co
return mp_const_none;
error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
@@ -329,7 +329,7 @@ STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args,
// create a new Timer object
int32_t timer_idx = mp_obj_get_int(args[0]);
if (timer_idx < 0 || timer_idx > (PYBTIMER_NUM_TIMERS - 1)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
pyb_timer_obj_t *tim = &pyb_timer_obj[timer_idx];
@@ -370,7 +370,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
// verify that the timer has been already initialized
if (!tim->config) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
if (channel_n != TIMER_A && channel_n != TIMER_B && channel_n != (TIMER_A | TIMER_B)) {
// invalid channel
@@ -440,7 +440,7 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
return ch;
error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_obj, 2, pyb_timer_channel);
@@ -560,7 +560,7 @@ STATIC mp_obj_t pyb_timer_channel_freq(mp_uint_t n_args, const mp_obj_t *args) {
// set
int32_t _frequency = mp_obj_get_int(args[1]);
if (_frequency <= 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
ch->frequency = _frequency;
ch->period = 1000000 / _frequency;
@@ -579,7 +579,7 @@ STATIC mp_obj_t pyb_timer_channel_period(mp_uint_t n_args, const mp_obj_t *args)
// set
int32_t _period = mp_obj_get_int(args[1]);
if (_period <= 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
ch->period = _period;
ch->frequency = 1000000 / _period;
@@ -712,7 +712,7 @@ STATIC mp_obj_t pyb_timer_channel_irq (mp_uint_t n_args, const mp_obj_t *pos_arg
return _irq;
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_irq_obj, 1, pyb_timer_channel_irq);
diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c
index e7b5255bd..493522f83 100644
--- a/cc3200/mods/pybuart.c
+++ b/cc3200/mods/pybuart.c
@@ -280,7 +280,7 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) {
STATIC void uart_check_init(pyb_uart_obj_t *self) {
// not initialized
if (!self->baudrate) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
}
@@ -432,7 +432,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *a
return mp_const_none;
error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC const mp_arg_t pyb_uart_init_args[] = {
@@ -472,7 +472,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, mp_uint_t n_args, m
}
if (uart_id > PYB_UART_1) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
// get the correct uart instance
@@ -556,7 +556,7 @@ STATIC mp_obj_t pyb_uart_irq (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
return uart_irq_new (self, trigger, priority, args[2].u_obj);
invalid_args:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq);
@@ -622,7 +622,7 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t
// write the data
if (!uart_tx_strn(self, buf, size)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_operation_failed);
}
return size;
}
diff --git a/cc3200/mods/pybwdt.c b/cc3200/mods/pybwdt.c
index 6e5fe4714..30478c83c 100644
--- a/cc3200/mods/pybwdt.c
+++ b/cc3200/mods/pybwdt.c
@@ -100,14 +100,14 @@ STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_wdt_init_args, args);
if (args[0].u_obj != mp_const_none && mp_obj_get_int(args[0].u_obj) > 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable);
}
uint timeout_ms = args[1].u_int;
if (timeout_ms < PYBWDT_MIN_TIMEOUT_MS) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
if (pyb_wdt_obj.running) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
+ mp_raise_msg(&mp_type_OSError, mpexception_os_request_not_possible);
}
// Enable the WDT peripheral clock
diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h
index 0b16d730d..bf3e691bd 100644
--- a/cc3200/mpconfigport.h
+++ b/cc3200/mpconfigport.h
@@ -38,6 +38,7 @@
// options to control how Micro Python is built
#define MICROPY_ALLOC_PATH_MAX (128)
+#define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_EMIT_THUMB (0)
#define MICROPY_EMIT_INLINE_THUMB (0)
#define MICROPY_COMP_MODULE_CONST (1)
diff --git a/cc3200/mpthreadport.c b/cc3200/mpthreadport.c
index 064aa6ba1..e77ac4ae5 100644
--- a/cc3200/mpthreadport.c
+++ b/cc3200/mpthreadport.c
@@ -28,10 +28,13 @@
#include "py/mpconfig.h"
#include "py/mpstate.h"
+#include "py/runtime.h"
#include "py/gc.h"
#include "py/mpthread.h"
+#include "py/mphal.h"
#include "mptask.h"
#include "task.h"
+#include "irq.h"
#if MICROPY_PY_THREAD
@@ -131,7 +134,7 @@ void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
TaskHandle_t id = xTaskCreateStatic(freertos_entry, "Thread", *stack_size / sizeof(void*), arg, 2, stack, tcb);
if (id == NULL) {
mp_thread_mutex_unlock(&thread_mutex);
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't create thread"));
+ mp_raise_msg(&mp_type_OSError, "can't create thread");
}
// add thread to linked list of all threads
@@ -165,14 +168,23 @@ void mp_thread_mutex_init(mp_thread_mutex_t *mutex) {
mutex->handle = xSemaphoreCreateMutexStatic(&mutex->buffer);
}
+// To allow hard interrupts to work with threading we only take/give the semaphore
+// if we are not within an interrupt context and interrupts are enabled.
+
int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) {
- int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
- return ret == pdTRUE;
+ if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
+ int ret = xSemaphoreTake(mutex->handle, wait ? portMAX_DELAY : 0);
+ return ret == pdTRUE;
+ } else {
+ return 1;
+ }
}
void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) {
- xSemaphoreGive(mutex->handle);
- // TODO check return value
+ if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
+ xSemaphoreGive(mutex->handle);
+ // TODO check return value
+ }
}
#endif // MICROPY_PY_THREAD
diff --git a/cc3200/serverstask.c b/cc3200/serverstask.c
index 1305afda0..6b5899e18 100644
--- a/cc3200/serverstask.c
+++ b/cc3200/serverstask.c
@@ -29,7 +29,7 @@
#include "py/mpconfig.h"
#include "py/misc.h"
-#include "py/nlr.h"
+#include "py/runtime.h"
#include "py/mphal.h"
#include "serverstask.h"
#include "simplelink.h"
@@ -187,7 +187,7 @@ void servers_close_socket (int16_t *sd) {
void servers_set_login (char *user, char *pass) {
if (strlen(user) > SERVERS_USER_PASS_LEN_MAX || strlen(pass) > SERVERS_USER_PASS_LEN_MAX) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
memcpy(servers_user, user, SERVERS_USER_PASS_LEN_MAX);
memcpy(servers_pass, pass, SERVERS_USER_PASS_LEN_MAX);
@@ -196,7 +196,7 @@ void servers_set_login (char *user, char *pass) {
void servers_set_timeout (uint32_t timeout) {
if (timeout < SERVERS_MIN_TIMEOUT_MS) {
// timeout is too low
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
+ mp_raise_ValueError(mpexception_value_invalid_arguments);
}
servers_data.timeout = timeout;
}
diff --git a/conf.py b/conf.py
index 47dc20f59..bb2a2d897 100644
--- a/conf.py
+++ b/conf.py
@@ -69,7 +69,7 @@ copyright = '2014-2016, Damien P. George, Scott Shawcroft, Tony DiCola and other
# The short X.Y version.
version = '1.8'
# The full version, including alpha/beta/rc tags.
-release = '1.8.4'
+release = '1.8.5'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/library/machine.SPI.rst b/docs/library/machine.SPI.rst
index 73b3a3996..9b4d62e01 100644
--- a/docs/library/machine.SPI.rst
+++ b/docs/library/machine.SPI.rst
@@ -1,10 +1,13 @@
.. currentmodule:: machine
-class SPI -- a master-driven serial protocol
-============================================
+class SPI -- a Serial Peripheral Interface bus protocol
+=======================================================
-SPI is a serial protocol that is driven by a master. At the physical level
-there are 3 lines: SCK, MOSI, MISO.
+SPI is a serial protocol that is driven by a master. At the physical level,
+bus consistens of 3 lines: SCK, MOSI, MISO. Multiple devices can share the
+same bus. Each device should have a separate, 4th signal, SS (Slave Select),
+to select a particualr device on a bus with which communication takes place.
+Management of an SS signal should happen in user code (via machine.Pin class).
.. only:: port_wipy
@@ -21,65 +24,83 @@ there are 3 lines: SCK, MOSI, MISO.
Constructors
------------
-.. only:: port_wipy
+.. class:: SPI(id, ...)
- .. class:: SPI(id, ...)
+ Construct an SPI object on the given bus, ``id``. Values of ``id`` depend
+ on a particular port and its hardware. Values 0, 1, etc. are commonly used
+ to select hardware SPI block #0, #1, etc. Value -1 can be used for
+ bitbanging (software) implementation of SPI (if supported by a port).
- Construct an SPI object on the given bus. ``id`` can be only 0.
- With no additional parameters, the SPI object is created but not
- initialised (it has the settings from the last initialisation of
- the bus, if any). If extra arguments are given, the bus is initialised.
- See ``init`` for parameters of initialisation.
+ With no additional parameters, the SPI object is created but not
+ initialised (it has the settings from the last initialisation of
+ the bus, if any). If extra arguments are given, the bus is initialised.
+ See ``init`` for parameters of initialisation.
Methods
-------
-.. method:: SPI.init(mode, baudrate=1000000, \*, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, pins=(CLK, MOSI, MISO))
+.. method:: SPI.init(baudrate=1000000, \*, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, pins=(CLK, MOSI, MISO), sck=None, mosi=None, miso=None)
Initialise the SPI bus with the given parameters:
- - ``mode`` must be ``SPI.MASTER``.
- ``baudrate`` is the SCK clock rate.
- ``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`` is the width of each transfer, accepted values are 8, 16 and 32.
- - ``firstbit`` can be ``SPI.MSB`` only.
- - ``pins`` is an optional tuple with the pins to assign to the SPI bus.
+ - ``bits`` is the width in bits of each transfer. Only 8 of is guaranteed to be supported by all hardware.
+ - ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``.
+ - ``pins`` is an optional tuple with the pins to assign to the SPI bus (deprecated, only for WiPy).
+ - ``sck``, ``mosi``, ``miso`` are pins (machine.Pin) objects to use for bus signals. For most
+ hardware SPI blocks (as selected by ``id`` parameter to the constructore), pins are fixed
+ and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for
+ a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver
+ (``id``=-1).
.. method:: SPI.deinit()
Turn off the SPI bus.
-.. method:: SPI.write(buf)
+.. method:: SPI.read(nbytes, write=0x00)
+
+ Read a number of bytes specified by ``nbytes`` while continuously writing
+ the single byte given by ``write``.
+ Returns a ``bytes`` object with the data that was read.
+
+.. method:: SPI.readinto(buf, write=0x00)
- Write the data contained in ``buf``.
- Returns the number of bytes written.
+ Read into the buffer specified by ``buf`` while continuously writing the
+ single byte given by ``write``.
+ Returns ``None``.
-.. method:: SPI.read(nbytes, *, write=0x00)
+ Note: on WiPy this function returns the number of bytes read.
- Read the ``nbytes`` while writing the data specified by ``write``.
- Return the number of bytes read.
+.. method:: SPI.write(buf)
-.. method:: SPI.readinto(buf, *, write=0x00)
+ Write the bytes contained in ``buf``.
+ Returns ``None``.
- Read into the buffer specified by ``buf`` while writing the data specified by
- ``write``.
- Return the number of bytes read.
+ Note: on WiPy this function returns the number of bytes written.
.. method:: SPI.write_readinto(write_buf, read_buf)
- Write from ``write_buf`` and read into ``read_buf``. Both buffers must have the
+ Write the bytes from ``write_buf`` while reading into ``read_buf``. The
+ buffers can be the same or different, but both buffers must have the
same length.
- Returns the number of bytes written
+ Returns ``None``.
+
+ Note: on WiPy this function returns the number of bytes written.
Constants
---------
.. data:: SPI.MASTER
- for initialising the SPI bus to master
+ for initialising the SPI bus to master; this is only used for the WiPy
.. data:: SPI.MSB
set the first bit to be the most significant bit
+
+.. data:: SPI.LSB
+
+ set the first bit to be the least significant bit
diff --git a/docs/reference/constrained.rst b/docs/reference/constrained.rst
new file mode 100644
index 000000000..7c1b6a3eb
--- /dev/null
+++ b/docs/reference/constrained.rst
@@ -0,0 +1,456 @@
+.. _constrained:
+
+MicroPython on Microcontrollers
+===============================
+
+MicroPython is designed to be capable of running on microcontrollers. These
+have hardware limitations which may be unfamiliar to programmers more familiar
+with conventional computers. In particular the amount of RAM and nonvolatile
+"disk" (flash memory) storage is limited. This tutorial offers ways to make
+the most of the limited resources. Because MicroPython runs on controllers
+based on a variety of architectures, the methods presented are generic: in some
+cases it will be necessary to obtain detailed information from platform specific
+documentation.
+
+Flash Memory
+------------
+
+On the Pyboard the simple way to address the limited capacity is to fit a micro
+SD card. In some cases this is impractical, either because the device does not
+have an SD card slot or for reasons of cost or power consumption; hence the
+on-chip flash must be used. The firmware including the MicroPython subsystem is
+stored in the onboard flash. The remaining capacity is available for use. For
+reasons connected with the physical architecture of the flash memory part of
+this capacity may be inaccessible as a filesystem. In such cases this space may
+be employed by incorporating user modules into a firmware build which is then
+flashed to the device.
+
+There are two ways to achieve this: frozen modules and frozen bytecode. Frozen
+modules store the Python source with the firmware. Frozen bytecode uses the
+cross compiler to convert the source to bytecode which is then stored with the
+firmware. In either case the module may be accessed with an import statement:
+
+.. code::
+
+ import mymodule
+
+The procedure for producing frozen modules and bytecode is platform dependent;
+instructions for building the firmware can be found in the README files in the
+relevant part of the source tree.
+
+In general terms the steps are as follows:
+
+* Clone the MicroPython `repository <https://github.com/micropython/micropython>`_.
+* Acquire the (platform specific) toolchain to build the firmware.
+* Build the cross compiler.
+* Place the modules to be frozen in a specified directory (dependent on whether
+ the module is to be frozen as source or as bytecode).
+* Build the firmware. A specific command may be required to build frozen
+ code of either type - see the platform documentation.
+* Flash the firmware to the device.
+
+RAM
+---
+
+When reducing RAM usage there are two phases to consider: compilation and
+execution. In addition to memory consumption, there is also an issue known as
+heap fragmentation. In general terms it is best to minimise the repeated
+creation and destruction of objects. The reason for this is covered in the
+section covering the `heap`_.
+
+Compilation Phase
+~~~~~~~~~~~~~~~~~
+
+When a module is imported, MicroPython compiles the code to bytecode which is
+then executed by the MicroPython virtual machine (VM). The bytecode is stored
+in RAM. The compiler itself requires RAM, but this becomes available for use
+when the compilation has completed.
+
+If a number of modules have already been imported the situation can arise where
+there is insufficient RAM to run the compiler. In this case the import
+statement will produce a memory exception.
+
+If a module instantiates global objects on import it will consume RAM at the
+time of import, which is then unavailable for the compiler to use on subsequent
+imports. In general it is best to avoid code which runs on import; a better
+approach is to have initialisation code which is run by the application after
+all modules have been imported. This maximises the RAM available to the
+compiler.
+
+If RAM is still insufficient to compile all modules one solution is to
+precompile modules. MicroPython has a cross compiler capable of compiling Python
+modules to bytecode (see the README in the mpy-cross directory). The resulting
+bytecode file has a .mpy extension; it may be copied to the filesystem and
+imported in the usual way. Alternatively some or all modules may be implemented
+as frozen bytecode: on most platforms this saves even more RAM as the bytecode
+is run directly from flash rather than being stored in RAM.
+
+Execution Phase
+~~~~~~~~~~~~~~~
+
+There are a number of coding techniques for reducing RAM usage.
+
+**Constants**
+
+MicroPython provides a ``const`` keyword which may be used as follows:
+
+.. code::
+
+ from micropython import const
+ ROWS = const(33)
+ _COLS = const(0x10)
+ a = ROWS
+ b = _COLS
+
+In both instances where the constant is assigned to a variable the compiler
+will avoid coding a lookup to the name of the constant by substituting its
+literal value. This saves bytecode and hence RAM. However the ``ROWS`` value
+will occupy at least two machine words, one each for the key and value in the
+globals dictionary. The presence in the dictionary is necessary because another
+module might import or use it. This RAM can be saved by prepending the name
+with an underscore as in ``_COLS``: this symbol is not visible outside the
+module so will not occupy RAM.
+
+The argument to ``const()`` may be anything which, at compile time, evaluates
+to an integer e.g. ``0x100`` or ``1 << 8``. It can even include other const
+symbols that have already been defined, e.g. ``1 << BIT``.
+
+**Constant data structures**
+
+Where there is a substantial volume of constant data and the platform supports
+execution from Flash, RAM may be saved as follows. The data should be located in
+Python modules and frozen as bytecode. The data must be defined as ``bytes``
+objects. The compiler 'knows' that ``bytes`` objects are immutable and ensures
+that the objects remain in flash memory rather than being copied to RAM. The
+``ustruct`` module can assist in converting between ``bytes`` types and other
+Python built-in types.
+
+When considering the implications of frozen bytecode, note that in Python
+strings, floats, bytes, integers and complex numbers are immutable. Accordingly
+these will be frozen into flash. Thus, in the line
+
+.. code::
+
+ mystring = "The quick brown fox"
+
+the actual string "The quick brown fox" will reside in flash. At runtime a
+reference to the string is assigned to the *variable* ``mystring``. The reference
+occupies a single machine word. In principle a long integer could be used to
+store constant data:
+
+.. code::
+
+ bar = 0xDEADBEEF0000DEADBEEF
+
+As in the string example, at runtime a reference to the arbitrarily large
+integer is assigned to the variable ``bar``. That reference occupies a
+single machine word.
+
+It might be expected that tuples of integers could be employed for the purpose
+of storing constant data with minimal RAM use. With the current compiler this
+is ineffective (the code works, but RAM is not saved).
+
+.. code::
+
+ foo = (1, 2, 3, 4, 5, 6, 100000)
+
+At runtime the tuple will be located in RAM. This may be subject to future
+improvement.
+
+**Needless object creation**
+
+There are a number of situations where objects may unwittingly be created and
+destroyed. This can reduce the usability of RAM through fragmentation. The
+following sections discuss instances of this.
+
+**String concatenation**
+
+Consider the following code fragments which aim to produce constant strings:
+
+.. code::
+
+ var = "foo" + "bar"
+ var1 = "foo" "bar"
+ var2 = """\
+ foo\
+ bar"""
+
+Each produces the same outcome, however the first needlessly creates two string
+objects at runtime, allocates more RAM for concatenation before producing the
+third. The others perform the concatenation at compile time which is more
+efficient, reducing fragmentation.
+
+Where strings must be dynamically created before being fed to a stream such as
+a file it will save RAM if this is done in a piecemeal fashion. Rather than
+creating a large string object, create a substring and feed it to the stream
+before dealing with the next.
+
+The best way to create dynamic strings is by means of the string ``format``
+method:
+
+.. code::
+
+ var = "Temperature {:5.2f} Pressure {:06d}\n".format(temp, press)
+
+**Buffers**
+
+When accessing devices such as instances of UART, I2C and SPI interfaces, using
+pre-allocated buffers avoids the creation of needless objects. Consider these
+two loops:
+
+.. code::
+
+ while True:
+ var = spi.read(100)
+ # process data
+
+ buf = bytearray(100)
+ while True:
+ spi.readinto(buf)
+ # process data in buf
+
+The first creates a buffer on each pass whereas the second re-uses a pre-allocated
+buffer; this is both faster and more efficient in terms of memory fragmentation.
+
+**Bytes are smaller than ints**
+
+On most platforms an integer consumes four bytes. Consider the two calls to the
+function ``foo()``:
+
+.. code::
+
+ def foo(bar):
+ for x in bar:
+ print(x)
+ foo((1, 2, 0xff))
+ foo(b'\1\2\xff')
+
+In the first call a tuple of integers is created in RAM. The second efficiently
+creates a ``bytes`` object consuming the minimum amount of RAM. If the module
+were frozen as bytecode, the ``bytes`` object would reside in flash.
+
+**Strings Versus Bytes**
+
+Python3 introduced Unicode support. This introduced a distinction between a
+string and an array of bytes. MicroPython ensures that Unicode strings take no
+additional space so long as all characters in the string are ASCII (i.e. have
+a value < 126). If values in the full 8-bit range are required ``bytes`` and
+``bytearray`` objects can be used to ensure that no additional space will be
+required. Note that most string methods (e.g. ``strip()``) apply also to ``bytes``
+instances so the process of eliminating Unicode can be painless.
+
+.. code::
+
+ s = 'the quick brown fox' # A string instance
+ b = b'the quick brown fox' # a bytes instance
+
+Where it is necessary to convert between strings and bytes the string ``encode``
+and the bytes ``decode`` methods can be used. Note that both strings and bytes
+are immutable. Any operation which takes as input such an object and produces
+another implies at least one RAM allocation to produce the result. In the
+second line below a new bytes object is allocated. This would also occur if ``foo``
+were a string.
+
+.. code::
+
+ foo = b' empty whitespace'
+ foo = foo.lstrip()
+
+**Runtime compiler execution**
+
+The Python keywords ``eval`` and ``exec`` invoke the compiler at runtime, which
+requires significant amounts of RAM. Note that the ``pickle`` library employs
+``exec``. It may be more RAM efficient to use the ``json`` library for object
+serialisation.
+
+**Storing strings in flash**
+
+Python strings are immutable hence have the potential to be stored in read only
+memory. The compiler can place in flash strings defined in Python code. As with
+frozen modules it is necessary to have a copy of the source tree on the PC and
+the toolchain to build the firmware. The procedure will work even if the
+modules have not been fully debugged, so long as they can be imported and run.
+
+After importing the modules, execute:
+
+.. code::
+
+ micropython.qstr_info(1)
+
+Then copy and paste all the Q(xxx) lines into a text editor. Check for and
+remove lines which are obviously invalid. Open the file qstrdefsport.h which
+will be found in stmhal (or the equivalent directory for the architecture in
+use). Copy and paste the corrected lines at the end of the file. Save the file,
+rebuild and flash the firmware. The outcome can be checked by importing the
+modules and again issuing:
+
+.. code::
+
+ micropython.qstr_info(1)
+
+The Q(xxx) lines should be gone.
+
+.. _heap:
+
+The Heap
+--------
+
+When a running program instantiates an object the necessary RAM is allocated
+from a fixed size pool known as the heap. When the object goes out of scope (in
+other words becomes inaccessible to code) the redundant object is known as
+"garbage". A process known as "garbage collection" (GC) reclaims that memory,
+returning it to the free heap. This process runs automatically, however it can
+be invoked directly by issuing ``gc.collect()``.
+
+The discourse on this is somewhat involved. For a 'quick fix' issue the
+following periodically:
+
+.. code::
+
+ gc.collect()
+ gc.threshold(gc.mem_free() // 4 + gc.mem_alloc())
+
+Fragmentation
+~~~~~~~~~~~~~
+
+Say a program creates an object ``foo``, then an object ``bar``. Subsequently
+``foo`` goes out of scope but ``bar`` remains. The RAM used by ``foo`` will be
+reclaimed by GC. However if ``bar`` was allocated to a higher address, the
+RAM reclaimed from ``foo`` will only be of use for objects no bigger than
+``foo``. In a complex or long running program the heap can become fragmented:
+despite there being a substantial amount of RAM available, there is insufficient
+contiguous space to allocate a particular object, and the program fails with a
+memory error.
+
+The techniques outlined above aim to minimise this. Where large permanent buffers
+or other objects are required it is best to instantiate these early in the
+process of program execution before fragmentation can occur. Further improvements
+may be made by monitoring the state of the heap and by controlling GC; these are
+outlined below.
+
+Reporting
+~~~~~~~~~
+
+A number of library functions are available to report on memory allocation and
+to control GC. These are to be found in the ``gc`` and ``micropython`` modules.
+The following example may be pasted at the REPL (``ctrl e`` to enter paste mode,
+``ctrl d`` to run it).
+
+.. code::
+
+ import gc
+ import micropython
+ gc.collect()
+ micropython.mem_info()
+ print('-----------------------------')
+ print('Initial free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
+ def func():
+ a = bytearray(10000)
+ gc.collect()
+ print('Func definition: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
+ func()
+ print('Func run free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
+ gc.collect()
+ print('Garbage collect free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))
+ print('-----------------------------')
+ micropython.mem_info(1)
+
+Methods employed above:
+
+* ``gc.collect()`` Force a garbage collection. See footnote.
+* ``micropython.mem_info()`` Print a summary of RAM utilisation.
+* ``gc.mem_free()`` Return the free heap size in bytes.
+* ``gc.mem_alloc()`` Return the number of bytes currently allocated.
+* ``micropython.mem_info(1)`` Print a table of heap utilisation (detailed below).
+
+The numbers produced are dependent on the platform, but it can be seen that
+declaring the function uses a small amount of RAM in the form of bytecode
+emitted by the compiler (the RAM used by the compiler has been reclaimed).
+Running the function uses over 10KiB, but on return ``a`` is garbage because it
+is out of scope and cannot be referenced. The final ``gc.collect()`` recovers
+that memory.
+
+The final output produced by ``micropython.mem_info(1)`` will vary in detail but
+may be interpreted as follows:
+
+====== =================
+Symbol Meaning
+====== =================
+ . free block
+ h head block
+ = tail block
+ m marked head block
+ T tuple
+ L list
+ D dict
+ F float
+ B byte code
+ M module
+====== =================
+
+Each letter represents a single block of memory, a block being 16 bytes. So each
+line of the heap dump represents 0x400 bytes or 1KiB of RAM.
+
+Control of Garbage Collection
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A GC can be demanded at any time by issuing ``gc.collect()``. It is advantageous
+to do this at intervals, firstly to pre-empt fragmentation and secondly for
+performance. A GC can take several milliseconds but is quicker when there is
+little work to do (about 1ms on the Pyboard). An explicit call can minimise that
+delay while ensuring it occurs at points in the program when it is acceptable.
+
+Automatic GC is provoked under the following circumstances. When an attempt at
+allocation fails, a GC is performed and the allocation re-tried. Only if this
+fails is an exception raised. Secondly an automatic GC will be triggered if the
+amount of free RAM falls below a threshold. This threshold can be adapted as
+execution progresses:
+
+.. code::
+
+ gc.collect()
+ gc.threshold(gc.mem_free() // 4 + gc.mem_alloc())
+
+This will provoke a GC when more than 25% of the currently free heap becomes
+occupied.
+
+In general modules should instantiate data objects at runtime using constructors
+or other initialisation functions. The reason is that if this occurs on
+initialisation the compiler may be starved of RAM when subsequent modules are
+imported. If modules do instantiate data on import then ``gc.collect()`` issued
+after the import will ameliorate the problem.
+
+String Operations
+-----------------
+
+MicroPython handles strings in an efficient manner and understanding this can
+help in designing applications to run on microcontrollers. When a module
+is compiled, strings which occur multiple times are stored once only, a process
+known as string interning. In MicroPython an interned string is known as a ``qstr``.
+In a module imported normally that single instance will be located in RAM, but
+as described above, in modules frozen as bytecode it will be located in flash.
+
+String comparisons are also performed efficiently using hashing rather than
+character by character. The penalty for using strings rather than integers may
+hence be small both in terms of performance and RAM usage - a fact which may
+come as a surprise to C programmers.
+
+Postscript
+----------
+
+MicroPython passes, returns and (by default) copies objects by reference. A
+reference occupies a single machine word so these processes are efficient in
+RAM usage and speed.
+
+Where variables are required whose size is neither a byte nor a machine word
+there are standard libraries which can assist in storing these efficiently and
+in performing conversions. See the ``array``, ``ustruct`` and ``uctypes``
+modules.
+
+Footnote: gc.collect() return value
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+On Unix and Windows platforms the ``gc.collect()`` method returns an integer
+which signifies the number of distinct memory regions that were reclaimed in the
+collection (more precisely, the number of heads that were turned into frees). For
+efficiency reasons bare metal ports do not return this value.
diff --git a/docs/reference/index.rst b/docs/reference/index.rst
index ae8d6530a..7a85fc5cf 100644
--- a/docs/reference/index.rst
+++ b/docs/reference/index.rst
@@ -15,6 +15,7 @@ MicroPython are described in the sections here.
repl.rst
isr_rules.rst
speed_python.rst
+ constrained.rst
.. only:: port_pyboard
diff --git a/esp8266/Makefile b/esp8266/Makefile
index d86fec180..5f0044df0 100644
--- a/esp8266/Makefile
+++ b/esp8266/Makefile
@@ -7,19 +7,19 @@ MICROPY_PY_USSL = 1
MICROPY_SSL_AXTLS = 1
MICROPY_PY_BTREE = 1
+FROZEN_DIR = scripts
+FROZEN_MPY_DIR = modules
+
# include py core make definitions
include ../py/py.mk
MPY_CROSS = ../mpy-cross/mpy-cross
MPY_TOOL = ../tools/mpy-tool.py
-MAKE_FROZEN = ../tools/make-frozen.py
-FROZEN_DIR = scripts
-FROZEN_MPY_DIR = modules
PORT ?= /dev/ttyACM0
BAUD ?= 115200
FLASH_MODE ?= qio
-FLASH_SIZE ?= 8m
+FLASH_SIZE ?= detect
CROSS_COMPILE = xtensa-lx106-elf-
ESP_SDK = $(shell $(CC) -print-sysroot)/usr
@@ -66,6 +66,7 @@ SRC_C = \
main.c \
help.c \
esp_mphal.c \
+ esp_init_data.c \
gccollect.c \
lexerstr32.c \
uart.c \
@@ -90,7 +91,6 @@ SRC_C = \
modmachine.c \
modonewire.c \
ets_alt_task.c \
- $(BUILD)/frozen.c \
fatfs_port.c \
axtls_helpers.c \
hspi.c \
diff --git a/esp8266/esp8266.ld b/esp8266/esp8266.ld
index c726790d3..5fb6f1379 100644
--- a/esp8266/esp8266.ld
+++ b/esp8266/esp8266.ld
@@ -20,7 +20,7 @@ PHDRS
irom0_0_phdr PT_LOAD;
}
-ENTRY(call_user_start)
+ENTRY(firmware_start)
EXTERN(_DebugExceptionVector)
EXTERN(_DoubleExceptionVector)
EXTERN(_KernelExceptionVector)
@@ -130,8 +130,10 @@ SECTIONS
*stmhal/pybstdio.o(.literal*, .text*)
+ build/main.o(.literal* .text*)
*gccollect.o(.literal* .text*)
*gchelper.o(.literal* .text*)
+ *help.o(.literal* .text*)
*lexerstr32.o(.literal* .text*)
*utils.o(.literal* .text*)
*modpyb.o(.literal*, .text*)
@@ -141,6 +143,7 @@ SECTIONS
*modpybadc.o(.literal*, .text*)
*modpybuart.o(.literal*, .text*)
*modpybi2c.o(.literal*, .text*)
+ *modmachine.o(.literal*, .text*)
*modmachinewdt.o(.literal*, .text*)
*modpybspi.o(.literal*, .text*)
*modpybhspi.o(.literal*, .text*)
@@ -199,7 +202,8 @@ SECTIONS
*(.entry.text)
*(.init.literal)
*(.init)
- *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
+ *(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*)
+ *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
*(.fini)
*(.gnu.version)
diff --git a/esp8266/esp_init_data.c b/esp8266/esp_init_data.c
new file mode 100644
index 000000000..b229f751d
--- /dev/null
+++ b/esp8266/esp_init_data.c
@@ -0,0 +1,80 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Paul Sokolovsky
+ *
+ * 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 <stdio.h>
+#include "ets_sys.h"
+#include "etshal.h"
+#include "esp_mphal.h"
+#include "user_interface.h"
+#include "extmod/misc.h"
+
+uint32_t SPIRead(uint32_t offset, void *buf, uint32_t len);
+uint32_t SPIWrite(uint32_t offset, const void *buf, uint32_t len);
+uint32_t SPIEraseSector(int sector);
+NORETURN void call_user_start(void);
+void ets_printf(const char *fmt, ...);
+extern char flashchip;
+
+static const uint8_t default_init_data[] __attribute__((aligned(4))) = {
+0x05, 0x00, 0x04, 0x02, 0x05, 0x05, 0x05, 0x02, 0x05, 0x00, 0x04, 0x05, 0x05, 0x04, 0x05, 0x05,
+0x04, 0xfe, 0xfd, 0xff, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe1, 0x0a, 0xff, 0xff, 0xf8, 0x00,
+0xf8, 0xf8, 0x52, 0x4e, 0x4a, 0x44, 0x40, 0x38, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xe1, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x93, 0x43, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+void firmware_start(void) {
+ // For SDK 1.5.2, either address has shifted and not mirrored in
+ // eagle.rom.addr.v6.ld, or extra initial member was added.
+ SpiFlashChip *flash = (SpiFlashChip*)(&flashchip + 4);
+
+ char buf[128];
+ SPIRead(flash->chip_size - 4 * 0x1000, buf, sizeof(buf));
+ /*for (int i = 0; i < sizeof(buf); i++) {
+ static char hexf[] = "%x ";
+ ets_printf(hexf, buf[i]);
+ }*/
+
+ bool inited = false;
+ for (int i = 0; i < sizeof(buf); i++) {
+ if (buf[i] != 0xff) {
+ inited = true;
+ break;
+ }
+ }
+
+ if (!inited) {
+ static char msg[] = "Writing init data\n";
+ ets_printf(msg);
+ SPIRead((uint32_t)&default_init_data - 0x40200000, buf, sizeof(buf));
+ SPIWrite(flash->chip_size - 4 * 0x1000, buf, sizeof(buf));
+ }
+
+ asm("j call_user_start");
+}
diff --git a/esp8266/main.c b/esp8266/main.c
index c938dcb30..033ab7afe 100644
--- a/esp8266/main.c
+++ b/esp8266/main.c
@@ -141,7 +141,7 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
}
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
-void nlr_jump_fail(void *val) {
+void MP_FASTCODE(nlr_jump_fail)(void *val) {
printf("NLR jump failed\n");
for (;;) {
}
diff --git a/esp8266/modules/webrepl.py b/esp8266/modules/webrepl.py
index da3e70c59..b200f4fc8 100644
--- a/esp8266/modules/webrepl.py
+++ b/esp8266/modules/webrepl.py
@@ -31,6 +31,10 @@ def setup_conn(port, accept_handler):
def accept_conn(listen_sock):
global client_s
cl, remote_addr = listen_sock.accept()
+ if uos.dupterm():
+ print("\nConcurrent WebREPL connection from", remote_addr, "rejected")
+ cl.close()
+ return
print("\nWebREPL connection from:", remote_addr)
client_s = cl
websocket_helper.server_handshake(cl)
diff --git a/esp8266/modutime.c b/esp8266/modutime.c
index 4b94ace74..abfe069cc 100644
--- a/esp8266/modutime.c
+++ b/esp8266/modutime.c
@@ -38,6 +38,7 @@
#include "modpybrtc.h"
#include "timeutils.h"
#include "user_interface.h"
+#include "extmod/utime_mphal.h"
/// \module time - time related functions
///
@@ -99,53 +100,6 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
}
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
-/// \function sleep(seconds)
-/// Sleep for the given number of seconds.
-STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
- #if MICROPY_PY_BUILTINS_FLOAT
- mp_hal_delay_ms(1000 * mp_obj_get_float(seconds_o));
- #else
- mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o));
- #endif
- return mp_const_none;
-}
-MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
-
-STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) {
- mp_hal_delay_ms(mp_obj_get_int(arg));
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms);
-
-STATIC mp_obj_t time_sleep_us(mp_obj_t arg) {
- mp_hal_delay_us(mp_obj_get_int(arg));
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
-
-STATIC mp_obj_t time_ticks_ms(void) {
- return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
-
-STATIC mp_obj_t time_ticks_us(void) {
- return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
-
-STATIC mp_obj_t time_ticks_cpu(void) {
- return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
-
-STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) {
- // we assume that the arguments come from ticks_xx so are small ints
- uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
- uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
- return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
-
/// \function time()
/// Returns the number of seconds, as an integer, since 1/1/2000.
STATIC mp_obj_t time_time(void) {
@@ -159,13 +113,13 @@ STATIC const mp_map_elem_t time_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&mp_utime_sleep_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&mp_utime_sleep_ms_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&mp_utime_sleep_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&mp_utime_ticks_ms_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&mp_utime_ticks_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&mp_utime_ticks_cpu_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&mp_utime_ticks_diff_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
};
diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h
index 19cf9a679..602b3e9c8 100644
--- a/esp8266/mpconfigport.h
+++ b/esp8266/mpconfigport.h
@@ -9,6 +9,7 @@
#define MICROPY_ALLOC_PARSE_RULE_INC (8)
#define MICROPY_ALLOC_PARSE_RESULT_INC (8)
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (64)
+#define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_EMIT_X64 (0)
#define MICROPY_EMIT_THUMB (0)
#define MICROPY_EMIT_INLINE_THUMB (0)
@@ -17,6 +18,7 @@
#define MICROPY_DEBUG_PRINTER_DEST mp_debug_print
#define MICROPY_ENABLE_GC (1)
#define MICROPY_STACK_CHECK (1)
+#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
#define MICROPY_REPL_EVENT_DRIVEN (0)
#define MICROPY_REPL_AUTO_INDENT (1)
#define MICROPY_HELPER_REPL (1)
@@ -33,6 +35,7 @@
#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_BUILTINS_SET (1)
#define MICROPY_PY_BUILTINS_SLICE (1)
+#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
#define MICROPY_PY_BUILTINS_PROPERTY (1)
#define MICROPY_PY___FILE__ (0)
#define MICROPY_PY_GC (1)
@@ -49,6 +52,7 @@
#define MICROPY_PY_SYS_MAXSIZE (1)
#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_STDFILES (1)
+#define MICROPY_PY_SYS_STDIO_BUFFER (1)
#define MICROPY_PY_UERRNO (1)
#define MICROPY_PY_UBINASCII (1)
#define MICROPY_PY_UCTYPES (1)
@@ -58,6 +62,7 @@
#define MICROPY_PY_UJSON (1)
#define MICROPY_PY_URANDOM (1)
#define MICROPY_PY_URE (1)
+#define MICROPY_PY_UTIME_MP_HAL (1)
#define MICROPY_PY_UZLIB (1)
#define MICROPY_PY_LWIP (1)
#define MICROPY_PY_MACHINE (1)
@@ -177,4 +182,6 @@ extern const struct _mp_obj_module_t onewire_module;
#define MICROPY_HW_MCU_NAME "ESP8266"
#define MICROPY_PY_SYS_PLATFORM "esp8266"
+#define MP_FASTCODE(n) __attribute__((section(".iram0.text." #n))) n
+
#define _assert(expr) ((expr) ? (void)0 : __assert_func(__FILE__, __LINE__, __func__, #expr))
diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index d76e5eedd..e201b2399 100644
--- a/extmod/machine_i2c.c
+++ b/extmod/machine_i2c.c
@@ -272,7 +272,7 @@ STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
for (int addr = 0x08; addr < 0x78; ++addr) {
mp_hal_i2c_start(self);
- int ack = mp_hal_i2c_write_byte(self, (addr << 1) | 1);
+ int ack = mp_hal_i2c_write_byte(self, (addr << 1));
if (ack) {
mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr));
}
diff --git a/extmod/modujson.c b/extmod/modujson.c
index 0d0781e06..ca4e6df10 100644
--- a/extmod/modujson.c
+++ b/extmod/modujson.c
@@ -1,9 +1,9 @@
/*
- * This file is part of the Micro Python project, http://micropython.org/
+ * This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
- * Copyright (c) 2014 Damien P. George
+ * Copyright (c) 2014-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
@@ -28,8 +28,10 @@
#include "py/nlr.h"
#include "py/objlist.h"
+#include "py/objstringio.h"
#include "py/parsenum.h"
#include "py/runtime.h"
+#include "py/stream.h"
#if MICROPY_PY_UJSON
@@ -42,7 +44,7 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
-// This function implements a simple non-recursive JSON parser.
+// The function below implements a simple non-recursive JSON parser.
//
// The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt
// The parser here will parse any valid JSON and return the correct
@@ -52,13 +54,35 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
// input is outside it's specs.
//
// Most of the work is parsing the primitives (null, false, true, numbers,
-// strings). It does 1 pass over the input string and so is easily extended to
-// being able to parse from a non-seekable stream. It tries to be fast and
+// strings). It does 1 pass over the input stream. It tries to be fast and
// small in code size, while not using more RAM than necessary.
-STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
- mp_uint_t len;
- const char *s = mp_obj_str_get_data(obj, &len);
- const char *top = s + len;
+
+typedef struct _ujson_stream_t {
+ mp_obj_t stream_obj;
+ mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
+ int errcode;
+ byte cur;
+} ujson_stream_t;
+
+#define S_EOF (0) // null is not allowed in json stream so is ok as EOF marker
+#define S_END(s) ((s).cur == S_EOF)
+#define S_CUR(s) ((s).cur)
+#define S_NEXT(s) (ujson_stream_next(&(s)))
+
+STATIC byte ujson_stream_next(ujson_stream_t *s) {
+ mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode);
+ if (s->errcode != 0) {
+ mp_raise_OSError(s->errcode);
+ }
+ if (ret == 0) {
+ s->cur = S_EOF;
+ }
+ return s->cur;
+}
+
+STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
+ const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ);
+ ujson_stream_t s = {stream_obj, stream_p->read, 0, 0};
vstr_t vstr;
vstr_init(&vstr, 8);
mp_obj_list_t stack; // we use a list as a simple stack for nested JSON
@@ -67,41 +91,43 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
mp_obj_t stack_top = MP_OBJ_NULL;
mp_obj_type_t *stack_top_type = NULL;
mp_obj_t stack_key = MP_OBJ_NULL;
+ S_NEXT(s);
for (;;) {
cont:
- if (s == top) {
+ if (S_END(s)) {
break;
}
mp_obj_t next = MP_OBJ_NULL;
bool enter = false;
- switch (*s) {
+ byte cur = S_CUR(s);
+ S_NEXT(s);
+ switch (cur) {
case ',':
case ':':
case ' ':
case '\t':
case '\n':
case '\r':
- s += 1;
goto cont;
case 'n':
- if (s + 3 < top && s[1] == 'u' && s[2] == 'l' && s[3] == 'l') {
- s += 4;
+ if (S_CUR(s) == 'u' && S_NEXT(s) == 'l' && S_NEXT(s) == 'l') {
+ S_NEXT(s);
next = mp_const_none;
} else {
goto fail;
}
break;
case 'f':
- if (s + 4 < top && s[1] == 'a' && s[2] == 'l' && s[3] == 's' && s[4] == 'e') {
- s += 5;
+ if (S_CUR(s) == 'a' && S_NEXT(s) == 'l' && S_NEXT(s) == 's' && S_NEXT(s) == 'e') {
+ S_NEXT(s);
next = mp_const_false;
} else {
goto fail;
}
break;
case 't':
- if (s + 3 < top && s[1] == 'r' && s[2] == 'u' && s[3] == 'e') {
- s += 4;
+ if (S_CUR(s) == 'r' && S_NEXT(s) == 'u' && S_NEXT(s) == 'e') {
+ S_NEXT(s);
next = mp_const_true;
} else {
goto fail;
@@ -109,11 +135,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
break;
case '"':
vstr_reset(&vstr);
- for (s++; s < top && *s != '"';) {
- byte c = *s;
+ for (; !S_END(s) && S_CUR(s) != '"';) {
+ byte c = S_CUR(s);
if (c == '\\') {
- s++;
- c = *s;
+ c = S_NEXT(s);
switch (c) {
case 'b': c = 0x08; break;
case 'f': c = 0x0c; break;
@@ -121,10 +146,9 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
case 'r': c = 0x0d; break;
case 't': c = 0x09; break;
case 'u': {
- if (s + 4 >= top) { goto fail; }
mp_uint_t num = 0;
for (int i = 0; i < 4; i++) {
- c = (*++s | 0x20) - '0';
+ c = (S_NEXT(s) | 0x20) - '0';
if (c > 9) {
c -= ('a' - ('9' + 1));
}
@@ -137,27 +161,29 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
}
vstr_add_byte(&vstr, c);
str_cont:
- s++;
+ S_NEXT(s);
}
- if (s == top) {
+ if (S_END(s)) {
goto fail;
}
- s++;
+ S_NEXT(s);
next = mp_obj_new_str(vstr.buf, vstr.len, false);
break;
case '-':
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': {
bool flt = false;
vstr_reset(&vstr);
- for (; s < top; s++) {
- if (*s == '.' || *s == 'E' || *s == 'e') {
+ for (;;) {
+ vstr_add_byte(&vstr, cur);
+ cur = S_CUR(s);
+ if (cur == '.' || cur == 'E' || cur == 'e') {
flt = true;
- } else if (*s == '-' || unichar_isdigit(*s)) {
+ } else if (cur == '-' || unichar_isdigit(cur)) {
// pass
} else {
break;
}
- vstr_add_byte(&vstr, *s);
+ S_NEXT(s);
}
if (flt) {
next = mp_parse_num_decimal(vstr.buf, vstr.len, false, false, NULL);
@@ -169,16 +195,13 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
case '[':
next = mp_obj_new_list(0, NULL);
enter = true;
- s += 1;
break;
case '{':
next = mp_obj_new_dict(0);
enter = true;
- s += 1;
break;
case '}':
case ']': {
- s += 1;
if (stack_top == MP_OBJ_NULL) {
// no object at all
goto fail;
@@ -231,10 +254,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
}
success:
// eat trailing whitespace
- while (s < top && unichar_isspace(*s)) {
- s++;
+ while (unichar_isspace(S_CUR(s))) {
+ S_NEXT(s);
}
- if (s < top) {
+ if (!S_END(s)) {
// unexpected chars
goto fail;
}
@@ -248,11 +271,21 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
fail:
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "syntax error in JSON"));
}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
+
+STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
+ mp_uint_t len;
+ const char *buf = mp_obj_str_get_data(obj, &len);
+ vstr_t vstr = {len, len, (char*)buf, true};
+ mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0};
+ return mod_ujson_load(MP_OBJ_FROM_PTR(&sio));
+}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads);
STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) },
{ MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) },
+ { MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) },
{ MP_ROM_QSTR(MP_QSTR_loads), MP_ROM_PTR(&mod_ujson_loads_obj) },
};
diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c
index ddb7ba0fe..5a7a745d8 100644
--- a/extmod/modussl_mbedtls.c
+++ b/extmod/modussl_mbedtls.c
@@ -215,6 +215,16 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in
return MP_STREAM_ERROR;
}
+STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
+ // Currently supports only blocking mode
+ (void)self_in;
+ if (!mp_obj_is_true(flag_in)) {
+ mp_not_implemented("");
+ }
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
+
STATIC mp_obj_t socket_close(mp_obj_t self_in) {
mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in);
@@ -236,6 +246,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) },
};
diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c
new file mode 100644
index 000000000..3ecdc9446
--- /dev/null
+++ b/extmod/utime_mphal.c
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2016 Damien P. George
+ * Copyright (c) 2016 Paul Sokolovsky
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mpconfig.h"
+#if MICROPY_PY_UTIME_MP_HAL
+
+#include <string.h>
+
+#include "py/obj.h"
+#include "py/mphal.h"
+#include "py/smallint.h"
+#include "extmod/utime_mphal.h"
+
+STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
+ #if MICROPY_PY_BUILTINS_FLOAT
+ mp_hal_delay_ms(1000 * mp_obj_get_float(seconds_o));
+ #else
+ mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o));
+ #endif
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_obj, time_sleep);
+
+STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) {
+ mp_int_t ms = mp_obj_get_int(arg);
+ if (ms > 0) {
+ mp_hal_delay_ms(ms);
+ }
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_ms_obj, time_sleep_ms);
+
+STATIC mp_obj_t time_sleep_us(mp_obj_t arg) {
+ mp_int_t us = mp_obj_get_int(arg);
+ if (us > 0) {
+ mp_hal_delay_us(us);
+ }
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_us_obj, time_sleep_us);
+
+STATIC mp_obj_t time_ticks_ms(void) {
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_ms_obj, time_ticks_ms);
+
+STATIC mp_obj_t time_ticks_us(void) {
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_us_obj, time_ticks_us);
+
+STATIC mp_obj_t time_ticks_cpu(void) {
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj, time_ticks_cpu);
+
+STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) {
+ // we assume that the arguments come from ticks_xx so are small ints
+ uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
+ uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
+ return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
+}
+MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj, time_ticks_diff);
+
+#endif // MICROPY_PY_UTIME_MP_HAL
diff --git a/extmod/utime_mphal.h b/extmod/utime_mphal.h
new file mode 100644
index 000000000..4f2395a09
--- /dev/null
+++ b/extmod/utime_mphal.h
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2016 Damien P. George
+ * Copyright (c) 2016 Paul Sokolovsky
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/obj.h"
+
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_ms_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_us_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_ms_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_us_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_cpu_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_diff_obj);
diff --git a/extmod/uzlib/tinf.h b/extmod/uzlib/tinf.h
index 3545bbd88..106203a09 100644
--- a/extmod/uzlib/tinf.h
+++ b/extmod/uzlib/tinf.h
@@ -32,6 +32,7 @@ extern "C" {
#define TINF_DONE 1
#define TINF_DATA_ERROR (-3)
#define TINF_CHKSUM_ERROR (-4)
+#define TINF_DICT_ERROR (-5)
/* checksum types */
#define TINF_CHKSUM_NONE 0
diff --git a/extmod/uzlib/tinflate.c b/extmod/uzlib/tinflate.c
index 0e53f7f07..58850eb4a 100644
--- a/extmod/uzlib/tinflate.c
+++ b/extmod/uzlib/tinflate.c
@@ -361,6 +361,9 @@ static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
/* possibly get more bits from distance code */
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
if (d->dict_ring) {
+ if (offs > d->dict_size) {
+ return TINF_DICT_ERROR;
+ }
d->lzOff = d->dict_idx - offs;
if (d->lzOff < 0) {
d->lzOff += d->dict_size;
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 3a17533e4..6e827fc66 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -31,6 +31,7 @@
#include <string.h>
#include "py/nlr.h"
#include "py/runtime.h"
+#include "py/mperrno.h"
#include "lib/fatfs/ff.h"
#include "lib/fatfs/diskio.h"
#include "extmod/vfs_fat_file.h"
@@ -76,24 +77,42 @@ STATIC mp_obj_t fat_vfs_listdir_func(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_listdir_obj, 1, 2, fat_vfs_listdir_func);
-STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) {
- (void)vfs_in;
+STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t path_in, mp_int_t attr) {
const char *path = mp_obj_str_get_str(path_in);
- // TODO check that path is actually a file before trying to unlink it
- FRESULT res = f_unlink(path);
- if (res == FR_OK) {
+
+ FILINFO fno;
+#if _USE_LFN
+ fno.lfname = NULL;
+ fno.lfsize = 0;
+#endif
+ FRESULT res = f_stat(path, &fno);
+
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+
+ // check if path is a file or directory
+ if ((fno.fattrib & AM_DIR) == attr) {
+ res = f_unlink(path);
+
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
return mp_const_none;
} else {
- mp_raise_OSError(fresult_to_errno_table[res]);
+ mp_raise_OSError(attr ? MP_ENOTDIR : MP_EISDIR);
}
}
+
+STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) {
+ (void)vfs_in;
+ return fat_vfs_remove_internal(path_in, 0); // 0 == file attribute
+}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_remove_obj, fat_vfs_remove);
STATIC mp_obj_t fat_vfs_rmdir(mp_obj_t vfs_in, mp_obj_t path_in) {
- // TODO: Currently just redirects to fat_vfs_remove(), which are
- // backed by the same underlying FatFs function. Should at least
- // check that path is actually a dir.
- return fat_vfs_remove(vfs_in, path_in);
+ (void) vfs_in;
+ return fat_vfs_remove_internal(path_in, AM_DIR);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir);
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index ecc9ed70f..e269ef593 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -110,14 +110,20 @@ STATIC mp_uint_t file_obj_write(mp_obj_t self_in, const void *buf, mp_uint_t siz
STATIC mp_obj_t file_obj_flush(mp_obj_t self_in) {
pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in);
- f_sync(&self->fp);
+ FRESULT res = f_sync(&self->fp);
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(file_obj_flush_obj, file_obj_flush);
STATIC mp_obj_t file_obj_close(mp_obj_t self_in) {
pyb_file_obj_t *self = MP_OBJ_TO_PTR(self_in);
- f_close(&self->fp);
+ FRESULT res = f_close(&self->fp);
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close);
diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c
index bc540199d..f9bbf68a1 100644
--- a/lib/utils/pyexec.c
+++ b/lib/utils/pyexec.c
@@ -45,6 +45,7 @@
#include "genhdr/mpversion.h"
pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
+int pyexec_system_exit = 0;
STATIC bool repl_display_debugging_info = 0;
#define EXEC_FLAG_PRINT_EOF (1)
@@ -61,6 +62,9 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
int ret = 0;
uint32_t start = 0;
+ // by default a SystemExit exception returns 0
+ pyexec_system_exit = 0;
+
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t module_fun;
@@ -99,7 +103,7 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
// check for SystemExit
if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) {
// at the moment, the value of SystemExit is unused
- ret = PYEXEC_FORCED_EXIT;
+ ret = pyexec_system_exit;
} else {
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
ret = 0;
@@ -148,7 +152,7 @@ STATIC int pyexec_raw_repl_process_char(int c);
STATIC int pyexec_friendly_repl_process_char(int c);
void pyexec_event_repl_init(void) {
- MP_STATE_VM(repl_line) = vstr_new_size(32);
+ MP_STATE_VM(repl_line) = vstr_new(32);
repl.cont_line = false;
readline_init(MP_STATE_VM(repl_line), ">>> ");
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
diff --git a/lib/utils/pyexec.h b/lib/utils/pyexec.h
index e0f62440e..ae69a195e 100644
--- a/lib/utils/pyexec.h
+++ b/lib/utils/pyexec.h
@@ -33,6 +33,11 @@ typedef enum {
extern pyexec_mode_kind_t pyexec_mode_kind;
+// Set this to the value (eg PYEXEC_FORCED_EXIT) that will be propagated through
+// the pyexec functions if a SystemExit exception is raised by the running code.
+// It will reset to 0 at the start of each execution (eg each REPL entry).
+extern int pyexec_system_exit;
+
#define PYEXEC_FORCED_EXIT (0x100)
#define PYEXEC_SWITCH_MODE (0x200)
diff --git a/py/argcheck.c b/py/argcheck.c
index a6c769ee8..8cef10b16 100644
--- a/py/argcheck.c
+++ b/py/argcheck.c
@@ -37,8 +37,7 @@ void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_ar
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_arg_error_terse_mismatch();
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "function does not take keyword arguments"));
+ mp_raise_msg(&mp_type_TypeError, "function does not take keyword arguments");
}
}
@@ -116,8 +115,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n
mp_arg_error_terse_mismatch();
} else {
// TODO better error message
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "extra positional arguments given"));
+ mp_raise_msg(&mp_type_TypeError, "extra positional arguments given");
}
}
if (kws_found < kws->used) {
@@ -125,8 +123,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n
mp_arg_error_terse_mismatch();
} else {
// TODO better error message
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "extra keyword arguments given"));
+ mp_raise_msg(&mp_type_TypeError, "extra keyword arguments given");
}
}
}
@@ -139,7 +136,7 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args,
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || _MSC_VER
NORETURN void mp_arg_error_terse_mismatch(void) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "argument num/types mismatch"));
+ mp_raise_msg(&mp_type_TypeError, "argument num/types mismatch");
}
#endif
diff --git a/py/bc.c b/py/bc.c
index e5abea244..07de08fc3 100644
--- a/py/bc.c
+++ b/py/bc.c
@@ -185,7 +185,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, mp_obj_fun_bc_t *self, siz
}
// Didn't find name match with positional args
if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
+ mp_raise_msg(&mp_type_TypeError, "function does not take keyword arguments");
}
mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
continue2:;
@@ -234,8 +234,7 @@ continue2:;
} else {
// no keyword arguments given
if (n_kwonly_args != 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "function missing keyword-only argument"));
+ mp_raise_msg(&mp_type_TypeError, "function missing keyword-only argument");
}
if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
*var_pos_kw_args = mp_obj_new_dict(0);
diff --git a/py/builtinevex.c b/py/builtinevex.c
index 74c43b176..636f86930 100644
--- a/py/builtinevex.c
+++ b/py/builtinevex.c
@@ -95,7 +95,7 @@ STATIC mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) {
case MP_QSTR_exec: parse_input_kind = MP_PARSE_FILE_INPUT; break;
case MP_QSTR_eval: parse_input_kind = MP_PARSE_EVAL_INPUT; break;
default:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad compile mode"));
+ mp_raise_msg(&mp_type_ValueError, "bad compile mode");
}
mp_obj_code_t *code = m_new_obj(mp_obj_code_t);
diff --git a/py/builtinimport.c b/py/builtinimport.c
index e4199f25d..e72eaf472 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -138,7 +138,7 @@ STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex, const char
if (lex == NULL) {
// we verified the file exists using stat, but lexer could still fail
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found"));
+ mp_raise_msg(&mp_type_ImportError, "module not found");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
"no module named '%s'", fname));
@@ -340,7 +340,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
DEBUG_printf("Warning: no dots in current module name and level>0\n");
p = this_name + this_name_l;
} else if (level != -1) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "Invalid relative import"));
+ mp_raise_msg(&mp_type_ImportError, "invalid relative import");
}
uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len);
@@ -355,7 +355,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q));
if (new_mod_q == MP_QSTR_) {
// CPython raises SystemError
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "cannot perform relative import"));
+ mp_raise_msg(&mp_type_ImportError, "cannot perform relative import");
}
module_name = MP_OBJ_NEW_QSTR(new_mod_q);
mod_str = new_mod;
@@ -425,7 +425,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
#endif
// couldn't find the file, so fail
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found"));
+ mp_raise_msg(&mp_type_ImportError, "module not found");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
"no module named '%q'", mod_name));
diff --git a/py/compile.c b/py/compile.c
index 0ea8a3c15..f84d5e214 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -2723,15 +2723,8 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
EMIT_ARG(set_source_line, pns->source_line);
compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)];
- if (f == NULL) {
-#if MICROPY_DEBUG_PRINTERS
- printf("node %u cannot be compiled\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns));
- mp_parse_node_print(pn, 0);
-#endif
- compile_syntax_error(comp, pn, "internal compiler error");
- } else {
- f(comp, pns);
- }
+ assert(f != NULL);
+ f(comp, pns);
}
}
@@ -2836,12 +2829,10 @@ STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn)
// no annotation
return;
}
- } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star) {
+ } else {
+ assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star);
// double star with possible annotation
// fallthrough
- } else {
- // no annotation
- return;
}
mp_parse_node_t pn_annotation = pns->nodes[1];
diff --git a/py/emitglue.c b/py/emitglue.c
index 2bfc4ad82..c81387fd4 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -425,7 +425,7 @@ mp_raw_code_t *mp_raw_code_load_file(const char *filename) {
return rc;
}
-#elif defined(__thumb2__) || defined(__thumb__)
+#elif defined(__thumb2__) || defined(__thumb__) || defined(__xtensa__)
// fatfs file reader (assume thumb2 arch uses fatfs...)
#include "lib/fatfs/ff.h"
diff --git a/py/lexer.c b/py/lexer.c
index b2c9c5ff7..4a7c8f580 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -343,7 +343,6 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, bool first_token) {
lex->tok_kind = MP_TOKEN_NEWLINE;
mp_uint_t num_spaces = lex->column - 1;
- lex->emit_dent = 0;
if (num_spaces == indent_top(lex)) {
} else if (num_spaces > indent_top(lex)) {
indent_push(lex, num_spaces);
@@ -359,16 +358,7 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, bool first_token) {
}
} else if (is_end(lex)) {
- if (indent_top(lex) > 0) {
- lex->tok_kind = MP_TOKEN_NEWLINE;
- lex->emit_dent = 0;
- while (indent_top(lex) > 0) {
- indent_pop(lex);
- lex->emit_dent -= 1;
- }
- } else {
- lex->tok_kind = MP_TOKEN_END;
- }
+ lex->tok_kind = MP_TOKEN_END;
} else if (is_char_or(lex, '\'', '\"')
|| (is_char_or3(lex, 'r', 'u', 'b') && is_char_following_or(lex, '\'', '\"'))
diff --git a/py/misc.h b/py/misc.h
index 3ed227a35..e60665e59 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -151,8 +151,7 @@ void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf);
struct _mp_print_t;
void vstr_init_print(vstr_t *vstr, size_t alloc, struct _mp_print_t *print);
void vstr_clear(vstr_t *vstr);
-vstr_t *vstr_new(void);
-vstr_t *vstr_new_size(size_t alloc);
+vstr_t *vstr_new(size_t alloc);
void vstr_free(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; }
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index 29f84d6c2..57e52efa5 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -178,7 +178,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
str[3] = (c & 0x3F) | 0x80;
len = 4;
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "chr() arg not in range(0x110000)"));
+ mp_raise_msg(&mp_type_ValueError, "chr() arg not in range(0x110000)");
}
return mp_obj_new_str(str, len, true);
#else
@@ -187,7 +187,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
char str[1] = {ord};
return mp_obj_new_str(str, 1, true);
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "chr() arg not in range(256)"));
+ mp_raise_msg(&mp_type_ValueError, "chr() arg not in range(256)");
}
#endif
}
@@ -286,7 +286,7 @@ STATIC mp_obj_t mp_builtin_min_max(size_t n_args, const mp_obj_t *args, mp_map_t
if (default_elem != NULL) {
best_obj = default_elem->value;
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "arg is an empty sequence"));
+ mp_raise_msg(&mp_type_ValueError, "arg is an empty sequence");
}
}
return best_obj;
@@ -507,8 +507,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum);
STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
if (n_args > 1) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "must use keyword argument for key function"));
+ mp_raise_msg(&mp_type_TypeError, "must use keyword argument for key function");
}
mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args);
mp_obj_list_sort(1, &self, kwargs);
diff --git a/py/modmicropython.c b/py/modmicropython.c
index f7d74db2e..675d169cc 100644
--- a/py/modmicropython.c
+++ b/py/modmicropython.c
@@ -34,6 +34,16 @@
// Various builtins specific to MicroPython runtime,
// living in micropython module
+STATIC mp_obj_t mp_micropython_opt_level(size_t n_args, const mp_obj_t *args) {
+ if (n_args == 0) {
+ return MP_OBJ_NEW_SMALL_INT(MP_STATE_VM(mp_optimise_value));
+ } else {
+ MP_STATE_VM(mp_optimise_value) = mp_obj_get_int(args[0]);
+ return mp_const_none;
+ }
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_micropython_opt_level_obj, 0, 1, mp_micropython_opt_level);
+
#if MICROPY_PY_MICROPYTHON_MEM_INFO
#if MICROPY_MEM_STATS
@@ -121,6 +131,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_alloc_emergency_exception_buf_obj, mp_alloc_
STATIC const mp_rom_map_elem_t mp_module_micropython_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_micropython) },
{ MP_ROM_QSTR(MP_QSTR_const), MP_ROM_PTR(&mp_identity_obj) },
+ { MP_ROM_QSTR(MP_QSTR_opt_level), MP_ROM_PTR(&mp_micropython_opt_level_obj) },
#if MICROPY_PY_MICROPYTHON_MEM_INFO
#if MICROPY_MEM_STATS
{ MP_ROM_QSTR(MP_QSTR_mem_total), MP_ROM_PTR(&mp_micropython_mem_total_obj) },
diff --git a/py/modthread.c b/py/modthread.c
index c358cdf9e..6f55281ad 100644
--- a/py/modthread.c
+++ b/py/modthread.c
@@ -239,7 +239,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args)
} else {
// positional and keyword arguments
if (mp_obj_get_type(args[2]) != &mp_type_dict) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "expecting a dict for keyword args"));
+ mp_raise_msg(&mp_type_TypeError, "expecting a dict for keyword args");
}
mp_map_t *map = &((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[2]))->map;
th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used);
diff --git a/py/mpconfig.h b/py/mpconfig.h
index e33a41f7a..dcdaffe0f 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -860,6 +860,12 @@ typedef double mp_float_t;
#define MICROPY_PY_UERRNO (0)
#endif
+// Whether to provide "utime" module functions implementation
+// in terms of mp_hal_* functions.
+#ifndef MICROPY_PY_UTIME_MP_HAL
+#define MICROPY_PY_UTIME_MP_HAL (0)
+#endif
+
// Whether to provide "_thread" module
#ifndef MICROPY_PY_THREAD
#define MICROPY_PY_THREAD (0)
diff --git a/py/mphal.h b/py/mphal.h
index 54a45b024..8d5654f9e 100644
--- a/py/mphal.h
+++ b/py/mphal.h
@@ -66,6 +66,10 @@ mp_uint_t mp_hal_ticks_ms(void);
mp_uint_t mp_hal_ticks_us(void);
#endif
+#ifndef mp_hal_ticks_cpu
+mp_uint_t mp_hal_ticks_cpu(void);
+#endif
+
// If port HAL didn't define its own pin API, use generic
// "virtual pin" API from the core.
#ifndef mp_hal_pin_obj_t
diff --git a/py/mpprint.c b/py/mpprint.c
index 97ea33ad2..9ad0f3f9a 100644
--- a/py/mpprint.c
+++ b/py/mpprint.c
@@ -252,8 +252,8 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char
// enough, a dynamic one will be allocated.
char stack_buf[sizeof(mp_int_t) * 4];
char *buf = stack_buf;
- mp_uint_t buf_size = sizeof(stack_buf);
- mp_uint_t fmt_size = 0;
+ size_t buf_size = sizeof(stack_buf);
+ size_t fmt_size = 0;
char *str;
if (prec > 1) {
diff --git a/py/mpz.c b/py/mpz.c
index bb7647956..cceb079cd 100644
--- a/py/mpz.c
+++ b/py/mpz.c
@@ -645,18 +645,6 @@ STATIC void mpn_div(mpz_dig_t *num_dig, mp_uint_t *num_len, const mpz_dig_t *den
#define MIN_ALLOC (2)
-STATIC const uint8_t log_base2_floor[] = {
- 0,
- 0, 1, 1, 2,
- 2, 2, 2, 3,
- 3, 3, 3, 3,
- 3, 3, 3, 4,
- 4, 4, 4, 4,
- 4, 4, 4, 4,
- 4, 4, 4, 4,
- 4, 4, 4, 5
-};
-
void mpz_init_zero(mpz_t *z) {
z->neg = 0;
z->fixed_dig = 0;
@@ -734,11 +722,9 @@ STATIC void mpz_need_dig(mpz_t *z, mp_uint_t need) {
}
if (z->dig == NULL || z->alloc < need) {
- if (z->fixed_dig) {
- // cannot reallocate fixed buffers
- assert(0);
- return;
- }
+ // if z has fixed digit buffer there's not much we can do as the caller will
+ // be expecting a buffer with at least "need" bytes (but it shouldn't happen)
+ assert(!z->fixed_dig);
z->dig = m_renew(mpz_dig_t, z->dig, z->alloc, need);
z->alloc = need;
}
@@ -1497,13 +1483,10 @@ mpz_t *mpz_lcm(const mpz_t *z1, const mpz_t *z2) {
quo * rhs + rem = lhs
0 <= rem < rhs
can have lhs, rhs the same
+ assumes rhs != 0 (undefined behaviour if it is)
*/
void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs) {
- if (rhs->len == 0) {
- mpz_set_from_int(dest_quo, 0);
- mpz_set_from_int(dest_rem, 0);
- return;
- }
+ assert(!mpz_is_zero(rhs));
mpz_need_dig(dest_quo, lhs->len + 1); // +1 necessary?
memset(dest_quo->dig, 0, (lhs->len + 1) * sizeof(mpz_dig_t));
@@ -1657,18 +1640,6 @@ mp_float_t mpz_as_float(const mpz_t *i) {
}
#endif
-mp_uint_t mpz_as_str_size(const mpz_t *i, mp_uint_t base, const char *prefix, char comma) {
- if (base < 2 || base > 32) {
- return 0;
- }
-
- mp_uint_t num_digits = i->len * DIG_SIZE / log_base2_floor[base] + 1;
- mp_uint_t num_commas = comma ? num_digits / 3: 0;
- mp_uint_t prefix_len = prefix ? strlen(prefix) : 0;
-
- return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte
-}
-
#if 0
this function is unused
char *mpz_as_str(const mpz_t *i, mp_uint_t base) {
@@ -1678,7 +1649,7 @@ char *mpz_as_str(const mpz_t *i, mp_uint_t base) {
}
#endif
-// assumes enough space as calculated by mpz_as_str_size
+// assumes enough space as calculated by mp_int_format_size
// returns length of string, not including null byte
mp_uint_t mpz_as_str_inpl(const mpz_t *i, mp_uint_t base, const char *prefix, char base_char, char comma, char *str) {
if (str == NULL || base < 2 || base > 32) {
diff --git a/py/mpz.h b/py/mpz.h
index 63ac772ff..55ef3e15f 100644
--- a/py/mpz.h
+++ b/py/mpz.h
@@ -127,6 +127,7 @@ void mpz_or_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs);
void mpz_xor_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs);
void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs);
+static inline size_t mpz_max_num_bits(const mpz_t *z) { return z->len * MPZ_DIG_SIZE; }
mp_int_t mpz_hash(const mpz_t *z);
bool mpz_as_int_checked(const mpz_t *z, mp_int_t *value);
bool mpz_as_uint_checked(const mpz_t *z, mp_uint_t *value);
diff --git a/py/obj.c b/py/obj.c
index d6ce3dae6..72b7a216b 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -233,8 +233,7 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) {
return mp_obj_int_get_checked(arg);
} else {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "can't convert to int"));
+ mp_raise_msg(&mp_type_TypeError, "can't convert to int");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"can't convert %s to int", mp_obj_get_type_str(arg)));
@@ -282,8 +281,7 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) {
return mp_obj_float_get(arg);
} else {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "can't convert to float"));
+ mp_raise_msg(&mp_type_TypeError, "can't convert to float");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"can't convert %s to float", mp_obj_get_type_str(arg)));
@@ -312,8 +310,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
mp_obj_complex_get(arg, real, imag);
} else {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "can't convert to complex"));
+ mp_raise_msg(&mp_type_TypeError, "can't convert to complex");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"can't convert %s to complex", mp_obj_get_type_str(arg)));
@@ -331,8 +328,7 @@ void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) {
mp_obj_list_get(o, len, items);
} else {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "expected tuple/list"));
+ mp_raise_msg(&mp_type_TypeError, "expected tuple/list");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"object '%s' is not a tuple or list", mp_obj_get_type_str(o)));
@@ -346,8 +342,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items) {
mp_obj_get_array(o, &seq_len, items);
if (seq_len != len) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
- "tuple/list has wrong length"));
+ mp_raise_msg(&mp_type_ValueError, "tuple/list has wrong length");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"requested length %d but object has length %d", (int)len, (int)seq_len));
@@ -362,8 +357,7 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index,
i = MP_OBJ_SMALL_INT_VALUE(index);
} else if (!mp_obj_get_int_maybe(index, &i)) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "indices must be integers"));
+ mp_raise_msg(&mp_type_TypeError, "indices must be integers");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"%q indices must be integers, not %s",
@@ -383,7 +377,7 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index,
} else {
if (i < 0 || (mp_uint_t)i >= len) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "index out of range"));
+ mp_raise_msg(&mp_type_IndexError, "index out of range");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError,
"%q index out of range", type->name));
@@ -416,8 +410,7 @@ mp_obj_t mp_obj_len(mp_obj_t o_in) {
mp_obj_t len = mp_obj_len_maybe(o_in);
if (len == MP_OBJ_NULL) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object has no len"));
+ mp_raise_msg(&mp_type_TypeError, "object has no len");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
@@ -458,8 +451,7 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
}
if (value == MP_OBJ_NULL) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object does not support item deletion"));
+ mp_raise_msg(&mp_type_TypeError, "object does not support item deletion");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object does not support item deletion", mp_obj_get_type_str(base)));
@@ -474,8 +466,7 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
}
} else {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object does not support item assignment"));
+ mp_raise_msg(&mp_type_TypeError, "object does not support item assignment");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object does not support item assignment", mp_obj_get_type_str(base)));
@@ -504,7 +495,7 @@ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
if (!mp_get_buffer(obj, bufinfo, flags)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "object with buffer protocol required"));
+ mp_raise_msg(&mp_type_TypeError, "object with buffer protocol required");
}
}
diff --git a/py/objarray.c b/py/objarray.c
index 2cd0fef6b..8e1d32f0f 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -95,7 +95,7 @@ STATIC void array_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
STATIC mp_obj_array_t *array_new(char typecode, mp_uint_t n) {
int typecode_size = mp_binary_get_size('@', typecode, NULL);
if (typecode_size == 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad typecode"));
+ mp_raise_msg(&mp_type_ValueError, "bad typecode");
}
mp_obj_array_t *o = m_new_obj(mp_obj_array_t);
#if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_PY_ARRAY
@@ -395,7 +395,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value);
if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {
compat_error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "lhs and rhs should be compatible"));
+ mp_raise_msg(&mp_type_ValueError, "lhs and rhs should be compatible");
}
src_len = src_slice->len;
src_items = src_slice->items;
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 5da655eb3..96be25255 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -197,7 +197,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t
case MP_BINARY_OP_INPLACE_TRUE_DIVIDE:
if (rhs_imag == 0) {
if (rhs_real == 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "complex division by zero"));
+ mp_raise_msg(&mp_type_ZeroDivisionError, "complex division by zero");
}
lhs_real /= rhs_real;
lhs_imag /= rhs_real;
@@ -226,7 +226,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t
lhs_real = 1;
rhs_real = 0;
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power"));
+ mp_raise_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power");
}
} else {
mp_float_t ln1 = MICROPY_FLOAT_C_FUN(log)(abs1);
diff --git a/py/objdict.c b/py/objdict.c
index 7a74557dc..4942d3779 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -162,7 +162,7 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) {
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP);
if (elem == NULL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "<value>"));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_KeyError, index));
} else {
return elem->value;
}
@@ -178,7 +178,7 @@ STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP);
if (elem == NULL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "<value>"));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_KeyError, index));
} else {
return elem->value;
}
@@ -250,15 +250,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_copy_obj, dict_copy);
// this is a classmethod
STATIC mp_obj_t dict_fromkeys(size_t n_args, const mp_obj_t *args) {
mp_obj_t iter = mp_getiter(args[1]);
- mp_obj_t len = mp_obj_len_maybe(iter);
mp_obj_t value = mp_const_none;
mp_obj_t next = MP_OBJ_NULL;
- mp_obj_t self_out;
if (n_args > 2) {
value = args[2];
}
+ // optimisation to allocate result based on len of argument
+ mp_obj_t self_out;
+ mp_obj_t len = mp_obj_len_maybe(args[1]);
if (len == MP_OBJ_NULL) {
/* object's type doesn't have a __len__ slot */
self_out = mp_obj_new_dict(0);
@@ -282,7 +283,7 @@ STATIC mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp
if (elem == NULL || elem->value == MP_OBJ_NULL) {
if (deflt == MP_OBJ_NULL) {
if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "<value>"));
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_KeyError, key));
} else {
value = mp_const_none;
}
@@ -342,7 +343,7 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) {
mp_uint_t cur = 0;
mp_map_elem_t *next = dict_iter_next(self, &cur);
if (next == NULL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "popitem(): dictionary is empty"));
+ mp_raise_msg(&mp_type_KeyError, "popitem(): dictionary is empty");
}
self->map.used--;
mp_obj_t items[] = {next->key, next->value};
@@ -384,9 +385,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg
if (key == MP_OBJ_STOP_ITERATION
|| value == MP_OBJ_STOP_ITERATION
|| stop != MP_OBJ_STOP_ITERATION) {
- nlr_raise(mp_obj_new_exception_msg(
- &mp_type_ValueError,
- "dictionary update sequence has the wrong length"));
+ mp_raise_msg(&mp_type_ValueError, "dictionary update sequence has the wrong length");
} else {
mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
}
diff --git a/py/objfloat.c b/py/objfloat.c
index 85b8b1386..73d07feac 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -198,7 +198,7 @@ mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs_i
case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE:
if (rhs_val == 0) {
zero_division_error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero"));
+ mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero");
}
// Python specs require that x == (x//y)*y + (x%y) so we must
// call divmod to compute the correct floor division, which
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 8c32a3649..cbef9fea3 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -105,7 +105,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
}
if (self->code_state.sp == self->code_state.state - 1) {
if (send_value != mp_const_none) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "can't send non-None value to a just-started generator"));
+ mp_raise_msg(&mp_type_TypeError, "can't send non-None value to a just-started generator");
}
} else {
*self->code_state.sp = send_value;
@@ -157,7 +157,7 @@ STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_o
case MP_VM_RETURN_YIELD:
if (throw_value != MP_OBJ_NULL && mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(throw_value)), MP_OBJ_FROM_PTR(&mp_type_GeneratorExit))) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit"));
+ mp_raise_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit");
}
return ret;
@@ -209,7 +209,7 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) {
mp_obj_t ret;
switch (mp_obj_gen_resume(self_in, mp_const_none, MP_OBJ_FROM_PTR(&mp_const_GeneratorExit_obj), &ret)) {
case MP_VM_RETURN_YIELD:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit"));
+ mp_raise_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit");
// Swallow StopIteration & GeneratorExit (== successful close), and re-raise any other
case MP_VM_RETURN_EXCEPTION:
diff --git a/py/objint.c b/py/objint.c
index 9f948a145..f8988d6c9 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -133,8 +133,8 @@ void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
// enough, a dynamic one will be allocated.
char stack_buf[sizeof(mp_int_t) * 4];
char *buf = stack_buf;
- mp_uint_t buf_size = sizeof(stack_buf);
- mp_uint_t fmt_size;
+ size_t buf_size = sizeof(stack_buf);
+ size_t fmt_size;
char *str = mp_obj_int_formatted(&buf, &buf_size, &fmt_size, self_in, 10, NULL, '\0', '\0');
mp_print_str(print, str);
@@ -162,14 +162,14 @@ STATIC const uint8_t log_base2_floor[] = {
4, 4, 4, 5
};
-STATIC uint int_as_str_size_formatted(uint base, const char *prefix, char comma) {
+size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma) {
if (base < 2 || base > 32) {
return 0;
}
- uint num_digits = sizeof(fmt_int_t) * 8 / log_base2_floor[base] + 1;
- uint num_commas = comma ? num_digits / 3: 0;
- uint prefix_len = prefix ? strlen(prefix) : 0;
+ size_t num_digits = num_bits / log_base2_floor[base] + 1;
+ size_t num_commas = comma ? num_digits / 3 : 0;
+ size_t prefix_len = prefix ? strlen(prefix) : 0;
return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte
}
@@ -180,7 +180,7 @@ STATIC uint int_as_str_size_formatted(uint base, const char *prefix, char comma)
//
// The resulting formatted string will be returned from this function and the
// formatted size will be in *fmt_size.
-char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in,
+char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
int base, const char *prefix, char base_char, char comma) {
fmt_int_t num;
if (MP_OBJ_IS_SMALL_INT(self_in)) {
@@ -211,7 +211,7 @@ char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size,
sign = '-';
}
- uint needed_size = int_as_str_size_formatted(base, prefix, comma);
+ size_t needed_size = mp_int_format_size(sizeof(fmt_int_t) * 8, base, prefix, comma);
if (needed_size > *buf_size) {
*buf = m_new(char, needed_size);
*buf_size = needed_size;
@@ -294,19 +294,19 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
// This is called only with strings whose value doesn't fit in SMALL_INT
mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "long int not supported in this build"));
+ mp_raise_msg(&mp_type_OverflowError, "long int not supported in this build");
return mp_const_none;
}
// This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT)
mp_obj_t mp_obj_new_int_from_ll(long long val) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
+ mp_raise_msg(&mp_type_OverflowError, "small int overflow");
return mp_const_none;
}
// This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT)
mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
+ mp_raise_msg(&mp_type_OverflowError, "small int overflow");
return mp_const_none;
}
@@ -316,7 +316,7 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) {
if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) {
return MP_OBJ_NEW_SMALL_INT(value);
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
+ mp_raise_msg(&mp_type_OverflowError, "small int overflow");
return mp_const_none;
}
@@ -342,7 +342,7 @@ mp_obj_t mp_obj_new_int(mp_int_t value) {
if (MP_SMALL_INT_FITS(value)) {
return MP_OBJ_NEW_SMALL_INT(value);
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
+ mp_raise_msg(&mp_type_OverflowError, "small int overflow");
return mp_const_none;
}
diff --git a/py/objint.h b/py/objint.h
index c79eb874a..6e627f1bd 100644
--- a/py/objint.h
+++ b/py/objint.h
@@ -50,13 +50,15 @@ typedef enum {
mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val);
#endif // MICROPY_PY_BUILTINS_FLOAT
+size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma);
+
void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
-char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in,
+char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
int base, const char *prefix, char base_char, char comma);
-char *mp_obj_int_formatted_impl(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in,
+char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
int base, const char *prefix, char base_char, char comma);
mp_int_t mp_obj_int_hash(mp_obj_t self_in);
-void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, mp_uint_t len, byte *buf);
+void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf);
int mp_obj_int_sign(mp_obj_t self_in);
mp_obj_t mp_obj_int_abs(mp_obj_t self_in);
mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in);
diff --git a/py/objint_longlong.c b/py/objint_longlong.c
index f10e46447..b051cfbe6 100644
--- a/py/objint_longlong.c
+++ b/py/objint_longlong.c
@@ -53,7 +53,7 @@
const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX};
#endif
-void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, mp_uint_t len, byte *buf) {
+void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int));
mp_obj_int_t *self = self_in;
long long val = self->val;
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index 3a30eb9d9..0a1d68598 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -90,12 +90,12 @@ STATIC mp_obj_int_t *mp_obj_int_new_mpz(void) {
// formatted size will be in *fmt_size.
//
// This particular routine should only be called for the mpz representation of the int.
-char *mp_obj_int_formatted_impl(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in,
+char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in,
int base, const char *prefix, char base_char, char comma) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int));
const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
- mp_uint_t needed_size = mpz_as_str_size(&self->mpz, base, prefix, comma);
+ size_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma);
if (needed_size > *buf_size) {
*buf = m_new(char, needed_size);
*buf_size = needed_size;
@@ -107,7 +107,7 @@ char *mp_obj_int_formatted_impl(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_
return str;
}
-void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, mp_uint_t len, byte *buf) {
+void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int));
mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
mpz_as_bytes(&self->mpz, big_endian, len, buf);
@@ -234,8 +234,7 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: {
if (mpz_is_zero(zrhs)) {
zero_division_error:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError,
- "division by zero"));
+ mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero");
}
mpz_t rem; mpz_init_zero(&rem);
mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs);
@@ -272,7 +271,7 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
case MP_BINARY_OP_INPLACE_RSHIFT: {
mp_int_t irhs = mp_obj_int_get_checked(rhs_in);
if (irhs < 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count"));
+ mp_raise_msg(&mp_type_ValueError, "negative shift count");
}
if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
mpz_shl_inpl(&res->mpz, zlhs, irhs);
@@ -398,7 +397,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
return value;
} else {
// overflow
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "overflow converting long int to machine word"));
+ mp_raise_msg(&mp_type_OverflowError, "overflow converting long int to machine word");
}
}
}
diff --git a/py/objlist.c b/py/objlist.c
index b5e8b9965..6d4a20a50 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -266,7 +266,7 @@ STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) {
mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_list));
mp_obj_list_t *self = MP_OBJ_TO_PTR(args[0]);
if (self->len == 0) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "pop from empty list"));
+ mp_raise_msg(&mp_type_IndexError, "pop from empty list");
}
mp_uint_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false);
mp_obj_t ret = self->items[index];
diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c
index 38cda1ad7..18931a16c 100644
--- a/py/objnamedtuple.c
+++ b/py/objnamedtuple.c
@@ -73,7 +73,7 @@ STATIC void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
} else {
// delete/store attribute
// provide more detailed error message than we'd get by just returning
- nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "can't set attribute"));
+ mp_raise_msg(&mp_type_AttributeError, "can't set attribute");
}
}
diff --git a/py/objobject.c b/py/objobject.c
index bba6f053e..b33dc491c 100644
--- a/py/objobject.c
+++ b/py/objobject.c
@@ -50,8 +50,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(object___init___obj, object___init__);
STATIC mp_obj_t object___new__(mp_obj_t cls) {
if (!MP_OBJ_IS_TYPE(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t*)MP_OBJ_TO_PTR(cls))) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "__new__ arg must be a user-type"));
+ mp_raise_msg(&mp_type_TypeError, "__new__ arg must be a user-type");
}
mp_obj_t o = MP_OBJ_SENTINEL;
mp_obj_t res = mp_obj_instance_make_new(MP_OBJ_TO_PTR(cls), 1, 0, &o);
diff --git a/py/objset.c b/py/objset.c
index 6b6f95f9b..fc124fcd8 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -68,7 +68,7 @@ STATIC void check_set(mp_obj_t o) {
if (MP_OBJ_IS_TYPE(o, &mp_type_frozenset)) {
// Mutable method called on frozenset; emulate CPython behavior, eg:
// AttributeError: 'frozenset' object has no attribute 'add'
- nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "'frozenset' has no such attribute"));
+ mp_raise_msg(&mp_type_AttributeError, "'frozenset' has no such attribute");
}
#endif
mp_check_self(MP_OBJ_IS_TYPE(o, &mp_type_set));
@@ -389,7 +389,7 @@ STATIC mp_obj_t set_pop(mp_obj_t self_in) {
mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_t obj = mp_set_remove_first(&self->set);
if (obj == MP_OBJ_NULL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "pop from an empty set"));
+ mp_raise_msg(&mp_type_KeyError, "pop from an empty set");
}
return obj;
}
diff --git a/py/objstringio.c b/py/objstringio.c
index eb0cc4eb3..a430fca3b 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -30,22 +30,16 @@
#include "py/nlr.h"
#include "py/objstr.h"
+#include "py/objstringio.h"
#include "py/runtime.h"
#include "py/stream.h"
#if MICROPY_PY_IO
-typedef struct _mp_obj_stringio_t {
- mp_obj_base_t base;
- vstr_t *vstr;
- // StringIO has single pointer used for both reading and writing
- mp_uint_t pos;
-} mp_obj_stringio_t;
-
#if MICROPY_CPYTHON_COMPAT
STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) {
if (o->vstr == NULL) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "I/O operation on closed file"));
+ mp_raise_msg(&mp_type_ValueError, "I/O operation on closed file");
}
}
#else
@@ -156,7 +150,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stringio___exit___obj, 4, 4, stringio
STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) {
mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t);
o->base.type = type;
- o->vstr = vstr_new();
+ o->vstr = vstr_new(16);
o->pos = 0;
return o;
}
diff --git a/py/objstringio.h b/py/objstringio.h
new file mode 100644
index 000000000..853bfb11b
--- /dev/null
+++ b/py/objstringio.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+#ifndef MICROPY_INCLUDED_PY_OBJSTRINGIO_H
+#define MICROPY_INCLUDED_PY_OBJSTRINGIO_H
+
+#include "py/obj.h"
+
+typedef struct _mp_obj_stringio_t {
+ mp_obj_base_t base;
+ vstr_t *vstr;
+ // StringIO has single pointer used for both reading and writing
+ mp_uint_t pos;
+} mp_obj_stringio_t;
+
+#endif // MICROPY_INCLUDED_PY_OBJSTRINGIO_H
diff --git a/py/objtype.c b/py/objtype.c
index 907308a75..8b46c5400 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -311,8 +311,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
}
if (init_ret != mp_const_none) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "__init__() should return None"));
+ mp_raise_msg(&mp_type_TypeError, "__init__() should return None");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
@@ -508,7 +507,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
// the code.
const mp_obj_t *proxy = mp_obj_property_get(member);
if (proxy[0] == mp_const_none) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "unreadable attribute"));
+ mp_raise_msg(&mp_type_AttributeError, "unreadable attribute");
} else {
dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in);
}
@@ -710,8 +709,7 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons
mp_obj_t call = mp_obj_instance_get_call(self_in);
if (call == MP_OBJ_NULL) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object not callable"));
+ mp_raise_msg(&mp_type_TypeError, "object not callable");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not callable", mp_obj_get_type_str(self_in)));
@@ -793,7 +791,7 @@ STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_
return mp_obj_new_type(mp_obj_str_get_qstr(args[0]), args[1], args[2]);
default:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "type takes 1 or 3 arguments"));
+ mp_raise_msg(&mp_type_TypeError, "type takes 1 or 3 arguments");
}
}
@@ -804,7 +802,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp
if (self->make_new == NULL) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "cannot create instance"));
+ mp_raise_msg(&mp_type_TypeError, "cannot create instance");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"cannot create '%q' instances", self->name));
@@ -892,8 +890,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
// TODO: Verify with CPy, tested on function type
if (t->make_new == NULL) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "type is not an acceptable base type"));
+ mp_raise_msg(&mp_type_TypeError, "type is not an acceptable base type");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"type '%q' is not an acceptable base type", t->name));
@@ -927,7 +924,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
const mp_obj_type_t *native_base;
uint num_native_bases = instance_count_native_bases(o, &native_base);
if (num_native_bases > 1) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict"));
+ mp_raise_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict");
}
mp_map_t *locals_map = &o->locals_dict->map;
@@ -1074,7 +1071,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) {
} else if (MP_OBJ_IS_TYPE(classinfo, &mp_type_tuple)) {
mp_obj_tuple_get(classinfo, &len, &items);
} else {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "issubclass() arg 2 must be a class or a tuple of classes"));
+ mp_raise_msg(&mp_type_TypeError, "issubclass() arg 2 must be a class or a tuple of classes");
}
for (uint i = 0; i < len; i++) {
@@ -1088,7 +1085,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) {
STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) {
if (!MP_OBJ_IS_TYPE(object, &mp_type_type)) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "issubclass() arg 1 must be a class"));
+ mp_raise_msg(&mp_type_TypeError, "issubclass() arg 1 must be a class");
}
return mp_obj_is_subclass(object, classinfo);
}
diff --git a/py/parsenum.c b/py/parsenum.c
index 83a6abd20..1010ad305 100644
--- a/py/parsenum.c
+++ b/py/parsenum.c
@@ -27,7 +27,7 @@
#include <stdbool.h>
#include <stdlib.h>
-#include "py/nlr.h"
+#include "py/runtime.h"
#include "py/parsenumbase.h"
#include "py/parsenum.h"
#include "py/smallint.h"
@@ -55,7 +55,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m
// check radix base
if ((base != 0 && base < 2) || base > 36) {
// this won't be reached if lex!=NULL
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "int() arg 2 must be >= 2 and <= 36"));
+ mp_raise_msg(&mp_type_ValueError, "int() arg 2 must be >= 2 and <= 36");
}
// skip leading space
diff --git a/py/py.mk b/py/py.mk
index 741ad52f9..ab07bbbde 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -229,6 +229,7 @@ PY_O_BASENAME = \
../extmod/vfs_fat_file.o \
../extmod/vfs_fat_lexer.o \
../extmod/vfs_fat_misc.o \
+ ../extmod/utime_mphal.o \
../extmod/moduos_dupterm.o \
../lib/embed/abort_.o \
../lib/utils/printf.o \
@@ -236,6 +237,10 @@ PY_O_BASENAME = \
# prepend the build destination prefix to the py object files
PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME))
+ifneq ($(FROZEN_DIR),)
+PY_O += $(BUILD)/$(BUILD)/frozen.o
+endif
+
# Sources that may contain qstrings
SRC_QSTR_IGNORE = nlr% emitnx% emitnthumb% emitnarm%
SRC_QSTR = $(SRC_MOD) $(addprefix py/,$(filter-out $(SRC_QSTR_IGNORE),$(PY_O_BASENAME:.o=.c)) emitnative.c)
diff --git a/py/runtime.c b/py/runtime.c
index 003c9f8b4..6eda77ee9 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -138,8 +138,7 @@ mp_obj_t mp_load_global(qstr qst) {
elem = mp_map_lookup((mp_map_t*)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
if (elem == NULL) {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_NameError,
- "name not defined"));
+ mp_raise_msg(&mp_type_NameError, "name not defined");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError,
"name '%q' is not defined", qst));
@@ -230,8 +229,7 @@ mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) {
}
}
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "unsupported type for operator"));
+ mp_raise_msg(&mp_type_TypeError, "unsupported type for operator");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"unsupported type for %q: '%s'",
@@ -323,7 +321,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
case MP_BINARY_OP_INPLACE_LSHIFT: {
if (rhs_val < 0) {
// negative shift not allowed
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count"));
+ mp_raise_msg(&mp_type_ValueError, "negative shift count");
} else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) {
// left-shift will overflow, so use higher precision integer
lhs = mp_obj_new_int_from_ll(lhs_val);
@@ -338,7 +336,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
case MP_BINARY_OP_INPLACE_RSHIFT:
if (rhs_val < 0) {
// negative shift not allowed
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count"));
+ mp_raise_msg(&mp_type_ValueError, "negative shift count");
} else {
// standard precision is enough for right-shift
if (rhs_val >= (mp_int_t)BITS_PER_WORD) {
@@ -414,7 +412,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
lhs = mp_obj_new_float(lhs_val);
goto generic_binary_op;
#else
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative power with no float support"));
+ mp_raise_msg(&mp_type_ValueError, "negative power with no float support");
#endif
} else {
mp_int_t ans = 1;
@@ -515,8 +513,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
}
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object not iterable"));
+ mp_raise_msg(&mp_type_TypeError, "object not iterable");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not iterable", mp_obj_get_type_str(rhs)));
@@ -538,8 +535,7 @@ generic_binary_op:
unsupported_op:
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "unsupported type for operator"));
+ mp_raise_msg(&mp_type_TypeError, "unsupported type for operator");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"unsupported types for %q: '%s', '%s'",
@@ -547,7 +543,7 @@ unsupported_op:
}
zero_division:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero"));
+ mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero");
}
mp_obj_t mp_call_function_0(mp_obj_t fun) {
@@ -581,8 +577,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args, mp_uint_t n_kw
}
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object not callable"));
+ mp_raise_msg(&mp_type_TypeError, "object not callable");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not callable", mp_obj_get_type_str(fun_in)));
@@ -813,16 +808,14 @@ void mp_unpack_sequence(mp_obj_t seq_in, mp_uint_t num, mp_obj_t *items) {
too_short:
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
- "wrong number of values to unpack"));
+ mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"need more than %d values to unpack", (int)seq_len));
}
too_long:
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
- "wrong number of values to unpack"));
+ mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"too many values to unpack (expected %d)", (int)num));
@@ -888,8 +881,7 @@ void mp_unpack_ex(mp_obj_t seq_in, mp_uint_t num_in, mp_obj_t *items) {
too_short:
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
- "wrong number of values to unpack"));
+ mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"need more than %d values to unpack", (int)seq_len));
@@ -928,8 +920,7 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c
const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]);
if (arg0_type != self->type) {
if (MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "argument has wrong type"));
+ mp_raise_msg(&mp_type_TypeError, "argument has wrong type");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"argument should be a '%q' not a '%q'", self->type->name, arg0_type->name));
@@ -1045,8 +1036,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
if (dest[0] == MP_OBJ_NULL) {
// no attribute/method called attr
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError,
- "no such attribute"));
+ mp_raise_msg(&mp_type_AttributeError, "no such attribute");
} else {
// following CPython, we give a more detailed error message for type objects
if (MP_OBJ_IS_TYPE(base, &mp_type_type)) {
@@ -1074,8 +1064,7 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
}
}
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError,
- "no such attribute"));
+ mp_raise_msg(&mp_type_AttributeError, "no such attribute");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
"'%s' object has no attribute '%q'",
@@ -1105,8 +1094,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in) {
// object not iterable
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object not iterable"));
+ mp_raise_msg(&mp_type_TypeError, "object not iterable");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not iterable", mp_obj_get_type_str(o_in)));
@@ -1128,8 +1116,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
return mp_call_method_n_kw(0, 0, dest);
} else {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object not an iterator"));
+ mp_raise_msg(&mp_type_TypeError, "object not an iterator");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
@@ -1165,8 +1152,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) {
}
} else {
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
- "object not an iterator"));
+ mp_raise_msg(&mp_type_TypeError, "object not an iterator");
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
@@ -1384,8 +1370,7 @@ void *m_malloc_fail(size_t num_bytes) {
// dummy
#if MICROPY_ENABLE_GC
} else if (gc_is_locked()) {
- nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError,
- "memory allocation failed, heap is locked"));
+ mp_raise_msg(&mp_type_MemoryError, "memory allocation failed, heap is locked");
#endif
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError,
diff --git a/py/sequence.c b/py/sequence.c
index 239f1b2cc..0acdd25be 100644
--- a/py/sequence.c
+++ b/py/sequence.c
@@ -235,7 +235,7 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args
}
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "object not in sequence"));
+ mp_raise_msg(&mp_type_ValueError, "object not in sequence");
}
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, mp_uint_t len, mp_obj_t value) {
diff --git a/py/stream.c b/py/stream.c
index 5610faf74..cc8a63ac2 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -101,7 +101,7 @@ const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) {
|| ((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL)
|| ((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) {
// CPython: io.UnsupportedOperation, OSError subclass
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "stream operation not supported"));
+ mp_raise_msg(&mp_type_OSError, "stream operation not supported");
}
return stream_p;
}
diff --git a/py/vstr.c b/py/vstr.c
index 5096475f1..6a91552b5 100644
--- a/py/vstr.c
+++ b/py/vstr.c
@@ -74,20 +74,8 @@ void vstr_clear(vstr_t *vstr) {
vstr->buf = NULL;
}
-vstr_t *vstr_new(void) {
+vstr_t *vstr_new(size_t alloc) {
vstr_t *vstr = m_new_obj(vstr_t);
- if (vstr == NULL) {
- return NULL;
- }
- vstr_init(vstr, 16);
- return vstr;
-}
-
-vstr_t *vstr_new_size(size_t alloc) {
- vstr_t *vstr = m_new_obj(vstr_t);
- if (vstr == NULL) {
- return NULL;
- }
vstr_init(vstr, alloc);
return vstr;
}
diff --git a/qemu-arm/Makefile b/qemu-arm/Makefile
index 31ba6baa2..9159f97e5 100644
--- a/qemu-arm/Makefile
+++ b/qemu-arm/Makefile
@@ -40,19 +40,28 @@ SRC_C = \
SRC_TEST_C = \
test_main.c \
+STM_SRC_C = $(addprefix stmhal/,\
+ pybstdio.c \
+ )
+
SRC_S = \
OBJ =
OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
+OBJ += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o))
OBJ_TEST =
OBJ_TEST += $(PY_O)
OBJ_TEST += $(addprefix $(BUILD)/, $(SRC_TEST_C:.c=.o))
OBJ_TEST += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
+OBJ_TEST += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o))
OBJ_TEST += $(BUILD)/tinytest.o
+# List of sources for qstr extraction
+SRC_QSTR += $(SRC_C) $(STM_SRC_C)
+
all: run
run: $(BUILD)/firmware.elf
diff --git a/qemu-arm/memory.h b/qemu-arm/memory.h
new file mode 100644
index 000000000..f3777b0e3
--- /dev/null
+++ b/qemu-arm/memory.h
@@ -0,0 +1,2 @@
+// this is needed for extmod/crypto-algorithms/sha256.c
+#include <string.h>
diff --git a/qemu-arm/mpconfigport.h b/qemu-arm/mpconfigport.h
index 1f23148c2..b8806405b 100644
--- a/qemu-arm/mpconfigport.h
+++ b/qemu-arm/mpconfigport.h
@@ -20,9 +20,18 @@
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
-#define MICROPY_PY_IO (0)
+#define MICROPY_PY_IO (1)
#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_MAXSIZE (1)
+#define MICROPY_PY_UERRNO (1)
+#define MICROPY_PY_UBINASCII (1)
+#define MICROPY_PY_URANDOM (1)
+#define MICROPY_PY_UCTYPES (1)
+#define MICROPY_PY_UZLIB (1)
+#define MICROPY_PY_UJSON (1)
+#define MICROPY_PY_URE (1)
+#define MICROPY_PY_UHEAPQ (1)
+#define MICROPY_PY_UHASHLIB (1)
#define MICROPY_USE_INTERNAL_PRINTF (0)
// type definitions for the specific machine
diff --git a/qemu-arm/mphalport.h b/qemu-arm/mphalport.h
index 4bd8276f3..d996402ae 100644
--- a/qemu-arm/mphalport.h
+++ b/qemu-arm/mphalport.h
@@ -1 +1,2 @@
-// empty file
+#define mp_hal_stdin_rx_chr() (0)
+#define mp_hal_stdout_tx_strn_cooked(s, l) write(1, (s), (l))
diff --git a/stmhal/Makefile b/stmhal/Makefile
index 7be0f28fe..e2e1dc6a1 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -274,16 +274,9 @@ $(PY_BUILD)/mpprint.o: COPT += -Os
all: $(BUILD)/firmware.dfu $(BUILD)/firmware.hex
ifneq ($(FROZEN_DIR),)
+# To use frozen source modules, put your .py files in a subdirectory (eg scripts/)
+# and then invoke make with FROZEN_DIR=scripts (be sure to build from scratch).
CFLAGS += -DMICROPY_MODULE_FROZEN_STR
-OBJ += $(BUILD)/frozen-files.o
-MAKE_FROZEN = ../tools/make-frozen.py
-
-$(BUILD)/frozen-files.o: $(BUILD)/frozen-files.c
- $(call compile_c)
-
-$(BUILD)/frozen-files.c: $(shell find $(FROZEN_DIR) -type f)
- @$(ECHO) "Creating $@"
- $(Q)$(PYTHON) $(MAKE_FROZEN) $(FROZEN_DIR) > $@
endif
ifneq ($(FROZEN_MPY_DIR),)
diff --git a/stmhal/accel.c b/stmhal/accel.c
index e75f1c994..827aa46e7 100644
--- a/stmhal/accel.c
+++ b/stmhal/accel.c
@@ -57,15 +57,9 @@
#define MMA_AXIS_SIGNED_VALUE(i) (((i) & 0x3f) | ((i) & 0x20 ? (~0x1f) : 0))
void accel_init(void) {
- GPIO_InitTypeDef GPIO_InitStructure;
-
// PB5 is connected to AVDD; pull high to enable MMA accel device
- 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;
- GPIO_InitStructure.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(MICROPY_HW_MMA_AVDD_PIN.gpio, &GPIO_InitStructure);
+ mp_hal_pin_low(&MICROPY_HW_MMA_AVDD_PIN); // turn off AVDD
+ mp_hal_pin_output(&MICROPY_HW_MMA_AVDD_PIN);
}
STATIC void accel_start(void) {
@@ -81,9 +75,9 @@ STATIC void accel_start(void) {
i2c_init(&I2CHandle1);
// turn off AVDD, wait 30ms, turn on AVDD, wait 30ms again
- GPIO_clear_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn off
+ mp_hal_pin_low(&MICROPY_HW_MMA_AVDD_PIN); // turn off
HAL_Delay(30);
- GPIO_set_pin(MICROPY_HW_MMA_AVDD_PIN.gpio, MICROPY_HW_MMA_AVDD_PIN.pin_mask); // turn on
+ mp_hal_pin_high(&MICROPY_HW_MMA_AVDD_PIN); // turn on
HAL_Delay(30);
HAL_StatusTypeDef status;
diff --git a/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h b/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h
index 885cedc89..d18abb908 100644
--- a/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h
+++ b/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h
@@ -66,6 +66,5 @@
#define MICROPY_HW_LED2 (pin_B12) // green
#define MICROPY_HW_LED3 (pin_B12) // green
#define MICROPY_HW_LED4 (pin_B12) // green
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
diff --git a/stmhal/boards/HYDRABUS/mpconfigboard.h b/stmhal/boards/HYDRABUS/mpconfigboard.h
index 4fe0874d7..06d169236 100644
--- a/stmhal/boards/HYDRABUS/mpconfigboard.h
+++ b/stmhal/boards/HYDRABUS/mpconfigboard.h
@@ -69,9 +69,8 @@
#define MICROPY_HW_LED2 (pin_A4) // same as LED1
#define MICROPY_HW_LED3 (pin_A4) // same as LED1
#define MICROPY_HW_LED4 (pin_A4) // same as LED1
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// SD card detect switch (not used, always on)
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8)
diff --git a/stmhal/boards/LIMIFROG/mpconfigboard.h b/stmhal/boards/LIMIFROG/mpconfigboard.h
index 782c9c90f..47b892233 100644
--- a/stmhal/boards/LIMIFROG/mpconfigboard.h
+++ b/stmhal/boards/LIMIFROG/mpconfigboard.h
@@ -63,9 +63,8 @@ void LIMIFROG_board_early_init(void);
// LEDs
#define MICROPY_HW_LED1 (pin_C3) // red
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = pin->pin_mask<<16)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// USB config
// #define MICROPY_HW_USB_OTG_ID_PIN (pin_C12) // This is not the official ID Pin which should be PA10
diff --git a/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h b/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h
index 8ec8df645..3155b6309 100644
--- a/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h
+++ b/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h
@@ -64,9 +64,8 @@ void NETDUINO_PLUS_2_board_early_init(void);
#define MICROPY_HW_LED2 (pin_C13) // White LED (aka Power)
#define MICROPY_HW_LED3 (pin_A10) // Same as Led(1)
#define MICROPY_HW_LED4 (pin_C13) // Same as Led(2)
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// USB VBUS detect pin
#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9)
diff --git a/stmhal/boards/NUCLEO_F401RE/mpconfigboard.h b/stmhal/boards/NUCLEO_F401RE/mpconfigboard.h
index 780eaf8fc..518f65824 100644
--- a/stmhal/boards/NUCLEO_F401RE/mpconfigboard.h
+++ b/stmhal/boards/NUCLEO_F401RE/mpconfigboard.h
@@ -54,6 +54,5 @@
// LEDs
#define MICROPY_HW_LED1 (pin_A5) // Green LD2 LED on Nucleo
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
diff --git a/stmhal/boards/NUCLEO_F411RE/mpconfigboard.h b/stmhal/boards/NUCLEO_F411RE/mpconfigboard.h
index e7ffd8510..4dac80493 100644
--- a/stmhal/boards/NUCLEO_F411RE/mpconfigboard.h
+++ b/stmhal/boards/NUCLEO_F411RE/mpconfigboard.h
@@ -65,6 +65,5 @@
// LEDs
#define MICROPY_HW_LED1 (pin_A5) // Green LD2 LED on Nucleo
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
diff --git a/stmhal/boards/OLIMEX_E407/mpconfigboard.h b/stmhal/boards/OLIMEX_E407/mpconfigboard.h
index c9241fe63..63ddcfb5d 100644
--- a/stmhal/boards/OLIMEX_E407/mpconfigboard.h
+++ b/stmhal/boards/OLIMEX_E407/mpconfigboard.h
@@ -71,9 +71,8 @@
// LEDs
#define MICROPY_HW_LED1 (pin_C13)
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRH = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRL = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin))
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_C11)
diff --git a/stmhal/boards/PYBLITEV10/mpconfigboard.h b/stmhal/boards/PYBLITEV10/mpconfigboard.h
index 83dcb938b..3147d2d7a 100644
--- a/stmhal/boards/PYBLITEV10/mpconfigboard.h
+++ b/stmhal/boards/PYBLITEV10/mpconfigboard.h
@@ -73,9 +73,8 @@
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, TIM_CHANNEL_1, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, TIM_CHANNEL_1, GPIO_AF2_TIM3 }
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_B5)
diff --git a/stmhal/boards/PYBV10/mpconfigboard.h b/stmhal/boards/PYBV10/mpconfigboard.h
index c654ec9a7..2540cc4eb 100644
--- a/stmhal/boards/PYBV10/mpconfigboard.h
+++ b/stmhal/boards/PYBV10/mpconfigboard.h
@@ -84,9 +84,8 @@
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, TIM_CHANNEL_1, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, TIM_CHANNEL_1, GPIO_AF2_TIM3 }
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8)
diff --git a/stmhal/boards/PYBV11/mpconfigboard.h b/stmhal/boards/PYBV11/mpconfigboard.h
index 9b5b7de27..881e1ccf0 100644
--- a/stmhal/boards/PYBV11/mpconfigboard.h
+++ b/stmhal/boards/PYBV11/mpconfigboard.h
@@ -84,9 +84,8 @@
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, TIM_CHANNEL_1, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, TIM_CHANNEL_1, GPIO_AF2_TIM3 }
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8)
diff --git a/stmhal/boards/PYBV3/mpconfigboard.h b/stmhal/boards/PYBV3/mpconfigboard.h
index 44fb22161..48d554925 100644
--- a/stmhal/boards/PYBV3/mpconfigboard.h
+++ b/stmhal/boards/PYBV3/mpconfigboard.h
@@ -73,9 +73,8 @@
#define MICROPY_HW_LED4 (pin_C5) // G2 - green
#define MICROPY_HW_LED1_PWM { TIM1, 1, TIM_CHANNEL_1, GPIO_AF1_TIM1 }
#define MICROPY_HW_LED2_PWM { TIM1, 1, TIM_CHANNEL_3, GPIO_AF1_TIM1 }
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRH = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRL = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin))
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_C13)
diff --git a/stmhal/boards/PYBV4/mpconfigboard.h b/stmhal/boards/PYBV4/mpconfigboard.h
index cc931fb6b..3e8300d15 100644
--- a/stmhal/boards/PYBV4/mpconfigboard.h
+++ b/stmhal/boards/PYBV4/mpconfigboard.h
@@ -81,9 +81,8 @@
#define MICROPY_HW_LED4 (pin_B4) // blue
#define MICROPY_HW_LED3_PWM { TIM2, 2, TIM_CHANNEL_1, GPIO_AF1_TIM2 }
#define MICROPY_HW_LED4_PWM { TIM3, 3, TIM_CHANNEL_1, GPIO_AF2_TIM3 }
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8)
diff --git a/stmhal/boards/STM32F411DISC/mpconfigboard.h b/stmhal/boards/STM32F411DISC/mpconfigboard.h
index 3bab1304c..be3589cd9 100644
--- a/stmhal/boards/STM32F411DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F411DISC/mpconfigboard.h
@@ -63,9 +63,8 @@
#define MICROPY_HW_LED2 (pin_D12) // green
#define MICROPY_HW_LED3 (pin_D13) // orange
#define MICROPY_HW_LED4 (pin_D15) // blue
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// USB config
#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9)
diff --git a/stmhal/boards/STM32F429DISC/mpconfigboard.h b/stmhal/boards/STM32F429DISC/mpconfigboard.h
index f2cf6c142..63f22e02c 100644
--- a/stmhal/boards/STM32F429DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F429DISC/mpconfigboard.h
@@ -67,9 +67,8 @@
// LEDs
#define MICROPY_HW_LED1 (pin_G14) // red
#define MICROPY_HW_LED2 (pin_G13) // green
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// USB config
#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_B13)
diff --git a/stmhal/boards/STM32F4DISC/mpconfigboard.h b/stmhal/boards/STM32F4DISC/mpconfigboard.h
index 01202e0c9..841bf7d15 100644
--- a/stmhal/boards/STM32F4DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F4DISC/mpconfigboard.h
@@ -82,9 +82,8 @@
#define MICROPY_HW_LED2 (pin_D12) // green
#define MICROPY_HW_LED3 (pin_D13) // orange
#define MICROPY_HW_LED4 (pin_D15) // blue
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// USB config
#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9)
diff --git a/stmhal/boards/STM32F7DISC/mpconfigboard.h b/stmhal/boards/STM32F7DISC/mpconfigboard.h
index a1dbc0f46..acdc4d005 100644
--- a/stmhal/boards/STM32F7DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F7DISC/mpconfigboard.h
@@ -79,9 +79,8 @@ void STM32F7DISC_board_early_init(void);
// LEDs
#define MICROPY_HW_LED1 (pin_I1) // green
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = (pin->pin_mask << 16))
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_C13)
diff --git a/stmhal/boards/STM32L476DISC/mpconfigboard.h b/stmhal/boards/STM32L476DISC/mpconfigboard.h
index 07e3ec7fd..55e7c9b56 100644
--- a/stmhal/boards/STM32L476DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32L476DISC/mpconfigboard.h
@@ -61,9 +61,8 @@
// LEDs
#define MICROPY_HW_LED1 (pin_B2) // red
#define MICROPY_HW_LED2 (pin_E8) // green
-#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
-#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRR = pin->pin_mask)
-#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRR = pin->pin_mask<<16)
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// USB config
// #define MICROPY_HW_USB_OTG_ID_PIN (pin_C12) // This is not the official ID Pin which should be PA10
diff --git a/stmhal/i2c.c b/stmhal/i2c.c
index 1909f8160..07269bce5 100644
--- a/stmhal/i2c.c
+++ b/stmhal/i2c.c
@@ -238,8 +238,8 @@ void i2c_init(I2C_HandleTypeDef *i2c) {
}
// init the GPIO lines
- mp_hal_gpio_set_af(scl_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit);
- mp_hal_gpio_set_af(sda_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit);
+ mp_hal_pin_set_af(scl_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit);
+ mp_hal_pin_set_af(sda_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit);
// init the I2C device
if (HAL_I2C_Init(i2c) != HAL_OK) {
diff --git a/stmhal/lcd.c b/stmhal/lcd.c
index 92f19b818..c406d6447 100644
--- a/stmhal/lcd.c
+++ b/stmhal/lcd.c
@@ -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();
- GPIO_clear_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); // CS=0; enable
+ mp_hal_pin_low(lcd->pin_cs1); // CS=0; enable
if (instr_data == LCD_INSTR) {
- GPIO_clear_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); // A0=0; select instr reg
+ mp_hal_pin_low(lcd->pin_a0); // A0=0; select instr reg
} else {
- GPIO_set_pin(lcd->pin_a0->gpio, lcd->pin_a0->pin_mask); // A0=1; select data reg
+ mp_hal_pin_high(lcd->pin_a0); // A0=1; select data reg
}
lcd_delay();
HAL_SPI_Transmit(lcd->spi, &i, 1, 1000);
lcd_delay();
- GPIO_set_pin(lcd->pin_cs1->gpio, lcd->pin_cs1->pin_mask); // CS=1; disable
+ mp_hal_pin_high(lcd->pin_cs1); // CS=1; disable
}
// write a string to the LCD at the current cursor location
@@ -262,34 +262,22 @@ 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
- 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);
+ mp_hal_pin_high(lcd->pin_cs1);
+ mp_hal_pin_high(lcd->pin_rst);
+ mp_hal_pin_high(lcd->pin_a0);
+ mp_hal_pin_low(lcd->pin_bl);
// init the pins to be push/pull outputs
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
- GPIO_InitStructure.Pull = GPIO_NOPULL;
-
- GPIO_InitStructure.Pin = lcd->pin_cs1->pin_mask;
- HAL_GPIO_Init(lcd->pin_cs1->gpio, &GPIO_InitStructure);
-
- GPIO_InitStructure.Pin = lcd->pin_rst->pin_mask;
- HAL_GPIO_Init(lcd->pin_rst->gpio, &GPIO_InitStructure);
-
- GPIO_InitStructure.Pin = lcd->pin_a0->pin_mask;
- HAL_GPIO_Init(lcd->pin_a0->gpio, &GPIO_InitStructure);
-
- GPIO_InitStructure.Pin = lcd->pin_bl->pin_mask;
- HAL_GPIO_Init(lcd->pin_bl->gpio, &GPIO_InitStructure);
+ mp_hal_pin_output(lcd->pin_cs1);
+ mp_hal_pin_output(lcd->pin_rst);
+ mp_hal_pin_output(lcd->pin_a0);
+ mp_hal_pin_output(lcd->pin_bl);
// init the LCD
HAL_Delay(1); // wait a bit
- GPIO_clear_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); // RST=0; reset
+ mp_hal_pin_low(lcd->pin_rst); // RST=0; reset
HAL_Delay(1); // wait for reset; 2us min
- GPIO_set_pin(lcd->pin_rst->gpio, lcd->pin_rst->pin_mask); // RST=1; enable
+ mp_hal_pin_high(lcd->pin_rst); // 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 +360,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)) {
- GPIO_set_pin(self->pin_bl->gpio, self->pin_bl->pin_mask); // set pin high to turn backlight on
+ mp_hal_pin_high(self->pin_bl); // set pin high to turn backlight on
} else {
- GPIO_clear_pin(self->pin_bl->gpio, self->pin_bl->pin_mask); // set pin low to turn backlight off
+ mp_hal_pin_low(self->pin_bl); // set pin low to turn backlight off
}
return mp_const_none;
}
diff --git a/stmhal/led.c b/stmhal/led.c
index fdf5b04d8..310efdcda 100644
--- a/stmhal/led.c
+++ b/stmhal/led.c
@@ -67,21 +67,12 @@ STATIC const pyb_led_obj_t pyb_led_obj[] = {
#define NUM_LEDS MP_ARRAY_SIZE(pyb_led_obj)
void led_init(void) {
- /* GPIO structure */
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /* Configure I/O speed, mode, output type and pull */
- GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
- GPIO_InitStructure.Mode = MICROPY_HW_LED_OTYPE;
- GPIO_InitStructure.Pull = GPIO_NOPULL;
-
/* Turn off LEDs and initialize */
for (int led = 0; led < NUM_LEDS; led++) {
const pin_obj_t *led_pin = pyb_led_obj[led].led_pin;
mp_hal_gpio_clock_enable(led_pin->gpio);
MICROPY_HW_LED_OFF(led_pin);
- GPIO_InitStructure.Pin = led_pin->pin_mask;
- HAL_GPIO_Init(led_pin->gpio, &GPIO_InitStructure);
+ mp_hal_pin_output(led_pin);
}
}
diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c
index 8bd04f3ec..7a337adb6 100644
--- a/stmhal/modmachine.c
+++ b/stmhal/modmachine.c
@@ -33,6 +33,7 @@
#include "extmod/machine_mem.h"
#include "extmod/machine_pulse.h"
#include "extmod/machine_i2c.h"
+#include "lib/utils/pyexec.h"
#include "lib/fatfs/ff.h"
#include "lib/fatfs/diskio.h"
#include "gccollect.h"
@@ -172,6 +173,12 @@ STATIC mp_obj_t machine_reset(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset);
+STATIC mp_obj_t machine_soft_reset(void) {
+ pyexec_system_exit = PYEXEC_FORCED_EXIT;
+ nlr_raise(mp_obj_new_exception(&mp_type_SystemExit));
+}
+MP_DEFINE_CONST_FUN_OBJ_0(machine_soft_reset_obj, machine_soft_reset);
+
// Activate the bootloader without BOOT* pins.
STATIC NORETURN mp_obj_t machine_bootloader(void) {
pyb_usb_dev_deinit();
@@ -502,6 +509,7 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&machine_unique_id_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&machine_reset_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_soft_reset), (mp_obj_t)&machine_soft_reset_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_bootloader), (mp_obj_t)&machine_bootloader_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&machine_freq_obj },
#if MICROPY_HW_ENABLE_RNG
diff --git a/stmhal/modnwwiznet5k.c b/stmhal/modnwwiznet5k.c
index c8b5d628f..f349e40af 100644
--- a/stmhal/modnwwiznet5k.c
+++ b/stmhal/modnwwiznet5k.c
@@ -65,11 +65,11 @@ STATIC void wiz_cris_exit(void) {
}
STATIC void wiz_cs_select(void) {
- GPIO_clear_pin(wiznet5k_obj.cs->gpio, wiznet5k_obj.cs->pin_mask);
+ mp_hal_pin_low(wiznet5k_obj.cs);
}
STATIC void wiz_cs_deselect(void) {
- GPIO_set_pin(wiznet5k_obj.cs->gpio, wiznet5k_obj.cs->pin_mask);
+ mp_hal_pin_high(wiznet5k_obj.cs);
}
STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) {
@@ -344,22 +344,12 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, mp_uint_t n_args, m
wiznet5k_obj.spi->Init.CRCPolynomial = 7; // unused
spi_init(wiznet5k_obj.spi, false);
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
- GPIO_InitStructure.Pull = GPIO_NOPULL;
- GPIO_InitStructure.Pin = wiznet5k_obj.cs->pin_mask;
- HAL_GPIO_Init(wiznet5k_obj.cs->gpio, &GPIO_InitStructure);
+ mp_hal_pin_output(wiznet5k_obj.cs);
+ mp_hal_pin_output(wiznet5k_obj.rst);
- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
- GPIO_InitStructure.Pull = GPIO_NOPULL;
- GPIO_InitStructure.Pin = wiznet5k_obj.rst->pin_mask;
- HAL_GPIO_Init(wiznet5k_obj.rst->gpio, &GPIO_InitStructure);
-
- GPIO_clear_pin(wiznet5k_obj.rst->gpio, wiznet5k_obj.rst->pin_mask);
+ mp_hal_pin_low(wiznet5k_obj.rst);
HAL_Delay(1); // datasheet says 2us
- GPIO_set_pin(wiznet5k_obj.rst->gpio, wiznet5k_obj.rst->pin_mask);
+ mp_hal_pin_high(wiznet5k_obj.rst);
HAL_Delay(160); // datasheet says 150ms
reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit);
diff --git a/stmhal/modpyb.c b/stmhal/modpyb.c
index 17c3411eb..5b2bf7aa9 100644
--- a/stmhal/modpyb.c
+++ b/stmhal/modpyb.c
@@ -62,6 +62,7 @@
#include "portmodules.h"
#include "modmachine.h"
#include "extmod/fsusermount.h"
+#include "extmod/utime_mphal.h"
/// \function millis()
/// Returns the number of milliseconds since the board was last reset.
@@ -162,8 +163,8 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_millis), (mp_obj_t)&pyb_elapsed_millis_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_micros), (mp_obj_t)&pyb_micros_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_micros), (mp_obj_t)&pyb_elapsed_micros_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&time_sleep_ms_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&time_sleep_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&mp_utime_sleep_ms_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&mp_utime_sleep_us_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&mod_os_sync_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&fsuser_mount_obj },
diff --git a/stmhal/modutime.c b/stmhal/modutime.c
index 60c92d60c..fae360bb0 100644
--- a/stmhal/modutime.c
+++ b/stmhal/modutime.c
@@ -31,6 +31,7 @@
#include "py/nlr.h"
#include "py/smallint.h"
#include "py/obj.h"
+#include "extmod/utime_mphal.h"
#include "systick.h"
#include "timeutils.h"
#include "portmodules.h"
@@ -129,84 +130,19 @@ STATIC mp_obj_t time_time(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
-/// \function sleep(seconds)
-/// Sleep for the given number of seconds. Seconds can be a floating-point number to
-/// sleep for a fractional number of seconds.
-STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
-#if MICROPY_PY_BUILTINS_FLOAT
- if (MP_OBJ_IS_INT(seconds_o)) {
-#endif
- HAL_Delay(1000 * mp_obj_get_int(seconds_o));
-#if MICROPY_PY_BUILTINS_FLOAT
- } else {
- HAL_Delay((uint32_t)(1000 * mp_obj_get_float(seconds_o)));
- }
-#endif
- return mp_const_none;
-}
-MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
-
-STATIC mp_obj_t time_sleep_ms(mp_obj_t ms_in) {
- mp_int_t ms = mp_obj_get_int(ms_in);
- if (ms > 0) {
- HAL_Delay(ms);
- }
- return mp_const_none;
-}
-MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms);
-
-STATIC mp_obj_t time_sleep_us(mp_obj_t usec_in) {
- mp_int_t usec = mp_obj_get_int(usec_in);
- if (usec > 0) {
- sys_tick_udelay(usec);
- }
- return mp_const_none;
-}
-MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
-
-STATIC mp_obj_t time_ticks_ms(void) {
- return MP_OBJ_NEW_SMALL_INT(HAL_GetTick() & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
-
-STATIC mp_obj_t time_ticks_us(void) {
- return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds() & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
-
-STATIC mp_obj_t time_ticks_cpu(void) {
- static bool enabled = false;
- if (!enabled) {
- CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
- DWT->CYCCNT = 0;
- DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
- enabled = true;
- }
- return MP_OBJ_NEW_SMALL_INT(DWT->CYCCNT & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
-
-STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) {
- // we assume that the arguments come from ticks_xx so are small ints
- uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
- uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
- return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
-
STATIC const mp_map_elem_t time_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&mp_utime_sleep_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&mp_utime_sleep_ms_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&mp_utime_sleep_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&mp_utime_ticks_ms_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&mp_utime_ticks_us_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&mp_utime_ticks_cpu_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&mp_utime_ticks_diff_obj },
};
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index 52fbcad68..264db3029 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -67,10 +67,13 @@
#define MICROPY_USE_INTERNAL_ERRNO (1)
#define MICROPY_PY_FUNCTION_ATTRS (1)
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
+#define MICROPY_PY_BUILTINS_STR_CENTER (1)
+#define MICROPY_PY_BUILTINS_STR_PARTITION (1)
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_BUILTINS_EXECFILE (1)
+#define MICROPY_PY_BUILTINS_COMPILE (1)
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
@@ -94,6 +97,7 @@
#define MICROPY_PY_URE (1)
#define MICROPY_PY_UHEAPQ (1)
#define MICROPY_PY_UHASHLIB (1)
+#define MICROPY_PY_UTIME_MP_HAL (1)
#define MICROPY_PY_MACHINE (1)
#define MICROPY_PY_MACHINE_PULSE (1)
#define MICROPY_PY_MACHINE_I2C (1)
@@ -176,6 +180,7 @@ extern const struct _mp_obj_module_t mp_module_network;
// extra constants
#define MICROPY_PORT_CONSTANTS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_umachine), (mp_obj_t)&machine_module }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&machine_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_stm), (mp_obj_t)&stm_module }, \
diff --git a/stmhal/mphalport.c b/stmhal/mphalport.c
index f392550b8..8d6aa1a75 100644
--- a/stmhal/mphalport.c
+++ b/stmhal/mphalport.c
@@ -7,6 +7,8 @@
#include "usb.h"
#include "uart.h"
+bool mp_hal_ticks_cpu_enabled = false;
+
// this table converts from HAL_StatusTypeDef to POSIX errno
const byte mp_hal_status_to_errno_table[4] = {
[HAL_OK] = 0,
@@ -71,6 +73,15 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
}
}
+void mp_hal_ticks_cpu_enable(void) {
+ if (!mp_hal_ticks_cpu_enabled) {
+ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+ DWT->CYCCNT = 0;
+ DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+ mp_hal_ticks_cpu_enabled = true;
+ }
+}
+
void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {
if (0) {
#ifdef __GPIOA_CLK_ENABLE
@@ -120,7 +131,9 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {
}
}
-void mp_hal_gpio_config(GPIO_TypeDef *gpio, uint32_t pin, uint32_t mode, uint32_t pull, uint32_t alt) {
+void mp_hal_pin_config(mp_hal_pin_obj_t pin_obj, uint32_t mode, uint32_t pull, uint32_t alt) {
+ GPIO_TypeDef *gpio = pin_obj->gpio;
+ uint32_t pin = pin_obj->pin;
mp_hal_gpio_clock_enable(gpio);
gpio->MODER = (gpio->MODER & ~(3 << (2 * pin))) | ((mode & 3) << (2 * pin));
gpio->OTYPER = (gpio->OTYPER & ~(1 << pin)) | ((mode >> 2) << pin);
@@ -129,7 +142,7 @@ void mp_hal_gpio_config(GPIO_TypeDef *gpio, uint32_t pin, uint32_t mode, uint32_
gpio->AFR[pin >> 3] = (gpio->AFR[pin >> 3] & ~(15 << (4 * (pin & 7)))) | (alt << (4 * (pin & 7)));
}
-bool mp_hal_gpio_set_af(const pin_obj_t *pin, GPIO_InitTypeDef *init, uint8_t fn, uint8_t unit) {
+bool mp_hal_pin_set_af(mp_hal_pin_obj_t pin, GPIO_InitTypeDef *init, uint8_t fn, uint8_t unit) {
mp_hal_gpio_clock_enable(pin->gpio);
const pin_af_obj_t *af = pin_find_af(pin, fn, unit);
diff --git a/stmhal/mphalport.h b/stmhal/mphalport.h
index 29a9fd6c3..e58bb33b5 100644
--- a/stmhal/mphalport.h
+++ b/stmhal/mphalport.h
@@ -14,41 +14,51 @@
#error mphalport.h: Unrecognized MCU_SERIES
#endif
-// Basic GPIO functions
-#define GPIO_read_pin(gpio, pin) (((gpio)->IDR >> (pin)) & 1)
-#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_L4)
-#define GPIO_set_pin(gpio, pin_mask) (((gpio)->BSRR) = (pin_mask))
-#define GPIO_clear_pin(gpio, pin_mask) (((gpio)->BSRR) = ((pin_mask) << 16))
-#else
-#define GPIO_set_pin(gpio, pin_mask) (((gpio)->BSRRL) = (pin_mask))
-#define GPIO_clear_pin(gpio, pin_mask) (((gpio)->BSRRH) = (pin_mask))
-#endif
-#define GPIO_read_output_pin(gpio, pin) (((gpio)->ODR >> (pin)) & 1)
-
-void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio);
-void mp_hal_gpio_config(GPIO_TypeDef *gpio, uint32_t pin, uint32_t mode, uint32_t pull, uint32_t alt);
-bool mp_hal_gpio_set_af(const pin_obj_t *pin, GPIO_InitTypeDef *init, uint8_t fn, uint8_t unit);
-
extern const unsigned char mp_hal_status_to_errno_table[4];
NORETURN void mp_hal_raise(HAL_StatusTypeDef status);
void mp_hal_set_interrupt_char(int c); // -1 to disable
// timing functions
+
#include "stmhal/systick.h"
+
#define mp_hal_delay_ms HAL_Delay
+#define mp_hal_delay_us(us) sys_tick_udelay(us)
#define mp_hal_delay_us_fast(us) sys_tick_udelay(us)
#define mp_hal_ticks_ms HAL_GetTick
#define mp_hal_ticks_us() sys_tick_get_microseconds()
+extern bool mp_hal_ticks_cpu_enabled;
+void mp_hal_ticks_cpu_enable(void);
+static inline mp_uint_t mp_hal_ticks_cpu(void) {
+ if (!mp_hal_ticks_cpu_enabled) {
+ mp_hal_ticks_cpu_enable();
+ }
+ return DWT->CYCCNT;
+}
+
// C-level pin HAL
+
#include "stmhal/pin.h"
+
#define mp_hal_pin_obj_t const pin_obj_t*
-#define mp_hal_get_pin_obj(o) pin_find(o)
-#define mp_hal_pin_input(p) mp_hal_gpio_config((p)->gpio, (p)->pin, 0, 0, 0)
-#define mp_hal_pin_output(p) mp_hal_gpio_config((p)->gpio, (p)->pin, 1, 0, 0)
-#define mp_hal_pin_open_drain(p) mp_hal_gpio_config((p)->gpio, (p)->pin, 5, 0, 0)
-#define mp_hal_pin_od_low(p) GPIO_clear_pin((p)->gpio, (p)->pin_mask)
-#define mp_hal_pin_od_high(p) GPIO_set_pin((p)->gpio, (p)->pin_mask)
-#define mp_hal_pin_read(p) GPIO_read_pin((p)->gpio, (p)->pin)
-#define mp_hal_pin_write(p, v) do { if (v) { GPIO_set_pin((p)->gpio, (p)->pin_mask); } else { GPIO_clear_pin((p)->gpio, (p)->pin_mask); } } while (0)
+#define mp_hal_get_pin_obj(o) pin_find(o)
+#define mp_hal_pin_input(p) mp_hal_pin_config((p), 0, 0, 0)
+#define mp_hal_pin_output(p) mp_hal_pin_config((p), 1, 0, 0)
+#define mp_hal_pin_open_drain(p) mp_hal_pin_config((p), 5, 0, 0)
+#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_L4)
+#define mp_hal_pin_high(p) (((p)->gpio->BSRR) = (p)->pin_mask)
+#define mp_hal_pin_low(p) (((p)->gpio->BSRR) = ((p)->pin_mask << 16))
+#else
+#define mp_hal_pin_high(p) (((p)->gpio->BSRRL) = (p)->pin_mask)
+#define mp_hal_pin_low(p) (((p)->gpio->BSRRH) = (p)->pin_mask)
+#endif
+#define mp_hal_pin_od_low(p) mp_hal_pin_low(p)
+#define mp_hal_pin_od_high(p) mp_hal_pin_high(p)
+#define mp_hal_pin_read(p) (((p)->gpio->IDR >> (p)->pin) & 1)
+#define mp_hal_pin_write(p, v) do { if (v) { mp_hal_pin_high(p); } else { mp_hal_pin_low(p); } } while (0)
+
+void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio);
+void mp_hal_pin_config(mp_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, uint32_t alt);
+bool mp_hal_pin_set_af(mp_hal_pin_obj_t pin, GPIO_InitTypeDef *init, uint8_t fn, uint8_t unit);
diff --git a/stmhal/pin.c b/stmhal/pin.c
index 9bd4e7a6d..21012d186 100644
--- a/stmhal/pin.c
+++ b/stmhal/pin.c
@@ -266,14 +266,10 @@ STATIC mp_obj_t pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, con
pin_obj_t *self = self_in;
if (n_args == 0) {
// get pin
- return MP_OBJ_NEW_SMALL_INT(GPIO_read_pin(self->gpio, self->pin));
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self));
} else {
// set pin
- if (mp_obj_is_true(args[0])) {
- GPIO_set_pin(self->gpio, self->pin_mask);
- } else {
- GPIO_clear_pin(self->gpio, self->pin_mask);
- }
+ mp_hal_pin_write(self, mp_obj_is_true(args[0]));
return mp_const_none;
}
}
@@ -371,11 +367,7 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, con
// if given, set the pin value before initialising to prevent glitches
if (args[3].u_obj != MP_OBJ_NULL) {
- if (mp_obj_is_true(args[3].u_obj)) {
- GPIO_set_pin(self->gpio, self->pin_mask);
- } else {
- GPIO_clear_pin(self->gpio, self->pin_mask);
- }
+ mp_hal_pin_write(self, mp_obj_is_true(args[3].u_obj));
}
// configure the GPIO as requested
@@ -411,7 +403,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
/// Set the pin to a low logic level.
STATIC mp_obj_t pin_low(mp_obj_t self_in) {
pin_obj_t *self = self_in;
- GPIO_clear_pin(self->gpio, self->pin_mask);;
+ mp_hal_pin_low(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low);
@@ -420,7 +412,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low);
/// Set the pin to a high logic level.
STATIC mp_obj_t pin_high(mp_obj_t self_in) {
pin_obj_t *self = self_in;
- GPIO_set_pin(self->gpio, self->pin_mask);;
+ mp_hal_pin_high(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high);
diff --git a/stmhal/pybstdio.c b/stmhal/pybstdio.c
index cf31f53ac..9cc787ce2 100644
--- a/stmhal/pybstdio.c
+++ b/stmhal/pybstdio.c
@@ -85,7 +85,7 @@ STATIC mp_uint_t stdio_write(mp_obj_t self_in, const void *buf, mp_uint_t size,
}
}
-STATIC mp_obj_t stdio_obj___exit__(mp_uint_t n_args, const mp_obj_t *args) {
+STATIC mp_obj_t stdio_obj___exit__(size_t n_args, const mp_obj_t *args) {
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stdio_obj___exit___obj, 4, 4, stdio_obj___exit__);
diff --git a/stmhal/spi.c b/stmhal/spi.c
index 7f805709d..e72810d28 100644
--- a/stmhal/spi.c
+++ b/stmhal/spi.c
@@ -332,7 +332,7 @@ void spi_init(SPI_HandleTypeDef *spi, bool enable_nss_pin) {
}
for (uint i = (enable_nss_pin && pins[0] ? 0 : 1); i < 4; i++) {
- mp_hal_gpio_set_af(pins[i], &GPIO_InitStructure, AF_FN_SPI, (self - &pyb_spi_obj[0]) + 1);
+ mp_hal_pin_set_af(pins[i], &GPIO_InitStructure, AF_FN_SPI, (self - &pyb_spi_obj[0]) + 1);
}
// init the SPI device
diff --git a/teensy/main.c b/teensy/main.c
index 890ee8149..ba7207fe8 100644
--- a/teensy/main.c
+++ b/teensy/main.c
@@ -317,7 +317,7 @@ soft_reset:
pyexec_frozen_module("main.py");
#else
{
- vstr_t *vstr = vstr_new();
+ vstr_t *vstr = vstr_new(16);
vstr_add_str(vstr, "/");
if (pyb_config_main == MP_OBJ_NULL) {
vstr_add_str(vstr, "main.py");
diff --git a/teensy/teensy_hal.h b/teensy/teensy_hal.h
index b00b6e4ac..80f320e0c 100644
--- a/teensy/teensy_hal.h
+++ b/teensy/teensy_hal.h
@@ -118,7 +118,9 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio);
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *init);
-#define GPIO_read_pin(gpio, pin) (((gpio)->PDIR >> (pin)) & 1)
-#define GPIO_set_pin(gpio, pin_mask) (((gpio)->PSOR) = (pin_mask))
-#define GPIO_clear_pin(gpio, pin_mask) (((gpio)->PCOR) = (pin_mask))
-#define GPIO_read_output_pin(gpio, pin) (((gpio)->PDOR >> (pin)) & 1)
+struct _pin_obj_t;
+#define mp_hal_pin_obj_t const struct _pin_obj_t*
+#define mp_hal_pin_high(p) (((p)->gpio->PSOR) = (p)->pin_mask)
+#define mp_hal_pin_low(p) (((p)->gpio->PCOR) = (p)->pin_mask)
+#define mp_hal_pin_read(p) (((p)->gpio->PDIR >> (p)->pin) & 1)
+#define mp_hal_pin_write(p, v) do { if (v) { mp_hal_pin_high(p); } else { mp_hal_pin_low(p); } } while (0)
diff --git a/tests/basics/array1.py b/tests/basics/array1.py
index e5ea6683c..c45b883c9 100644
--- a/tests/basics/array1.py
+++ b/tests/basics/array1.py
@@ -21,6 +21,10 @@ print(array.array('i'))
print(bool(array.array('i')))
print(bool(array.array('i', [1])))
+# containment, with incorrect type
+print('12' in array.array('B', b'12'))
+print([] in array.array('B', b'12'))
+
# bad typecode
try:
array.array('X')
diff --git a/tests/basics/async_def.py b/tests/basics/async_def.py
new file mode 100644
index 000000000..e345703d7
--- /dev/null
+++ b/tests/basics/async_def.py
@@ -0,0 +1,16 @@
+# test async def
+
+def dec(f):
+ print('decorator')
+ return f
+
+# test definition with a decorator
+@dec
+async def foo():
+ print('foo')
+
+coro = foo()
+try:
+ coro.send(None)
+except StopIteration:
+ print('StopIteration')
diff --git a/tests/basics/async_def.py.exp b/tests/basics/async_def.py.exp
new file mode 100644
index 000000000..f555ace99
--- /dev/null
+++ b/tests/basics/async_def.py.exp
@@ -0,0 +1,3 @@
+decorator
+foo
+StopIteration
diff --git a/tests/basics/async_with.py b/tests/basics/async_with.py
index 9eccfd816..5af0c5d95 100644
--- a/tests/basics/async_with.py
+++ b/tests/basics/async_with.py
@@ -3,6 +3,7 @@
class AContext:
async def __aenter__(self):
print('enter')
+ return 1
async def __aexit__(self, exc_type, exc, tb):
print('exit', exc_type, exc)
@@ -17,7 +18,8 @@ except StopIteration:
print('finished')
async def g():
- async with AContext():
+ async with AContext() as ac:
+ print(ac)
raise ValueError('error')
o = g()
diff --git a/tests/basics/async_with.py.exp b/tests/basics/async_with.py.exp
index 6072a3e0b..d00b18c96 100644
--- a/tests/basics/async_with.py.exp
+++ b/tests/basics/async_with.py.exp
@@ -3,5 +3,6 @@ body
exit None None
finished
enter
+1
exit <class 'ValueError'> error
ValueError
diff --git a/tests/basics/builtin_range.py b/tests/basics/builtin_range.py
index 9110cf12c..59fc0344a 100644
--- a/tests/basics/builtin_range.py
+++ b/tests/basics/builtin_range.py
@@ -50,3 +50,9 @@ try:
range(1)[0] = 1
except TypeError:
print("TypeError")
+
+# bad attr (can't store)
+try:
+ range(4).start = 0
+except AttributeError:
+ print('AttributeError')
diff --git a/tests/basics/del_global.py b/tests/basics/del_global.py
index 77d11cb3c..d740357b0 100644
--- a/tests/basics/del_global.py
+++ b/tests/basics/del_global.py
@@ -54,3 +54,8 @@ try:
print(c)
except NameError:
print("NameError")
+
+a = 1
+b = 2
+c = 3
+del (a, (b, c))
diff --git a/tests/basics/dict1.py b/tests/basics/dict1.py
index c70ca588a..20fa9def3 100644
--- a/tests/basics/dict1.py
+++ b/tests/basics/dict1.py
@@ -16,3 +16,27 @@ while x < 100:
d[x] = x
x += 1
print(d[50])
+
+# equality operator on dicts of different size
+print({} == {1:1})
+
+# equality operator on dicts of same size but with different keys
+print({1:1} == {2:1})
+
+# value not found
+try:
+ {}[0]
+except KeyError as er:
+ print('KeyError', er, repr(er), er.args)
+
+# unsupported unary op
+try:
+ +{}
+except TypeError:
+ print('TypeError')
+
+# unsupported binary op
+try:
+ {} + {}
+except TypeError:
+ print('TypeError')
diff --git a/tests/basics/dict_views.py b/tests/basics/dict_views.py
index fbf63fa0a..7ebcc1f56 100644
--- a/tests/basics/dict_views.py
+++ b/tests/basics/dict_views.py
@@ -3,4 +3,19 @@ for m in d.items, d.values, d.keys:
print(m())
print(list(m()))
+# print a view with more than one item
+print({1:1, 2:1}.values())
+
+# unsupported binary op on a dict values view
+try:
+ {1:1}.values() + 1
+except TypeError:
+ print('TypeError')
+
+# unsupported binary op on a dict keys view
+try:
+ {1:1}.keys() + 1
+except TypeError:
+ print('TypeError')
+
# set operations still to come
diff --git a/tests/basics/for_range.py b/tests/basics/for_range.py
index ddff5ebd4..58a8f7caa 100644
--- a/tests/basics/for_range.py
+++ b/tests/basics/for_range.py
@@ -35,6 +35,11 @@ try:
except TypeError:
print('TypeError')
try:
+ for x in range(start=0, end=1):
+ print(x)
+except TypeError:
+ print('TypeError')
+try:
for x in range(0, 1, step=1):
print(x)
except TypeError:
diff --git a/tests/basics/int_constfolding.py b/tests/basics/int_constfolding.py
index c01f964da..aa38fa6b8 100644
--- a/tests/basics/int_constfolding.py
+++ b/tests/basics/int_constfolding.py
@@ -38,3 +38,8 @@ print(-123 // 7, -123 % 7)
print(123 // -7, 123 % -7)
print(-123 // -7, -123 % -7)
+# zero big-num on rhs
+print(1 + ((1 << 65) - (1 << 65)))
+
+# negative big-num on rhs
+print(1 + (-(1 << 65)))
diff --git a/tests/basics/slice_attrs.py b/tests/basics/slice_attrs.py
index 76368a78c..67456ff8e 100644
--- a/tests/basics/slice_attrs.py
+++ b/tests/basics/slice_attrs.py
@@ -14,3 +14,12 @@ except:
A()[1:2:3]
+
+# test storing to attr (shouldn't be allowed)
+class B:
+ def __getitem__(self, idx):
+ try:
+ idx.start = 0
+ except AttributeError:
+ print('AttributeError')
+B()[:]
diff --git a/tests/basics/syntaxerror.py b/tests/basics/syntaxerror.py
index 2ae0183f8..e5cbbac06 100644
--- a/tests/basics/syntaxerror.py
+++ b/tests/basics/syntaxerror.py
@@ -49,6 +49,9 @@ test_syntax("f[0]**2 = 1")
# can't assign to empty tuple
test_syntax("() = 1")
+# can't have *x on RHS
+test_syntax("x = *x")
+
# can't have multiple *x on LHS
test_syntax("*a, *b = c")
@@ -76,6 +79,7 @@ test_syntax("continue")
test_syntax("return")
test_syntax("yield")
test_syntax("nonlocal a")
+test_syntax("await 1")
# error on uPy, warning on CPy
#test_syntax("def f():\n a = 1\n global a")
diff --git a/tests/basics/unpack1.py b/tests/basics/unpack1.py
index 10e01dea0..0e8ec592c 100644
--- a/tests/basics/unpack1.py
+++ b/tests/basics/unpack1.py
@@ -12,6 +12,7 @@ a, b, c = range(3); print(a, b, c)
(a,) = range(1); print(a)
(a, b) = range(2); print(a, b)
(a, b, c) = range(3); print(a, b, c)
+(a, (b, c)) = [-1, range(2)]; print(a, b, c)
# lists
diff --git a/tests/cmdline/cmd_showbc.py b/tests/cmdline/cmd_showbc.py
index 9989a7229..2f4e953bb 100644
--- a/tests/cmdline/cmd_showbc.py
+++ b/tests/cmdline/cmd_showbc.py
@@ -34,12 +34,14 @@ def f():
# subscript
p = b[0]
b[0] = p
+ b[0] += p
# slice
a = b[::]
# sequenc unpacking
a, b = c
+ a, *a = a
# tuple swapping
a, b = b, a
@@ -79,6 +81,7 @@ def f():
b
while not a:
b
+ a = a or a
# for loop
for a in b:
@@ -92,6 +95,11 @@ def f():
b
finally:
c
+ while a:
+ try:
+ break
+ except:
+ pass
# with
with a:
@@ -117,6 +125,12 @@ def f():
return
return 1
+# function with lots of locals
+def f():
+ l1 = l2 = l3 = l4 = l5 = l6 = l7 = l8 = l9 = l10 = 1
+ m1 = m2 = m3 = m4 = m5 = m6 = m7 = m8 = m9 = m10 = 2
+ l10 + m10
+
# functions with default args
def f(a=1):
pass
@@ -133,3 +147,6 @@ def f():
# class
class Class:
pass
+
+# delete name
+del Class
diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp
index 0e5c55942..1f0c054cf 100644
--- a/tests/cmdline/cmd_showbc.py.exp
+++ b/tests/cmdline/cmd_showbc.py.exp
@@ -7,9 +7,11 @@ arg names:
(N_EXC_STACK 0)
bc=-1 line=1
########
- bc=\\d\+ line=134
+ bc=\\d\+ line=152
00 MAKE_FUNCTION \.\+
\\d\+ STORE_NAME f
+\\d\+ MAKE_FUNCTION \.\+
+\\d\+ STORE_NAME f
\\d\+ LOAD_CONST_SMALL_INT 1
\\d\+ BUILD_TUPLE 1
\\d\+ LOAD_NULL
@@ -22,6 +24,7 @@ arg names:
\\d\+ LOAD_CONST_STRING 'Class'
\\d\+ CALL_FUNCTION n=2 nkw=0
\\d\+ STORE_NAME Class
+\\d\+ DELETE_NAME Class
\\d\+ LOAD_CONST_NONE
\\d\+ RETURN_VALUE
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes)
@@ -35,7 +38,7 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
(INIT_CELL 16)
bc=-4 line=1
########
- bc=\\d\+ line=118
+ bc=\\d\+ line=126
00 LOAD_CONST_NONE
01 LOAD_CONST_FALSE
02 BINARY_OP 5 __add__
@@ -123,6 +126,14 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ LOAD_CONST_SMALL_INT 0
\\d\+ STORE_SUBSCR
\\d\+ LOAD_DEREF 14
+\\d\+ LOAD_CONST_SMALL_INT 0
+\\d\+ DUP_TOP_TWO
+\\d\+ LOAD_SUBSCR
+\\d\+ LOAD_FAST 12
+\\d\+ BINARY_OP 18 __iadd__
+\\d\+ ROT_THREE
+\\d\+ STORE_SUBSCR
+\\d\+ LOAD_DEREF 14
\\d\+ LOAD_CONST_NONE
\\d\+ LOAD_CONST_NONE
\\d\+ BUILD_SLICE 2
@@ -132,6 +143,10 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ UNPACK_SEQUENCE 2
\\d\+ STORE_FAST 0
\\d\+ STORE_DEREF 14
+\\d\+ LOAD_FAST 0
+\\d\+ UNPACK_EX 1
+\\d\+ STORE_FAST 0
+\\d\+ STORE_FAST 0
\\d\+ LOAD_DEREF 14
\\d\+ LOAD_FAST 0
\\d\+ ROT_TWO
@@ -225,6 +240,10 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ POP_TOP
\\d\+ LOAD_FAST 0
\\d\+ POP_JUMP_IF_FALSE \\d\+
+\\d\+ LOAD_FAST 0
+\\d\+ JUMP_IF_TRUE_OR_POP \\d\+
+\\d\+ LOAD_FAST 0
+\\d\+ STORE_FAST 0
\\d\+ LOAD_DEREF 14
\\d\+ GET_ITER
\\d\+ FOR_ITER \\d\+
@@ -251,6 +270,17 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
\\d\+ LOAD_FAST 1
\\d\+ POP_TOP
\\d\+ END_FINALLY
+\\d\+ JUMP \\d\+
+\\d\+ SETUP_EXCEPT \\d\+
+\\d\+ UNWIND_JUMP \\d\+ 1
+\\d\+ POP_BLOCK
+\\d\+ JUMP \\d\+
+\\d\+ POP_TOP
+\\d\+ POP_EXCEPT
+\\d\+ JUMP \\d\+
+\\d\+ END_FINALLY
+\\d\+ LOAD_FAST 0
+\\d\+ POP_JUMP_IF_TRUE \\d\+
\\d\+ LOAD_FAST 0
\\d\+ SETUP_WITH \\d\+
\\d\+ POP_TOP
@@ -291,13 +321,68 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes)
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
########
+\.\+rg names:
+(N_STATE 22)
+(N_EXC_STACK 0)
+ bc=-1 line=1
+########
+ bc=\\d\+ line=132
+00 LOAD_CONST_SMALL_INT 1
+01 DUP_TOP
+02 STORE_FAST 0
+03 DUP_TOP
+04 STORE_FAST 1
+05 DUP_TOP
+06 STORE_FAST 2
+07 DUP_TOP
+08 STORE_FAST 3
+09 DUP_TOP
+10 STORE_FAST 4
+11 DUP_TOP
+12 STORE_FAST 5
+13 DUP_TOP
+14 STORE_FAST 6
+15 DUP_TOP
+16 STORE_FAST 7
+17 DUP_TOP
+18 STORE_FAST 8
+19 STORE_FAST 9
+20 LOAD_CONST_SMALL_INT 2
+21 DUP_TOP
+22 STORE_FAST 10
+23 DUP_TOP
+24 STORE_FAST 11
+25 DUP_TOP
+26 STORE_FAST 12
+27 DUP_TOP
+28 STORE_FAST 13
+29 DUP_TOP
+30 STORE_FAST 14
+31 DUP_TOP
+32 STORE_FAST 15
+33 DUP_TOP
+34 STORE_FAST_N 16
+36 DUP_TOP
+37 STORE_FAST_N 17
+39 DUP_TOP
+40 STORE_FAST_N 18
+42 STORE_FAST_N 19
+44 LOAD_FAST 9
+45 LOAD_FAST_N 19
+47 BINARY_OP 5 __add__
+48 POP_TOP
+49 LOAD_CONST_NONE
+50 RETURN_VALUE
+File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes)
+Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
+########
\.\+5b
arg names: a
(N_STATE 5)
(N_EXC_STACK 0)
(INIT_CELL 0)
########
- bc=\\d\+ line=124
+ bc=\\d\+ line=138
00 LOAD_CONST_SMALL_INT 2
01 BUILD_TUPLE 1
03 LOAD_NULL
@@ -314,9 +399,9 @@ arg names:
(N_STATE 2)
(N_EXC_STACK 0)
bc=-1 line=1
- bc=0 line=129
- bc=3 line=130
- bc=6 line=131
+ bc=0 line=143
+ bc=3 line=144
+ bc=6 line=145
00 LOAD_CONST_NONE
01 YIELD_VALUE
02 POP_TOP
@@ -338,7 +423,7 @@ arg names:
(N_STATE 1)
(N_EXC_STACK 0)
bc=-1 line=1
- bc=13 line=135
+ bc=13 line=149
00 LOAD_NAME __name__ (cache=0)
04 STORE_NAME __module__
07 LOAD_CONST_STRING 'Class'
@@ -411,7 +496,7 @@ arg names: *
(N_EXC_STACK 0)
bc=-\\d\+ line=1
########
- bc=\\d\+ line=105
+ bc=\\d\+ line=113
00 LOAD_DEREF 0
02 LOAD_CONST_SMALL_INT 1
03 BINARY_OP 5 __add__
@@ -430,7 +515,7 @@ arg names: * b
(N_EXC_STACK 0)
bc=-\\d\+ line=1
########
- bc=\\d\+ line=125
+ bc=\\d\+ line=139
00 LOAD_FAST 1
01 LOAD_DEREF 0
03 BINARY_OP 5 __add__
diff --git a/tests/cmdline/repl_basic.py b/tests/cmdline/repl_basic.py
index b416493dc..cbd5d3a4a 100644
--- a/tests/cmdline/repl_basic.py
+++ b/tests/cmdline/repl_basic.py
@@ -1,3 +1,4 @@
# basic REPL tests
print(1)

+2
diff --git a/tests/cmdline/repl_basic.py.exp b/tests/cmdline/repl_basic.py.exp
index 96b8c28dc..2b390ea98 100644
--- a/tests/cmdline/repl_basic.py.exp
+++ b/tests/cmdline/repl_basic.py.exp
@@ -5,4 +5,6 @@ Use \.\+
1
>>> print(1)
1
+>>> 2
+2
>>>
diff --git a/tests/extmod/ujson_load.py b/tests/extmod/ujson_load.py
new file mode 100644
index 000000000..bf484a207
--- /dev/null
+++ b/tests/extmod/ujson_load.py
@@ -0,0 +1,11 @@
+try:
+ from uio import StringIO
+ import ujson as json
+except:
+ from io import StringIO
+ import json
+
+print(json.load(StringIO('null')))
+print(json.load(StringIO('"abc\\u0064e"')))
+print(json.load(StringIO('[false, true, 1, -2]')))
+print(json.load(StringIO('{"a":true}')))
diff --git a/tests/extmod/vfs_fat_ramdisk.py b/tests/extmod/vfs_fat_ramdisk.py
index f470dbcfe..6380761c6 100644
--- a/tests/extmod/vfs_fat_ramdisk.py
+++ b/tests/extmod/vfs_fat_ramdisk.py
@@ -41,8 +41,8 @@ except MemoryError:
uos.VfsFat.mkfs(bdev)
-assert b"FOO_FILETXT" not in bdev.data
-assert b"hello!" not in bdev.data
+print(b"FOO_FILETXT" not in bdev.data)
+print(b"hello!" not in bdev.data)
vfs = uos.VfsFat(bdev, "/ramdisk")
print("statvfs:", vfs.statvfs("/ramdisk"))
@@ -57,44 +57,66 @@ f2 = vfs.open("foo_file.txt")
print(f2.read())
f2.close()
-assert b"FOO_FILETXT" in bdev.data
-assert b"hello!" in bdev.data
+print(b"FOO_FILETXT" in bdev.data)
+print(b"hello!" in bdev.data)
-assert vfs.listdir() == ['foo_file.txt']
+print(vfs.listdir())
+
+try:
+ vfs.rmdir("foo_file.txt")
+except OSError as e:
+ print(e.args[0] == 20) # uerrno.ENOTDIR
vfs.remove('foo_file.txt')
-assert vfs.listdir() == []
+print(vfs.listdir())
vfs.mkdir("foo_dir")
-assert vfs.listdir() == ['foo_dir']
+print(vfs.listdir())
+
+try:
+ vfs.remove("foo_dir")
+except OSError as e:
+ print(e.args[0] == uerrno.EISDIR)
+
f = vfs.open("foo_dir/file-in-dir.txt", "w")
f.write("data in file")
f.close()
-assert vfs.listdir("foo_dir") == ['file-in-dir.txt']
+print(vfs.listdir("foo_dir"))
vfs.rename("foo_dir/file-in-dir.txt", "moved-to-root.txt")
-assert vfs.listdir() == ['foo_dir', 'moved-to-root.txt']
+print(vfs.listdir())
vfs.chdir("foo_dir")
print("getcwd:", vfs.getcwd())
-assert vfs.listdir() == []
+print(vfs.listdir())
with vfs.open("sub_file.txt", "w") as f:
f.write("test2")
-assert vfs.listdir() == ["sub_file.txt"]
+print(vfs.listdir())
+
+try:
+ vfs.chdir("sub_file.txt")
+except OSError as e:
+ print(e.args[0] == uerrno.ENOENT)
vfs.chdir("..")
print("getcwd:", vfs.getcwd())
+try:
+ vfs.rmdir("foo_dir")
+except OSError as e:
+ print(e.args[0] == uerrno.EACCES)
+
+vfs.remove("foo_dir/sub_file.txt")
+vfs.rmdir("foo_dir")
+print(vfs.listdir())
vfs.umount()
try:
vfs.listdir()
except OSError as e:
- assert e.args[0] == uerrno.ENODEV
-else:
- raise AssertionError("expected OSError not thrown")
+ print(e.args[0] == uerrno.ENODEV)
vfs = uos.VfsFat(bdev, "/ramdisk")
-assert vfs.listdir() == ['foo_dir', 'moved-to-root.txt']
+print(vfs.listdir())
diff --git a/tests/extmod/vfs_fat_ramdisk.py.exp b/tests/extmod/vfs_fat_ramdisk.py.exp
index fd893b6e4..8a498b2fc 100644
--- a/tests/extmod/vfs_fat_ramdisk.py.exp
+++ b/tests/extmod/vfs_fat_ramdisk.py.exp
@@ -1,5 +1,23 @@
+True
+True
statvfs: (512, 512, 14, 14, 14, 0, 0, 0, 0, 255)
getcwd: /ramdisk
hello!
+True
+True
+['foo_file.txt']
+True
+[]
+['foo_dir']
+True
+['file-in-dir.txt']
+['foo_dir', 'moved-to-root.txt']
getcwd: /ramdisk/foo_dir
+[]
+['sub_file.txt']
+True
getcwd: /ramdisk
+True
+['moved-to-root.txt']
+True
+['moved-to-root.txt']
diff --git a/tests/import/import2a.py b/tests/import/import2a.py
index ce32b10b1..def6aeb6a 100644
--- a/tests/import/import2a.py
+++ b/tests/import/import2a.py
@@ -1,2 +1,5 @@
from import1b import var
print(var)
+
+from import1b import var as var2
+print(var2)
diff --git a/tests/micropython/emg_exc.py b/tests/micropython/emg_exc.py
new file mode 100644
index 000000000..d228e6faa
--- /dev/null
+++ b/tests/micropython/emg_exc.py
@@ -0,0 +1,20 @@
+# test that emergency exceptions work
+
+import micropython
+import sys
+
+# some ports need to allocate heap for the emg exc
+try:
+ micropython.alloc_emergency_exception_buf(256)
+except AttributeError:
+ pass
+
+def f():
+ micropython.heap_lock()
+ try:
+ raise ValueError(1)
+ except ValueError as er:
+ sys.print_exception(er)
+ micropython.heap_unlock()
+
+f()
diff --git a/tests/micropython/emg_exc.py.exp b/tests/micropython/emg_exc.py.exp
new file mode 100644
index 000000000..82b10b5f5
--- /dev/null
+++ b/tests/micropython/emg_exc.py.exp
@@ -0,0 +1 @@
+ValueError:
diff --git a/tests/micropython/heap_lock.py b/tests/micropython/heap_lock.py
new file mode 100644
index 000000000..0f0a70eff
--- /dev/null
+++ b/tests/micropython/heap_lock.py
@@ -0,0 +1,14 @@
+# check that heap_lock/heap_unlock work as expected
+
+import micropython
+
+micropython.heap_lock()
+
+try:
+ print([])
+except MemoryError:
+ print('MemoryError')
+
+micropython.heap_unlock()
+
+print([])
diff --git a/tests/micropython/heap_lock.py.exp b/tests/micropython/heap_lock.py.exp
new file mode 100644
index 000000000..67b208cfc
--- /dev/null
+++ b/tests/micropython/heap_lock.py.exp
@@ -0,0 +1,2 @@
+MemoryError
+[]
diff --git a/tests/micropython/heapalloc.py b/tests/micropython/heapalloc.py
index 2dc7fa5e7..a651158ca 100644
--- a/tests/micropython/heapalloc.py
+++ b/tests/micropython/heapalloc.py
@@ -1,6 +1,6 @@
# check that we can do certain things without allocating heap memory
-import gc
+import micropython
def f1(a):
print(a)
@@ -28,12 +28,7 @@ def test():
f2(i, i) # 2 args
f3(1, 2, 3, 4) # function with lots of local state
-# call h with heap allocation disabled and all memory used up
-gc.disable()
-try:
- while True:
- 'a'.lower # allocates 1 cell for boundmeth
-except MemoryError:
- pass
+# call test() with heap allocation disabled
+micropython.heap_lock()
test()
-gc.enable()
+micropython.heap_unlock()
diff --git a/tests/micropython/opt_level.py b/tests/micropython/opt_level.py
new file mode 100644
index 000000000..4e2f2f4ea
--- /dev/null
+++ b/tests/micropython/opt_level.py
@@ -0,0 +1,14 @@
+import micropython as micropython
+
+# check we can get and set the level
+micropython.opt_level(0)
+print(micropython.opt_level())
+micropython.opt_level(1)
+print(micropython.opt_level())
+
+# check that the optimisation levels actually differ
+micropython.opt_level(0)
+exec('print(__debug__)')
+micropython.opt_level(1)
+exec('print(__debug__)')
+exec('assert 0')
diff --git a/tests/micropython/opt_level.py.exp b/tests/micropython/opt_level.py.exp
new file mode 100644
index 000000000..74b3dd74e
--- /dev/null
+++ b/tests/micropython/opt_level.py.exp
@@ -0,0 +1,4 @@
+0
+1
+True
+False
diff --git a/tests/micropython/viper_args.py b/tests/micropython/viper_args.py
index ca2a5e670..2aebe1b04 100644
--- a/tests/micropython/viper_args.py
+++ b/tests/micropython/viper_args.py
@@ -26,3 +26,11 @@ def f4(x1:int, x2:int, x3:int, x4:int):
f4(1, 2, 3, 4)
# only up to 4 arguments currently supported
+
+# test compiling *x, **x, * args (currently unsupported at runtime)
+@micropython.viper
+def f(*x, **y):
+ pass
+@micropython.viper
+def f(*):
+ pass
diff --git a/tests/misc/non_compliant.py b/tests/misc/non_compliant.py
index 1157ff8b2..677438b83 100644
--- a/tests/misc/non_compliant.py
+++ b/tests/misc/non_compliant.py
@@ -3,6 +3,18 @@
import array
import ustruct
+# when super can't find self
+try:
+ exec('def f(): super()')
+except SyntaxError:
+ print('SyntaxError')
+
+# store to exception attribute is not allowed
+try:
+ ValueError().x = 0
+except AttributeError:
+ print('AttributeError')
+
# array deletion not implemented
try:
a = array.array('b', (1, 2, 3))
@@ -17,6 +29,12 @@ try:
except NotImplementedError:
print('NotImplementedError')
+# containment, looking for integer not implemented
+try:
+ print(1 in array.array('B', b'12'))
+except NotImplementedError:
+ print('NotImplementedError')
+
# should raise type error
try:
print(set('12') >= '1')
@@ -59,6 +77,12 @@ try:
except NotImplementedError:
print('NotImplementedError')
+# str subscr with step!=1 not implemented
+try:
+ print('abc'[1:2:3])
+except NotImplementedError:
+ print('NotImplementedError')
+
# bytes(...) with keywords not implemented
try:
bytes('abc', encoding='utf8')
diff --git a/tests/misc/non_compliant.py.exp b/tests/misc/non_compliant.py.exp
index c03580442..737650e9e 100644
--- a/tests/misc/non_compliant.py.exp
+++ b/tests/misc/non_compliant.py.exp
@@ -1,5 +1,8 @@
+SyntaxError
+AttributeError
TypeError
NotImplementedError
+NotImplementedError
True
True
TypeError, ValueError
@@ -12,5 +15,6 @@ NotImplementedError
NotImplementedError
NotImplementedError
NotImplementedError
+NotImplementedError
b'\x01\x02'
b'\x01\x00'
diff --git a/tests/run-tests b/tests/run-tests
index cb920c094..4ac7d8e28 100755
--- a/tests/run-tests
+++ b/tests/run-tests
@@ -237,7 +237,6 @@ def run_tests(pyb, tests, args):
skip_tests.add('float/float_divmod.py') # tested by float/float_divmod_relaxed.py instead
skip_tests.add('float/float2int_doubleprec.py') # requires double precision floating point to work
skip_tests.add('micropython/meminfo.py') # output is very different to PC output
- skip_tests.add('extmod/machine1.py') # raw memory access not supported
skip_tests.add('extmod/machine_mem.py') # raw memory access not supported
if args.target == 'wipy':
@@ -273,7 +272,7 @@ def run_tests(pyb, tests, args):
if args.emit == 'native':
skip_tests.update({'basics/%s.py' % t for t in 'gen_yield_from gen_yield_from_close gen_yield_from_ducktype gen_yield_from_exc gen_yield_from_iter gen_yield_from_send gen_yield_from_stopped gen_yield_from_throw generator1 generator2 generator_args generator_close generator_closure generator_exc generator_return generator_send'.split()}) # require yield
skip_tests.update({'basics/%s.py' % t for t in 'bytes_gen class_store_class globals_del string_join'.split()}) # require yield
- skip_tests.update({'basics/async_%s.py' % t for t in 'await await2 for for2 with with2'.split()}) # require yield
+ skip_tests.update({'basics/async_%s.py' % t for t in 'def await await2 for for2 with with2'.split()}) # require yield
skip_tests.update({'basics/%s.py' % t for t in 'try_reraise try_reraise2'.split()}) # require raise_varargs
skip_tests.update({'basics/%s.py' % t for t in 'with_break with_continue with_return'.split()}) # require complete with support
skip_tests.add('basics/array_construct2.py') # requires generators
diff --git a/tests/unicode/unicode.py b/tests/unicode/unicode.py
index b31f064e9..5f29bc1c9 100644
--- a/tests/unicode/unicode.py
+++ b/tests/unicode/unicode.py
@@ -18,8 +18,9 @@ enc = s.encode()
print(enc, enc.decode() == s)
# printing of unicode chars using repr
-# TODO we don't do this correctly
-#print(repr(s))
+# NOTE: for some characters (eg \u10ff) we differ to CPython
+print(repr('a\uffff'))
+print(repr('a\U0001ffff'))
# test invalid escape code
try:
diff --git a/tools/micropython-upip-1.0.tar.gz b/tools/micropython-upip-1.0.tar.gz
deleted file mode 100644
index f34915070..000000000
--- a/tools/micropython-upip-1.0.tar.gz
+++ /dev/null
Binary files differ
diff --git a/tools/micropython-upip-1.1.3.tar.gz b/tools/micropython-upip-1.1.3.tar.gz
new file mode 100644
index 000000000..90f726d86
--- /dev/null
+++ b/tools/micropython-upip-1.1.3.tar.gz
Binary files differ
diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py
index 091c1b065..bab937135 100755
--- a/tools/tinytest-codegen.py
+++ b/tools/tinytest-codegen.py
@@ -46,8 +46,15 @@ testgroup_member = (
## XXX: may be we could have `--without <groups>` argument...
# currently these tests are selected because they pass on qemu-arm
-test_dirs = ('basics', 'micropython', 'inlineasm') # 'float', 'import', 'io', 'misc')
-exclude_tests = ('inlineasm/asmfpaddsub.py', 'inlineasm/asmfpcmp.py', 'inlineasm/asmfpldrstr.py', 'inlineasm/asmfpmuldiv.py', 'inlineasm/asmfpsqrt.py',)
+test_dirs = ('basics', 'micropython', 'extmod', 'inlineasm') # 'float', 'import', 'io', 'misc')
+exclude_tests = (
+ 'inlineasm/asmfpaddsub.py', 'inlineasm/asmfpcmp.py', 'inlineasm/asmfpldrstr.py', 'inlineasm/asmfpmuldiv.py', 'inlineasm/asmfpsqrt.py',
+ 'extmod/time_ms_us.py',
+ 'extmod/ujson_dumps_float.py', 'extmod/ujson_loads_float.py',
+ 'extmod/uctypes_native_float.py', 'extmod/uctypes_le_float.py',
+ 'extmod/machine_pinbase.py', 'extmod/machine_pulse.py',
+ 'extmod/vfs_fat_ramdisk.py',
+)
output = []
diff --git a/unix/Makefile b/unix/Makefile
index 4a313b3a8..53ff4cb48 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -273,7 +273,7 @@ coverage_test: coverage
gcov -o build-coverage/extmod ../extmod/*.c
$(BUILD)/_frozen_upip.c: $(BUILD)/frozen_upip/upip.py
- ../tools/make-frozen.py $(dir $^) > $@
+ $(MAKE_FROZEN) $(dir $^) > $@
# Select latest upip version available
UPIP_TARBALL := $(shell ls -1 -v ../tools/micropython-upip-*.tar.gz | tail -n1)
diff --git a/unix/coverage.c b/unix/coverage.c
index c84a653f7..6a1b43fdc 100644
--- a/unix/coverage.c
+++ b/unix/coverage.c
@@ -34,7 +34,7 @@ STATIC mp_obj_t extra_coverage(void) {
// vstr
{
mp_printf(&mp_plat_print, "# vstr\n");
- vstr_t *vstr = vstr_new_size(16);
+ vstr_t *vstr = vstr_new(16);
vstr_hint_size(vstr, 32);
vstr_add_str(vstr, "ts");
vstr_ins_byte(vstr, 1, 'e');
diff --git a/zephyr/Makefile b/zephyr/Makefile
index d0dce488d..9682dc5cc 100644
--- a/zephyr/Makefile
+++ b/zephyr/Makefile
@@ -15,6 +15,8 @@ BOARD ?= qemu_x86
# Zephyr 1.6.0
OUTDIR_PREFIX = $(BOARD)
+FROZEN_DIR = scripts
+
# Zephyr (generated) config files - must be defined before include below
Z_SYSGEN_H = outdir/$(OUTDIR_PREFIX)/misc/generated/sysgen/sysgen.h
Z_EXPORTS = outdir/$(OUTDIR_PREFIX)/Makefile.export
@@ -31,13 +33,19 @@ INC += -I$(ZEPHYR_BASE)/net/ip/contiki
INC += -I$(ZEPHYR_BASE)/net/ip/contiki/os
SRC_C = main.c \
+ help.c \
uart_core.c \
lib/utils/stdout_helpers.c \
lib/utils/printf.c \
lib/utils/pyexec.c \
+ lib/utils/interrupt_char.c \
+ lib/utils/pyhelp.c \
lib/mp-readline/readline.c \
$(SRC_MOD)
+# List of sources for qstr extraction
+SRC_QSTR += $(SRC_C)
+
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
CFLAGS = $(KBUILD_CFLAGS) $(NOSTDINC_FLAGS) $(ZEPHYRINCLUDE) \
diff --git a/zephyr/README.md b/zephyr/README.md
index 43e92c787..63fb0e39f 100644
--- a/zephyr/README.md
+++ b/zephyr/README.md
@@ -41,5 +41,5 @@ qemu_cortex_m3):
make qemu
-For deploying/flashing teh application on a real board, follow Zephyr
+For deploying/flashing the application on a real board, follow Zephyr
documentation for a given board.
diff --git a/zephyr/help.c b/zephyr/help.c
new file mode 100644
index 000000000..e574adf47
--- /dev/null
+++ b/zephyr/help.c
@@ -0,0 +1,56 @@
+/*
+ * 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 <stdio.h>
+
+#include "lib/utils/pyhelp.h"
+
+STATIC const char *help_text =
+"Welcome to MicroPython!\n"
+"\n"
+"Control commands:\n"
+" CTRL-A -- on a blank line, enter raw REPL mode\n"
+" CTRL-B -- on a blank line, enter normal REPL mode\n"
+" CTRL-C -- interrupt a running program\n"
+" CTRL-D -- on a blank line, do a soft reset of the board\n"
+" CTRL-E -- on a blank line, enter paste mode\n"
+"\n"
+"For further help on a specific object, type help(obj)\n"
+;
+
+STATIC mp_obj_t builtin_help(uint n_args, const mp_obj_t *args) {
+ if (n_args == 0) {
+ // print a general help message
+ printf("%s", help_text);
+
+ } else {
+ // try to print something sensible about the given object
+ pyhelp_print_obj(args[0]);
+ }
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, builtin_help);
diff --git a/zephyr/main.c b/zephyr/main.c
index 65074b157..8d319098b 100644
--- a/zephyr/main.c
+++ b/zephyr/main.c
@@ -1,3 +1,29 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2016 Linaro Limited
+ *
+ * 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 <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -7,7 +33,9 @@
#include "py/runtime.h"
#include "py/repl.h"
#include "py/gc.h"
+#include "py/stackctrl.h"
#include "lib/utils/pyexec.h"
+#include "lib/mp-readline/readline.h"
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
@@ -35,11 +63,16 @@ static char heap[16 * 1024];
int real_main(void) {
int stack_dummy;
stack_top = (char*)&stack_dummy;
+ mp_stack_set_top(stack_top);
+ // Should be set to stack size in prj.mdef minus fuzz factor
+ mp_stack_set_limit(3584);
#if MICROPY_ENABLE_GC
gc_init(heap, heap + sizeof(heap));
#endif
mp_init();
+ MP_STATE_PORT(mp_kbd_exception) = mp_obj_new_exception(&mp_type_KeyboardInterrupt);
+ pyexec_frozen_module("main.py");
#if MICROPY_REPL_EVENT_DRIVEN
pyexec_event_repl_init();
for (;;) {
diff --git a/zephyr/mpconfigport.h b/zephyr/mpconfigport.h
index cf5884e0e..1654e79b8 100644
--- a/zephyr/mpconfigport.h
+++ b/zephyr/mpconfigport.h
@@ -1,10 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Linaro Limited
+ *
+ * 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 <alloca.h>
+// Include Zephyr's autoconf.h, which should be made first by Zephyr makefiles
+#include "autoconf.h"
+
// Saving extra crumbs to make sure binary fits in 128K
#define MICROPY_COMP_CONST_FOLDING (0)
#define MICROPY_COMP_CONST (0)
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
+#define MICROPY_STACK_CHECK (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_HELPER_REPL (1)
#define MICROPY_REPL_AUTO_INDENT (1)
@@ -23,6 +52,7 @@
#define MICROPY_PY_COLLECTIONS (0)
#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_IO (0)
+#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_STRUCT (0)
#define MICROPY_PY_SYS_MODULES (0)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
@@ -30,6 +60,7 @@
#define MICROPY_PY_BUILTINS_COMPLEX (0)
#define MICROPY_HW_BOARD_NAME "zephyr-generic"
#define MICROPY_HW_MCU_NAME "unknown-cpu"
+#define MICROPY_MODULE_FROZEN_STR (1)
typedef int mp_int_t; // must be pointer size
typedef unsigned mp_uint_t; // must be pointer size
@@ -43,7 +74,10 @@ typedef long mp_off_t;
#define MP_STATE_PORT MP_STATE_VM
#define MICROPY_PORT_ROOT_POINTERS \
+ mp_obj_t mp_kbd_exception; \
const char *readline_hist[8];
-// Include Zephyr's autoconf.h, which should be made first by Zephyr makefiles
-#include "autoconf.h"
+// extra built in names to add to the global namespace
+#define MICROPY_PORT_BUILTINS \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \
+
diff --git a/zephyr/mphalport.h b/zephyr/mphalport.h
index 60d68bd2d..1bb64e000 100644
--- a/zephyr/mphalport.h
+++ b/zephyr/mphalport.h
@@ -1,2 +1 @@
static inline mp_uint_t mp_hal_ticks_ms(void) { return 0; }
-static inline void mp_hal_set_interrupt_char(char c) {}
diff --git a/zephyr/src/zephyr_getchar.c b/zephyr/src/zephyr_getchar.c
index 3a1898a60..89e3e0efb 100644
--- a/zephyr/src/zephyr_getchar.c
+++ b/zephyr/src/zephyr_getchar.c
@@ -20,6 +20,9 @@
#include <misc/printk.h>
#include "zephyr_getchar.h"
+extern int mp_interrupt_char;
+void mp_keyboard_interrupt(void);
+
static struct nano_sem uart_sem;
#define UART_BUFSIZE 256
static uint8_t uart_ringbuf[UART_BUFSIZE];
@@ -32,8 +35,13 @@ static int console_irq_input_hook(struct device *dev, uint8_t ch)
printk("UART buffer overflow - char dropped\n");
return 1;
}
- uart_ringbuf[i_put] = ch;
- i_put = i_next;
+ if (ch == mp_interrupt_char) {
+ mp_keyboard_interrupt();
+ return 1;
+ } else {
+ uart_ringbuf[i_put] = ch;
+ i_put = i_next;
+ }
//printk("%x\n", ch);
nano_isr_sem_give(&uart_sem);
return 1;
diff --git a/zephyr/src/zephyr_start.c b/zephyr/src/zephyr_start.c
index b490cc770..9e8a90beb 100644
--- a/zephyr/src/zephyr_start.c
+++ b/zephyr/src/zephyr_start.c
@@ -1,3 +1,28 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Linaro Limited
+ *
+ * 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 <zephyr.h>
#include "zephyr_getchar.h"
diff --git a/zephyr/uart_core.c b/zephyr/uart_core.c
index 5f48f973f..702c97d20 100644
--- a/zephyr/uart_core.c
+++ b/zephyr/uart_core.c
@@ -1,3 +1,28 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Linaro Limited
+ *
+ * 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 <unistd.h>
#include "py/mpconfig.h"
#include "src/zephyr_getchar.h"