Skip to content

Commit 72dbdee

Browse files
committed
Add SPI support to STM32 platform
Also add stm32_chip_info to `erlang:system_info/1` Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 8756d65 commit 72dbdee

23 files changed

Lines changed: 1583 additions & 31 deletions

File tree

.github/workflows/stm32-build.yaml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ jobs:
185185
mkdir build-host
186186
cd build-host
187187
cmake .. -G Ninja
188-
cmake --build . -t stm32_boot_test stm32_gpio_test stm32_i2c_test
188+
cmake --build . -t stm32_boot_test stm32_gpio_test stm32_i2c_test stm32_spi_test
189189
190190
- name: Install Renode
191191
if: matrix.renode_platform
@@ -241,3 +241,18 @@ jobs:
241241
--variable AVM:@$PWD/build-host/src/platforms/stm32/tests/test_erl_sources/stm32_i2c_test.avm \
242242
--variable AVM_ADDRESS:${{ matrix.avm_address }} \
243243
--variable PLATFORM:$PLATFORM
244+
245+
- name: Run Renode SPI test
246+
if: matrix.renode_platform
247+
run: |
248+
LOCAL_REPL="src/platforms/stm32/tests/renode/${{ matrix.renode_platform }}"
249+
if [ -f "$LOCAL_REPL" ]; then
250+
PLATFORM="@$PWD/$LOCAL_REPL"
251+
else
252+
PLATFORM="@platforms/cpus/${{ matrix.renode_platform }}"
253+
fi
254+
renode-test src/platforms/stm32/tests/renode/stm32_spi_test.robot \
255+
--variable ELF:@$PWD/src/platforms/stm32/build/AtomVM-${{ matrix.device }}.elf \
256+
--variable AVM:@$PWD/build-host/src/platforms/stm32/tests/test_erl_sources/stm32_spi_test.avm \
257+
--variable AVM_ADDRESS:${{ matrix.avm_address }} \
258+
--variable PLATFORM:$PLATFORM

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [0.7.0-beta.0] - Unreleased
88

9+
### Added
10+
- Added I2C and SPI APIs to stm32 platform
11+
912
## [0.7.0-alpha.1] - 2026-04-06
1013

1114
### Added

examples/erlang/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,5 @@ pack_runnable(http_client http_client estdlib eavmlib avm_network)
4545
pack_runnable(disterl disterl estdlib)
4646
pack_runnable(i2c_scanner i2c_scanner eavmlib estdlib DIALYZE_AGAINST avm_esp32 avm_rp2 avm_stm32)
4747
pack_runnable(i2c_lis3dh i2c_lis3dh eavmlib estdlib DIALYZE_AGAINST avm_esp32 avm_rp2 avm_stm32)
48-
pack_runnable(spi_flash spi_flash eavmlib estdlib DIALYZE_AGAINST avm_esp32 avm_rp2)
49-
pack_runnable(spi_lis3dh spi_lis3dh eavmlib estdlib DIALYZE_AGAINST avm_esp32 avm_rp2)
48+
pack_runnable(spi_flash spi_flash eavmlib estdlib DIALYZE_AGAINST avm_esp32 avm_rp2 avm_stm32)
49+
pack_runnable(spi_lis3dh spi_lis3dh eavmlib estdlib DIALYZE_AGAINST avm_esp32 avm_rp2 avm_stm32)

examples/erlang/spi_flash.erl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
%% Default pins are auto-detected from the platform and chip model:
2828
%%
2929
%% Pico (SPI0): SCK=GP2, MOSI=GP3, MISO=GP4, CS=GP5
30+
%% STM32 (SPI1): SCK=PA5, MOSI=PA7, MISO=PA6, CS=PA4
3031
%% ESP32/S2/S3 (SPI2): SCK=18, MOSI=23, MISO=19, CS=5
3132
%% ESP32-C2/C3/C5 (SPI2): SCK=6, MOSI=7, MISO=2, CS=10
3233
%% ESP32-C6/C61 (SPI2): SCK=6, MOSI=7, MISO=2, CS=16
@@ -108,6 +109,7 @@ default_pins() ->
108109

109110
%% {SCK, MOSI, MISO, CS}
110111
default_pins(pico) -> {2, 3, 4, 5};
112+
default_pins(stm32) -> {{a, 5}, {a, 7}, {a, 6}, {a, 4}};
111113
default_pins(esp32) -> esp32_default_pins().
112114

113115
esp32_default_pins() ->

examples/erlang/spi_lis3dh.erl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
%% Default pins are auto-detected from the platform and chip model:
2828
%%
2929
%% Pico (SPI0): SCK=GP2, MOSI=GP3, MISO=GP4, CS=GP5
30+
%% STM32 (SPI1): SCK=PA5, MOSI=PA7, MISO=PA6, CS=PA4
3031
%% ESP32/S2/S3 (SPI2): SCK=18, MOSI=23, MISO=19, CS=5
3132
%% ESP32-C2/C3/C5 (SPI2): SCK=6, MOSI=7, MISO=2, CS=10
3233
%% ESP32-C6/C61 (SPI2): SCK=6, MOSI=7, MISO=2, CS=16
@@ -134,6 +135,7 @@ default_pins() ->
134135

