This new series of MCUs is similar to the L4 series with an additional
Cortex-M0 coprocessor. The firmware for the wireless stack must be managed
separately and MicroPython does not currently interface to it. Supported
features so far include: RTC, UART, USB, internal flash filesystem.
Entering a bootloader (ST system bootloader, or custom mboot) from software
by directly branching to it is not reliable, and the reliability of it
working can depend on the peripherals that were enabled by the application
code. It's also not possible to branch to a bootloader if the WDT is
enabled (unless the bootloader has specific provisions to feed the WDT).
This patch changes the way a bootloader is entered from software by first
doing a complete system reset, then branching to the desired bootloader
early on in the start-up process. The top two words of RAM (of the stack)
are reserved to store flags indicating that the bootloader should be
entered after a reset.
Previously the end of the heap was the start (lowest address) of the stack.
With the changes in this commit these addresses are now independent,
allowing a board to place the heap and stack in separate locations.
Includes:
- Support for CAN3.
- Support for UART9 and UART10.
- stm32f413xg.ld and stm32f413xh.ld linker scripts.
- stm32f413_af.csv alternate function mapping.
- startup_stm32f413xx.s because F413 has different interrupt vector table.
- Memory configuration with: 240K filesystem, 240K heap, 16K stack.
To use HSI instead of HSE define MICROPY_HW_CLK_USE_HSI as 1 in the board
configuration file. The default is to use HSE.
HSI has been made the default for the NUCLEO_F401RE board to serve as an
example, and because early revisions of this board need a hardware
modification to get HSE working.
Instead of checking each callback (currently storage and dma) explicitly
for each SysTick IRQ, use a simple circular function table indexed by the
lower bits of the millisecond tick counter. This allows callbacks to be
easily enabled/disabled at runtime, and scales well to a large number of
callbacks.
If no block devices are defined by a board then storage support will be
disabled. This means there is no filesystem provided by either the
internal flash or external SPI flash. But the VFS system can still be
enabled and filesystems provided on external devices like an SD card.
When disabled, the pyb.I2C class saves around 8k of code space and 172
bytes of RAM. The same functionality is now available in machine.I2C
(for F4 and F7 MCUs).
It is still enabled by default.
To use HSE bypass mode the board should define:
#define MICROPY_HW_CLK_USE_BYPASS (1)
If this is not defined, or is defined to 0, then HSE oscillator mode is
used.
This patch allows a given board to configure which pins are used for the
CAN peripherals, in a similar way to all the other bus peripherals (I2C,
UART, SPI). To enable CAN on a board the mpconfigboard.h file should
define (for example):
#define MICROPY_HW_CAN1_TX (pin_B9)
#define MICROPY_HW_CAN1_RX (pin_B8)
#define MICROPY_HW_CAN2_TX (pin_B13)
#define MICROPY_HW_CAN2_RX (pin_B12)
And the board config file should no longer define MICROPY_HW_ENABLE_CAN.
The CMSIS files for the STM32 range provide macros to distinguish between
the different MCU series: STM32F4, STM32F7, STM32H7, STM32L4, etc. Prefer
to use these instead of custom ones.
This patch allows to completely compile-out support for USB, and no-USB is
now the default. If a board wants to enable USB it should define:
#define MICROPY_HW_ENABLE_USB (1)
And then one or more of the following to select the USB PHY:
#define MICROPY_HW_USB_FS (1)
#define MICROPY_HW_USB_HS (1)
#define MICROPY_HW_USB_HS_IN_FS (1)
Header files that are considered internal to the py core and should not
normally be included directly are:
py/nlr.h - internal nlr configuration and declarations
py/bc0.h - contains bytecode macro definitions
py/runtime0.h - contains basic runtime enums
Instead, the top-level header files to include are one of:
py/obj.h - includes runtime0.h and defines everything to use the
mp_obj_t type
py/runtime.h - includes mpstate.h and hence nlr.h, obj.h, runtime0.h,
and defines everything to use the general runtime support functions
Additional, specific headers (eg py/objlist.h) can be included if needed.
This is to keep the top-level directory clean, to make it clear what is
core and what is a port, and to allow the repository to grow with new ports
in a sustainable way.
The renames are:
HAL_Delay -> mp_hal_delay_ms
sys_tick_udelay -> mp_hal_delay_us
sys_tick_get_microseconds -> mp_hal_ticks_us
And mp_hal_ticks_ms is added to provide the full set of timing functions.
Also, a separate HAL_Delay function is added which differs slightly from
mp_hal_delay_ms and is intended for use only by the ST HAL functions.
This patch changes the threading implementation from simple round-robin
with busy waits on mutexs, to proper scheduling whereby threads that are
waiting on a mutex are only scheduled when the mutex becomes available.
This new function controls what happens on a hard-fault:
- debugging disabled: board will do a reset
- debugging enabled: board will print registers and stack and flash LEDs
The default is disabled, ie to do a reset. This is different to previous
behaviour which flashed the LEDs and waited indefinitely.
This patch brings the _thread module to stmhal/pyboard. There is a very
simple round-robin thread scheduler, which is disabled if there is only
one thread (for efficiency when threading is not used).
The scheduler currently switches threads at a rate of 250Hz using the
systick timer and the pend-SV interrupt.
The GIL is disabled so one must be careful to use lock objects to prevent
concurrent access of objects.
The threading is disabled by default, one can enabled it with the config
option MICROPY_PY_THREAD to test it out.
It turns out that TIM1 and TIM8 have their own Capture/Compare
interrupt vector. For all of the other timers, the capture/compare
interrupt vector is the same as the update vector.
So we need to add handlers for these vectors and enable them
when using capture/compare callbacks.
During testing of this, I also found that passing a channel callback
into the channel constructor would not enable interrupts properly.
I tested using:
```
>>> pyb.Timer(1, freq=4).channel(1, pyb.Timer.OC_TOGGLE, callback=lambda t: print('.', end=''))
```
I tested the above with channels 1, 4, and 8
TIM3 is no longer used by USB CDC for triggering outgoing data, so we
can now make it available to the user.
PWM fading on LED(4) is now gone, but will be reinstated in a new way.