The aim here is to have spi.c contain the low-level SPI driver which is
independent (not fully but close) of MicroPython objects and methods, and
the higher-level bindings are separated out to pyb_spi.c and machine_spi.c.
Requesting a baudrate of X should never configure the peripheral to have a
baudrate greater than X because connected hardware may not be able to
handle higher speeds. This patch makes sure to round the prescaler up so
that the actual baudrate is rounded down.
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.
The DMA peripheral is limited to transferring 65535 elements at a time so
in order to send more than that the SPI driver must split the transfers up.
The user must be aware of this limit if they are relying on precise timing
of the entire SPI transfer, because there might be a small delay between
the split transfers.
Fixes issue #3851, and thanks to @kwagyeman for the original fix.
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.
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.
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.
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).
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.
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.