summaryrefslogtreecommitdiff
path: root/stmhal
diff options
context:
space:
mode:
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,
};