summaryrefslogtreecommitdiff
path: root/stmhal
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2017-06-20 10:56:05 -0700
committerScott Shawcroft <scott.shawcroft@gmail.com>2017-06-20 10:56:05 -0700
commit30ee7019ca651bce1fe966c1089fe977d51dc92b (patch)
tree0114b6f744dd175b7722dd8edcbe24f4ee84bb45 /stmhal
parent97fcdfbd08c922efd7470d6482d7c7c703ffc0ae (diff)
parent869cdcfdfc860b1177baf9b0f8818915ba54f3f5 (diff)
Merge tag 'v1.9.1'2.0.0-alpha.0
Fixes for stmhal USB mass storage, lwIP bindings and VFS regressions This release provides an important fix for the USB mass storage device in the stmhal port by implementing the SCSI SYNCHRONIZE_CACHE command, which is now require by some Operating Systems. There are also fixes for the lwIP bindings to improve non-blocking sockets and error codes. The VFS has some regressions fixed including the ability to statvfs the root. All changes are listed below. py core: - modbuiltins: add core-provided version of input() function - objstr: catch case of negative "maxsplit" arg to str.rsplit() - persistentcode: allow to compile with complex numbers disabled - objstr: allow to compile with obj-repr D, and unicode disabled - modsys: allow to compile with obj-repr D and PY_ATTRTUPLE disabled - provide mp_decode_uint_skip() to help reduce stack usage - makeqstrdefs.py: make script run correctly with Python 2.6 - objstringio: if created from immutable object, follow copy on write policy extmod: - modlwip: connect: for non-blocking mode, return EINPROGRESS - modlwip: fix error codes for duplicate calls to connect() - modlwip: accept: fix error code for non-blocking mode - vfs: allow to statvfs the root directory - vfs: allow "buffering" and "encoding" args to VFS's open() - modframebuf: fix signed/unsigned comparison pendantic warning lib: - libm: use isfinite instead of finitef, for C99 compatibility - utils/interrupt_char: remove support for KBD_EXCEPTION disabled tests: - basics/string_rsplit: add tests for negative "maxsplit" argument - float: convert "sys.exit()" to "raise SystemExit" - float/builtin_float_minmax: PEP8 fixes - basics: convert "sys.exit()" to "raise SystemExit" - convert remaining "sys.exit()" to "raise SystemExit" unix port: - convert to use core-provided version of built-in import() - Makefile: replace references to make with $(MAKE) windows port: - convert to use core-provided version of built-in import() qemu-arm port: - Makefile: adjust object-file lists to get correct dependencies - enable micropython.mem_*() functions to allow more tests stmhal port: - boards: enable DAC for NUCLEO_F767ZI board - add support for NUCLEO_F446RE board - pass USB handler as parameter to allow more than one USB handler - usb: use local USB handler variable in Start-of-Frame handler - usb: make state for USB device private to top-level USB driver - usbdev: for MSC implement SCSI SYNCHRONIZE_CACHE command - convert from using stmhal's input() to core provided version cc3200 port: - convert from using stmhal's input() to core provided version teensy port: - convert from using stmhal's input() to core provided version esp8266 port: - Makefile: replace references to make with $(MAKE) - Makefile: add clean-modules target - convert from using stmhal's input() to core provided version zephyr port: - modusocket: getaddrinfo: Fix mp_obj_len() usage - define MICROPY_PY_SYS_PLATFORM (to "zephyr") - machine_pin: use native Zephyr types for Zephyr API calls docs: - machine.Pin: remove out_value() method - machine.Pin: add on() and off() methods - esp8266: consistently replace Pin.high/low methods with .on/off - esp8266/quickref: polish Pin.on()/off() examples - network: move confusingly-named cc3200 Server class to its reference - uos: deconditionalize, remove minor port-specific details - uos: move cc3200 port legacy VFS mounting functions to its ref doc - machine: sort machine classes in logical order, not alphabetically - network: first step to describe standard network class interface examples: - embedding: use core-provided KeyboardInterrupt object
Diffstat (limited to 'stmhal')
-rw-r--r--stmhal/Makefile34
-rw-r--r--stmhal/README.md9
-rw-r--r--stmhal/accel.c24
-rw-r--r--stmhal/adc.c24
-rw-r--r--stmhal/boards/LIMIFROG/mpconfigboard.h7
-rw-r--r--stmhal/boards/NUCLEO_F446RE/mpconfigboard.h64
-rw-r--r--stmhal/boards/NUCLEO_F446RE/mpconfigboard.mk4
-rw-r--r--stmhal/boards/NUCLEO_F446RE/pins.csv72
-rw-r--r--stmhal/boards/NUCLEO_F446RE/stm32f4xx_hal_conf.h413
-rw-r--r--stmhal/boards/NUCLEO_F767ZI/mpconfigboard.h7
-rw-r--r--stmhal/boards/NUCLEO_F767ZI/pins.csv50
-rw-r--r--stmhal/boards/NUCLEO_F767ZI/stm32f7xx_hal_conf.h2
-rw-r--r--stmhal/boards/NUCLEO_L476RG/mpconfigboard.h4
-rw-r--r--stmhal/boards/STM32F411DISC/mpconfigboard.h2
-rw-r--r--stmhal/boards/STM32F769DISC/mpconfigboard.h16
-rw-r--r--stmhal/boards/STM32F769DISC/mpconfigboard.mk2
-rw-r--r--stmhal/boards/STM32F769DISC/pins.csv12
-rw-r--r--stmhal/boards/STM32F7DISC/mpconfigboard.h10
-rw-r--r--stmhal/boards/STM32L476DISC/board_init.c10
-rw-r--r--stmhal/boards/STM32L476DISC/mpconfigboard.h17
-rwxr-xr-xstmhal/boards/make-pins.py8
-rw-r--r--stmhal/boards/openocd_stm32f4.cfg2
-rw-r--r--stmhal/boards/openocd_stm32f7.cfg2
-rw-r--r--stmhal/boards/openocd_stm32l4.cfg2
-rw-r--r--stmhal/boards/stm32f411.ld8
-rw-r--r--stmhal/boards/stm32f429.ld8
-rw-r--r--stmhal/boards/stm32f767_af.csv33
-rw-r--r--stmhal/boards/stm32f769_af.csv171
-rw-r--r--stmhal/can.c42
-rw-r--r--stmhal/dac.c20
-rw-r--r--stmhal/dma.c8
-rw-r--r--stmhal/dma.h2
-rw-r--r--stmhal/extint.c29
-rw-r--r--stmhal/fatfs_port.c15
-rw-r--r--stmhal/gccollect.c15
-rw-r--r--stmhal/hal/f7/src/stm32f7xx_hal_dma.c4
-rw-r--r--stmhal/help.c21
-rw-r--r--stmhal/i2c.c79
-rw-r--r--stmhal/import.c36
-rw-r--r--stmhal/irq.h4
-rw-r--r--stmhal/lcd.c32
-rw-r--r--stmhal/led.c14
-rw-r--r--stmhal/main.c289
-rw-r--r--stmhal/make-stmconst.py6
-rw-r--r--stmhal/memory.h2
-rw-r--r--stmhal/modmachine.c114
-rw-r--r--stmhal/modnetwork.c10
-rw-r--r--stmhal/modnwcc3k.c31
-rw-r--r--stmhal/modnwwiznet5k.c18
-rw-r--r--stmhal/modpyb.c150
-rw-r--r--stmhal/modstm.c10
l---------stmhal/modules/lcd160cr.py1
l---------stmhal/modules/lcd160cr_test.py1
-rw-r--r--stmhal/moduos.c310
-rw-r--r--stmhal/modusocket.c66
-rw-r--r--stmhal/modutime.c4
-rw-r--r--stmhal/mpconfigport.h131
-rw-r--r--stmhal/mphalport.c14
-rw-r--r--stmhal/mphalport.h12
-rw-r--r--stmhal/mpthreadport.c94
-rw-r--r--stmhal/mpthreadport.h (renamed from stmhal/builtin_open.c)35
-rw-r--r--stmhal/pendsv.c64
-rw-r--r--stmhal/pendsv.h2
-rw-r--r--stmhal/pin.c117
-rw-r--r--stmhal/pin_defs_stmhal.h12
-rw-r--r--stmhal/pybstdio.c28
-rw-r--r--stmhal/pybthread.c237
-rw-r--r--stmhal/pybthread.h78
-rw-r--r--stmhal/rtc.c14
-rw-r--r--stmhal/sdcard.c102
-rw-r--r--stmhal/sdcard.h2
-rw-r--r--stmhal/servo.c12
-rw-r--r--stmhal/spi.c56
-rw-r--r--stmhal/startup_stm32.S24
-rw-r--r--stmhal/stm32_it.c67
-rw-r--r--stmhal/stm32_it.h2
-rw-r--r--stmhal/storage.c118
-rw-r--r--stmhal/systick.c45
-rw-r--r--stmhal/systick.h2
-rw-r--r--stmhal/timer.c79
-rw-r--r--stmhal/uart.c34
-rw-r--r--stmhal/usb.c69
-rw-r--r--stmhal/usb.h2
-rw-r--r--stmhal/usbd_cdc_interface.c121
-rw-r--r--stmhal/usbd_cdc_interface.h1
-rw-r--r--stmhal/usbd_hid_interface.c43
-rw-r--r--stmhal/usbd_hid_interface.h3
-rw-r--r--stmhal/usbd_msc_storage.c7
-rw-r--r--stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h9
-rw-r--r--stmhal/usbdev/class/inc/usbd_msc_scsi.h2
-rw-r--r--stmhal/usbdev/class/src/usbd_cdc_msc_hid.c26
-rw-r--r--stmhal/usbdev/class/src/usbd_msc_scsi.c12
-rw-r--r--stmhal/usrsw.c6
-rw-r--r--stmhal/wdt.c6
94 files changed, 2520 insertions, 1518 deletions
diff --git a/stmhal/Makefile b/stmhal/Makefile
index 30ec40f3a..7f9e17133 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -15,6 +15,9 @@ include boards/$(BOARD)/mpconfigboard.mk
# qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h $(BUILD)/modstm_qstr.h
+# directory containing scripts to be frozen as bytecode
+FROZEN_MPY_DIR ?= modules
+
# include py core make definitions
include ../py/py.mk
@@ -23,7 +26,7 @@ CMSIS_DIR=cmsis
HAL_DIR=hal/$(MCU_SERIES)
USBDEV_DIR=usbdev
#USBHOST_DIR=usbhost
-FATFS_DIR=lib/fatfs
+FATFS_DIR=lib/oofatfs
DFU=../tools/dfu.py
# may need to prefix dfu-util with sudo
USE_PYDFU ?= 1
@@ -44,16 +47,13 @@ INC += -I$(CMSIS_DIR)/
INC += -I$(HAL_DIR)/inc
INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/inc
#INC += -I$(USBHOST_DIR)
-INC += -I../lib/mp-readline
-INC += -I../lib/netutils
-INC += -I../lib/timeutils
-CFLAGS_CORTEX_M = -mthumb -mabi=aapcs-linux -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
+CFLAGS_CORTEX_M = -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
CFLAGS_MCU_f4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 -DMCU_SERIES_F4
CFLAGS_MCU_f7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7 -DMCU_SERIES_F7
CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 -DMCU_SERIES_L4
-CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_MOD)
+CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib $(CFLAGS_MOD)
CFLAGS += -D$(CMSIS_MCU)
CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES))
CFLAGS += $(COPT)
@@ -61,7 +61,7 @@ CFLAGS += -Iboards/$(BOARD)
CFLAGS += -DSTM32_HAL_H='<stm32$(MCU_SERIES)xx_hal.h>'
LDFLAGS = -nostdlib -L $(LD_DIR) -T $(LD_FILE) -Map=$(@:.elf=.map) --cref
-LIBS =
+LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
# Remove uncalled code from the final image.
CFLAGS += -fdata-sections -ffunction-sections
@@ -75,9 +75,6 @@ else
COPT += -Os -DNDEBUG
endif
-# uncomment this if you want libgcc
-#LIBS += $(shell $(CC) -print-libgcc-file-name)
-
SRC_LIB = $(addprefix lib/,\
libc/string0.c \
libm/math.c \
@@ -86,7 +83,7 @@ SRC_LIB = $(addprefix lib/,\
libm/atanf.c \
libm/atan2f.c \
libm/fmodf.c \
- libm/roundf.c \
+ libm/nearbyintf.c \
libm/log1pf.c \
libm/acoshf.c \
libm/asinhf.c \
@@ -106,14 +103,18 @@ SRC_LIB = $(addprefix lib/,\
libm/sf_erf.c \
libm/wf_lgamma.c \
libm/wf_tgamma.c \
- fatfs/ff.c \
- fatfs/option/ccsbcs.c \
+ oofatfs/ff.c \
+ oofatfs/option/unicode.c \
mp-readline/builtin_input.c \
mp-readline/readline.c \
netutils/netutils.c \
timeutils/timeutils.c \
utils/pyexec.c \
- utils/pyhelp.c \
+ utils/interrupt_char.c \
+ )
+
+DRIVERS_SRC_C = $(addprefix drivers/,\
+ memory/spiflash.c \
)
SRC_C = \
@@ -126,9 +127,11 @@ SRC_C = \
usbd_hid_interface.c \
usbd_msc_storage.c \
mphalport.c \
+ mpthreadport.c \
irq.c \
pendsv.c \
systick.c \
+ pybthread.c \
timer.c \
led.c \
pin.c \
@@ -153,14 +156,12 @@ SRC_C = \
modutime.c \
modusocket.c \
modnetwork.c \
- import.c \
extint.c \
usrsw.c \
rng.c \
rtc.c \
flash.c \
storage.c \
- builtin_open.c \
sdcard.c \
fatfs_port.c \
lcd.c \
@@ -254,6 +255,7 @@ endif
OBJ =
OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
+OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_O))
OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o))
diff --git a/stmhal/README.md b/stmhal/README.md
index 6ebee3525..32b6d4176 100644
--- a/stmhal/README.md
+++ b/stmhal/README.md
@@ -17,6 +17,15 @@ to build each individual board.
Build instructions
------------------
+Before building the firmware for a given board the MicroPython cross-compiler
+must be built; it will be used to pre-compile some of the built-in scripts to
+bytecode. The cross-compiler is built and run on the host machine, using:
+```bash
+$ make -C mpy-cross
+```
+This command should be executed from the root directory of this repository.
+All other commands below should be executed from the stmhal/ directory.
+
An ARM compiler is required for the build, along with the associated binary
utilities. The default compiler is `arm-none-eabi-gcc`, which is available for
Arch Linux via the package `arm-none-eabi-gcc`, for Ubuntu via instructions
diff --git a/stmhal/accel.c b/stmhal/accel.c
index 827e9177a..d0d4148ab 100644
--- a/stmhal/accel.c
+++ b/stmhal/accel.c
@@ -76,9 +76,9 @@ STATIC void accel_start(void) {
// turn off AVDD, wait 30ms, turn on AVDD, wait 30ms again
mp_hal_pin_low(&MICROPY_HW_MMA_AVDD_PIN); // turn off
- HAL_Delay(30);
+ mp_hal_delay_ms(30);
mp_hal_pin_high(&MICROPY_HW_MMA_AVDD_PIN); // turn on
- HAL_Delay(30);
+ mp_hal_delay_ms(30);
HAL_StatusTypeDef status;
@@ -98,7 +98,7 @@ STATIC void accel_start(void) {
status = HAL_I2C_Mem_Write(&I2CHandle1, MMA_ADDR, MMA_REG_MODE, I2C_MEMADD_SIZE_8BIT, data, 1, 200);
// wait for MMA to become active
- HAL_Delay(30);
+ mp_hal_delay_ms(30);
}
/******************************************************************************/
@@ -211,15 +211,15 @@ STATIC mp_obj_t pyb_accel_write(mp_obj_t self_in, mp_obj_t reg, mp_obj_t val) {
}
MP_DEFINE_CONST_FUN_OBJ_3(pyb_accel_write_obj, pyb_accel_write);
-STATIC const mp_map_elem_t pyb_accel_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_accel_locals_dict_table[] = {
// TODO add init, deinit, and perhaps reset methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_x), (mp_obj_t)&pyb_accel_x_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_y), (mp_obj_t)&pyb_accel_y_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_z), (mp_obj_t)&pyb_accel_z_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_tilt), (mp_obj_t)&pyb_accel_tilt_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_filtered_xyz), (mp_obj_t)&pyb_accel_filtered_xyz_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&pyb_accel_read_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&pyb_accel_write_obj },
+ { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&pyb_accel_x_obj) },
+ { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&pyb_accel_y_obj) },
+ { MP_ROM_QSTR(MP_QSTR_z), MP_ROM_PTR(&pyb_accel_z_obj) },
+ { MP_ROM_QSTR(MP_QSTR_tilt), MP_ROM_PTR(&pyb_accel_tilt_obj) },
+ { MP_ROM_QSTR(MP_QSTR_filtered_xyz), MP_ROM_PTR(&pyb_accel_filtered_xyz_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&pyb_accel_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_accel_write_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_accel_locals_dict, pyb_accel_locals_dict_table);
@@ -228,7 +228,7 @@ const mp_obj_type_t pyb_accel_type = {
{ &mp_type_type },
.name = MP_QSTR_Accel,
.make_new = pyb_accel_make_new,
- .locals_dict = (mp_obj_t)&pyb_accel_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_accel_locals_dict,
};
#endif // MICROPY_HW_HAS_MMA7660
diff --git a/stmhal/adc.c b/stmhal/adc.c
index 11259546b..6485e2ab7 100644
--- a/stmhal/adc.c
+++ b/stmhal/adc.c
@@ -93,7 +93,7 @@
#elif defined(STM32F427xx) || defined(STM32F429xx) || \
defined(STM32F437xx) || defined(STM32F439xx) || \
defined(STM32F746xx) || defined(STM32F767xx) || \
- defined(STM32F769xx)
+ defined(STM32F769xx) || defined(STM32F446xx)
#define VBAT_DIV (4)
#elif defined(STM32L476xx)
#define VBAT_DIV (3)
@@ -439,9 +439,9 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(adc_read_timed_obj, adc_read_timed);
-STATIC const mp_map_elem_t adc_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_timed), (mp_obj_t)&adc_read_timed_obj},
+STATIC const mp_rom_map_elem_t adc_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&adc_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read_timed), MP_ROM_PTR(&adc_read_timed_obj) },
};
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
@@ -451,7 +451,7 @@ const mp_obj_type_t pyb_adc_type = {
.name = MP_QSTR_ADC,
.print = adc_print,
.make_new = adc_make_new,
- .locals_dict = (mp_obj_t)&adc_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&adc_locals_dict,
};
/******************************************************************************/
@@ -658,13 +658,13 @@ STATIC mp_obj_t adc_all_read_vref(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_vref_obj, adc_all_read_vref);
#endif
-STATIC const mp_map_elem_t adc_all_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_channel), (mp_obj_t)&adc_all_read_channel_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_temp), (mp_obj_t)&adc_all_read_core_temp_obj},
+STATIC const mp_rom_map_elem_t adc_all_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_read_channel), MP_ROM_PTR(&adc_all_read_channel_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read_core_temp), MP_ROM_PTR(&adc_all_read_core_temp_obj) },
#if MICROPY_PY_BUILTINS_FLOAT
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vbat), (mp_obj_t)&adc_all_read_core_vbat_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vref), (mp_obj_t)&adc_all_read_core_vref_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_vref), (mp_obj_t)&adc_all_read_vref_obj},
+ { MP_ROM_QSTR(MP_QSTR_read_core_vbat), MP_ROM_PTR(&adc_all_read_core_vbat_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read_core_vref), MP_ROM_PTR(&adc_all_read_core_vref_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read_vref), MP_ROM_PTR(&adc_all_read_vref_obj) },
#endif
};
@@ -674,5 +674,5 @@ const mp_obj_type_t pyb_adc_all_type = {
{ &mp_type_type },
.name = MP_QSTR_ADCAll,
.make_new = adc_all_make_new,
- .locals_dict = (mp_obj_t)&adc_all_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&adc_all_locals_dict,
};
diff --git a/stmhal/boards/LIMIFROG/mpconfigboard.h b/stmhal/boards/LIMIFROG/mpconfigboard.h
index 95fd6bf50..d04634ac3 100644
--- a/stmhal/boards/LIMIFROG/mpconfigboard.h
+++ b/stmhal/boards/LIMIFROG/mpconfigboard.h
@@ -37,13 +37,6 @@ void LIMIFROG_board_early_init(void);
#define MICROPY_HW_I2C1_SDA (pin_B9)
#define MICROPY_HW_I2C2_SCL (pin_B10)
#define MICROPY_HW_I2C2_SDA (pin_B11)
-// We use an array of baudrates and corresponding TIMINGR values.
-//
-// The value 0x90112626 was obtained from the DISCOVERY_I2C1_TIMING constant
-// defined in the STM32L4Cube file Drivers/BSP/STM32L476G-Discovery/stm32l476g_discovery.h
-#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x90112626}}
-#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 100000
-#define MICROPY_HW_I2C_BAUDRATE_MAX 100000
// SPI busses
#define MICROPY_HW_SPI1_NSS (pin_A4)
diff --git a/stmhal/boards/NUCLEO_F446RE/mpconfigboard.h b/stmhal/boards/NUCLEO_F446RE/mpconfigboard.h
new file mode 100644
index 000000000..d801fa188
--- /dev/null
+++ b/stmhal/boards/NUCLEO_F446RE/mpconfigboard.h
@@ -0,0 +1,64 @@
+#define MICROPY_HW_BOARD_NAME "NUCLEO-F446RE"
+#define MICROPY_HW_MCU_NAME "STM32F446xx"
+
+#define MICROPY_HW_HAS_SWITCH (1)
+#define MICROPY_HW_HAS_FLASH (1)
+#define MICROPY_HW_ENABLE_RTC (1)
+
+// HSE is 8MHz, CPU freq set to 168MHz. Using PLLQ for USB this gives a nice
+// 48 MHz clock for USB. To goto 180 MHz, I think that USB would need to be
+// configured to use PLLSAI
+#define MICROPY_HW_CLK_PLLM (8)
+#define MICROPY_HW_CLK_PLLN (336)
+#define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2)
+#define MICROPY_HW_CLK_PLLQ (7)
+
+// UART config
+#define MICROPY_HW_UART2_TX (pin_A2)
+#define MICROPY_HW_UART2_RX (pin_A3)
+#define MICROPY_HW_UART6_TX (pin_C6)
+#define MICROPY_HW_UART6_RX (pin_C7)
+// UART 2 connects to the STM32F103 (STLINK) on the Nucleo board
+// and this is exposed as a USB Serial port.
+#define MICROPY_HW_UART_REPL PYB_UART_2
+#define MICROPY_HW_UART_REPL_BAUD 115200
+
+// I2C busses
+#define MICROPY_HW_I2C1_SCL (pin_B6) // Arduino D10, pin 17 on CN10
+#define MICROPY_HW_I2C1_SDA (pin_B7) // pin 21 on CN7
+#define MICROPY_HW_I2C2_SCL (pin_B10) // Arduino D6, pin 25 on CN10
+#define MICROPY_HW_I2C2_SDA (pin_B3) // Arduino D3, pin 31 on CN10
+#define MICROPY_HW_I2C3_SCL (pin_A8) // Arduino D7, pin 23 on CN10
+#define MICROPY_HW_I2C3_SDA (pin_C9) // pin 1 on CN10
+
+// SPI busses
+#define MICROPY_HW_SPI1_NSS (pin_A15) // pin 17 on CN7
+#define MICROPY_HW_SPI1_SCK (pin_A5) // Arduino D13, pin 11 on CN10
+#define MICROPY_HW_SPI1_MISO (pin_A6) // Arduino D12, pin 13 on CN10
+#define MICROPY_HW_SPI1_MOSI (pin_A7) // Arduino D11, pin 15 on CN10
+
+#define MICROPY_HW_SPI2_NSS (pin_B12) // pin 16 on CN10
+#define MICROPY_HW_SPI2_SCK (pin_B13) // pin 30 on CN10
+#define MICROPY_HW_SPI2_MISO (pin_B14) // pin 28 on CN10
+#define MICROPY_HW_SPI2_MOSI (pin_B15) // pin 26 on CN10
+
+#define MICROPY_HW_SPI3_NSS (pin_A4) // Arduino A2, pin 32 on CN7
+#define MICROPY_HW_SPI3_SCK (pin_B3) // Arduino D3, pin 31 on CN10
+#define MICROPY_HW_SPI3_MISO (pin_B4) // Arduino D5, pin 27 on CN10
+#define MICROPY_HW_SPI3_MOSI (pin_B5) // Arduino D4, pin 29 on CN10
+
+#define MICROPY_HW_SPI4_NSS (pin_B12) // pin 16 on CN10
+#define MICROPY_HW_SPI4_SCK (pin_B13) // pin 30 on CN10
+#define MICROPY_HW_SPI4_MISO (pin_A1) // pin 30 on CN7
+#define MICROPY_HW_SPI4_MOSI (pin_A11) // pin 14 on CN10
+
+// USRSW is pulled low. Pressing the button makes the input go high.
+#define MICROPY_HW_USRSW_PIN (pin_C13)
+#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL)
+#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING)
+#define MICROPY_HW_USRSW_PRESSED (0)
+
+// LEDs
+#define MICROPY_HW_LED1 (pin_A5) // Green LD2 LED on Nucleo
+#define MICROPY_HW_LED_ON(pin) (mp_hal_pin_high(pin))
+#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
diff --git a/stmhal/boards/NUCLEO_F446RE/mpconfigboard.mk b/stmhal/boards/NUCLEO_F446RE/mpconfigboard.mk
new file mode 100644
index 000000000..e1ec6d57c
--- /dev/null
+++ b/stmhal/boards/NUCLEO_F446RE/mpconfigboard.mk
@@ -0,0 +1,4 @@
+MCU_SERIES = f4
+CMSIS_MCU = STM32F446xx
+AF_FILE = boards/stm32f429_af.csv
+LD_FILE = boards/stm32f411.ld
diff --git a/stmhal/boards/NUCLEO_F446RE/pins.csv b/stmhal/boards/NUCLEO_F446RE/pins.csv
new file mode 100644
index 000000000..5b09bcc74
--- /dev/null
+++ b/stmhal/boards/NUCLEO_F446RE/pins.csv
@@ -0,0 +1,72 @@
+D0,PA3
+D1,PA2
+D2,PA10
+D3,PB3
+D4,PB5
+D5,PB4
+D6,PB10
+D7,PA8
+D8,PA9
+D9,PC7
+D10,PB6
+D11,PA7
+D12,PA6
+D13,PA5
+D14,PB9
+D15,PB8
+A0,PA0
+A1,PA1
+A2,PA4
+A3,PB0
+A4,PC1
+A5,PC0
+PA0,PA0
+PA1,PA1
+PA2,PA2
+PA3,PA3
+PA4,PA4
+PA5,PA5
+PA6,PA6
+PA7,PA7
+PA8,PA8
+PA9,PA9
+PA10,PA10
+PA11,PA11
+PA12,PA12
+PA15,PA15
+PB0,PB0
+PB1,PB1
+PB2,PB2
+PB3,PB3
+PB4,PB4
+PB5,PB5
+PB6,PB6
+PB7,PB7
+PB8,PB8
+PB9,PB9
+PB10,PB10
+PB12,PB12
+PB13,PB13
+PB14,PB14
+PB15,PB15
+PC0,PC0
+PC1,PC1
+PC2,PC2
+PC3,PC3
+PC4,PC4
+PC5,PC5
+PC6,PC6
+PC7,PC7
+PC8,PC8
+PC9,PC9
+PC10,PC10
+PC11,PC11
+PC12,PC12
+PC13,PC13
+PC14,PC14
+PC15,PC15
+PD2,PD2
+PH0,PH0
+PH1,PH1
+LED,PA5
+SW,PC13
diff --git a/stmhal/boards/NUCLEO_F446RE/stm32f4xx_hal_conf.h b/stmhal/boards/NUCLEO_F446RE/stm32f4xx_hal_conf.h
new file mode 100644
index 000000000..3d0ce926b
--- /dev/null
+++ b/stmhal/boards/NUCLEO_F446RE/stm32f4xx_hal_conf.h
@@ -0,0 +1,413 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_conf.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 19-June-2014
+ * @brief HAL configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_CONF_H
+#define __STM32F4xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+// This board doesn't really have USB, but the stmhal codebase doesn't build
+// without some USB defined, so we leave this on for now.
+#define USE_USB_FS
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+#define HAL_ADC_MODULE_ENABLED
+#define HAL_CAN_MODULE_ENABLED
+/* #define HAL_CRC_MODULE_ENABLED */
+/* #define HAL_CRYP_MODULE_ENABLED */
+#define HAL_DAC_MODULE_ENABLED
+/* #define HAL_DCMI_MODULE_ENABLED */
+#define HAL_DMA_MODULE_ENABLED
+/* #define HAL_DMA2D_MODULE_ENABLED */
+/* #define HAL_ETH_MODULE_ENABLED */
+#define HAL_FLASH_MODULE_ENABLED
+/* #define HAL_NAND_MODULE_ENABLED */
+/* #define HAL_NOR_MODULE_ENABLED */
+/* #define HAL_PCCARD_MODULE_ENABLED */
+/* #define HAL_SRAM_MODULE_ENABLED */
+/* #define HAL_SDRAM_MODULE_ENABLED */
+/* #define HAL_HASH_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+/* #define HAL_I2S_MODULE_ENABLED */
+/* #define HAL_IWDG_MODULE_ENABLED */
+/* #define HAL_LTDC_MODULE_ENABLED */
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+/* #define HAL_RNG_MODULE_ENABLED */
+#define HAL_RTC_MODULE_ENABLED
+/* #define HAL_SAI_MODULE_ENABLED */
+#define HAL_SD_MODULE_ENABLED
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+/* #define HAL_USART_MODULE_ENABLED */
+/* #define HAL_IRDA_MODULE_ENABLED */
+/* #define HAL_SMARTCARD_MODULE_ENABLED */
+/* #define HAL_WWDG_MODULE_ENABLED */
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_PCD_MODULE_ENABLED
+/* #define HAL_HCD_MODULE_ENABLED */
+
+
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)40000)
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature. */
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)0x00) /*!< tick interrupt priority */
+#define USE_RTOS 0
+#define PREFETCH_ENABLE 1
+#define INSTRUCTION_CACHE_ENABLE 1
+#define DATA_CACHE_ENABLE 1
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1 */
+
+/* ################## Ethernet peripheral configuration ##################### */
+
+/* Section 1 : Ethernet peripheral configuration */
+
+/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
+#define MAC_ADDR0 2
+#define MAC_ADDR1 0
+#define MAC_ADDR2 0
+#define MAC_ADDR3 0
+#define MAC_ADDR4 0
+#define MAC_ADDR5 0
+
+/* Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
+#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
+#define ETH_RXBUFNB ((uint32_t)4) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB ((uint32_t)4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/* Section 2: PHY configuration section */
+
+/* DP83848 PHY Address*/
+#define DP83848_PHY_ADDRESS 0x01
+/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
+#define PHY_RESET_DELAY ((uint32_t)0x000000FF)
+/* PHY Configuration delay */
+#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF)
+
+#define PHY_READ_TO ((uint32_t)0x0000FFFF)
+#define PHY_WRITE_TO ((uint32_t)0x0000FFFF)
+
+/* Section 3: Common PHY Registers */
+
+#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
+#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
+
+#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
+#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
+#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
+#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
+#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
+
+/* Section 4: Extended PHY Registers */
+
+#define PHY_SR ((uint16_t)0x10) /*!< PHY status register Offset */
+#define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */
+#define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */
+
+#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */
+#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */
+#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */
+
+#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */
+#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */
+
+#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */
+#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f4xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f4xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f4xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f4xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f4xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32f4xx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_DMA2D_MODULE_ENABLED
+ #include "stm32f4xx_hal_dma2d.h"
+#endif /* HAL_DMA2D_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f4xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_DCMI_MODULE_ENABLED
+ #include "stm32f4xx_hal_dcmi.h"
+#endif /* HAL_DCMI_MODULE_ENABLED */
+
+#ifdef HAL_ETH_MODULE_ENABLED
+ #include "stm32f4xx_hal_eth.h"
+#endif /* HAL_ETH_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_SDRAM_MODULE_ENABLED
+ #include "stm32f4xx_hal_sdram.h"
+#endif /* HAL_SDRAM_MODULE_ENABLED */
+
+#ifdef HAL_HASH_MODULE_ENABLED
+ #include "stm32f4xx_hal_hash.h"
+#endif /* HAL_HASH_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f4xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LTDC_MODULE_ENABLED
+ #include "stm32f4xx_hal_ltdc.h"
+#endif /* HAL_LTDC_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f4xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32f4xx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f4xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32f4xx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SD_MODULE_ENABLED
+ #include "stm32f4xx_hal_sd.h"
+#endif /* HAL_SD_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f4xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f4xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f4xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f4xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f4xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32f4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_CONF_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/boards/NUCLEO_F767ZI/mpconfigboard.h b/stmhal/boards/NUCLEO_F767ZI/mpconfigboard.h
index 647525384..8952bce82 100644
--- a/stmhal/boards/NUCLEO_F767ZI/mpconfigboard.h
+++ b/stmhal/boards/NUCLEO_F767ZI/mpconfigboard.h
@@ -16,7 +16,7 @@
#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_ENABLE_TIMER (1)
#define MICROPY_HW_ENABLE_SERVO (0)
-#define MICROPY_HW_ENABLE_DAC (0)
+#define MICROPY_HW_ENABLE_DAC (1)
#define MICROPY_HW_ENABLE_CAN (1)
// HSE is 25MHz
@@ -52,11 +52,6 @@
#define MICROPY_HW_I2C3_SCL (pin_H7)
#define MICROPY_HW_I2C3_SDA (pin_H8)
-// TODO These should go in i2c.c
-#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x40912732}}
-#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 100000
-#define MICROPY_HW_I2C_BAUDRATE_MAX 100000
-
// SPI
#define MICROPY_HW_SPI3_NSS (pin_A4)
#define MICROPY_HW_SPI3_SCK (pin_B3)
diff --git a/stmhal/boards/NUCLEO_F767ZI/pins.csv b/stmhal/boards/NUCLEO_F767ZI/pins.csv
index f9f743489..897b1473e 100644
--- a/stmhal/boards/NUCLEO_F767ZI/pins.csv
+++ b/stmhal/boards/NUCLEO_F767ZI/pins.csv
@@ -1,25 +1,35 @@
-A0,PA0
-A1,PF10
-A2,PF9
-A3,PF8
-A4,PF7
-A5,PF6
-D0,PC7
-D1,PC6
-D2,PG6
-D3,PB4
-D4,PG7
-D5,PA8
-D6,PH6
-D7,PI3
-D8,PI2
-D9,PA15
-D10,PI0
-D11,PB15
-D12,PB14
-D13,PI1
+A0,PA3
+A1,PC0
+A2,PC3
+A3,PF3
+A4,PF5
+A5,PF10
+D0,PG9
+D1,PG14
+D2,PF15
+D3,PE13
+D4,PF14
+D5,PE11
+D6,PE9
+D7,PF13
+D8,PF12
+D9,PD15
+D10,PD14
+D11,PA7
+D12,PA6
+D13,PA5
D14,PB9
D15,PB8
+D16,PC6
+D17,PB15
+D18,PB13
+D19,PB12
+D20,PA15
+D21,PC7
+D22,PB5
+D23,PB3
+D24,PA4
+D25,PB4
LED1,PB0
LED2,PB7
LED3,PB14
diff --git a/stmhal/boards/NUCLEO_F767ZI/stm32f7xx_hal_conf.h b/stmhal/boards/NUCLEO_F767ZI/stm32f7xx_hal_conf.h
index d2c31cb09..e1aa4578d 100644
--- a/stmhal/boards/NUCLEO_F767ZI/stm32f7xx_hal_conf.h
+++ b/stmhal/boards/NUCLEO_F767ZI/stm32f7xx_hal_conf.h
@@ -58,7 +58,7 @@
/* #define HAL_CEC_MODULE_ENABLED */
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
-/* #define HAL_DAC_MODULE_ENABLED */
+#define HAL_DAC_MODULE_ENABLED
/* #define HAL_DCMI_MODULE_ENABLED */
#define HAL_DMA_MODULE_ENABLED
/* #define HAL_DMA2D_MODULE_ENABLED */
diff --git a/stmhal/boards/NUCLEO_L476RG/mpconfigboard.h b/stmhal/boards/NUCLEO_L476RG/mpconfigboard.h
index 181580b14..f2474619f 100644
--- a/stmhal/boards/NUCLEO_L476RG/mpconfigboard.h
+++ b/stmhal/boards/NUCLEO_L476RG/mpconfigboard.h
@@ -21,10 +21,6 @@
#define MICROPY_HW_UART_REPL PYB_UART_2
#define MICROPY_HW_UART_REPL_BAUD 115200
-#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x90112626}}
-#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 100000
-#define MICROPY_HW_I2C_BAUDRATE_MAX 100000
-
#define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_4
// I2C busses
diff --git a/stmhal/boards/STM32F411DISC/mpconfigboard.h b/stmhal/boards/STM32F411DISC/mpconfigboard.h
index d87701f8a..1488cd764 100644
--- a/stmhal/boards/STM32F411DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F411DISC/mpconfigboard.h
@@ -35,7 +35,7 @@
// I2C busses
#define MICROPY_HW_I2C1_SCL (pin_B6)
-#define MICROPY_HW_I2C1_SDA (pin_B7)
+#define MICROPY_HW_I2C1_SDA (pin_B9)
//#define MICROPY_HW_I2C2_SCL (pin_B10)
//#define MICROPY_HW_I2C2_SDA (pin_B11)
#define MICROPY_HW_I2C3_SCL (pin_A8)
diff --git a/stmhal/boards/STM32F769DISC/mpconfigboard.h b/stmhal/boards/STM32F769DISC/mpconfigboard.h
index a4cbcc520..50b9c1618 100644
--- a/stmhal/boards/STM32F769DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F769DISC/mpconfigboard.h
@@ -1,4 +1,5 @@
-//This board is only confirmed to operate using openocd.
+// This board is confirmed to operate using stlink and openocd.
+// REPL is on UART(1) and is available through the stlink USB-UART device.
// To use openocd run "OPENOCD_CONFIG=boards/openocd_stm32f7.cfg" in
// the make command.
#define MICROPY_HW_BOARD_NAME "F769DISC"
@@ -42,11 +43,6 @@
#define MICROPY_HW_I2C3_SCL (pin_H7)
#define MICROPY_HW_I2C3_SDA (pin_H8)
-// TODO These should go in i2c.c
-#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x40912732}}
-#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 100000
-#define MICROPY_HW_I2C_BAUDRATE_MAX 100000
-
// SPI
#define MICROPY_HW_SPI2_NSS (pin_A11)
#define MICROPY_HW_SPI2_SCK (pin_A12)
@@ -54,7 +50,7 @@
#define MICROPY_HW_SPI2_MOSI (pin_B15)
// USRSW is pulled low. Pressing the button makes the input go high.
-#define MICROPY_HW_USRSW_PIN (pin_I11)
+#define MICROPY_HW_USRSW_PIN (pin_A0)
#define MICROPY_HW_USRSW_PULL (GPIO_NOPULL)
#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING)
#define MICROPY_HW_USRSW_PRESSED (1)
@@ -67,6 +63,12 @@
#define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin))
// SD card detect switch
+#define MICROPY_HW_SDMMC2_CK (pin_D6)
+#define MICROPY_HW_SDMMC2_CMD (pin_D7)
+#define MICROPY_HW_SDMMC2_D0 (pin_G9)
+#define MICROPY_HW_SDMMC2_D1 (pin_G10)
+#define MICROPY_HW_SDMMC2_D2 (pin_B3)
+#define MICROPY_HW_SDMMC2_D3 (pin_B4)
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_I15)
#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP)
#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET)
diff --git a/stmhal/boards/STM32F769DISC/mpconfigboard.mk b/stmhal/boards/STM32F769DISC/mpconfigboard.mk
index 2e1e9952b..b65a18afb 100644
--- a/stmhal/boards/STM32F769DISC/mpconfigboard.mk
+++ b/stmhal/boards/STM32F769DISC/mpconfigboard.mk
@@ -1,4 +1,4 @@
MCU_SERIES = f7
CMSIS_MCU = STM32F769xx
-AF_FILE = boards/stm32f769_af.csv
+AF_FILE = boards/stm32f767_af.csv
LD_FILE = boards/stm32f769.ld
diff --git a/stmhal/boards/STM32F769DISC/pins.csv b/stmhal/boards/STM32F769DISC/pins.csv
index e59a51387..dcc2df208 100644
--- a/stmhal/boards/STM32F769DISC/pins.csv
+++ b/stmhal/boards/STM32F769DISC/pins.csv
@@ -33,12 +33,12 @@ AUDIO_SCL,PH7
EXT_SDA,PB9
EXT_SCL,PB8
EXT_RST,PG3
-SD_D0,PC8
-SD_D1,PC9
-SD_D2,PC10
-SD_D3,PC11
-SD_CK,PC12
-SD_CMD,PD2
+SD_D0,PG9
+SD_D1,PG10
+SD_D2,PB3
+SD_D3,PB4
+SD_CK,PD6
+SD_CMD,PD7
SD_SW,PI15
LCD_BL_CTRL,PK3
LCD_INT,PI13
diff --git a/stmhal/boards/STM32F7DISC/mpconfigboard.h b/stmhal/boards/STM32F7DISC/mpconfigboard.h
index 38665055f..44a39c0a1 100644
--- a/stmhal/boards/STM32F7DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F7DISC/mpconfigboard.h
@@ -51,16 +51,6 @@ void STM32F7DISC_board_early_init(void);
#define MICROPY_HW_I2C3_SCL (pin_H7)
#define MICROPY_HW_I2C3_SDA (pin_H8)
-// The STM32F7 uses a TIMINGR register which is configured using an Excel
-// Spreadsheet from AN4235: http://www.st.com/web/en/catalog/tools/PF258335
-// We use an array of baudrates and corresponding TIMINGR values.
-//
-// The value 0x40912732 was obtained from the DISCOVERY_I2Cx_TIMING constant
-// defined in the STM32F7Cube file Drivers/BSP/STM32F746G-Discovery/stm32f7456g_discovery.h
-#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x40912732}}
-#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 100000
-#define MICROPY_HW_I2C_BAUDRATE_MAX 100000
-
// SPI
#define MICROPY_HW_SPI2_NSS (pin_I0)
#define MICROPY_HW_SPI2_SCK (pin_I1)
diff --git a/stmhal/boards/STM32L476DISC/board_init.c b/stmhal/boards/STM32L476DISC/board_init.c
new file mode 100644
index 000000000..fdc41c401
--- /dev/null
+++ b/stmhal/boards/STM32L476DISC/board_init.c
@@ -0,0 +1,10 @@
+#include "py/mphal.h"
+#include "genhdr/pins.h"
+
+void STM32L476DISC_board_early_init(void) {
+ // set SPI flash WP and HOLD pins high
+ mp_hal_pin_output(&pin_E14);
+ mp_hal_pin_output(&pin_E15);
+ mp_hal_pin_write(&pin_E14, 1);
+ mp_hal_pin_write(&pin_E15, 1);
+}
diff --git a/stmhal/boards/STM32L476DISC/mpconfigboard.h b/stmhal/boards/STM32L476DISC/mpconfigboard.h
index 2be5c9de6..258a86b60 100644
--- a/stmhal/boards/STM32L476DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32L476DISC/mpconfigboard.h
@@ -1,5 +1,8 @@
#include STM32_HAL_H
+#define MICROPY_BOARD_EARLY_INIT STM32L476DISC_board_early_init
+void STM32L476DISC_board_early_init(void);
+
#define MICROPY_HW_BOARD_NAME "L476-DISCO"
#define MICROPY_HW_MCU_NAME "STM32L476"
@@ -16,6 +19,13 @@
#define MICROPY_HW_ENABLE_DAC (0)
#define MICROPY_HW_ENABLE_CAN (0)
+// use external SPI flash for storage
+#define MICROPY_HW_SPIFLASH_SIZE_BITS (128 * 1024 * 1024)
+#define MICROPY_HW_SPIFLASH_CS (pin_E11)
+#define MICROPY_HW_SPIFLASH_SCK (pin_E10)
+#define MICROPY_HW_SPIFLASH_MOSI (pin_E12)
+#define MICROPY_HW_SPIFLASH_MISO (pin_E13)
+
// MSI is used and is 4MHz
#define MICROPY_HW_CLK_PLLM (1)
#define MICROPY_HW_CLK_PLLN (40)
@@ -37,13 +47,6 @@
#define MICROPY_HW_I2C1_SDA (pin_B7)
#define MICROPY_HW_I2C2_SCL (pin_B10)
#define MICROPY_HW_I2C2_SDA (pin_B11)
-// We use an array of baudrates and corresponding TIMINGR values.
-//
-// The value 0x90112626 was obtained from the DISCOVERY_I2C1_TIMING constant
-// defined in the STM32L4Cube file Drivers/BSP/STM32L476G-Discovery/stm32l476g_discovery.h
-#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x90112626}}
-#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 100000
-#define MICROPY_HW_I2C_BAUDRATE_MAX 100000
// SPI busses
#define MICROPY_HW_SPI2_NSS (pin_D0)
diff --git a/stmhal/boards/make-pins.py b/stmhal/boards/make-pins.py
index b33c92edc..51619ffa2 100755
--- a/stmhal/boards/make-pins.py
+++ b/stmhal/boards/make-pins.py
@@ -14,7 +14,8 @@ SUPPORTED_FN = {
'I2S' : ['CK', 'MCK', 'SD', 'WS', 'EXTSD'],
'USART' : ['RX', 'TX', 'CTS', 'RTS', 'CK'],
'UART' : ['RX', 'TX', 'CTS', 'RTS'],
- 'SPI' : ['NSS', 'SCK', 'MISO', 'MOSI']
+ 'SPI' : ['NSS', 'SCK', 'MISO', 'MOSI'],
+ 'SDMMC' : ['CK', 'CMD', 'D0', 'D1', 'D2', 'D3'],
}
CONDITIONAL_VAR = {
@@ -23,6 +24,7 @@ CONDITIONAL_VAR = {
'SPI' : 'MICROPY_HW_SPI{num}_SCK',
'UART' : 'MICROPY_HW_UART{num}_TX',
'USART' : 'MICROPY_HW_UART{num}_TX',
+ 'SDMMC' : 'MICROPY_HW_SDMMC{num}_CK',
}
def parse_port_pin(name_str):
@@ -281,11 +283,11 @@ class Pins(object):
self.board_pins.append(NamedPin(row[0], pin))
def print_named(self, label, named_pins):
- print('STATIC const mp_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
+ print('STATIC const mp_rom_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
for named_pin in named_pins:
pin = named_pin.pin()
if pin.is_board_pin():
- print(' {{ MP_OBJ_NEW_QSTR(MP_QSTR_{:s}), (mp_obj_t)&pin_{:s} }},'.format(named_pin.name(), pin.cpu_pin_name()))
+ print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},'.format(named_pin.name(), pin.cpu_pin_name()))
print('};')
print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
diff --git a/stmhal/boards/openocd_stm32f4.cfg b/stmhal/boards/openocd_stm32f4.cfg
index 122ae42b1..ee96b91bd 100644
--- a/stmhal/boards/openocd_stm32f4.cfg
+++ b/stmhal/boards/openocd_stm32f4.cfg
@@ -4,7 +4,7 @@
# To flash your firmware:
#
# $ openocd -f openocd_stm32f4.cfg \
-# -c "stm_flash build-BOARD/firmware0.bin build-BOARD/firmware1.bin"
+# -c "stm_flash build-BOARD/firmware0.bin 0x08000000 build-BOARD/firmware1.bin 0x08020000"
#
# For a gdb server on port 3333:
#
diff --git a/stmhal/boards/openocd_stm32f7.cfg b/stmhal/boards/openocd_stm32f7.cfg
index 18aa58c96..55b632650 100644
--- a/stmhal/boards/openocd_stm32f7.cfg
+++ b/stmhal/boards/openocd_stm32f7.cfg
@@ -4,7 +4,7 @@
# To flash your firmware:
#
# $ openocd -f openocd_stm32f7.cfg \
-# -c "stm_flash build-BOARD/firmware0.bin build-BOARD/firmware1.bin"
+# -c "stm_flash build-BOARD/firmware0.bin 0x08000000 build-BOARD/firmware1.bin 0x08020000"
#
# For a gdb server on port 3333:
#
diff --git a/stmhal/boards/openocd_stm32l4.cfg b/stmhal/boards/openocd_stm32l4.cfg
index 3c9b99981..59e98de03 100644
--- a/stmhal/boards/openocd_stm32l4.cfg
+++ b/stmhal/boards/openocd_stm32l4.cfg
@@ -4,7 +4,7 @@
# To flash your firmware:
#
# $ openocd -f openocd_stm32l4.cfg \
-# -c "stm_flash build-BOARD/firmware0.bin build-BOARD/firmware1.bin"
+# -c "stm_flash build-BOARD/firmware0.bin 0x08000000 build-BOARD/firmware1.bin 0x08004000"
#
# For a gdb server on port 3333:
#
diff --git a/stmhal/boards/stm32f411.ld b/stmhal/boards/stm32f411.ld
index 823b5f56a..0b7bcb553 100644
--- a/stmhal/boards/stm32f411.ld
+++ b/stmhal/boards/stm32f411.ld
@@ -16,10 +16,10 @@ MEMORY
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;
-/* top end of the stack */
-
-/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
-_estack = ORIGIN(RAM) + LENGTH(RAM) - 1;
+/* Define tho top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
/* define common sections and symbols */
INCLUDE common.ld
diff --git a/stmhal/boards/stm32f429.ld b/stmhal/boards/stm32f429.ld
index d199f4550..0feb5bd62 100644
--- a/stmhal/boards/stm32f429.ld
+++ b/stmhal/boards/stm32f429.ld
@@ -16,10 +16,10 @@ MEMORY
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;
-/* top end of the stack */
-
-/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
-_estack = ORIGIN(RAM) + LENGTH(RAM) - 1;
+/* Define tho top end of the stack. The stack is full descending so begins just
+ above last byte of RAM. Note that EABI requires the stack to be 8-byte
+ aligned for a call. */
+_estack = ORIGIN(RAM) + LENGTH(RAM);
/* define common sections and symbols */
INCLUDE common.ld
diff --git a/stmhal/boards/stm32f767_af.csv b/stmhal/boards/stm32f767_af.csv
index eabc9ab3b..db27818c6 100644
--- a/stmhal/boards/stm32f767_af.csv
+++ b/stmhal/boards/stm32f767_af.csv
@@ -1,11 +1,11 @@
Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15
-,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11/LPTIM1/CEC,I2C1/2/3/4/CEC,SPI1/2/3/4/5/6,SPI3/SAI1,SPI2/3/USART1/2/3/UART5/SPDIFRX,SAI2/USART6/UART4/5/7/8/SPDIFRX,CAN1/2/TIM12/13/14/QUADSPI/LCD,SAI2/QUADSPI/OTG2_HS/OTG1_FS,ETH/OTG1_FS,FMC/SDMMC1/OTG2_FS,DCMI,LCD,SYS
+,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11/LPTIM1/CEC,I2C1/2/3/4/CEC,SPI1/2/3/4/5/6,SPI3/SAI1,SPI2/3/USART1/2/3/UART5/SPDIFRX,SAI2/USART6/UART4/5/7/8/SPDIFRX,CAN1/2/TIM12/13/14/QUADSPI/LCD,SAI2/QUADSPI/SDMMC2/OTG2_HS/OTG1_FS,SDMMC2/ETH,FMC/SDMMC1/OTG2_FS,DCMI,LCD,SYS
PortA,PA0,,TIM2_CH1/TIM2_ETR,TIM5_CH1,TIM8_ETR,,,,USART2_CTS,UART4_TX,,SAI2_SD_B,ETH_MII_CRS,,,,EVENTOUT
PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,UART4_RX,QUADSPI_BK1_IO3,SAI2_MCK_B,ETH_MII_RX_CLK/ETH_RMII_REF_CLK,,,LCD_R2,EVENTOUT
PortA,PA2,,TIM2_CH3,TIM5_CH3,TIM9_CH1,,,,USART2_TX,SAI2_SCK_B,,,ETH_MDIO,,,LCD_R1,EVENTOUT
PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,,USART2_RX,,,OTG_HS_ULPI_D0,ETH_MII_COL,,,LCD_B5,EVENTOUT
PortA,PA4,,,,,,SPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,USART2_CK,,,,,OTG_HS_SOF,DCMI_HSYNC,LCD_VSYNC,EVENTOUT
-PortA,PA5,,TIM2_CH1/TIM2_ETR,TIM8_CH1N,SPI1_SCK/I2S1_CK,,,,,,,OTG_HS_ULPI_CK,,,,LCD_R4,EVENTOUT
+PortA,PA5,,TIM2_CH1/TIM2_ETR,,TIM8_CH1N,,SPI1_SCK/I2S1_CK,,,,,OTG_HS_ULPI_CK,,,,LCD_R4,EVENTOUT
PortA,PA6,,TIM1_BKIN,TIM3_CH1,TIM8_BKIN,,SPI1_MISO,,,,TIM13_CH1,,,,DCMI_PIXCLK,LCD_G2,EVENTOUT
PortA,PA7,,TIM1_CH1N,TIM3_CH2,TIM8_CH1N,,SPI1_MOSI/I2S1_SD,,,,TIM14_CH1,,ETH_MII_RX_DV/ETH_RMII_CRS_DV,FMC_SDNWE,,,EVENTOUT
PortA,PA8,MCO1,TIM1_CH1,,TIM8_BKIN2,I2C3_SCL,,,USART1_CK,,,OTG_FS_SOF,,,,LCD_R6,EVENTOUT
@@ -19,27 +19,27 @@ PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,HDMICE,CSPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,,U
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
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,,,,,,,,,EVENTOUT
-PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,SPI2_NSS/I2S2_WS,,,,,,,,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
PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI/I2S1_SD,SPI3_MOSI/I2S3_SD,,,CAN2_RX,OTG_HS_ULPI_D7,ETH_PPS_OUT,FMC_SDCKE1,DCMI_D10,,EVENTOUT
PortB,PB6,,,TIM4_CH1,HDMICEC,I2C1_SCL,,,USART1_TX,,CAN2_TX,QUADSPI_BK1_NCS,,FMC_SDNE1,DCMI_D5,,EVENTOUT
PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,,,,,FMC_NL,DCMI_VSYNC,,EVENTOUT
-PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,,ETH_MII_TXD3,SDMMC1_D4,DCMI_D6,LCD_B6,EVENTOUT
-PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,,,,CAN1_TX,,,SDMMC1_D5,DCMI_D7,LCD_B7,EVENTOUT
+PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,SDMMC2_D4,ETH_MII_TXD3,SDMMC1_D4,DCMI_D6,LCD_B6,EVENTOUT
+PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,,,,CAN1_TX,SDMMC2_D5,,SDMMC1_D5,DCMI_D7,LCD_B7,EVENTOUT
PortB,PB10,,TIM2_CH3,,,I2C2_SCL,SPI2_SCK/I2S2_CK,,USART3_TX,,,OTG_HS_ULPI_D3,ETH_MII_RX_ER,,,LCD_G4,EVENTOUT
PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,,,OTG_HS_ULPI_D4,ETH_MII_TX_EN/ETH_RMII_TX_EN,,,LCD_G5,EVENTOUT
PortB,PB12,,TIM1_BKIN,,,I2C2_SMBA,SPI2_NSS/I2S2_WS,,USART3_CK,,CAN2_RX,OTG_HS_ULPI_D5,ETH_MII_TXD0/ETH_RMII_TXD0,OTG_HS_ID,,,EVENTOUT
PortB,PB13,,TIM1_CH1N,,,,SPI2_SCK/I2S2_CK,,USART3_CTS,,CAN2_TX,OTG_HS_ULPI_D6,ETH_MII_TXD1/ETH_RMII_TXD1,,,,EVENTOUT
-PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,,USART3_RTS,,TIM12_CH1,,,OTG_HS_DM,,,EVENTOUT
-PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,,,OTG_HS_DP,,,EVENTOUT
+PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,,USART3_RTS,,TIM12_CH1,SDMMC2_D0,,OTG_HS_DM,,,EVENTOUT
+PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,SDMMC2_D1,,OTG_HS_DP,,,EVENTOUT
PortC,PC0,,,,,,,,,SAI2_FS_B,,OTG_HS_ULPI_STP,,FMC_SDNWE,,LCD_R5,EVENTOUT
PortC,PC1,TRACED0,,,,,SPI2_MOSI/I2S2_SD,SAI1_SD_A,,,,,ETH_MDC,,,,EVENTOUT
PortC,PC2,,,,,,SPI2_MISO,,,,,OTG_HS_ULPI_DIR,ETH_MII_TXD2,FMC_SDNE0,,,EVENTOUT
PortC,PC3,,,,,,SPI2_MOSI/I2S2_SD,,,,,OTG_HS_ULPI_NXT,ETH_MII_TX_CLK,FMC_SDCKE0,,,EVENTOUT
PortC,PC4,,,,,,I2S1_MCK,,,SPDIFRX_IN2,,,ETH_MII_RXD0/ETH_RMII_RXD0,FMC_SDNE0,,,EVENTOUT
PortC,PC5,,,,,,,,,SPDIFRX_IN3,,,ETH_MII_RXD1/ETH_RMII_RXD1,FMC_SDCKE0,,,EVENTOUT
-PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,,,SDMMC1_D6,DCMI_D0,LCD_HSYNC,EVENTOUT
-PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,,,SDMMC1_D7,DCMI_D1,LCD_G6,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,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,QUADSPI_BK1_IO1,,,SDMMC1_D2,DCMI_D8,LCD_R2,EVENTOUT
@@ -54,8 +54,8 @@ PortD,PD2,TRACED2,,TIM3_ETR,,,,,,UART5_RX,,,,SDMMC1_CMD,DCMI_D11,,EVENTOUT
PortD,PD3,,,,,,SPI2_SCK/I2S2_CK,,USART2_CTS,,,,,FMC_CLK,DCMI_D5,LCD_G7,EVENTOUT
PortD,PD4,,,,,,,,USART2_RTS,,,,,FMC_NOE,,,EVENTOUT
PortD,PD5,,,,,,,,USART2_TX,,,,,FMC_NWE,,,EVENTOUT
-PortD,PD6,,,,,,SPI3_MOSI/I2S3_SD,SAI1_SD_A,USART2_RX,,,,,FMC_NWAIT,DCMI_D10,LCD_B2,EVENTOUT
-PortD,PD7,,,,,,,,USART2_CK,SPDIFRX_IN0,,,,FMC_NE1,,,EVENTOUT
+PortD,PD6,,,,,,SPI3_MOSI/I2S3_SD,SAI1_SD_A,USART2_RX,,,,SDMMC2_CK,FMC_NWAIT,DCMI_D10,LCD_B2,EVENTOUT
+PortD,PD7,,,,,,,,USART2_CK,SPDIFRX_IN0,,,SDMMC2_CMD,FMC_NE1,,,EVENTOUT
PortD,PD8,,,,,,,,USART3_TX,SPDIFRX_IN1,,,,FMC_D13,,,EVENTOUT
PortD,PD9,,,,,,,,USART3_RX,,,,,FMC_D14,,,EVENTOUT
PortD,PD10,,,,,,,,USART3_CK,,,,,FMC_D15,,LCD_B3,EVENTOUT
@@ -105,10 +105,10 @@ PortG,PG5,,,,,,,,,,,,,FMC_A15/FMC_BA1,,,EVENTOUT
PortG,PG6,,,,,,,,,,,,,,DCMI_D12,LCD_R7,EVENTOUT
PortG,PG7,,,,,,,,,USART6_CK,,,,FMC_INT,DCMI_D13,LCD_CLK,EVENTOUT
PortG,PG8,,,,,,SPI6_NSS,,SPDIFRX_IN2,USART6_RTS,,,ETH_PPS_OUT,FMC_SDCLK,,,EVENTOUT
-PortG,PG9,,,,,,,,SPDIFRX_IN3,USART6_RX,QUADSPI_BK2_IO2,SAI2_FS_B,,FMC_NE2/FMC_NCE,DCMI_VSYNC,,EVENTOUT
-PortG,PG10,,,,,,,,,,LCD_G3,SAI2_SD_B,,FMC_NE3,DCMI_D2,LCD_B2,EVENTOUT
-PortG,PG11,,,,,,,,SPDIFRX_IN0,,,,ETH_MII_TX_EN/ETH_RMII_TX_EN,,DCMI_D3,LCD_B3,EVENTOUT
-PortG,PG12,,,,LPTIM1_IN1,,SPI6_MISO,,SPDIFRX_IN1,USART6_RTS,LCD_B4,,,FMC_NE4,,LCD_B1,EVENTOUT
+PortG,PG9,,,,,,,,SPDIFRX_IN3,USART6_RX,QUADSPI_BK2_IO2,SAI2_FS_B,SDMMC2_D0,FMC_NE2/FMC_NCE,DCMI_VSYNC,,EVENTOUT
+PortG,PG10,,,,,,,,,,LCD_G3,SAI2_SD_B,SDMMC2_D1,FMC_NE3,DCMI_D2,LCD_B2,EVENTOUT
+PortG,PG11,,,,,,,,SPDIFRX_IN0,,,SDMMC2_D2,ETH_MII_TX_EN/ETH_RMII_TX_EN,,DCMI_D3,LCD_B3,EVENTOUT
+PortG,PG12,,,,LPTIM1_IN1,,SPI6_MISO,,SPDIFRX_IN1,USART6_RTS,LCD_B4,,SDMMC2_D3,FMC_NE4,,LCD_B1,EVENTOUT
PortG,PG13,TRACED0,,,LPTIM1_OUT,,SPI6_SCK,,,USART6_CTS,,,ETH_MII_TXD0/ETH_RMII_TXD0,FMC_A24,,LCD_R0,EVENTOUT
PortG,PG14,TRACED1,,,LPTIM1_ETR,,SPI6_MOSI,,,USART6_TX,QUADSPI_BK2_IO3,,ETH_MII_TXD1/ETH_RMII_TXD1,FMC_A25,,LCD_B0,EVENTOUT
PortG,PG15,,,,,,,,,USART6_CTS,,,,FMC_SDNCAS,DCMI_D13,,EVENTOUT
@@ -168,4 +168,3 @@ PortK,PK4,,,,,,,,,,,,,,,LCD_B5,EVENTOUT
PortK,PK5,,,,,,,,,,,,,,,LCD_B6,EVENTOUT
PortK,PK6,,,,,,,,,,,,,,,LCD_B7,EVENTOUT
PortK,PK7,,,,,,,,,,,,,,,LCD_DE,EVENTOUT
-
diff --git a/stmhal/boards/stm32f769_af.csv b/stmhal/boards/stm32f769_af.csv
deleted file mode 100644
index eabc9ab3b..000000000
--- a/stmhal/boards/stm32f769_af.csv
+++ /dev/null
@@ -1,171 +0,0 @@
-Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15
-,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11/LPTIM1/CEC,I2C1/2/3/4/CEC,SPI1/2/3/4/5/6,SPI3/SAI1,SPI2/3/USART1/2/3/UART5/SPDIFRX,SAI2/USART6/UART4/5/7/8/SPDIFRX,CAN1/2/TIM12/13/14/QUADSPI/LCD,SAI2/QUADSPI/OTG2_HS/OTG1_FS,ETH/OTG1_FS,FMC/SDMMC1/OTG2_FS,DCMI,LCD,SYS
-PortA,PA0,,TIM2_CH1/TIM2_ETR,TIM5_CH1,TIM8_ETR,,,,USART2_CTS,UART4_TX,,SAI2_SD_B,ETH_MII_CRS,,,,EVENTOUT
-PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,UART4_RX,QUADSPI_BK1_IO3,SAI2_MCK_B,ETH_MII_RX_CLK/ETH_RMII_REF_CLK,,,LCD_R2,EVENTOUT
-PortA,PA2,,TIM2_CH3,TIM5_CH3,TIM9_CH1,,,,USART2_TX,SAI2_SCK_B,,,ETH_MDIO,,,LCD_R1,EVENTOUT
-PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,,USART2_RX,,,OTG_HS_ULPI_D0,ETH_MII_COL,,,LCD_B5,EVENTOUT
-PortA,PA4,,,,,,SPI1_NSS/I2S1_WS,SPI3_NSS/I2S3_WS,USART2_CK,,,,,OTG_HS_SOF,DCMI_HSYNC,LCD_VSYNC,EVENTOUT
-PortA,PA5,,TIM2_CH1/TIM2_ETR,TIM8_CH1N,SPI1_SCK/I2S1_CK,,,,,,,OTG_HS_ULPI_CK,,,,LCD_R4,EVENTOUT
-PortA,PA6,,TIM1_BKIN,TIM3_CH1,TIM8_BKIN,,SPI1_MISO,,,,TIM13_CH1,,,,DCMI_PIXCLK,LCD_G2,EVENTOUT
-PortA,PA7,,TIM1_CH1N,TIM3_CH2,TIM8_CH1N,,SPI1_MOSI/I2S1_SD,,,,TIM14_CH1,,ETH_MII_RX_DV/ETH_RMII_CRS_DV,FMC_SDNWE,,,EVENTOUT
-PortA,PA8,MCO1,TIM1_CH1,,TIM8_BKIN2,I2C3_SCL,,,USART1_CK,,,OTG_FS_SOF,,,,LCD_R6,EVENTOUT
-PortA,PA9,,TIM1_CH2,,,I2C3_SMBA,SPI2_SCK/I2S2_CK,,USART1_TX,,,,,,DCMI_D0,,EVENTOUT
-PortA,PA10,,TIM1_CH3,,,,,,USART1_RX,,,OTG_FS_ID,,,DCMI_D1,,EVENTOUT
-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
-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,,,,,,,,,EVENTOUT
-PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,SPI2_NSS/I2S2_WS,,,,,,,,EVENTOUT
-PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI/I2S1_SD,SPI3_MOSI/I2S3_SD,,,CAN2_RX,OTG_HS_ULPI_D7,ETH_PPS_OUT,FMC_SDCKE1,DCMI_D10,,EVENTOUT
-PortB,PB6,,,TIM4_CH1,HDMICEC,I2C1_SCL,,,USART1_TX,,CAN2_TX,QUADSPI_BK1_NCS,,FMC_SDNE1,DCMI_D5,,EVENTOUT
-PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,,,,,FMC_NL,DCMI_VSYNC,,EVENTOUT
-PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,,ETH_MII_TXD3,SDMMC1_D4,DCMI_D6,LCD_B6,EVENTOUT
-PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,,,,CAN1_TX,,,SDMMC1_D5,DCMI_D7,LCD_B7,EVENTOUT
-PortB,PB10,,TIM2_CH3,,,I2C2_SCL,SPI2_SCK/I2S2_CK,,USART3_TX,,,OTG_HS_ULPI_D3,ETH_MII_RX_ER,,,LCD_G4,EVENTOUT
-PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,,,OTG_HS_ULPI_D4,ETH_MII_TX_EN/ETH_RMII_TX_EN,,,LCD_G5,EVENTOUT
-PortB,PB12,,TIM1_BKIN,,,I2C2_SMBA,SPI2_NSS/I2S2_WS,,USART3_CK,,CAN2_RX,OTG_HS_ULPI_D5,ETH_MII_TXD0/ETH_RMII_TXD0,OTG_HS_ID,,,EVENTOUT
-PortB,PB13,,TIM1_CH1N,,,,SPI2_SCK/I2S2_CK,,USART3_CTS,,CAN2_TX,OTG_HS_ULPI_D6,ETH_MII_TXD1/ETH_RMII_TXD1,,,,EVENTOUT
-PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,,USART3_RTS,,TIM12_CH1,,,OTG_HS_DM,,,EVENTOUT
-PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,,,OTG_HS_DP,,,EVENTOUT
-PortC,PC0,,,,,,,,,SAI2_FS_B,,OTG_HS_ULPI_STP,,FMC_SDNWE,,LCD_R5,EVENTOUT
-PortC,PC1,TRACED0,,,,,SPI2_MOSI/I2S2_SD,SAI1_SD_A,,,,,ETH_MDC,,,,EVENTOUT
-PortC,PC2,,,,,,SPI2_MISO,,,,,OTG_HS_ULPI_DIR,ETH_MII_TXD2,FMC_SDNE0,,,EVENTOUT
-PortC,PC3,,,,,,SPI2_MOSI/I2S2_SD,,,,,OTG_HS_ULPI_NXT,ETH_MII_TX_CLK,FMC_SDCKE0,,,EVENTOUT
-PortC,PC4,,,,,,I2S1_MCK,,,SPDIFRX_IN2,,,ETH_MII_RXD0/ETH_RMII_RXD0,FMC_SDNE0,,,EVENTOUT
-PortC,PC5,,,,,,,,,SPDIFRX_IN3,,,ETH_MII_RXD1/ETH_RMII_RXD1,FMC_SDCKE0,,,EVENTOUT
-PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,,,SDMMC1_D6,DCMI_D0,LCD_HSYNC,EVENTOUT
-PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,,,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,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
-PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT
-PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT
-PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT
-PortD,PD0,,,,,,,,,,CAN1_RX,,,FMC_D2,,,EVENTOUT
-PortD,PD1,,,,,,,,,,CAN1_TX,,,FMC_D3,,,EVENTOUT
-PortD,PD2,TRACED2,,TIM3_ETR,,,,,,UART5_RX,,,,SDMMC1_CMD,DCMI_D11,,EVENTOUT
-PortD,PD3,,,,,,SPI2_SCK/I2S2_CK,,USART2_CTS,,,,,FMC_CLK,DCMI_D5,LCD_G7,EVENTOUT
-PortD,PD4,,,,,,,,USART2_RTS,,,,,FMC_NOE,,,EVENTOUT
-PortD,PD5,,,,,,,,USART2_TX,,,,,FMC_NWE,,,EVENTOUT
-PortD,PD6,,,,,,SPI3_MOSI/I2S3_SD,SAI1_SD_A,USART2_RX,,,,,FMC_NWAIT,DCMI_D10,LCD_B2,EVENTOUT
-PortD,PD7,,,,,,,,USART2_CK,SPDIFRX_IN0,,,,FMC_NE1,,,EVENTOUT
-PortD,PD8,,,,,,,,USART3_TX,SPDIFRX_IN1,,,,FMC_D13,,,EVENTOUT
-PortD,PD9,,,,,,,,USART3_RX,,,,,FMC_D14,,,EVENTOUT
-PortD,PD10,,,,,,,,USART3_CK,,,,,FMC_D15,,LCD_B3,EVENTOUT
-PortD,PD11,,,,,I2C4_SMBA,,,USART3_CTS,,QUADSPI_BK1_IO0,SAI2_SD_A,,FMC_A16/FMC_CLE,,,EVENTOUT
-PortD,PD12,,,TIM4_CH1,LPTIM1_IN1,I2C4_SCL,,,USART3_RTS,,QUADSPI_BK1_IO1,SAI2_FS_A,,FMC_A17/FMC_ALE,,,EVENTOUT
-PortD,PD13,,,TIM4_CH2,LPTIM1_OUT,I2C4_SDA,,,,,QUADSPI_BK1_IO3,SAI2_SCK_A,,FMC_A18,,,EVENTOUT
-PortD,PD14,,,TIM4_CH3,,,,,,UART8_CTS,,,,FMC_D0,,,EVENTOUT
-PortD,PD15,,,TIM4_CH4,,,,,,UART8_RTS,,,,FMC_D1,,,EVENTOUT
-PortE,PE0,,,TIM4_ETR,LPTIM1_ETR,,,,,UART8_RX,,SAI2_MCK_A,,FMC_NBL0,DCMI_D2,,EVENTOUT
-PortE,PE1,,,,LPTIM1_IN2,,,,,UART8_TX,,,,FMC_NBL1,DCMI_D3,,EVENTOUT
-PortE,PE2,TRACECLK,,,,,SPI4_SCK,SAI1_MCLK_A,,,QUADSPI_BK1_IO2,,ETH_MII_TXD3,FMC_A23,,,EVENTOUT
-PortE,PE3,TRACED0,,,,,,SAI1_SD_B,,,,,,FMC_A19,,,EVENTOUT
-PortE,PE4,TRACED1,,,,,SPI4_NSS,SAI1_FS_A,,,,,,FMC_A20,DCMI_D4,LCD_B0,EVENTOUT
-PortE,PE5,TRACED2,,,TIM9_CH1,,SPI4_MISO,SAI1_SCK_A,,,,,,FMC_A21,DCMI_D6,LCD_G0,EVENTOUT
-PortE,PE6,TRACED3,TIM1_BKIN2,,TIM9_CH2,,SPI4_MOSI,SAI1_SD_A,,,,SAI2_MCK_B,,FMC_A22,DCMI_D7,LCD_G1,EVENTOUT
-PortE,PE7,,TIM1_ETR,,,,,,,UART7_RX,,QUADSPI_BK2_IO0,,FMC_D4,,,EVENTOUT
-PortE,PE8,,TIM1_CH1N,,,,,,,UART7_TX,,QUADSPI_BK2_IO1,,FMC_D5,,,EVENTOUT
-PortE,PE9,,TIM1_CH1,,,,,,,UART7_RTS,,QUADSPI_BK2_IO2,,FMC_D6,,,EVENTOUT
-PortE,PE10,,TIM1_CH2N,,,,,,,UART7_CTS,,QUADSPI_BK2_IO3,,FMC_D7,,,EVENTOUT
-PortE,PE11,,TIM1_CH2,,,,SPI4_NSS,,,,,SAI2_SD_B,,FMC_D8,,LCD_G3,EVENTOUT
-PortE,PE12,,TIM1_CH3N,,,,SPI4_SCK,,,,,SAI2_SCK_B,,FMC_D9,,LCD_B4,EVENTOUT
-PortE,PE13,,TIM1_CH3,,,,SPI4_MISO,,,,,SAI2_FS_B,,FMC_D10,,LCD_DE,EVENTOUT
-PortE,PE14,,TIM1_CH4,,,,SPI4_MOSI,,,,,SAI2_MCK_B,,FMC_D11,,LCD_CLK,EVENTOUT
-PortE,PE15,,TIM1_BKIN,,,,,,,,,,,FMC_D12,,LCD_R7,EVENTOUT
-PortF,PF0,,,,,I2C2_SDA,,,,,,,,FMC_A0,,,EVENTOUT
-PortF,PF1,,,,,I2C2_SCL,,,,,,,,FMC_A1,,,EVENTOUT
-PortF,PF2,,,,,I2C2_SMBA,,,,,,,,FMC_A2,,,EVENTOUT
-PortF,PF3,,,,,,,,,,,,,FMC_A3,,,EVENTOUT
-PortF,PF4,,,,,,,,,,,,,FMC_A4,,,EVENTOUT
-PortF,PF5,,,,,,,,,,,,,FMC_A5,,,EVENTOUT
-PortF,PF6,,,,TIM10_CH1,,SPI5_NSS,SAI1_SD_B,,UART7_RX,QUADSPI_BK1_IO3,,,,,,EVENTOUT
-PortF,PF7,,,,TIM11_CH1,,SPI5_SCK,SAI1_MCLK_B,,UART7_TX,QUADSPI_BK1_IO2,,,,,,EVENTOUT
-PortF,PF8,,,,,,SPI5_MISO,SAI1_SCK_B,,UART7_RTS,TIM13_CH1,QUADSPI_BK1_IO0,,,,,EVENTOUT
-PortF,PF9,,,,,,SPI5_MOSI,SAI1_FS_B,,UART7_CTS,TIM14_CH1,QUADSPI_BK1_IO1,,,,,EVENTOUT
-PortF,PF10,,,,,,,,,,,,,,DCMI_D11,LCD_DE,EVENTOUT
-PortF,PF11,,,,,,SPI5_MOSI,,,,,SAI2_SD_B,,FMC_SDNRAS,DCMI_D12,,EVENTOUT
-PortF,PF12,,,,,,,,,,,,,FMC_A6,,,EVENTOUT
-PortF,PF13,,,,,I2C4_SMBA,,,,,,,,FMC_A7,,,EVENTOUT
-PortF,PF14,,,,,I2C4_SCL,,,,,,,,FMC_A8,,,EVENTOUT
-PortF,PF15,,,,,I2C4_SDA,,,,,,,,FMC_A9,,,EVENTOUT
-PortG,PG0,,,,,,,,,,,,,FMC_A10,,,EVENTOUT
-PortG,PG1,,,,,,,,,,,,,FMC_A11,,,EVENTOUT
-PortG,PG2,,,,,,,,,,,,,FMC_A12,,,EVENTOUT
-PortG,PG3,,,,,,,,,,,,,FMC_A13,,,EVENTOUT
-PortG,PG4,,,,,,,,,,,,,FMC_A14/FMC_BA0,,,EVENTOUT
-PortG,PG5,,,,,,,,,,,,,FMC_A15/FMC_BA1,,,EVENTOUT
-PortG,PG6,,,,,,,,,,,,,,DCMI_D12,LCD_R7,EVENTOUT
-PortG,PG7,,,,,,,,,USART6_CK,,,,FMC_INT,DCMI_D13,LCD_CLK,EVENTOUT
-PortG,PG8,,,,,,SPI6_NSS,,SPDIFRX_IN2,USART6_RTS,,,ETH_PPS_OUT,FMC_SDCLK,,,EVENTOUT
-PortG,PG9,,,,,,,,SPDIFRX_IN3,USART6_RX,QUADSPI_BK2_IO2,SAI2_FS_B,,FMC_NE2/FMC_NCE,DCMI_VSYNC,,EVENTOUT
-PortG,PG10,,,,,,,,,,LCD_G3,SAI2_SD_B,,FMC_NE3,DCMI_D2,LCD_B2,EVENTOUT
-PortG,PG11,,,,,,,,SPDIFRX_IN0,,,,ETH_MII_TX_EN/ETH_RMII_TX_EN,,DCMI_D3,LCD_B3,EVENTOUT
-PortG,PG12,,,,LPTIM1_IN1,,SPI6_MISO,,SPDIFRX_IN1,USART6_RTS,LCD_B4,,,FMC_NE4,,LCD_B1,EVENTOUT
-PortG,PG13,TRACED0,,,LPTIM1_OUT,,SPI6_SCK,,,USART6_CTS,,,ETH_MII_TXD0/ETH_RMII_TXD0,FMC_A24,,LCD_R0,EVENTOUT
-PortG,PG14,TRACED1,,,LPTIM1_ETR,,SPI6_MOSI,,,USART6_TX,QUADSPI_BK2_IO3,,ETH_MII_TXD1/ETH_RMII_TXD1,FMC_A25,,LCD_B0,EVENTOUT
-PortG,PG15,,,,,,,,,USART6_CTS,,,,FMC_SDNCAS,DCMI_D13,,EVENTOUT
-PortH,PH0,,,,,,,,,,,,,,,,EVENTOUT
-PortH,PH1,,,,,,,,,,,,,,,,EVENTOUT
-PortH,PH2,,,,LPTIM1_IN2,,,,,,QUADSPI_BK2_IO0,SAI2_SCK_B,ETH_MII_CRS,FMC_SDCKE0,,LCD_R0,EVENTOUT
-PortH,PH3,,,,,,,,,,QUADSPI_BK2_IO1,SAI2_MCK_B,ETH_MII_COL,FMC_SDNE0,,LCD_R1,EVENTOUT
-PortH,PH4,,,,,I2C2_SCL,,,,,,OTG_HS_ULPI_NXT,,,,,EVENTOUT
-PortH,PH5,,,,,I2C2_SDA,SPI5_NSS,,,,,,,FMC_SDNWE,,,EVENTOUT
-PortH,PH6,,,,,I2C2_SMBA,SPI5_SCK,,,,TIM12_CH1,,ETH_MII_RXD2,FMC_SDNE1,DCMI_D8,,EVENTOUT
-PortH,PH7,,,,,I2C3_SCL,SPI5_MISO,,,,,,ETH_MII_RXD3,FMC_SDCKE1,DCMI_D9,,EVENTOUT
-PortH,PH8,,,,,I2C3_SDA,,,,,,,,FMC_D16,DCMI_HSYNC,LCD_R2,EVENTOUT
-PortH,PH9,,,,,I2C3_SMBA,,,,,TIM12_CH2,,,FMC_D17,DCMI_D0,LCD_R3,EVENTOUT
-PortH,PH10,,,TIM5_CH1,,I2C4_SMBA,,,,,,,,FMC_D18,DCMI_D1,LCD_R4,EVENTOUT
-PortH,PH11,,,TIM5_CH2,,I2C4_SCL,,,,,,,,FMC_D19,DCMI_D2,LCD_R5,EVENTOUT
-PortH,PH12,,,TIM5_CH3,,I2C4_SDA,,,,,,,,FMC_D20,DCMI_D3,LCD_R6,EVENTOUT
-PortH,PH13,,,,TIM8_CH1N,,,,,,CAN1_TX,,,FMC_D21,,LCD_G2,EVENTOUT
-PortH,PH14,,,,TIM8_CH2N,,,,,,,,,FMC_D22,DCMI_D4,LCD_G3,EVENTOUT
-PortH,PH15,,,,TIM8_CH3N,,,,,,,,,FMC_D23,DCMI_D11,LCD_G4,EVENTOUT
-PortI,PI0,,,TIM5_CH4,,,SPI2_NSS/I2S2_WS,,,,,,,FMC_D24,DCMI_D13,LCD_G5,EVENTOUT
-PortI,PI1,,,,TIM8_BKIN2,,SPI2_SCK/I2S2_CK,,,,,,,FMC_D25,DCMI_D8,LCD_G6,EVENTOUT
-PortI,PI2,,,,TIM8_CH4,,SPI2_MISO,,,,,,,FMC_D26,DCMI_D9,LCD_G7,EVENTOUT
-PortI,PI3,,,,TIM8_ETR,,SPI2_MOSI/I2S2_SD,,,,,,,FMC_D27,DCMI_D10,,EVENTOUT
-PortI,PI4,,,,TIM8_BKIN,,,,,,,SAI2_MCK_A,,FMC_NBL2,DCMI_D5,LCD_B4,EVENTOUT
-PortI,PI5,,,,TIM8_CH1,,,,,,,SAI2_SCK_A,,FMC_NBL3,DCMI_VSYNC,LCD_B5,EVENTOUT
-PortI,PI6,,,,TIM8_CH2,,,,,,,SAI2_SD_A,,FMC_D28,DCMI_D6,LCD_B6,EVENTOUT
-PortI,PI7,,,,TIM8_CH3,,,,,,,SAI2_FS_A,,FMC_D29,DCMI_D7,LCD_B7,EVENTOUT
-PortI,PI8,,,,,,,,,,,,,,,,EVENTOUT
-PortI,PI9,,,,,,,,,,CAN1_RX,,,FMC_D30,,LCD_VSYNC,EVENTOUT
-PortI,PI10,,,,,,,,,,,,ETH_MII_RX_ER,FMC_D31,,LCD_HSYNC,EVENTOUT
-PortI,PI11,,,,,,,,,,,OTG_HS_ULPI_DIR,,,,,EVENTOUT
-PortI,PI12,,,,,,,,,,,,,,,LCD_HSYNC,EVENTOUT
-PortI,PI13,,,,,,,,,,,,,,,LCD_VSYNC,EVENTOUT
-PortI,PI14,,,,,,,,,,,,,,,LCD_CLK,EVENTOUT
-PortI,PI15,,,,,,,,,,,,,,,LCD_R0,EVENTOUT
-PortJ,PJ0,,,,,,,,,,,,,,,LCD_R1,EVENTOUT
-PortJ,PJ1,,,,,,,,,,,,,,,LCD_R2,EVENTOUT
-PortJ,PJ2,,,,,,,,,,,,,,,LCD_R3,EVENTOUT
-PortJ,PJ3,,,,,,,,,,,,,,,LCD_R4,EVENTOUT
-PortJ,PJ4,,,,,,,,,,,,,,,LCD_R5,EVENTOUT
-PortJ,PJ5,,,,,,,,,,,,,,,LCD_R6,EVENTOUT
-PortJ,PJ6,,,,,,,,,,,,,,,LCD_R7,EVENTOUT
-PortJ,PJ7,,,,,,,,,,,,,,,LCD_G0,EVENTOUT
-PortJ,PJ8,,,,,,,,,,,,,,,LCD_G1,EVENTOUT
-PortJ,PJ9,,,,,,,,,,,,,,,LCD_G2,EVENTOUT
-PortJ,PJ10,,,,,,,,,,,,,,,LCD_G3,EVENTOUT
-PortJ,PJ11,,,,,,,,,,,,,,,LCD_G4,EVENTOUT
-PortJ,PJ12,,,,,,,,,,,,,,,LCD_B0,EVENTOUT
-PortJ,PJ13,,,,,,,,,,,,,,,LCD_B1,EVENTOUT
-PortJ,PJ14,,,,,,,,,,,,,,,LCD_B2,EVENTOUT
-PortJ,PJ15,,,,,,,,,,,,,,,LCD_B3,EVENTOUT
-PortK,PK0,,,,,,,,,,,,,,,LCD_G5,EVENTOUT
-PortK,PK1,,,,,,,,,,,,,,,LCD_G6,EVENTOUT
-PortK,PK2,,,,,,,,,,,,,,,LCD_G7,EVENTOUT
-PortK,PK3,,,,,,,,,,,,,,,LCD_B4,EVENTOUT
-PortK,PK4,,,,,,,,,,,,,,,LCD_B5,EVENTOUT
-PortK,PK5,,,,,,,,,,,,,,,LCD_B6,EVENTOUT
-PortK,PK6,,,,,,,,,,,,,,,LCD_B7,EVENTOUT
-PortK,PK7,,,,,,,,,,,,,,,LCD_DE,EVENTOUT
-
diff --git a/stmhal/can.c b/stmhal/can.c
index 24ad9b5a7..c2cb0bd24 100644
--- a/stmhal/can.c
+++ b/stmhal/can.c
@@ -632,8 +632,8 @@ STATIC mp_obj_t pyb_can_setfilter(mp_uint_t n_args, const mp_obj_t *pos_args, mp
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);
- mp_uint_t len;
- mp_uint_t rtr_len;
+ size_t len;
+ size_t rtr_len;
mp_uint_t rtr_masks[4] = {0, 0, 0, 0};
mp_obj_t *rtr_flags;
mp_obj_t *params;
@@ -778,29 +778,29 @@ STATIC mp_obj_t pyb_can_rxcallback(mp_obj_t self_in, mp_obj_t fifo_in, mp_obj_t
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_can_rxcallback_obj, pyb_can_rxcallback);
-STATIC const mp_map_elem_t pyb_can_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_can_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_can_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_can_deinit_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_can_any_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_can_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_can_recv_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_initfilterbanks), (mp_obj_t)&pyb_can_initfilterbanks_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setfilter), (mp_obj_t)&pyb_can_setfilter_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_clearfilter), (mp_obj_t)&pyb_can_clearfilter_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_rxcallback), (mp_obj_t)&pyb_can_rxcallback_obj },
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_can_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_can_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_can_any_obj) },
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_can_send_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_can_recv_obj) },
+ { MP_ROM_QSTR(MP_QSTR_initfilterbanks), MP_ROM_PTR(&pyb_can_initfilterbanks_obj) },
+ { MP_ROM_QSTR(MP_QSTR_setfilter), MP_ROM_PTR(&pyb_can_setfilter_obj) },
+ { MP_ROM_QSTR(MP_QSTR_clearfilter), MP_ROM_PTR(&pyb_can_clearfilter_obj) },
+ { MP_ROM_QSTR(MP_QSTR_rxcallback), MP_ROM_PTR(&pyb_can_rxcallback_obj) },
// class constants
// Note: we use the ST constants >> 4 so they fit in a small-int. The
// right-shift is undone when the constants are used in the init function.
- { MP_OBJ_NEW_QSTR(MP_QSTR_NORMAL), MP_OBJ_NEW_SMALL_INT(CAN_MODE_NORMAL >> 4) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LOOPBACK), MP_OBJ_NEW_SMALL_INT(CAN_MODE_LOOPBACK >> 4) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SILENT), MP_OBJ_NEW_SMALL_INT(CAN_MODE_SILENT >> 4) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_OBJ_NEW_SMALL_INT(CAN_MODE_SILENT_LOOPBACK >> 4) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_MASK16), MP_OBJ_NEW_SMALL_INT(MASK16) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LIST16), MP_OBJ_NEW_SMALL_INT(LIST16) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_MASK32), MP_OBJ_NEW_SMALL_INT(MASK32) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LIST32), MP_OBJ_NEW_SMALL_INT(LIST32) },
+ { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(CAN_MODE_NORMAL >> 4) },
+ { MP_ROM_QSTR(MP_QSTR_LOOPBACK), MP_ROM_INT(CAN_MODE_LOOPBACK >> 4) },
+ { MP_ROM_QSTR(MP_QSTR_SILENT), MP_ROM_INT(CAN_MODE_SILENT >> 4) },
+ { MP_ROM_QSTR(MP_QSTR_SILENT_LOOPBACK), MP_ROM_INT(CAN_MODE_SILENT_LOOPBACK >> 4) },
+ { MP_ROM_QSTR(MP_QSTR_MASK16), MP_ROM_INT(MASK16) },
+ { MP_ROM_QSTR(MP_QSTR_LIST16), MP_ROM_INT(LIST16) },
+ { MP_ROM_QSTR(MP_QSTR_MASK32), MP_ROM_INT(MASK32) },
+ { MP_ROM_QSTR(MP_QSTR_LIST32), MP_ROM_INT(LIST32) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_can_locals_dict, pyb_can_locals_dict_table);
@@ -866,6 +866,7 @@ void can_rx_irq_handler(uint can_id, uint fifo_id) {
}
if (callback != mp_const_none) {
+ mp_sched_lock();
gc_lock();
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
@@ -878,6 +879,7 @@ void can_rx_irq_handler(uint can_id, uint fifo_id) {
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
+ mp_sched_unlock();
}
}
diff --git a/stmhal/dac.c b/stmhal/dac.c
index 48c0ce8bd..6524c6840 100644
--- a/stmhal/dac.c
+++ b/stmhal/dac.c
@@ -481,20 +481,20 @@ mp_obj_t pyb_dac_write_timed(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_dac_write_timed_obj, 1, pyb_dac_write_timed);
#endif
-STATIC const mp_map_elem_t pyb_dac_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_dac_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_dac_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_dac_deinit_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&pyb_dac_write_obj },
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_dac_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_dac_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_dac_write_obj) },
#if defined(TIM6)
- { MP_OBJ_NEW_QSTR(MP_QSTR_noise), (mp_obj_t)&pyb_dac_noise_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_triangle), (mp_obj_t)&pyb_dac_triangle_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_write_timed), (mp_obj_t)&pyb_dac_write_timed_obj },
+ { MP_ROM_QSTR(MP_QSTR_noise), MP_ROM_PTR(&pyb_dac_noise_obj) },
+ { MP_ROM_QSTR(MP_QSTR_triangle), MP_ROM_PTR(&pyb_dac_triangle_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write_timed), MP_ROM_PTR(&pyb_dac_write_timed_obj) },
#endif
// class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_NORMAL), MP_OBJ_NEW_SMALL_INT(DMA_NORMAL) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_CIRCULAR), MP_OBJ_NEW_SMALL_INT(DMA_CIRCULAR) },
+ { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(DMA_NORMAL) },
+ { MP_ROM_QSTR(MP_QSTR_CIRCULAR), MP_ROM_INT(DMA_CIRCULAR) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_dac_locals_dict, pyb_dac_locals_dict_table);
@@ -503,7 +503,7 @@ const mp_obj_type_t pyb_dac_type = {
{ &mp_type_type },
.name = MP_QSTR_DAC,
.make_new = pyb_dac_make_new,
- .locals_dict = (mp_obj_t)&pyb_dac_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_dac_locals_dict,
};
#endif // MICROPY_HW_ENABLE_DAC
diff --git a/stmhal/dma.c b/stmhal/dma.c
index cf861fe12..04c874dc2 100644
--- a/stmhal/dma.c
+++ b/stmhal/dma.c
@@ -186,6 +186,9 @@ const dma_descr_t dma_I2C_1_TX = { DMA1_Stream6, DMA_CHANNEL_1, DMA_MEMORY_TO_PE
*/
// DMA2 streams
+#if defined(MCU_SERIES_F7) && defined(SDMMC2) && MICROPY_HW_HAS_SDCARD
+const dma_descr_t dma_SDMMC_2_RX= { DMA2_Stream0, DMA_CHANNEL_11, DMA_PERIPH_TO_MEMORY, dma_id_8, &dma_init_struct_sdio };
+#endif
const dma_descr_t dma_SPI_1_RX = { DMA2_Stream2, DMA_CHANNEL_3, DMA_PERIPH_TO_MEMORY, dma_id_10, &dma_init_struct_spi_i2c };
const dma_descr_t dma_SPI_5_RX = { DMA2_Stream3, DMA_CHANNEL_2, DMA_PERIPH_TO_MEMORY, dma_id_11, &dma_init_struct_spi_i2c };
#if defined(MICROPY_HW_HAS_SDCARD) && MICROPY_HW_HAS_SDCARD
@@ -196,6 +199,9 @@ const dma_descr_t dma_SPI_5_TX = { DMA2_Stream4, DMA_CHANNEL_2, DMA_MEMORY_TO_PE
const dma_descr_t dma_SPI_4_TX = { DMA2_Stream4, DMA_CHANNEL_5, DMA_MEMORY_TO_PERIPH, dma_id_12, &dma_init_struct_spi_i2c };
const dma_descr_t dma_SPI_6_TX = { DMA2_Stream5, DMA_CHANNEL_1, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_spi_i2c };
const dma_descr_t dma_SPI_1_TX = { DMA2_Stream5, DMA_CHANNEL_3, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_spi_i2c };
+#if defined(MCU_SERIES_F7) && defined(SDMMC2) && MICROPY_HW_HAS_SDCARD
+const dma_descr_t dma_SDMMC_2_TX= { DMA2_Stream5, DMA_CHANNEL_11, DMA_MEMORY_TO_PERIPH, dma_id_13, &dma_init_struct_sdio };
+#endif
const dma_descr_t dma_SPI_6_RX = { DMA2_Stream6, DMA_CHANNEL_1, DMA_PERIPH_TO_MEMORY, dma_id_14, &dma_init_struct_spi_i2c };
#if defined(MICROPY_HW_HAS_SDCARD) && MICROPY_HW_HAS_SDCARD
const dma_descr_t dma_SDIO_0_TX= { DMA2_Stream6, DMA_CHANNEL_4, DMA_MEMORY_TO_PERIPH, dma_id_14, &dma_init_struct_sdio };
@@ -443,7 +449,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void *data){
} else {
// only necessary initialization
dma->State = HAL_DMA_STATE_READY;
-#if defined(MCU_SERIES_F4)
+#if defined(MCU_SERIES_F4) || defined(MCU_SERIES_F7)
// calculate DMA base address and bitshift to be used in IRQ handler
extern uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
DMA_CalcBaseAndBitshift(dma);
diff --git a/stmhal/dma.h b/stmhal/dma.h
index d9d771270..57b8f866d 100644
--- a/stmhal/dma.h
+++ b/stmhal/dma.h
@@ -45,6 +45,7 @@ extern const dma_descr_t dma_DAC_2_TX;
extern const dma_descr_t dma_SPI_3_TX;
extern const dma_descr_t dma_I2C_1_TX;
extern const dma_descr_t dma_I2C_2_TX;
+extern const dma_descr_t dma_SDMMC_2_RX;
extern const dma_descr_t dma_SPI_1_RX;
extern const dma_descr_t dma_SPI_5_RX;
extern const dma_descr_t dma_SDIO_0_RX;
@@ -53,6 +54,7 @@ extern const dma_descr_t dma_SPI_5_TX;
extern const dma_descr_t dma_SPI_4_TX;
extern const dma_descr_t dma_SPI_6_TX;
extern const dma_descr_t dma_SPI_1_TX;
+extern const dma_descr_t dma_SDMMC_2_TX;
extern const dma_descr_t dma_SPI_6_RX;
extern const dma_descr_t dma_SDIO_0_TX;
diff --git a/stmhal/extint.c b/stmhal/extint.c
index dacf8dd56..642ecfd85 100644
--- a/stmhal/extint.c
+++ b/stmhal/extint.c
@@ -28,7 +28,6 @@
#include <stddef.h>
#include <string.h>
-#include "py/nlr.h"
#include "py/runtime.h"
#include "py/gc.h"
#include "py/mphal.h"
@@ -369,23 +368,23 @@ STATIC void extint_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print
mp_printf(print, "<ExtInt line=%u>", self->line);
}
-STATIC const mp_map_elem_t extint_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_line), (mp_obj_t)&extint_obj_line_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&extint_obj_enable_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&extint_obj_disable_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_swint), (mp_obj_t)&extint_obj_swint_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_regs), (mp_obj_t)&extint_regs_obj },
+STATIC const mp_rom_map_elem_t extint_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&extint_obj_line_obj) },
+ { MP_ROM_QSTR(MP_QSTR_enable), MP_ROM_PTR(&extint_obj_enable_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disable), MP_ROM_PTR(&extint_obj_disable_obj) },
+ { MP_ROM_QSTR(MP_QSTR_swint), MP_ROM_PTR(&extint_obj_swint_obj) },
+ { MP_ROM_QSTR(MP_QSTR_regs), MP_ROM_PTR(&extint_regs_obj) },
// class constants
/// \constant IRQ_RISING - interrupt on a rising edge
/// \constant IRQ_FALLING - interrupt on a falling edge
/// \constant IRQ_RISING_FALLING - interrupt on a rising or falling edge
- { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_FALLING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING_FALLING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_EVT_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_RISING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_EVT_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_FALLING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_EVT_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_RISING_FALLING) },
+ { MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_MODE_IT_RISING) },
+ { MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_MODE_IT_FALLING) },
+ { MP_ROM_QSTR(MP_QSTR_IRQ_RISING_FALLING), MP_ROM_INT(GPIO_MODE_IT_RISING_FALLING) },
+ { MP_ROM_QSTR(MP_QSTR_EVT_RISING), MP_ROM_INT(GPIO_MODE_EVT_RISING) },
+ { MP_ROM_QSTR(MP_QSTR_EVT_FALLING), MP_ROM_INT(GPIO_MODE_EVT_FALLING) },
+ { MP_ROM_QSTR(MP_QSTR_EVT_RISING_FALLING), MP_ROM_INT(GPIO_MODE_EVT_RISING_FALLING) },
};
STATIC MP_DEFINE_CONST_DICT(extint_locals_dict, extint_locals_dict_table);
@@ -395,7 +394,7 @@ const mp_obj_type_t extint_type = {
.name = MP_QSTR_ExtInt,
.print = extint_obj_print,
.make_new = extint_make_new,
- .locals_dict = (mp_obj_t)&extint_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&extint_locals_dict,
};
void extint_init0(void) {
@@ -412,6 +411,7 @@ void Handle_EXTI_Irq(uint32_t line) {
if (line < EXTI_NUM_VECTORS) {
mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[line];
if (*cb != mp_const_none) {
+ mp_sched_lock();
// When executing code within a handler we must lock the GC to prevent
// any memory allocations. We must also catch any exceptions.
gc_lock();
@@ -427,6 +427,7 @@ void Handle_EXTI_Irq(uint32_t line) {
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
+ mp_sched_unlock();
}
}
}
diff --git a/stmhal/fatfs_port.c b/stmhal/fatfs_port.c
index 421ceddba..17ec3f726 100644
--- a/stmhal/fatfs_port.c
+++ b/stmhal/fatfs_port.c
@@ -24,23 +24,10 @@
* THE SOFTWARE.
*/
-#include "py/mphal.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h" /* FatFs lower layer API */
-#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
+#include "lib/oofatfs/ff.h"
#include "rtc.h"
-const PARTITION VolToPart[MICROPY_FATFS_VOLUMES] = {
- {0, 1}, // Logical drive 0 ==> Physical drive 0, 1st partition
- {1, 0}, // Logical drive 1 ==> Physical drive 1 (auto detection)
- {2, 0}, // Logical drive 2 ==> Physical drive 2 (auto detection)
- {3, 0}, // Logical drive 3 ==> Physical drive 3 (auto detection)
- /*
- {0, 2}, // Logical drive 2 ==> Physical drive 0, 2nd partition
- {0, 3}, // Logical drive 3 ==> Physical drive 0, 3rd partition
- */
-};
-
DWORD get_fattime(void) {
rtc_init_finalise();
RTC_TimeTypeDef time;
diff --git a/stmhal/gccollect.c b/stmhal/gccollect.c
index de76b71ac..d7223dedc 100644
--- a/stmhal/gccollect.c
+++ b/stmhal/gccollect.c
@@ -27,8 +27,10 @@
#include <stdio.h>
#include <stdint.h>
+#include "py/mpstate.h"
#include "py/obj.h"
#include "py/gc.h"
+#include "py/mpthread.h"
#include "gccollect.h"
#include "systick.h"
@@ -37,7 +39,7 @@ mp_uint_t gc_helper_get_regs_and_sp(mp_uint_t *regs);
void gc_collect(void) {
// get current time, in case we want to time the GC
#if 0
- uint32_t start = sys_tick_get_microseconds();
+ uint32_t start = mp_hal_ticks_us();
#endif
// start the GC
@@ -48,14 +50,23 @@ void gc_collect(void) {
mp_uint_t sp = gc_helper_get_regs_and_sp(regs);
// trace the stack, including the registers (since they live on the stack in this function)
+ #if MICROPY_PY_THREAD
+ gc_collect_root((void**)sp, ((uint32_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t));
+ #else
gc_collect_root((void**)sp, ((uint32_t)&_ram_end - sp) / sizeof(uint32_t));
+ #endif
+
+ // trace root pointers from any threads
+ #if MICROPY_PY_THREAD
+ mp_thread_gc_others();
+ #endif
// end the GC
gc_collect_end();
#if 0
// print GC info
- uint32_t ticks = sys_tick_get_microseconds() - start;
+ uint32_t ticks = mp_hal_ticks_us() - start;
gc_info_t info;
gc_info(&info);
printf("GC@%lu %lums\n", start, ticks);
diff --git a/stmhal/hal/f7/src/stm32f7xx_hal_dma.c b/stmhal/hal/f7/src/stm32f7xx_hal_dma.c
index 92f0d975c..df915ce52 100644
--- a/stmhal/hal/f7/src/stm32f7xx_hal_dma.c
+++ b/stmhal/hal/f7/src/stm32f7xx_hal_dma.c
@@ -149,7 +149,7 @@ typedef struct
* @{
*/
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
-static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
+uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
static HAL_StatusTypeDef DMA_CheckFifoParam(DMA_HandleTypeDef *hdma);
/**
@@ -1187,7 +1187,7 @@ static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t
* the configuration information for the specified DMA Stream.
* @retval Stream base address
*/
-static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
+uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
{
uint32_t stream_number = (((uint32_t)hdma->Instance & 0xFFU) - 16U) / 24U;
diff --git a/stmhal/help.c b/stmhal/help.c
index 21e81ebc0..83ef7e596 100644
--- a/stmhal/help.c
+++ b/stmhal/help.c
@@ -24,11 +24,9 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
+#include "py/builtin.h"
-#include "lib/utils/pyhelp.h"
-
-STATIC const char *help_text =
+const char *stmhal_help_text =
"Welcome to MicroPython!\n"
"\n"
"For online help please visit http://micropython.org/help/.\n"
@@ -69,18 +67,5 @@ STATIC const char *help_text =
" CTRL-E -- on a blank line, enter paste mode\n"
"\n"
"For further help on a specific object, type help(obj)\n"
+"For a list of available modules, type help('modules')\n"
;
-
-STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
- if (n_args == 0) {
- // print a general help message
- printf("%s", help_text);
-
- } else {
- // try to print something sensible about the given object
- pyhelp_print_obj(args[0]);
- }
-
- return mp_const_none;
-}
-MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, pyb_help);
diff --git a/stmhal/i2c.c b/stmhal/i2c.c
index 29c350d22..4a792d163 100644
--- a/stmhal/i2c.c
+++ b/stmhal/i2c.c
@@ -37,14 +37,6 @@
#include "dma.h"
#include "i2c.h"
-#if !defined(MICROPY_HW_I2C_BAUDRATE_DEFAULT)
-#define MICROPY_HW_I2C_BAUDRATE_DEFAULT 400000
-#endif
-
-#if !defined(MICROPY_HW_I2C_BAUDRATE_MAX)
-#define MICROPY_HW_I2C_BAUDRATE_MAX 400000
-#endif
-
/// \moduleref pyb
/// \class I2C - a two-wire serial protocol
///
@@ -134,10 +126,42 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = {
#endif
};
-#if defined(MICROPY_HW_I2C_BAUDRATE_TIMING)
+#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_L4)
+
// The STM32F0, F3, F7 and L4 use a TIMINGR register rather than ClockSpeed and
// DutyCycle.
+#if defined(STM32F746xx)
+
+// The value 0x40912732 was obtained from the DISCOVERY_I2Cx_TIMING constant
+// defined in the STM32F7Cube file Drivers/BSP/STM32F746G-Discovery/stm32f7456g_discovery.h
+#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x40912732}}
+#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (100000)
+#define MICROPY_HW_I2C_BAUDRATE_MAX (100000)
+
+#elif defined(STM32F767xx) || defined(STM32F769xx)
+
+// These timing values are for f_I2CCLK=54MHz and are only approximate
+#define MICROPY_HW_I2C_BAUDRATE_TIMING { \
+ {100000, 0xb0420f13}, \
+ {400000, 0x70330309}, \
+ {1000000, 0x50100103}, \
+ }
+#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (400000)
+#define MICROPY_HW_I2C_BAUDRATE_MAX (1000000)
+
+#elif defined(MCU_SERIES_L4)
+
+// The value 0x90112626 was obtained from the DISCOVERY_I2C1_TIMING constant
+// defined in the STM32L4Cube file Drivers/BSP/STM32L476G-Discovery/stm32l476g_discovery.h
+#define MICROPY_HW_I2C_BAUDRATE_TIMING {{100000, 0x90112626}}
+#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (100000)
+#define MICROPY_HW_I2C_BAUDRATE_MAX (100000)
+
+#else
+#error "no I2C timings for this MCU"
+#endif
+
STATIC const struct {
uint32_t baudrate;
uint32_t timing;
@@ -167,6 +191,9 @@ uint32_t i2c_get_baudrate(I2C_InitTypeDef *init) {
#else
+#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (400000)
+#define MICROPY_HW_I2C_BAUDRATE_MAX (400000)
+
STATIC void i2c_set_baudrate(I2C_InitTypeDef *init, uint32_t baudrate) {
init->ClockSpeed = baudrate;
init->DutyCycle = I2C_DUTYCYCLE_16_9;
@@ -176,7 +203,7 @@ uint32_t i2c_get_baudrate(I2C_InitTypeDef *init) {
return init->ClockSpeed;
}
-#endif // MICROPY_HW_I2C_BAUDRATE_TIMING
+#endif
void i2c_init0(void) {
// reset the I2C1 handles
@@ -346,7 +373,7 @@ STATIC void i2c_reset_after_error(I2C_HandleTypeDef *i2c) {
// stop bit was generated and bus is back to normal
return;
}
- HAL_Delay(1);
+ mp_hal_delay_ms(1);
}
// bus was/is busy, need to reset the peripheral to get it to work again
i2c_deinit(i2c);
@@ -733,12 +760,14 @@ STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
if (!use_dma) {
status = HAL_I2C_Master_Transmit(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len, args[2].u_int);
} else {
+ MP_HAL_CLEAN_DCACHE(bufinfo.buf, bufinfo.len);
status = HAL_I2C_Master_Transmit_DMA(self->i2c, i2c_addr, bufinfo.buf, bufinfo.len);
}
} else {
if (!use_dma) {
status = HAL_I2C_Slave_Transmit(self->i2c, bufinfo.buf, bufinfo.len, args[2].u_int);
} else {
+ MP_HAL_CLEAN_DCACHE(bufinfo.buf, bufinfo.len);
status = HAL_I2C_Slave_Transmit_DMA(self->i2c, bufinfo.buf, bufinfo.len);
}
}
@@ -807,12 +836,14 @@ STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
if (!use_dma) {
status = HAL_I2C_Master_Receive(self->i2c, i2c_addr, (uint8_t*)vstr.buf, vstr.len, args[2].u_int);
} else {
+ MP_HAL_CLEANINVALIDATE_DCACHE(vstr.buf, vstr.len);
status = HAL_I2C_Master_Receive_DMA(self->i2c, i2c_addr, (uint8_t*)vstr.buf, vstr.len);
}
} else {
if (!use_dma) {
status = HAL_I2C_Slave_Receive(self->i2c, (uint8_t*)vstr.buf, vstr.len, args[2].u_int);
} else {
+ MP_HAL_CLEANINVALIDATE_DCACHE(vstr.buf, vstr.len);
status = HAL_I2C_Slave_Receive_DMA(self->i2c, (uint8_t*)vstr.buf, vstr.len);
}
}
@@ -893,6 +924,7 @@ STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
dma_init(&rx_dma, self->rx_dma_descr, self->i2c);
self->i2c->hdmatx = NULL;
self->i2c->hdmarx = &rx_dma;
+ MP_HAL_CLEANINVALIDATE_DCACHE(vstr.buf, vstr.len);
status = HAL_I2C_Mem_Read_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, (uint8_t*)vstr.buf, vstr.len);
if (status == HAL_OK) {
status = i2c_wait_dma_finished(self->i2c, args[3].u_int);
@@ -961,6 +993,7 @@ STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp
dma_init(&tx_dma, self->tx_dma_descr, self->i2c);
self->i2c->hdmatx = &tx_dma;
self->i2c->hdmarx = NULL;
+ MP_HAL_CLEAN_DCACHE(bufinfo.buf, bufinfo.len);
status = HAL_I2C_Mem_Write_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len);
if (status == HAL_OK) {
status = i2c_wait_dma_finished(self->i2c, args[3].u_int);
@@ -977,22 +1010,22 @@ STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_write_obj, 1, pyb_i2c_mem_write);
-STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_i2c_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_i2c_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_i2c_deinit_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_is_ready), (mp_obj_t)&pyb_i2c_is_ready_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&pyb_i2c_scan_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_i2c_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_i2c_recv_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mem_read), (mp_obj_t)&pyb_i2c_mem_read_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mem_write), (mp_obj_t)&pyb_i2c_mem_write_obj },
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_i2c_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_i2c_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR_is_ready), MP_ROM_PTR(&pyb_i2c_is_ready_obj) },
+ { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&pyb_i2c_scan_obj) },
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_i2c_send_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_i2c_recv_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mem_read), MP_ROM_PTR(&pyb_i2c_mem_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mem_write), MP_ROM_PTR(&pyb_i2c_mem_write_obj) },
// class constants
/// \constant MASTER - for initialising the bus to master mode
/// \constant SLAVE - for initialising the bus to slave mode
- { MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(PYB_I2C_MASTER) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SLAVE), MP_OBJ_NEW_SMALL_INT(PYB_I2C_SLAVE) },
+ { MP_ROM_QSTR(MP_QSTR_MASTER), MP_ROM_INT(PYB_I2C_MASTER) },
+ { MP_ROM_QSTR(MP_QSTR_SLAVE), MP_ROM_INT(PYB_I2C_SLAVE) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table);
@@ -1002,5 +1035,5 @@ const mp_obj_type_t pyb_i2c_type = {
.name = MP_QSTR_I2C,
.print = pyb_i2c_print,
.make_new = pyb_i2c_make_new,
- .locals_dict = (mp_obj_t)&pyb_i2c_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_i2c_locals_dict,
};
diff --git a/stmhal/import.c b/stmhal/import.c
deleted file mode 100644
index 1edbe2caa..000000000
--- a/stmhal/import.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This file is part of the Micro Python project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <stdio.h>
-
-#include "py/lexer.h"
-#include "lib/fatfs/ff.h"
-
-mp_import_stat_t fat_vfs_import_stat(const char *path);
-
-mp_import_stat_t mp_import_stat(const char *path) {
- return fat_vfs_import_stat(path);
-}
diff --git a/stmhal/irq.h b/stmhal/irq.h
index bb1749e03..a56f23652 100644
--- a/stmhal/irq.h
+++ b/stmhal/irq.h
@@ -133,10 +133,10 @@ MP_DECLARE_CONST_FUN_OBJ_0(pyb_irq_stats_obj);
#define IRQ_SUBPRI_CAN 0
// Interrupt priority for non-special timers.
-#define IRQ_PRI_TIMX 14
+#define IRQ_PRI_TIMX 13
#define IRQ_SUBPRI_TIMX 0
-#define IRQ_PRI_EXTINT 15
+#define IRQ_PRI_EXTINT 14
#define IRQ_SUBPRI_EXTINT 0
// PENDSV should be at the lowst priority so that other interrupts complete
diff --git a/stmhal/lcd.c b/stmhal/lcd.c
index e73b6e16d..da0974460 100644
--- a/stmhal/lcd.c
+++ b/stmhal/lcd.c
@@ -274,11 +274,11 @@ STATIC mp_obj_t pyb_lcd_make_new(const mp_obj_type_t *type, size_t n_args, size_
mp_hal_pin_output(lcd->pin_bl);
// init the LCD
- HAL_Delay(1); // wait a bit
+ mp_hal_delay_ms(1); // wait a bit
mp_hal_pin_low(lcd->pin_rst); // RST=0; reset
- HAL_Delay(1); // wait for reset; 2us min
+ mp_hal_delay_ms(1); // wait for reset; 2us min
mp_hal_pin_high(lcd->pin_rst); // RST=1; enable
- HAL_Delay(1); // wait for reset; 2us min
+ mp_hal_delay_ms(1); // wait for reset; 2us min
lcd_out(lcd, LCD_INSTR, 0xa0); // ADC select, normal
lcd_out(lcd, LCD_INSTR, 0xc0); // common output mode select, normal (this flips the display)
lcd_out(lcd, LCD_INSTR, 0xa2); // LCD bias set, 1/9 bias
@@ -373,7 +373,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_lcd_light_obj, pyb_lcd_light);
/// Write the string `str` to the screen. It will appear immediately.
STATIC mp_obj_t pyb_lcd_write(mp_obj_t self_in, mp_obj_t str) {
pyb_lcd_obj_t *self = self_in;
- mp_uint_t len;
+ size_t len;
const char *data = mp_obj_str_get_data(str, &len);
lcd_write_strn(self, data, len);
return mp_const_none;
@@ -445,7 +445,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_lcd_pixel_obj, 4, 4, pyb_lcd_pixe
STATIC mp_obj_t pyb_lcd_text(mp_uint_t n_args, const mp_obj_t *args) {
// extract arguments
pyb_lcd_obj_t *self = args[0];
- mp_uint_t len;
+ size_t len;
const char *data = mp_obj_str_get_data(args[1], &len);
int x0 = mp_obj_get_int(args[2]);
int y0 = mp_obj_get_int(args[3]);
@@ -504,17 +504,17 @@ STATIC mp_obj_t pyb_lcd_show(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_lcd_show_obj, pyb_lcd_show);
-STATIC const mp_map_elem_t pyb_lcd_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_lcd_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_command), (mp_obj_t)&pyb_lcd_command_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_contrast), (mp_obj_t)&pyb_lcd_contrast_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_light), (mp_obj_t)&pyb_lcd_light_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&pyb_lcd_write_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_fill), (mp_obj_t)&pyb_lcd_fill_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_get), (mp_obj_t)&pyb_lcd_get_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_pixel), (mp_obj_t)&pyb_lcd_pixel_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_text), (mp_obj_t)&pyb_lcd_text_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_show), (mp_obj_t)&pyb_lcd_show_obj },
+ { MP_ROM_QSTR(MP_QSTR_command), MP_ROM_PTR(&pyb_lcd_command_obj) },
+ { MP_ROM_QSTR(MP_QSTR_contrast), MP_ROM_PTR(&pyb_lcd_contrast_obj) },
+ { MP_ROM_QSTR(MP_QSTR_light), MP_ROM_PTR(&pyb_lcd_light_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_lcd_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&pyb_lcd_fill_obj) },
+ { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&pyb_lcd_get_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&pyb_lcd_pixel_obj) },
+ { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&pyb_lcd_text_obj) },
+ { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&pyb_lcd_show_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_lcd_locals_dict, pyb_lcd_locals_dict_table);
@@ -523,7 +523,7 @@ const mp_obj_type_t pyb_lcd_type = {
{ &mp_type_type },
.name = MP_QSTR_LCD,
.make_new = pyb_lcd_make_new,
- .locals_dict = (mp_obj_t)&pyb_lcd_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_lcd_locals_dict,
};
#endif // MICROPY_HW_HAS_LCD
diff --git a/stmhal/led.c b/stmhal/led.c
index 357aed407..466514684 100644
--- a/stmhal/led.c
+++ b/stmhal/led.c
@@ -275,7 +275,7 @@ void led_debug(int n, int delay) {
led_state(2, n & 2);
led_state(3, n & 4);
led_state(4, n & 8);
- HAL_Delay(delay);
+ mp_hal_delay_ms(delay);
}
/******************************************************************************/
@@ -349,11 +349,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(led_obj_intensity_obj, 1, 2, led_obj_intensity);
-STATIC const mp_map_elem_t led_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&led_obj_on_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&led_obj_off_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&led_obj_toggle_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_intensity), (mp_obj_t)&led_obj_intensity_obj },
+STATIC const mp_rom_map_elem_t led_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&led_obj_on_obj) },
+ { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&led_obj_off_obj) },
+ { MP_ROM_QSTR(MP_QSTR_toggle), MP_ROM_PTR(&led_obj_toggle_obj) },
+ { MP_ROM_QSTR(MP_QSTR_intensity), MP_ROM_PTR(&led_obj_intensity_obj) },
};
STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);
@@ -363,7 +363,7 @@ const mp_obj_type_t pyb_led_type = {
.name = MP_QSTR_LED,
.print = led_obj_print,
.make_new = led_obj_make_new,
- .locals_dict = (mp_obj_t)&led_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&led_locals_dict,
};
#else
diff --git a/stmhal/main.c b/stmhal/main.c
index 97150ecac..566c2db07 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -27,23 +27,20 @@
#include <stdio.h>
#include <string.h>
-#include "py/nlr.h"
-#include "py/lexer.h"
-#include "py/parse.h"
-#include "py/obj.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
#include "py/gc.h"
#include "py/mphal.h"
-
+#include "lib/mp-readline/readline.h"
#include "lib/utils/pyexec.h"
-#include "lib/fatfs/ff.h"
-#include "extmod/fsusermount.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
#include "systick.h"
#include "pendsv.h"
+#include "pybthread.h"
#include "gccollect.h"
-#include "readline.h"
#include "modmachine.h"
#include "i2c.h"
#include "spi.h"
@@ -66,18 +63,19 @@
void SystemClock_Config(void);
+pyb_thread_t pyb_thread_main;
fs_user_mount_t fs_user_mount_flash;
void flash_error(int n) {
for (int i = 0; i < n; i++) {
- led_state(PYB_LED_R1, 1);
- led_state(PYB_LED_R2, 0);
- HAL_Delay(250);
- led_state(PYB_LED_R1, 0);
- led_state(PYB_LED_R2, 1);
- HAL_Delay(250);
+ led_state(PYB_LED_RED, 1);
+ led_state(PYB_LED_GREEN, 0);
+ mp_hal_delay_ms(250);
+ led_state(PYB_LED_RED, 0);
+ led_state(PYB_LED_GREEN, 1);
+ mp_hal_delay_ms(250);
}
- led_state(PYB_LED_R2, 0);
+ led_state(PYB_LED_GREEN, 0);
}
void NORETURN __fatal_error(const char *msg) {
@@ -166,96 +164,91 @@ static const char fresh_readme_txt[] =
;
// avoid inlining to avoid stack usage within main()
-MP_NOINLINE STATIC void init_flash_fs(uint reset_mode) {
+MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
// init the vfs object
- fs_user_mount_t *vfs = &fs_user_mount_flash;
- vfs->str = "/flash";
- vfs->len = 6;
- vfs->flags = 0;
- pyb_flash_init_vfs(vfs);
-
- // put the flash device in slot 0 (it will be unused at this point)
- MP_STATE_PORT(fs_user_mount)[0] = vfs;
+ fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
+ vfs_fat->flags = 0;
+ pyb_flash_init_vfs(vfs_fat);
// try to mount the flash
- FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
+ FRESULT res = f_mount(&vfs_fat->fatfs);
if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
// no filesystem, or asked to reset it, so create a fresh one
// LED on to indicate creation of LFS
- led_state(PYB_LED_R2, 1);
+ led_state(PYB_LED_GREEN, 1);
uint32_t start_tick = HAL_GetTick();
- res = f_mkfs("/flash", 0, 0);
+ uint8_t working_buf[_MAX_SS];
+ res = f_mkfs(&vfs_fat->fatfs, FM_FAT, 0, working_buf, sizeof(working_buf));
if (res == FR_OK) {
// success creating fresh LFS
} else {
printf("PYB: can't create flash filesystem\n");
- MP_STATE_PORT(fs_user_mount)[0] = NULL;
- return;
+ return false;
}
// set label
- f_setlabel("/flash/pybflash");
+ f_setlabel(&vfs_fat->fatfs, "pybflash");
// create empty main.py
FIL fp;
- f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/main.py", FA_WRITE | FA_CREATE_ALWAYS);
UINT n;
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
// TODO check we could write n bytes
f_close(&fp);
// create .inf driver file
- f_open(&fp, "/flash/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/pybcdc.inf", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fp, fresh_pybcdc_inf, sizeof(fresh_pybcdc_inf) - 1 /* don't count null terminator */, &n);
f_close(&fp);
// create readme file
- f_open(&fp, "/flash/README.txt", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/README.txt", FA_WRITE | FA_CREATE_ALWAYS);
f_write(&fp, fresh_readme_txt, sizeof(fresh_readme_txt) - 1 /* don't count null terminator */, &n);
f_close(&fp);
// keep LED on for at least 200ms
sys_tick_wait_at_least(start_tick, 200);
- led_state(PYB_LED_R2, 0);
+ led_state(PYB_LED_GREEN, 0);
} else if (res == FR_OK) {
// mount sucessful
} else {
+ fail:
printf("PYB: can't mount flash\n");
- MP_STATE_PORT(fs_user_mount)[0] = NULL;
- return;
+ return false;
+ }
+
+ // mount the flash device (there should be no other devices mounted at this point)
+ // we allocate this structure on the heap because vfs->next is a root pointer
+ mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
+ if (vfs == NULL) {
+ goto fail;
}
+ vfs->str = "/flash";
+ vfs->len = 6;
+ vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
+ vfs->next = NULL;
+ MP_STATE_VM(vfs_mount_table) = vfs;
// The current directory is used as the boot up directory.
// It is set to the internal flash filesystem by default.
- f_chdrive("/flash");
+ MP_STATE_PORT(vfs_cur) = vfs;
// Make sure we have a /flash/boot.py. Create it if needed.
FILINFO fno;
-#if _USE_LFN
- fno.lfname = NULL;
- fno.lfsize = 0;
-#endif
- res = f_stat("/flash/boot.py", &fno);
- if (res == FR_OK) {
- if (fno.fattrib & AM_DIR) {
- // exists as a directory
- // TODO handle this case
- // see http://elm-chan.org/fsw/ff/img/app2.c for a "rm -rf" implementation
- } else {
- // exists as a file, good!
- }
- } else {
+ res = f_stat(&vfs_fat->fatfs, "/boot.py", &fno);
+ if (res != FR_OK) {
// doesn't exist, create fresh file
// LED on to indicate creation of boot.py
- led_state(PYB_LED_R2, 1);
+ led_state(PYB_LED_GREEN, 1);
uint32_t start_tick = HAL_GetTick();
FIL fp;
- f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
+ f_open(&vfs_fat->fatfs, &fp, "/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
UINT n;
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
// TODO check we could write n bytes
@@ -263,9 +256,87 @@ MP_NOINLINE STATIC void init_flash_fs(uint reset_mode) {
// keep LED on for at least 200ms
sys_tick_wait_at_least(start_tick, 200);
- led_state(PYB_LED_R2, 0);
+ led_state(PYB_LED_GREEN, 0);
+ }
+
+ return true;
+}
+
+#if MICROPY_HW_HAS_SDCARD
+STATIC bool init_sdcard_fs(bool first_soft_reset) {
+ bool first_part = true;
+ for (int part_num = 1; part_num <= 4; ++part_num) {
+ // create vfs object
+ fs_user_mount_t *vfs_fat = m_new_obj_maybe(fs_user_mount_t);
+ mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
+ if (vfs == NULL || vfs_fat == NULL) {
+ break;
+ }
+ vfs_fat->flags = FSUSER_FREE_OBJ;
+ sdcard_init_vfs(vfs_fat, part_num);
+
+ // try to mount the partition
+ FRESULT res = f_mount(&vfs_fat->fatfs);
+
+ if (res != FR_OK) {
+ // couldn't mount
+ m_del_obj(fs_user_mount_t, vfs_fat);
+ m_del_obj(mp_vfs_mount_t, vfs);
+ } else {
+ // mounted via FatFs, now mount the SD partition in the VFS
+ if (first_part) {
+ // the first available partition is traditionally called "sd" for simplicity
+ vfs->str = "/sd";
+ vfs->len = 3;
+ } else {
+ // subsequent partitions are numbered by their index in the partition table
+ if (part_num == 2) {
+ vfs->str = "/sd2";
+ } else if (part_num == 2) {
+ vfs->str = "/sd3";
+ } else {
+ vfs->str = "/sd4";
+ }
+ vfs->len = 4;
+ }
+ vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
+ vfs->next = NULL;
+ for (mp_vfs_mount_t **m = &MP_STATE_VM(vfs_mount_table);; m = &(*m)->next) {
+ if (*m == NULL) {
+ *m = vfs;
+ break;
+ }
+ }
+
+ if (first_soft_reset) {
+ // use SD card as medium for the USB MSD
+ #if defined(USE_DEVICE_MODE)
+ pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD;
+ #endif
+ }
+
+ #if defined(USE_DEVICE_MODE)
+ // only use SD card as current directory if that's what the USB medium is
+ if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD)
+ #endif
+ {
+ if (first_part) {
+ // use SD card as current directory
+ MP_STATE_PORT(vfs_cur) = vfs;
+ }
+ }
+ first_part = false;
+ }
+ }
+
+ if (first_part) {
+ printf("PYB: can't mount SD card\n");
+ return false;
+ } else {
+ return true;
}
}
+#endif
STATIC uint update_reset_mode(uint reset_mode) {
#if MICROPY_HW_HAS_SWITCH
@@ -278,7 +349,7 @@ STATIC uint update_reset_mode(uint reset_mode) {
if (!switch_get()) {
break;
}
- HAL_Delay(20);
+ mp_hal_delay_ms(20);
if (i % 30 == 29) {
if (++reset_mode > 3) {
reset_mode = 1;
@@ -293,13 +364,13 @@ STATIC uint update_reset_mode(uint reset_mode) {
led_state(2, 0);
led_state(3, 0);
led_state(4, 0);
- HAL_Delay(50);
+ mp_hal_delay_ms(50);
led_state(2, reset_mode & 1);
led_state(3, reset_mode & 2);
led_state(4, reset_mode & 4);
- HAL_Delay(50);
+ mp_hal_delay_ms(50);
}
- HAL_Delay(400);
+ mp_hal_delay_ms(400);
#elif defined(MICROPY_HW_LED1)
@@ -312,11 +383,11 @@ STATIC uint update_reset_mode(uint reset_mode) {
break;
}
led_state(1, 1);
- HAL_Delay(100);
+ mp_hal_delay_ms(100);
led_state(1, 0);
- HAL_Delay(200);
+ mp_hal_delay_ms(200);
}
- HAL_Delay(400);
+ mp_hal_delay_ms(400);
if (!switch_get()) {
break;
}
@@ -328,11 +399,11 @@ STATIC uint update_reset_mode(uint reset_mode) {
for (uint i = 0; i < 2; i++) {
for (uint j = 0; j < reset_mode; j++) {
led_state(1, 1);
- HAL_Delay(100);
+ mp_hal_delay_ms(100);
led_state(1, 0);
- HAL_Delay(200);
+ mp_hal_delay_ms(200);
}
- HAL_Delay(400);
+ mp_hal_delay_ms(400);
}
#else
#error Need a reset mode update method
@@ -345,11 +416,6 @@ STATIC uint update_reset_mode(uint reset_mode) {
int main(void) {
// TODO disable JTAG
- // Stack limit should be less than real stack size, so we have a chance
- // to recover from limit hit. (Limit is measured in bytes.)
- mp_stack_ctrl_init();
- mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024);
-
/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
@@ -383,6 +449,9 @@ int main(void) {
#endif
// basic sub-system init
+ #if MICROPY_PY_THREAD
+ pyb_thread_init(&pyb_thread_main);
+ #endif
pendsv_init();
led_init();
#if MICROPY_HW_HAS_SWITCH
@@ -428,6 +497,17 @@ soft_reset:
storage_init();
}
+ // Python threading init
+ #if MICROPY_PY_THREAD
+ mp_thread_init();
+ #endif
+
+ // Stack limit should be less than real stack size, so we have a chance
+ // to recover from limit hit. (Limit is measured in bytes.)
+ // Note: stack control relies on main thread being initialised above
+ mp_stack_set_top(&_estack);
+ mp_stack_set_limit((char*)&_estack - (char*)&_heap_end - 1024);
+
// GC init
gc_init(&_heap_start, &_heap_end);
@@ -435,8 +515,6 @@ soft_reset:
mp_init();
mp_obj_list_init(mp_sys_path, 0);
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
- mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash));
- mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
mp_obj_list_init(mp_sys_argv, 0);
// Initialise low-level sub-systems. Here we need to very basic things like
@@ -479,53 +557,28 @@ soft_reset:
// Initialise the local flash filesystem.
// Create it if needed, mount in on /flash, and set it as current dir.
- init_flash_fs(reset_mode);
+ bool mounted_flash = init_flash_fs(reset_mode);
+ bool mounted_sdcard = false;
#if MICROPY_HW_HAS_SDCARD
// if an SD card is present then mount it on /sd/
if (sdcard_is_present()) {
- // create vfs object
- fs_user_mount_t *vfs = m_new_obj_maybe(fs_user_mount_t);
- if (vfs == NULL) {
- goto no_mem_for_sd;
+ // if there is a file in the flash called "SKIPSD", then we don't mount the SD card
+ if (!mounted_flash || f_stat(&fs_user_mount_flash.fatfs, "/SKIPSD", NULL) != FR_OK) {
+ mounted_sdcard = init_sdcard_fs(first_soft_reset);
}
- vfs->str = "/sd";
- vfs->len = 3;
- vfs->flags = FSUSER_FREE_OBJ;
- sdcard_init_vfs(vfs);
-
- // put the sd device in slot 1 (it will be unused at this point)
- MP_STATE_PORT(fs_user_mount)[1] = vfs;
-
- FRESULT res = f_mount(&vfs->fatfs, vfs->str, 1);
- if (res != FR_OK) {
- printf("PYB: can't mount SD card\n");
- MP_STATE_PORT(fs_user_mount)[1] = NULL;
- m_del_obj(fs_user_mount_t, vfs);
- } else {
- // TODO these should go before the /flash entries in the path
- mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
- mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
-
- if (first_soft_reset) {
- // use SD card as medium for the USB MSD
-#if defined(USE_DEVICE_MODE)
- pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD;
+ }
#endif
- }
- #if defined(USE_DEVICE_MODE)
- // only use SD card as current directory if that's what the USB medium is
- if (pyb_usb_storage_medium == PYB_USB_STORAGE_MEDIUM_SDCARD)
- #endif
- {
- // use SD card as current directory
- f_chdrive("/sd");
- }
- }
- no_mem_for_sd:;
+ // set sys.path based on mounted filesystems (/sd is first so it can override /flash)
+ if (mounted_sdcard) {
+ mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
+ mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
+ }
+ if (mounted_flash) {
+ mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash));
+ mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
}
-#endif
// reset config variables; they should be set by boot.py
MP_STATE_PORT(pyb_config_main) = MP_OBJ_NULL;
@@ -534,9 +587,9 @@ soft_reset:
// TODO perhaps have pyb.reboot([bootpy]) function to soft-reboot and execute custom boot.py
if (reset_mode == 1 || reset_mode == 3) {
const char *boot_py = "boot.py";
- FRESULT res = f_stat(boot_py, NULL);
- if (res == FR_OK) {
- int ret = pyexec_file(boot_py, NULL);
+ mp_import_stat_t stat = mp_import_stat(boot_py);
+ if (stat == MP_IMPORT_STAT_FILE) {
+ int ret = pyexec_file(boot_py);
if (ret & PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
}
@@ -597,9 +650,9 @@ soft_reset:
} else {
main_py = mp_obj_str_get_str(MP_STATE_PORT(pyb_config_main));
}
- FRESULT res = f_stat(main_py, NULL);
- if (res == FR_OK) {
- int ret = pyexec_file(main_py, NULL);
+ mp_import_stat_t stat = mp_import_stat(main_py);
+ if (stat == MP_IMPORT_STAT_FILE) {
+ int ret = pyexec_file(main_py);
if (ret & PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
}
@@ -637,6 +690,10 @@ soft_reset_exit:
can_deinit();
#endif
+ #if MICROPY_PY_THREAD
+ pyb_thread_deinit();
+ #endif
+
first_soft_reset = false;
goto soft_reset;
}
diff --git a/stmhal/make-stmconst.py b/stmhal/make-stmconst.py
index c9eb42a40..9bb7a0569 100644
--- a/stmhal/make-stmconst.py
+++ b/stmhal/make-stmconst.py
@@ -162,13 +162,13 @@ def print_regs_as_submodules(reg_name, reg_defs, modules, needed_qstrs):
modules.append((mod_name_lower, mod_name_upper))
print("""
-STATIC const mp_map_elem_t stm_%s_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_%s) },
+STATIC const mp_rom_map_elem_t stm_%s_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_%s) },
""" % (mod_name_lower, mod_name_upper))
needed_qstrs.add(mod_name_upper)
for r in reg_defs:
- print(' { MP_OBJ_NEW_QSTR(MP_QSTR_%s), MP_OBJ_NEW_SMALL_INT(%#x) }, // %s-bits, %s' % (r[0], r[1], r[2], r[3]))
+ print(' { MP_ROM_QSTR(MP_QSTR_%s), MP_ROM_INT(%#x) }, // %s-bits, %s' % (r[0], r[1], r[2], r[3]))
needed_qstrs.add(r[0])
print("""};
diff --git a/stmhal/memory.h b/stmhal/memory.h
deleted file mode 100644
index f3777b0e3..000000000
--- a/stmhal/memory.h
+++ /dev/null
@@ -1,2 +0,0 @@
-// this is needed for extmod/crypto-algorithms/sha256.c
-#include <string.h>
diff --git a/stmhal/modmachine.c b/stmhal/modmachine.c
index 7a337adb6..c5444ec98 100644
--- a/stmhal/modmachine.c
+++ b/stmhal/modmachine.c
@@ -25,19 +25,23 @@
*/
#include <stdio.h>
+#include <string.h>
#include "modmachine.h"
#include "py/gc.h"
#include "py/runtime.h"
#include "py/mphal.h"
#include "extmod/machine_mem.h"
+#include "extmod/machine_signal.h"
#include "extmod/machine_pulse.h"
#include "extmod/machine_i2c.h"
#include "lib/utils/pyexec.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
#include "gccollect.h"
#include "irq.h"
+#include "pybthread.h"
#include "rng.h"
#include "storage.h"
#include "pin.h"
@@ -46,6 +50,7 @@
#include "rtc.h"
#include "i2c.h"
#include "spi.h"
+#include "uart.h"
#include "wdt.h"
#if defined(MCU_SERIES_F4)
@@ -144,12 +149,22 @@ STATIC mp_obj_t machine_info(mp_uint_t n_args, const mp_obj_t *args) {
// free space on flash
{
- DWORD nclst;
- FATFS *fatfs;
- f_getfree("/flash", &nclst, &fatfs);
- printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512));
+ for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
+ if (strncmp("/flash", vfs->str, vfs->len) == 0) {
+ // assumes that it's a FatFs filesystem
+ fs_user_mount_t *vfs_fat = MP_OBJ_TO_PTR(vfs->obj);
+ DWORD nclst;
+ f_getfree(&vfs_fat->fatfs, &nclst);
+ printf("LFS free: %u bytes\n", (uint)(nclst * vfs_fat->fatfs.csize * 512));
+ break;
+ }
+ }
}
+ #if MICROPY_PY_THREAD
+ pyb_thread_dump();
+ #endif
+
if (n_args == 1) {
// arg given means dump gc allocation table
gc_dump_alloc_table();
@@ -310,7 +325,7 @@ STATIC mp_obj_t machine_freq(mp_uint_t n_args, const mp_obj_t *args) {
//printf("%lu %lu %lu %lu %lu\n", sysclk_source, m, n, p, q);
// let the USB CDC have a chance to process before we change the clock
- HAL_Delay(5);
+ mp_hal_delay_ms(5);
// desired system clock source is in sysclk_source
RCC_ClkInitTypeDef RCC_ClkInitStruct;
@@ -504,65 +519,64 @@ STATIC mp_obj_t machine_reset_cause(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause);
-STATIC const mp_map_elem_t machine_module_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_umachine) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&machine_unique_id_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&machine_reset_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_soft_reset), (mp_obj_t)&machine_soft_reset_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_bootloader), (mp_obj_t)&machine_bootloader_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&machine_freq_obj },
+STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
+ { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_info_obj) },
+ { MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) },
+ { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) },
+ { MP_ROM_QSTR(MP_QSTR_soft_reset), MP_ROM_PTR(&machine_soft_reset_obj) },
+ { MP_ROM_QSTR(MP_QSTR_bootloader), MP_ROM_PTR(&machine_bootloader_obj) },
+ { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) },
#if MICROPY_HW_ENABLE_RNG
- { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
+ { MP_ROM_QSTR(MP_QSTR_rng), MP_ROM_PTR(&pyb_rng_get_obj) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&pyb_wfi_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&machine_sleep_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deepsleep), (mp_obj_t)&machine_deepsleep_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&machine_reset_cause_obj },
+ { MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&pyb_wfi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&machine_sleep_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&machine_deepsleep_obj) },
+ { MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) },
#if 0
- { MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&machine_wake_reason_obj },
+ { MP_ROM_QSTR(MP_QSTR_wake_reason), MP_ROM_PTR(&machine_wake_reason_obj) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
+ { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&pyb_disable_irq_obj) },
+ { MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&pyb_enable_irq_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_time_pulse_us), (mp_obj_t)&machine_time_pulse_us_obj },
+ { MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) },
- { MP_ROM_QSTR(MP_QSTR_mem8), (mp_obj_t)&machine_mem8_obj },
- { MP_ROM_QSTR(MP_QSTR_mem16), (mp_obj_t)&machine_mem16_obj },
- { MP_ROM_QSTR(MP_QSTR_mem32), (mp_obj_t)&machine_mem32_obj },
+ { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
+ { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pin_type) },
+ { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) },
#if 0
- { MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
+ { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&pyb_rtc_type) },
+ { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) },
#endif
- // TODO: Per new API, I2C types below, if called with 1 arg (ID), should still
- // initialize master mode on the peripheral.
- { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&machine_i2c_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&machine_hard_spi_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hard_spi_type) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
+ { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&pyb_wdt_type) },
#if 0
- { MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type },
+ { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&pyb_timer_type) },
+ { MP_ROM_QSTR(MP_QSTR_HeartBeat), MP_ROM_PTR(&pyb_heartbeat_type) },
+ { MP_ROM_QSTR(MP_QSTR_SD), MP_ROM_PTR(&pyb_sd_type) },
// class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_IDLE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
+ { MP_ROM_QSTR(MP_QSTR_IDLE), MP_ROM_INT(PYB_PWR_MODE_ACTIVE) },
+ { MP_ROM_QSTR(MP_QSTR_SLEEP), MP_ROM_INT(PYB_PWR_MODE_LPDS) },
+ { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(PYB_PWR_MODE_HIBERNATE) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_PWRON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_POWER_ON) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_HARD) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_WDT) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_DEEPSLEEP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_RESET_SOFT) },
+ { MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(PYB_RESET_POWER_ON) },
+ { MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(PYB_RESET_HARD) },
+ { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(PYB_RESET_WDT) },
+ { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(PYB_RESET_DEEPSLEEP) },
+ { MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(PYB_RESET_SOFT) },
#if 0
- { MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_GPIO) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) },
+ { MP_ROM_QSTR(MP_QSTR_WLAN_WAKE), MP_ROM_INT(PYB_SLP_WAKED_BY_WLAN) },
+ { MP_ROM_QSTR(MP_QSTR_PIN_WAKE), MP_ROM_INT(PYB_SLP_WAKED_BY_GPIO) },
+ { MP_ROM_QSTR(MP_QSTR_RTC_WAKE), MP_ROM_INT(PYB_SLP_WAKED_BY_RTC) },
#endif
};
diff --git a/stmhal/modnetwork.c b/stmhal/modnetwork.c
index c15bfc7b2..09a80ef3c 100644
--- a/stmhal/modnetwork.c
+++ b/stmhal/modnetwork.c
@@ -71,17 +71,17 @@ STATIC mp_obj_t network_route(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route);
-STATIC const mp_map_elem_t mp_module_network_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_network) },
+STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) },
#if MICROPY_PY_WIZNET5K
- { MP_OBJ_NEW_QSTR(MP_QSTR_WIZNET5K), (mp_obj_t)&mod_network_nic_type_wiznet5k },
+ { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) },
#endif
#if MICROPY_PY_CC3K
- { MP_OBJ_NEW_QSTR(MP_QSTR_CC3K), (mp_obj_t)&mod_network_nic_type_cc3k },
+ { MP_ROM_QSTR(MP_QSTR_CC3K), MP_ROM_PTR(&mod_network_nic_type_cc3k) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_route), (mp_obj_t)&network_route_obj },
+ { MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table);
diff --git a/stmhal/modnwcc3k.c b/stmhal/modnwcc3k.c
index e3ad49402..ae84f9393 100644
--- a/stmhal/modnwcc3k.c
+++ b/stmhal/modnwcc3k.c
@@ -37,7 +37,8 @@
#include "py/stream.h"
#include "py/runtime.h"
#include "py/mperrno.h"
-#include "netutils.h"
+#include "py/mphal.h"
+#include "lib/netutils/netutils.h"
#include "modnetwork.h"
#include "pin.h"
#include "genhdr/pins.h"
@@ -121,7 +122,7 @@ STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uin
if (retry == 0 || CC3000_EXPORT(errno) != -95) {
return CC3000_EXPORT(errno);
}
- HAL_Delay(50);
+ mp_hal_delay_ms(50);
}
if (ip == 0) {
@@ -477,11 +478,11 @@ STATIC mp_obj_t cc3k_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
// get ssid
- mp_uint_t ssid_len;
+ size_t ssid_len;
const char *ssid = mp_obj_str_get_data(args[0].u_obj, &ssid_len);
// get key and sec
- mp_uint_t key_len = 0;
+ size_t key_len = 0;
const char *key = NULL;
mp_uint_t sec = WLAN_SEC_UNSEC;
if (args[1].u_obj != mp_const_none) {
@@ -562,18 +563,18 @@ STATIC mp_obj_t cc3k_patch_program(mp_obj_t self_in, mp_obj_t key_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(cc3k_patch_program_obj, cc3k_patch_program);
-STATIC const mp_map_elem_t cc3k_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&cc3k_connect_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_disconnect), (mp_obj_t)&cc3k_disconnect_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_isconnected), (mp_obj_t)&cc3k_isconnected_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&cc3k_ifconfig_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_patch_version), (mp_obj_t)&cc3k_patch_version_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_patch_program), (mp_obj_t)&cc3k_patch_program_obj },
+STATIC const mp_rom_map_elem_t cc3k_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&cc3k_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&cc3k_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&cc3k_isconnected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&cc3k_ifconfig_obj) },
+ { MP_ROM_QSTR(MP_QSTR_patch_version), MP_ROM_PTR(&cc3k_patch_version_obj) },
+ { MP_ROM_QSTR(MP_QSTR_patch_program), MP_ROM_PTR(&cc3k_patch_program_obj) },
// class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_WEP), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WEP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_WPA), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WPA) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_WPA2), MP_OBJ_NEW_SMALL_INT(WLAN_SEC_WPA2) },
+ { MP_ROM_QSTR(MP_QSTR_WEP), MP_ROM_INT(WLAN_SEC_WEP) },
+ { MP_ROM_QSTR(MP_QSTR_WPA), MP_ROM_INT(WLAN_SEC_WPA) },
+ { MP_ROM_QSTR(MP_QSTR_WPA2), MP_ROM_INT(WLAN_SEC_WPA2) },
};
STATIC MP_DEFINE_CONST_DICT(cc3k_locals_dict, cc3k_locals_dict_table);
@@ -583,7 +584,7 @@ const mod_network_nic_type_t mod_network_nic_type_cc3k = {
{ &mp_type_type },
.name = MP_QSTR_CC3K,
.make_new = cc3k_make_new,
- .locals_dict = (mp_obj_t)&cc3k_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&cc3k_locals_dict,
},
.gethostbyname = cc3k_gethostbyname,
.socket = cc3k_socket_socket,
diff --git a/stmhal/modnwwiznet5k.c b/stmhal/modnwwiznet5k.c
index 04d37ccee..4752cdc0b 100644
--- a/stmhal/modnwwiznet5k.c
+++ b/stmhal/modnwwiznet5k.c
@@ -33,7 +33,7 @@
#include "py/runtime.h"
#include "py/mperrno.h"
#include "py/mphal.h"
-#include "netutils.h"
+#include "lib/netutils/netutils.h"
#include "modnetwork.h"
#include "pin.h"
#include "genhdr/pins.h"
@@ -202,7 +202,7 @@ STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_
*_errno = MP_ENOTCONN; // ??
return -1;
}
- HAL_Delay(1);
+ mp_hal_delay_ms(1);
}
}
@@ -348,9 +348,9 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size
mp_hal_pin_output(wiznet5k_obj.rst);
mp_hal_pin_low(wiznet5k_obj.rst);
- HAL_Delay(1); // datasheet says 2us
+ mp_hal_delay_ms(1); // datasheet says 2us
mp_hal_pin_high(wiznet5k_obj.rst);
- HAL_Delay(160); // datasheet says 150ms
+ mp_hal_delay_ms(160); // datasheet says 150ms
reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit);
reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect);
@@ -371,7 +371,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size
ctlnetwork(CN_SET_NETINFO, (void*)&netinfo);
// seems we need a small delay after init
- HAL_Delay(250);
+ mp_hal_delay_ms(250);
// register with network module
mod_network_register_nic(&wiznet5k_obj);
@@ -433,9 +433,9 @@ STATIC mp_obj_t wiznet5k_ifconfig(mp_uint_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig);
-STATIC const mp_map_elem_t wiznet5k_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_regs), (mp_obj_t)&wiznet5k_regs_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&wiznet5k_ifconfig_obj },
+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) },
};
STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table);
@@ -445,7 +445,7 @@ const mod_network_nic_type_t mod_network_nic_type_wiznet5k = {
{ &mp_type_type },
.name = MP_QSTR_WIZNET5K,
.make_new = wiznet5k_make_new,
- .locals_dict = (mp_obj_t)&wiznet5k_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&wiznet5k_locals_dict,
},
.gethostbyname = wiznet5k_gethostbyname,
.socket = wiznet5k_socket_socket,
diff --git a/stmhal/modpyb.c b/stmhal/modpyb.c
index e602234fc..b8da948ab 100644
--- a/stmhal/modpyb.c
+++ b/stmhal/modpyb.c
@@ -34,10 +34,12 @@
#include "py/obj.h"
#include "py/gc.h"
#include "py/builtin.h"
+#include "py/mphal.h"
#include "lib/utils/pyexec.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
+#include "lib/oofatfs/ff.h"
+#include "lib/oofatfs/diskio.h"
#include "gccollect.h"
+#include "stm32_it.h"
#include "irq.h"
#include "systick.h"
#include "led.h"
@@ -61,22 +63,14 @@
#include "usb.h"
#include "portmodules.h"
#include "modmachine.h"
-#include "extmod/fsusermount.h"
+#include "extmod/vfs.h"
#include "extmod/utime_mphal.h"
-/// \function millis()
-/// Returns the number of milliseconds since the board was last reset.
-///
-/// The result is always a micropython smallint (31-bit signed number), so
-/// after 2^30 milliseconds (about 12.4 days) this will start to return
-/// negative numbers.
-STATIC mp_obj_t pyb_millis(void) {
- // We want to "cast" the 32 bit unsigned into a small-int. This means
- // copying the MSB down 1 bit (extending the sign down), which is
- // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
- return MP_OBJ_NEW_SMALL_INT(HAL_GetTick());
+STATIC mp_obj_t pyb_fault_debug(mp_obj_t value) {
+ pyb_hard_fault_debug = mp_obj_is_true(value);
+ return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_fault_debug_obj, pyb_fault_debug);
/// \function elapsed_millis(start)
/// Returns the number of milliseconds which have elapsed since `start`.
@@ -90,25 +84,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
/// # Perform some operation
STATIC mp_obj_t pyb_elapsed_millis(mp_obj_t start) {
uint32_t startMillis = mp_obj_get_int(start);
- uint32_t currMillis = HAL_GetTick();
+ uint32_t currMillis = mp_hal_ticks_ms();
return MP_OBJ_NEW_SMALL_INT((currMillis - startMillis) & 0x3fffffff);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_millis_obj, pyb_elapsed_millis);
-/// \function micros()
-/// Returns the number of microseconds since the board was last reset.
-///
-/// The result is always a micropython smallint (31-bit signed number), so
-/// after 2^30 microseconds (about 17.8 minutes) this will start to return
-/// negative numbers.
-STATIC mp_obj_t pyb_micros(void) {
- // We want to "cast" the 32 bit unsigned into a small-int. This means
- // copying the MSB down 1 bit (extending the sign down), which is
- // equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
- return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds());
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_micros_obj, pyb_micros);
-
/// \function elapsed_micros(start)
/// Returns the number of microseconds which have elapsed since `start`.
///
@@ -121,108 +101,110 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_micros_obj, pyb_micros);
/// # Perform some operation
STATIC mp_obj_t pyb_elapsed_micros(mp_obj_t start) {
uint32_t startMicros = mp_obj_get_int(start);
- uint32_t currMicros = sys_tick_get_microseconds();
+ uint32_t currMicros = mp_hal_ticks_us();
return MP_OBJ_NEW_SMALL_INT((currMicros - startMicros) & 0x3fffffff);
}
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
-STATIC const mp_map_elem_t pyb_module_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
+STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pyb) },
+
+ { MP_ROM_QSTR(MP_QSTR_fault_debug), MP_ROM_PTR(&pyb_fault_debug_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_bootloader), (mp_obj_t)&machine_bootloader_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_hard_reset), (mp_obj_t)&machine_reset_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&machine_unique_id_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&machine_freq_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj },
+ { MP_ROM_QSTR(MP_QSTR_bootloader), MP_ROM_PTR(&machine_bootloader_obj) },
+ { MP_ROM_QSTR(MP_QSTR_hard_reset), MP_ROM_PTR(&machine_reset_obj) },
+ { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&machine_info_obj) },
+ { MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) },
+ { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) },
+ { MP_ROM_QSTR(MP_QSTR_repl_info), MP_ROM_PTR(&pyb_set_repl_info_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_wfi), (mp_obj_t)&pyb_wfi_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
+ { MP_ROM_QSTR(MP_QSTR_wfi), MP_ROM_PTR(&pyb_wfi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&pyb_disable_irq_obj) },
+ { MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&pyb_enable_irq_obj) },
#if IRQ_ENABLE_STATS
- { MP_OBJ_NEW_QSTR(MP_QSTR_irq_stats), (mp_obj_t)&pyb_irq_stats_obj },
+ { MP_ROM_QSTR(MP_QSTR_irq_stats), MP_ROM_PTR(&pyb_irq_stats_obj) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&machine_sleep_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&machine_deepsleep_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&mod_os_dupterm_obj },
+ { 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_OBJ_NEW_QSTR(MP_QSTR_usb_mode), (mp_obj_t)&pyb_usb_mode_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_hid_mouse), (mp_obj_t)&pyb_usb_hid_mouse_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_hid_keyboard), (mp_obj_t)&pyb_usb_hid_keyboard_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_USB_VCP), (mp_obj_t)&pyb_usb_vcp_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_USB_HID), (mp_obj_t)&pyb_usb_hid_type },
+ { 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) },
+ { MP_ROM_QSTR(MP_QSTR_hid_keyboard), MP_ROM_PTR(&pyb_usb_hid_keyboard_obj) },
+ { MP_ROM_QSTR(MP_QSTR_USB_VCP), MP_ROM_PTR(&pyb_usb_vcp_type) },
+ { MP_ROM_QSTR(MP_QSTR_USB_HID), MP_ROM_PTR(&pyb_usb_hid_type) },
// these 2 are deprecated; use USB_VCP.isconnected and USB_HID.send instead
- { MP_OBJ_NEW_QSTR(MP_QSTR_have_cdc), (mp_obj_t)&pyb_have_cdc_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj },
+ { MP_ROM_QSTR(MP_QSTR_have_cdc), MP_ROM_PTR(&pyb_have_cdc_obj) },
+ { MP_ROM_QSTR(MP_QSTR_hid), MP_ROM_PTR(&pyb_hid_send_report_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_millis), (mp_obj_t)&pyb_elapsed_millis_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_micros), (mp_obj_t)&pyb_micros_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_micros), (mp_obj_t)&pyb_elapsed_micros_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&mp_utime_sleep_ms_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&mp_utime_sleep_us_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&mod_os_sync_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&fsuser_mount_obj },
+ { MP_ROM_QSTR(MP_QSTR_millis), MP_ROM_PTR(&mp_utime_ticks_ms_obj) },
+ { MP_ROM_QSTR(MP_QSTR_elapsed_millis), MP_ROM_PTR(&pyb_elapsed_millis_obj) },
+ { MP_ROM_QSTR(MP_QSTR_micros), MP_ROM_PTR(&mp_utime_ticks_us_obj) },
+ { MP_ROM_QSTR(MP_QSTR_elapsed_micros), MP_ROM_PTR(&pyb_elapsed_micros_obj) },
+ { MP_ROM_QSTR(MP_QSTR_delay), MP_ROM_PTR(&mp_utime_sleep_ms_obj) },
+ { MP_ROM_QSTR(MP_QSTR_udelay), MP_ROM_PTR(&mp_utime_sleep_us_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mod_os_sync_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type },
+ { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&pyb_timer_type) },
#if MICROPY_HW_ENABLE_RNG
- { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
+ { MP_ROM_QSTR(MP_QSTR_rng), MP_ROM_PTR(&pyb_rng_get_obj) },
#endif
#if MICROPY_HW_ENABLE_RTC
- { MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
+ { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&pyb_rtc_type) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ExtInt), (mp_obj_t)&extint_type },
+ { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pin_type) },
+ { MP_ROM_QSTR(MP_QSTR_ExtInt), MP_ROM_PTR(&extint_type) },
#if MICROPY_HW_ENABLE_SERVO
- { MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_servo_type },
+ { MP_ROM_QSTR(MP_QSTR_pwm), MP_ROM_PTR(&pyb_pwm_set_obj) },
+ { MP_ROM_QSTR(MP_QSTR_servo), MP_ROM_PTR(&pyb_servo_set_obj) },
+ { MP_ROM_QSTR(MP_QSTR_Servo), MP_ROM_PTR(&pyb_servo_type) },
#endif
#if MICROPY_HW_HAS_SWITCH
- { MP_OBJ_NEW_QSTR(MP_QSTR_Switch), (mp_obj_t)&pyb_switch_type },
+ { MP_ROM_QSTR(MP_QSTR_Switch), MP_ROM_PTR(&pyb_switch_type) },
#endif
#if MICROPY_HW_HAS_FLASH
- { MP_OBJ_NEW_QSTR(MP_QSTR_Flash), (mp_obj_t)&pyb_flash_type },
+ { MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&pyb_flash_type) },
#endif
#if MICROPY_HW_HAS_SDCARD
- { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj }, // now obsolete
- { MP_OBJ_NEW_QSTR(MP_QSTR_SDCard), (mp_obj_t)&pyb_sdcard_type },
+ { MP_ROM_QSTR(MP_QSTR_SD), MP_ROM_PTR(&pyb_sdcard_obj) }, // now obsolete
+ { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&pyb_sdcard_type) },
#endif
#if defined(MICROPY_HW_LED1)
- { MP_OBJ_NEW_QSTR(MP_QSTR_LED), (mp_obj_t)&pyb_led_type },
+ { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pyb_led_type) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type },
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&pyb_i2c_type) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&pyb_spi_type) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
#if MICROPY_HW_ENABLE_CAN
- { MP_OBJ_NEW_QSTR(MP_QSTR_CAN), (mp_obj_t)&pyb_can_type },
+ { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&pyb_can_type) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ADCAll), (mp_obj_t)&pyb_adc_all_type },
+ { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) },
+ { MP_ROM_QSTR(MP_QSTR_ADCAll), MP_ROM_PTR(&pyb_adc_all_type) },
#if MICROPY_HW_ENABLE_DAC
- { MP_OBJ_NEW_QSTR(MP_QSTR_DAC), (mp_obj_t)&pyb_dac_type },
+ { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pyb_dac_type) },
#endif
#if MICROPY_HW_HAS_MMA7660
- { MP_OBJ_NEW_QSTR(MP_QSTR_Accel), (mp_obj_t)&pyb_accel_type },
+ { MP_ROM_QSTR(MP_QSTR_Accel), MP_ROM_PTR(&pyb_accel_type) },
#endif
#if MICROPY_HW_HAS_LCD
- { MP_OBJ_NEW_QSTR(MP_QSTR_LCD), (mp_obj_t)&pyb_lcd_type },
+ { MP_ROM_QSTR(MP_QSTR_LCD), MP_ROM_PTR(&pyb_lcd_type) },
#endif
};
diff --git a/stmhal/modstm.c b/stmhal/modstm.c
index 76c8eb155..18882fa47 100644
--- a/stmhal/modstm.c
+++ b/stmhal/modstm.c
@@ -37,12 +37,12 @@
#include "py/objint.h"
#include "genhdr/modstm_mpz.h"
-STATIC const mp_map_elem_t stm_module_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_stm) },
+STATIC const mp_rom_map_elem_t stm_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_stm) },
- { MP_ROM_QSTR(MP_QSTR_mem8), (mp_obj_t)&machine_mem8_obj },
- { MP_ROM_QSTR(MP_QSTR_mem16), (mp_obj_t)&machine_mem16_obj },
- { MP_ROM_QSTR(MP_QSTR_mem32), (mp_obj_t)&machine_mem32_obj },
+ { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) },
#include "genhdr/modstm_const.h"
};
diff --git a/stmhal/modules/lcd160cr.py b/stmhal/modules/lcd160cr.py
new file mode 120000
index 000000000..c0e180714
--- /dev/null
+++ b/stmhal/modules/lcd160cr.py
@@ -0,0 +1 @@
+../../drivers/display/lcd160cr.py \ No newline at end of file
diff --git a/stmhal/modules/lcd160cr_test.py b/stmhal/modules/lcd160cr_test.py
new file mode 120000
index 000000000..56f091351
--- /dev/null
+++ b/stmhal/modules/lcd160cr_test.py
@@ -0,0 +1 @@
+../../drivers/display/lcd160cr_test.py \ No newline at end of file
diff --git a/stmhal/moduos.c b/stmhal/moduos.c
index b3c6570a5..ece6019fb 100644
--- a/stmhal/moduos.c
+++ b/stmhal/moduos.c
@@ -31,15 +31,14 @@
#include "py/runtime.h"
#include "py/objtuple.h"
#include "py/objstr.h"
+#include "lib/timeutils/timeutils.h"
+#include "lib/oofatfs/ff.h"
+#include "lib/oofatfs/diskio.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
#include "genhdr/mpversion.h"
-#include "lib/fatfs/ff.h"
-#include "lib/fatfs/diskio.h"
-#include "timeutils.h"
#include "rng.h"
#include "uart.h"
-#include "extmod/vfs_fat_file.h"
-#include "sdcard.h"
-#include "extmod/fsusermount.h"
#include "portmodules.h"
/// \module os - basic "operating system" services
@@ -80,263 +79,13 @@ STATIC mp_obj_t os_uname(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
-/// \function chdir(path)
-/// Change current directory.
-STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
- const char *path;
- path = mp_obj_str_get_str(path_in);
-
- FRESULT res = f_chdrive(path);
-
- if (res == FR_OK) {
- res = f_chdir(path);
- }
-
- if (res != FR_OK) {
- // TODO should be mp_type_FileNotFoundError
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
- }
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
-
-/// \function getcwd()
-/// Get the current directory.
-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) {
- mp_raise_OSError(fresult_to_errno_table[res]);
- }
-
- return mp_obj_new_str(buf, strlen(buf), false);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
-
-/// \function listdir([dir])
-/// With no argument, list the current directory. Otherwise list the given directory.
-STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
- bool is_str_type = true;
- const char *path;
- if (n_args == 1) {
- if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
- is_str_type = false;
- }
- path = mp_obj_str_get_str(args[0]);
- } else {
- path = "";
- }
-
- // "hack" to list root directory
- if (path[0] == '/' && path[1] == '\0') {
- mp_obj_t dir_list = mp_obj_new_list(0, NULL);
- for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
- if (vfs != NULL) {
- mp_obj_list_append(dir_list, mp_obj_new_str(vfs->str + 1, vfs->len - 1, false));
- }
- }
- return dir_list;
- }
-
- return fat_vfs_listdir(path, is_str_type);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
-
-/// \function mkdir(path)
-/// Create a new directory.
-STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- FRESULT res = f_mkdir(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- case FR_EXIST:
- // TODO should be FileExistsError
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path));
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
-
-/// \function remove(path)
-/// Remove a file.
-STATIC mp_obj_t os_remove(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- // TODO check that path is actually a file before trying to unlink it
- FRESULT res = f_unlink(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
-
-/// \function rename(old_path, new_path)
-/// Rename a file
-STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
- const char *old_path = mp_obj_str_get_str(path_in);
- const char *new_path = mp_obj_str_get_str(path_out);
- FRESULT res = f_rename(old_path, new_path);
- if (res == FR_EXIST) {
- // if new_path exists then try removing it
- res = f_unlink(new_path);
- if (res == FR_OK) {
- // try to rename again
- res = f_rename(old_path, new_path);
- }
- }
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error renaming file '%s' to '%s'", old_path, new_path));
- }
-
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
-
-/// \function rmdir(path)
-/// Remove a directory.
-STATIC mp_obj_t os_rmdir(mp_obj_t path_o) {
- const char *path = mp_obj_str_get_str(path_o);
- // TODO check that path is actually a directory before trying to unlink it
- FRESULT res = f_unlink(path);
- switch (res) {
- case FR_OK:
- return mp_const_none;
- default:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path));
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
-
-// Checks for path equality, ignoring trailing slashes:
-// path_equal(/, /) -> true
-// path_equal(/flash//, /flash) -> true
-// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
-STATIC bool path_equal(const char *path, const char *path_canonical) {
- for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
- }
- if (*path_canonical != '\0') {
- return false;
- }
- for (; *path == '/'; ++path) {
- }
- return *path == '\0';
-}
-
-/// \function stat(path)
-/// Get the status of a file or directory.
-STATIC mp_obj_t os_stat(mp_obj_t path_in) {
- const char *path = mp_obj_str_get_str(path_in);
-
- FILINFO fno;
-#if _USE_LFN
- fno.lfname = NULL;
- fno.lfsize = 0;
-#endif
-
- FRESULT res;
- if (path_equal(path, "/")) {
- // stat root directory
- fno.fsize = 0;
- fno.fdate = 0;
- fno.ftime = 0;
- fno.fattrib = AM_DIR;
- } else {
- res = FR_NO_PATH;
- for (size_t i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(fs_user_mount)); ++i) {
- fs_user_mount_t *vfs = MP_STATE_PORT(fs_user_mount)[i];
- if (vfs != NULL && path_equal(path, vfs->str)) {
- // stat mounted device directory
- fno.fsize = 0;
- fno.fdate = 0;
- fno.ftime = 0;
- fno.fattrib = AM_DIR;
- res = FR_OK;
- }
- }
- if (res == FR_NO_PATH) {
- // stat normal file
- res = f_stat(path, &fno);
- }
- if (res != FR_OK) {
- mp_raise_OSError(fresult_to_errno_table[res]);
- }
- }
-
- mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
- mp_int_t mode = 0;
- if (fno.fattrib & AM_DIR) {
- mode |= 0x4000; // stat.S_IFDIR
- } else {
- mode |= 0x8000; // stat.S_IFREG
- }
- mp_int_t seconds = timeutils_seconds_since_2000(
- 1980 + ((fno.fdate >> 9) & 0x7f),
- (fno.fdate >> 5) & 0x0f,
- fno.fdate & 0x1f,
- (fno.ftime >> 11) & 0x1f,
- (fno.ftime >> 5) & 0x3f,
- 2 * (fno.ftime & 0x1f)
- );
- t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
- t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
- t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
- t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink
- t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
- t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
- t->items[6] = MP_OBJ_NEW_SMALL_INT(fno.fsize); // st_size
- t->items[7] = MP_OBJ_NEW_SMALL_INT(seconds); // st_atime
- t->items[8] = MP_OBJ_NEW_SMALL_INT(seconds); // st_mtime
- t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime
-
- return t;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
-
-STATIC mp_obj_t os_statvfs(mp_obj_t path_in) {
- const char *path = mp_obj_str_get_str(path_in);
-
- DWORD nclst;
- FATFS *fatfs;
- FRESULT res = f_getfree(path, &nclst, &fatfs);
- if (res != FR_OK) {
- goto error;
- }
-
- mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
-
- t->items[0] = MP_OBJ_NEW_SMALL_INT(fatfs->csize * 512); // f_bsize - block size
- t->items[1] = t->items[0]; // f_frsize - fragment size
- t->items[2] = MP_OBJ_NEW_SMALL_INT((fatfs->n_fatent - 2) * fatfs->csize); // f_blocks - total number of blocks
- t->items[3] = MP_OBJ_NEW_SMALL_INT(nclst); // f_bfree - number of free blocks
- t->items[4] = t->items[3]; // f_bavail - free blocks avail to unpriviledged users
- t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // f_files - # inodes
- t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree - # free inodes
- t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail - # free inodes avail to unpriviledges users
- t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags
- t->items[9] = MP_OBJ_NEW_SMALL_INT(_MAX_LFN); // f_namemax
-
- return t;
-
-error:
- mp_raise_OSError(fresult_to_errno_table[res]);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_statvfs_obj, os_statvfs);
-
/// \function sync()
/// Sync all filesystems.
STATIC mp_obj_t os_sync(void) {
- disk_ioctl(0, CTRL_SYNC, NULL);
- disk_ioctl(1, CTRL_SYNC, NULL);
- disk_ioctl(2, CTRL_SYNC, NULL);
+ for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
+ // this assumes that vfs->obj is fs_user_mount_t with block device functions
+ disk_ioctl(MP_OBJ_TO_PTR(vfs->obj), CTRL_SYNC, NULL);
+ }
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(mod_os_sync_obj, os_sync);
@@ -379,36 +128,37 @@ STATIC mp_obj_t os_dupterm(mp_uint_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_dupterm_obj, 0, 1, os_dupterm);
-STATIC const mp_map_elem_t os_module_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
+STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_uname), (mp_obj_t)&os_uname_obj },
+ { MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_rename),(mp_obj_t)&os_rename_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_statvfs), (mp_obj_t)&os_statvfs_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
+ { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
+ { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
+ { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) },
+ { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
+ { MP_ROM_QSTR(MP_QSTR_rename),MP_ROM_PTR(&mp_vfs_rename_obj)},
+ { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
+ { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
+ { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove
- { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&mod_os_sync_obj },
+ { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mod_os_sync_obj) },
/// \constant sep - separation character used in paths
- { MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
+ { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
#if MICROPY_HW_ENABLE_RNG
- { MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
+ { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) },
#endif
// these are MicroPython extensions
- { MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&mod_os_dupterm_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&fsuser_mount_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_umount), (mp_obj_t)&fsuser_umount_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&fsuser_mkfs_obj },
+ { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mod_os_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) },
};
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
diff --git a/stmhal/modusocket.c b/stmhal/modusocket.c
index 7ff890264..081a322ae 100644
--- a/stmhal/modusocket.c
+++ b/stmhal/modusocket.c
@@ -32,7 +32,7 @@
#include "py/objlist.h"
#include "py/runtime.h"
#include "py/mperrno.h"
-#include "netutils.h"
+#include "lib/netutils/netutils.h"
#include "modnetwork.h"
#if MICROPY_PY_USOCKET
@@ -347,20 +347,20 @@ STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
-STATIC const mp_map_elem_t socket_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&socket_close_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&socket_bind_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&socket_listen_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&socket_sendto_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&socket_recvfrom_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&socket_setsockopt_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&socket_settimeout_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&socket_setblocking_obj },
+STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&socket_close_obj) },
+ { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) },
+ { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socket_bind_obj) },
+ { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socket_listen_obj) },
+ { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socket_accept_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socket_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socket_send_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) },
+ { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) },
+ { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) },
+ { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
};
STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
@@ -380,7 +380,7 @@ STATIC const mp_obj_type_t socket_type = {
.name = MP_QSTR_socket,
.make_new = socket_make_new,
.protocol = &socket_stream_p,
- .locals_dict = (mp_obj_t)&socket_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&socket_locals_dict,
};
/******************************************************************************/
@@ -388,7 +388,7 @@ STATIC const mp_obj_type_t socket_type = {
// function usocket.getaddrinfo(host, port)
STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
- mp_uint_t hlen;
+ size_t hlen;
const char *host = mp_obj_str_get_data(host_in, &hlen);
mp_int_t port = mp_obj_get_int(port_in);
@@ -417,28 +417,28 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);
-STATIC const mp_map_elem_t mp_module_usocket_globals_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usocket) },
+STATIC const mp_rom_map_elem_t mp_module_usocket_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usocket) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&mod_usocket_getaddrinfo_obj },
+ { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) },
+ { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&mod_usocket_getaddrinfo_obj) },
// class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET6), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET6) },
+ { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) },
+ { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(MOD_NETWORK_AF_INET6) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_DGRAM) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_RAW) },
+ { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(MOD_NETWORK_SOCK_STREAM) },
+ { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(MOD_NETWORK_SOCK_DGRAM) },
+ { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(MOD_NETWORK_SOCK_RAW) },
/*
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_IP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_ICMP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_ICMP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV4), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_IPV4) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_TCP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_TCP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_UDP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_IPV6), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_IPV6) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_RAW), MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_IPPROTO_RAW) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(MOD_NETWORK_IPPROTO_IP) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_ICMP), MP_ROM_INT(MOD_NETWORK_IPPROTO_ICMP) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV4), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV4) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(MOD_NETWORK_IPPROTO_TCP) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_UDP), MP_ROM_INT(MOD_NETWORK_IPPROTO_UDP) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV6), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV6) },
+ { MP_ROM_QSTR(MP_QSTR_IPPROTO_RAW), MP_ROM_INT(MOD_NETWORK_IPPROTO_RAW) },
*/
};
diff --git a/stmhal/modutime.c b/stmhal/modutime.c
index 7f2c549bd..97af35c49 100644
--- a/stmhal/modutime.c
+++ b/stmhal/modutime.c
@@ -31,9 +31,9 @@
#include "py/nlr.h"
#include "py/smallint.h"
#include "py/obj.h"
+#include "lib/timeutils/timeutils.h"
#include "extmod/utime_mphal.h"
#include "systick.h"
-#include "timeutils.h"
#include "portmodules.h"
#include "rtc.h"
@@ -100,7 +100,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
/// the number of seconds since Jan 1, 2000.
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
- mp_uint_t len;
+ size_t len;
mp_obj_t *elem;
mp_obj_get_array(tuple, &len, &elem);
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index c9b5480c8..ac3c1f247 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -1,9 +1,9 @@
/*
- * This file is part of the Micro Python project, http://micropython.org/
+ * This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
- * Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2013-2017 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,6 +24,9 @@
* THE SOFTWARE.
*/
+// Options to control how MicroPython is built for this port,
+// overriding defaults in py/mpconfig.h.
+
#pragma once
#ifndef __INCLUDED_MPCONFIGPORT_H
#define __INCLUDED_MPCONFIGPORT_H
@@ -31,42 +34,48 @@
// board specific definitions
#include "mpconfigboard.h"
-// options to control how Micro Python is built
-
+// memory allocation policies
#define MICROPY_ALLOC_PATH_MAX (128)
+
+// emitters
#define MICROPY_PERSISTENT_CODE_LOAD (1)
#define MICROPY_EMIT_THUMB (1)
#define MICROPY_EMIT_INLINE_THUMB (1)
+
+// compiler configuration
#define MICROPY_COMP_MODULE_CONST (1)
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1)
+#define MICROPY_COMP_RETURN_IF_EXPR (1)
+
+// optimisations
+#define MICROPY_OPT_COMPUTED_GOTO (1)
+#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
+#define MICROPY_OPT_MPZ_BITWISE (1)
+
+// Python internal features
+#define MICROPY_READER_VFS (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_FINALISER (1)
#define MICROPY_STACK_CHECK (1)
+#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
+#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
#define MICROPY_KBD_EXCEPTION (1)
#define MICROPY_HELPER_REPL (1)
#define MICROPY_REPL_EMACS_KEYS (1)
#define MICROPY_REPL_AUTO_INDENT (1)
-#define MICROPY_ENABLE_SOURCE_LINE (1)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
+#define MICROPY_ENABLE_SOURCE_LINE (1)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
-#define MICROPY_OPT_COMPUTED_GOTO (1)
-#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
-#define MICROPY_OPT_MPZ_BITWISE (1)
-#define MICROPY_READER_FATFS (1)
-
-// fatfs configuration used in ffconf.h
-#define MICROPY_FATFS_ENABLE_LFN (1)
-#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
-#define MICROPY_FATFS_USE_LABEL (1)
-#define MICROPY_FATFS_RPATH (2)
-#define MICROPY_FATFS_VOLUMES (4)
-#define MICROPY_FATFS_MULTI_PARTITION (1)
-#define MICROPY_FSUSERMOUNT (1)
-
#define MICROPY_STREAMS_NON_BLOCK (1)
#define MICROPY_MODULE_WEAK_LINKS (1)
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
#define MICROPY_USE_INTERNAL_ERRNO (1)
+#define MICROPY_ENABLE_SCHEDULER (1)
+#define MICROPY_SCHEDULER_DEPTH (8)
+#define MICROPY_VFS (1)
+#define MICROPY_VFS_FAT (1)
+
+// control over Python builtins
#define MICROPY_PY_FUNCTION_ATTRS (1)
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
#define MICROPY_PY_BUILTINS_STR_CENTER (1)
@@ -74,39 +83,49 @@
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
#define MICROPY_PY_BUILTINS_FROZENSET (1)
-#define MICROPY_PY_BUILTINS_EXECFILE (1)
-#define MICROPY_PY_BUILTINS_COMPILE (1)
+#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
+#define MICROPY_PY_BUILTINS_COMPILE (1)
+#define MICROPY_PY_BUILTINS_EXECFILE (1)
+#define MICROPY_PY_BUILTINS_INPUT (1)
+#define MICROPY_PY_BUILTINS_POW3 (1)
+#define MICROPY_PY_BUILTINS_HELP (1)
+#define MICROPY_PY_BUILTINS_HELP_TEXT stmhal_help_text
+#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
-#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
-#define MICROPY_PY_SYS_EXIT (1)
+#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
+#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1)
+#define MICROPY_PY_CMATH (1)
+#define MICROPY_PY_IO (1)
+#define MICROPY_PY_IO_FILEIO (1)
#define MICROPY_PY_SYS_MAXSIZE (1)
+#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_STDFILES (1)
#define MICROPY_PY_SYS_STDIO_BUFFER (1)
#ifndef MICROPY_PY_SYS_PLATFORM // let boards override it if they want
#define MICROPY_PY_SYS_PLATFORM "pyboard"
#endif
-#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
-#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1)
-#define MICROPY_PY_CMATH (1)
-#define MICROPY_PY_IO (1)
-#define MICROPY_PY_IO_FILEIO (1)
#define MICROPY_PY_UERRNO (1)
-#define MICROPY_PY_UBINASCII (1)
-#define MICROPY_PY_URANDOM (1)
-#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
-#define MICROPY_PY_USELECT (1)
+#define MICROPY_PY_THREAD (0)
+#define MICROPY_PY_THREAD_GIL (0)
+
+// extended modules
#define MICROPY_PY_UCTYPES (1)
#define MICROPY_PY_UZLIB (1)
#define MICROPY_PY_UJSON (1)
#define MICROPY_PY_URE (1)
#define MICROPY_PY_UHEAPQ (1)
-#define MICROPY_PY_UTIMEQ (1)
#define MICROPY_PY_UHASHLIB (1)
+#define MICROPY_PY_UBINASCII (1)
+#define MICROPY_PY_URANDOM (1)
+#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
+#define MICROPY_PY_USELECT (1)
+#define MICROPY_PY_UTIMEQ (1)
#define MICROPY_PY_UTIME_MP_HAL (1)
#define MICROPY_PY_MACHINE (1)
#define MICROPY_PY_MACHINE_PULSE (1)
+#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
#define MICROPY_PY_MACHINE_I2C (1)
#define MICROPY_PY_MACHINE_I2C_MAKE_NEW machine_hard_i2c_make_new
#define MICROPY_PY_MACHINE_SPI (1)
@@ -116,22 +135,31 @@
#define MICROPY_PY_MACHINE_SPI_MIN_DELAY (0)
#define MICROPY_PY_MACHINE_SPI_MAX_BAUDRATE (HAL_RCC_GetSysClockFreq() / 48)
#define MICROPY_PY_FRAMEBUF (1)
-
#ifndef MICROPY_PY_USOCKET
#define MICROPY_PY_USOCKET (1)
#endif
-
#ifndef MICROPY_PY_NETWORK
#define MICROPY_PY_NETWORK (1)
#endif
-#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
-#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
+// fatfs configuration used in ffconf.h
+#define MICROPY_FATFS_ENABLE_LFN (1)
+#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
+#define MICROPY_FATFS_USE_LABEL (1)
+#define MICROPY_FATFS_RPATH (2)
+#define MICROPY_FATFS_MULTI_PARTITION (1)
+
+// TODO these should be generic, not bound to fatfs
+#define mp_type_fileio fatfs_type_fileio
+#define mp_type_textio fatfs_type_textio
+
+// use vfs's functions for import stat and builtin open
+#define mp_import_stat mp_vfs_import_stat
+#define mp_builtin_open mp_vfs_open
+#define mp_builtin_open_obj mp_vfs_open_obj
// extra built in names to add to the global namespace
#define MICROPY_PORT_BUILTINS \
- { MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \
- { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
// extra built in modules to add to the list of known ones
@@ -238,8 +266,6 @@ extern const struct _mp_obj_module_t mp_module_network;
// type definitions for the specific machine
-#define BYTES_PER_WORD (4)
-
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
#define MP_SSIZE_MAX (0x7fffffff)
@@ -275,7 +301,28 @@ static inline mp_uint_t disable_irq(void) {
#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
-#define MICROPY_EVENT_POLL_HOOK __WFI();
+
+#if MICROPY_PY_THREAD
+#define MICROPY_EVENT_POLL_HOOK \
+ do { \
+ extern void mp_handle_pending(void); \
+ mp_handle_pending(); \
+ if (pyb_thread_enabled) { \
+ MP_THREAD_GIL_EXIT(); \
+ pyb_thread_yield(); \
+ MP_THREAD_GIL_ENTER(); \
+ } else { \
+ __WFI(); \
+ } \
+ } while (0);
+#else
+#define MICROPY_EVENT_POLL_HOOK \
+ do { \
+ extern void mp_handle_pending(void); \
+ mp_handle_pending(); \
+ __WFI(); \
+ } while (0);
+#endif
// There is no classical C heap in bare-metal ports, only Python
// garbage-collected heap. For completeness, emulate C heap via
diff --git a/stmhal/mphalport.c b/stmhal/mphalport.c
index 6893701f5..dff781ff2 100644
--- a/stmhal/mphalport.c
+++ b/stmhal/mphalport.c
@@ -21,10 +21,6 @@ NORETURN void mp_hal_raise(HAL_StatusTypeDef status) {
mp_raise_OSError(mp_hal_status_to_errno_table[status]);
}
-void mp_hal_set_interrupt_char(int c) {
- usb_vcp_set_interrupt_char(c);
-}
-
int mp_hal_stdin_rx_chr(void) {
for (;;) {
#if 0
@@ -43,7 +39,7 @@ 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));
}
- __WFI();
+ MICROPY_EVENT_POLL_HOOK
}
}
@@ -76,6 +72,10 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
void mp_hal_ticks_cpu_enable(void) {
if (!mp_hal_ticks_cpu_enabled) {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+ #if defined(__CORTEX_M) && __CORTEX_M == 7
+ // on Cortex-M7 we must unlock the DWT before writing to its registers
+ DWT->LAR = 0xc5acce55;
+ #endif
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
mp_hal_ticks_cpu_enabled = true;
@@ -110,6 +110,10 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {
#endif
#if defined(GPIOG) && defined(__GPIOG_CLK_ENABLE)
} else if (gpio == GPIOG) {
+ #if defined(STM32L476xx) || defined(STM32L486xx)
+ // Port G pins 2 thru 15 are powered using VddIO2 on these MCUs.
+ HAL_PWREx_EnableVddIO2();
+ #endif
__GPIOG_CLK_ENABLE();
#endif
#ifdef __GPIOH_CLK_ENABLE
diff --git a/stmhal/mphalport.h b/stmhal/mphalport.h
index 7204d4bd3..77cb0204d 100644
--- a/stmhal/mphalport.h
+++ b/stmhal/mphalport.h
@@ -10,8 +10,8 @@
#define MP_HAL_CLEAN_DCACHE(addr, size)
#elif defined(MCU_SERIES_F7)
#define MP_HAL_UNIQUE_ID_ADDRESS (0x1ff0f420)
-#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size) (SCB_CleanInvalidateDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
-#define MP_HAL_CLEAN_DCACHE(addr, size) (SCB_CleanDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
+#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size) (SCB_CleanInvalidateDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)((uint8_t*)addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
+#define MP_HAL_CLEAN_DCACHE(addr, size) (SCB_CleanDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)((uint8_t*)addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
#elif defined(MCU_SERIES_L4)
#define MP_HAL_UNIQUE_ID_ADDRESS (0x1fff7590)
#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size)
@@ -27,13 +27,7 @@ void mp_hal_set_interrupt_char(int c); // -1 to disable
// timing functions
-#include "stmhal/systick.h"
-
-#define mp_hal_delay_ms HAL_Delay
-#define mp_hal_delay_us(us) sys_tick_udelay(us)
-#define mp_hal_delay_us_fast(us) sys_tick_udelay(us)
-#define mp_hal_ticks_ms HAL_GetTick
-#define mp_hal_ticks_us() sys_tick_get_microseconds()
+#define mp_hal_delay_us_fast(us) mp_hal_delay_us(us)
extern bool mp_hal_ticks_cpu_enabled;
void mp_hal_ticks_cpu_enable(void);
diff --git a/stmhal/mpthreadport.c b/stmhal/mpthreadport.c
new file mode 100644
index 000000000..d7c5b569b
--- /dev/null
+++ b/stmhal/mpthreadport.c
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include "py/mpconfig.h"
+#include "py/mpstate.h"
+#include "py/gc.h"
+#include "py/mpthread.h"
+#include "gccollect.h"
+
+#if MICROPY_PY_THREAD
+
+// the mutex controls access to the linked list
+STATIC mp_thread_mutex_t thread_mutex;
+
+void mp_thread_init(void) {
+ mp_thread_mutex_init(&thread_mutex);
+ mp_thread_set_state(&mp_state_ctx.thread);
+}
+
+void mp_thread_gc_others(void) {
+ mp_thread_mutex_lock(&thread_mutex, 1);
+ for (pyb_thread_t *th = pyb_thread_all; th != NULL; th = th->all_next) {
+ gc_collect_root((void**)&th, 1);
+ gc_collect_root(&th->arg, 1);
+ gc_collect_root(&th->stack, 1);
+ if (th != pyb_thread_cur) {
+ gc_collect_root(th->stack, th->stack_len);
+ }
+ }
+ mp_thread_mutex_unlock(&thread_mutex);
+}
+
+void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
+ if (*stack_size == 0) {
+ *stack_size = 4096; // default stack size
+ } else if (*stack_size < 2048) {
+ *stack_size = 2048; // minimum stack size
+ }
+
+ // round stack size to a multiple of the word size
+ size_t stack_len = *stack_size / sizeof(uint32_t);
+ *stack_size = stack_len * sizeof(uint32_t);
+
+ // allocate stack and linked-list node (must be done outside thread_mutex lock)
+ uint32_t *stack = m_new(uint32_t, stack_len);
+ pyb_thread_t *th = m_new_obj(pyb_thread_t);
+
+ mp_thread_mutex_lock(&thread_mutex, 1);
+
+ // create thread
+ uint32_t id = pyb_thread_new(th, stack, stack_len, entry, arg);
+ if (id == 0) {
+ mp_thread_mutex_unlock(&thread_mutex);
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't create thread"));
+ }
+
+ mp_thread_mutex_unlock(&thread_mutex);
+
+ // adjust stack_size to provide room to recover from hitting the limit
+ *stack_size -= 1024;
+}
+
+void mp_thread_start(void) {
+}
+
+void mp_thread_finish(void) {
+}
+
+#endif // MICROPY_PY_THREAD
diff --git a/stmhal/builtin_open.c b/stmhal/mpthreadport.h
index 697eec8ea..3d8b4ef01 100644
--- a/stmhal/builtin_open.c
+++ b/stmhal/mpthreadport.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2013, 2014 Damien P. George
+ * Copyright (c) 2016 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,8 +23,35 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#ifndef __MICROPY_INCLUDED_STMHAL_MPTHREADPORT_H__
+#define __MICROPY_INCLUDED_STMHAL_MPTHREADPORT_H__
-#include "py/runtime.h"
-#include "extmod/vfs_fat_file.h"
+#include "py/mpthread.h"
+#include "pybthread.h"
-MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, fatfs_builtin_open);
+typedef pyb_mutex_t mp_thread_mutex_t;
+
+void mp_thread_init(void);
+void mp_thread_gc_others(void);
+
+static inline void mp_thread_set_state(void *state) {
+ pyb_thread_set_local(state);
+}
+
+static inline struct _mp_state_thread_t *mp_thread_get_state(void) {
+ return pyb_thread_get_local();
+}
+
+static inline void mp_thread_mutex_init(mp_thread_mutex_t *m) {
+ pyb_mutex_init(m);
+}
+
+static inline int mp_thread_mutex_lock(mp_thread_mutex_t *m, int wait) {
+ return pyb_mutex_lock(m, wait);
+}
+
+static inline void mp_thread_mutex_unlock(mp_thread_mutex_t *m) {
+ pyb_mutex_unlock(m);
+}
+
+#endif // __MICROPY_INCLUDED_STMHAL_MPTHREADPORT_H__
diff --git a/stmhal/pendsv.c b/stmhal/pendsv.c
index ff4480eed..200d13a5a 100644
--- a/stmhal/pendsv.c
+++ b/stmhal/pendsv.c
@@ -29,6 +29,7 @@
#include "py/mpstate.h"
#include "py/runtime.h"
+#include "lib/utils/interrupt_char.h"
#include "pendsv.h"
#include "irq.h"
@@ -52,12 +53,12 @@ void pendsv_init(void) {
// PENDSV feature. This will wait until all interrupts are finished then raise
// the given exception object using nlr_jump in the context of the top-level
// thread.
-void pendsv_nlr_jump(void *o) {
+void pendsv_kbd_intr(void) {
if (MP_STATE_VM(mp_pending_exception) == MP_OBJ_NULL) {
- MP_STATE_VM(mp_pending_exception) = o;
+ mp_keyboard_interrupt();
} else {
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
- pendsv_object = o;
+ pendsv_object = &MP_STATE_VM(mp_kbd_exception);
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
}
@@ -70,25 +71,57 @@ void pendsv_isr_handler(void) {
// on entry to this (naked) function, stack has the following layout:
//
// stack layout with DEBUG disabled:
- // sp[6]: pc
- // sp[5]: ?
- // sp[4]: ?
- // sp[3]: ?
- // sp[2]: ?
- // sp[1]: ?
+ // sp[6]: pc=r15
+ // sp[5]: lr=r14
+ // sp[4]: r12
+ // sp[3]: r3
+ // sp[2]: r2
+ // sp[1]: r1
// sp[0]: r0
//
// stack layout with DEBUG enabled:
- // sp[8]: pc
- // sp[7]: lr
- // sp[6]: ?
- // sp[5]: ?
- // sp[4]: ?
- // sp[3]: ?
+ // sp[8]: pc=r15
+ // sp[7]: lr=r14
+ // sp[6]: r12
+ // sp[5]: r3
+ // sp[4]: r2
+ // sp[3]: r1
// sp[2]: r0
// sp[1]: 0xfffffff9
// sp[0]: ?
+#if MICROPY_PY_THREAD
+ __asm volatile (
+ "ldr r1, pendsv_object_ptr\n"
+ "ldr r0, [r1]\n"
+ "cmp r0, 0\n"
+ "beq .no_obj\n"
+ "str r0, [sp, #0]\n" // store to r0 on stack
+ "mov r0, #0\n"
+ "str r0, [r1]\n" // clear pendsv_object
+ "ldr r0, nlr_jump_ptr\n"
+ "str r0, [sp, #24]\n" // store to pc on stack
+ "bx lr\n" // return from interrupt; will return to nlr_jump
+
+ ".no_obj:\n" // pendsv_object==NULL
+ "push {r4-r11, lr}\n"
+ "vpush {s16-s31}\n"
+ "mrs r5, primask\n" // save PRIMASK in r5
+ "cpsid i\n" // disable interrupts while we change stacks
+ "mov r0, sp\n" // pass sp to save
+ "mov r4, lr\n" // save lr because we are making a call
+ "bl pyb_thread_next\n" // get next thread to execute
+ "mov lr, r4\n" // restore lr
+ "mov sp, r0\n" // switch stacks
+ "msr primask, r5\n" // reenable interrupts
+ "vpop {s16-s31}\n"
+ "pop {r4-r11, lr}\n"
+ "bx lr\n" // return from interrupt; will return to new thread
+ ".align 2\n"
+ "pendsv_object_ptr: .word pendsv_object\n"
+ "nlr_jump_ptr: .word nlr_jump\n"
+ );
+#else
__asm volatile (
"ldr r0, pendsv_object_ptr\n"
"ldr r0, [r0]\n"
@@ -108,6 +141,7 @@ void pendsv_isr_handler(void) {
"pendsv_object_ptr: .word pendsv_object\n"
"nlr_jump_ptr: .word nlr_jump\n"
);
+#endif
/*
uint32_t x[2] = {0x424242, 0xdeaddead};
diff --git a/stmhal/pendsv.h b/stmhal/pendsv.h
index 7886d9f98..77c78d4c1 100644
--- a/stmhal/pendsv.h
+++ b/stmhal/pendsv.h
@@ -25,7 +25,7 @@
*/
void pendsv_init(void);
-void pendsv_nlr_jump(void *val);
+void pendsv_kbd_intr(void);
// since we play tricks with the stack, the compiler must not generate a
// prelude for this function
diff --git a/stmhal/pin.c b/stmhal/pin.c
index 9c4eb8ba1..db7596900 100644
--- a/stmhal/pin.c
+++ b/stmhal/pin.c
@@ -31,6 +31,7 @@
#include "py/nlr.h"
#include "py/runtime.h"
#include "py/mphal.h"
+#include "extmod/virtpin.h"
#include "pin.h"
/// \moduleref pyb
@@ -244,7 +245,7 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *pin, mp_uint_t n_args, cons
/// \classmethod \constructor(id, ...)
/// Create a new Pin object associated with the id. If additional arguments are given,
/// they are used to initialise the pin. See `init`.
-STATIC mp_obj_t pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
// Run an argument through the mapper and return the result.
@@ -399,23 +400,19 @@ STATIC mp_obj_t pin_value(mp_uint_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
-/// \method low()
-/// Set the pin to a low logic level.
-STATIC mp_obj_t pin_low(mp_obj_t self_in) {
+STATIC mp_obj_t pin_off(mp_obj_t self_in) {
pin_obj_t *self = self_in;
mp_hal_pin_low(self);
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_off_obj, pin_off);
-/// \method high()
-/// Set the pin to a high logic level.
-STATIC mp_obj_t pin_high(mp_obj_t self_in) {
+STATIC mp_obj_t pin_on(mp_obj_t self_in) {
pin_obj_t *self = self_in;
mp_hal_pin_high(self);
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_on_obj, pin_on);
/// \method name()
/// Get the pin name.
@@ -495,60 +492,84 @@ STATIC mp_obj_t pin_af(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_obj, pin_af);
-STATIC const mp_map_elem_t pin_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pin_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pin_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pin_value_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pin_low_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_names), (mp_obj_t)&pin_names_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_af_list), (mp_obj_t)&pin_af_list_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_gpio), (mp_obj_t)&pin_gpio_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_mode), (mp_obj_t)&pin_mode_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_pull), (mp_obj_t)&pin_pull_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_af), (mp_obj_t)&pin_af_obj },
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pin_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&pin_value_obj) },
+ { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&pin_off_obj) },
+ { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&pin_on_obj) },
+ // Legacy names as used by pyb.Pin
+ { MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&pin_off_obj) },
+ { MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&pin_on_obj) },
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&pin_name_obj) },
+ { MP_ROM_QSTR(MP_QSTR_names), MP_ROM_PTR(&pin_names_obj) },
+ { MP_ROM_QSTR(MP_QSTR_af_list), MP_ROM_PTR(&pin_af_list_obj) },
+ { MP_ROM_QSTR(MP_QSTR_port), MP_ROM_PTR(&pin_port_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&pin_pin_obj) },
+ { MP_ROM_QSTR(MP_QSTR_gpio), MP_ROM_PTR(&pin_gpio_obj) },
+ { MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&pin_mode_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pull), MP_ROM_PTR(&pin_pull_obj) },
+ { MP_ROM_QSTR(MP_QSTR_af), MP_ROM_PTR(&pin_af_obj) },
// class methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_mapper), (mp_obj_t)&pin_mapper_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_dict), (mp_obj_t)&pin_map_dict_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_debug), (mp_obj_t)&pin_debug_obj },
+ { MP_ROM_QSTR(MP_QSTR_mapper), MP_ROM_PTR(&pin_mapper_obj) },
+ { MP_ROM_QSTR(MP_QSTR_dict), MP_ROM_PTR(&pin_map_dict_obj) },
+ { MP_ROM_QSTR(MP_QSTR_debug), MP_ROM_PTR(&pin_debug_obj) },
// class attributes
- { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&pin_board_pins_obj_type },
- { MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj_type },
+ { MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&pin_board_pins_obj_type) },
+ { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&pin_cpu_pins_obj_type) },
// class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_INPUT) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OUT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ALT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ALT_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ANALOG), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_ANALOG) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) },
+ { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_INPUT) },
+ { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUTPUT_PP) },
+ { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_OUTPUT_OD) },
+ { MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(GPIO_MODE_AF_PP) },
+ { MP_ROM_QSTR(MP_QSTR_ALT_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_AF_OD) },
+ { MP_ROM_QSTR(MP_QSTR_ANALOG), MP_ROM_INT(GPIO_MODE_ANALOG) },
+ { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(GPIO_PULLUP) },
+ { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(GPIO_PULLDOWN) },
// legacy class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_OUT_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OUT_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_AF_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) },
+ { MP_ROM_QSTR(MP_QSTR_OUT_PP), MP_ROM_INT(GPIO_MODE_OUTPUT_PP) },
+ { MP_ROM_QSTR(MP_QSTR_OUT_OD), MP_ROM_INT(GPIO_MODE_OUTPUT_OD) },
+ { MP_ROM_QSTR(MP_QSTR_AF_PP), MP_ROM_INT(GPIO_MODE_AF_PP) },
+ { MP_ROM_QSTR(MP_QSTR_AF_OD), MP_ROM_INT(GPIO_MODE_AF_OD) },
+ { MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(GPIO_NOPULL) },
#include "genhdr/pins_af_const.h"
};
STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table);
+STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
+ (void)errcode;
+ pin_obj_t *self = self_in;
+
+ switch (request) {
+ case MP_PIN_READ: {
+ return mp_hal_pin_read(self);
+ }
+ case MP_PIN_WRITE: {
+ mp_hal_pin_write(self, arg);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+STATIC const mp_pin_p_t pin_pin_p = {
+ .ioctl = pin_ioctl,
+};
+
const mp_obj_type_t pin_type = {
{ &mp_type_type },
.name = MP_QSTR_Pin,
.print = pin_print,
- .make_new = pin_make_new,
+ .make_new = mp_pin_make_new,
.call = pin_call,
- .locals_dict = (mp_obj_t)&pin_locals_dict,
+ .protocol = &pin_pin_p,
+ .locals_dict = (mp_obj_dict_t*)&pin_locals_dict,
};
/// \moduleref pyb
@@ -611,10 +632,10 @@ STATIC mp_obj_t pin_af_reg(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_reg_obj, pin_af_reg);
-STATIC const mp_map_elem_t pin_af_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_index), (mp_obj_t)&pin_af_index_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_af_name_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_reg), (mp_obj_t)&pin_af_reg_obj },
+STATIC const mp_rom_map_elem_t pin_af_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_index), MP_ROM_PTR(&pin_af_index_obj) },
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&pin_af_name_obj) },
+ { MP_ROM_QSTR(MP_QSTR_reg), MP_ROM_PTR(&pin_af_reg_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pin_af_locals_dict, pin_af_locals_dict_table);
@@ -622,5 +643,5 @@ const mp_obj_type_t pin_af_type = {
{ &mp_type_type },
.name = MP_QSTR_PinAF,
.print = pin_af_obj_print,
- .locals_dict = (mp_obj_t)&pin_af_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pin_af_locals_dict,
};
diff --git a/stmhal/pin_defs_stmhal.h b/stmhal/pin_defs_stmhal.h
index 80c967016..d6a2ef424 100644
--- a/stmhal/pin_defs_stmhal.h
+++ b/stmhal/pin_defs_stmhal.h
@@ -48,6 +48,7 @@ enum {
AF_FN_UART = AF_FN_USART,
AF_FN_SPI,
AF_FN_I2S,
+ AF_FN_SDMMC,
};
enum {
@@ -85,6 +86,13 @@ enum {
AF_PIN_TYPE_I2S_SD,
AF_PIN_TYPE_I2S_WS,
AF_PIN_TYPE_I2S_EXTSD,
+
+ AF_PIN_TYPE_SDMMC_CK = 0,
+ AF_PIN_TYPE_SDMMC_CMD,
+ AF_PIN_TYPE_SDMMC_D0,
+ AF_PIN_TYPE_SDMMC_D1,
+ AF_PIN_TYPE_SDMMC_D2,
+ AF_PIN_TYPE_SDMMC_D3,
};
// The HAL uses a slightly different naming than we chose, so we provide
@@ -109,13 +117,15 @@ enum {
// Note that SPI and I2S are really the same peripheral as far as the HAL
// is concerned, so there is no I2S_TypeDef.
+// We use void* for SDMMC because not all MCUs have the SDMMC_TypeDef type.
#define PIN_DEFS_PORT_AF_UNION \
TIM_TypeDef *TIM; \
I2C_TypeDef *I2C; \
USART_TypeDef *USART; \
USART_TypeDef *UART; \
SPI_TypeDef *SPI;\
- SPI_TypeDef *I2S;
+ SPI_TypeDef *I2S; \
+ void *SDMMC; \
typedef GPIO_TypeDef pin_gpio_t;
diff --git a/stmhal/pybstdio.c b/stmhal/pybstdio.c
index dec4f227a..bd15c583d 100644
--- a/stmhal/pybstdio.c
+++ b/stmhal/pybstdio.c
@@ -92,19 +92,19 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stdio_obj___exit___obj, 4, 4, stdio_o
// TODO gc hook to close the file if not already closed
-STATIC const mp_map_elem_t stdio_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t stdio_locals_dict_table[] = {
#if MICROPY_PY_SYS_STDIO_BUFFER
- { MP_OBJ_NEW_QSTR(MP_QSTR_buffer), (mp_obj_t)&stdio_buffer_obj },
+ { MP_ROM_QSTR(MP_QSTR_buffer), MP_ROM_PTR(&stdio_buffer_obj) },
#endif
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_readlines), (mp_obj_t)&mp_stream_unbuffered_readlines_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&mp_identity_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&mp_identity_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR___enter__), (mp_obj_t)&mp_identity_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR___exit__), (mp_obj_t)&stdio_obj___exit___obj },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
+ { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)},
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_identity_obj) },
+ { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_identity_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&stdio_obj___exit___obj) },
};
STATIC MP_DEFINE_CONST_DICT(stdio_locals_dict, stdio_locals_dict_table);
@@ -120,10 +120,10 @@ STATIC const mp_obj_type_t stdio_obj_type = {
.name = MP_QSTR_FileIO,
// TODO .make_new?
.print = stdio_obj_print,
- .getiter = mp_identity,
+ .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &stdio_obj_stream_p,
- .locals_dict = (mp_obj_t)&stdio_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&stdio_locals_dict,
};
const pyb_stdio_obj_t mp_sys_stdin_obj = {{&stdio_obj_type}, .fd = STDIO_FD_IN};
@@ -153,7 +153,7 @@ STATIC const mp_obj_type_t stdio_buffer_obj_type = {
{ &mp_type_type },
.name = MP_QSTR_FileIO,
.print = stdio_obj_print,
- .getiter = mp_identity,
+ .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &stdio_buffer_obj_stream_p,
.locals_dict = (mp_obj_t)&stdio_locals_dict,
diff --git a/stmhal/pybthread.c b/stmhal/pybthread.c
new file mode 100644
index 000000000..6baf88f66
--- /dev/null
+++ b/stmhal/pybthread.c
@@ -0,0 +1,237 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "py/obj.h"
+#include "gccollect.h"
+#include "irq.h"
+#include "pybthread.h"
+
+#if MICROPY_PY_THREAD
+
+#define PYB_MUTEX_UNLOCKED ((void*)0)
+#define PYB_MUTEX_LOCKED ((void*)1)
+
+// These macros are used when we only need to protect against a thread
+// switch; other interrupts are still allowed to proceed.
+#define RAISE_IRQ_PRI() raise_irq_pri(IRQ_PRI_PENDSV)
+#define RESTORE_IRQ_PRI(state) restore_irq_pri(state)
+
+extern void __fatal_error(const char*);
+
+volatile int pyb_thread_enabled;
+pyb_thread_t *volatile pyb_thread_all;
+pyb_thread_t *volatile pyb_thread_cur;
+
+static inline void pyb_thread_add_to_runable(pyb_thread_t *thread) {
+ thread->run_prev = pyb_thread_cur->run_prev;
+ thread->run_next = pyb_thread_cur;
+ pyb_thread_cur->run_prev->run_next = thread;
+ pyb_thread_cur->run_prev = thread;
+}
+
+static inline void pyb_thread_remove_from_runable(pyb_thread_t *thread) {
+ if (thread->run_next == thread) {
+ __fatal_error("deadlock");
+ }
+ thread->run_prev->run_next = thread->run_next;
+ thread->run_next->run_prev = thread->run_prev;
+}
+
+void pyb_thread_init(pyb_thread_t *thread) {
+ pyb_thread_enabled = 0;
+ pyb_thread_all = thread;
+ pyb_thread_cur = thread;
+ thread->sp = NULL; // will be set when this thread switches out
+ thread->local_state = 0; // will be set by mp_thread_init
+ thread->arg = NULL;
+ thread->stack = &_heap_end;
+ thread->stack_len = ((uint32_t)&_estack - (uint32_t)&_heap_end) / sizeof(uint32_t);
+ thread->all_next = NULL;
+ thread->run_prev = thread;
+ thread->run_next = thread;
+ thread->queue_next = NULL;
+}
+
+void pyb_thread_deinit() {
+ uint32_t irq_state = disable_irq();
+ pyb_thread_enabled = 0;
+ pyb_thread_all = pyb_thread_cur;
+ pyb_thread_cur->all_next = NULL;
+ pyb_thread_cur->run_prev = pyb_thread_cur;
+ pyb_thread_cur->run_next = pyb_thread_cur;
+ enable_irq(irq_state);
+}
+
+STATIC void pyb_thread_terminate(void) {
+ uint32_t irq_state = disable_irq();
+ pyb_thread_t *thread = pyb_thread_cur;
+ // take current thread off the run list
+ pyb_thread_remove_from_runable(thread);
+ // take current thread off the list of all threads
+ for (pyb_thread_t **n = (pyb_thread_t**)&pyb_thread_all;; n = &(*n)->all_next) {
+ if (*n == thread) {
+ *n = thread->all_next;
+ break;
+ }
+ }
+ // clean pointers as much as possible to help GC
+ thread->all_next = NULL;
+ thread->queue_next = NULL;
+ thread->stack = NULL;
+ if (pyb_thread_all->all_next == NULL) {
+ // only 1 thread left
+ pyb_thread_enabled = 0;
+ }
+ // thread switch will occur after we enable irqs
+ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
+ enable_irq(irq_state);
+ // should not return
+ __fatal_error("could not terminate");
+}
+
+uint32_t pyb_thread_new(pyb_thread_t *thread, void *stack, size_t stack_len, void *entry, void *arg) {
+ uint32_t *stack_top = (uint32_t*)stack + stack_len; // stack is full descending
+ *--stack_top = 0x01000000; // xPSR (thumb bit set)
+ *--stack_top = (uint32_t)entry & 0xfffffffe; // pc (must have bit 0 cleared, even for thumb code)
+ *--stack_top = (uint32_t)pyb_thread_terminate; // lr
+ *--stack_top = 0; // r12
+ *--stack_top = 0; // r3
+ *--stack_top = 0; // r2
+ *--stack_top = 0; // r1
+ *--stack_top = (uint32_t)arg; // r0
+ *--stack_top = 0xfffffff9; // lr (return to thread mode, non-FP, use MSP)
+ stack_top -= 8; // r4-r11
+ stack_top -= 16; // s16-s31 (we assume all threads use FP registers)
+ thread->sp = stack_top;
+ thread->local_state = 0;
+ thread->arg = arg;
+ thread->stack = stack;
+ thread->stack_len = stack_len;
+ thread->queue_next = NULL;
+ uint32_t irq_state = disable_irq();
+ pyb_thread_enabled = 1;
+ thread->all_next = pyb_thread_all;
+ pyb_thread_all = thread;
+ pyb_thread_add_to_runable(thread);
+ enable_irq(irq_state);
+ return (uint32_t)thread; // success
+}
+
+void pyb_thread_dump(void) {
+ if (!pyb_thread_enabled) {
+ printf("THREAD: only main thread\n");
+ } else {
+ printf("THREAD:\n");
+ for (pyb_thread_t *th = pyb_thread_all; th != NULL; th = th->all_next) {
+ bool runable = false;
+ for (pyb_thread_t *th2 = pyb_thread_cur;; th2 = th2->run_next) {
+ if (th == th2) {
+ runable = true;
+ break;
+ }
+ if (th2->run_next == pyb_thread_cur) {
+ break;
+ }
+ }
+ printf(" id=%p sp=%p sz=%u", th, th->stack, th->stack_len);
+ if (runable) {
+ printf(" (runable)");
+ }
+ printf("\n");
+ }
+ }
+}
+
+// should only be called from pendsv_isr_handler
+void *pyb_thread_next(void *sp) {
+ pyb_thread_cur->sp = sp;
+ pyb_thread_cur = pyb_thread_cur->run_next;
+ pyb_thread_cur->timeslice = 4; // in milliseconds
+ return pyb_thread_cur->sp;
+}
+
+void pyb_mutex_init(pyb_mutex_t *m) {
+ *m = PYB_MUTEX_UNLOCKED;
+}
+
+int pyb_mutex_lock(pyb_mutex_t *m, int wait) {
+ uint32_t irq_state = RAISE_IRQ_PRI();
+ if (*m == PYB_MUTEX_UNLOCKED) {
+ // mutex is available
+ *m = PYB_MUTEX_LOCKED;
+ RESTORE_IRQ_PRI(irq_state);
+ } else {
+ // mutex is locked
+ if (!wait) {
+ RESTORE_IRQ_PRI(irq_state);
+ return 0; // failed to lock mutex
+ }
+ if (*m == PYB_MUTEX_LOCKED) {
+ *m = pyb_thread_cur;
+ } else {
+ for (pyb_thread_t *n = *m;; n = n->queue_next) {
+ if (n->queue_next == NULL) {
+ n->queue_next = pyb_thread_cur;
+ break;
+ }
+ }
+ }
+ pyb_thread_cur->queue_next = NULL;
+ // take current thread off the run list
+ pyb_thread_remove_from_runable(pyb_thread_cur);
+ // thread switch will occur after we enable irqs
+ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
+ RESTORE_IRQ_PRI(irq_state);
+ // when we come back we have the mutex
+ }
+ return 1; // have mutex
+}
+
+void pyb_mutex_unlock(pyb_mutex_t *m) {
+ uint32_t irq_state = RAISE_IRQ_PRI();
+ if (*m == PYB_MUTEX_LOCKED) {
+ // no threads are blocked on the mutex
+ *m = PYB_MUTEX_UNLOCKED;
+ } else {
+ // at least one thread is blocked on this mutex
+ pyb_thread_t *th = *m;
+ if (th->queue_next == NULL) {
+ // no other threads are blocked
+ *m = PYB_MUTEX_LOCKED;
+ } else {
+ // at least one other thread is still blocked
+ *m = th->queue_next;
+ }
+ // put unblocked thread on runable list
+ pyb_thread_add_to_runable(th);
+ }
+ RESTORE_IRQ_PRI(irq_state);
+}
+
+#endif // MICROPY_PY_THREAD
diff --git a/stmhal/pybthread.h b/stmhal/pybthread.h
new file mode 100644
index 000000000..6edb2400e
--- /dev/null
+++ b/stmhal/pybthread.h
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STMHAL_PYBTHREAD_H
+#define MICROPY_INCLUDED_STMHAL_PYBTHREAD_H
+
+typedef struct _pyb_thread_t {
+ void *sp;
+ uint32_t local_state;
+ void *arg; // thread Python args, a GC root pointer
+ void *stack; // pointer to the stack
+ size_t stack_len; // number of words in the stack
+ uint32_t timeslice;
+ struct _pyb_thread_t *all_next;
+ struct _pyb_thread_t *run_prev;
+ struct _pyb_thread_t *run_next;
+ struct _pyb_thread_t *queue_next;
+} pyb_thread_t;
+
+typedef pyb_thread_t *pyb_mutex_t;
+
+extern volatile int pyb_thread_enabled;
+extern pyb_thread_t *volatile pyb_thread_all;
+extern pyb_thread_t *volatile pyb_thread_cur;
+
+void pyb_thread_init(pyb_thread_t *th);
+void pyb_thread_deinit();
+uint32_t pyb_thread_new(pyb_thread_t *th, void *stack, size_t stack_len, void *entry, void *arg);
+void pyb_thread_dump(void);
+
+static inline uint32_t pyb_thread_get_id(void) {
+ return (uint32_t)pyb_thread_cur;
+}
+
+static inline void pyb_thread_set_local(void *value) {
+ pyb_thread_cur->local_state = (uint32_t)value;
+}
+
+static inline void *pyb_thread_get_local(void) {
+ return (void*)pyb_thread_cur->local_state;
+}
+
+static inline void pyb_thread_yield(void) {
+ if (pyb_thread_cur->run_next == pyb_thread_cur) {
+ __WFI();
+ } else {
+ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
+ }
+}
+
+void pyb_mutex_init(pyb_mutex_t *m);
+int pyb_mutex_lock(pyb_mutex_t *m, int wait);
+void pyb_mutex_unlock(pyb_mutex_t *m);
+
+#endif // MICROPY_INCLUDED_STMHAL_PYBTHREAD_H
diff --git a/stmhal/rtc.c b/stmhal/rtc.c
index 4fa26d25b..bc9c889c2 100644
--- a/stmhal/rtc.c
+++ b/stmhal/rtc.c
@@ -718,12 +718,12 @@ mp_obj_t pyb_rtc_calibration(mp_uint_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_calibration_obj, 1, 2, pyb_rtc_calibration);
-STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_rtc_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_rtc_info_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_wakeup), (mp_obj_t)&pyb_rtc_wakeup_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_calibration), (mp_obj_t)&pyb_rtc_calibration_obj },
+STATIC const mp_rom_map_elem_t pyb_rtc_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_rtc_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&pyb_rtc_info_obj) },
+ { MP_ROM_QSTR(MP_QSTR_datetime), MP_ROM_PTR(&pyb_rtc_datetime_obj) },
+ { MP_ROM_QSTR(MP_QSTR_wakeup), MP_ROM_PTR(&pyb_rtc_wakeup_obj) },
+ { MP_ROM_QSTR(MP_QSTR_calibration), MP_ROM_PTR(&pyb_rtc_calibration_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
@@ -731,5 +731,5 @@ const mp_obj_type_t pyb_rtc_type = {
{ &mp_type_type },
.name = MP_QSTR_RTC,
.make_new = pyb_rtc_make_new,
- .locals_dict = (mp_obj_t)&pyb_rtc_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_rtc_locals_dict,
};
diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c
index a93b2b056..5a4b3b0e4 100644
--- a/stmhal/sdcard.c
+++ b/stmhal/sdcard.c
@@ -28,9 +28,9 @@
#include "py/nlr.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h"
-#include "extmod/fsusermount.h"
-#include "mphalport.h"
+#include "py/mphal.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs_fat.h"
#include "sdcard.h"
#include "pin.h"
@@ -43,11 +43,29 @@
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_L4)
+// The F7 has 2 SDMMC units but at the moment we only support using one of them in
+// a given build. If a boards config file defines MICROPY_HW_SDMMC2_CK then SDMMC2
+// is used, otherwise SDMMC1 is used.
+
+#if defined(MICROPY_HW_SDMMC2_CK)
+#define SDIO SDMMC2
+#define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC2_CLK_ENABLE()
+#define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC2_CLK_DISABLE()
+#define SDMMC_IRQn SDMMC2_IRQn
+#define SDMMC_TX_DMA dma_SDMMC_2_TX
+#define SDMMC_RX_DMA dma_SDMMC_2_RX
+#else
+#define SDIO SDMMC1
+#define SDMMC_CLK_ENABLE() __HAL_RCC_SDMMC1_CLK_ENABLE()
+#define SDMMC_CLK_DISABLE() __HAL_RCC_SDMMC1_CLK_DISABLE()
+#define SDMMC_IRQn SDMMC1_IRQn
+#define SDMMC_TX_DMA dma_SDIO_0_TX
+#define SDMMC_RX_DMA dma_SDIO_0_RX
+#endif
+
// The F7 & L4 series calls the peripheral SDMMC rather than SDIO, so provide some
// #defines for backwards compatability.
-#define SDIO SDMMC1
-
#define SDIO_CLOCK_EDGE_RISING SDMMC_CLOCK_EDGE_RISING
#define SDIO_CLOCK_EDGE_FALLING SDMMC_CLOCK_EDGE_FALLING
@@ -66,6 +84,16 @@
#define SDIO_TRANSFER_CLK_DIV SDMMC_TRANSFER_CLK_DIV
+#else
+
+// These are definitions for F4 MCUs so there is a common macro across all MCUs.
+
+#define SDMMC_CLK_ENABLE() __SDIO_CLK_ENABLE()
+#define SDMMC_CLK_DISABLE() __SDIO_CLK_DISABLE()
+#define SDMMC_IRQn SDIO_IRQn
+#define SDMMC_TX_DMA dma_SDIO_0_TX
+#define SDMMC_RX_DMA dma_SDIO_0_RX
+
#endif
// TODO: Since SDIO is fundamentally half-duplex, we really only need to
@@ -90,12 +118,23 @@ void sdcard_init(void) {
// Note: the mp_hal_pin_config function will configure the GPIO in
// fast mode which can do up to 50MHz. This should be plenty for SDIO
// which clocks up to 25MHz maximum.
+ #if defined(MICROPY_HW_SDMMC2_CK)
+ // Use SDMMC2 peripheral with pins provided by the board's config
+ mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_CK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
+ mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_CMD, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
+ mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
+ mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
+ mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
+ mp_hal_pin_config_alt(&MICROPY_HW_SDMMC2_D3, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, AF_FN_SDMMC, 2);
+ #else
+ // Default SDIO/SDMMC1 config
mp_hal_pin_config(&pin_C8, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
mp_hal_pin_config(&pin_C9, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
mp_hal_pin_config(&pin_C10, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
mp_hal_pin_config(&pin_C11, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
mp_hal_pin_config(&pin_C12, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
mp_hal_pin_config(&pin_D2, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_UP, GPIO_AF12_SDIO);
+ #endif
// configure the SD card detect pin
// we do this here so we can detect if the SD card is inserted before powering it on
@@ -104,18 +143,18 @@ void sdcard_init(void) {
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
// enable SDIO clock
- __SDIO_CLK_ENABLE();
+ SDMMC_CLK_ENABLE();
// NVIC configuration for SDIO interrupts
- HAL_NVIC_SetPriority(SDIO_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
- HAL_NVIC_EnableIRQ(SDIO_IRQn);
+ HAL_NVIC_SetPriority(SDMMC_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
+ HAL_NVIC_EnableIRQ(SDMMC_IRQn);
// GPIO have already been initialised by sdcard_init
}
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
- HAL_NVIC_DisableIRQ(SDIO_IRQn);
- __SDIO_CLK_DISABLE();
+ HAL_NVIC_DisableIRQ(SDMMC_IRQn);
+ SDMMC_CLK_DISABLE();
}
bool sdcard_is_present(void) {
@@ -145,7 +184,7 @@ bool sdcard_power_on(void) {
if (retry == 0) {
goto error;
}
- HAL_Delay(50);
+ mp_hal_delay_ms(50);
}
// configure the SD bus width for wide operation
@@ -184,6 +223,14 @@ void SDIO_IRQHandler(void) {
IRQ_EXIT(SDIO_IRQn);
}
+#if defined(MCU_SERIES_F7)
+void SDMMC2_IRQHandler(void) {
+ IRQ_ENTER(SDMMC2_IRQn);
+ HAL_SD_IRQHandler(&sd_handle);
+ IRQ_EXIT(SDMMC2_IRQn);
+}
+#endif
+
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
// check that SD card is initialised
if (sd_handle.Instance == NULL) {
@@ -214,7 +261,7 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo
// we must disable USB irqs to prevent MSC contention with SD card
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
- dma_init(&sd_rx_dma, &dma_SDIO_0_RX, &sd_handle);
+ dma_init(&sd_rx_dma, &SDMMC_RX_DMA, &sd_handle);
sd_handle.hdmarx = &sd_rx_dma;
// make sure cache is flushed and invalidated so when DMA updates the RAM
@@ -227,7 +274,7 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo
err = HAL_SD_CheckReadOperation(&sd_handle, 100000000);
}
- dma_deinit(&dma_SDIO_0_RX);
+ dma_deinit(&SDMMC_RX_DMA);
sd_handle.hdmarx = NULL;
restore_irq_pri(basepri);
@@ -274,7 +321,7 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
// we must disable USB irqs to prevent MSC contention with SD card
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
- dma_init(&sd_tx_dma, &dma_SDIO_0_TX, &sd_handle);
+ dma_init(&sd_tx_dma, &SDMMC_TX_DMA, &sd_handle);
sd_handle.hdmatx = &sd_tx_dma;
// make sure cache is flushed to RAM so the DMA can read the correct data
@@ -285,7 +332,7 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
// wait for DMA transfer to finish, with a large timeout
err = HAL_SD_CheckWriteOperation(&sd_handle, 100000000);
}
- dma_deinit(&dma_SDIO_0_TX);
+ dma_deinit(&SDMMC_TX_DMA);
sd_handle.hdmatx = NULL;
restore_irq_pri(basepri);
@@ -422,16 +469,16 @@ STATIC mp_obj_t pyb_sdcard_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_sdcard_ioctl_obj, pyb_sdcard_ioctl);
-STATIC const mp_map_elem_t pyb_sdcard_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_present), (mp_obj_t)&sd_present_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_power), (mp_obj_t)&sd_power_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&sd_info_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&sd_read_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&sd_write_obj },
+STATIC const mp_rom_map_elem_t pyb_sdcard_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_present), MP_ROM_PTR(&sd_present_obj) },
+ { MP_ROM_QSTR(MP_QSTR_power), MP_ROM_PTR(&sd_power_obj) },
+ { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&sd_info_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&sd_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&sd_write_obj) },
// block device protocol
- { MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_sdcard_readblocks_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_sdcard_writeblocks_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_sdcard_ioctl_obj },
+ { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&pyb_sdcard_readblocks_obj) },
+ { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&pyb_sdcard_writeblocks_obj) },
+ { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&pyb_sdcard_ioctl_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_sdcard_locals_dict, pyb_sdcard_locals_dict_table);
@@ -440,11 +487,14 @@ const mp_obj_type_t pyb_sdcard_type = {
{ &mp_type_type },
.name = MP_QSTR_SDCard,
.make_new = pyb_sdcard_make_new,
- .locals_dict = (mp_obj_t)&pyb_sdcard_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_sdcard_locals_dict,
};
-void sdcard_init_vfs(fs_user_mount_t *vfs) {
+void sdcard_init_vfs(fs_user_mount_t *vfs, int part) {
+ vfs->base.type = &mp_fat_vfs_type;
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
+ vfs->fatfs.drv = vfs;
+ vfs->fatfs.part = part;
vfs->readblocks[0] = (mp_obj_t)&pyb_sdcard_readblocks_obj;
vfs->readblocks[1] = (mp_obj_t)&pyb_sdcard_obj;
vfs->readblocks[2] = (mp_obj_t)sdcard_read_blocks; // native version
diff --git a/stmhal/sdcard.h b/stmhal/sdcard.h
index ccc24927e..237e48d8b 100644
--- a/stmhal/sdcard.h
+++ b/stmhal/sdcard.h
@@ -41,4 +41,4 @@ extern const struct _mp_obj_type_t pyb_sdcard_type;
extern const struct _mp_obj_base_t pyb_sdcard_obj;
struct _fs_user_mount_t;
-void sdcard_init_vfs(struct _fs_user_mount_t *vfs);
+void sdcard_init_vfs(struct _fs_user_mount_t *vfs, int part);
diff --git a/stmhal/servo.c b/stmhal/servo.c
index dff549582..4c62044dd 100644
--- a/stmhal/servo.c
+++ b/stmhal/servo.c
@@ -317,11 +317,11 @@ STATIC mp_obj_t pyb_servo_speed(mp_uint_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_servo_speed_obj, 1, 3, pyb_servo_speed);
-STATIC const mp_map_elem_t pyb_servo_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_pulse_width), (mp_obj_t)&pyb_servo_pulse_width_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_calibration), (mp_obj_t)&pyb_servo_calibration_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_angle), (mp_obj_t)&pyb_servo_angle_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_speed), (mp_obj_t)&pyb_servo_speed_obj },
+STATIC const mp_rom_map_elem_t pyb_servo_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_pulse_width), MP_ROM_PTR(&pyb_servo_pulse_width_obj) },
+ { MP_ROM_QSTR(MP_QSTR_calibration), MP_ROM_PTR(&pyb_servo_calibration_obj) },
+ { MP_ROM_QSTR(MP_QSTR_angle), MP_ROM_PTR(&pyb_servo_angle_obj) },
+ { MP_ROM_QSTR(MP_QSTR_speed), MP_ROM_PTR(&pyb_servo_speed_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_servo_locals_dict, pyb_servo_locals_dict_table);
@@ -331,5 +331,5 @@ const mp_obj_type_t pyb_servo_type = {
.name = MP_QSTR_Servo,
.print = pyb_servo_print,
.make_new = pyb_servo_make_new,
- .locals_dict = (mp_obj_t)&pyb_servo_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_servo_locals_dict,
};
diff --git a/stmhal/spi.c b/stmhal/spi.c
index 234d4bab7..eb7edbea0 100644
--- a/stmhal/spi.c
+++ b/stmhal/spi.c
@@ -403,6 +403,11 @@ STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t
return HAL_OK;
}
+// A transfer of "len" bytes should take len*8*1000/baudrate milliseconds.
+// To simplify the calculation we assume the baudrate is never less than 8kHz
+// and use that value for the baudrate in the formula, plus a small constant.
+#define SPI_TRANSFER_TIMEOUT(len) ((len) + 100)
+
STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *src, uint8_t *dest, uint32_t timeout) {
// Note: there seems to be a problem sending 1 byte using DMA the first
// time directly after the SPI/DMA is initialised. The cause of this is
@@ -419,6 +424,7 @@ STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *s
dma_init(&tx_dma, self->tx_dma_descr, self->spi);
self->spi->hdmatx = &tx_dma;
self->spi->hdmarx = NULL;
+ MP_HAL_CLEAN_DCACHE(src, len);
status = HAL_SPI_Transmit_DMA(self->spi, (uint8_t*)src, len);
if (status == HAL_OK) {
status = spi_wait_dma_finished(self->spi, timeout);
@@ -440,7 +446,7 @@ STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *s
}
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
self->spi->hdmarx = &rx_dma;
-
+ MP_HAL_CLEANINVALIDATE_DCACHE(dest, len);
status = HAL_SPI_Receive_DMA(self->spi, dest, len);
if (status == HAL_OK) {
status = spi_wait_dma_finished(self->spi, timeout);
@@ -460,6 +466,8 @@ STATIC void spi_transfer(const pyb_spi_obj_t *self, size_t len, const uint8_t *s
self->spi->hdmatx = &tx_dma;
dma_init(&rx_dma, self->rx_dma_descr, self->spi);
self->spi->hdmarx = &rx_dma;
+ MP_HAL_CLEAN_DCACHE(src, len);
+ MP_HAL_CLEANINVALIDATE_DCACHE(dest, len);
status = HAL_SPI_TransmitReceive_DMA(self->spi, (uint8_t*)src, dest, len);
if (status == HAL_OK) {
status = spi_wait_dma_finished(self->spi, timeout);
@@ -775,44 +783,44 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_recv_obj, 1, pyb_spi_send_recv);
-STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_spi_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_spi_deinit_obj },
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_spi_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_spi_deinit_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_machine_spi_read_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_machine_spi_readinto_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_machine_spi_write_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_write_readinto), (mp_obj_t)&mp_machine_spi_write_readinto_obj },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) },
// legacy methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_spi_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_spi_recv_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_send_recv), (mp_obj_t)&pyb_spi_send_recv_obj },
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_spi_send_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_spi_recv_obj) },
+ { MP_ROM_QSTR(MP_QSTR_send_recv), MP_ROM_PTR(&pyb_spi_send_recv_obj) },
// class constants
/// \constant MASTER - for initialising the bus to master mode
/// \constant SLAVE - for initialising the bus to slave mode
/// \constant MSB - set the first bit to MSB
/// \constant LSB - set the first bit to LSB
- { MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(SPI_MODE_MASTER) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SLAVE), MP_OBJ_NEW_SMALL_INT(SPI_MODE_SLAVE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_MSB), MP_OBJ_NEW_SMALL_INT(SPI_FIRSTBIT_MSB) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LSB), MP_OBJ_NEW_SMALL_INT(SPI_FIRSTBIT_LSB) },
+ { MP_ROM_QSTR(MP_QSTR_MASTER), MP_ROM_INT(SPI_MODE_MASTER) },
+ { MP_ROM_QSTR(MP_QSTR_SLAVE), MP_ROM_INT(SPI_MODE_SLAVE) },
+ { MP_ROM_QSTR(MP_QSTR_MSB), MP_ROM_INT(SPI_FIRSTBIT_MSB) },
+ { MP_ROM_QSTR(MP_QSTR_LSB), MP_ROM_INT(SPI_FIRSTBIT_LSB) },
/* TODO
- { MP_OBJ_NEW_QSTR(MP_QSTR_DIRECTION_2LINES ((uint32_t)0x00000000)
- { MP_OBJ_NEW_QSTR(MP_QSTR_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY
- { MP_OBJ_NEW_QSTR(MP_QSTR_DIRECTION_1LINE SPI_CR1_BIDIMODE
- { MP_OBJ_NEW_QSTR(MP_QSTR_NSS_SOFT SPI_CR1_SSM
- { MP_OBJ_NEW_QSTR(MP_QSTR_NSS_HARD_INPUT ((uint32_t)0x00000000)
- { MP_OBJ_NEW_QSTR(MP_QSTR_NSS_HARD_OUTPUT ((uint32_t)0x00040000)
+ { MP_ROM_QSTR(MP_QSTR_DIRECTION_2LINES ((uint32_t)0x00000000)
+ { MP_ROM_QSTR(MP_QSTR_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY
+ { MP_ROM_QSTR(MP_QSTR_DIRECTION_1LINE SPI_CR1_BIDIMODE
+ { MP_ROM_QSTR(MP_QSTR_NSS_SOFT SPI_CR1_SSM
+ { MP_ROM_QSTR(MP_QSTR_NSS_HARD_INPUT ((uint32_t)0x00000000)
+ { MP_ROM_QSTR(MP_QSTR_NSS_HARD_OUTPUT ((uint32_t)0x00040000)
*/
};
STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table);
STATIC void spi_transfer_machine(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
- spi_transfer((pyb_spi_obj_t*)self_in, len, src, dest, 100);
+ spi_transfer((pyb_spi_obj_t*)self_in, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
}
STATIC const mp_machine_spi_p_t pyb_spi_p = {
@@ -825,7 +833,7 @@ const mp_obj_type_t pyb_spi_type = {
.print = pyb_spi_print,
.make_new = pyb_spi_make_new,
.protocol = &pyb_spi_p,
- .locals_dict = (mp_obj_t)&pyb_spi_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_spi_locals_dict,
};
/******************************************************************************/
@@ -929,7 +937,7 @@ STATIC void machine_hard_spi_deinit(mp_obj_base_t *self_in) {
STATIC void machine_hard_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
machine_hard_spi_obj_t *self = (machine_hard_spi_obj_t*)self_in;
- spi_transfer(self->pyb, len, src, dest, 100);
+ spi_transfer(self->pyb, len, src, dest, SPI_TRANSFER_TIMEOUT(len));
}
STATIC const mp_machine_spi_p_t machine_hard_spi_p = {
diff --git a/stmhal/startup_stm32.S b/stmhal/startup_stm32.S
index 25b0fdd39..a688cd067 100644
--- a/stmhal/startup_stm32.S
+++ b/stmhal/startup_stm32.S
@@ -335,6 +335,12 @@ g_pfnVectors:
.word I2C4_EV_IRQHandler /* I2C4 Event */
.word I2C4_ER_IRQHandler /* I2C4 Error */
.word SPDIF_RX_IRQHandler /* SPDIF_RX */
+ .word DSIHOST_IRQHandler /* DSI host */
+ .word DFSDM1_FLT0_IRQHandler /* DFSDM1 filter 0 */
+ .word DFSDM1_FLT1_IRQHandler /* DFSDM1 filter 1 */
+ .word DFSDM1_FLT2_IRQHandler /* DFSDM1 filter 2 */
+ .word DFSDM1_FLT3_IRQHandler /* DFSDM1 filter 3 */
+ .word SDMMC2_IRQHandler /* SDMMC2 */
#endif
/*******************************************************************************
@@ -793,6 +799,24 @@ g_pfnVectors:
.weak SPDIF_RX_IRQHandler
.thumb_set SPDIF_RX_IRQHandler,Default_Handler
+
+ .weak DSIHOST_IRQHandler
+ .thumb_set DSIHOST_IRQHandler,Default_Handler
+
+ .weak DFSDM1_FLT0_IRQHandler
+ .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler
+
+ .weak DFSDM1_FLT1_IRQHandler
+ .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler
+
+ .weak DFSDM1_FLT2_IRQHandler
+ .thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler
+
+ .weak DFSDM1_FLT3_IRQHandler
+ .thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler
+
+ .weak SDMMC2_IRQHandler
+ .thumb_set SDMMC2_IRQHandler,Default_Handler
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/stm32_it.c b/stmhal/stm32_it.c
index e1129ac39..913f1c931 100644
--- a/stmhal/stm32_it.c
+++ b/stmhal/stm32_it.c
@@ -70,9 +70,13 @@
#include "stm32_it.h"
#include STM32_HAL_H
+#include "py/mpstate.h"
#include "py/obj.h"
+#include "py/mphal.h"
#include "pendsv.h"
#include "irq.h"
+#include "pybthread.h"
+#include "gccollect.h"
#include "extint.h"
#include "timer.h"
#include "uart.h"
@@ -80,6 +84,7 @@
#include "can.h"
#include "dma.h"
#include "i2c.h"
+#include "usb.h"
extern void __fatal_error(const char*);
extern PCD_HandleTypeDef pcd_fs_handle;
@@ -92,11 +97,6 @@ extern PCD_HandleTypeDef pcd_hs_handle;
// Set the following to 1 to get some more information on the Hard Fault
// More information about decoding the fault registers can be found here:
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0646a/Cihdjcfc.html
-#define REPORT_HARD_FAULT_REGS 0
-
-#if REPORT_HARD_FAULT_REGS
-
-#include "py/mphal.h"
STATIC char *fmt_hex(uint32_t val, char *buf) {
const char *hexDig = "0123456789abcdef";
@@ -122,6 +122,15 @@ STATIC void print_reg(const char *label, uint32_t val) {
mp_hal_stdout_tx_str("\r\n");
}
+STATIC void print_hex_hex(const char *label, uint32_t val1, uint32_t val2) {
+ char hex_str[9];
+ mp_hal_stdout_tx_str(label);
+ mp_hal_stdout_tx_str(fmt_hex(val1, hex_str));
+ mp_hal_stdout_tx_str(" ");
+ mp_hal_stdout_tx_str(fmt_hex(val2, hex_str));
+ mp_hal_stdout_tx_str("\r\n");
+}
+
// The ARMv7M Architecture manual (section B.1.5.6) says that upon entry
// to an exception, that the registers will be in the following order on the
// // stack: R0, R1, R2, R3, R12, LR, PC, XPSR
@@ -130,12 +139,25 @@ typedef struct {
uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
} ExceptionRegisters_t;
+int pyb_hard_fault_debug = 0;
+
void HardFault_C_Handler(ExceptionRegisters_t *regs) {
+ if (!pyb_hard_fault_debug) {
+ NVIC_SystemReset();
+ }
+
+ // We need to disable the USB so it doesn't try to write data out on
+ // the VCP and then block indefinitely waiting for the buffer to drain.
+ pyb_usb_flags = 0;
+
+ mp_hal_stdout_tx_str("HardFault\r\n");
+
print_reg("R0 ", regs->r0);
print_reg("R1 ", regs->r1);
print_reg("R2 ", regs->r2);
print_reg("R3 ", regs->r3);
print_reg("R12 ", regs->r12);
+ print_reg("SP ", (uint32_t)regs);
print_reg("LR ", regs->lr);
print_reg("PC ", regs->pc);
print_reg("XPSR ", regs->xpsr);
@@ -150,6 +172,19 @@ void HardFault_C_Handler(ExceptionRegisters_t *regs) {
if (cfsr & 0x8000) {
print_reg("BFAR ", SCB->BFAR);
}
+
+ if ((void*)&_ram_start <= (void*)regs && (void*)regs < (void*)&_ram_end) {
+ mp_hal_stdout_tx_str("Stack:\r\n");
+ uint32_t *stack_top = &_estack;
+ if ((void*)regs < (void*)&_heap_end) {
+ // stack not in static stack area so limit the amount we print
+ stack_top = (uint32_t*)regs + 32;
+ }
+ for (uint32_t *sp = (uint32_t*)regs; sp < stack_top; ++sp) {
+ print_hex_hex(" ", (uint32_t)sp, *sp);
+ }
+ }
+
/* Go to infinite loop when Hard Fault exception occurs */
while (1) {
__fatal_error("HardFault");
@@ -177,14 +212,6 @@ void HardFault_Handler(void) {
" b HardFault_C_Handler \n" // Off to C land
);
}
-#else
-void HardFault_Handler(void) {
- /* Go to infinite loop when Hard Fault exception occurs */
- while (1) {
- __fatal_error("HardFault");
- }
-}
-#endif // REPORT_HARD_FAULT_REGS
/**
* @brief This function handles NMI exception.
@@ -271,7 +298,7 @@ void SysTick_Handler(void) {
uwTick += 1;
// Read the systick control regster. This has the side effect of clearing
- // the COUNTFLAG bit, which makes the logic in sys_tick_get_microseconds
+ // the COUNTFLAG bit, which makes the logic in mp_hal_ticks_us
// work properly.
SysTick->CTRL;
@@ -287,6 +314,18 @@ void SysTick_Handler(void) {
if (DMA_IDLE_ENABLED() && DMA_IDLE_TICK(uwTick)) {
dma_idle_handler(uwTick);
}
+
+ #if MICROPY_PY_THREAD
+ if (pyb_thread_enabled) {
+ if (pyb_thread_cur->timeslice == 0) {
+ if (pyb_thread_cur->run_next != pyb_thread_cur) {
+ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
+ }
+ } else {
+ --pyb_thread_cur->timeslice;
+ }
+ }
+ #endif
}
/******************************************************************************/
diff --git a/stmhal/stm32_it.h b/stmhal/stm32_it.h
index fc61d57be..a168cda83 100644
--- a/stmhal/stm32_it.h
+++ b/stmhal/stm32_it.h
@@ -63,6 +63,8 @@
******************************************************************************
*/
+extern int pyb_hard_fault_debug;
+
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
diff --git a/stmhal/storage.c b/stmhal/storage.c
index 14b504d71..1931cd607 100644
--- a/stmhal/storage.c
+++ b/stmhal/storage.c
@@ -29,8 +29,8 @@
#include "py/obj.h"
#include "py/runtime.h"
-#include "lib/fatfs/ff.h"
-#include "extmod/fsusermount.h"
+#include "lib/oofatfs/ff.h"
+#include "extmod/vfs_fat.h"
#include "systick.h"
#include "led.h"
@@ -38,6 +38,14 @@
#include "storage.h"
#include "irq.h"
+#if defined(MICROPY_HW_SPIFLASH_SIZE_BITS)
+#define USE_INTERNAL (0)
+#else
+#define USE_INTERNAL (1)
+#endif
+
+#if USE_INTERNAL
+
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)
#define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k
@@ -51,7 +59,7 @@
#define FLASH_MEM_SEG2_NUM_BLOCKS (128) // sector 11: 128k
#endif
-#elif defined(STM32F401xE) || defined(STM32F411xE)
+#elif defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx)
STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k
#define CACHE_MEM_START_ADDR (&flash_cache_mem[0])
@@ -141,7 +149,7 @@ static uint8_t *flash_cache_get_addr_for_write(uint32_t flash_addr) {
flash_cache_sector_size = flash_sector_size;
}
flash_flags |= FLASH_FLAG_DIRTY;
- led_state(PYB_LED_R1, 1); // indicate a dirty cache with LED on
+ led_state(PYB_LED_RED, 1); // indicate a dirty cache with LED on
flash_tick_counter_last_write = HAL_GetTick();
return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
}
@@ -158,19 +166,50 @@ static uint8_t *flash_cache_get_addr_for_read(uint32_t flash_addr) {
return (uint8_t*)flash_addr;
}
+#else
+
+#include "drivers/memory/spiflash.h"
+#include "genhdr/pins.h"
+
+#define FLASH_PART1_START_BLOCK (0x100)
+#define FLASH_PART1_NUM_BLOCKS (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE)
+
+static bool flash_is_initialised = false;
+
+STATIC const mp_spiflash_t spiflash = {
+ .cs = &MICROPY_HW_SPIFLASH_CS,
+ .spi = {
+ .base = {&mp_machine_soft_spi_type},
+ .delay_half = MICROPY_PY_MACHINE_SPI_MIN_DELAY,
+ .polarity = 0,
+ .phase = 0,
+ .sck = &MICROPY_HW_SPIFLASH_SCK,
+ .mosi = &MICROPY_HW_SPIFLASH_MOSI,
+ .miso = &MICROPY_HW_SPIFLASH_MISO,
+ },
+};
+
+#endif
+
void storage_init(void) {
if (!flash_is_initialised) {
+ #if USE_INTERNAL
flash_flags = 0;
flash_cache_sector_id = 0;
flash_tick_counter_last_write = 0;
+ #else
+ mp_spiflash_init((mp_spiflash_t*)&spiflash);
+ #endif
flash_is_initialised = true;
}
+ #if USE_INTERNAL
// Enable the flash IRQ, which is used to also call our storage IRQ handler
// It needs to go at a higher priority than all those components that rely on
// the flash storage (eg higher than USB MSC).
HAL_NVIC_SetPriority(FLASH_IRQn, IRQ_PRI_FLASH, IRQ_SUBPRI_FLASH);
HAL_NVIC_EnableIRQ(FLASH_IRQn);
+ #endif
}
uint32_t storage_get_block_size(void) {
@@ -182,6 +221,8 @@ uint32_t storage_get_block_count(void) {
}
void storage_irq_handler(void) {
+ #if USE_INTERNAL
+
if (!(flash_flags & FLASH_FLAG_DIRTY)) {
return;
}
@@ -220,12 +261,16 @@ void storage_irq_handler(void) {
// clear the flash flags now that we have a clean cache
flash_flags = 0;
// indicate a clean cache with LED off
- led_state(PYB_LED_R1, 0);
+ led_state(PYB_LED_RED, 0);
}
+
+ #endif
}
void storage_flush(void) {
+ #if USE_INTERNAL
flash_cache_flush();
+ #endif
}
static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) {
@@ -264,6 +309,8 @@ static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_blo
buf[15] = num_blocks >> 24;
}
+#if USE_INTERNAL
+
static uint32_t convert_block_to_flash_addr(uint32_t block) {
if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
// a block in partition 1
@@ -279,6 +326,8 @@ static uint32_t convert_block_to_flash_addr(uint32_t block) {
return -1;
}
+#endif
+
bool storage_read_block(uint8_t *dest, uint32_t block) {
//printf("RD %u\n", block);
if (block == 0) {
@@ -299,6 +348,8 @@ bool storage_read_block(uint8_t *dest, uint32_t block) {
return true;
} else {
+ #if USE_INTERNAL
+
// non-MBR block, get data from flash memory, possibly via cache
uint32_t flash_addr = convert_block_to_flash_addr(block);
if (flash_addr == -1) {
@@ -308,6 +359,27 @@ bool storage_read_block(uint8_t *dest, uint32_t block) {
uint8_t *src = flash_cache_get_addr_for_read(flash_addr);
memcpy(dest, src, FLASH_BLOCK_SIZE);
return true;
+
+ #else
+
+ // non-MBR block, get data from SPI flash
+
+ if (block < FLASH_PART1_START_BLOCK || block >= FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
+ // bad block number
+ return false;
+ }
+
+ // we must disable USB irqs to prevent MSC contention with SPI flash
+ uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
+
+ mp_spiflash_read((mp_spiflash_t*)&spiflash,
+ (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, dest);
+
+ restore_irq_pri(basepri);
+
+ return true;
+
+ #endif
}
}
@@ -318,6 +390,8 @@ bool storage_write_block(const uint8_t *src, uint32_t block) {
return true;
} else {
+ #if USE_INTERNAL
+
// non-MBR block, copy to cache
uint32_t flash_addr = convert_block_to_flash_addr(block);
if (flash_addr == -1) {
@@ -327,6 +401,27 @@ bool storage_write_block(const uint8_t *src, uint32_t block) {
uint8_t *dest = flash_cache_get_addr_for_write(flash_addr);
memcpy(dest, src, FLASH_BLOCK_SIZE);
return true;
+
+ #else
+
+ // non-MBR block, write to SPI flash
+
+ if (block < FLASH_PART1_START_BLOCK || block >= FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
+ // bad block number
+ return false;
+ }
+
+ // we must disable USB irqs to prevent MSC contention with SPI flash
+ uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
+
+ int ret = mp_spiflash_write((mp_spiflash_t*)&spiflash,
+ (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, src);
+
+ restore_irq_pri(basepri);
+
+ return ret == 0;
+
+ #endif
}
}
@@ -393,10 +488,10 @@ STATIC mp_obj_t pyb_flash_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in)
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_flash_ioctl_obj, pyb_flash_ioctl);
-STATIC const mp_map_elem_t pyb_flash_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_readblocks), (mp_obj_t)&pyb_flash_readblocks_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_writeblocks), (mp_obj_t)&pyb_flash_writeblocks_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&pyb_flash_ioctl_obj },
+STATIC const mp_rom_map_elem_t pyb_flash_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&pyb_flash_readblocks_obj) },
+ { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&pyb_flash_writeblocks_obj) },
+ { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&pyb_flash_ioctl_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_flash_locals_dict, pyb_flash_locals_dict_table);
@@ -405,11 +500,14 @@ const mp_obj_type_t pyb_flash_type = {
{ &mp_type_type },
.name = MP_QSTR_Flash,
.make_new = pyb_flash_make_new,
- .locals_dict = (mp_obj_t)&pyb_flash_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_flash_locals_dict,
};
void pyb_flash_init_vfs(fs_user_mount_t *vfs) {
+ vfs->base.type = &mp_fat_vfs_type;
vfs->flags |= FSUSER_NATIVE | FSUSER_HAVE_IOCTL;
+ vfs->fatfs.drv = vfs;
+ vfs->fatfs.part = 1; // flash filesystem lives on first partition
vfs->readblocks[0] = (mp_obj_t)&pyb_flash_readblocks_obj;
vfs->readblocks[1] = (mp_obj_t)&pyb_flash_obj;
vfs->readblocks[2] = (mp_obj_t)storage_read_blocks; // native version
diff --git a/stmhal/systick.c b/stmhal/systick.c
index aed5b9690..4eac583e2 100644
--- a/stmhal/systick.c
+++ b/stmhal/systick.c
@@ -24,18 +24,20 @@
* THE SOFTWARE.
*/
-#include STM32_HAL_H
-
-#include "py/obj.h"
+#include "py/runtime.h"
+#include "py/mphal.h"
#include "irq.h"
#include "systick.h"
+#include "pybthread.h"
+
+extern __IO uint32_t uwTick;
-// We provide our own version of HAL_Delay that calls __WFI while waiting, in
-// order to reduce power consumption.
+// We provide our own version of HAL_Delay that calls __WFI while waiting,
+// and works when interrupts are disabled. This function is intended to be
+// used only by the ST HAL functions.
void HAL_Delay(uint32_t Delay) {
if (query_irq() == IRQ_STATE_ENABLED) {
// IRQs enabled, so can use systick counter to do the delay
- extern __IO uint32_t uwTick;
uint32_t start = uwTick;
// Wraparound of tick is taken care of by 2's complement arithmetic.
while (uwTick - start < Delay) {
@@ -43,6 +45,25 @@ void HAL_Delay(uint32_t Delay) {
__WFI();
}
} else {
+ // IRQs disabled, use mp_hal_delay_ms routine.
+ mp_hal_delay_ms(Delay);
+ }
+}
+
+// Core delay function that does an efficient sleep and may switch thread context.
+// If IRQs are enabled then we must have the GIL.
+void mp_hal_delay_ms(mp_uint_t Delay) {
+ if (query_irq() == IRQ_STATE_ENABLED) {
+ // IRQs enabled, so can use systick counter to do the delay
+ uint32_t start = uwTick;
+ // Wraparound of tick is taken care of by 2's complement arithmetic.
+ while (uwTick - start < Delay) {
+ // This macro will execute the necessary idle behaviour. It may
+ // raise an exception, switch threads or enter sleep mode (waiting for
+ // (at least) the SysTick interrupt).
+ MICROPY_EVENT_POLL_HOOK
+ }
+ } else {
// IRQs disabled, so need to use a busy loop for the delay.
// To prevent possible overflow of the counter we use a double loop.
const uint32_t count_1ms = HAL_RCC_GetSysClockFreq() / 4000;
@@ -54,11 +75,11 @@ void HAL_Delay(uint32_t Delay) {
}
// delay for given number of microseconds
-void sys_tick_udelay(uint32_t usec) {
+void mp_hal_delay_us(mp_uint_t usec) {
if (query_irq() == IRQ_STATE_ENABLED) {
// IRQs enabled, so can use systick counter to do the delay
- uint32_t start = sys_tick_get_microseconds();
- while (sys_tick_get_microseconds() - start < usec) {
+ uint32_t start = mp_hal_ticks_us();
+ while (mp_hal_ticks_us() - start < usec) {
}
} else {
// IRQs disabled, so need to use a busy loop for the delay
@@ -82,11 +103,15 @@ void sys_tick_wait_at_least(uint32_t start_tick, uint32_t delay_ms) {
}
}
+mp_uint_t mp_hal_ticks_ms(void) {
+ return uwTick;
+}
+
// The SysTick timer counts down at 168 MHz, so we can use that knowledge
// to grab a microsecond counter.
//
// We assume that HAL_GetTickis returns milliseconds.
-uint32_t sys_tick_get_microseconds(void) {
+mp_uint_t mp_hal_ticks_us(void) {
mp_uint_t irq_state = disable_irq();
uint32_t counter = SysTick->VAL;
uint32_t milliseconds = HAL_GetTick();
diff --git a/stmhal/systick.h b/stmhal/systick.h
index 5a4dfb3ed..1e7f62335 100644
--- a/stmhal/systick.h
+++ b/stmhal/systick.h
@@ -24,7 +24,5 @@
* THE SOFTWARE.
*/
-void sys_tick_udelay(uint32_t usec);
void sys_tick_wait_at_least(uint32_t stc, uint32_t delay_ms);
bool sys_tick_has_passed(uint32_t stc, uint32_t delay_ms);
-uint32_t sys_tick_get_microseconds(void);
diff --git a/stmhal/timer.c b/stmhal/timer.c
index 494045c28..fd0695bdd 100644
--- a/stmhal/timer.c
+++ b/stmhal/timer.c
@@ -1180,37 +1180,37 @@ STATIC mp_obj_t pyb_timer_callback(mp_obj_t self_in, mp_obj_t callback) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_timer_callback_obj, pyb_timer_callback);
-STATIC const mp_map_elem_t pyb_timer_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_timer_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_timer_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_timer_deinit_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_channel), (mp_obj_t)&pyb_timer_channel_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_counter), (mp_obj_t)&pyb_timer_counter_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_source_freq), (mp_obj_t)&pyb_timer_source_freq_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_timer_freq_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_prescaler), (mp_obj_t)&pyb_timer_prescaler_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_period), (mp_obj_t)&pyb_timer_period_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_timer_callback_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_UP), MP_OBJ_NEW_SMALL_INT(TIM_COUNTERMODE_UP) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_DOWN), MP_OBJ_NEW_SMALL_INT(TIM_COUNTERMODE_DOWN) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_CENTER), MP_OBJ_NEW_SMALL_INT(TIM_COUNTERMODE_CENTERALIGNED1) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_PWM), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_PWM_NORMAL) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_PWM_INVERTED), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_PWM_INVERTED) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OC_TIMING), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_OC_TIMING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OC_ACTIVE), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_OC_ACTIVE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OC_INACTIVE), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_OC_INACTIVE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OC_TOGGLE), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_OC_TOGGLE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OC_FORCED_ACTIVE), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_OC_FORCED_ACTIVE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_OC_FORCED_INACTIVE), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_OC_FORCED_INACTIVE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_IC), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_IC) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ENC_A), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_ENC_A) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ENC_B), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_ENC_B) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_ENC_AB), MP_OBJ_NEW_SMALL_INT(CHANNEL_MODE_ENC_AB) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_HIGH), MP_OBJ_NEW_SMALL_INT(TIM_OCPOLARITY_HIGH) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_LOW), MP_OBJ_NEW_SMALL_INT(TIM_OCPOLARITY_LOW) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_RISING), MP_OBJ_NEW_SMALL_INT(TIM_ICPOLARITY_RISING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_FALLING), MP_OBJ_NEW_SMALL_INT(TIM_ICPOLARITY_FALLING) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_BOTH), MP_OBJ_NEW_SMALL_INT(TIM_ICPOLARITY_BOTHEDGE) },
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_timer_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_timer_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR_channel), MP_ROM_PTR(&pyb_timer_channel_obj) },
+ { MP_ROM_QSTR(MP_QSTR_counter), MP_ROM_PTR(&pyb_timer_counter_obj) },
+ { MP_ROM_QSTR(MP_QSTR_source_freq), MP_ROM_PTR(&pyb_timer_source_freq_obj) },
+ { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&pyb_timer_freq_obj) },
+ { MP_ROM_QSTR(MP_QSTR_prescaler), MP_ROM_PTR(&pyb_timer_prescaler_obj) },
+ { MP_ROM_QSTR(MP_QSTR_period), MP_ROM_PTR(&pyb_timer_period_obj) },
+ { MP_ROM_QSTR(MP_QSTR_callback), MP_ROM_PTR(&pyb_timer_callback_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UP), MP_ROM_INT(TIM_COUNTERMODE_UP) },
+ { MP_ROM_QSTR(MP_QSTR_DOWN), MP_ROM_INT(TIM_COUNTERMODE_DOWN) },
+ { MP_ROM_QSTR(MP_QSTR_CENTER), MP_ROM_INT(TIM_COUNTERMODE_CENTERALIGNED1) },
+ { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_INT(CHANNEL_MODE_PWM_NORMAL) },
+ { MP_ROM_QSTR(MP_QSTR_PWM_INVERTED), MP_ROM_INT(CHANNEL_MODE_PWM_INVERTED) },
+ { MP_ROM_QSTR(MP_QSTR_OC_TIMING), MP_ROM_INT(CHANNEL_MODE_OC_TIMING) },
+ { MP_ROM_QSTR(MP_QSTR_OC_ACTIVE), MP_ROM_INT(CHANNEL_MODE_OC_ACTIVE) },
+ { MP_ROM_QSTR(MP_QSTR_OC_INACTIVE), MP_ROM_INT(CHANNEL_MODE_OC_INACTIVE) },
+ { MP_ROM_QSTR(MP_QSTR_OC_TOGGLE), MP_ROM_INT(CHANNEL_MODE_OC_TOGGLE) },
+ { MP_ROM_QSTR(MP_QSTR_OC_FORCED_ACTIVE), MP_ROM_INT(CHANNEL_MODE_OC_FORCED_ACTIVE) },
+ { MP_ROM_QSTR(MP_QSTR_OC_FORCED_INACTIVE), MP_ROM_INT(CHANNEL_MODE_OC_FORCED_INACTIVE) },
+ { MP_ROM_QSTR(MP_QSTR_IC), MP_ROM_INT(CHANNEL_MODE_IC) },
+ { MP_ROM_QSTR(MP_QSTR_ENC_A), MP_ROM_INT(CHANNEL_MODE_ENC_A) },
+ { MP_ROM_QSTR(MP_QSTR_ENC_B), MP_ROM_INT(CHANNEL_MODE_ENC_B) },
+ { MP_ROM_QSTR(MP_QSTR_ENC_AB), MP_ROM_INT(CHANNEL_MODE_ENC_AB) },
+ { MP_ROM_QSTR(MP_QSTR_HIGH), MP_ROM_INT(TIM_OCPOLARITY_HIGH) },
+ { MP_ROM_QSTR(MP_QSTR_LOW), MP_ROM_INT(TIM_OCPOLARITY_LOW) },
+ { MP_ROM_QSTR(MP_QSTR_RISING), MP_ROM_INT(TIM_ICPOLARITY_RISING) },
+ { MP_ROM_QSTR(MP_QSTR_FALLING), MP_ROM_INT(TIM_ICPOLARITY_FALLING) },
+ { MP_ROM_QSTR(MP_QSTR_BOTH), MP_ROM_INT(TIM_ICPOLARITY_BOTHEDGE) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_timer_locals_dict, pyb_timer_locals_dict_table);
@@ -1219,7 +1219,7 @@ const mp_obj_type_t pyb_timer_type = {
.name = MP_QSTR_Timer,
.print = pyb_timer_print,
.make_new = pyb_timer_make_new,
- .locals_dict = (mp_obj_t)&pyb_timer_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_timer_locals_dict,
};
/// \moduleref pyb
@@ -1302,6 +1302,7 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback)
} else if (mp_obj_is_callable(callback)) {
self->callback = callback;
uint8_t tim_id = self->timer->tim_id;
+ __HAL_TIM_CLEAR_IT(&self->timer->tim, TIMER_IRQ_MASK(self->channel));
if (tim_id == 1) {
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
#if defined(TIM8) // STM32F401 doesn't have a TIM8
@@ -1336,13 +1337,13 @@ STATIC mp_obj_t pyb_timer_channel_callback(mp_obj_t self_in, mp_obj_t callback)
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_timer_channel_callback_obj, pyb_timer_channel_callback);
-STATIC const mp_map_elem_t pyb_timer_channel_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_timer_channel_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_timer_channel_callback_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_pulse_width), (mp_obj_t)&pyb_timer_channel_capture_compare_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_pulse_width_percent), (mp_obj_t)&pyb_timer_channel_pulse_width_percent_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_capture), (mp_obj_t)&pyb_timer_channel_capture_compare_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_compare), (mp_obj_t)&pyb_timer_channel_capture_compare_obj },
+ { MP_ROM_QSTR(MP_QSTR_callback), MP_ROM_PTR(&pyb_timer_channel_callback_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pulse_width), MP_ROM_PTR(&pyb_timer_channel_capture_compare_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pulse_width_percent), MP_ROM_PTR(&pyb_timer_channel_pulse_width_percent_obj) },
+ { MP_ROM_QSTR(MP_QSTR_capture), MP_ROM_PTR(&pyb_timer_channel_capture_compare_obj) },
+ { MP_ROM_QSTR(MP_QSTR_compare), MP_ROM_PTR(&pyb_timer_channel_capture_compare_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_timer_channel_locals_dict, pyb_timer_channel_locals_dict_table);
@@ -1350,7 +1351,7 @@ STATIC const mp_obj_type_t pyb_timer_channel_type = {
{ &mp_type_type },
.name = MP_QSTR_TimerChannel,
.print = pyb_timer_channel_print,
- .locals_dict = (mp_obj_t)&pyb_timer_channel_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_timer_channel_locals_dict,
};
STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_obj_t callback) {
@@ -1363,6 +1364,7 @@ STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_o
// execute callback if it's set
if (callback != mp_const_none) {
+ mp_sched_lock();
// When executing code within a handler we must lock the GC to prevent
// any memory allocations. We must also catch any exceptions.
gc_lock();
@@ -1382,6 +1384,7 @@ STATIC void timer_handle_irq_channel(pyb_timer_obj_t *tim, uint8_t channel, mp_o
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
gc_unlock();
+ mp_sched_unlock();
}
}
}
diff --git a/stmhal/uart.c b/stmhal/uart.c
index 606ebd106..5664de4cc 100644
--- a/stmhal/uart.c
+++ b/stmhal/uart.c
@@ -335,7 +335,7 @@ STATIC bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
if (HAL_GetTick() - start >= timeout) {
return false; // timeout
}
- __WFI();
+ MICROPY_EVENT_POLL_HOOK
}
}
@@ -376,7 +376,7 @@ STATIC bool uart_tx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
if (HAL_GetTick() - start >= timeout) {
return false; // timeout
}
- __WFI();
+ MICROPY_EVENT_POLL_HOOK
}
}
@@ -911,29 +911,29 @@ STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak);
-STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
+STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
// instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_uart_init_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_uart_deinit_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_uart_any_obj },
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_uart_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) },
/// \method read([nbytes])
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
/// \method readline()
- { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
+ { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
/// \method readinto(buf[, nbytes])
- { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
/// \method write(buf)
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_writechar), (mp_obj_t)&pyb_uart_writechar_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readchar), (mp_obj_t)&pyb_uart_readchar_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak), (mp_obj_t)&pyb_uart_sendbreak_obj },
+ { MP_ROM_QSTR(MP_QSTR_writechar), MP_ROM_PTR(&pyb_uart_writechar_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readchar), MP_ROM_PTR(&pyb_uart_readchar_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&pyb_uart_sendbreak_obj) },
// class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_RTS), MP_OBJ_NEW_SMALL_INT(UART_HWCONTROL_RTS) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_CTS), MP_OBJ_NEW_SMALL_INT(UART_HWCONTROL_CTS) },
+ { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) },
+ { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
@@ -1038,8 +1038,8 @@ const mp_obj_type_t pyb_uart_type = {
.name = MP_QSTR_UART,
.print = pyb_uart_print,
.make_new = pyb_uart_make_new,
- .getiter = mp_identity,
+ .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &uart_stream_p,
- .locals_dict = (mp_obj_t)&pyb_uart_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_uart_locals_dict,
};
diff --git a/stmhal/usb.c b/stmhal/usb.c
index 902abf160..15300c9fa 100644
--- a/stmhal/usb.c
+++ b/stmhal/usb.c
@@ -39,6 +39,7 @@
#include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h"
+#include "py/mphal.h"
#include "bufhelper.h"
#include "usb.h"
@@ -54,7 +55,7 @@
mp_uint_t pyb_usb_flags = 0;
#ifdef USE_DEVICE_MODE
-USBD_HandleTypeDef hUSBDDevice;
+STATIC USBD_HandleTypeDef hUSBDDevice;
pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE;
#endif
@@ -97,7 +98,7 @@ const mp_obj_tuple_t pyb_usb_hid_keyboard_obj = {
};
void pyb_usb_init0(void) {
- USBD_CDC_SetInterrupt(-1);
+ mp_hal_set_interrupt_char(-1);
MP_STATE_PORT(pyb_hid_report_desc) = MP_OBJ_NULL;
}
@@ -142,15 +143,6 @@ bool usb_vcp_is_enabled(void) {
return (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED) != 0;
}
-void usb_vcp_set_interrupt_char(int c) {
- if (pyb_usb_flags & PYB_USB_FLAG_DEV_ENABLED) {
- if (c != -1) {
- mp_obj_exception_clear_traceback(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)));
- }
- USBD_CDC_SetInterrupt(c);
- }
-}
-
int usb_vcp_recv_byte(uint8_t *c) {
return USBD_CDC_Rx(c, 1, 0);
}
@@ -365,7 +357,7 @@ STATIC mp_obj_t pyb_usb_vcp_make_new(const mp_obj_type_t *type, size_t n_args, s
}
STATIC mp_obj_t pyb_usb_vcp_setinterrupt(mp_obj_t self_in, mp_obj_t int_chr_in) {
- usb_vcp_set_interrupt_char(mp_obj_get_int(int_chr_in));
+ mp_hal_set_interrupt_char(mp_obj_get_int(int_chr_in));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_usb_vcp_setinterrupt_obj, pyb_usb_vcp_setinterrupt);
@@ -459,21 +451,21 @@ mp_obj_t pyb_usb_vcp___exit__(mp_uint_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_usb_vcp___exit___obj, 4, 4, pyb_usb_vcp___exit__);
-STATIC const mp_map_elem_t pyb_usb_vcp_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_setinterrupt), (mp_obj_t)&pyb_usb_vcp_setinterrupt_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_isconnected), (mp_obj_t)&pyb_usb_vcp_isconnected_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_usb_vcp_any_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_usb_vcp_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_usb_vcp_recv_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_readlines), (mp_obj_t)&mp_stream_unbuffered_readlines_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&mp_identity_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&mp_identity_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR___enter__), (mp_obj_t)&mp_identity_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR___exit__), (mp_obj_t)&pyb_usb_vcp___exit___obj },
+STATIC const mp_rom_map_elem_t pyb_usb_vcp_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_setinterrupt), MP_ROM_PTR(&pyb_usb_vcp_setinterrupt_obj) },
+ { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&pyb_usb_vcp_isconnected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_usb_vcp_any_obj) },
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_usb_vcp_send_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_usb_vcp_recv_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
+ { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)},
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_identity_obj) },
+ { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_identity_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pyb_usb_vcp___exit___obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_usb_vcp_locals_dict, pyb_usb_vcp_locals_dict_table);
@@ -527,10 +519,10 @@ const mp_obj_type_t pyb_usb_vcp_type = {
.name = MP_QSTR_USB_VCP,
.print = pyb_usb_vcp_print,
.make_new = pyb_usb_vcp_make_new,
- .getiter = mp_identity,
+ .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &pyb_usb_vcp_stream_p,
- .locals_dict = (mp_obj_t)&pyb_usb_vcp_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_usb_vcp_locals_dict,
};
/******************************************************************************/
@@ -577,7 +569,7 @@ STATIC mp_obj_t pyb_usb_hid_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_
mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
// receive the data
- int ret = USBD_HID_Rx((uint8_t*)vstr.buf, vstr.len, vals[1].u_int);
+ int ret = USBD_HID_Rx(&hUSBDDevice, (uint8_t*)vstr.buf, vstr.len, vals[1].u_int);
// return the received data
if (o_ret != MP_OBJ_NULL) {
@@ -608,7 +600,11 @@ STATIC mp_obj_t pyb_usb_hid_send(mp_obj_t self_in, mp_obj_t report_in) {
}
// send the data
- USBD_HID_SendReport(&hUSBDDevice, bufinfo.buf, bufinfo.len);
+ if (USBD_OK == USBD_HID_SendReport(&hUSBDDevice, bufinfo.buf, bufinfo.len)) {
+ return mp_obj_new_int(bufinfo.len);
+ } else {
+ return mp_obj_new_int(0);
+ }
#endif
return mp_const_none;
@@ -621,9 +617,9 @@ STATIC mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
}
MP_DEFINE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj, pyb_hid_send_report);
-STATIC const mp_map_elem_t pyb_usb_hid_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_usb_hid_send_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_usb_hid_recv_obj },
+STATIC const mp_rom_map_elem_t pyb_usb_hid_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_usb_hid_send_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_usb_hid_recv_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_usb_hid_locals_dict, pyb_usb_hid_locals_dict_table);
@@ -633,6 +629,9 @@ STATIC mp_uint_t pyb_usb_hid_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
+ if ((flags & MP_STREAM_POLL_RD) && USBD_HID_RxNum() > 0) {
+ ret |= MP_STREAM_POLL_RD;
+ }
if ((flags & MP_STREAM_POLL_WR) && USBD_HID_CanSendReport(&hUSBDDevice)) {
ret |= MP_STREAM_POLL_WR;
}
@@ -652,7 +651,7 @@ const mp_obj_type_t pyb_usb_hid_type = {
.name = MP_QSTR_USB_HID,
.make_new = pyb_usb_hid_make_new,
.protocol = &pyb_usb_hid_stream_p,
- .locals_dict = (mp_obj_t)&pyb_usb_hid_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_usb_hid_locals_dict,
};
/******************************************************************************/
diff --git a/stmhal/usb.h b/stmhal/usb.h
index e153f0c6b..42e6c76f8 100644
--- a/stmhal/usb.h
+++ b/stmhal/usb.h
@@ -47,7 +47,6 @@ typedef enum {
} USB_PHY_ID;
extern mp_uint_t pyb_usb_flags;
-extern struct _USBD_HandleTypeDef hUSBDDevice;
extern pyb_usb_storage_medium_t pyb_usb_storage_medium;
extern const struct _mp_obj_tuple_t pyb_usb_hid_mouse_obj;
extern const struct _mp_obj_tuple_t pyb_usb_hid_keyboard_obj;
@@ -61,7 +60,6 @@ void pyb_usb_init0(void);
bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_HID_ModeInfoTypeDef *hid_info);
void pyb_usb_dev_deinit(void);
bool usb_vcp_is_enabled(void);
-void usb_vcp_set_interrupt_char(int c);
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);
diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c
index 1f46b9dcc..addcf8c85 100644
--- a/stmhal/usbd_cdc_interface.c
+++ b/stmhal/usbd_cdc_interface.c
@@ -43,6 +43,7 @@
#include "py/mpstate.h"
#include "py/obj.h"
+#include "lib/utils/interrupt_char.h"
#include "irq.h"
#include "timer.h"
#include "usb.h"
@@ -60,7 +61,7 @@
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
-#define APP_RX_DATA_SIZE 1024 // I think this must be at least CDC_DATA_FS_OUT_PACKET_SIZE=64 (APP_RX_DATA_SIZE was 2048)
+#define APP_RX_DATA_SIZE 1024 // this must be 2 or greater, and a power of 2
#define APP_TX_DATA_SIZE 1024 // I think this can be any value (was 2048)
/* Private macro -------------------------------------------------------------*/
@@ -68,9 +69,10 @@
static __IO uint8_t dev_is_connected = 0; // indicates if we are connected
-static uint8_t UserRxBuffer[APP_RX_DATA_SIZE]; // received data from USB OUT endpoint is stored in this buffer
-static uint16_t UserRxBufCur = 0; // points to next available character in UserRxBuffer
-static uint16_t UserRxBufLen = 0; // counts number of valid characters in UserRxBuffer
+static uint8_t cdc_rx_packet_buf[CDC_DATA_FS_MAX_PACKET_SIZE]; // received data from USB OUT endpoint is stored in this buffer
+static uint8_t cdc_rx_user_buf[APP_RX_DATA_SIZE]; // received data is buffered here until the user reads it
+static volatile uint16_t cdc_rx_buf_put = 0; // circular buffer index
+static uint16_t cdc_rx_buf_get = 0; // circular buffer index
static uint8_t UserTxBuffer[APP_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer
static uint16_t UserTxBufPtrIn = 0; // increment this pointer modulo APP_TX_DATA_SIZE when new data is available
@@ -79,13 +81,11 @@ static uint16_t UserTxBufPtrOutShadow = 0; // shadow of above
static uint8_t UserTxBufPtrWaitCount = 0; // used to implement a timeout waiting for low-level USB driver
static uint8_t UserTxNeedEmptyPacket = 0; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size
-static int user_interrupt_char = -1;
-
/* Private function prototypes -----------------------------------------------*/
-static int8_t CDC_Itf_Init (void);
+static int8_t CDC_Itf_Init (USBD_HandleTypeDef *pdev);
static int8_t CDC_Itf_DeInit (void);
static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length);
-static int8_t CDC_Itf_Receive (uint8_t* pbuf, uint32_t *Len);
+static int8_t CDC_Itf_Receive (USBD_HandleTypeDef *pdev, uint8_t* pbuf, uint32_t *Len);
const USBD_CDC_ItfTypeDef USBD_CDC_fops = {
CDC_Itf_Init,
@@ -102,7 +102,7 @@ const USBD_CDC_ItfTypeDef USBD_CDC_fops = {
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
-static int8_t CDC_Itf_Init(void)
+static int8_t CDC_Itf_Init(USBD_HandleTypeDef *pdev)
{
#if 0
/*##-1- Configure the UART peripheral ######################################*/
@@ -141,19 +141,12 @@ static int8_t CDC_Itf_Init(void)
#endif
/*##-5- Set Application Buffers ############################################*/
- USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0);
- USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer);
+ USBD_CDC_SetTxBuffer(pdev, UserTxBuffer, 0);
+ USBD_CDC_SetRxBuffer(pdev, cdc_rx_packet_buf);
- UserRxBufCur = 0;
- UserRxBufLen = 0;
+ cdc_rx_buf_put = 0;
+ cdc_rx_buf_get = 0;
- /* NOTE: we cannot reset these here, because USBD_CDC_SetInterrupt
- * may be called before this init function to set these values.
- * This can happen if the USB enumeration occurs after the call to
- * USBD_CDC_SetInterrupt.
- user_interrupt_char = -1;
- */
-
return (USBD_OK);
}
@@ -269,8 +262,10 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
if (UserTxBufPtrOut != UserTxBufPtrOutShadow) {
// We have sent data and are waiting for the low-level USB driver to
// finish sending it over the USB in-endpoint.
- // SOF occurs every 1ms, so we have a 150 * 1ms = 150ms timeout
- if (UserTxBufPtrWaitCount < 150) {
+ // SOF occurs every 1ms, so we have a 500 * 1ms = 500ms timeout
+ // We have a relatively large timeout because the USB host may be busy
+ // doing other things and we must give it a chance to read our data.
+ if (UserTxBufPtrWaitCount < 500) {
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
if (USBx_INEP(CDC_IN_EP & 0x7f)->DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ) {
// USB in-endpoint is still reading the data
@@ -293,9 +288,9 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
buffptr = UserTxBufPtrOutShadow;
- USBD_CDC_SetTxBuffer(&hUSBDDevice, (uint8_t*)&UserTxBuffer[buffptr], buffsize);
+ USBD_CDC_SetTxBuffer(hpcd->pData, (uint8_t*)&UserTxBuffer[buffptr], buffsize);
- if (USBD_CDC_TransmitPacket(&hUSBDDevice) == USBD_OK) {
+ if (USBD_CDC_TransmitPacket(hpcd->pData) == USBD_OK) {
UserTxBufPtrOutShadow += buffsize;
if (UserTxBufPtrOutShadow == APP_TX_DATA_SIZE) {
UserTxBufPtrOutShadow = 0;
@@ -319,64 +314,33 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
* @param Buf: Buffer of data received
* @param Len: Number of data received (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
- * @note The buffer we are passed here is just UserRxBuffer, so we are
+ * @note The buffer we are passed here is just cdc_rx_packet_buf, so we are
* free to modify it.
*/
-static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) {
+static int8_t CDC_Itf_Receive(USBD_HandleTypeDef *pdev, uint8_t* Buf, uint32_t *Len) {
#if 0
// this sends the data over the UART using DMA
HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len);
#endif
- // TODO improve this function to implement a circular buffer
-
- // if we have processed all the characters, reset the buffer counters
- if (UserRxBufCur > 0 && UserRxBufCur >= UserRxBufLen) {
- memmove(UserRxBuffer, UserRxBuffer + UserRxBufLen, *Len);
- UserRxBufCur = 0;
- UserRxBufLen = 0;
- }
-
- uint32_t delta_len;
-
- if (user_interrupt_char == -1) {
- // no special interrupt character
- delta_len = *Len;
-
- } else {
- // filter out special interrupt character from the buffer
- bool char_found = false;
- uint8_t *dest = Buf;
- uint8_t *src = Buf;
- uint8_t *buf_top = Buf + *Len;
- for (; src < buf_top; src++) {
- if (*src == user_interrupt_char) {
- char_found = true;
- // raise exception when interrupts are finished
- pendsv_nlr_jump(&MP_STATE_VM(mp_kbd_exception));
- } else {
- if (char_found) {
- *dest = *src;
- }
- dest++;
+ // copy the incoming data into the circular buffer
+ for (uint8_t *src = Buf, *top = Buf + *Len; src < top; ++src) {
+ if (mp_interrupt_char != -1 && *src == mp_interrupt_char) {
+ pendsv_kbd_intr();
+ } else {
+ uint16_t next_put = (cdc_rx_buf_put + 1) & (APP_RX_DATA_SIZE - 1);
+ if (next_put == cdc_rx_buf_get) {
+ // overflow, we just discard the rest of the chars
+ break;
}
+ cdc_rx_user_buf[cdc_rx_buf_put] = *src;
+ cdc_rx_buf_put = next_put;
}
-
- // length of remaining characters
- delta_len = dest - Buf;
- }
-
- if (UserRxBufLen + delta_len + CDC_DATA_FS_MAX_PACKET_SIZE > APP_RX_DATA_SIZE) {
- // if we keep this data then the buffer can overflow on the next USB rx
- // so we don't increment the length, and throw this data away
- } else {
- // data fits, leaving room for another CDC_DATA_FS_OUT_PACKET_SIZE
- UserRxBufLen += delta_len;
}
- // initiate next USB packet transfer, to append to existing data in buffer
- USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer + UserRxBufLen);
- USBD_CDC_ReceivePacket(&hUSBDDevice);
+ // initiate next USB packet transfer
+ USBD_CDC_SetRxBuffer(pdev, cdc_rx_packet_buf);
+ USBD_CDC_ReceivePacket(pdev);
return USBD_OK;
}
@@ -385,10 +349,6 @@ int USBD_CDC_IsConnected(void) {
return dev_is_connected;
}
-void USBD_CDC_SetInterrupt(int chr) {
- user_interrupt_char = chr;
-}
-
int USBD_CDC_TxHalfEmpty(void) {
int32_t tx_waiting = (int32_t)UserTxBufPtrIn - (int32_t)UserTxBufPtrOut;
if (tx_waiting < 0) {
@@ -473,7 +433,11 @@ void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len) {
// Returns number of bytes in the rx buffer.
int USBD_CDC_RxNum(void) {
- return UserRxBufLen - UserRxBufCur;
+ int32_t rx_waiting = (int32_t)cdc_rx_buf_put - (int32_t)cdc_rx_buf_get;
+ if (rx_waiting < 0) {
+ rx_waiting += APP_RX_DATA_SIZE;
+ }
+ return rx_waiting;
}
// timout in milliseconds.
@@ -483,7 +447,7 @@ int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
for (uint32_t i = 0; i < len; i++) {
// Wait until we have at least 1 byte to read
uint32_t start = HAL_GetTick();
- while (UserRxBufLen == UserRxBufCur) {
+ while (cdc_rx_buf_put == cdc_rx_buf_get) {
// Wraparound of tick is taken care of by 2's complement arithmetic.
if (HAL_GetTick() - start >= timeout) {
// timeout
@@ -497,7 +461,8 @@ int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
}
// Copy byte from device to user buffer
- buf[i] = UserRxBuffer[UserRxBufCur++];
+ buf[i] = cdc_rx_user_buf[cdc_rx_buf_get];
+ cdc_rx_buf_get = (cdc_rx_buf_get + 1) & (APP_RX_DATA_SIZE - 1);
}
// Success, return number of bytes read
diff --git a/stmhal/usbd_cdc_interface.h b/stmhal/usbd_cdc_interface.h
index 2ea1a42c4..d96861a7e 100644
--- a/stmhal/usbd_cdc_interface.h
+++ b/stmhal/usbd_cdc_interface.h
@@ -32,7 +32,6 @@
extern const USBD_CDC_ItfTypeDef USBD_CDC_fops;
int USBD_CDC_IsConnected(void);
-void USBD_CDC_SetInterrupt(int chr);
int USBD_CDC_TxHalfEmpty(void);
int USBD_CDC_Tx(const uint8_t *buf, uint32_t len, uint32_t timeout);
diff --git a/stmhal/usbd_hid_interface.c b/stmhal/usbd_hid_interface.c
index 04f1b7fd0..11b3a3acd 100644
--- a/stmhal/usbd_hid_interface.c
+++ b/stmhal/usbd_hid_interface.c
@@ -45,22 +45,36 @@
/* Private variables ---------------------------------------------------------*/
-static __IO uint8_t dev_is_connected = 0; // indicates if we are connected
-
static uint8_t buffer[2][HID_DATA_FS_MAX_PACKET_SIZE]; // pair of buffers to read individual packets into
static int8_t current_read_buffer = 0; // which buffer to read from
-static uint32_t last_read_len; // length of last read
+static uint32_t last_read_len = 0; // length of last read
static int8_t current_write_buffer = 0; // which buffer to write to
-
/* Private function prototypes -----------------------------------------------*/
-static int8_t HID_Itf_Receive (uint8_t* pbuf, uint32_t Len);
+static int8_t HID_Itf_Init (USBD_HandleTypeDef *pdev);
+static int8_t HID_Itf_Receive (USBD_HandleTypeDef *pdev, uint8_t* pbuf, uint32_t Len);
const USBD_HID_ItfTypeDef USBD_HID_fops = {
+ HID_Itf_Init,
HID_Itf_Receive
};
/**
+ * @brief HID_Itf_Init
+ * Initializes the HID media low layer
+ * @param None
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
+ */
+static int8_t HID_Itf_Init(USBD_HandleTypeDef *pdev)
+{
+ current_read_buffer = 0;
+ last_read_len = 0;
+ current_write_buffer = 0;
+ USBD_HID_SetRxBuffer(pdev, buffer[current_write_buffer]);
+ return USBD_OK;
+}
+
+/**
* @brief HID_Itf_Receive
* Data received over USB OUT endpoint is processed here.
* @param Buf: Buffer of data received
@@ -69,19 +83,25 @@ const USBD_HID_ItfTypeDef USBD_HID_fops = {
* @note The buffer we are passed here is just UserRxBuffer, so we are
* free to modify it.
*/
-static int8_t HID_Itf_Receive(uint8_t* Buf, uint32_t Len) {
+static int8_t HID_Itf_Receive(USBD_HandleTypeDef *pdev, uint8_t* Buf, uint32_t Len) {
current_write_buffer = !current_write_buffer;
last_read_len = Len;
// initiate next USB packet transfer, to append to existing data in buffer
- USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]);
- USBD_HID_ReceivePacket(&hUSBDDevice);
-
+ USBD_HID_SetRxBuffer(pdev, buffer[current_write_buffer]);
+ USBD_HID_ReceivePacket(pdev);
+ // Set NAK to indicate we need to process read buffer
+ USBD_HID_SetNAK(pdev);
return USBD_OK;
}
+// Returns number of ready rx buffers.
+int USBD_HID_RxNum(void) {
+ return (current_read_buffer != current_write_buffer);
+}
+
// timout in milliseconds.
// Returns number of bytes read from the device.
-int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
+int USBD_HID_Rx(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len, uint32_t timeout) {
// Wait until we have buffer to read
uint32_t start = HAL_GetTick();
while (current_read_buffer == current_write_buffer) {
@@ -106,6 +126,9 @@ int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
memcpy(buf, buffer[current_read_buffer], last_read_len);
current_read_buffer = !current_read_buffer;
+ // Clear NAK to indicate we are ready to read more data
+ USBD_HID_ClearNAK(pdev);
+
// Success, return number of bytes read
return last_read_len;
}
diff --git a/stmhal/usbd_hid_interface.h b/stmhal/usbd_hid_interface.h
index 9cdf32549..fbc874796 100644
--- a/stmhal/usbd_hid_interface.h
+++ b/stmhal/usbd_hid_interface.h
@@ -6,4 +6,5 @@
extern const USBD_HID_ItfTypeDef USBD_HID_fops;
-int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout);
+int USBD_HID_RxNum(void);
+int USBD_HID_Rx(USBD_HandleTypeDef *pdev, uint8_t *buf, uint32_t len, uint32_t timeout);
diff --git a/stmhal/usbd_msc_storage.c b/stmhal/usbd_msc_storage.c
index 82fa550dc..cec973741 100644
--- a/stmhal/usbd_msc_storage.c
+++ b/stmhal/usbd_msc_storage.c
@@ -37,7 +37,6 @@
#include "usbd_msc_storage.h"
#include "py/misc.h"
-#include "lib/fatfs/diskio.h"
#include "storage.h"
#include "sdcard.h"
@@ -121,7 +120,7 @@ int8_t FLASH_STORAGE_StartStopUnit(uint8_t lun, uint8_t started) {
int8_t FLASH_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) {
// sync the flash so that the cache is cleared and the device can be unplugged/turned off
- disk_ioctl(0, CTRL_SYNC, NULL);
+ storage_flush();
return 0;
}
@@ -134,7 +133,7 @@ int8_t FLASH_STORAGE_PreventAllowMediumRemoval(uint8_t lun, uint8_t param) {
* @retval Status
*/
int8_t FLASH_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
- disk_read(0, buf, blk_addr, blk_len);
+ storage_read_blocks(buf, blk_addr, blk_len);
/*
for (int i = 0; i < blk_len; i++) {
if (!storage_read_block(buf + i * FLASH_BLOCK_SIZE, blk_addr + i)) {
@@ -154,7 +153,7 @@ int8_t FLASH_STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t
* @retval Status
*/
int8_t FLASH_STORAGE_Write (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {
- disk_write(0, buf, blk_addr, blk_len);
+ storage_write_blocks(buf, blk_addr, blk_len);
/*
for (int i = 0; i < blk_len; i++) {
if (!storage_write_block(buf + i * FLASH_BLOCK_SIZE, blk_addr + i)) {
diff --git a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
index 76a767892..96617b107 100644
--- a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
+++ b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h
@@ -28,10 +28,10 @@ typedef struct {
} USBD_CDC_LineCodingTypeDef;
typedef struct _USBD_CDC_Itf {
- int8_t (* Init) (void);
+ int8_t (* Init) (USBD_HandleTypeDef *pdev);
int8_t (* DeInit) (void);
int8_t (* Control) (uint8_t, uint8_t * , uint16_t);
- int8_t (* Receive) (uint8_t *, uint32_t *);
+ int8_t (* Receive) (USBD_HandleTypeDef *pdev, uint8_t *, uint32_t *);
} USBD_CDC_ItfTypeDef;
typedef struct {
@@ -48,7 +48,8 @@ typedef struct {
} USBD_CDC_HandleTypeDef;
typedef struct _USBD_HID_Itf {
- int8_t (* Receive)(uint8_t *, uint32_t);
+ int8_t (* Init) (USBD_HandleTypeDef *pdev);
+ int8_t (* Receive)(USBD_HandleTypeDef *pdev, uint8_t *, uint32_t);
} USBD_HID_ItfTypeDef;
typedef struct _USBD_STORAGE {
@@ -115,5 +116,7 @@ uint8_t USBD_HID_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
int USBD_HID_CanSendReport(USBD_HandleTypeDef *pdev);
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
+uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev);
+uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev);
#endif // _USB_CDC_MSC_CORE_H_
diff --git a/stmhal/usbdev/class/inc/usbd_msc_scsi.h b/stmhal/usbdev/class/inc/usbd_msc_scsi.h
index dea247bca..34f059ee5 100644
--- a/stmhal/usbdev/class/inc/usbd_msc_scsi.h
+++ b/stmhal/usbdev/class/inc/usbd_msc_scsi.h
@@ -55,6 +55,8 @@
#define SCSI_MODE_SENSE6 0x1A
#define SCSI_MODE_SENSE10 0x5A
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
+#define SCSI_SYNCHRONIZE_CACHE10 0x35
+#define SCSI_SYNCHRONIZE_CACHE16 0x91
#define SCSI_READ6 0x08
#define SCSI_READ10 0x28
#define SCSI_READ12 0xA8
diff --git a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c
index d13657023..e0edf1370 100644
--- a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c
+++ b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c
@@ -669,7 +669,7 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
CDC_CMD_PACKET_SIZE);
// Init physical Interface components
- CDC_fops->Init();
+ CDC_fops->Init(pdev);
// Init Xfer states
CDC_ClassData.TxState =0;
@@ -724,6 +724,8 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) {
USBD_EP_TYPE_INTR,
mps_out);
+ HID_fops->Init(pdev);
+
// Prepare Out endpoint to receive next packet
USBD_LL_PrepareReceive(pdev, hid_out_ep, HID_ClassData.RxBuffer, mps_out);
@@ -961,7 +963,7 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
- CDC_fops->Receive(CDC_ClassData.RxBuffer, &CDC_ClassData.RxLength);
+ CDC_fops->Receive(pdev, CDC_ClassData.RxBuffer, &CDC_ClassData.RxLength);
return USBD_OK;
} else if ((usbd_mode & USBD_MODE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) {
@@ -969,7 +971,7 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
return USBD_OK;
} else if ((usbd_mode & USBD_MODE_HID) && epnum == (hid_out_ep & 0x7f)) {
HID_ClassData.RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
- HID_fops->Receive(HID_ClassData.RxBuffer, HID_ClassData.RxLength);
+ HID_fops->Receive(pdev, HID_ClassData.RxBuffer, HID_ClassData.RxLength);
}
return USBD_OK;
@@ -1091,6 +1093,24 @@ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t
return USBD_OK;
}
+uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev) {
+ // get USBx object from pdev (needed for USBx_OUTEP macro below)
+ PCD_HandleTypeDef *hpcd = pdev->pData;
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ // set NAK on HID OUT endpoint
+ USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
+ return USBD_OK;
+}
+
+uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev) {
+ // get USBx object from pdev (needed for USBx_OUTEP macro below)
+ PCD_HandleTypeDef *hpcd = pdev->pData;
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ // clear NAK on HID OUT endpoint
+ USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
+ return USBD_OK;
+}
+
// CDC/MSC/HID interface class callback structure
USBD_ClassTypeDef USBD_CDC_MSC_HID = {
USBD_CDC_MSC_HID_Init,
diff --git a/stmhal/usbdev/class/src/usbd_msc_scsi.c b/stmhal/usbdev/class/src/usbd_msc_scsi.c
index 366f1f00e..b2931b745 100644
--- a/stmhal/usbdev/class/src/usbd_msc_scsi.c
+++ b/stmhal/usbdev/class/src/usbd_msc_scsi.c
@@ -89,6 +89,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
static int8_t SCSI_AllowMediumRemoval(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_SynchronizeCache(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params);
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params);
static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
@@ -151,6 +152,10 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
case SCSI_MODE_SENSE10:
return SCSI_ModeSense10 (pdev, lun, params);
+ case SCSI_SYNCHRONIZE_CACHE10:
+ case SCSI_SYNCHRONIZE_CACHE16:
+ return SCSI_SynchronizeCache(pdev, lun, params);
+
case SCSI_READ_FORMAT_CAPACITIES:
return SCSI_ReadFormatCapacity(pdev, lun, params);
@@ -374,6 +379,13 @@ static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
return 0;
}
+static int8_t SCSI_SynchronizeCache(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) {
+ // nothing to synchronize, so just return "success"
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+ hmsc->bot_data_length = 0;
+ return 0;
+}
+
/**
* @brief SCSI_RequestSense
* Process Request Sense command
diff --git a/stmhal/usrsw.c b/stmhal/usrsw.c
index 5bf4cc767..d4f0c6939 100644
--- a/stmhal/usrsw.c
+++ b/stmhal/usrsw.c
@@ -122,8 +122,8 @@ mp_obj_t pyb_switch_callback(mp_obj_t self_in, mp_obj_t callback) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_switch_callback_obj, pyb_switch_callback);
-STATIC const mp_map_elem_t pyb_switch_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_switch_callback_obj },
+STATIC const mp_rom_map_elem_t pyb_switch_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_callback), MP_ROM_PTR(&pyb_switch_callback_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_switch_locals_dict, pyb_switch_locals_dict_table);
@@ -134,7 +134,7 @@ const mp_obj_type_t pyb_switch_type = {
.print = pyb_switch_print,
.make_new = pyb_switch_make_new,
.call = pyb_switch_call,
- .locals_dict = (mp_obj_t)&pyb_switch_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_switch_locals_dict,
};
#endif // MICROPY_HW_HAS_SWITCH
diff --git a/stmhal/wdt.c b/stmhal/wdt.c
index d9a089d01..af2481e92 100644
--- a/stmhal/wdt.c
+++ b/stmhal/wdt.c
@@ -94,8 +94,8 @@ STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_wdt_feed_obj, pyb_wdt_feed);
-STATIC const mp_map_elem_t pyb_wdt_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_feed), (mp_obj_t)&pyb_wdt_feed_obj },
+STATIC const mp_rom_map_elem_t pyb_wdt_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&pyb_wdt_feed_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_wdt_locals_dict, pyb_wdt_locals_dict_table);
@@ -104,5 +104,5 @@ const mp_obj_type_t pyb_wdt_type = {
{ &mp_type_type },
.name = MP_QSTR_WDT,
.make_new = pyb_wdt_make_new,
- .locals_dict = (mp_obj_t)&pyb_wdt_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&pyb_wdt_locals_dict,
};