135136
%% {SCK, MOSI, MISO, CS}
136137
default_pins(pico) -> {2, 3, 4, 5};
138+
default_pins(stm32) -> {{a, 5}, {a, 7}, {a, 6}, {a, 4}};
137139
default_pins(esp32) -> esp32_default_pins().
138140

139141
esp32_default_pins() ->

examples/erlang/stm32/CMakeLists.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,41 @@ pack_runnable(blink_weact_studio_u585 blink_weact_studio_u585 eavmlib avm_stm32)
3232
pack_runnable(blink_weact_studio_wb55 blink_weact_studio_wb55 eavmlib avm_stm32)
3333
pack_runnable(blink_nucleo64 blink_nucleo64 eavmlib avm_stm32)
3434
pack_runnable(blink_nucleo144 blink_nucleo144 eavmlib avm_stm32)
35+
36+
if(AVM_RELEASE)
37+
set(INCLUDE_LINES "--remove_lines")
38+
else()
39+
set(INCLUDE_LINES "")
40+
endif()
41+
42+
set(SPI_LIS3DH_BEAM ${CMAKE_BINARY_DIR}/examples/erlang/spi_lis3dh.beam)
43+
add_custom_command(
44+
OUTPUT stm32_spi_lis3dh.avm
45+
DEPENDS spi_lis3dh_main ${SPI_LIS3DH_BEAM}
46+
${CMAKE_BINARY_DIR}/libs/estdlib/src/estdlib.avm estdlib
47+
${CMAKE_BINARY_DIR}/libs/avm_stm32/src/avm_stm32.avm avm_stm32
48+
PackBEAM
49+
COMMAND ${CMAKE_BINARY_DIR}/tools/packbeam/packbeam create ${INCLUDE_LINES} stm32_spi_lis3dh.avm
50+
${SPI_LIS3DH_BEAM}
51+
${CMAKE_BINARY_DIR}/libs/estdlib/src/estdlib.avm
52+
${CMAKE_BINARY_DIR}/libs/avm_stm32/src/avm_stm32.avm
53+
COMMENT "Packing runnable stm32_spi_lis3dh.avm"
54+
VERBATIM
55+
)
56+
add_custom_target(stm32_spi_lis3dh ALL DEPENDS stm32_spi_lis3dh.avm)
57+
58+
set(SPI_FLASH_BEAM ${CMAKE_BINARY_DIR}/examples/erlang/spi_flash.beam)
59+
add_custom_command(
60+
OUTPUT stm32_spi_flash.avm
61+
DEPENDS spi_flash_main ${SPI_FLASH_BEAM}
62+
${CMAKE_BINARY_DIR}/libs/estdlib/src/estdlib.avm estdlib
63+
${CMAKE_BINARY_DIR}/libs/avm_stm32/src/avm_stm32.avm avm_stm32
64+
PackBEAM
65+
COMMAND ${CMAKE_BINARY_DIR}/tools/packbeam/packbeam create ${INCLUDE_LINES} stm32_spi_flash.avm
66+
${SPI_FLASH_BEAM}
67+
${CMAKE_BINARY_DIR}/libs/estdlib/src/estdlib.avm
68+
${CMAKE_BINARY_DIR}/libs/avm_stm32/src/avm_stm32.avm
69+
COMMENT "Packing runnable stm32_spi_flash.avm"
70+
VERBATIM
71+
)
72+
add_custom_target(stm32_spi_flash ALL DEPENDS stm32_spi_flash.avm)

libs/avm_stm32/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ include(BuildErlang)
2525
set(ERLANG_MODULES
2626
gpio
2727
i2c
28+
spi
2829
)
2930

3031
pack_archive(avm_stm32 DEPENDS_ON eavmlib ERLC_FLAGS +warnings_as_errors MODULES ${ERLANG_MODULES})

libs/avm_stm32/src/gpio.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@
5959
-type direction() :: input | output | output_od.
6060
%% The direction is used to set the mode of operation for a GPIO pin, either as an input, an output, or output with open drain.
6161
%% Pull mode and output_speed must be set at the same time as direction. See @type mode_config()
62-
-type mode_config() :: {direction(), pull()} | {output, pull(), output_speed()}.
62+
-type mode_config() ::
63+
{direction(), pull()} | {output, pull(), output_speed()} | {af, non_neg_integer()}.
6364
%% Extended mode configuration options. Default pull() is `floating', default output_speed() is `mhz_2' if options are omitted.
65+
%% `{af, AFNumber}' configures the pin in alternate function push-pull mode with the given AF number (e.g. 5 for SPI1).
6466
-type pull() :: up | down | floating.
6567
%% Internal resistor pull mode. STM32 does not support `up_down'.
6668
-type output_speed() :: mhz_2 | mhz_25 | mhz_50 | mhz_100.

0 commit comments

Comments
 (0)