Most stm32 boards can now be built in nan-boxing mode via:
$ make NANBOX=1
Note that if float is enabled then it will be forced to double-precision.
Also, native emitters will be disabled.
- Corrected pin assignments and checked with CubeMX.
- Added additional I2C and UARTs.
- Added Ethernet interface definitions with lwIP and SSL support (but
Ethernet is currently unsupported on H7 MCUs so not fully enabled).
- Removed remarks on DFU/OCD in mpconfigboard.h because deploy-stlink works
fine too.
- Added more UARTs, I2C, corrected SPI, CAN, etc; verified against CubeMX.
- Adapted pins.csv to remove errors, add omissions, etc. according to
NUCLEO-144 User Manual.
- Changed linker file stm32f767.ld to reflect correct size of the Flash.
- Tested with LAN and SD card.
The Nucleo board does not have an SD card slot but does have the requisite
pins next to each other and labelled, so provide the configuration for
convenience.
The default protection for the BLE ringbuf is to use
MICROPY_BEGIN_ATOMIC_SECTION, which disables all interrupts. On stm32 it
only needs to disable the lowest priority IRQ, pendsv, because that's the
IRQ level at which the BLE stack is driven.
qstrs in this file are always included in all builds, even if not used
anywhere. So remove those that are never needed, and make USB names
conditional on having USB enabled.
And return -MP_EIO if calling storage_read_block/storage_write_block fails.
This lines up with the return type and value (negative for error) of the
calls to MICROPY_HW_BDEV_READBLOCKS (and WRITEBLOCKS, and BDEV2 versions).
The pyb.Flash() class can now be used to construct objects which reference
sections of the flash storage, starting at a certain offset and going for a
certain length. Such objects also support the extended block protocol.
The signature for the constructor is: pyb.Flash(start=-1, len=-1).
This commit refactors and generalises the boot-mount routine on stm32 so
that it can mount filesystems of arbitrary type. That is, it no longer
assumes that the filesystem is FAT. It does this by using mp_vfs_mount()
which does auto-detection of the filesystem type.
Using mp_hal_delay_ms allows the scheduler to run, which might result in
another transmit operation happening, which would bypass the sleep (and
fail). Use mp_hal_delay_us instead.
This commit removes the Makefile-level MICROPY_FATFS config and moves the
MICROPY_VFS_FAT config to the Makefile level to replace it. It also moves
the include of the oofatfs source files in the build from each port to a
central place in extmod/extmod.mk.
For a port to enabled VFS FAT support it should now set MICROPY_VFS_FAT=1
at the level of the Makefile. This will include the relevant oofatfs files
in the build and set MICROPY_VFS_FAT=1 at the C (preprocessor) level.
This commit adds an implementation of machine.Timer backed by the soft
timer mechanism. It allows an arbitrary number of timers with 1ms
resolution, with an associated Python callback. The Python-level API
matches existing ports that have a soft timer, and is used as:
from machine import Timer
t = Timer(freq=10, callback=lambda t:print(t))
...
t = Timer(mode=Timer.ONE_SHOT, period=2000, callback=lambda t:print(t))
...
t.deinit()
This commit adds an implementation of a "software timer" with a 1ms
resolution, using SysTick. It allows unlimited number of concurrent
timers (limited only by memory needed for each timer entry). They can be
one-shot or periodic, and associated with a Python callback.
There is a very small overhead added to the SysTick IRQ, which could be
further optimised in the future, eg by patching SysTick_Handler code
dynamically.
For consistency with "umachine". Now that weak links are enabled
by default for built-in modules, this should be a no-op, but allows
extension of the bluetooth module by user code.
Also move registration of ubluetooth to objmodule rather than
port-specific.
This commit implements automatic module weak links for all built-in
modules, by searching for "ufoo" in the built-in module list if "foo"
cannot be found. This means that all modules named "ufoo" are always
available as "foo". Also, a port can no longer add any other weak links,
which makes strict the definition of a weak link.
It saves some code size (about 100-200 bytes) on ports that previously had
lots of weak links.
Some changes from the previous behaviour:
- It doesn't intern the non-u module names (eg "foo" is not interned),
which saves code size, but will mean that "import foo" creates a new qstr
(namely "foo") in RAM (unless the importing module is frozen).
- help('modules') no longer lists non-u module names, only the u-variants;
this reduces duplication in the help listing.
Weak links are effectively the same as having a set of symbolic links on
the filesystem that is searched last. So an "import foo" will search
built-in modules first, then all paths in sys.path, then weak links last,
importing "ufoo" if it exists. Thus a file called "foo.py" somewhere in
sys.path will still have precedence over the weak link of "foo" to "ufoo".
See issues: #1740, #4449, #5229, #5241.
When loading a manifest file, e.g. by include(), it will chdir first to the
directory of that manifest. This means that all file operations within a
manifest are relative to that manifest's location.
As a consequence of this, additional environment variables are needed to
find absolute paths, so the following are added: $(MPY_LIB_DIR),
$(PORT_DIR), $(BOARD_DIR). And rename $(MPY) to $(MPY_DIR) to be
consistent.
Existing manifests are updated to match.
Prior to this commit the systick IRQ priority was set at lowest priority on
F0/L0/WB MCUs, because it was left at the default and never configured.
This commit ensures the priority is configured and sets it to the highest
priority.
On other ports (e.g. ESP32) they provide a complete Nimble implementation
(i.e. we don't need to use the code in extmod/nimble). This change
extracts out the bits that we don't need to use in other ports:
- malloc/free/realloc for Nimble memory.
- pendsv poll handler
- depowering the cywbt
Also cleans up the root pointer management.
STM32F0 has PCLK=48MHz and maximum ADC clock is 14MHz so use PCLK/4=12MHz
to stay within spec of the ADC peripheral. In pyb.ADC set common sampling
time to approx 4uS for internal and external sources. In machine.ADC
reduce sample time to approx 1uS for external source, leave internal at
maximum sampling time.
This commit adds the option to use HSE or MSI system clock, and LSE or LSI
RTC clock, on L4 MCUs.
Note that prior to this commit the default clocks on an L4 part were MSI
and LSE. The defaults are now MSI and LSI.
In mpconfigboard.h select the clock source via:
#define MICROPY_HW_RTC_USE_LSE (0) or (1)
#define MICROPY_HW_CLK_USE_HSE (0) or (1)
and the PLLSAI1 N,P,Q,R settings:
#define MICROPY_HW_CLK_PLLSAIN (12)
#define MICROPY_HW_CLK_PLLSAIP (RCC_PLLP_DIV7)
#define MICROPY_HW_CLK_PLLSAIQ (RCC_PLLQ_DIV2)
#define MICROPY_HW_CLK_PLLSAIR (RCC_PLLR_DIV2)
For use with F0 MCUs that don't have HSI48. Select the clock source
explicitly in mpconfigboard.h.
On the NUCLEO_F091RC board use HSE bypass when HSE is chosen because the
NUCLEO clock source is STLINK not a crystal.
Before this patch the UART baudrate on F0 MCUs was wrong because the
stm32lib SystemCoreClockUpdate sets SystemCoreClock to 8MHz instead of
48MHz if HSI48 is routed directly to SYSCLK.
The workaround is to use HSI48 -> PREDIV (/2) -> PLL (*2) -> SYSCLK.
Fixes issue #5049.
Enabled by default, but disabled when REPL is connected to the VCP (this is
the existing behaviour). Can be configured at run-time with, eg:
pyb.USB_VCP().init(flow=pyb.USB_VCP.RTS | pyb.USB_VCP.CTS)
The new fdcan.c file provides the low-level C interface to the FDCAN
peripheral, and pyb_can.c is updated to support both traditional CAN and
FDCAN, depending on the MCU being compiled for.
According to the schematic, the SDRAM part on this board is a
MT48LC4M32B2B5-6A, with "Row addressing 4K A[11:0]" (per datasheet). This
commit updates mpconfigboard.h from 13 to 12 to match.
- STM32F407VGT6 (1MB of Flash, 192+4 Kbytes of SRAM)
- 5V (via USB) or Li-Polymer Battery (3.7V) power input
- 2 x LEDs
- 2 x user switches
- 2 x mikroBUS sockets
- 2 x 1x26 mikromedia-compatible headers (52 pins)
https://www.mikroe.com/clicker-2-stm32f4
Mboot currently requires at least three LEDs to display each of the four
states. However, since there are only four possible states, the states can
be displayed via binary counting on only 2 LEDs (if only 2 are available).
The existing patterns are still used for 3 or 4 LEDs.
As per PEP 485, this function appeared in for Python 3.5. Configured via
MICROPY_PY_MATH_ISCLOSE which is disabled by default, but enabled for the
ports which already have MICROPY_PY_MATH_SPECIAL_FUNCTIONS enabled.
Before this patch I2C transactions using a hardware I2C peripheral on F0/F7
MCUs would not correctly generate the I2C restart condition, and instead
would generate a stop followed by a start. This is because the CR2 AUTOEND
bit was being set before CR2 START when the peripheral already had the I2C
bus from a previous transaction that did not generate a stop.
As a consequence all combined transactions, eg read-then-write for an I2C
memory transfer, generated a stop condition after the first transaction and
didn't generate a stop at the very end (but still released the bus). Some
I2C devices require a repeated start to function correctly.
This patch fixes this by making sure the CR2 AUTOEND bit is set after the
start condition and slave address have been fully transferred out.
Some SD/MMC breakout boards don't support 4-bit bus mode. This adds a new
macro MICROPY_HW_SDMMC_BUS_WIDTH that allows each board to define the width
of the SD/MMC bus interface used on that board, defaulting to 4 bits.
The previous version did not work on MCUs that only had USB device mode
(compared to OTG) because of the handling of NAK. And this previous
handling of NAK had a race condition where a new packet could come in
before USBD_HID_SetNAK was called (since USBD_HID_ReceivePacket clears NAK
as part of its operation). Furthermore, the double buffering of incoming
reports was not working, only one buffer could be used at a time.
This commit rewrites the HID interface code to have a single incoming
buffer, and only calls USBD_HID_ReceivePacket after the user has read the
incoming report (similar to how the VCP does its flow control). As such,
USBD_HID_SetNAK and USBD_HID_ClearNAK are no longer needed.
API functionality from the user's point of view should be unchanged with
this commit.
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.
The new configurations MICROPY_HW_USB_MSC and MICROPY_HW_USB_HID can be
used by a board to enabled or disable MSC and/or HID. They are both
enabled by default.
In a non-thread build, using &_ram_end as the top-of-stack is no longer
correct because the stack is not always at the very top end of RAM. See
eg 04c7cdb668 and
3786592097. The correct value to use is
&_estack, which is the value stored in MP_STATE_THREAD(stack_top), and
using the same code for both thread and non-thread builds makes the code
cleaner.
stm32lib now provides system_stm32XXxx.c source files for all MCU variants,
which includes SystemInit and prescaler tables. Since these are quite
standard and don't need to be changed, switch to use them instead of custom
variants, making the start-up code cleaner.
The SystemInit code in stm32lib was checked and is equivalent to what is
removed from the stm32 port in this commit.
This is a start to make a more consistent machine.RTC class across ports.
The stm32 pyb.RTC class at least has the datetime() method which behaves
the same as esp8266 and esp32, and with this patch the ntptime.py script
now works with stm32.
If both FS and HS USB peripherals are enabled for a board then the active
one used for the REPL will now be auto-detected, by checking to see if both
the DP and DM lines are actively pulled low. By default the code falls
back to use MICROPY_HW_USB_MAIN_DEV if nothing can be detected.
When going out of memory-mapped mode to do a control transfer to the QSPI
flash, the MPU settings must be changed to forbid access to the memory
mapped region. And any ongoing transfer (eg memory mapped continuous read)
must be aborted.
The Cortex-M7 CPU will do speculative loads from any memory location that
is not explicitly forbidden. This includes the QSPI memory-mapped region
starting at 0x90000000 and with size 256MiB. Speculative loads to this
QSPI region may 1) interfere with the QSPI peripheral registers (eg the
address register) if the QSPI is not in memory-mapped mode; 2) attempt to
access data outside the configured size of the QSPI flash when it is in
memory-mapped mode. Both of these scenarios will lead to issues with the
QSPI peripheral (eg Cortex bus lock up in scenario 2).
To prevent such speculative loads from interfering with the peripheral the
MPU is configured in this commit to restrict access to the QSPI mapped
region: when not memory mapped the entire region is forbidden; when memory
mapped only accesses to the valid flash size are permitted.
Commit 9e68eec8ea introduced a regression
where the PID of the USB device would be 0xffff if the default value was
used. This commit fixes that by using a signed int type.
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.
With this the user can select multiple logical units to expose over USB MSC
at once, eg: pyb.usb_mode('VCP+MSC', msc=(pyb.Flash(), pyb.SDCard())). The
default behaviour is the original behaviour of just one unit at a time.
Eventually these responses could be filled in by a function to make their
contents dynamic, depending on the attached logical units. But for now
they are fixed, and this patch fixes the MODE SENSE(6) responses so it is
the correct length with the correct header.
SCSI can support multiple logical units over the one interface (in this
case over USBD MSC) and here the MSC code is reworked to support this
feature. At this point only one LU is used and the behaviour is mostly
unchanged from before, except the INQUIRY result is different (it will
report "Flash" for both flash and SD card).
To use it a board should define MICROPY_PY_USSL=1 and MICROPY_SSL_MBEDTLS=1
at the Makefile level. With the provided configuration it adds about 64k
to the build.
It doesn't work to tie the polling of an underlying NIC driver (eg to check
the NIC for pending Ethernet frames) with its associated lwIP netif. This
is because most NICs are implemented with IRQs and don't need polling,
because there can be multiple lwIP netif's per NIC driver, and because it
restricts the use of the netif->state variable. Instead the NIC should
have its own specific way of processing incoming Ethernet frame.
This patch removes this generic NIC polling feature, and for the only
driver that uses it (Wiznet5k) replaces it with an explicit call to the
poll function (which could eventually be improved by using a proper
external interrupt).
If the board-pin name is left empty then only the cpu-pin name is used, eg
",PA0". If the board-pin name starts with a hyphen then it's available as
a C definition but not in the firmware, eg "-X1,PA0".
The board config option MICROPY_HW_USB_ENABLE_CDC2 is now changed to
MICROPY_HW_USB_CDC_NUM, and the latter should be defined to the maximum
number of CDC interfaces to support (defaults to 1).
Set the active MPU region to the actual size of SDRAM configured and
invalidate the rest of the memory-mapped region, to prevent errors due to
CPU speculation. Also update the attributes of the SDRAM region as per ST
recommendations, and change region numbers to avoid conflicts elsewhere in
the codebase (see eth usage).
On MCUs that have an I2C TIMINGR register, this can now be explicitly set
via the "timingr" keyword argument to the I2C constructor, for both
machine.I2C and pyb.I2C. This allows to configure precise timing values
when the defaults are inadequate.
Previously the hardware I2C timeout was hard coded to 50ms which isn't
guaranteed to be enough depending on the clock stretching specs of the I2C
device(s) in use.
This patch ensures the hardware I2C implementation honors the existing
timeout argument passed to the machine.I2C constructor. The default
timeout for software and hardware I2C is now 50ms.
Recent gcc versions (at least 9.1) give a warning about using "sp" in the
clobber list. Such code is removed by this patch. A dedicated function is
instead used to set SP and branch to the bootloader so the code has full
control over what happens.
Fixes issue #4785.
Before this change, if the USB was reconnected it was possible that some
characters in the TX buffer were retransmitted because tx_buf_ptr_out and
tx_buf_ptr_out_shadow were reset while tx_buf_ptr_in wasn't. That
behaviour is fixed here by retaining the TX buffer state across reconnects.
Fixes issue #4761.
The new function factory_reset_make_files() populates the given filesystem
with the default factory files. It is defined with weak linkage so it can
be overridden by a board.
This commit also brings some minor user-facing changes:
- boot.py is now no longer created unconditionally if it doesn't exist, it
is now only created when the filesystem is formatted and the other files
are populated (so, before, if the user deleted boot.py it would be
recreated at next boot; now it won't be).
- pybcdc.inf and README.txt are only created if the board has USB, because
they only really make sense if the filesystem is exposed via USB.
It's more common to need non-blocking behaviour when reading from a UART,
rather than having a large timeout like 1000ms (the original behaviour).
With a large timeout it's 1) likely that the function will read forever if
characters keep trickling it; or 2) the function will unnecessarily wait
when characters come sporadically, eg at a REPL prompt.
The alternate function pin allocations are different to other NUCLEO-144
boards. This is because the STM32F413 has a very high peripheral count:
10x UART, 5x SPI, 3x I2C, 3x CAN. The pinout was chosen to expose all
these devices on separate pins except CAN3 which shares a pin with UART1
and SPI1 which shares pins with DAC.
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.
This patch makes pllvalues.py generate two tables: one for when HSI is used
and one for when HSE is used. The correct table is then selected at
compile time via the existing MICROPY_HW_CLK_USE_HSI.
On the STM32F722 (at least, but STM32F767 is not affected) the CK48MSEL bit
must be deselected before PLLSAION is turned off, or else the 48MHz
peripherals (RNG, SDMMC, USB) may get stuck without a clock source.
In such "lock up" cases it seems that these peripherals are still being
clocked from the PLLSAI even though the CK48MSEL bit is turned off. A hard
reset does not get them out of this stuck state. Enabling the PLLSAI and
then disabling it does get them out. A test case to see this is:
import machine, pyb
for i in range(100):
machine.freq(122_000000)
machine.freq(120_000000)
print(i, [pyb.rng() for _ in range(4)])
On occasion the RNG will just return 0's, but will get fixed again on the
next loop (when PLLSAI is enabled by the change to a SYSCLK of 122MHz).
Fixes issue #4696.
The stm32 and nrf ports already had the behaviour that they would first
check if the script exists before executing it, and this patch makes all
other ports work the same way. This helps when developing apps because
it's hard to tell (when unconditionally trying to execute the scripts) if
the resulting OSError at boot up comes from missing boot.py or main.py, or
from some other error. And it's not really an error if these scripts don't
exist.
This patch makes the DAC driver simpler and removes the need for the ST
HAL. As part of it, new helper functions are added to the DMA driver,
which also use direct register access instead of the ST HAL.
Main changes to the DAC interface are:
- The DAC uPy object is no longer allocated dynamically on the heap,
rather it's statically allocated and the same object is retrieved for
subsequent uses of pyb.DAC(<id>). This allows to access the DAC objects
without resetting the DAC peripheral. It also means that the DAC is only
reset if explicitly passed initialisation parameters, like "bits" or
"buffering".
- The DAC.noise() and DAC.triangle() methods now output a signal which is
full scale (previously it was a fraction of the full output voltage).
- The DAC.write_timed() method is fixed so that it continues in the
background when another peripheral (eg SPI) uses the DMA (previously the
DAC would stop if another peripheral finished with the DMA and shut the
DMA peripheral off completely).
Based on the above, the following backwards incompatibilities are
introduced:
- pyb.DAC(id) will now only reset the DAC the first time it is called,
whereas previously each call to create a DAC object would reset the DAC.
To get the old behaviour pass the bits parameter like: pyb.DAC(id, bits).
- DAC.noise() and DAC.triangle() are now full scale. To get previous
behaviour (to change the amplitude and offset) write to the DAC_CR (MAMP
bits) and DAC_DHR12Rx registers manually.
If MICROPY_HW_RTC_USE_BYPASS is enabled the RTC startup goes as follows:
- RTC is started with LSE in bypass mode to begin with
- if that fails to start (after a given timeout) then LSE is reconfigured
in non-bypass
- if that fails to start then RTC is switched to LSI
Use uos.dupterm for REPL configuration of the main USB_VCP(0) stream on
dupterm slot 1, if USB is enabled. This means dupterm can also be used to
disable the boot REPL port if desired, via uos.dupterm(None, 1).
For efficiency this adds a simple hook to the global uos.dupterm code to
work with streams that are known to be native streams.
These macros are unused, and they can conflict with other entities by the
same name. If needed they can be provided as static inline functions, or
just functions.
Fixes issue #4559.
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.
This demonstrates how to use external QSPI flash in XIP (execute in place)
mode. The default configuration has all extmod/ code placed into external
QSPI flash, but other code can easily be put there by modifying the custom
f769_qspi.ld script.
A board can now use the make variables TEXT0_SECTIONS and TEXT1_SECTIONS to
specify the linker sections that should go in its firmware. Defaults are
provided which give the existing behaviour.
Currently all usages of mp_hal_pin_config_alt_static() set the pin speed to
"high" (50Mhz). The SDRAM interface typically runs much faster than this
so should be set to the maximum pin speed.
This commit adds mp_hal_pin_config_alt_static_speed() which allows setting
the pin speed along with the other alternate function details.
A few RTC constants weren't being parsed properly due to whitespace
differences, and this patch makes certain whitespace optional. Changes
made:
- allow for no space between /*!< and EXTI, eg for:
__IO uint32_t IMR; /*!<EXTI Interrupt mask register, Address offset: 0x00 */
- allow for no space between semicolon and start of comment, eg for:
__IO uint32_t ALRMASSR;/*!< RTC alarm A sub second register, Address offset: 0x44 */