This patch moves the implementation of stream closure from a dedicated
method to the ioctl of the stream protocol, for each type that implements
closing. The benefits of this are:
1. Rounds out the stream ioctl function, which already includes flush,
seek and poll (among other things).
2. Makes calling mp_stream_close() on an object slightly more efficient
because it now no longer needs to lookup the close method and call it,
rather it just delegates straight to the ioctl function (if it exists).
3. Reduces code size and allows future types that implement the stream
protocol to be smaller because they don't need a dedicated close method.
Code size reduction is around 200 bytes smaller for x86 archs and around
30 bytes smaller for the bare-metal archs.
The main() function has a predefined type in C which is not so useful for
embedded contexts. This patch renames main() to stm32_main() so we can
define our own type signature for this function. The type signature is
defined to have a single argument which is the "reset_mode" and is passed
through as r0 from Reset_Handler. This allows, for example, a bootloader
to pass through information into the main application.
The Reset_Handler needs to copy the data section and zero the BSS, and
these operations should be as optimised as possible to reduce start up
time. The versions provided in this patch are about 2x faster (on a Cortex
M4) than the previous implementations.
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.
This patch forces a board to explicitly define TEXT1_ADDR in order to
split the firmware into two separate pieces. Otherwise the default is now
to produce only a single continuous firmware image with all ISR, text and
data together.
This patch allows a particular board to independently specify the linker
scripts for 1) the MCU memory layout; 2) how the different firmware
sections are arranged in memory. Right now all boards follow the same
layout with two separate firmware section, one for the ISR and one for the
text and data. This leaves room for storage (filesystem data) to live
between the firmware sections.
The idea with this patch is to accommodate boards that don't have internal
flash storage and only need to have one continuous firmware section. Thus
the common.ld script is renamed to common_ifs.ld to make explicit that it
is used for cases where the board has internal flash storage.
Explicitly writing out the implementation of sys_tick_has_passed makes
these bdev files independent of systick.c and more reusable as a general
component. It also reduces the code size slightly.
The irq.h header is added to spibdev.c because it uses declarations in that
file (irq.h is usually included implicitly via mphalport.h but not always).
Taking the address assumes that the pin is an object (eg a struct), but it
could be a literal (eg an int). Not taking the address makes this driver
more general for other uses.
genhdr/pins.h is an internal header file that defines all of the pin
objects and it's cleaner to have pin.h include it (where the struct's for
these objects are defined) rather than an explicit include by every user.
The HAL requires strict aliasing optimisation to be turned on to function
correctly (at least for the SD card driver on F4 MCUs). This optimisation
was recently disabled with the addition of H7 support due to the H7 HAL
having errors with the strict aliasing optimisation enabled. But this is
now fixed in the latest stm32lib and so the optimisation can now be
re-enabled.
Thanks to @chuckbook for finding that there was a problem with the SD card
on F4 MCUs with the strict aliasing optimisation disabled.
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 provides a custom (and simple) function to receive data on the
CAN bus, instead of the HAL function. This custom version calls
mp_handle_pending() while waiting for messages, which, among other things,
allows to interrupt the recv() method via KeyboardInterrupt.
Certain pins (eg 4 and 5) seem to behave differently at the hardware level
when in open-drain mode: they glitch when set "high" and drive the pin
active high for a brief period before disabling the output driver. To work
around this make the pin an input to let it float high.
This config variable controls whether to support storage on the internal
flash of the MCU. It is enabled by default and should be explicitly
disabled by boards that don't want internal flash storage.
It makes it cleaner, and simpler to support multiple different block
devices. It also allows to easily extend a given block device with new
ioctl operations.
This patch alters the SPI-flash memory driver so that it uses the new
low-level C SPI protocol (from drivers/bus/spi.h) instead of the uPy SPI
protocol (from extmod/machine_spi.h). This allows the SPI-flash driver to
be used independently from the uPy runtime.
This patch takes the software SPI implementation from extmod/machine_spi.c
and moves it to a dedicated file in drivers/bus/softspi.c. This allows the
SPI driver to be used independently of the uPy runtime, making it a more
general component.
The PWM at full value was not considered as an "active" channel so if no
other channel was used the timer used to mange PWM was not started. So
when another duty value was set the PWM timer restarted and there was a
visible glitch when driving LEDs. Such a glitch can be seen with the
following code (assuming active-low LED on pin 0):
p = machine.PWM(machine.Pin(0))
p.duty(1023) # full width, LED is off
p.duty(1022) # LED flashes brightly then goes dim
This patch fixes the glitch.
This test for calling gc_realloc() while the GC is locked can be done in
pure Python, so better to do it that way since it can then be tested on
more ports.
These new tests cover cases that can't be reached from Python and get
coverage of py/mpz.c to 100%.
These "unreachable from Python" pieces of code could be removed but they
form an integral part of the mpz C API and may be useful for non-Python
usage of mpz.
These ports don't need anything from extmod so don't include those files
at all in the build. This speeds up the build by about 10% when building
with a single core.
Currently only the first 2 args are used, but this patch should at least
make getaddrinfo() signature-compatible with CPython and other bare-metal
ports that use the lwip bindings.
Prior to this patch, storage.c was a combination of code that handled
either internal flash or external SPI flash and exposed one of them as a
block device for the local storage. It was also exposed to the USB MSC.
This patch splits out the flash and SPI code to separate files, which each
provide a general block-device interface (at the C level). Then storage.c
just picks one of them to use as the local storage medium. The aim of this
factoring is to allow to add new block devices in the future and allow for
easier configurability.
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)
Newer versions of the HAL use names which are cleaner and more
self-consistent amongst the HAL itself. This patch switches to use those
names in most places so it is easier to update the HAL in the future.
Prior to this patch the USBD driver did not handle the recipient correctly
for setup requests. It was not interpreting the req->wIndex field in the
right way: in some cases this field indicates the endpoint number but the
code was assuming it always indicated the interface number.
This patch fixes this. The only noticeable change is to the MSC
interface, which should now correctly respond to the USB_REQ_CLEAR_FEATURE
request and hence unmount properly from the host when requested.
mpconfigboard_common.h now sets the defaults so there is no longer a need
to explicitly list all configuration options in a board's mpconfigboard.h
file.
This file mirrors py/mpconfig.h but for board-level config options. It
provides a default configuration, to be overridden by a specific
mpconfigboard.h file, as well as setting up certain macros to automatically
configure a board.
The calls to rtc_init_start(), sdcard_init() and storage_init() are all
guarded by a check for first_soft_reset, so it's simpler to just put them
all before the soft-reset loop, without the check.
The call to machine_init() can also go before the soft-reset loop because
it is only needed to check the reset cause which can happen once at the
first boot. To allow this to work, the reset cause must be set to SOFT
upon a soft-reset, which is the role of the new function machine_deinit().
Upon boot the RTC early-init function should detect if LSE or LSI is
already selected/running and, if so, use it. When the LSI has previously
(in the previous reset cycle) been selected as the clock source the only
way to reliably tell is if the RTCSEL bits of the RCC_BDCR are set to the
correct LSI value. In particular the RCC_CSR bits for LSI control do not
indicate if the LSI is ready even if it is selected.
This patch removes the check on the RCC_CSR bits for the LSI being on and
ready and only uses the check on the RCC_BDCR to see if the LSI should be
used straightaway. This was tested on a PYBLITEv1.0 and with the patch the
LSI persists correctly as the RTC source as long as the backup domain
remains powered.
Previously, if LSE is selected but fails and the RTC falls back to LSI,
then the rtc_info flags would incorrectly state that LSE is used. This
patch fixes that by setting the bit in rtc_info only after the clock is
ready.
There is an underlying hardware SPI driver (built on top of the STM HAL)
and then on top of this sits the legacy pyb.SPI class as well as the
machine.SPI class. This patch improves the separation between these
layers, in particular decoupling machine.SPI from pyb.SPI.
The SPI sub-system is independent from the uPy state (eg the heap) and so
can safely persist across a soft reset. And this is actually necessary for
drivers that rely on SPI and that also need to persist across soft reset
(eg external SPI flash memory).
This patch adds support in the USBD configuration and CDC-MSC-HID class for
high-speed USB mode. To enable it the board configuration must define
USE_USB_HS, and either not define USE_USB_HS_IN_FS, or be an STM32F723 or
STM32F733 MCU which have a built-in HS PHY. High-speed mode is then
selected dynamically by passing "high_speed=True" to the pyb.usb_mode()
function, otherwise it defaults to full-speed mode.
This patch has been tested on an STM32F733.
By defining MICROPY_HW_USB_MAIN_DEV a given board can select to use either
USB_PHY_FS_ID or USB_PHY_HS_ID as the main USBD peripheral, on which the
REPL will appear. If not defined this will be automatically configured.
There's no need to have these as separate functions, they just take up
unnecessary code space and combining them allows to factor common code, and
also allows to support arbitrary string descriptor indices.
The routine waits for the DMA to finish, which is signalled from a DMA IRQ
handler. Using WFI makes the CPU sleep while waiting for the IRQ to arrive
which decreases power consumption. To make it work correctly the check for
the change in state must be atomic and so IRQs must be disabled during the
check. The key feature of the Cortex MCU that makes this possible is that
WFI will exit when an IRQ arrives even if IRQs are disabled.
Build and test 32bit and 64bit versions of the windows port using gcc
from mingw-w64. Note a bunch of tests which rely on floating point
math/printing have been disabled for now since they fail.
The number of registers used should be 10, not 12, to match the assembly
code in nlrx64.c. With this change the 64bit mingw builds don't need to
use the setjmp implementation, and this fixes miscellaneous crashes and
assertion failures as reported in #1751 for instance.
To avoid mistakes in the future where something gcc-related for Windows
only gets fixed for one particular compiler/environment combination,
make use of a MICROPY_NLR_OS_WINDOWS macro.
To make sure everything nlr-related is now ok when built with gcc this
has been verified with:
- unix port built with gcc on Cygwin (i686-pc-cygwin-gcc and
x86_64-pc-cygwin-gcc, version 6.4.0)
- windows port built with mingw-w64's gcc from Cygwin
(i686-w64-mingw32-gcc and x86_64-w64-mingw32-gcc, version 6.4.0)
and MSYS2 (like the ones on Cygwin but version 7.2.0)
Add some features which are already enabled in the unix port and
default to using the Python stack for scoped allocations: this can be
more performant in cases the heap is heavily used because for example
the memory needed for storing *args and **kwargs doesn't require
scanning the heap to find a free block.
For MSVC off_t is defined in sys/types.h but according to the comment
earlier in mpconfigport.h this cannot be included directly.
So just make off_t the same as mp_off_t.
This fixes the build for MSVC with MICROPY_STREAMS_POSIX_API
enabled because stream.h uses off_t.
These were copied from the stm32 port (then stmhal) at the very beginning
of this port, with the anticipation that the esp8266 port would have board
definition files with a list of valid pins and their names. But that has
not been implemented and likely won't be, so remove the corresponding lines
from the Makefile.
This patch adds in internal config value MICROPY_HW_ENABLE_HW_I2C that is
automatically configured, and enabled only if one or more hardware I2C
ports are defined in the mpconfigboard.h file. If none are defined then
the pyb.I2C class is excluded from the build, along with all supporting
code. The machine.I2C class will still be available for software I2C.
Disabling all hardware I2C on an F4 board saves around 10,000 bytes of code
and 200 bytes of RAM.
If TEST is defined, file it refers to will be used as the testsuite
source (should be generated with tools/tinytest-codegen.py).
"make-bin-testsuite" script is introduce to build such a binary.
Because otherwise the function can return with data still waiting to be
clocked out, and CS might then be disabled before the SPI transaction is
complete. Fixes issue #3487.
The way tinytest was used in qemu-arm test target is that it didn't test
much. MicroPython tests are based on matching the test output against
reference output, but qemu-arm's implementation didn't do that, it
effectively tested just that there was no exception during test
execution. "upytesthelper" wrapper was introduce to fix it, so switch
test implementation to use it.
This requires passing different CFLAGS when building the firmware, so
split out test-related parts to Makefile.test.
Code lineage:
osdebug() is based loosely on the version in esp8266, but there didn't
seem to be an obvious way of choosing a particular UART. The basic
behavior is the same, though: provide None, and logging is disabled;
provide an integer and logging is restored to the default level.
To build on that, and because the IDF provides more functionality, a
second parameter has now been implemented which allows the active log
level to be set:
esp.osdebug(uart[, level])
The module has a corresponding set of LOG_ values to set this accordingly.
When configuring a static set of values with ifconfig() the DNS was not
being set. This patch fixes that, and additionally uses the tcpip_adapter
API to ensure it is thread safe.
Further discussion is here:
https://github.com/micropython/micropython-esp32/issues/210/