This commit adds initial support for STM32H5xx MCUs. The following
features have been confirmed to be working on an STM32H573:
- UART over REPL and USB CDC
- USB CDC and MSC
- internal flash filesystem
- machine.Pin
- machine.SPI transfers with DMA
- machine.ADC
- machine.RTC
- pyb.LED
- pyb.Switch
- pyb.rng
- mboot
Signed-off-by: Damien George <damien@micropython.org>
To override it a board must define MICROPY_BOARD_FATAL_ERROR to a function
that takes a string message and does not return.
Signed-off-by: Damien George <damien@micropython.org>
This commit adds support for the STM32G4 series of MCUs, and a board
definition for NUCLEO_G474RE. This board has the REPL on LPUART1 which is
connected to the on-board ST-link USB-UART.
Prior to this commit IRQs on STM32F4 could be lost because SR is cleared by
reading SR then reading DR. For example, if both RXNE and IDLE IRQs were
active upon entry to the IRQ handler, then IDLE is lost because the code
that handles RXNE comes first and accidentally clears SR (by reading SR
then DR to get the incoming character).
This commit fixes this problem by making the IRQ handler more atomic in the
following operations:
- get current IRQ status flags
- deal with RX character
- clear remaining status flags
- call user handler
On the STM32F4 it's very hard to get this right because the only way to
clear IRQ status flags is to read SR then DR, but the read of DR may read
some data which should remain in the register until the user wants to read
it. And it won't work to cache the read because RTS/CTS flow control will
then not work. So instead the new code disables interrupts if the DR is
full and waits for the user to read it before reenabling the interrupts.
Fixes issue mentioned in #4599 and #6082.
Signed-off-by: Damien George <damien@micropython.org>
This commit is based upon prior work of @dpgeorge and @koendv.
MCU support for the STM32H7A3 and B3 families MCUs:
- STM32H7A3xx
- STM32H7A3xxQ (SMPS)
- STM32H7B3xx
- STM32H7B3xxQ (SMPS)
Support has been added for the STM32H7B3I_DK board.
Signed-off-by: Jan Staal <info@janstaal.com>
It needs to use a different function because the formula to compute the
baudrate on LPUART1 is different to a normal UART.
Fixes issue #7466.
Signed-off-by: Damien George <damien@micropython.org>
RX and CTS are the input pins and pull-ups are enabled so they don't cause
a problem if left unconnected. But the output pins don't need a pull up
(they were originally all configured with pull up in commit
8f7491a109).
If needed, the pull-ups can be disabled in Python using machine.Pin after
the UART is constructed.
See issue #4369.
Signed-off-by: Damien George <damien@micropython.org>
This function includes the UART prescaler in the calculation (if it has
one, eg on H7 and WB MCUs).
Signed-off-by: Damien George <damien@micropython.org>
Add LPUART1 as a standard UART. No low power features are supported, yet.
LPUART1 is enabled as the next available UART after the standard U(S)ARTs:
STM32WB: LPUART1 = UART(2)
STM32L0: LPUART1 = UART(6)
STM32L4: LPUART1 = UART(6)
STM32H7: LPUART1 = UART(9)
On all ports: LPUART1 = machine.UART('LP1')
LPUART1 is enabled by defining MICROPY_HW_LPUART1_TX and
MICROPY_HW_LPUART1_RX in mpconfigboard.h.
Signed-off-by: Chris Mason <c.mason@inchipdesign.com.au>
This allows changing the baudrate of the UART without reinitialising it
(reinitialising can lead to spurious characters sent on the TX line).
Signed-off-by: Damien George <damien@micropython.org>
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.
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.
On MCUs other than F4 the ORE (overrun error) flag needs to be cleared
independently of clearing RXNE, even though both are wired to trigger the
same RXNE IRQ. In the case that an overrun occurred it's necessary to
explicitly clear the ORE flag or else the RXNE interrupt will keep firing.
Otherwise IRQs may not be enabled for the user UART.irq() handler. In
particular this fixes the user IRQ_RXIDLE interrupt so that it triggers
even when there is no RX buffer.
This UART_HandleTypeDef is quite large (around 70 bytes in RAM needed for
each UART object) and is not needed: instead the state of the peripheral
held in its registers provides all the required information.
As per the machine.UART documentation, this is used to set the length of
the RX buffer. The legacy read_buf_len argument is retained for backwards
compatibility, with rxbuf overriding it if provided.
Also change the order of printing of flow so it is after stop (so bits,
parity, stop are one after the other), and reduce code size by using
mp_print_str instead of mp_printf where possible.
See issue #1981.
With this and previous patches the stm32 port can now be compiled using
object representation D (nan boxing). Note that native code and frozen mpy
files with float constants are currently not supported with this object
representation.
For a given IRQn (eg UART) there's no need to carry around both a PRI and
SUBPRI value (eg IRQ_PRI_UART, IRQ_SUBPRI_UART). Instead, the IRQ_PRI_UART
value has been changed in this patch to be the encoded hardware value,
using NVIC_EncodePriority. This way the NVIC_SetPriority function can be
used directly, instead of going through HAL_NVIC_SetPriority which must do
extra processing to encode the PRI+SUBPRI.
For a priority grouping of 4 (4 bits for preempt priority, 0 bits for the
sub-priority), which is used in the stm32 port, the IRQ_PRI_xxx constants
remain unchanged in their value.
This patch also "fixes" the use of raise_irq_pri() which should be passed
the encoded value (but as mentioned above the unencoded value is the same
as the encoded value for priority grouping 4, so there was no bug from this
error).
Rather than pin objects themselves. The actual object is now pin_X_obj and
defines are provided so that pin_X is &pin_X_obj. This makes it so that
code that uses pin objects doesn't need to know if they are literals or
objects (that need pointers taken) or something else. They are just
entities that can be passed to the map_hal_pin_xxx functions. This mirrors
how the core handles constant objects (eg mp_const_none which is
&mp_const_none_obj) and allows for the possibility of different
implementations of the pin layer.
For example, prior to this patch there was the following:
extern const pin_obj_t pin_A0;
#define pyb_pin_X1 pin_A0
...
mp_hal_pin_high(&pin_A0);
and now there is:
extern const pin_obj_t pin_A0_obj;
#define pin_A0 (&pin_A0_obj)
#define pyb_pin_X1 pin_A0
...
mp_hal_pin_high(pin_A0);
This patch should have minimal effect on board configuration files. The
only change that may be needed is if a board has .c files that configure
pins.