The problem is the existing code which tries to optimise the
reinitialisation of the DMA breaks the abstraction of the HAL. For the
STM32L4 the HAL's DMA setup code maintains two private vars (ChannelIndex,
DmaBaseAddress) and updates a hardware register (CCR).
In HAL_DMA_Init(), the CCR is updated to set the direction of the DMA.
This is a problem because, when using the SD Card interface, the same DMA
channel is used in both directions, so the direction bit in the CCR must
follow that.
A quick and effective fix for the L4 is to simply call HAL_DMA_DeInit() and
HAL_DMA_Init() every time.
ADC3 is used because the H7's internal ADC channels are connected to ADC3
and the uPy driver doesn't support more than one ADC.
Only 12-bit resolution is supported because 12 is hard-coded and 14/16 bits
are not recommended on some ADC3 pins (see errata).
Values from internal ADC channels are known to give wrong values at
present.
After calling HAL_SYSTICK_Config the SysTick IRQ priority is set to 15, the
lowest priority. This commit reconfigures the IRQ priority to the desired
TICK_INT_PRIORITY value.
By default the stm module is included in the build, but a board can now
define MICROPY_PY_STM to 0 to not include this module. This reduces the
firmware by about 7k.
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 individual union members (like SPI, I2C) are never used, only the
generic "reg" entry is. And the union names can clash with macro
definitions in the HAL so better to remove them.
The only configuration that changes with this patch is that on L4 MCUs the
clock prescaler changed from ADC_CLOCK_ASYNC_DIV2 to ADC_CLOCK_ASYNC_DIV1
for the ADCAll object. This should be ok.
A value of DISABLE for EOCSelection is invalid. This would have been
interpreted instead as ADC_EOC_SEQ_CONV, but really it should be
ADC_EOC_SINGLE_CONV for the uses in this code. So this has been fixed.
ExternalTrigConv should be ADC_SOFTWARE_START because all ADC
conversions are started by software. This is now fixed.
This can be used to select the output buffer behaviour of the DAC. The
default values are chosen to retain backwards compatibility with existing
behaviour.
Thanks to @peterhinch for the initial idea to add this feature.
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.