diff options
Diffstat (limited to 'ports/stm32')
| -rw-r--r-- | ports/stm32/Makefile | 6 | ||||
| -rw-r--r-- | ports/stm32/boards/stm32f767_af.csv | 8 | ||||
| -rw-r--r-- | ports/stm32/modnwcc3k.c | 2 | ||||
| -rw-r--r-- | ports/stm32/modnwwiznet5k.c | 48 | ||||
| -rw-r--r-- | ports/stm32/modpyb.c | 26 | ||||
| -rw-r--r-- | ports/stm32/moduos.c | 25 | ||||
| -rw-r--r-- | ports/stm32/modusocket.c | 55 | ||||
| -rw-r--r-- | ports/stm32/mpconfigport.h | 8 | ||||
| -rw-r--r-- | ports/stm32/mpconfigport.mk | 5 | ||||
| -rw-r--r-- | ports/stm32/mphalport.c | 26 | ||||
| -rw-r--r-- | ports/stm32/uart.c | 15 | ||||
| -rw-r--r-- | ports/stm32/uart.h | 1 | ||||
| -rw-r--r-- | ports/stm32/usb.c | 14 | ||||
| -rw-r--r-- | ports/stm32/usb.h | 1 | ||||
| -rw-r--r-- | ports/stm32/usbd_cdc_interface.c | 6 | ||||
| -rw-r--r-- | ports/stm32/usbd_cdc_interface.h | 4 |
16 files changed, 147 insertions, 103 deletions
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 |
