summaryrefslogtreecommitdiff
path: root/ports
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2017-11-02 12:41:50 -0700
committerScott Shawcroft <scott.shawcroft@gmail.com>2017-11-02 12:41:50 -0700
commit7b393bc406bfa50f7bbfacd573d0fdab04dcb5f4 (patch)
tree26edf5d84c27d5a86247e2c11b10905607371d3e /ports
parent3cfb06042ec46b1214576bb7013a996a287697a6 (diff)
parentfe45d78b1edd6d2202c3544797885cb0b12d4f03 (diff)
Merge tag 'v1.9.3'
Introduction of ports subdirectory where all ports are moved to The main change in this release is the introduction of a "ports/" subdirectory at the top-level of the repository, and all of the ports are moved here. In the process the "stmhal" port is renamed to "stm32" to better reflect the MCU that it targets. In addition, the STM32 CMSIS and HAL sources are moved to a new submodule called "stm32lib". The bytecode has changed in this release, compared to the previous release, and as a consequence the .mpy version number has increased to version 3. This means that scripts compiled with the previous mpy-cross must be recompiled to work with this new version. There have also been various enhancements and optimisations, such as: check for valid UTF-8 when creating str objects, support for reverse special binary operations like __radd__, full domain checking in the math module, support for floor-division and modulo in the viper emitter, and addition of stack overflow checking when executing a regex. The stm32 port sees improved support for F7 MCUs, addition of a new board B_L475E_IOT01A based on the STM32L475, and support for the Wiznet W5500 chipset along with improved socket behaviour. A detailed list of changes follows. py core: - objstr: startswith, endswith: check arg to be a string - nlrx86,x64: replace #define of defined() with portable macro usage - objtype: handle NotImplemented return from binary special methods - objtype: mp_obj_class_lookup: improve debug logging - map: remove unused new/free functions - make m_malloc_fail() have void return type, since it doesn't return - modstruct: in struct.pack, stop converting if there are no args left - modstruct: check and prevent buffer-read overflow in struct unpacking - modstruct: check and prevent buffer-write overflow in struct packing - nlrthumb: get working again on standard Thumb arch (ie not Thumb2) - objfloat: fix binary ops with incompatible objects - obj: fix comparison of float/complex NaN with itself - objtype: implement fallback for instance inplace special methods - objtuple: properly implement comparison with incompatible types - objstr: add check for valid UTF-8 when making a str from bytes - objlist: properly implement comparison with incompatible types - runtime0.h: move relational ops to the beginning of mp_binary_op_t - runtime0.h: move MP_BINARY_OP_DIVMOD to the end of mp_binary_op_t - objtype: make sure mp_binary_op_method_name has full size again - runtime0.h: put inplace arith ops in front of normal operations - builtinhelp: simplify code slightly by extracting object type - runtime: implement dispatch for "reverse op" special methods - nlrx86: fix building for Android/x86 - builtinhelp: change signature of help text var from pointer to array - runtime.h: change empty mp_warning macro so var-args are non empty - modbuiltins: implement abs() by dispatching to MP_UNARY_OP_ABS - {objfloat,objcomplex}: optimise MP_UNARY_OP_ABS by reusing variables - mpconfig.h: add note that using computed gotos in VM is not C99 - objstr: strip: don't strip "\0" by default - objexcept: prevent infinite recursion when allocating exceptions - stream: remove unnecessary checks for NULL return from vstr_add_len - vstr: raise a RuntimeError if fixed vstr buffer overflows - vm: use lowercase letter at start of exception message - persistentcode: define mp_raw_code_save_file() for any unix target - add config option to print warnings/errors to stderr - objfloat: support raising a negative number to a fractional power - objset: simplify set and frozenset by separating their locals dicts - objset: check that RHS of a binary op is a set/frozenset - objset: include the failed key in a KeyError raised from set.remove - objtype: change type of enum-to-qstr table to uint16_t to save space - objstr: make empty bytes object have a null-terminating byte - mpprint: only check for null string printing when NDEBUG not defined - objtype: clean up unary- and binary-op enum-to-qstr mapping tables - persistentcode: bump .mpy version number to version 3 - bc: update opcode_format_table to match the bytecode - modmath: add full checks for math domain errors - modmath: convert log2 macro into a function - formatfloat: don't print the negative sign of a NaN value - formatfloat: use standard isinf, isnan funcs instead of custom ones - modbuiltins: use existing utf8_get_char helper in builtin ord func - emitnative: implement floor-division and modulo for viper emitter - objtype: use CPython compatible method name for sizeof - objtype: fit qstrs for special methods in byte type - objtype: define all special methods if requested - objtype: introduce MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS extmod: - modubinascii: only include uzlib/tinf.h when it's really needed - modussl_mbedtls: allow to compile with MBEDTLS_DEBUG_C disabled - machine_pinbase: put PinBase singleton in ROM - re1.5: upgrade to v0.8.2, adds hook for stack overflow checking - modure: add stack overflow checking when executing a regex - uos_dupterm: update uos.dupterm() and helper funcs to have index - uos_dupterm: swallow any errors from dupterm closing the stream - vfs: replace VLA in proxy func with small, static sized array - modussl: add finaliser support for ussl objects - modussl_mbedtls: allow to compile with unix coverage build lib: - add new submodule, stm32lib containing STM32 CMSIS and HAL source - embed/abort_: use mp_raise_msg helper function - libm: fix tanhf so that it correctly handles +/- infinity args - libm: remove implementation of log2f, use MP_NEED_LOG2 instead - axtls: update, support for SSL_EAGAIN return code - berkeley-db-1.xx: update, allow to override MINCACHE, DEFPSIZE drivers: - memory/spiflash: change from hard-coded soft SPI to generic SPI - display/ssd1306.py: improve performance of graphics methods - nrf24l01: make nRF24L01 test script more portable - display/ssd1306: implement SSD1306_I2C poweron method - display/ssd1306: make poweron() work the same with SSD1306_SPI - wiznet5k: improve the performance of socket ops with threading - wiznet5k: get low-level W5500 driver working tools: - upip: upgrade to 1.2.2 - pyboard: use repr() when quoting data in error messages - pyboard: update docstring for additional device support tests: - object_new: better messages, check user __new__() method - class_new: add checks for __init__ being called and other improvements - class_new: add another testcase for __new__/__init__ interaction - class_inplace_op: test for inplace op fallback to normal one - run-bench-tests: update locations of executables, now in ports/ - class_reverse_op: test for reverse arith ops special methods - run-tests: skip class_inplace_op for minimal profile - run-tests: fix copy-paste mistake in var name - cpydiff: add cases for locals() discrepancies - extmod: add test for ure regexes leading to infinite recursion - extmod: add test for '-' in character class in regex - run-tests: close device under test using "finally" - net_inet: update tls test to work with CPython and incl new site unix port: - rename modsocket.c to modusocket.c - modusocket: remove #if MICROPY_SOCKET_EXTRA code blocks - enable MICROPY_PY_REVERSE_SPECIAL_METHODS stm32 port: - modmachine: make machine.bootloader() work when MPU is enabled - modmachine: improve support for sleep/deepsleep on F7 MCUs - compute PLL freq table during build instead of at run time - modmachine: for F7 MCU, save power by reducing internal volt reg - boards/pllvalues.py: make script work with both Python 2 and 3 - Makefile: use lib/stm32lib instead of local cmsis and hal files - remove cmsis and hal files, they are now a submodule - Makefile: automatically fetch stm32lib submodule if needed - update to new STM Cube HAL library - fix clock initialisation of L4 MCUs - rename stmhal port directory to stm32 - remove unused usbd_msc.c file - boards: change remaining stm32f4xx_hal_conf.h to unix line ending - boards: change linker scripts to use "K" instead of hex byte size - boards: fix I2C1 pin mapping on NUCLEO_F401RE/F411RE boards - i2c: when scanning for I2C devices only do 1 probe per address - modnwwiznet5k: release the GIL on blocking network operations - boards: add new board B_L475E_IOT01A based on STM32L475 - make-stmconst.py: make sure mpz const data lives in ROM - timer: make pyb.Timer() instances persistent - mpconfigport.h: add configuration for max periphs on L4 series - usbdev: make the USBD callback struct const so it can go in ROM - usbdev: change static function variable to non-static - usbdev: put all CDC state in a struct - usbdev: put all HID state in a struct - usbdev: simplify CDC tx/rx buffer passing - usbdev: simplify HID tx/rx buffer passing - usbdev/core: add state parameter to all callback functions - usbdev: put all state for the USB device driver in a struct - usbdev: simplify pointers to MSC state and block dev operations - usbdev: merge all global USB device state into a single struct - usbdev: make device descriptor callbacks take a state pointer - usbdev: move all the USB device descriptor state into its struct - timer: enable ARPE so that timer freq can be changed smoothly - modnwwiznet5k: get the IP address of an established socket - boards: fix typos in stm32f767_af.csv table - usbd_cdc_interface: don't reset CDC output buf on initialisation - modnwwiznet5k: implement WIZNET5K.isconnected() method - modusocket: make getaddrinfo() work when passed an IP address - modusocket: return OSError(-2) if getaddrinfo fails - mpconfigport.h: add MICROPY_THREAD_YIELD() macro - modnwwiznet5k: add support for W5500 Ethernet chip - modnwwiznet5k: increase SPI bus speed to 42MHz - modnwwiznet5k: implement stream ioctl for the Wiznet driver - mphalport: improve efficiency of mp_hal_stdout_tx_strn_cooked - make uos.dupterm() conform to specs by using extmod version cc3200 port: - enable micropython.kbd_intr() method - use standard implementation of keyboard interrupt esp8266 port: - rename axtls_helpers.c to posix_helpers.c - posix_helpers: set ENOMEM on memory alloc failure - set DEFPSIZE=1024, MINCACHE=3 for "btree" module - esp_mphal: send data in chunks to mp_uos_dupterm_tx_strn - modnetwork: add "bssid" keyword arg to WLAN.connect() method - modules/webrepl_setup: add info about allowed password length zephyr port: - Makefile: revamp "test" target after ports were moved to ports/ - use CONFIG_NET_APP_SETTINGS to setup initial network addresses - switch to interrupt-driven pull-style console pic16bit port: - add definition of SEEK_SET to unistd.h docs: - pyboard/tutorial: add "timeout=0" to UART in pass-through example - more xrefs to "MicroPython port" in glossary - library/network: fix ref to "socket" module (should be "usocket") - machine.Signal: improve style/grammar and add usage example - library: add description of "index" parameter to uos.dupterm() - library/micropython: fix typo in RST formatting - library/framebuf.rst: generalise constructor to all colour formats - btree: describe page caching policy of the underlying implementation - esp8266/tutorial: update neopixel with example of using 4 bbp - library/network: clarify usage of "bssid" arg in connect() method - pyboard/quickref: add info for Switch, RTC, CAN, Accel classes - pyboard/tutorial: update now that yellow LED also supports PWM - esp8266/quickref: add quickref info for RTC class - library: add missing cross-ref links for classes in pyb module - library/network: update docs to state that W5500 is supported - uselect: document one-shot polling mode - usocket: elaborate descriptions - usocket: document inet_ntop(), inet_pton() - library/network: add dhcp_hostname parameter - reference/isr_rules: minor typo correction - ussl: fix module name refs and use "MicroPython port" term - esp8266/general: add section on TLS limitations - usocket: document that settimeout() isn't supported by all ports - ure: add "|" (alternative) to the list of supported operators - reference/isr_rules.rst: add tutorial on use of micropython.schedule() travis: - use --upgrade when pip is installing cpp-coveralls - update build command now that stm32 Wiznet config has changed examples: - hwconfig_console: add .on()/.off() methods all: - convert mp_uint_t to mp_unary_op_t/mp_binary_op_t where appropriate - convert remaining "mp_uint_t n_args" to "size_t n_args" - make new ports/ sub-directory and move all ports there - update Makefiles and others to build with new ports/ dir layout - remove inclusion of internal py header files - use NULL instead of "" when calling mp_raise exception helpers README: - update "Dependencies" section - add explicit section on contributing - add gcc and arm-none-eabi-newlib to list of required components .gitattributes: - remove obsolete entries for stmhal/hal, stmhal/cmsis - add entries for files that will move to ports/ dir
Diffstat (limited to 'ports')
-rw-r--r--ports/esp8266/esp_mphal.c37
-rw-r--r--ports/esp8266/machine_hspi.c2
-rw-r--r--ports/esp8266/machine_wdt.c2
-rw-r--r--ports/esp8266/main.c3
-rw-r--r--ports/esp8266/modnetwork.c44
-rw-r--r--ports/esp8266/modules/webrepl_setup.py9
-rw-r--r--ports/minimal/frozentest.mpybin255 -> 255 bytes
-rw-r--r--ports/stm32/Makefile6
-rw-r--r--ports/stm32/boards/stm32f767_af.csv8
-rw-r--r--ports/stm32/modnwcc3k.c2
-rw-r--r--ports/stm32/modnwwiznet5k.c48
-rw-r--r--ports/stm32/modpyb.c26
-rw-r--r--ports/stm32/moduos.c25
-rw-r--r--ports/stm32/modusocket.c55
-rw-r--r--ports/stm32/mpconfigport.h8
-rw-r--r--ports/stm32/mpconfigport.mk5
-rw-r--r--ports/stm32/mphalport.c26
-rw-r--r--ports/stm32/uart.c15
-rw-r--r--ports/stm32/uart.h1
-rw-r--r--ports/stm32/usb.c14
-rw-r--r--ports/stm32/usb.h1
-rw-r--r--ports/stm32/usbd_cdc_interface.c6
-rw-r--r--ports/stm32/usbd_cdc_interface.h4
-rw-r--r--ports/teensy/teensy_hal.c1
-rw-r--r--ports/teensy/uart.c2
-rw-r--r--ports/unix/Makefile2
-rw-r--r--ports/unix/modjni.c2
-rw-r--r--ports/unix/modusocket.c (renamed from ports/unix/modsocket.c)26
-rw-r--r--ports/unix/mpconfigport.h1
-rw-r--r--ports/unix/unix_mphal.c17
-rw-r--r--ports/zephyr/main.c5
-rw-r--r--ports/zephyr/prj_base.conf14
-rw-r--r--ports/zephyr/prj_qemu_cortex_m3.conf4
-rw-r--r--ports/zephyr/prj_qemu_x86.conf4
-rw-r--r--ports/zephyr/src/zephyr_start.c5
-rw-r--r--ports/zephyr/uart_core.c14
36 files changed, 249 insertions, 195 deletions
diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c
index 4f3ca5836..93ebc450a 100644
--- a/ports/esp8266/esp_mphal.c
+++ b/ports/esp8266/esp_mphal.c
@@ -159,41 +159,6 @@ void mp_hal_signal_input(void) {
#endif
}
-static int call_dupterm_read(void) {
- if (MP_STATE_PORT(term_obj) == NULL) {
- return -1;
- }
-
- nlr_buf_t nlr;
- if (nlr_push(&nlr) == 0) {
- mp_obj_t readinto_m[3];
- mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_readinto, readinto_m);
- readinto_m[2] = MP_STATE_PORT(dupterm_arr_obj);
- mp_obj_t res = mp_call_method_n_kw(1, 0, readinto_m);
- if (res == mp_const_none) {
- nlr_pop();
- return -2;
- }
- if (res == MP_OBJ_NEW_SMALL_INT(0)) {
- mp_uos_deactivate("dupterm: EOF received, deactivating\n", MP_OBJ_NULL);
- nlr_pop();
- return -1;
- }
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(MP_STATE_PORT(dupterm_arr_obj), &bufinfo, MP_BUFFER_READ);
- nlr_pop();
- if (*(byte*)bufinfo.buf == mp_interrupt_char) {
- mp_keyboard_interrupt();
- return -2;
- }
- return *(byte*)bufinfo.buf;
- } else {
- mp_uos_deactivate("dupterm: Exception in read() method, deactivating: ", nlr.ret_val);
- }
-
- return -1;
-}
-
STATIC void dupterm_task_handler(os_event_t *evt) {
static byte lock;
if (lock) {
@@ -201,7 +166,7 @@ STATIC void dupterm_task_handler(os_event_t *evt) {
}
lock = 1;
while (1) {
- int c = call_dupterm_read();
+ int c = mp_uos_dupterm_rx_chr();
if (c < 0) {
break;
}
diff --git a/ports/esp8266/machine_hspi.c b/ports/esp8266/machine_hspi.c
index eaabbab7e..9fd0f4868 100644
--- a/ports/esp8266/machine_hspi.c
+++ b/ports/esp8266/machine_hspi.c
@@ -149,7 +149,7 @@ mp_obj_t machine_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t
// args[0] holds the id of the peripheral
if (args[0] != MP_OBJ_NEW_SMALL_INT(1)) {
// FlashROM is on SPI0, so far we don't support its usage
- mp_raise_ValueError("");
+ mp_raise_ValueError(NULL);
}
machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t);
diff --git a/ports/esp8266/machine_wdt.c b/ports/esp8266/machine_wdt.c
index 04b42782e..4432297fa 100644
--- a/ports/esp8266/machine_wdt.c
+++ b/ports/esp8266/machine_wdt.c
@@ -51,7 +51,7 @@ STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args
case 0:
return &wdt_default;
default:
- mp_raise_ValueError("");
+ mp_raise_ValueError(NULL);
}
}
diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c
index 04ea82761..c590ab59e 100644
--- a/ports/esp8266/main.c
+++ b/ports/esp8266/main.c
@@ -101,8 +101,7 @@ STATIC void mp_reset(void) {
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR));
mp_obj_list_init(mp_sys_argv, 0);
- MP_STATE_PORT(term_obj) = MP_OBJ_NULL;
- MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL;
+
reset_pins();
#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
extern void esp_native_code_init(void);
diff --git a/ports/esp8266/modnetwork.c b/ports/esp8266/modnetwork.c
index 2c61e5dcd..b41a11f59 100644
--- a/ports/esp8266/modnetwork.c
+++ b/ports/esp8266/modnetwork.c
@@ -93,29 +93,55 @@ STATIC mp_obj_t esp_active(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_active_obj, 1, 2, esp_active);
-STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *args) {
- require_if(args[0], STATION_IF);
+STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_ssid, ARG_password, ARG_bssid };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ // parse args
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ require_if(pos_args[0], STATION_IF);
struct station_config config = {{0}};
size_t len;
const char *p;
+ bool set_config = false;
- if (n_args > 1) {
- p = mp_obj_str_get_data(args[1], &len);
+ // set parameters based on given args
+ if (args[ARG_ssid].u_obj != mp_const_none) {
+ p = mp_obj_str_get_data(args[ARG_ssid].u_obj, &len);
len = MIN(len, sizeof(config.ssid));
memcpy(config.ssid, p, len);
- if (n_args > 2) {
- p = mp_obj_str_get_data(args[2], &len);
- len = MIN(len, sizeof(config.password));
- memcpy(config.password, p, len);
+ set_config = true;
+ }
+ if (args[ARG_password].u_obj != mp_const_none) {
+ p = mp_obj_str_get_data(args[ARG_password].u_obj, &len);
+ len = MIN(len, sizeof(config.password));
+ memcpy(config.password, p, len);
+ set_config = true;
+ }
+ if (args[ARG_bssid].u_obj != mp_const_none) {
+ p = mp_obj_str_get_data(args[ARG_bssid].u_obj, &len);
+ if (len != sizeof(config.bssid)) {
+ mp_raise_ValueError(NULL);
}
+ config.bssid_set = 1;
+ memcpy(config.bssid, p, sizeof(config.bssid));
+ set_config = true;
+ }
+ if (set_config) {
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, 1, 7, esp_connect);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_connect_obj, 1, esp_connect);
STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) {
require_if(self_in, STATION_IF);
diff --git a/ports/esp8266/modules/webrepl_setup.py b/ports/esp8266/modules/webrepl_setup.py
index 52c76863a..50d866b55 100644
--- a/ports/esp8266/modules/webrepl_setup.py
+++ b/ports/esp8266/modules/webrepl_setup.py
@@ -16,12 +16,9 @@ def getpass(prompt):
def input_pass():
while 1:
- passwd1 = getpass("New password: ")
- if len(passwd1) < 4:
- print("Password too short")
- continue
- elif len(passwd1) > 9:
- print("Password too long")
+ passwd1 = getpass("New password (4-9 chars): ")
+ if len(passwd1) < 4 or len(passwd1) > 9:
+ print("Invalid password length")
continue
passwd2 = getpass("Confirm password: ")
if passwd1 == passwd2:
diff --git a/ports/minimal/frozentest.mpy b/ports/minimal/frozentest.mpy
index 87f9581bf..7c6809bf6 100644
--- a/ports/minimal/frozentest.mpy
+++ b/ports/minimal/frozentest.mpy
Binary files differ
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile
index e3cb1b217..a6e82b24d 100644
--- a/ports/stm32/Makefile
+++ b/ports/stm32/Makefile
@@ -287,13 +287,13 @@ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\
class/src/usbd_msc_data.c \
)
-ifeq ($(MICROPY_PY_WIZNET5K),1)
+ifneq ($(MICROPY_PY_WIZNET5K),0)
WIZNET5K_DIR=drivers/wiznet5k
INC += -I$(TOP)/$(WIZNET5K_DIR)
-CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=1
+CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K)
SRC_MOD += modnwwiznet5k.c
SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\
- ethernet/w5200/w5200.c \
+ ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \
ethernet/wizchip_conf.c \
ethernet/socket.c \
internet/dns/dns.c \
diff --git a/ports/stm32/boards/stm32f767_af.csv b/ports/stm32/boards/stm32f767_af.csv
index db27818c6..1708dfcca 100644
--- a/ports/stm32/boards/stm32f767_af.csv
+++ b/ports/stm32/boards/stm32f767_af.csv
@@ -15,9 +15,9 @@ PortA,PA11,,TIM1_CH4,,,,,,USART1_CTS,,CAN1_RX,OTG_FS_DM,,,,LCD_R4,EVENTOUT
PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,SAI2_FS_B,CAN1_TX,OTG_FS_DP,,,,LCD_R5,EVENTOUT
PortA,PA13,JTMS,SWDIO,,,,,,,,,,,,,,EVENTOUT
PortA,PA14,JTCK,SWCLK,,,,,,,,,,,,,,EVENTOUT
-PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,HDMICE,CSPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,,UART4_RTS,,,,,,,EVENTOUT
-PortB,PB0,,TIM1_CH2N,TIM3_CH3T,IM8_CH2N,,,,,UART4_CTS,LCD_R3,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,,EVENTOUT
-PortB,PB1,,TIM1_CH3N,TIM3_CH4T,IM8_CH3N,,,,,,LCD_R6,OTG_HS_ULPI_D2,ETH_MII_RXD3,,,,EVENTOUT
+PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,HDMICEC,SPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,,UART4_RTS,,,,,,,EVENTOUT
+PortB,PB0,,TIM1_CH2N,TIM3_CH3T,TIM8_CH2N,,,,,UART4_CTS,LCD_R3,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,,EVENTOUT
+PortB,PB1,,TIM1_CH3N,TIM3_CH4T,TIM8_CH3N,,,,,,LCD_R6,OTG_HS_ULPI_D2,ETH_MII_RXD3,,,,EVENTOUT
PortB,PB2,,,,,,,SAI1_SD_A,SPI3_MOSI/I2S3_SD,,QUADSPI_CLK,,,,,,EVENTOUT
PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK/I2S1_CK,SPI3_SCK/I2S3_CK,,,,SDMMC2_D2,,,,,EVENTOUT
PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,SPI2_NSS/I2S2_WS,,,SDMMC2_D3,,,,,EVENTOUT
@@ -41,7 +41,7 @@ PortC,PC5,,,,,,,,,SPDIFRX_IN3,,,ETH_MII_RXD1/ETH_RMII_RXD1,FMC_SDCKE0,,,EVENTOUT
PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,SDMMC2_D6,,SDMMC1_D6,DCMI_D0,LCD_HSYNC,EVENTOUT
PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,SDMMC2_D7,,SDMMC1_D7,DCMI_D1,LCD_G6,EVENTOUT
PortC,PC8,TRACED1,,TIM3_CH3,TIM8_CH3,,,,UART5_RTS,USART6_CK,,,,SDMMC1_D0,DCMI_D2,,EVENTOUT
-PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,UART5_CTS,,QUADSPI_BK1_IO0,,,SDMMC1_D1,DCMI_D3,,EVENTOUT
+PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S2_CKIN,,UART5_CTS,,QUADSPI_BK1_IO0,,,SDMMC1_D1,DCMI_D3,,EVENTOUT
PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,QUADSPI_BK1_IO1,,,SDMMC1_D2,DCMI_D8,LCD_R2,EVENTOUT
PortC,PC11,,,,,,,SPI3_MISO,USART3_RX,UART4_RX,QUADSPI_BK2_NCS,,,SDMMC1_D3,DCMI_D4,,EVENTOUT
PortC,PC12,TRACED3,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDMMC1_CK,DCMI_D9,,EVENTOUT
diff --git a/ports/stm32/modnwcc3k.c b/ports/stm32/modnwcc3k.c
index 551206da8..8cc0a613d 100644
--- a/ports/stm32/modnwcc3k.c
+++ b/ports/stm32/modnwcc3k.c
@@ -125,7 +125,7 @@ STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uin
if (ip == 0) {
// unknown host
- return MP_ENOENT;
+ return -2;
}
out_ip[0] = ip >> 24;
diff --git a/ports/stm32/modnwwiznet5k.c b/ports/stm32/modnwwiznet5k.c
index 21e4dbbbf..763137c70 100644
--- a/ports/stm32/modnwwiznet5k.c
+++ b/ports/stm32/modnwwiznet5k.c
@@ -30,6 +30,7 @@
#include "py/objlist.h"
#include "py/runtime.h"
+#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "lib/netutils/netutils.h"
@@ -92,7 +93,7 @@ STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len,
return 0;
} else {
// failure
- return MP_ENOENT;
+ return -2;
}
}
@@ -173,11 +174,7 @@ STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_
int sr = getSn_SR((uint8_t)socket->u_param.fileno);
if (sr == SOCK_ESTABLISHED) {
socket2->u_param = socket->u_param;
- // TODO need to populate this with the correct values
- ip[0] = 0;
- ip[1] = 0;
- ip[2] = 0;
- ip[3] = 0;
+ getSn_DIPR((uint8_t)socket2->u_param.fileno, ip);
*port = getSn_PORT(socket2->u_param.fileno);
// WIZnet turns the listening socket into the client socket, so we
@@ -309,9 +306,19 @@ STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_
}
STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) {
- // TODO
- *_errno = MP_EINVAL;
- return -1;
+ if (request == MP_STREAM_POLL) {
+ int ret = 0;
+ if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) {
+ ret |= MP_STREAM_POLL_RD;
+ }
+ if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) {
+ ret |= MP_STREAM_POLL_WR;
+ }
+ return ret;
+ } else {
+ *_errno = MP_EINVAL;
+ return MP_STREAM_ERROR;
+ }
}
#if 0
@@ -350,7 +357,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size
wiznet5k_obj.spi->Init.CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle
wiznet5k_obj.spi->Init.CLKPhase = SPI_PHASE_1EDGE; // data latched on first edge, which is rising edge for low-idle
wiznet5k_obj.spi->Init.NSS = SPI_NSS_SOFT;
- wiznet5k_obj.spi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz
+ wiznet5k_obj.spi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; // clock freq = f_PCLK / this_prescale_value; Wiz820i can do up to 80MHz
wiznet5k_obj.spi->Init.FirstBit = SPI_FIRSTBIT_MSB;
wiznet5k_obj.spi->Init.TIMode = SPI_TIMODE_DISABLED;
wiznet5k_obj.spi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
@@ -402,7 +409,12 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) {
if (i % 16 == 0) {
printf("\n %04x:", i);
}
- printf(" %02x", WIZCHIP_READ(i));
+ #if MICROPY_PY_WIZNET5K == 5200
+ uint32_t reg = i;
+ #else
+ uint32_t reg = _W5500_IO_BASE_ | i << 8;
+ #endif
+ printf(" %02x", WIZCHIP_READ(reg));
}
for (int sn = 0; sn < 4; ++sn) {
printf("\nWiz SREG[%d]:", sn);
@@ -410,7 +422,12 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) {
if (i % 16 == 0) {
printf("\n %04x:", i);
}
- printf(" %02x", WIZCHIP_READ(WIZCHIP_SREG_ADDR(sn, i)));
+ #if MICROPY_PY_WIZNET5K == 5200
+ uint32_t reg = WIZCHIP_SREG_ADDR(sn, i);
+ #else
+ uint32_t reg = _W5500_IO_BASE_ | i << 8 | WIZCHIP_SREG_BLOCK(sn) << 3;
+ #endif
+ printf(" %02x", WIZCHIP_READ(reg));
}
}
printf("\n");
@@ -418,6 +435,12 @@ STATIC mp_obj_t wiznet5k_regs(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_regs_obj, wiznet5k_regs);
+STATIC mp_obj_t wiznet5k_isconnected(mp_obj_t self_in) {
+ (void)self_in;
+ return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_isconnected_obj, wiznet5k_isconnected);
+
/// \method ifconfig([(ip, subnet, gateway, dns)])
/// Get/set IP address, subnet mask, gateway and DNS.
STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) {
@@ -449,6 +472,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k
STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&wiznet5k_regs_obj) },
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) },
+ { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wiznet5k_isconnected_obj) },
};
STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table);
diff --git a/ports/stm32/modpyb.c b/ports/stm32/modpyb.c
index 176fc8466..81cbdcc19 100644
--- a/ports/stm32/modpyb.c
+++ b/ports/stm32/modpyb.c
@@ -27,7 +27,7 @@
#include <stdint.h>
#include <stdio.h>
-#include "py/obj.h"
+#include "py/runtime.h"
#include "py/gc.h"
#include "py/builtin.h"
#include "py/mphal.h"
@@ -104,6 +104,28 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_micros_obj, pyb_elapsed_micros);
MP_DECLARE_CONST_FUN_OBJ_KW(pyb_main_obj); // defined in main.c
+// Get or set the UART object that the REPL is repeated on.
+// This is a legacy function, use of uos.dupterm is preferred.
+STATIC mp_obj_t pyb_repl_uart(size_t n_args, const mp_obj_t *args) {
+ if (n_args == 0) {
+ if (MP_STATE_PORT(pyb_stdio_uart) == NULL) {
+ return mp_const_none;
+ } else {
+ return MP_STATE_PORT(pyb_stdio_uart);
+ }
+ } else {
+ if (args[0] == mp_const_none) {
+ MP_STATE_PORT(pyb_stdio_uart) = NULL;
+ } else if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
+ MP_STATE_PORT(pyb_stdio_uart) = args[0];
+ } else {
+ mp_raise_ValueError("need a UART object");
+ }
+ return mp_const_none;
+ }
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart);
+
STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pyb) },
@@ -126,7 +148,7 @@ STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&machine_sleep_obj) },
{ MP_ROM_QSTR(MP_QSTR_standby), MP_ROM_PTR(&machine_deepsleep_obj) },
{ MP_ROM_QSTR(MP_QSTR_main), MP_ROM_PTR(&pyb_main_obj) },
- { MP_ROM_QSTR(MP_QSTR_repl_uart), MP_ROM_PTR(&mod_os_dupterm_obj) },
+ { MP_ROM_QSTR(MP_QSTR_repl_uart), MP_ROM_PTR(&pyb_repl_uart_obj) },
{ MP_ROM_QSTR(MP_QSTR_usb_mode), MP_ROM_PTR(&pyb_usb_mode_obj) },
{ MP_ROM_QSTR(MP_QSTR_hid_mouse), MP_ROM_PTR(&pyb_usb_hid_mouse_obj) },
diff --git a/ports/stm32/moduos.c b/ports/stm32/moduos.c
index f661b3b5e..f6e1483d3 100644
--- a/ports/stm32/moduos.c
+++ b/ports/stm32/moduos.c
@@ -33,6 +33,7 @@
#include "lib/timeutils/timeutils.h"
#include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h"
+#include "extmod/misc.h"
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
#include "genhdr/mpversion.h"
@@ -105,28 +106,6 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
#endif
-// Get or set the UART object that the REPL is repeated on.
-// TODO should accept any object with read/write methods.
-STATIC mp_obj_t os_dupterm(size_t n_args, const mp_obj_t *args) {
- if (n_args == 0) {
- if (MP_STATE_PORT(pyb_stdio_uart) == NULL) {
- return mp_const_none;
- } else {
- return MP_STATE_PORT(pyb_stdio_uart);
- }
- } else {
- if (args[0] == mp_const_none) {
- MP_STATE_PORT(pyb_stdio_uart) = NULL;
- } else if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
- MP_STATE_PORT(pyb_stdio_uart) = args[0];
- } else {
- mp_raise_ValueError("need a UART object");
- }
- return mp_const_none;
- }
-}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_dupterm_obj, 0, 1, os_dupterm);
-
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
@@ -154,7 +133,7 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
#endif
// these are MicroPython extensions
- { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mod_os_dupterm_obj) },
+ { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) },
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
diff --git a/ports/stm32/modusocket.c b/ports/stm32/modusocket.c
index c5ab3b6d7..71a237b0d 100644
--- a/ports/stm32/modusocket.c
+++ b/ports/stm32/modusocket.c
@@ -390,29 +390,48 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
size_t hlen;
const char *host = mp_obj_str_get_data(host_in, &hlen);
mp_int_t port = mp_obj_get_int(port_in);
+ uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE];
+ bool have_ip = false;
+
+ if (hlen > 0) {
+ // check if host is already in IP form
+ nlr_buf_t nlr;
+ if (nlr_push(&nlr) == 0) {
+ netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG);
+ have_ip = true;
+ nlr_pop();
+ } else {
+ // swallow exception: host was not in IP form so need to do DNS lookup
+ }
+ }
- // find a NIC that can do a name lookup
- for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
- mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
- mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
- if (nic_type->gethostbyname != NULL) {
- uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE];
- int ret = nic_type->gethostbyname(nic, host, hlen, out_ip);
- if (ret != 0) {
- // TODO CPython raises: socket.gaierror: [Errno -2] Name or service not known
- mp_raise_OSError(ret);
+ if (!have_ip) {
+ // find a NIC that can do a name lookup
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
+ mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
+ mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
+ if (nic_type->gethostbyname != NULL) {
+ int ret = nic_type->gethostbyname(nic, host, hlen, out_ip);
+ if (ret != 0) {
+ mp_raise_OSError(ret);
+ }
+ have_ip = true;
+ break;
}
- mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
- tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET);
- tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
- tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
- tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
- tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG);
- return mp_obj_new_list(1, (mp_obj_t*)&tuple);
}
}
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC"));
+ if (!have_ip) {
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC"));
+ }
+
+ mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
+ tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET);
+ tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
+ tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
+ tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
+ tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG);
+ return mp_obj_new_list(1, (mp_obj_t*)&tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index 7888b5355..51d442561 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -126,6 +126,7 @@
#define MICROPY_PY_USELECT (1)
#define MICROPY_PY_UTIMEQ (1)
#define MICROPY_PY_UTIME_MP_HAL (1)
+#define MICROPY_PY_OS_DUPTERM (1)
#define MICROPY_PY_MACHINE (1)
#define MICROPY_PY_MACHINE_PULSE (1)
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
@@ -326,6 +327,8 @@ static inline mp_uint_t disable_irq(void) {
__WFI(); \
} \
} while (0);
+
+#define MICROPY_THREAD_YIELD() pyb_thread_yield()
#else
#define MICROPY_EVENT_POLL_HOOK \
do { \
@@ -333,8 +336,13 @@ static inline mp_uint_t disable_irq(void) {
mp_handle_pending(); \
__WFI(); \
} while (0);
+
+#define MICROPY_THREAD_YIELD()
#endif
+// We need an implementation of the log2 function which is not a macro
+#define MP_NEED_LOG2 (1)
+
// There is no classical C heap in bare-metal ports, only Python
// garbage-collected heap. For completeness, emulate C heap via
// GC heap. Note that MicroPython core never uses malloc() and friends,
diff --git a/ports/stm32/mpconfigport.mk b/ports/stm32/mpconfigport.mk
index 64145383e..e708de6c1 100644
--- a/ports/stm32/mpconfigport.mk
+++ b/ports/stm32/mpconfigport.mk
@@ -1,6 +1,9 @@
# Enable/disable extra modules
-# wiznet5k module for ethernet support
+# wiznet5k module for ethernet support; valid values are:
+# 0 : no Wiznet support
+# 5200 : support for W5200 module
+# 5500 : support for W5500 module
MICROPY_PY_WIZNET5K ?= 0
# cc3k module for wifi support
diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c
index ab3dc227a..e9c4f28f7 100644
--- a/ports/stm32/mphalport.c
+++ b/ports/stm32/mphalport.c
@@ -3,6 +3,7 @@
#include "py/runtime.h"
#include "py/mperrno.h"
#include "py/mphal.h"
+#include "extmod/misc.h"
#include "usb.h"
#include "uart.h"
@@ -38,6 +39,10 @@ int mp_hal_stdin_rx_chr(void) {
} else if (MP_STATE_PORT(pyb_stdio_uart) != NULL && uart_rx_any(MP_STATE_PORT(pyb_stdio_uart))) {
return uart_rx_char(MP_STATE_PORT(pyb_stdio_uart));
}
+ int dupterm_c = mp_uos_dupterm_rx_chr();
+ if (dupterm_c >= 0) {
+ return dupterm_c;
+ }
MICROPY_EVENT_POLL_HOOK
}
}
@@ -56,15 +61,26 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
if (usb_vcp_is_enabled()) {
usb_vcp_send_strn(str, len);
}
+ mp_uos_dupterm_tx_strn(str, len);
}
+// Efficiently convert "\n" to "\r\n"
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
- // send stdout to UART and USB CDC VCP
- if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
- uart_tx_strn_cooked(MP_STATE_PORT(pyb_stdio_uart), str, len);
+ const char *last = str;
+ while (len--) {
+ if (*str == '\n') {
+ if (str > last) {
+ mp_hal_stdout_tx_strn(last, str - last);
+ }
+ mp_hal_stdout_tx_strn("\r\n", 2);
+ ++str;
+ last = str;
+ } else {
+ ++str;
+ }
}
- if (usb_vcp_is_enabled()) {
- usb_vcp_send_strn_cooked(str, len);
+ if (str > last) {
+ mp_hal_stdout_tx_strn(last, str - last);
}
}
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index a8913a055..8f0513e8c 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -454,26 +454,11 @@ STATIC size_t uart_tx_data(pyb_uart_obj_t *self, const void *src_in, size_t num_
return num_tx;
}
-STATIC void uart_tx_char(pyb_uart_obj_t *uart_obj, int c) {
- uint16_t ch = c;
- int errcode;
- uart_tx_data(uart_obj, &ch, 1, &errcode);
-}
-
void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
int errcode;
uart_tx_data(uart_obj, str, len, &errcode);
}
-void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
- for (const char *top = str + len; str < top; str++) {
- if (*str == '\n') {
- uart_tx_char(uart_obj, '\r');
- }
- uart_tx_char(uart_obj, *str);
- }
-}
-
// this IRQ handler is set up to handle RXNE interrupts only
void uart_irq_handler(mp_uint_t uart_id) {
// get the uart object
diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h
index e96b25b5f..d176520a1 100644
--- a/ports/stm32/uart.h
+++ b/ports/stm32/uart.h
@@ -48,6 +48,5 @@ void uart_irq_handler(mp_uint_t uart_id);
mp_uint_t uart_rx_any(pyb_uart_obj_t *uart_obj);
int uart_rx_char(pyb_uart_obj_t *uart_obj);
void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
-void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len);
#endif // MICROPY_INCLUDED_STMHAL_UART_H
diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c
index 906eb1989..5017bb930 100644
--- a/ports/stm32/usb.c
+++ b/ports/stm32/usb.c
@@ -178,20 +178,6 @@ void usb_vcp_send_strn(const char *str, int len) {
#endif
}
-void usb_vcp_send_strn_cooked(const char *str, int len) {
-#ifdef USE_DEVICE_MODE
- if (usb_device.enabled) {
- for (const char *top = str + len; str < top; str++) {
- if (*str == '\n') {
- usbd_cdc_tx_always(&usb_device.usbd_cdc_itf, (const uint8_t*)"\r\n", 2);
- } else {
- usbd_cdc_tx_always(&usb_device.usbd_cdc_itf, (const uint8_t*)str, 1);
- }
- }
- }
-#endif
-}
-
/******************************************************************************/
// MicroPython bindings for USB
diff --git a/ports/stm32/usb.h b/ports/stm32/usb.h
index f60ea8033..41c461fb2 100644
--- a/ports/stm32/usb.h
+++ b/ports/stm32/usb.h
@@ -63,7 +63,6 @@ void pyb_usb_dev_deinit(void);
bool usb_vcp_is_enabled(void);
int usb_vcp_recv_byte(uint8_t *c); // if a byte is available, return 1 and put the byte in *c, else return 0
void usb_vcp_send_strn(const char* str, int len);
-void usb_vcp_send_strn_cooked(const char *str, int len);
void pyb_usb_host_init(void);
void pyb_usb_host_process(void);
diff --git a/ports/stm32/usbd_cdc_interface.c b/ports/stm32/usbd_cdc_interface.c
index 4c49c9321..2e9fba917 100644
--- a/ports/stm32/usbd_cdc_interface.c
+++ b/ports/stm32/usbd_cdc_interface.c
@@ -57,10 +57,14 @@
#define CDC_SEND_BREAK 0x23
uint8_t *usbd_cdc_init(usbd_cdc_itf_t *cdc, usbd_cdc_msc_hid_state_t *usbd) {
+ // Link the parent state
cdc->usbd = usbd;
+
+ // Reset all the CDC state
+ // Note: we don't reset tx_buf_ptr_in in order to allow the output buffer to
+ // be filled (by usbd_cdc_tx_always) before the USB device is connected.
cdc->rx_buf_put = 0;
cdc->rx_buf_get = 0;
- cdc->tx_buf_ptr_in = 0;
cdc->tx_buf_ptr_out = 0;
cdc->tx_buf_ptr_out_shadow = 0;
cdc->tx_buf_ptr_wait_count = 0;
diff --git a/ports/stm32/usbd_cdc_interface.h b/ports/stm32/usbd_cdc_interface.h
index 6dcab7d47..98b8fc077 100644
--- a/ports/stm32/usbd_cdc_interface.h
+++ b/ports/stm32/usbd_cdc_interface.h
@@ -43,8 +43,8 @@ typedef struct _usbd_cdc_itf_t {
uint16_t rx_buf_get; // circular buffer index
uint8_t tx_buf[USBD_CDC_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer
- uint16_t tx_buf_ptr_in; // increment this pointer modulo APP_TX_DATA_SIZE when new data is available
- volatile uint16_t tx_buf_ptr_out; // increment this pointer modulo APP_TX_DATA_SIZE when data is drained
+ uint16_t tx_buf_ptr_in; // increment this pointer modulo USBD_CDC_TX_DATA_SIZE when new data is available
+ volatile uint16_t tx_buf_ptr_out; // increment this pointer modulo USBD_CDC_TX_DATA_SIZE when data is drained
uint16_t tx_buf_ptr_out_shadow; // shadow of above
uint8_t tx_buf_ptr_wait_count; // used to implement a timeout waiting for low-level USB driver
uint8_t tx_need_empty_packet; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size
diff --git a/ports/teensy/teensy_hal.c b/ports/teensy/teensy_hal.c
index 84d68cff8..7ce82f1d2 100644
--- a/ports/teensy/teensy_hal.c
+++ b/ports/teensy/teensy_hal.c
@@ -49,6 +49,7 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
// send stdout to UART and USB CDC VCP
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
+ void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len);
uart_tx_strn_cooked(MP_STATE_PORT(pyb_stdio_uart), str, len);
}
if (usb_vcp_is_enabled()) {
diff --git a/ports/teensy/uart.c b/ports/teensy/uart.c
index 3d5111217..a8cfd63ea 100644
--- a/ports/teensy/uart.c
+++ b/ports/teensy/uart.c
@@ -426,11 +426,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_send_obj, 1, pyb_uart_send);
///
/// Return value: if `recv` is an integer then a new buffer of the bytes received,
/// otherwise the same buffer that was passed in to `recv`.
+#if 0
STATIC const mp_arg_t pyb_uart_recv_args[] = {
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
};
#define PYB_UART_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_uart_recv_args)
+#endif
STATIC mp_obj_t pyb_uart_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
// TODO assumes transmission size is 8-bits wide
diff --git a/ports/unix/Makefile b/ports/unix/Makefile
index dbe3e592e..5bdcf4e1a 100644
--- a/ports/unix/Makefile
+++ b/ports/unix/Makefile
@@ -97,7 +97,7 @@ SRC_MOD += modtermios.c
endif
ifeq ($(MICROPY_PY_SOCKET),1)
CFLAGS_MOD += -DMICROPY_PY_SOCKET=1
-SRC_MOD += modsocket.c
+SRC_MOD += modusocket.c
endif
ifeq ($(MICROPY_PY_THREAD),1)
CFLAGS_MOD += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0
diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c
index 15b6d9cd7..f29c095cf 100644
--- a/ports/unix/modjni.c
+++ b/ports/unix/modjni.c
@@ -266,7 +266,7 @@ STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value)
return mp_const_none;
}
}
- mp_raise_NotImplementedError("");
+ mp_raise_NotImplementedError(NULL);
}
if (!JJ(IsInstanceOf, self->obj, List_class)) {
diff --git a/ports/unix/modsocket.c b/ports/unix/modusocket.c
index 7e82554c7..cfb6a9f5e 100644
--- a/ports/unix/modsocket.c
+++ b/ports/unix/modusocket.c
@@ -60,8 +60,6 @@
should be add to separate modules (C or Python level).
*/
-#define MICROPY_SOCKET_EXTRA (0)
-
// This type must "inherit" from mp_obj_fdfile_t, i.e. matching subset of
// fields should have the same layout.
typedef struct _mp_obj_socket_t {
@@ -382,26 +380,6 @@ const mp_obj_type_t mp_type_socket = {
.locals_dict = (mp_obj_dict_t*)&usocket_locals_dict,
};
-#if MICROPY_SOCKET_EXTRA
-STATIC mp_obj_t mod_socket_htons(mp_obj_t arg) {
- return MP_OBJ_NEW_SMALL_INT(htons(MP_OBJ_SMALL_INT_VALUE(arg)));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_socket_htons_obj, mod_socket_htons);
-
-
-STATIC mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) {
- const char *s = mp_obj_str_get_str(arg);
- struct hostent *h = gethostbyname(s);
- if (h == NULL) {
- // CPython: socket.herror
- mp_raise_OSError(h_errno);
- }
- assert(h->h_length == 4);
- return mp_obj_new_int(*(int*)*h->h_addr_list);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_socket_gethostbyname_obj, mod_socket_gethostbyname);
-#endif // MICROPY_SOCKET_EXTRA
-
#define BINADDR_MAX_LEN sizeof(struct in6_addr)
STATIC mp_obj_t mod_socket_inet_pton(mp_obj_t family_in, mp_obj_t addr_in) {
int family = mp_obj_get_int(family_in);
@@ -549,10 +527,6 @@ STATIC const mp_rom_map_elem_t mp_module_socket_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_inet_pton), MP_ROM_PTR(&mod_socket_inet_pton_obj) },
{ MP_ROM_QSTR(MP_QSTR_inet_ntop), MP_ROM_PTR(&mod_socket_inet_ntop_obj) },
{ MP_ROM_QSTR(MP_QSTR_sockaddr), MP_ROM_PTR(&mod_socket_sockaddr_obj) },
-#if MICROPY_SOCKET_EXTRA
- { MP_ROM_QSTR(MP_QSTR_htons), MP_ROM_PTR(&mod_socket_htons_obj) },
- { MP_ROM_QSTR(MP_QSTR_gethostbyname), MP_ROM_PTR(&mod_socket_gethostbyname_obj) },
-#endif
#define C(name) { MP_ROM_QSTR(MP_QSTR_ ## name), MP_ROM_INT(name) }
C(AF_UNIX),
diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h
index 50b979279..db382e0a7 100644
--- a/ports/unix/mpconfigport.h
+++ b/ports/unix/mpconfigport.h
@@ -85,6 +85,7 @@
#define MICROPY_PY_BUILTINS_POW3 (1)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
+#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
#define MICROPY_PY_SYS_EXIT (1)
diff --git a/ports/unix/unix_mphal.c b/ports/unix/unix_mphal.c
index 2b273d834..f27c62fd1 100644
--- a/ports/unix/unix_mphal.c
+++ b/ports/unix/unix_mphal.c
@@ -108,11 +108,11 @@ void mp_hal_stdio_mode_orig(void) {
#endif
#if MICROPY_PY_OS_DUPTERM
-static int call_dupterm_read(void) {
+static int call_dupterm_read(size_t idx) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_obj_t read_m[3];
- mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_read, read_m);
+ mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_read, read_m);
read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
if (res == mp_const_none) {
@@ -122,18 +122,18 @@ static int call_dupterm_read(void) {
mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
if (bufinfo.len == 0) {
mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n");
- MP_STATE_PORT(term_obj) = NULL;
+ MP_STATE_VM(dupterm_objs[idx]) = MP_OBJ_NULL;
return -1;
}
nlr_pop();
return *(byte*)bufinfo.buf;
} else {
// Temporarily disable dupterm to avoid infinite recursion
- mp_obj_t save_term = MP_STATE_PORT(term_obj);
- MP_STATE_PORT(term_obj) = NULL;
+ mp_obj_t save_term = MP_STATE_VM(dupterm_objs[idx]);
+ MP_STATE_VM(dupterm_objs[idx]) = NULL;
mp_printf(&mp_plat_print, "dupterm: ");
mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
- MP_STATE_PORT(term_obj) = save_term;
+ MP_STATE_VM(dupterm_objs[idx]) = save_term;
}
return -1;
@@ -143,10 +143,11 @@ static int call_dupterm_read(void) {
int mp_hal_stdin_rx_chr(void) {
unsigned char c;
#if MICROPY_PY_OS_DUPTERM
- if (MP_STATE_PORT(term_obj) != MP_OBJ_NULL) {
+ // TODO only support dupterm one slot at the moment
+ if (MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL) {
int c;
do {
- c = call_dupterm_read();
+ c = call_dupterm_read(0);
} while (c == -2);
if (c == -1) {
goto main_term;
diff --git a/ports/zephyr/main.c b/ports/zephyr/main.c
index 7255d981f..7eb9da3e1 100644
--- a/ports/zephyr/main.c
+++ b/ports/zephyr/main.c
@@ -60,7 +60,9 @@ static char *stack_top;
static char heap[MICROPY_HEAP_SIZE];
void init_zephyr(void) {
- // TODO: Make addresses configurable
+ // We now rely on CONFIG_NET_APP_SETTINGS to set up bootstrap
+ // network addresses.
+#if 0
#ifdef CONFIG_NETWORKING
if (net_if_get_default() == NULL) {
// If there's no default networking interface,
@@ -81,6 +83,7 @@ void init_zephyr(void) {
static struct in6_addr in6addr_my = {{{0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};
net_if_ipv6_addr_add(net_if_get_default(), &in6addr_my, NET_ADDR_MANUAL, 0);
#endif
+#endif
}
int real_main(void) {
diff --git a/ports/zephyr/prj_base.conf b/ports/zephyr/prj_base.conf
index c3ba2812f..fbcedf260 100644
--- a/ports/zephyr/prj_base.conf
+++ b/ports/zephyr/prj_base.conf
@@ -4,6 +4,12 @@ CONFIG_REBOOT=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_CONSOLE_HANDLER=y
CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS=y
+
+CONFIG_CONSOLE_PULL=y
+CONFIG_CONSOLE_GETCHAR=y
+CONFIG_CONSOLE_GETCHAR_BUFSIZE=128
+CONFIG_CONSOLE_PUTCHAR_BUFSIZE=128
+
CONFIG_NEWLIB_LIBC=y
CONFIG_FLOAT=y
CONFIG_MAIN_STACK_SIZE=4096
@@ -18,6 +24,14 @@ CONFIG_NET_SOCKETS=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NET_NBUF_RX_COUNT=5
+CONFIG_NET_APP_SETTINGS=y
+CONFIG_NET_APP_INIT_TIMEOUT=3
+CONFIG_NET_APP_NEED_IPV6=y
+CONFIG_NET_APP_NEED_IPV4=y
+CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
+CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
+CONFIG_NET_APP_MY_IPV4_GW="192.0.2.2"
+
# DNS
CONFIG_DNS_RESOLVER=y
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2
diff --git a/ports/zephyr/prj_qemu_cortex_m3.conf b/ports/zephyr/prj_qemu_cortex_m3.conf
index 09614c362..1ade981e2 100644
--- a/ports/zephyr/prj_qemu_cortex_m3.conf
+++ b/ports/zephyr/prj_qemu_cortex_m3.conf
@@ -1,3 +1,7 @@
+# Interrupt-driven UART console has emulation artifacts under QEMU,
+# disable it
+CONFIG_CONSOLE_PULL=n
+
# Networking drivers
# SLIP driver for QEMU
CONFIG_NET_SLIP_TAP=y
diff --git a/ports/zephyr/prj_qemu_x86.conf b/ports/zephyr/prj_qemu_x86.conf
index ef60cfec9..9bc81259a 100644
--- a/ports/zephyr/prj_qemu_x86.conf
+++ b/ports/zephyr/prj_qemu_x86.conf
@@ -1,3 +1,7 @@
+# Interrupt-driven UART console has emulation artifacts under QEMU,
+# disable it
+CONFIG_CONSOLE_PULL=n
+
# Networking drivers
# SLIP driver for QEMU
CONFIG_NET_SLIP_TAP=y
diff --git a/ports/zephyr/src/zephyr_start.c b/ports/zephyr/src/zephyr_start.c
index 9e8a90beb..452e304ca 100644
--- a/ports/zephyr/src/zephyr_start.c
+++ b/ports/zephyr/src/zephyr_start.c
@@ -24,11 +24,16 @@
* THE SOFTWARE.
*/
#include <zephyr.h>
+#include <console.h>
#include "zephyr_getchar.h"
int real_main(void);
void main(void) {
+#ifdef CONFIG_CONSOLE_PULL
+ console_init();
+#else
zephyr_getchar_init();
+#endif
real_main();
}
diff --git a/ports/zephyr/uart_core.c b/ports/zephyr/uart_core.c
index 1e85053cd..e41fb9acc 100644
--- a/ports/zephyr/uart_core.c
+++ b/ports/zephyr/uart_core.c
@@ -28,6 +28,7 @@
#include "src/zephyr_getchar.h"
// Zephyr headers
#include <uart.h>
+#include <console.h>
/*
* Core UART functions to implement for a port
@@ -35,11 +36,23 @@
// Receive single character
int mp_hal_stdin_rx_chr(void) {
+#ifdef CONFIG_CONSOLE_PULL
+ return console_getchar();
+#else
return zephyr_getchar();
+#endif
}
// Send string of given length
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
+#ifdef CONFIG_CONSOLE_PULL
+ while (len--) {
+ char c = *str++;
+ while (console_putchar(c) == -1) {
+ k_sleep(1);
+ }
+ }
+#else
static struct device *uart_console_dev;
if (uart_console_dev == NULL) {
uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);
@@ -48,4 +61,5 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
while (len--) {
uart_poll_out(uart_console_dev, *str++);
}
+#endif
}