Merge tag 'v1.8.6' into parse-bytecode
ESP8266 port uses SDK 2.0, has more heap, has support for 512k devices This release brings some code size reductions to the core as well as more tests and improved coverage which is now at 94.3%. The time.ticks_diff(a, b) function has changed: the order of the arguments has been swapped so that it behaves like "a - b", and it can now return a negative number if "a" came before "b" (modulo the period of the ticks functions). For the ESP8266 port the Espressif SDK has been updated to 2.0.0, the heap has been increased from 28k to 36k, and there is support for 512k devices via "make 512k". upip is included by default as frozen bytecode. The network module now allows access-point reconnection without WiFi credentials, and exposes configuration for the station DHCP hostname. The DS18B20 driver now handles negative temperatures, and NeoPixel and APA102 drivers handle 4 bytes-per-pixel LEDs. For the CC3200 port there is now support for loading of precompiled .mpy files and threading now works properly with interrupts. A detailed list of changes follows. py core: - py.mk: automatically add frozen.c to source list if FROZEN_DIR is defined - be more specific with MP_DECLARE_CONST_FUN_OBJ macros - specialise builtin funcs to use separate type for fixed arg count - {modbuiltins,obj}: use MP_PYTHON_PRINTER where possible - modbuiltins: add builtin "slice", pointing to existing slice type - add "delattr" builtin, conditional on MICROPY_CPYTHON_COMPAT - sequence: fix reverse slicing of lists - fix null pointer dereference in mpz.c, fix missing va_end in warning.c - remove asserts that are always true in emitbc.c - fix wrong assumption that m_renew will not move if shrinking - change config default so m_malloc0 uses memset if GC not enabled - add MICROPY_FLOAT_CONST macro for defining float constants - move frozen bytecode Makefile rules from ports to common mk files - strip leading dirs from frozen mpy files, so any path can be used extmod: - vfs_fat_file: check fatfs f_sync() and f_close() returns for errors - vfs_fat_file: make file.close() a no-op if file already closed - utime_mphal: ticks_diff(): switch arg order, return signed value - utime_mphal: add MP_THREAD_GIL_EXIT/ENTER warppers for sleep functions - utime_mphal: implement ticks_add(), add to all maintained ports - utime_mphal: allow ticks functions period be configurable by a port lib: - utils/pyhelp.c: use mp_printf() instead of printf() - utils/pyexec: add mp_hal_set_interrupt_char() prototype - libm: move Thumb-specific sqrtf function to separate file drivers: - add "from micropython import const" when const is used tools: - upgrade upip to 1.1.4: fix error on unix when installing to non-existing absolute path - pip-micropython: remove deprecated wrapper tool - check_code_size.sh: code size validation script for CI - replace upip tarball with just source file, to make its inclusion as frozen modules in multiple ports less magic tests: - extmod/vfs_fat: improve VFS test coverage - basics/builtin_slice: add test for "slice" builtin name - basics: add test for builtin "delattr" - extmod/vfs_fat_fsusermount: improve fsusermount test coverage - extmod/vfs_fat_oldproto: test old block device protocol - basics/gc1: garbage collector threshold() coverage - extmod/uhashlib_sha1: coverage for SHA1 algorithm - extmod/uhashlib_sha256: rename sha256.py test - btree1: fix out of memory error running on esp8266 - extmod/ticks_diff: test for new semantics of ticks_diff() - extmod/framebuf1: test framebuffer pixel clear, and text function minimal port: - Makefile: split rule for firmware.bin generation unix port: - Makefile: remove references to deprecated pip-micropython - modtime: use ticks_diff() implementation from extmod/utime_mphal.c - mphalport.h: add warning of mp_hal_delay_ms() implementation - modtime: switch ticks/sleep_ms/us() to utime_mphal - fix symbol references for x86 Mac - replace upip tarball with just source file windows port: - enable utime_mphal following unix, define mp_hal_ticks_* - fix utime_mphal compilation for msvc - implement mp_hal_ticks_cpu in terms of QueryPerformanceCounter qemu-arm port: - exclude ticks_diff test for qemu-arm port - exclude extmod/vfs_fat_fileio.py test - exclude new vfs_fat tests - enable software floating point support, and float tests stmhal port: - modutime: refactor to use extmod's version of ticks_cpu - refactor pin usage to use mp_hal_pin API - led: refactor LED to use mp_hal_pin_output() init function - Makefile: use standard rules for frozen module generation - modutime: consistently convert to MP_ROM_QSTR/MP_ROM_PTR - enable SD power save (disable CLK on idle) cc3200 port: - use mp_raise_XXX helper functions to reduce code size - mods/pybspi: allow "write" arg of read/readinto to be positional - enable loading of precompiled .mpy files - fix thread mutex's so threading works with interrupts teensy port: - update to provide new mp_hal_pin_XXX functions following stmhal esp8266 port: - Makefile: use latest esptool.py flash size auto-detection - esp_init_data: auto-initialize system params with vendor SDK 2.0.0 - esp8266.ld: move help.o to iROM - esp8266.ld: move modmachine.o to iROM - esp8266.ld: move main.o to iROM - add MP_FASTCODE modifier to put a function to iRAM - main: mark nlr_jump_fail() as MP_FASTCODE - modules/webrepl: enforce only one concurrent WebREPL connection - etshal.h: add few more ESP8266 vendor lib prototypes - modesp: add flash_user_start() function - add support for building firmware version for 512K modules - scripts: make neopixel/apa102 handle 4bpp LEDs with common code - modutime: consistently convert to MP_ROM_QSTR/MP_ROM_PTR - modnetwork: config(): fix copy-paste error in setting "mac" - scripts/port_diag: add descriptions for esf_buf types - modnetwork.c: allows AP reconnection without WiFi credentials - main: bump heap size to 36K - etshal.h: add prototypes for SPIRead/SPIWrite/SPIEraseSector - etshal.h: adjust size of MD5_CTX structure - modules: fix negative temperature in ds18x20 driver - rename "machine" module implementation to use contemporary naming - rework webrepl_setup to run over wired REPL - espneopixel.c: solve glitching LED issues with cpu at 80MHz - include upip as a standard frozen bytecode module - update docs for esptool 1.2.1/SDK 2.0 (--flash_size=detect) - modnetwork.c: expose configuration for station DHCP hostname zephyr port: - implement utime module - use board/SoC values for startup banner based on Zephyr config - initial implementation of machine.Pin - zephyr_getchar: update for recent Zephyr refactor of console hooks - support time -> utime module "weaklink" - README: update for the current featureset, add more info - mpconfigport.h: move less important params to the bottom - Makefile: allow to adjust heap size from make command line - Makefile: update comments to the current state of affairs - Makefile: allow to override Zephyr config from make command line - Makefile: add minimal port - Makefile: add -fomit-frame-pointer to reduce code size - mphalport.h: update for new "unified" kernal API (sleep functions) docs: - machine.SPI: bring up to date with Hardware API, make vendor-neutral - machine.SPI: improve descriptions of xfer methods - library/builtins: add docs for delattr and slice - library/network: reword intro paragraph - library/network: typo fixes, consistent acronym capitalization - library/index: update TOCs so builtins sorted before modules - utime: document ticks_cpu() in more detail - utime: describe new semantics of ticks_diff() (signed ring arithmetics) - utime: add docs for ticks_add(), improvements for other ticks_*() - esp8266: update for new WebREPL setup procedure - */quickref.rst: use new semantics of ticks_diff() - library/machine.Pin: update Pin docs to align with new HW API travis: - integrate tools/check_code_size.sh - minimal: Use CROSS=1, for binary size check examples: - http_server_simplistic: add "not suitable for real use" note - hwapi: example showing best practices for HW API usage in apps - hwapi: add hwconfig for DragonBoard 410c
This commit is contained in:
commit
76b564ca47
10
.travis.yml
10
.travis.yml
|
@ -3,6 +3,9 @@ dist: trusty
|
|||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
cache:
|
||||
directories:
|
||||
- "${HOME}/persist"
|
||||
|
||||
before_script:
|
||||
# Extra CPython versions
|
||||
|
@ -24,7 +27,12 @@ before_script:
|
|||
|
||||
script:
|
||||
- make -C mpy-cross
|
||||
- make -C minimal test
|
||||
- make -C minimal CROSS=1 build/firmware.bin
|
||||
- ls -l minimal/build/firmware.bin
|
||||
- tools/check_code_size.sh
|
||||
- mkdir -p ${HOME}/persist
|
||||
# Save new firmware for reference, but only if building a main branch, not a pull request
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cp minimal/build/firmware.bin ${HOME}/persist/; fi'
|
||||
- make -C unix deplibs
|
||||
- make -C unix
|
||||
- make -C unix nanbox
|
||||
|
|
|
@ -1448,7 +1448,7 @@ indicating that they also supported the first campaign.
|
|||
* 902 B Stevens
|
||||
903 Cptnslick, US
|
||||
904 janlj@me.com
|
||||
905 São Caetano do Sul, SP, Brazil
|
||||
905 Fabricio Biazzotto
|
||||
906 Lenz Hirsch
|
||||
907 SerSher, RU
|
||||
908 Florian, DE
|
||||
|
|
|
@ -26,15 +26,15 @@ time, and struct, etc. Select ports have support for _thread module
|
|||
(multithreading). Note that only subset of Python 3.4 functionality
|
||||
implemented for the data types and modules.
|
||||
|
||||
See the repository www.github.com/micropython/pyboard for the Micro
|
||||
Python board, the officially supported reference electronic circuit board.
|
||||
See the repository www.github.com/micropython/pyboard for the MicroPython
|
||||
board (PyBoard), the officially supported reference electronic circuit board.
|
||||
|
||||
Major components in this repository:
|
||||
- py/ -- the core Python implementation, including compiler, runtime, and
|
||||
core library.
|
||||
- unix/ -- a version of MicroPython that runs on Unix.
|
||||
- stmhal/ -- a version of MicroPython that runs on the MicroPython board
|
||||
with an STM32F405RG (using ST's Cube HAL drivers).
|
||||
- stmhal/ -- a version of MicroPython that runs on the PyBoard and similar
|
||||
STM32 boards (using ST's Cube HAL drivers).
|
||||
- minimal/ -- a minimal MicroPython port. Start with this if you want
|
||||
to port MicroPython to another microcontroller.
|
||||
- tests/ -- test framework and test scripts.
|
||||
|
|
|
@ -61,7 +61,6 @@ typedef long mp_off_t;
|
|||
#define MP_PLAT_PRINT_STRN(str, len) (void)0
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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]),
|
||||
|
|
|
@ -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);
|
||||
// }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
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) {
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,6 @@
|
|||
void rng_init0 (void);
|
||||
uint32_t rng_get (void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(machine_rng_get_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_0(machine_rng_get_obj);
|
||||
|
||||
#endif // __RANDOM_H
|
||||
|
|
|
@ -99,7 +99,7 @@ copyright = '2014-2016, Damien P. George and contributors'
|
|||
# The short X.Y version.
|
||||
version = '1.8'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.8.5'
|
||||
release = '1.8.6'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
|
@ -71,13 +71,16 @@ and developers, who can diagnose themselves any issues arising from
|
|||
modifying the standard process).
|
||||
|
||||
Once the filesystem is mounted, ``boot.py`` is executed from it. The standard
|
||||
version of this file is created during first-time module set up and by
|
||||
default starts up a WebREPL daemon to handle incoming connections. This
|
||||
file is customizable by end users (for example, you may want to disable
|
||||
WebREPL for extra security, or add other services which should be run on
|
||||
version of this file is created during first-time module set up and has
|
||||
commands to start a WebREPL daemon (disabled by default, configurable
|
||||
with ``webrepl_setup`` module), etc. This
|
||||
file is customizable by end users (for example, you may want to set some
|
||||
parameters or add other services which should be run on
|
||||
a module start-up). But keep in mind that incorrect modifications to boot.py
|
||||
may still lead to boot loops or lock ups, requiring to reflash a module
|
||||
from scratch.
|
||||
from scratch. (In particular, it's recommended that you use either
|
||||
``webrepl_setup`` module or manual editing to configure WebREPL, but not
|
||||
both).
|
||||
|
||||
As a final step of boot procedure, ``main.py`` is executed from filesystem,
|
||||
if exists. This file is a hook to start up a user application each time
|
||||
|
|
|
@ -83,7 +83,7 @@ Use the :mod:`time <utime>` module::
|
|||
time.sleep_ms(500) # sleep for 500 milliseconds
|
||||
time.sleep_us(10) # sleep for 10 microseconds
|
||||
start = time.ticks_ms() # get millisecond counter
|
||||
delta = time.ticks_diff(start, time.ticks_ms()) # compute time difference
|
||||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
||||
|
||||
Timers
|
||||
------
|
||||
|
@ -336,29 +336,27 @@ WebREPL (web browser interactive prompt)
|
|||
WebREPL (REPL over WebSockets, accessible via a web browser) is an
|
||||
experimental feature available in ESP8266 port. Download web client
|
||||
from https://github.com/micropython/webrepl (hosted version available
|
||||
at http://micropython.org/webrepl), and start the daemon on a device
|
||||
using::
|
||||
at http://micropython.org/webrepl), and configure it by executing::
|
||||
|
||||
import webrepl_setup
|
||||
|
||||
and following on-screen instructions. After reboot, it will be available
|
||||
for connection. If you disabled automatic start-up on boot, you may
|
||||
run configured daemon on demand using::
|
||||
|
||||
import webrepl
|
||||
webrepl.start()
|
||||
|
||||
(Release versions have it started on boot by default.)
|
||||
|
||||
On a first connection, you will be prompted to set password for future
|
||||
sessions to use.
|
||||
|
||||
The supported way to use WebREPL is by connecting to ESP8266 access point,
|
||||
but the daemon is also started on STA interface if it is active, so if your
|
||||
router is set up and works correctly, you may also use WebREPL while connected
|
||||
to your normal Internet access point (use the ESP8266 AP connection method
|
||||
if you face any issues).
|
||||
|
||||
WebREPL is an experimental feature and a work in progress, and has known
|
||||
issues.
|
||||
Besides terminal/command prompt access, WebREPL also has provision for file
|
||||
transfer (both upload and download). Web client has buttons for the
|
||||
corresponding functions, or you can use command-line client ``webrepl_cli.py``
|
||||
from the repository above.
|
||||
|
||||
There's also provision to transfer (both upload and download)
|
||||
files over WebREPL connection, but it has even more experimental status
|
||||
than the WebREPL terminal mode. It is still a practical way to
|
||||
get script files onto ESP8266, so give it a try using ``webrepl_cli.py``
|
||||
from the repository above. See the MicroPython forum for other
|
||||
community-supported alternatives to transfer files to ESP8266.
|
||||
See the MicroPython forum for other community-supported alternatives
|
||||
to transfer files to ESP8266.
|
||||
|
|
|
@ -64,7 +64,6 @@ device starts up.
|
|||
Accessing the filesystem via WebREPL
|
||||
------------------------------------
|
||||
|
||||
You can access the filesystem over WebREPL using the provided command-line
|
||||
tool. This tool is found at `<https://github.com/micropython/webrepl>`__
|
||||
and is called webrepl_cli.py. Please refer to that program for information
|
||||
on how to use it.
|
||||
You can access the filesystem over WebREPL using the web client in a browser
|
||||
or via the command-line tool. Please refer to Quick Reference and Tutorial
|
||||
sections for more information about WebREPL.
|
||||
|
|
|
@ -54,7 +54,7 @@ device before putting on new MicroPython firmware.
|
|||
|
||||
Currently we only support esptool.py to copy across the firmware. You can find
|
||||
this tool here: `<https://github.com/themadinventor/esptool/>`__, or install it
|
||||
using pip::
|
||||
using pip (at least version 1.2.1 is required)::
|
||||
|
||||
pip install esptool
|
||||
|
||||
|
@ -69,7 +69,7 @@ Using esptool.py you can erase the flash with the command::
|
|||
|
||||
And then deploy the new firmware using::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m 0 esp8266-2016-05-03-v1.8.bin
|
||||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-2016-05-03-v1.8.bin
|
||||
|
||||
You might need to change the "port" setting to something else relevant for your
|
||||
PC. You may also need to reduce the baudrate if you get errors when flashing
|
||||
|
@ -80,7 +80,7 @@ For some boards with a particular FlashROM configuration (e.g. some variants of
|
|||
a NodeMCU board) you may need to use the following command to deploy
|
||||
the firmware (note the ``-fm dio`` option)::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m -fm dio 0 esp8266-2016-05-03-v1.8.bin
|
||||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect -fm dio 0 esp8266-2016-05-03-v1.8.bin
|
||||
|
||||
If the above commands run without error then MicroPython should be installed on
|
||||
your board!
|
||||
|
@ -138,6 +138,8 @@ after it, here are troubleshooting recommendations:
|
|||
* If lower baud rate didn't help, you may want to try older version of
|
||||
esptool.py, which had a different programming algorithm::
|
||||
pip install esptool==1.0.1
|
||||
This version doesn't support ``--flash_size=detect`` option, so you will
|
||||
need to specify FlashROM size explicitly (in megabits).
|
||||
|
||||
* The ``--flash_size`` option in the commands above is mandatory. Omitting
|
||||
it will lead to a corrupted firmware.
|
||||
|
|
|
@ -41,6 +41,18 @@ For your convenience, WebREPL client is hosted at
|
|||
locally from the the GitHub repository
|
||||
`<https://github.com/micropython/webrepl>`__ .
|
||||
|
||||
Before connecting to WebREPL, you should set a password and enable it via
|
||||
a normal serial connection. Initial versions of MicroPython for ESP8266
|
||||
came with WebREPL automatically enabled on the boot and with the
|
||||
ability to set a password via WiFi on the first connection, but as WebREPL
|
||||
was becoming more widely known and popular, the initial setup has switched
|
||||
to a wired connection for improved security::
|
||||
|
||||
import webrepl_setup
|
||||
|
||||
Follow the on-screen instructions and prompts. To make any changes active,
|
||||
you will need to reboot your device.
|
||||
|
||||
To use WebREPL connect your computer to the ESP8266's access point
|
||||
(MicroPython-xxxxxx, see the previous section about this). If you have
|
||||
already reconfigured your ESP8266 to connect to a router then you can
|
||||
|
@ -49,19 +61,11 @@ skip this part.
|
|||
Once you are on the same network as the ESP8266 you click the "Connect" button
|
||||
(if you are connecting via a router then you may need to change the IP address,
|
||||
by default the IP address is correct when connected to the ESP8266's access
|
||||
point). If the connection succeeds then you should see a welcome message.
|
||||
point). If the connection succeeds then you should see a password prompt.
|
||||
|
||||
On the first connection you need to set a password. Make sure that the
|
||||
terminal widget is selected by clicking on it, and then follow prompts to
|
||||
type in your password twice (they should match each other). Then ESP8266
|
||||
will then reboot with the password applied (the WiFi will go down but come
|
||||
back up again). Note that some modules may have troubles rebooting
|
||||
automatically and need reset button press or power cycle (do this if
|
||||
you don't see ESP8266 access point appearing in a minute or so).
|
||||
|
||||
You should then click the "Connect" button again, and enter your password
|
||||
to connect. If you type in the correct password you should get a prompt
|
||||
looking like ``>>>``. You can now start typing Python commands!
|
||||
Once you type the password configured at the setup step above, press Enter once
|
||||
more and you should get a prompt looking like ``>>>``. You can now start
|
||||
typing Python commands!
|
||||
|
||||
Using the REPL
|
||||
--------------
|
||||
|
|
|
@ -28,6 +28,11 @@ All builtin functions are described here. They are also available via
|
|||
|
||||
.. class:: complex()
|
||||
|
||||
.. function:: delattr(obj, name)
|
||||
|
||||
The argument *name* should be a string, and this function deletes the named
|
||||
attribute from the object given by *obj*.
|
||||
|
||||
.. class:: dict()
|
||||
|
||||
.. function:: dir()
|
||||
|
@ -110,6 +115,10 @@ All builtin functions are described here. They are also available via
|
|||
|
||||
.. function:: setattr()
|
||||
|
||||
.. class:: slice()
|
||||
|
||||
The *slice* builtin is the type that slice objects have.
|
||||
|
||||
.. function:: sorted()
|
||||
|
||||
.. function:: staticmethod()
|
||||
|
|
|
@ -51,8 +51,8 @@ library.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
array.rst
|
||||
cmath.rst
|
||||
gc.rst
|
||||
math.rst
|
||||
|
@ -76,8 +76,8 @@ library.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
array.rst
|
||||
cmath.rst
|
||||
gc.rst
|
||||
math.rst
|
||||
|
@ -101,8 +101,8 @@ library.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
array.rst
|
||||
gc.rst
|
||||
select.rst
|
||||
sys.rst
|
||||
|
@ -119,8 +119,8 @@ library.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
array.rst
|
||||
builtins.rst
|
||||
array.rst
|
||||
gc.rst
|
||||
math.rst
|
||||
sys.rst
|
||||
|
|
|
@ -3,16 +3,44 @@
|
|||
class Pin -- control I/O pins
|
||||
=============================
|
||||
|
||||
A pin is the basic object to control I/O pins (also known as GPIO -
|
||||
general-purpose input/output). It has methods to set
|
||||
the mode of the pin (input, output, etc) and methods to get and set the
|
||||
digital logic level. For analog control of a pin, see the ADC class.
|
||||
A pin object is used to control I/O pins (also known as GPIO - general-purpose
|
||||
input/output). Pin objects are commonly associated with a physical pin that can
|
||||
drive an output voltage and read input voltages. The pin class has methods to set the mode of
|
||||
the pin (IN, OUT, etc) and methods to get and set the digital logic level.
|
||||
For analog control of a pin, see the :class:`ADC` class.
|
||||
|
||||
Usage Model:
|
||||
A pin object is constructed by using an identifier which unambiguously
|
||||
specifies a certain I/O pin. The allowed forms of the identifier and the
|
||||
physical pin that the identifier maps to are port-specific. Possibilities
|
||||
for the identifier are an integer, a string or a tuple with port and pin
|
||||
number.
|
||||
|
||||
Usage Model::
|
||||
|
||||
from machine import Pin
|
||||
|
||||
# create an output pin on pin #0
|
||||
p0 = Pin(0, Pin.OUT)
|
||||
|
||||
# set the value low then high
|
||||
p0.value(0)
|
||||
p0.value(1)
|
||||
|
||||
# create an input pin on pin #2, with a pull up resistor
|
||||
p2 = Pin(2, Pin.IN, Pin.PULL_UP)
|
||||
|
||||
# read and print the pin value
|
||||
print(p2.value())
|
||||
|
||||
# reconfigure pin #0 in input mode
|
||||
p0.mode(p0.IN)
|
||||
|
||||
# configure an irq callback
|
||||
p0.irq(lambda p:print(p))
|
||||
|
||||
.. only:: port_wipy
|
||||
|
||||
Board pins are identified by their string id::
|
||||
On the WiPy board the pins are identified by their string id::
|
||||
|
||||
from machine import Pin
|
||||
g = machine.Pin('GP9', mode=Pin.OUT, pull=None, drive=Pin.MED_POWER, alt=-1)
|
||||
|
@ -40,144 +68,18 @@ Usage Model:
|
|||
All pin objects go through the pin mapper to come up with one of the
|
||||
gpio pins.
|
||||
|
||||
.. only:: port_esp8266
|
||||
|
||||
::
|
||||
|
||||
from machine import Pin
|
||||
|
||||
# create an output pin on GPIO0
|
||||
p0 = Pin(0, Pin.OUT)
|
||||
p0.value(0)
|
||||
p0.value(1)
|
||||
|
||||
# create an input pin on GPIO2
|
||||
p2 = Pin(2, Pin.IN, Pin.PULL_UP)
|
||||
print(p2.value())
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: Pin(id, ...)
|
||||
|
||||
Create a new Pin object associated with the id. If additional arguments are given,
|
||||
they are used to initialise the pin. See :meth:`Pin.init`.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. only:: port_wipy
|
||||
|
||||
.. method:: Pin.init(mode, pull, \*, drive, alt)
|
||||
|
||||
Initialise the pin:
|
||||
|
||||
- ``mode`` can be one of:
|
||||
|
||||
- ``Pin.IN`` - input pin.
|
||||
- ``Pin.OUT`` - output pin in push-pull mode.
|
||||
- ``Pin.OPEN_DRAIN`` - output pin in open-drain mode.
|
||||
- ``Pin.ALT`` - pin mapped to an alternate function.
|
||||
- ``Pin.ALT_OPEN_DRAIN`` - pin mapped to an alternate function in open-drain mode.
|
||||
|
||||
- ``pull`` can be one of:
|
||||
|
||||
- ``None`` - no pull up or down resistor.
|
||||
- ``Pin.PULL_UP`` - pull up resistor enabled.
|
||||
- ``Pin.PULL_DOWN`` - pull down resistor enabled.
|
||||
|
||||
- ``drive`` can be one of:
|
||||
For the ``drive`` parameter the strengths are:
|
||||
|
||||
- ``Pin.LOW_POWER`` - 2mA drive capability.
|
||||
- ``Pin.MED_POWER`` - 4mA drive capability.
|
||||
- ``Pin.HIGH_POWER`` - 6mA drive capability.
|
||||
|
||||
- ``alt`` is the number of the alternate function. Please refer to the
|
||||
`pinout and alternate functions table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
|
||||
For the ``alt`` parameter please refer to the pinout and alternate functions
|
||||
table at <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
|
||||
for the specific alternate functions that each pin supports.
|
||||
|
||||
Returns: ``None``.
|
||||
|
||||
.. method:: Pin.id()
|
||||
|
||||
Get the pin id.
|
||||
|
||||
.. only:: port_esp8266
|
||||
|
||||
.. method:: Pin.init(mode, pull=None, \*, value)
|
||||
|
||||
Initialise the pin:
|
||||
|
||||
- `mode` can be one of:
|
||||
|
||||
- ``Pin.IN`` - input pin.
|
||||
- ``Pin.OUT`` - output pin in push-pull mode.
|
||||
|
||||
- `pull` can be one of:
|
||||
|
||||
- ``None`` - no pull up or down resistor.
|
||||
- ``Pin.PULL_UP`` - pull up resistor enabled.
|
||||
|
||||
- if `value` is given then it is the output value to set the pin
|
||||
if it is in output mode.
|
||||
|
||||
.. method:: Pin.value([value])
|
||||
|
||||
Get or set the digital logic level of the pin:
|
||||
|
||||
- With no argument, return 0 or 1 depending on the logic level of the pin.
|
||||
- With ``value`` given, set the logic level of the pin. ``value`` can be
|
||||
anything that converts to a boolean. If it converts to ``True``, the pin
|
||||
is set high, otherwise it is set low.
|
||||
|
||||
.. method:: Pin.__call__([value])
|
||||
|
||||
Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin.
|
||||
See :func:`Pin.value` for more details.
|
||||
|
||||
.. method:: Pin.alt_list()
|
||||
|
||||
Returns a list of the alternate functions supported by the pin. List items are
|
||||
a tuple of the form: ``('ALT_FUN_NAME', ALT_FUN_INDEX)``
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. only:: port_wipy
|
||||
|
||||
.. method:: Pin.toggle()
|
||||
|
||||
Toggle the value of the pin.
|
||||
|
||||
.. method:: Pin.mode([mode])
|
||||
|
||||
Get or set the pin mode.
|
||||
|
||||
.. method:: Pin.pull([pull])
|
||||
|
||||
Get or set the pin pull.
|
||||
|
||||
.. method:: Pin.drive([drive])
|
||||
|
||||
Get or set the pin drive strength.
|
||||
|
||||
.. method:: Pin.irq(\*, trigger, priority=1, handler=None, wake=None)
|
||||
|
||||
Create a callback to be triggered when the input level at the pin changes.
|
||||
|
||||
- ``trigger`` configures the pin level which can generate an interrupt. Possible values are:
|
||||
|
||||
- ``Pin.IRQ_FALLING`` interrupt on falling edge.
|
||||
- ``Pin.IRQ_RISING`` interrupt on rising edge.
|
||||
- ``Pin.IRQ_LOW_LEVEL`` interrupt on low level.
|
||||
- ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level.
|
||||
|
||||
The values can be *ORed* together, for instance mode=Pin.IRQ_FALLING | Pin.IRQ_RISING
|
||||
|
||||
- ``priority`` level of the interrupt. Can take values in the range 1-7.
|
||||
Higher values represent higher priorities.
|
||||
- ``handler`` is an optional function to be called when new characters arrive.
|
||||
- ``wakes`` selects the power mode in which this interrupt can wake up the
|
||||
board. Please note:
|
||||
For interrupts, the ``priority`` can take values in the range 1-7. And the
|
||||
``wake`` parameter has the following properties:
|
||||
|
||||
- If ``wake_from=machine.Sleep.ACTIVE`` any pin can wake the board.
|
||||
- If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``,
|
||||
|
@ -187,27 +89,203 @@ Methods
|
|||
- If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``,
|
||||
``GP11``, ``GP17`` and ``GP24`` can wake the board. In this case all of the
|
||||
6 pins can be enabled as a ``machine.Sleep.HIBERNATE`` wake source at the same time.
|
||||
- Values can be ORed to make a pin generate interrupts in more than one power
|
||||
mode.
|
||||
|
||||
Returns a callback object.
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. only:: port_esp8266
|
||||
.. class:: Pin(id, mode=-1, pull=-1, \*, value, drive, alt)
|
||||
|
||||
.. method:: Pin.irq(\*, trigger, handler=None)
|
||||
Access the pin peripheral (GPIO pin) associated with the given ``id``. If
|
||||
additional arguments are given in the constructor then they are used to initialise
|
||||
the pin. Any settings that are not specified will remain in their previous state.
|
||||
|
||||
Create a callback to be triggered when the input level at the pin changes.
|
||||
The arguments are:
|
||||
|
||||
- ``trigger`` configures the pin level which can generate an interrupt. Possible values are:
|
||||
- ``id`` is mandatory and can be an arbitrary object. Among possible value
|
||||
types are: int (an internal Pin identifier), str (a Pin name), and tuple
|
||||
(pair of [port, pin]).
|
||||
|
||||
- ``mode`` specifies the pin mode, which can be one of:
|
||||
|
||||
- ``Pin.IN`` - Pin is configured for input. If viewed as an output the pin
|
||||
is in high-impedance state.
|
||||
|
||||
- ``Pin.OUT`` - Pin is configured for (normal) output.
|
||||
|
||||
- ``Pin.OPEN_DRAIN`` - Pin is configured for open-drain output. Open-drain
|
||||
output works in the following way: if the output value is set to 0 the pin
|
||||
is active at a low level; if the output value is 1 the pin is in a high-impedance
|
||||
state. Not all ports implement this mode, or some might only on certain pins.
|
||||
|
||||
- ``Pin.ALT`` - Pin is configured to perform an alternative function, which is
|
||||
port specific. For a pin configured in such a way any other Pin methods
|
||||
(except :meth:`Pin.init`) are not applicable (calling them will lead to undefined,
|
||||
or a hardware-specific, result). Not all ports implement this mode.
|
||||
|
||||
- ``Pin.ALT_OPEN_DRAIN`` - The Same as ``Pin.ALT``, but the pin is configured as
|
||||
open-drain. Not all ports implement this mode.
|
||||
|
||||
- ``pull`` specifies if the pin has a (weak) pull resistor attached, and can be
|
||||
one of:
|
||||
|
||||
- ``None`` - No pull up or down resistor.
|
||||
- ``Pin.PULL_UP`` - Pull up resistor enabled.
|
||||
- ``Pin.PULL_DOWN`` - Pull down resistor enabled.
|
||||
|
||||
- ``value`` is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial
|
||||
output pin value if given, otherwise the state of the pin peripheral remains
|
||||
unchanged.
|
||||
|
||||
- ``drive`` specifies the output power of the pin and can be one of: ``Pin.LOW_POWER``,
|
||||
``Pin.MED_POWER`` or ``Pin.HIGH_POWER``. The actual current driving capabilities
|
||||
are port dependent. Not all ports implement this argument.
|
||||
|
||||
- ``alt`` specifies an alternate function for the pin and the values it can take are
|
||||
port dependent. This argument is valid only for ``Pin.ALT`` and ``Pin.ALT_OPEN_DRAIN``
|
||||
modes. It may be used when a pin supports more than one alternate function. If only
|
||||
one pin alternate function is supported the this argument is not required. Not all
|
||||
ports implement this argument.
|
||||
|
||||
As specified above, the Pin class allows to set an alternate function for a particular
|
||||
pin, but it does not specify any further operations on such a pin. Pins configured in
|
||||
alternate-function mode are usually not used as GPIO but are instead driven by other
|
||||
hardware peripherals. The only operation supported on such a pin is re-initialising,
|
||||
by calling the constructor or :meth:`Pin.init` method. If a pin that is configured in
|
||||
alternate-function mode is re-initialised with ``Pin.IN``, ``Pin.OUT``, or
|
||||
``Pin.OPEN_DRAIN``, the alternate function will be removed from the pin.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Pin.init(mode=-1, pull=-1, \*, value, drive, alt)
|
||||
|
||||
Re-initialise the pin using the given parameters. Only those arguments that
|
||||
are specified will be set. The rest of the pin peripheral state will remain
|
||||
unchanged. See the constructor documentation for details of the arguments.
|
||||
|
||||
Returns ``None``.
|
||||
|
||||
.. method:: Pin.value([x])
|
||||
|
||||
This method allows to set and get the value of the pin, depending on whether
|
||||
the argument ``x`` is supplied or not.
|
||||
|
||||
If the argument is omitted then this method gets the digital logic level of
|
||||
the pin, returning 0 or 1 corresponding to low and high voltage signals
|
||||
respectively. The behaviour of this method depends on the mode of the pin:
|
||||
|
||||
- ``Pin.IN`` - The method returns the actual input value currently present
|
||||
on the pin.
|
||||
- ``Pin.OUT`` - The behaviour and return value of the method is undefined.
|
||||
- ``Pin.OPEN_DRAIN`` - If the pin is in state '0' then the behaviour and
|
||||
return value of the method is undefined. Otherwise, if the pin is in
|
||||
state '1', the method returns the actual input value currently present
|
||||
on the pin.
|
||||
|
||||
If the argument is supplied then this method sets the digital logic level of
|
||||
the pin. The argument ``x`` can be anything that converts to a boolean.
|
||||
If it converts to ``True``, the pin is set to state '1', otherwise it is set
|
||||
to state '0'. The behaviour of this method depends on the mode of the pin:
|
||||
|
||||
- ``Pin.IN`` - The value is stored in the output buffer for the pin. The
|
||||
pin state does not change, it remains in the high-impedance state. The
|
||||
stored value will become active on the pin as soon as it is changed to
|
||||
``Pin.OUT`` or ``Pin.OPEN_DRAIN`` mode.
|
||||
- ``Pin.OUT`` - The output buffer is set to the given value immediately.
|
||||
- ``Pin.OPEN_DRAIN`` - If the value is '0' the pin is set to a low voltage
|
||||
state. Otherwise the pin is set to high-impedance state.
|
||||
|
||||
When setting the value this method returns ``None``.
|
||||
|
||||
.. method:: Pin.out_value()
|
||||
|
||||
Return the value stored in the output buffer of a pin, regardless of its mode.
|
||||
|
||||
Not all ports implement this method.
|
||||
|
||||
.. method:: Pin.__call__([x])
|
||||
|
||||
Pin objects are callable. The call method provides a (fast) shortcut to set
|
||||
and get the value of the pin. It is equivalent to Pin.value([x]).
|
||||
See :meth:`Pin.value` for more details.
|
||||
|
||||
.. method:: Pin.toggle()
|
||||
|
||||
Toggle the output value of the pin. Equivalent to ``pin.value(not pin.out_value())``.
|
||||
Returns ``None``.
|
||||
|
||||
Not all ports implement this method.
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. method:: Pin.id()
|
||||
|
||||
Get the pin identifier. This may return the ``id`` as specified in the
|
||||
constructor. Or it may return a canonical software-specific pin id.
|
||||
|
||||
.. method:: Pin.mode([mode])
|
||||
|
||||
Get or set the pin mode.
|
||||
See the constructor documentation for details of the ``mode`` argument.
|
||||
|
||||
.. method:: Pin.pull([pull])
|
||||
|
||||
Get or set the pin pull state.
|
||||
See the constructor documentation for details of the ``pull`` argument.
|
||||
|
||||
.. method:: Pin.drive([drive])
|
||||
|
||||
Get or set the pin drive strength.
|
||||
See the constructor documentation for details of the ``drive`` argument.
|
||||
|
||||
Not all ports implement this method.
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. method:: Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), \*, priority=1, wake=None)
|
||||
|
||||
Configure an interrupt handler to be called when the trigger source of the
|
||||
pin is active. If the pin mode is ``Pin.IN`` then the trigger source is
|
||||
the external value on the pin. If the pin mode is ``Pin.OUT`` then the
|
||||
trigger source is the output buffer of the pin. Otherwise, if the pin mode
|
||||
is ``Pin.OPEN_DRAIN`` then the trigger source is the output buffer for
|
||||
state '0' and the external pin value for state '1'.
|
||||
|
||||
The arguments are:
|
||||
|
||||
- ``handler`` is an optional function to be called when the interrupt
|
||||
triggers.
|
||||
|
||||
- ``trigger`` configures the event which can generate an interrupt.
|
||||
Possible values are:
|
||||
|
||||
- ``Pin.IRQ_FALLING`` interrupt on falling edge.
|
||||
- ``Pin.IRQ_RISING`` interrupt on rising edge.
|
||||
- ``Pin.IRQ_LOW_LEVEL`` interrupt on low level.
|
||||
- ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level.
|
||||
|
||||
The values can be OR'ed together to trigger on multiple events.
|
||||
These values can be OR'ed together to trigger on multiple events.
|
||||
|
||||
- ``handler`` is an optional function to be called when the interrupt triggers.
|
||||
- ``priority`` sets the priority level of the interrupt. The values it
|
||||
can take are port-specific, but higher values always represent higher
|
||||
priorities.
|
||||
|
||||
- ``wake`` selects the power mode in which this interrupt can wake up the
|
||||
system. It can be ``machine.IDLE``, ``machine.SLEEP`` or ``machine.DEEPSLEEP``.
|
||||
These values can also be OR'ed together to make a pin generate interrupts in
|
||||
more than one power mode.
|
||||
|
||||
This method returns a callback object.
|
||||
|
||||
.. only:: port_wipy
|
||||
|
||||
.. method:: Pin.alt_list()
|
||||
|
||||
Returns a list of the alternate functions supported by the pin. List items are
|
||||
a tuple of the form: ``('ALT_FUN_NAME', ALT_FUN_INDEX)``
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
Returns a callback object.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
@ -239,7 +317,8 @@ not all constants are available on all ports.
|
|||
.. data:: Pin.PULL_UP
|
||||
Pin.PULL_DOWN
|
||||
|
||||
Selects the whether there is a pull up/down resistor.
|
||||
Selects whether there is a pull up/down resistor. Use the value
|
||||
``None`` for no pull.
|
||||
|
||||
.. data:: Pin.LOW_POWER
|
||||
Pin.MED_POWER
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
.. currentmodule:: machine
|
||||
|
||||
class SPI -- a master-driven serial protocol
|
||||
============================================
|
||||
class SPI -- a Serial Peripheral Interface bus protocol (master side)
|
||||
=====================================================================
|
||||
|
||||
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 synchronous serial protocol that is driven by a master. At the
|
||||
physical level, a bus consists 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,11 +25,13 @@ 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.
|
||||
|
@ -34,52 +40,69 @@ Constructors
|
|||
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, sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO))
|
||||
|
||||
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 is guaranteed to be supported by all hardware.
|
||||
- ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``.
|
||||
- ``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).
|
||||
- ``pins`` - WiPy port doesn't ``sck``, ``mosi``, ``miso`` arguments, and instead allows to
|
||||
specify them as a tuple of ``pins`` paramter.
|
||||
|
||||
.. method:: SPI.deinit()
|
||||
|
||||
Turn off the SPI bus.
|
||||
|
||||
.. 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)
|
||||
|
||||
Read into the buffer specified by ``buf`` while continuously writing the
|
||||
single byte given by ``write``.
|
||||
Returns ``None``.
|
||||
|
||||
Note: on WiPy this function returns the number of bytes read.
|
||||
|
||||
.. method:: SPI.write(buf)
|
||||
|
||||
Write the data contained in ``buf``.
|
||||
Returns the number of bytes written.
|
||||
Write the bytes contained in ``buf``.
|
||||
Returns ``None``.
|
||||
|
||||
.. method:: SPI.read(nbytes, *, write=0x00)
|
||||
|
||||
Read the ``nbytes`` while writing the data specified by ``write``.
|
||||
Return the number of bytes read.
|
||||
|
||||
.. method:: SPI.readinto(buf, *, write=0x00)
|
||||
|
||||
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
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
.. module:: network
|
||||
:synopsis: network configuration
|
||||
|
||||
This module provides network drivers and routing configuration. Network
|
||||
drivers for specific hardware are available within this module and are
|
||||
used to configure a hardware network interface. Configured interfaces
|
||||
are then available for use via the :mod:`socket` module. To use this module
|
||||
the network build of firmware must be installed.
|
||||
This module provides network drivers and routing configuration. To use this
|
||||
module, a MicroPython variant/build with network capabilities must be installed.
|
||||
Network drivers for specific hardware are available within this module and are
|
||||
used to configure hardware network interface(s). Network services provided
|
||||
by configured interfaces are then available for use via the :mod:`socket`
|
||||
module.
|
||||
|
||||
For example::
|
||||
|
||||
|
@ -79,7 +80,7 @@ For example::
|
|||
class CC3K
|
||||
==========
|
||||
|
||||
This class provides a driver for CC3000 wifi modules. Example usage::
|
||||
This class provides a driver for CC3000 WiFi modules. Example usage::
|
||||
|
||||
import network
|
||||
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
|
||||
|
@ -128,16 +129,16 @@ For example::
|
|||
|
||||
.. method:: cc3k.connect(ssid, key=None, \*, security=WPA2, bssid=None)
|
||||
|
||||
Connect to a wifi access point using the given SSID, and other security
|
||||
Connect to a WiFi access point using the given SSID, and other security
|
||||
parameters.
|
||||
|
||||
.. method:: cc3k.disconnect()
|
||||
|
||||
Disconnect from the wifi access point.
|
||||
Disconnect from the WiFi access point.
|
||||
|
||||
.. method:: cc3k.isconnected()
|
||||
|
||||
Returns True if connected to a wifi access point and has a valid IP address,
|
||||
Returns True if connected to a WiFi access point and has a valid IP address,
|
||||
False otherwise.
|
||||
|
||||
.. method:: cc3k.ifconfig()
|
||||
|
@ -323,7 +324,7 @@ For example::
|
|||
|
||||
.. method:: wlan.isconnected()
|
||||
|
||||
In case of STA mode, returns ``True`` if connected to a wifi access
|
||||
In case of STA mode, returns ``True`` if connected to a WiFi access
|
||||
point and has a valid IP address. In AP mode returns ``True`` when a
|
||||
station is connected. Returns ``False`` otherwise.
|
||||
|
||||
|
@ -348,7 +349,7 @@ For example::
|
|||
|
||||
# Set WiFi access point name (formally known as ESSID) and WiFi channel
|
||||
ap.config(essid='My AP', channel=11)
|
||||
# Queey params one by one
|
||||
# Query params one by one
|
||||
print(ap.config('essid'))
|
||||
print(ap.config('channel'))
|
||||
|
||||
|
@ -433,7 +434,7 @@ For example::
|
|||
|
||||
.. method:: wlan.connect(ssid, \*, auth=None, bssid=None, timeout=None)
|
||||
|
||||
Connect to a wifi access point using the given SSID, and other security
|
||||
Connect to a WiFi access point using the given SSID, and other security
|
||||
parameters.
|
||||
|
||||
- ``auth`` is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``,
|
||||
|
@ -451,16 +452,16 @@ For example::
|
|||
|
||||
.. method:: wlan.disconnect()
|
||||
|
||||
Disconnect from the wifi access point.
|
||||
Disconnect from the WiFi access point.
|
||||
|
||||
.. method:: wlan.isconnected()
|
||||
|
||||
In case of STA mode, returns ``True`` if connected to a wifi access point and has a valid IP address.
|
||||
In case of STA mode, returns ``True`` if connected to a WiFi access point and has a valid IP address.
|
||||
In AP mode returns ``True`` when a station is connected, ``False`` otherwise.
|
||||
|
||||
.. method:: wlan.ifconfig(if_id=0, config=['dhcp' or configtuple])
|
||||
|
||||
With no parameters given eturns a 4-tuple of ``(ip, subnet_mask, gateway, DNS_server)``.
|
||||
With no parameters given returns a 4-tuple of ``(ip, subnet_mask, gateway, DNS_server)``.
|
||||
|
||||
if ``'dhcp'`` is passed as a parameter then the DHCP client is enabled and the IP params
|
||||
are negotiated with the AP.
|
||||
|
@ -498,10 +499,10 @@ For example::
|
|||
Create a callback to be triggered when a WLAN event occurs during ``machine.SLEEP``
|
||||
mode. Events are triggered by socket activity or by WLAN connection/disconnection.
|
||||
|
||||
- ``handler`` is the function that gets called when the irq is triggered.
|
||||
- ``handler`` is the function that gets called when the IRQ is triggered.
|
||||
- ``wake`` must be ``machine.SLEEP``.
|
||||
|
||||
Returns an irq object.
|
||||
Returns an IRQ object.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
|
|
@ -82,38 +82,129 @@ Functions
|
|||
|
||||
.. function:: ticks_ms()
|
||||
|
||||
Returns an increasing millisecond counter with arbitrary reference point,
|
||||
that wraps after some (unspecified) value. The value should be treated as
|
||||
opaque, suitable for use only with ticks_diff().
|
||||
Returns an increasing millisecond counter with an arbitrary reference point,
|
||||
that wraps around after some value. This value is not explicitly exposed,
|
||||
but we will refer to it as `TICKS_MAX` to simplify discussion. Period of
|
||||
the values is `TICKS_PERIOD = TICKS_MAX + 1`. `TICKS_PERIOD` is guaranteed
|
||||
to be a power of two, but otherwise may differ from port to port. The same
|
||||
period value is used for all of ticks_ms(), ticks_us(), ticks_cpu() functions
|
||||
(for simplicity). Thus, these functions will return a value in range
|
||||
[0 .. `TICKS_MAX`], inclusive, total `TICKS_PERIOD` values. Note that only
|
||||
non-negative values are used. For the most part, you should treat values
|
||||
returned by these functions as opaque. The only operations available for them
|
||||
are ``ticks_diff()`` and ``ticks_add()`` functions described below.
|
||||
|
||||
Note: Performing standard mathematical operations (+, -) or relational
|
||||
operators (<, <=, >, >=) directly on these value will lead to invalid
|
||||
result. Performing mathematical operations and then passing their results
|
||||
as arguments to ``ticks_diff()`` or ``ticks_add()`` will also lead to
|
||||
invalid results from the latter functions.
|
||||
|
||||
.. function:: ticks_us()
|
||||
|
||||
Just like ``ticks_ms`` above, but in microseconds.
|
||||
|
||||
.. only:: port_wipy or port_pyboard
|
||||
.. function:: ticks_cpu()
|
||||
|
||||
.. function:: ticks_cpu()
|
||||
Similar to ``ticks_ms`` and ``ticks_us``, but with the highest possible resolution
|
||||
in the system. This is usually CPU clocks, and that's why the function is named that
|
||||
way. But it doesn't have to a CPU clock, some other timing source available in a
|
||||
system (e.g. high-resolution timer) can be used instead. The exact timing unit
|
||||
(resolution) of this function is not specified on ``utime`` module level, but
|
||||
documentation for a specific port may provide more specific information. This
|
||||
function is intended for very fine benchmarking or very tight real-time loops.
|
||||
Avoid using it in portable code.
|
||||
|
||||
Similar to ``ticks_ms`` and ``ticks_us``, but with higher resolution (usually CPU clocks).
|
||||
Availability: Not every port implements this function.
|
||||
|
||||
.. only:: port_unix or port_pyboard or port_wipy or port_esp8266
|
||||
|
||||
.. function:: ticks_diff(old, new)
|
||||
.. function:: ticks_add(ticks, delta)
|
||||
|
||||
Measure period between consecutive calls to ticks_ms(), ticks_us(), or ticks_cpu().
|
||||
The value returned by these functions may wrap around at any time, so directly
|
||||
subtracting them is not supported. ticks_diff() should be used instead. "old" value should
|
||||
actually precede "new" value in time, or result is undefined. This function should not be
|
||||
used to measure arbitrarily long periods of time (because ticks_*() functions wrap around
|
||||
and usually would have short period). The expected usage pattern is implementing event
|
||||
polling with timeout::
|
||||
Offset ticks value by a given number, which can be either positive or negative.
|
||||
Given a ``ticks`` value, this function allows to calculate ticks value ``delta``
|
||||
ticks before or after it, following modular-arithmetic definition of tick values
|
||||
(see ``ticks_ms()`` above). ``ticks`` parameter must be a direct result of call
|
||||
to ``tick_ms()``, ``ticks_us()``, ``ticks_cpu()`` functions (or from previous
|
||||
call to ``ticks_add()``). However, ``delta`` can be an arbitrary integer number
|
||||
or numeric expression. ``ticks_add()`` is useful for calculating deadlines for
|
||||
events/tasks. (Note: you must use ``ticks_diff()`` function to work with
|
||||
deadlines.)
|
||||
|
||||
Examples::
|
||||
|
||||
# Find out what ticks value there was 100ms ago
|
||||
print(tick_add(time.ticks_ms(), -100))
|
||||
|
||||
# Calculate deadline for operation and test for it
|
||||
deadline = tick_add(time.ticks_ms(), 200)
|
||||
while ticks_diff(deadline, time.ticks_ms()) > 0:
|
||||
do_a_little_of_something()
|
||||
|
||||
# Find out TICKS_MAX used by this port
|
||||
print(tick_add(0, -1))
|
||||
|
||||
|
||||
.. function:: ticks_diff(ticks1, ticks2)
|
||||
|
||||
Measure ticks difference between values returned from ticks_ms(), ticks_us(), or ticks_cpu()
|
||||
functions. The argument order is the same as for subtraction operator,
|
||||
``tick_diff(ticks1, ticks2)`` has the same meaning as ``ticks1 - ticks2``. However, values returned by
|
||||
ticks_ms(), etc. functions may wrap around, so directly using subtraction on them will
|
||||
produce incorrect result. That is why ticks_diff() is needed, it implements modular
|
||||
(or more specifically, ring) arithmetics to produce correct result even for wrap-around
|
||||
values (as long as they not too distant inbetween, see below). The function returns
|
||||
**signed** value in the range [`-TICKS_PERIOD/2` .. `TICKS_PERIOD/2-1`] (that's a typical
|
||||
range definition for two's-complement signed binary integers). If the result is negative,
|
||||
it means that `ticks1` occured earlier in time than `ticks2`. Otherwise, it means that
|
||||
`ticks1` occured after `ticks2`. This holds `only` if `ticks1` and `ticks2` are apart from
|
||||
each other for no more than `TICKS_PERIOD/2-1` ticks. If that does not hold, incorrect
|
||||
result will be returned. Specifically, if 2 tick values are apart for `TICKS_PERIOD/2-1`
|
||||
ticks, that value will be returned by the function. However, if `TICKS_PERIOD/2` of
|
||||
real-time ticks has passed between them, the function will return `-TICKS_PERIOD/2`
|
||||
instead, i.e. result value will wrap around to the negative range of possible values.
|
||||
|
||||
Informal rationale of the constraints above: Suppose you are locked in a room with no
|
||||
means to monitor passing of time except a standard 12-notch clock. Then if you look at
|
||||
dial-plate now, and don't look again for another 13 hours (e.g., if you fall for a
|
||||
long sleep), then once you finally look again, it may seem to you that only 1 hour
|
||||
has passed. To avoid this mistake, just look at the clock regularly. Your application
|
||||
should do the same. "Too long sleep" metaphor also maps directly to application
|
||||
behavior: don't let your application run any single task for too long. Run tasks
|
||||
in steps, and do time-keeping inbetween.
|
||||
|
||||
``ticks_diff()`` is designed to accommodate various usage patterns, among them:
|
||||
|
||||
Polling with timeout. In this case, the order of events is known, and you will deal
|
||||
only with positive results of ``ticks_diff()``::
|
||||
|
||||
# Wait for GPIO pin to be asserted, but at most 500us
|
||||
start = time.ticks_us()
|
||||
while pin.value() == 0:
|
||||
if time.ticks_diff(start, time.ticks_us()) > 500:
|
||||
if time.ticks_diff(time.ticks_us(), start) > 500:
|
||||
raise TimeoutError
|
||||
|
||||
Scheduling events. In this case, ``ticks_diff()`` result may be negative
|
||||
if an event is overdue::
|
||||
|
||||
# This code snippet is not optimized
|
||||
now = time.ticks_ms()
|
||||
scheduled_time = task.scheduled_time()
|
||||
if ticks_diff(now, scheduled_time) > 0:
|
||||
print("Too early, let's nap")
|
||||
sleep_ms(ticks_diff(now, scheduled_time))
|
||||
task.run()
|
||||
elif ticks_diff(now, scheduled_time) == 0:
|
||||
print("Right at time!")
|
||||
task.run()
|
||||
elif ticks_diff(now, scheduled_time) < 0:
|
||||
print("Oops, running late, tell task to run faster!")
|
||||
task.run(run_faster=true)
|
||||
|
||||
Note: Do not pass ``time()`` values to ``ticks_diff()``, and should use
|
||||
normal mathematical operations on them. But note that ``time()`` may (and will)
|
||||
also overflow. This is known as https://en.wikipedia.org/wiki/Year_2038_problem .
|
||||
|
||||
|
||||
.. function:: time()
|
||||
|
||||
Returns the number of seconds, as an integer, since the Epoch, assuming that underlying
|
||||
|
|
|
@ -37,7 +37,7 @@ Use the :mod:`time <utime>` module::
|
|||
time.sleep_ms(500) # sleep for 500 milliseconds
|
||||
time.sleep_us(10) # sleep for 10 microseconds
|
||||
start = time.ticks_ms() # get value of millisecond counter
|
||||
delta = time.ticks_diff(start, time.ticks_ms()) # compute time difference
|
||||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
||||
|
||||
LEDs
|
||||
----
|
||||
|
|
|
@ -132,7 +132,7 @@ The following enables any function or method to be timed by adding an
|
|||
def new_func(*args, **kwargs):
|
||||
t = time.ticks_us()
|
||||
result = f(*args, **kwargs)
|
||||
delta = time.ticks_diff(t, time.ticks_us())
|
||||
delta = time.ticks_diff(time.ticks_us(), t)
|
||||
print('Function {} Time = {:6.3f}ms'.format(myname, delta/1000))
|
||||
return result
|
||||
return new_func
|
||||
|
|
|
@ -99,7 +99,7 @@ STATIC tSpiInformation sSpiInformation;
|
|||
STATIC char spi_buffer[CC3000_RX_BUFFER_SIZE];
|
||||
unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
|
||||
|
||||
STATIC const mp_obj_fun_builtin_t irq_callback_obj;
|
||||
STATIC const mp_obj_fun_builtin_fixed_t irq_callback_obj;
|
||||
|
||||
// set the pins to use to communicate with the CC3000
|
||||
// the arguments must be of type pin_obj_t* and SPI_HandleTypeDef*
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#include "py/obj.h"
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(dht_readinto_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_2(dht_readinto_obj);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
|
||||
|
||||
from micropython import const
|
||||
import time
|
||||
import framebuf
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""NRF24L01 driver for Micro Python
|
||||
"""
|
||||
|
||||
from micropython import const
|
||||
import pyb
|
||||
|
||||
# nRF24L01+ registers
|
||||
|
|
|
@ -21,6 +21,7 @@ Example usage on ESP8266:
|
|||
|
||||
"""
|
||||
|
||||
from micropython import const
|
||||
import time
|
||||
|
||||
|
||||
|
|
|
@ -5,20 +5,19 @@ QSTR_DEFS = qstrdefsport.h #$(BUILD)/pins_qstr.h
|
|||
|
||||
MICROPY_PY_USSL = 1
|
||||
MICROPY_SSL_AXTLS = 1
|
||||
MICROPY_FATFS = 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
|
||||
|
||||
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
|
||||
|
||||
|
@ -44,7 +43,8 @@ CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \
|
|||
CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \
|
||||
$(CFLAGS_XTENSA) $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
|
||||
|
||||
LDFLAGS = -nostdlib -T esp8266.ld -Map=$(@:.elf=.map) --cref
|
||||
LDSCRIPT = esp8266.ld
|
||||
LDFLAGS = -nostdlib -T $(LDSCRIPT) -Map=$(@:.elf=.map) --cref
|
||||
LIBS = -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 $(LDFLAGS_MOD)
|
||||
|
||||
LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
|
@ -65,6 +65,7 @@ SRC_C = \
|
|||
main.c \
|
||||
help.c \
|
||||
esp_mphal.c \
|
||||
esp_init_data.c \
|
||||
gccollect.c \
|
||||
lexerstr32.c \
|
||||
uart.c \
|
||||
|
@ -74,22 +75,21 @@ SRC_C = \
|
|||
espapa102.c \
|
||||
intr.c \
|
||||
modpyb.c \
|
||||
modpybpin.c \
|
||||
modpybpwm.c \
|
||||
modpybrtc.c \
|
||||
modpybadc.c \
|
||||
modpybuart.c \
|
||||
modmachinewdt.c \
|
||||
modpybspi.c \
|
||||
modpybhspi.c \
|
||||
modmachine.c \
|
||||
machine_pin.c \
|
||||
machine_pwm.c \
|
||||
machine_rtc.c \
|
||||
machine_adc.c \
|
||||
machine_uart.c \
|
||||
machine_wdt.c \
|
||||
machine_spi.c \
|
||||
machine_hspi.c \
|
||||
modesp.c \
|
||||
modnetwork.c \
|
||||
modutime.c \
|
||||
moduos.c \
|
||||
modmachine.c \
|
||||
modonewire.c \
|
||||
ets_alt_task.c \
|
||||
$(BUILD)/frozen.c \
|
||||
fatfs_port.c \
|
||||
axtls_helpers.c \
|
||||
hspi.c \
|
||||
|
@ -130,10 +130,14 @@ LIB_SRC_C = $(addprefix lib/,\
|
|||
utils/pyexec.c \
|
||||
utils/pyhelp.c \
|
||||
utils/interrupt_char.c \
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
)
|
||||
|
||||
ifeq ($(MICROPY_FATFS), 1)
|
||||
LIB_SRC_C += \
|
||||
lib/fatfs/ff.c \
|
||||
lib/fatfs/option/ccsbcs.c
|
||||
endif
|
||||
|
||||
DRIVERS_SRC_C = $(addprefix drivers/,\
|
||||
dht/dht.c \
|
||||
)
|
||||
|
@ -141,9 +145,6 @@ DRIVERS_SRC_C = $(addprefix drivers/,\
|
|||
SRC_S = \
|
||||
gchelper.s \
|
||||
|
||||
FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py')
|
||||
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
|
||||
|
||||
OBJ =
|
||||
OBJ += $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
|
@ -152,7 +153,6 @@ OBJ += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o))
|
|||
OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
|
||||
OBJ += $(BUILD)/$(BUILD)/frozen_mpy.o
|
||||
#OBJ += $(BUILD)/pins_$(BOARD).o
|
||||
|
||||
# List of sources for qstr extraction
|
||||
|
@ -175,23 +175,11 @@ $(BUILD)/uart.o: $(CONFVARS_FILE)
|
|||
|
||||
FROZEN_EXTRA_DEPS = $(CONFVARS_FILE)
|
||||
|
||||
# to build .mpy files from .py files
|
||||
$(BUILD)/$(FROZEN_MPY_DIR)/%.mpy: $(FROZEN_MPY_DIR)/%.py
|
||||
@$(ECHO) "MPY $<"
|
||||
$(Q)$(MKDIR) -p $(dir $@)
|
||||
$(Q)$(MPY_CROSS) -o $@ -s $(^:$(FROZEN_MPY_DIR)/%=%) $^
|
||||
|
||||
# to build frozen_mpy.c from all .mpy files
|
||||
$(BUILD)/frozen_mpy.c: $(FROZEN_MPY_MPY_FILES) $(BUILD)/genhdr/qstrdefs.generated.h
|
||||
@$(ECHO) "Creating $@"
|
||||
$(Q)$(PYTHON) $(MPY_TOOL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h $(FROZEN_MPY_MPY_FILES) > $@
|
||||
|
||||
.PHONY: deploy
|
||||
|
||||
deploy: $(BUILD)/firmware-combined.bin
|
||||
$(ECHO) "Writing $< to the board"
|
||||
$(Q)esptool.py --port $(PORT) --baud $(BAUD) write_flash --verify --flash_size=$(FLASH_SIZE) --flash_mode=$(FLASH_MODE) 0 $<
|
||||
#$(Q)esptool.py --port $(PORT) --baud $(BAUD) write_flash --flash_size=8m 0 $(BUILD)/firmware.elf-0x00000.bin 0x9000 $(BUILD)/firmware.elf-0x0[1-f]000.bin
|
||||
|
||||
reset:
|
||||
echo -e "\r\nimport machine; machine.reset()\r\n" >$(PORT)
|
||||
|
@ -206,6 +194,9 @@ $(BUILD)/firmware.elf: $(OBJ)
|
|||
$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(Q)$(SIZE) $@
|
||||
|
||||
512k:
|
||||
$(MAKE) LDSCRIPT=esp8266_512k.ld CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_512k.h>"' MICROPY_FATFS=0 MICROPY_PY_BTREE=0
|
||||
|
||||
#MAKE_PINS = boards/make-pins.py
|
||||
#BOARD_PINS = boards/$(BOARD)/pins.csv
|
||||
#AF_FILE = boards/stm32f4xx_af.csv
|
||||
|
|
|
@ -70,13 +70,14 @@ $ make deploy
|
|||
```
|
||||
This will use the `esptool.py` script to download the images. You must have
|
||||
your ESP module in the bootloader mode, and connected to a serial port on your PC.
|
||||
The default serial port is `/dev/ttyACM0`, flash mode is `qio` and flash size is `8m`.
|
||||
To specify other values, use, eg:
|
||||
The default serial port is `/dev/ttyACM0`, flash mode is `qio` and flash size is
|
||||
`detect` (auto-detect based on Flash ID). To specify other values, use, eg (note
|
||||
that flash size is in megabits):
|
||||
```bash
|
||||
$ make PORT=/dev/ttyUSB0 FLASH_MODE=qio FLASH_SIZE=8m deploy
|
||||
$ make PORT=/dev/ttyUSB0 FLASH_MODE=qio FLASH_SIZE=32m deploy
|
||||
```
|
||||
|
||||
The image produced is `firmware-combined.bin`, to be flashed at 0x00000.
|
||||
The image produced is `build/firmware-combined.bin`, to be flashed at 0x00000.
|
||||
|
||||
First start
|
||||
-----------
|
||||
|
|
|
@ -20,7 +20,7 @@ PHDRS
|
|||
irom0_0_phdr PT_LOAD;
|
||||
}
|
||||
|
||||
ENTRY(call_user_start)
|
||||
ENTRY(firmware_start)
|
||||
EXTERN(_DebugExceptionVector)
|
||||
EXTERN(_DoubleExceptionVector)
|
||||
EXTERN(_KernelExceptionVector)
|
||||
|
@ -130,20 +130,23 @@ 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*)
|
||||
*modpybpin.o(.literal*, .text*)
|
||||
*modpybpwm.o(.literal*, .text*)
|
||||
*modpybrtc.o(.literal*, .text*)
|
||||
*modpybadc.o(.literal*, .text*)
|
||||
*modpybuart.o(.literal*, .text*)
|
||||
*machine_pin.o(.literal*, .text*)
|
||||
*machine_pwm.o(.literal*, .text*)
|
||||
*machine_rtc.o(.literal*, .text*)
|
||||
*machine_adc.o(.literal*, .text*)
|
||||
*machine_uart.o(.literal*, .text*)
|
||||
*modpybi2c.o(.literal*, .text*)
|
||||
*modmachinewdt.o(.literal*, .text*)
|
||||
*modpybspi.o(.literal*, .text*)
|
||||
*modpybhspi.o(.literal*, .text*)
|
||||
*modmachine.o(.literal*, .text*)
|
||||
*machine_wdt.o(.literal*, .text*)
|
||||
*machine_spi.o(.literal*, .text*)
|
||||
*machine_hspi.o(.literal*, .text*)
|
||||
*hspi.o(.literal*, .text*)
|
||||
*modesp.o(.literal* .text*)
|
||||
*modnetwork.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)
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
/* GNU linker script for ESP8266 */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3ff00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3ffe8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40209000, len = 0x72000
|
||||
}
|
||||
|
||||
/* define the top of RAM */
|
||||
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);
|
||||
|
||||
PHDRS
|
||||
{
|
||||
dport0_0_phdr PT_LOAD;
|
||||
dram0_0_phdr PT_LOAD;
|
||||
dram0_0_bss_phdr PT_LOAD;
|
||||
iram1_0_phdr PT_LOAD;
|
||||
irom0_0_phdr PT_LOAD;
|
||||
}
|
||||
|
||||
ENTRY(firmware_start)
|
||||
EXTERN(_DebugExceptionVector)
|
||||
EXTERN(_DoubleExceptionVector)
|
||||
EXTERN(_KernelExceptionVector)
|
||||
EXTERN(_NMIExceptionVector)
|
||||
EXTERN(_UserExceptionVector)
|
||||
|
||||
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
||||
|
||||
/* Various memory-map dependent cache attribute settings: */
|
||||
_memmap_cacheattr_wb_base = 0x00000110;
|
||||
_memmap_cacheattr_wt_base = 0x00000110;
|
||||
_memmap_cacheattr_bp_base = 0x00000220;
|
||||
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
||||
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
||||
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
||||
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.dport0.rodata : ALIGN(4)
|
||||
{
|
||||
_dport0_rodata_start = ABSOLUTE(.);
|
||||
*(.dport0.rodata)
|
||||
*(.dport.rodata)
|
||||
_dport0_rodata_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.literal : ALIGN(4)
|
||||
{
|
||||
_dport0_literal_start = ABSOLUTE(.);
|
||||
*(.dport0.literal)
|
||||
*(.dport.literal)
|
||||
_dport0_literal_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.data : ALIGN(4)
|
||||
{
|
||||
_dport0_data_start = ABSOLUTE(.);
|
||||
*(.dport0.data)
|
||||
*(.dport.data)
|
||||
_dport0_data_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.irom0.text : ALIGN(4)
|
||||
{
|
||||
_irom0_text_start = ABSOLUTE(.);
|
||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||
|
||||
/* we put some specific text in this section */
|
||||
|
||||
*py/argcheck.o*(.literal* .text*)
|
||||
*py/asm*.o*(.literal* .text*)
|
||||
*py/bc.o*(.literal* .text*)
|
||||
*py/binary.o*(.literal* .text*)
|
||||
*py/builtin*.o*(.literal* .text*)
|
||||
*py/compile.o*(.literal* .text*)
|
||||
*py/emit*.o*(.literal* .text*)
|
||||
*py/formatfloat.o*(.literal* .text*)
|
||||
*py/frozenmod.o*(.literal* .text*)
|
||||
*py/gc.o*(.literal* .text*)
|
||||
*py/lexer*.o*(.literal* .text*)
|
||||
*py/malloc*.o*(.literal* .text*)
|
||||
*py/map*.o*(.literal* .text*)
|
||||
*py/mod*.o*(.literal* .text*)
|
||||
*py/mpprint.o*(.literal* .text*)
|
||||
*py/mpstate.o*(.literal* .text*)
|
||||
*py/mpz.o*(.literal* .text*)
|
||||
*py/native*.o*(.literal* .text*)
|
||||
*py/nlr*.o*(.literal* .text*)
|
||||
*py/obj*.o*(.literal* .text*)
|
||||
*py/opmethods.o*(.literal* .text*)
|
||||
*py/parse*.o*(.literal* .text*)
|
||||
*py/qstr.o*(.literal* .text*)
|
||||
*py/repl.o*(.literal* .text*)
|
||||
*py/runtime.o*(.literal* .text*)
|
||||
*py/scope.o*(.literal* .text*)
|
||||
*py/sequence.o*(.literal* .text*)
|
||||
*py/showbc.o*(.literal* .text*)
|
||||
*py/smallint.o*(.literal* .text*)
|
||||
*py/stackctrl.o*(.literal* .text*)
|
||||
*py/stream.o*(.literal* .text*)
|
||||
*py/unicode.o*(.literal* .text*)
|
||||
*py/vm.o*(.literal* .text*)
|
||||
*py/vstr.o*(.literal* .text*)
|
||||
*py/warning.o*(.literal* .text*)
|
||||
|
||||
*extmod/*.o*(.literal* .text*)
|
||||
|
||||
*lib/fatfs/*.o*(.literal*, .text*)
|
||||
*/libaxtls.a:(.literal*, .text*)
|
||||
*lib/berkeley-db-1.xx/*.o(.literal*, .text*)
|
||||
*lib/libm/*.o*(.literal*, .text*)
|
||||
*lib/mp-readline/*.o(.literal*, .text*)
|
||||
*lib/netutils/*.o*(.literal*, .text*)
|
||||
*lib/timeutils/*.o*(.literal*, .text*)
|
||||
*lib/utils/*.o*(.literal*, .text*)
|
||||
|
||||
*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*)
|
||||
*machine_pin.o(.literal*, .text*)
|
||||
*machine_pwm.o(.literal*, .text*)
|
||||
*machine_rtc.o(.literal*, .text*)
|
||||
*machine_adc.o(.literal*, .text*)
|
||||
*machine_uart.o(.literal*, .text*)
|
||||
*modpybi2c.o(.literal*, .text*)
|
||||
*modmachine.o(.literal*, .text*)
|
||||
*machine_wdt.o(.literal*, .text*)
|
||||
*machine_spi.o(.literal*, .text*)
|
||||
*machine_hspi.o(.literal*, .text*)
|
||||
*hspi.o(.literal*, .text*)
|
||||
*modesp.o(.literal* .text*)
|
||||
*modnetwork.o(.literal* .text*)
|
||||
*moduos.o(.literal* .text*)
|
||||
*modutime.o(.literal* .text*)
|
||||
*modlwip.o(.literal* .text*)
|
||||
*modsocket.o(.literal* .text*)
|
||||
*modonewire.o(.literal* .text*)
|
||||
|
||||
/* we put as much rodata as possible in this section */
|
||||
/* note that only rodata accessed as a machine word is allowed here */
|
||||
*py/qstr.o(.rodata.const_pool)
|
||||
*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
|
||||
*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
|
||||
*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
|
||||
*/frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
|
||||
*/frozen.o(.rodata.mp_frozen_content) /* frozen modules */
|
||||
|
||||
/* for -mforce-l32 */
|
||||
build/*.o(.rodata*)
|
||||
|
||||
_irom0_text_end = ABSOLUTE(.);
|
||||
} >irom0_0_seg :irom0_0_phdr
|
||||
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.UserEnter.text)
|
||||
. = ALIGN(16);
|
||||
*(.DebugExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.NMIExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.KernelExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.UserExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.DoubleExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN (16);
|
||||
*(.entry.text)
|
||||
*(.init.literal)
|
||||
*(.init)
|
||||
*(.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)
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
.lit4 : ALIGN(4)
|
||||
{
|
||||
_lit4_start = ABSOLUTE(.);
|
||||
*(*.lit4)
|
||||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
*(.jcr)
|
||||
_data_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*(.sdk.version)
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||
*(.xt_except_table)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
*(.eh_frame)
|
||||
/* C++ constructor and destructor tables, properly ordered: */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
/* C++ exception handlers table: */
|
||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc)
|
||||
*(.gnu.linkonce.h.*)
|
||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||
_bss_table_start = ABSOLUTE(.);
|
||||
LONG(_bss_start)
|
||||
LONG(_bss_end)
|
||||
_bss_table_end = ABSOLUTE(.);
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
_heap_start = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_bss_phdr
|
||||
}
|
||||
|
||||
/* get ROM code address */
|
||||
INCLUDE "eagle.rom.addr.v6.ld"
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
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");
|
||||
}
|
|
@ -75,7 +75,7 @@ void ets_event_poll(void);
|
|||
// C-level pin HAL
|
||||
#include "etshal.h"
|
||||
#include "gpio.h"
|
||||
#include "esp8266/modpyb.h"
|
||||
#include "esp8266/modmachine.h"
|
||||
#define mp_hal_pin_obj_t uint32_t
|
||||
#define mp_hal_get_pin_obj(o) mp_obj_get_pin(o)
|
||||
void mp_hal_pin_input(mp_hal_pin_obj_t pin);
|
||||
|
|
|
@ -33,7 +33,7 @@ void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32
|
|||
#ifdef NEO_KHZ400
|
||||
if(is800KHz) {
|
||||
#endif
|
||||
time0 = fcpu / 2500000; // 0.4us
|
||||
time0 = fcpu / 2857143; // 0.35us
|
||||
time1 = fcpu / 1250000; // 0.8us
|
||||
period = fcpu / 800000; // 1.25us per bit
|
||||
#ifdef NEO_KHZ400
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "etshal.h"
|
||||
#include "user_interface.h"
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
#include "esponewire.h"
|
||||
|
||||
#define TIMING_RESET1 (0)
|
||||
|
|
|
@ -24,7 +24,9 @@ extern void ets_wdt_disable(void);
|
|||
extern void wdt_feed(void);
|
||||
|
||||
// Opaque structure
|
||||
typedef char MD5_CTX[64];
|
||||
#ifndef MD5_CTX
|
||||
typedef char MD5_CTX[88];
|
||||
#endif
|
||||
|
||||
void MD5Init(MD5_CTX *context);
|
||||
void MD5Update(MD5_CTX *context, const void *data, unsigned int len);
|
||||
|
@ -32,6 +34,12 @@ void MD5Final(unsigned char digest[16], MD5_CTX *context);
|
|||
|
||||
// These prototypes are for recent SDKs with "malloc tracking"
|
||||
void *pvPortMalloc(unsigned sz, const char *fname, int line);
|
||||
void *pvPortZalloc(unsigned sz, const char *fname, int line);
|
||||
void *pvPortRealloc(void *p, unsigned sz, const char *fname, int line);
|
||||
void vPortFree(void *p, const char *fname, int line);
|
||||
|
||||
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);
|
||||
|
||||
#endif // _INCLUDED_ETSHAL_H_
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "py/obj.h"
|
||||
#include "lib/fatfs/ff.h"
|
||||
#include "timeutils.h"
|
||||
#include "modpybrtc.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
DWORD get_fattime(void) {
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "etshal.h"
|
||||
#include "ets_alt_task.h"
|
||||
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
// this is in a separate file so it can go in iRAM
|
||||
void pin_intr_handler_iram(void *arg) {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mphal.h"
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
#define GET_TRIGGER(phys_port) \
|
||||
GPIO_PIN_INT_TYPE_GET(GPIO_REG_READ(GPIO_PIN_ADDR(phys_port)))
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
typedef struct _pyb_pwm_obj_t {
|
||||
mp_obj_base_t base;
|
|
@ -32,7 +32,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "timeutils.h"
|
||||
#include "user_interface.h"
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
typedef struct _pyb_rtc_obj_t {
|
||||
mp_obj_base_t base;
|
|
@ -34,7 +34,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
// UartDev is defined and initialized in rom code.
|
||||
extern UartDevice UartDev;
|
|
@ -39,7 +39,7 @@
|
|||
#include "gccollect.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
STATIC char heap[28 * 1024];
|
||||
STATIC char heap[36 * 1024];
|
||||
|
||||
STATIC void mp_reset(void) {
|
||||
mp_stack_set_top((void*)0x40000000);
|
||||
|
@ -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 (;;) {
|
||||
}
|
||||
|
|
|
@ -45,8 +45,7 @@
|
|||
#include "mem.h"
|
||||
#include "espneopixel.h"
|
||||
#include "espapa102.h"
|
||||
#include "modpyb.h"
|
||||
#include "modpybrtc.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
#define MODESP_ESPCONN (0)
|
||||
|
||||
|
@ -629,6 +628,11 @@ STATIC mp_obj_t esp_flash_size(void) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);
|
||||
|
||||
STATIC mp_obj_t esp_flash_user_start(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(0x90000);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_user_start_obj, esp_flash_user_start);
|
||||
|
||||
STATIC mp_obj_t esp_check_fw(void) {
|
||||
MD5_CTX ctx;
|
||||
uint32_t *sz_p = (uint32_t*)0x40208ffc;
|
||||
|
@ -706,6 +710,7 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR_flash_write), (mp_obj_t)&esp_flash_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_flash_erase), (mp_obj_t)&esp_flash_erase_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_flash_size), (mp_obj_t)&esp_flash_size_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_flash_user_start), (mp_obj_t)&esp_flash_user_start_obj },
|
||||
#if MODESP_ESPCONN
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&esp_socket_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&esp_getaddrinfo_obj },
|
||||
|
|
|
@ -33,8 +33,7 @@
|
|||
#include "extmod/machine_mem.h"
|
||||
#include "extmod/machine_pulse.h"
|
||||
#include "extmod/machine_i2c.h"
|
||||
#include "modpyb.h"
|
||||
#include "modpybrtc.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
#include "xtirq.h"
|
||||
#include "os_type.h"
|
||||
|
|
|
@ -13,7 +13,7 @@ extern const mp_obj_type_t pyb_spi_type;
|
|||
extern const mp_obj_type_t pyb_hspi_type;
|
||||
extern const mp_obj_type_t machine_spi_type;
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_info_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj);
|
||||
|
||||
typedef struct _pyb_pin_obj_t {
|
||||
mp_obj_base_t base;
|
||||
|
@ -33,4 +33,11 @@ pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in);
|
|||
int pin_get(uint pin);
|
||||
void pin_set(uint pin, int value);
|
||||
|
||||
extern uint32_t pyb_rtc_alarm0_wake;
|
||||
extern uint64_t pyb_rtc_alarm0_expiry;
|
||||
|
||||
void pyb_rtc_set_us_since_2000(uint64_t nowus);
|
||||
uint64_t pyb_rtc_get_us_since_2000();
|
||||
void rtc_prepare_deepsleep(uint64_t sleep_us);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_ESP8266_MODPYB_H__
|
|
@ -100,17 +100,23 @@ STATIC mp_obj_t esp_connect(mp_uint_t n_args, const mp_obj_t *args) {
|
|||
mp_uint_t len;
|
||||
const char *p;
|
||||
|
||||
if (n_args > 1) {
|
||||
p = mp_obj_str_get_data(args[1], &len);
|
||||
memcpy(config.ssid, p, len);
|
||||
if (n_args > 2) {
|
||||
p = mp_obj_str_get_data(args[2], &len);
|
||||
} else {
|
||||
p = "";
|
||||
}
|
||||
memcpy(config.password, p, len);
|
||||
|
||||
error_check(wifi_station_set_config(&config), "Cannot set STA config");
|
||||
}
|
||||
error_check(wifi_station_connect(), "Cannot connect to AP");
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_connect_obj, 3, 7, esp_connect);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_connect_obj, 1, 7, esp_connect);
|
||||
|
||||
STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) {
|
||||
require_if(self_in, STATION_IF);
|
||||
|
@ -295,7 +301,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
|
|||
switch ((uintptr_t)kwargs->table[i].key) {
|
||||
case QS(MP_QSTR_mac): {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
|
||||
mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ);
|
||||
if (bufinfo.len != 6) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
|
||||
"invalid buffer length"));
|
||||
|
@ -336,6 +342,14 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
|
|||
cfg.ap.channel = mp_obj_get_int(kwargs->table[i].value);
|
||||
break;
|
||||
}
|
||||
case QS(MP_QSTR_dhcp_hostname): {
|
||||
req_if = STATION_IF;
|
||||
if (self->if_id == STATION_IF) {
|
||||
const char *s = mp_obj_str_get_str(kwargs->table[i].value);
|
||||
wifi_station_set_hostname((char*)s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
goto unknown;
|
||||
}
|
||||
|
@ -389,6 +403,12 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs
|
|||
req_if = SOFTAP_IF;
|
||||
val = MP_OBJ_NEW_SMALL_INT(cfg.ap.channel);
|
||||
break;
|
||||
case QS(MP_QSTR_dhcp_hostname): {
|
||||
req_if = STATION_IF;
|
||||
char* s = wifi_station_get_hostname();
|
||||
val = mp_obj_new_str(s, strlen(s), false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
goto unknown;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
#include "esponewire.h"
|
||||
|
||||
STATIC mp_obj_t onewire_timings(mp_obj_t timings_in) {
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
|
||||
#include "py/gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "modpyb.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
// The pyb module no longer exists since all functionality now appears
|
||||
// elsewhere, in more standard places (eg time, machine modules). The
|
||||
// only remaining function is pyb.info() which has been moved to the
|
||||
// esp module, pending deletion/renaming/moving elsewher.
|
||||
// esp module, pending deletion/renaming/moving elsewhere.
|
||||
|
||||
STATIC mp_obj_t pyb_info(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// print info about memory
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
extern uint32_t pyb_rtc_alarm0_wake;
|
||||
extern uint64_t pyb_rtc_alarm0_expiry;
|
||||
|
||||
void pyb_rtc_set_us_since_2000(uint64_t nowus);
|
||||
|
||||
uint64_t pyb_rtc_get_us_since_2000();
|
||||
|
||||
void rtc_prepare_deepsleep(uint64_t sleep_us);
|
|
@ -1,6 +1,8 @@
|
|||
# DS18x20 temperature sensor driver for MicroPython.
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
from micropython import const
|
||||
|
||||
_CONVERT = const(0x44)
|
||||
_RD_SCRATCH = const(0xbe)
|
||||
_WR_SCRATCH = const(0x4e)
|
||||
|
@ -43,4 +45,7 @@ class DS18X20:
|
|||
t = buf[0] >> 1
|
||||
return t - 0.25 + (buf[7] - buf[6]) / buf[7]
|
||||
else:
|
||||
return (buf[1] << 8 | buf[0]) / 16
|
||||
t = buf[1] << 8 | buf[0]
|
||||
if t & 0x8000: # sign bit set
|
||||
t = -((t ^ 0xffff) + 1)
|
||||
return t / 16
|
||||
|
|
|
@ -3,7 +3,7 @@ import esp
|
|||
class FlashBdev:
|
||||
|
||||
SEC_SIZE = 4096
|
||||
START_SEC = 0x90000 // SEC_SIZE
|
||||
START_SEC = esp.flash_user_start() // SEC_SIZE
|
||||
NUM_BLK = 0x6b
|
||||
|
||||
def __init__(self, blocks=NUM_BLK):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# 1-Wire driver for MicroPython on ESP8266
|
||||
# MIT license; Copyright (c) 2016 Damien P. George
|
||||
|
||||
from micropython import const
|
||||
import _onewire as _ow
|
||||
|
||||
class OneWireError(Exception):
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../tools/upip.py
|
|
@ -0,0 +1 @@
|
|||
../../tools/upip_utarfile.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)
|
||||
|
@ -55,18 +59,16 @@ def start(port=8266, password=None):
|
|||
stop()
|
||||
if password is None:
|
||||
try:
|
||||
import port_config
|
||||
_webrepl.password(port_config.WEBREPL_PASS)
|
||||
import webrepl_cfg
|
||||
_webrepl.password(webrepl_cfg.PASS)
|
||||
setup_conn(port, accept_conn)
|
||||
print("Started webrepl in normal mode")
|
||||
except:
|
||||
import webrepl_setup
|
||||
setup_conn(port, webrepl_setup.handle_conn)
|
||||
print("Started webrepl in setup mode")
|
||||
print("WebREPL is not configured, run 'import webrepl_setup'")
|
||||
else:
|
||||
_webrepl.password(password)
|
||||
setup_conn(port, accept_conn)
|
||||
print("Started webrepl in normal mode")
|
||||
print("Started webrepl in manual override mode")
|
||||
|
||||
|
||||
def start_foreground(port=8266):
|
||||
|
|
|
@ -1,83 +1,111 @@
|
|||
import sys
|
||||
import socket
|
||||
import time
|
||||
#import uos as os
|
||||
import os
|
||||
import machine
|
||||
|
||||
from websocket import *
|
||||
import websocket_helper
|
||||
RC = "./boot.py"
|
||||
CONFIG = "./webrepl_cfg.py"
|
||||
|
||||
|
||||
def setup_server():
|
||||
s = socket.socket()
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
||||
ai = socket.getaddrinfo("0.0.0.0", 8266)
|
||||
addr = ai[0][4]
|
||||
|
||||
s.bind(addr)
|
||||
s.listen(1)
|
||||
return s
|
||||
|
||||
def getpass(stream, prompt):
|
||||
stream.write(prompt)
|
||||
passwd = b""
|
||||
def input_choice(prompt, choices):
|
||||
while 1:
|
||||
c = stream.read(1)
|
||||
if c in (b"\r", b"\n"):
|
||||
stream.write("\r\n")
|
||||
return passwd
|
||||
passwd += c
|
||||
stream.write("*")
|
||||
resp = input(prompt)
|
||||
if resp in choices:
|
||||
return resp
|
||||
|
||||
def handle_conn(listen_sock):
|
||||
cl, remote_addr = listen_sock.accept()
|
||||
|
||||
print("""
|
||||
|
||||
First-time WebREPL connection has been received. WebREPL initial setup
|
||||
will now start over this connection. During setup, UART REPL will be
|
||||
non-responsive. After setup finishes, the board will be rebooted. In
|
||||
case of error during setup, current session will continue.
|
||||
|
||||
If you receive this message unexpectedly, it may mean that your WebREPL
|
||||
connection is being hacked (power off board if unsure).
|
||||
""")
|
||||
|
||||
websocket_helper.server_handshake(cl)
|
||||
ws = websocket(cl)
|
||||
|
||||
ws.write("""\
|
||||
Welcome to MicroPython WebREPL!\r
|
||||
\r
|
||||
This is the first time you connect to WebREPL, so please set a password\r
|
||||
to use for the following WebREPL sessions. Once you enter the password\r
|
||||
twice, your board will reboot with WebREPL running in active mode. On\r
|
||||
some boards, you may need to press reset button or reconnect power.\r
|
||||
\r
|
||||
""")
|
||||
def getpass(prompt):
|
||||
return input(prompt)
|
||||
|
||||
def input_pass():
|
||||
while 1:
|
||||
passwd1 = getpass(ws, "New password: ")
|
||||
passwd1 = getpass("New password: ")
|
||||
if len(passwd1) < 4:
|
||||
ws.write("Password too short\r\n")
|
||||
print("Password too short")
|
||||
continue
|
||||
elif len(passwd1) > 9:
|
||||
ws.write("Password too long\r\n")
|
||||
print("Password too long")
|
||||
continue
|
||||
passwd2 = getpass(ws, "Confirm password: ")
|
||||
passwd2 = getpass("Confirm password: ")
|
||||
if passwd1 == passwd2:
|
||||
break
|
||||
ws.write("Passwords do not match\r\n")
|
||||
return passwd1
|
||||
print("Passwords do not match")
|
||||
|
||||
with open("port_config.py", "w") as f:
|
||||
f.write("WEBREPL_PASS = %r\n" % passwd1.decode("ascii"))
|
||||
|
||||
ws.write("Password successfully set, restarting...\r\n")
|
||||
cl.close()
|
||||
time.sleep(2)
|
||||
import machine
|
||||
def exists(fname):
|
||||
try:
|
||||
with open(fname):
|
||||
pass
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
def copy_stream(s_in, s_out):
|
||||
buf = bytearray(64)
|
||||
while 1:
|
||||
sz = s_in.readinto(buf)
|
||||
s_out.write(buf, sz)
|
||||
|
||||
|
||||
def get_daemon_status():
|
||||
with open(RC) as f:
|
||||
for l in f:
|
||||
if "webrepl" in l:
|
||||
if l.startswith("#"):
|
||||
return False
|
||||
return True
|
||||
return None
|
||||
|
||||
def add_daemon():
|
||||
with open(RC) as old_f, open(RC + ".tmp", "w") as new_f:
|
||||
new_f.write("import webrepl\nwebrepl.start()\n")
|
||||
copy_stream(old_f, new_f)
|
||||
|
||||
def change_daemon(action):
|
||||
LINES = ("import webrepl", "webrepl.start()")
|
||||
with open(RC) as old_f, open(RC + ".tmp", "w") as new_f:
|
||||
for l in old_f:
|
||||
for patt in LINES:
|
||||
if patt in l:
|
||||
if action and l.startswith("#"):
|
||||
l = l[1:]
|
||||
elif not action and not l.startswith("#"):
|
||||
l = "#" + l
|
||||
new_f.write(l)
|
||||
# FatFs rename() is not POSIX compliant, will raise OSError if
|
||||
# dest file exists.
|
||||
os.remove(RC)
|
||||
os.rename(RC + ".tmp", RC)
|
||||
|
||||
|
||||
def main():
|
||||
status = get_daemon_status()
|
||||
|
||||
print("WebREPL daemon auto-start status:", "enabled" if status else "disabled")
|
||||
print("\nWould you like to (E)nable or (D)isable it running on boot?")
|
||||
print("(Empty line to quit)")
|
||||
resp = input("> ").upper()
|
||||
|
||||
if resp == "E":
|
||||
if exists(CONFIG):
|
||||
resp2 = input_choice("Would you like to change WebREPL password? (y/n) ", ("y", "n", ""))
|
||||
else:
|
||||
print("To enable WebREPL, you must set password for it")
|
||||
resp2 = "y"
|
||||
|
||||
if resp2 == "y":
|
||||
passwd = input_pass()
|
||||
with open(CONFIG, "w") as f:
|
||||
f.write("PASS = %r\n" % passwd)
|
||||
|
||||
|
||||
if resp not in ("D", "E") or (resp == "D" and not status) or (resp == "E" and status):
|
||||
print("No further action required")
|
||||
sys.exit()
|
||||
|
||||
change_daemon(resp == "E")
|
||||
|
||||
print("Changes will be activated after reboot")
|
||||
resp = input_choice("Would you like to reboot now? (y/n) ", ("y", "n", ""))
|
||||
if resp == "y":
|
||||
machine.reset()
|
||||
|
||||
|
||||
def test():
|
||||
s = setup_server()
|
||||
handle_conn(s)
|
||||
main()
|
||||
|
|
|
@ -34,8 +34,7 @@
|
|||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/smallint.h"
|
||||
#include "modpyb.h"
|
||||
#include "modpybrtc.h"
|
||||
#include "modmachine.h"
|
||||
#include "timeutils.h"
|
||||
#include "user_interface.h"
|
||||
#include "extmod/utime_mphal.h"
|
||||
|
@ -108,19 +107,20 @@ STATIC mp_obj_t time_time(void) {
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
|
||||
STATIC const mp_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||
STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_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_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 },
|
||||
{ MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&time_localtime_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&time_mktime_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_utime_sleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_utime_ticks_ms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_utime_ticks_us_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||
|
|
|
@ -182,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))
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#include <mpconfigport.h>
|
||||
|
||||
#undef MICROPY_FSUSERMOUNT
|
||||
#define MICROPY_FSUSERMOUNT (0)
|
||||
#undef MICROPY_VFS_FAT
|
||||
#define MICROPY_VFS_FAT (0)
|
||||
|
||||
#undef MICROPY_PERSISTENT_CODE_LOAD
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (0)
|
||||
|
||||
#undef MICROPY_PY_IO_FILEIO
|
||||
#define MICROPY_PY_IO_FILEIO (0)
|
||||
|
||||
#undef MICROPY_PY_SYS_STDIO_BUFFER
|
||||
#define MICROPY_PY_SYS_STDIO_BUFFER (0)
|
||||
#undef MICROPY_PY_BUILTINS_SLICE_ATTRS
|
||||
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (0)
|
||||
#undef MICROPY_PY_ALL_SPECIAL_METHODS
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
|
|
@ -2,27 +2,16 @@
|
|||
# MIT license; Copyright (c) 2016 Robert Foss, Daniel Busch
|
||||
|
||||
from esp import apa102_write
|
||||
from neopixel import NeoPixel
|
||||
|
||||
class APA102:
|
||||
def __init__(self, clock_pin, data_pin, n):
|
||||
|
||||
class APA102(NeoPixel):
|
||||
ORDER = (0, 1, 2, 3)
|
||||
|
||||
def __init__(self, clock_pin, data_pin, n, bpp=4):
|
||||
super().__init__(data_pin, n, bpp)
|
||||
self.clock_pin = clock_pin
|
||||
self.data_pin = data_pin
|
||||
self.n = n
|
||||
self.buf = bytearray(n * 4)
|
||||
|
||||
self.clock_pin.init(clock_pin.OUT)
|
||||
self.data_pin.init(data_pin.OUT)
|
||||
|
||||
def __setitem__(self, index, val):
|
||||
r, g, b, brightness = val
|
||||
self.buf[index * 4] = r
|
||||
self.buf[index * 4 + 1] = g
|
||||
self.buf[index * 4 + 2] = b
|
||||
self.buf[index * 4 + 3] = brightness
|
||||
|
||||
def __getitem__(self, index):
|
||||
i = index * 4
|
||||
return self.buf[i], self.buf[i + 1], self.buf[i + 2], self.buf[i + 3]
|
||||
|
||||
def write(self):
|
||||
apa102_write(self.clock_pin, self.data_pin, self.buf)
|
||||
apa102_write(self.clock_pin, self.pin, self.buf)
|
||||
|
|
|
@ -3,29 +3,30 @@
|
|||
|
||||
from esp import neopixel_write
|
||||
|
||||
|
||||
class NeoPixel:
|
||||
def __init__(self, pin, n):
|
||||
ORDER = (1, 0, 2, 3)
|
||||
|
||||
def __init__(self, pin, n, bpp=3):
|
||||
self.pin = pin
|
||||
self.n = n
|
||||
self.buf = bytearray(n * 3)
|
||||
self.bpp = bpp
|
||||
self.buf = bytearray(n * bpp)
|
||||
self.pin.init(pin.OUT)
|
||||
|
||||
def __setitem__(self, index, val):
|
||||
r, g, b = val
|
||||
self.buf[index * 3] = g
|
||||
self.buf[index * 3 + 1] = r
|
||||
self.buf[index * 3 + 2] = b
|
||||
offset = index * self.bpp
|
||||
for i in range(self.bpp):
|
||||
self.buf[offset + self.ORDER[i]] = val[i]
|
||||
|
||||
def __getitem__(self, index):
|
||||
i = index * 3
|
||||
return self.buf[i + 1], self.buf[i], self.buf[i + 2]
|
||||
offset = index * self.bpp
|
||||
return tuple(self.buf[offset + self.ORDER[i]]
|
||||
for i in range(self.bpp))
|
||||
|
||||
def fill(self, color):
|
||||
r, g, b = color
|
||||
for i in range(len(self.buf) / 3):
|
||||
self.buf[i * 3] = g
|
||||
self.buf[i * 3 + 1] = r
|
||||
self.buf[i * 3 + 2] = b
|
||||
for i in range(self.n):
|
||||
self[i] = color
|
||||
|
||||
def write(self):
|
||||
neopixel_write(self.pin, self.buf, True)
|
||||
|
|
|
@ -24,8 +24,8 @@ def main():
|
|||
print("STA ifconfig:", network.WLAN(network.STA_IF).ifconfig())
|
||||
print("AP ifconfig:", network.WLAN(network.AP_IF).ifconfig())
|
||||
print("Free WiFi driver buffers of type:")
|
||||
for i in range(5):
|
||||
print("%d: %d" % (i, esp.esf_free_bufs(i)))
|
||||
for i, comm in enumerate(("1,2 TX", "4 Mngmt TX(len: 0x41-0x100)", "5 Mngmt TX (len: 0-0x40)", "7", "8 RX")):
|
||||
print("%d: %d (%s)" % (i, esp.esf_free_bufs(i), comm))
|
||||
print("lwIP PCBs:")
|
||||
lwip.print_pcbs()
|
||||
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
This directory shows the best practices for using MicroPython hardware API
|
||||
(`machine` module). `machine` module strives to provide consistent API
|
||||
across various boards, with the aim to enable writing portable applications,
|
||||
which would work from a board to board, from a system to another systems.
|
||||
This is inherently a hard problem, because hardware is different from one
|
||||
board type to another, and even from examplar of board to another. For
|
||||
example, if your app requires an external LED, one user may connect it
|
||||
to one GPIO pin, while another user may find it much more convinient to
|
||||
use another pin. This of course applies to relays, buzzers, sensors, etc.
|
||||
|
||||
With complications above in mind, it's still possible to write portable
|
||||
applications by using "low[est] denominator" subset of hardware API and
|
||||
following simple rules outlined below. The applications won't be able
|
||||
to rely on advanced hardware capabilities of a particular board and
|
||||
will be limited to generic capabilities, but it's still possible to
|
||||
write many useful applications in such a way, with the obvious benefit of
|
||||
"write once - run everywhere" approach (only configuration for a particular
|
||||
board is required).
|
||||
|
||||
The key to this approach is splitting your application into (at least)
|
||||
2 parts:
|
||||
|
||||
* main application logic
|
||||
* hardware configuration
|
||||
|
||||
The key point is that hardware configuration should be a separate file
|
||||
(module in Python terms). A good name would be `hwconfig.py`, and that's
|
||||
how we'll call it from now on. Another key point is that main application
|
||||
should never instantiate (construct) hardware objects directly. Instead,
|
||||
they should be defined in `hwconfig.py`, and main application should
|
||||
import and reference hardware objects via this module. The simplest
|
||||
application of this idea would look like:
|
||||
|
||||
`hwconfig.py`:
|
||||
|
||||
from machine import Pin
|
||||
|
||||
LED = Pin("A3", Pin.OUT)
|
||||
|
||||
`app.py`:
|
||||
|
||||
from hwconfig import *
|
||||
import utime
|
||||
|
||||
while True:
|
||||
LED.value(1)
|
||||
utime.sleep_ms(500)
|
||||
LED.value(0)
|
||||
utime.sleep_ms(500)
|
||||
|
||||
|
||||
To deploy this application to a particular board, a user will need:
|
||||
|
||||
1. Edit `hwconfig.py` to adjust Pin and other hardware peripheral
|
||||
parameters and locations.
|
||||
2. Actually deploy `hwconfig.py` and `app.py` to a board (e.g. copy to
|
||||
board's filesystem, or build new firmware with these modules frozen
|
||||
into it).
|
||||
|
||||
Note that there's no need to edit the main application code! (Which may
|
||||
be complex, while `hwconfig.py` should usually remain short enough, and
|
||||
focused solely on hardware configuration).
|
||||
|
||||
An obvious improvement to this approach is the following. There're few
|
||||
well-known boards which run MicroPython, and most of them include an
|
||||
onboard LED. So, to help users of these boards to do configuration
|
||||
quickly (that's especially important for novice users, for who may
|
||||
be stumped by the need to reach out to a board reference to find LED
|
||||
pin assignments), `hwconfig.py` your application ships may include
|
||||
commented out sections with working configurations for different
|
||||
boards. The step 1 above then will be:
|
||||
|
||||
1. Look thru `hwconfig.py` to find a section which either exactly
|
||||
matches your board, or the closest to it. Uncomment, and if any
|
||||
adjustments required, apply them.
|
||||
|
||||
It's important to keep in mind that adjustments may be always required,
|
||||
and that there may be users whose configuration doesn't match any of
|
||||
the available. So, always include a section or instructions for them.
|
||||
Consider for example that even on a supported board, user may want to
|
||||
blink not an on-board LED, but the one they connected externally.
|
||||
MicroPython's Hardware API offers portability not just among "supported"
|
||||
boards, but to any board at all, so make sure users can enjoy it.
|
||||
|
||||
There's next step of improvement to make. While having one `hwconfig.py`
|
||||
with many sections would work for smaller projects with few hardware
|
||||
objects, it may become more cumbersome to maintain both on programmer's
|
||||
and user's sides for larger projects. Then instead of single
|
||||
`hwconfig.py` file, you can provide few "template" ones for well-known
|
||||
boards:
|
||||
|
||||
* `hwconfig_pyboard.py`
|
||||
* `hwconfig_wipy.py`
|
||||
* `hwconfig_esp8266.py`
|
||||
* etc.
|
||||
|
||||
Then step 1 above will be:
|
||||
|
||||
1. Look thru available `hwconfig_*.py` files and find one which matches
|
||||
your board the best, then rename to `hwconfig.py` and make adjustments,
|
||||
if any.
|
||||
|
||||
Again, please keep in mind that there may be users whose hardware will be
|
||||
completely unlike you heard of. Give them some helpful hints too, perhaps
|
||||
provide `hwconfig_custom.py` with some instructions.
|
||||
|
||||
That's where we stop with improvements to the "separate file for hardware
|
||||
configuration" idea, as it is already pretty flexible and viable. An
|
||||
application in this directory shows it in practice, using slightly less
|
||||
trivial example than just a blinking LED: `soft_pwm.py` implements a
|
||||
software PWM (pulse width modulation) to produce an LED fade-in/fade-out
|
||||
effect - without any dependence on hardware PWM availability.
|
||||
|
||||
Note that improvements to board configuration handling may continue further.
|
||||
For example, one may invent a "configuration manager" helper module which will
|
||||
try to detect current board (among well-known ones), and load appropriate
|
||||
`hwconfig_*.py` - this assumes that a user would lazily deploy them all
|
||||
(or that application will be automatically installed, e.g. using MicroPython's
|
||||
`upip` package manager). The key point in this case remains the same as
|
||||
elaborated above - always assume there can, and will be a custom configuration,
|
||||
and it should be well supported. So, any automatic detection should be
|
||||
overridable by a user, and instructions how to do so are among the most
|
||||
important you may provide for your application.
|
||||
|
||||
By following these best practices, you will use MicroPython at its full
|
||||
potential, and let users enjoy it too. Good luck!
|
|
@ -0,0 +1,12 @@
|
|||
from machine import Pin
|
||||
|
||||
# 96Boards/Qualcomm DragonBoard 410c
|
||||
# By default, on-board LEDs are controlled by kernel LED driver.
|
||||
# To make corresponding pins be available as normal GPIO,
|
||||
# corresponding driver needs to be unbound first (as root):
|
||||
# echo -n "soc:leds" >/sys/class/leds/apq8016-sbc:green:user1/device/driver/unbind
|
||||
# Note that application also either should be run as root, or
|
||||
# /sys/class/gpio ownership needs to be changed.
|
||||
|
||||
# User LED 1 on gpio21
|
||||
LED = Pin(21, Pin.OUT)
|
|
@ -0,0 +1,5 @@
|
|||
from machine import Pin
|
||||
|
||||
# ESP12 module as used by many boards
|
||||
# Blue LED on pin 2
|
||||
LED = Pin(2, Pin.OUT)
|
|
@ -0,0 +1,5 @@
|
|||
from machine import Pin
|
||||
|
||||
# Freescale/NXP FRDM-K64F board
|
||||
# Blue LED on port B, pin 21
|
||||
LED = Pin(("GPIO_1", 21), Pin.OUT)
|
|
@ -0,0 +1,38 @@
|
|||
import utime
|
||||
from hwconfig import LED
|
||||
|
||||
|
||||
# Using sleep_ms() gives pretty poor PWM resolution and
|
||||
# brightness control, but we use it in the attempt to
|
||||
# make this demo portable to even more boards (e.g. to
|
||||
# those which don't provide sleep_us(), or provide, but
|
||||
# it's not precise, like would be on non realtime OSes).
|
||||
# We otherwise use 20ms period, to make frequency not less
|
||||
# than 50Hz to avoid visible flickering (you may still see
|
||||
# if you're unlucky).
|
||||
def pwm_cycle(led, duty, cycles):
|
||||
duty_off = 20 - duty
|
||||
for i in range(cycles):
|
||||
if duty:
|
||||
led.value(1)
|
||||
utime.sleep_ms(duty)
|
||||
if duty_off:
|
||||
led.value(0)
|
||||
utime.sleep_ms(duty_off)
|
||||
|
||||
|
||||
# At the duty setting of 1, an LED is still pretty bright, then
|
||||
# at duty 0, it's off. This makes rather unsmooth transition, and
|
||||
# breaks fade effect. So, we avoid value of 0 and oscillate between
|
||||
# 1 and 20. Actually, highest values like 19 and 20 are also
|
||||
# barely distinguishible (like, both of them too bright and burn
|
||||
# your eye). So, improvement to the visible effect would be to use
|
||||
# more steps (at least 10x), and then higher frequency, and use
|
||||
# range which includes 1 but excludes values at the top.
|
||||
while True:
|
||||
# Fade in
|
||||
for i in range(1, 21):
|
||||
pwm_cycle(LED, i, 2)
|
||||
# Fade out
|
||||
for i in range(20, 0, -1):
|
||||
pwm_cycle(LED, i, 2)
|
|
@ -1,3 +1,5 @@
|
|||
# Do not use this code in real projects! Read
|
||||
# http_server_simplistic_commented.py for details.
|
||||
try:
|
||||
import usocket as socket
|
||||
except:
|
||||
|
|
|
@ -57,6 +57,6 @@ typedef struct _fs_user_mount_t {
|
|||
fs_user_mount_t *fatfs_mount_mkfs(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args, bool mkfs);
|
||||
mp_obj_t fatfs_umount(mp_obj_t bdev_or_path_in);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(fsuser_mount_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(fsuser_umount_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(fsuser_mkfs_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mount_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(fsuser_umount_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_KW(fsuser_mkfs_obj);
|
||||
|
|
|
@ -32,6 +32,6 @@
|
|||
|
||||
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(machine_time_pulse_us_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj);
|
||||
|
||||
#endif // __MICROPY_INCLUDED_EXTMOD_MACHINE_PULSE_H__
|
||||
|
|
|
@ -47,9 +47,9 @@ typedef struct _mp_machine_soft_spi_obj_t {
|
|||
|
||||
void mp_machine_soft_spi_transfer(mp_obj_base_t *self, size_t len, const uint8_t *src, uint8_t *dest);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_read_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_readinto_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_machine_spi_write_readinto_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_read_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_machine_spi_readinto_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_2(mp_machine_spi_write_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_3(mp_machine_spi_write_readinto_obj);
|
||||
|
||||
#endif // MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <stddef.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(mp_uos_dupterm_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj);
|
||||
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
void mp_uos_dupterm_tx_strn(const char *str, size_t len);
|
||||
|
|
|
@ -33,10 +33,10 @@ extern mp_obj_t mod_binascii_a2b_base64(mp_obj_t data);
|
|||
extern mp_obj_t mod_binascii_b2a_base64(mp_obj_t data);
|
||||
extern mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_hexlify_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_unhexlify_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_a2b_base64_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_b2a_base64_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(mod_binascii_crc32_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_hexlify_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(mod_binascii_unhexlify_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj);
|
||||
|
||||
#endif /* MICROPY_EXTMOD_MODUBINASCII */
|
||||
|
|
|
@ -33,14 +33,17 @@
|
|||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/runtime.h"
|
||||
#include "extmod/utime_mphal.h"
|
||||
|
||||
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
#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
|
||||
MP_THREAD_GIL_ENTER();
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_obj, time_sleep);
|
||||
|
@ -48,7 +51,9 @@ 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_THREAD_GIL_EXIT();
|
||||
mp_hal_delay_ms(ms);
|
||||
MP_THREAD_GIL_ENTER();
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
@ -57,33 +62,47 @@ 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_THREAD_GIL_EXIT();
|
||||
mp_hal_delay_us(us);
|
||||
MP_THREAD_GIL_ENTER();
|
||||
}
|
||||
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);
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
|
||||
}
|
||||
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);
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
|
||||
}
|
||||
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);
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
|
||||
}
|
||||
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) {
|
||||
STATIC mp_obj_t time_ticks_diff(mp_obj_t end_in, mp_obj_t start_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_uint_t start = MP_OBJ_SMALL_INT_VALUE(start_in);
|
||||
mp_uint_t end = MP_OBJ_SMALL_INT_VALUE(end_in);
|
||||
// Optimized formula avoiding if conditions. We adjust difference "forward",
|
||||
// wrap it around and adjust back.
|
||||
mp_int_t diff = ((end - start + MICROPY_PY_UTIME_TICKS_PERIOD / 2) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1))
|
||||
- MICROPY_PY_UTIME_TICKS_PERIOD / 2;
|
||||
return MP_OBJ_NEW_SMALL_INT(diff);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj, time_ticks_diff);
|
||||
|
||||
STATIC mp_obj_t time_ticks_add(mp_obj_t ticks_in, mp_obj_t delta_in) {
|
||||
// we assume that first argument come from ticks_xx so is small int
|
||||
mp_uint_t ticks = MP_OBJ_SMALL_INT_VALUE(ticks_in);
|
||||
mp_uint_t delta = mp_obj_get_int(delta_in);
|
||||
return MP_OBJ_NEW_SMALL_INT((ticks + delta) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj, time_ticks_add);
|
||||
|
||||
#endif // MICROPY_PY_UTIME_MP_HAL
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue