diff --git a/.github/workflows/compile-all.yml b/.github/workflows/compile-all.yml
index 1327e814fe..34ceb4c302 100644
--- a/.github/workflows/compile-all.yml
+++ b/.github/workflows/compile-all.yml
@@ -226,7 +226,7 @@ jobs:
- name: Checkout code and update modm tools
run: |
(git submodule sync && git submodule update --init --jobs 8) & pip3 install --upgrade --upgrade-strategy=eager modm & wait
- - name: Compile HAL for all STM32F7 Part 1
+ - name: Compile HAL for all STM32F7 Part 2
run: |
(cd test/all && python3 run_all.py stm32f7 --quick-remaining --split 2 --part 1)
- name: Upload log artifacts
@@ -236,6 +236,49 @@ jobs:
name: stm32f7-compile-all-2
path: test/all/log
+ stm32l0-compile-all-1:
+ if: github.event.label.name == 'ci:hal'
+ runs-on: ubuntu-20.04
+ container:
+ image: ghcr.io/modm-ext/modm-build-cortex-m:latest
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v2
+ - name: Checkout code and update modm tools
+ run: |
+ (git submodule sync && git submodule update --init --jobs 8) & pip3 install --upgrade --upgrade-strategy=eager modm & wait
+ - name: Compile HAL for all STM32L0 Part 1
+ run: |
+ (cd test/all && python3 run_all.py stm32l0 --quick-remaining --split 2 --part 0)
+ - name: Upload log artifacts
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: stm32l0-compile-all-1
+ path: test/all/log
+
+ stm32l0-compile-all-2:
+ if: github.event.label.name == 'ci:hal'
+ runs-on: ubuntu-20.04
+ container:
+ image: ghcr.io/modm-ext/modm-build-cortex-m:latest
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v2
+ - name: Checkout code and update modm tools
+ run: |
+ (git submodule sync && git submodule update --init --jobs 8) & pip3 install --upgrade --upgrade-strategy=eager modm & wait
+ - name: Compile HAL for all STM32L0 Part 2
+ run: |
+ (cd test/all && python3 run_all.py stm32l0 --quick-remaining --split 2 --part 1)
+ - name: Upload log artifacts
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: stm32l0-compile-all-2
+ path: test/all/log
+
+
stm32l1-compile-all:
if: github.event.label.name == 'ci:hal'
runs-on: ubuntu-20.04
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 8a7761f098..047f4a6aa0 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -107,6 +107,10 @@ jobs:
if: always()
run: |
(cd examples && ../tools/scripts/examples_compile.py nucleo_g071rb)
+ - name: Examples STM32L0 Series
+ if: always()
+ run: |
+ (cd examples && ../tools/scripts/examples_compile.py nucleo_l031k6)
- name: Examples STM32L1 Series
if: always()
run: |
@@ -280,7 +284,7 @@ jobs:
uses: actions/checkout@v2
- name: Update submodules and install lbuild
run: |
- (git submodule sync && git submodule update --init --jobs 8) & pip3 --upgrade --upgrade-strategy=eager modm & wait
+ (git submodule sync && git submodule update --init --jobs 8) & pip3 install --upgrade --upgrade-strategy=eager modm & wait
- name: Test run of docs.modm.io-generator-script
if: always()
run: |
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index dd9c2a5b10..2ae0053974 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -63,7 +63,7 @@ jobs:
- name: Compile STM32 Examples
run: |
(cd examples && ../tools/scripts/examples_compile.py nucleo_f031k6 nucleo_f103rb nucleo_f303re nucleo_f411re nucleo_f746zg)
- (cd examples && ../tools/scripts/examples_compile.py nucleo_g071rb nucleo_l152re nucleo_l476rg nucleo_g474re)
+ (cd examples && ../tools/scripts/examples_compile.py nucleo_g071rb nucleo_l031k6 nucleo_l152re nucleo_l476rg nucleo_g474re)
- name: Compile AVR Examples
run: |
diff --git a/.github/workflows/windows_armcortexm.yml b/.github/workflows/windows_armcortexm.yml
index 593acad1b5..8988fe570d 100644
--- a/.github/workflows/windows_armcortexm.yml
+++ b/.github/workflows/windows_armcortexm.yml
@@ -56,7 +56,7 @@ jobs:
shell: bash
run: |
(cd examples && python ../tools/scripts/examples_compile.py nucleo_f031k6 nucleo_f103rb nucleo_f303re nucleo_f411re nucleo_f746zg)
- (cd examples && python ../tools/scripts/examples_compile.py nucleo_g071rb nucleo_l152re nucleo_l476rg nucleo_g474re)
+ (cd examples && python ../tools/scripts/examples_compile.py nucleo_g071rb nucleo_l031k6 nucleo_l152re nucleo_l476rg nucleo_g474re)
# - name: Compile AVR Examples
# shell: bash
diff --git a/README.md b/README.md
index 83a525e5ae..e296d93996 100644
--- a/README.md
+++ b/README.md
@@ -74,9 +74,9 @@ git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git
## Microcontrollers
-modm can create a HAL for 2679 devices of these vendors:
+modm can create a HAL for 3107 devices of these vendors:
-- STMicroelectronics STM32: 2010 devices.
+- STMicroelectronics STM32: 2438 devices.
- Microchip SAM: 163 devices.
- Microchip AVR: 506 devices.
@@ -95,7 +95,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
|
-STM32 |
+STM32 |
SAM |
AT |
@@ -108,6 +108,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
| F7 |
G0 |
G4 |
+L0 |
L1 |
L4 |
D21 |
@@ -124,6 +125,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+○ |
✅ |
✅ |
○ |
@@ -141,6 +143,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✗ |
○ |
✗ |
+✗ |
✅ |
✗ |
○ |
@@ -157,6 +160,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
○ |
✅ |
○ |
+○ |
✅ |
○ |
○ |
@@ -175,6 +179,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
○ |
○ |
○ |
+○ |
✗ |
○ |
✗ |
@@ -189,6 +194,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
○ |
○ |
○ |
+○ |
✅ |
○ |
✗ |
@@ -210,6 +216,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✗ |
✗ |
✗ |
+✗ |
| External Interrupt |
✅ |
@@ -226,6 +233,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
| External Memory |
✗ |
@@ -237,6 +245,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✗ |
○ |
✗ |
+✗ |
○ |
✗ |
✗ |
@@ -258,6 +267,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
| I2C |
✅ |
@@ -270,6 +280,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
○ |
✅ |
✅ |
@@ -287,6 +298,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
○ |
○ |
○ |
+○ |
✗ |
✗ |
✗ |
@@ -300,6 +312,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
✗ |
✅ |
✗ |
@@ -318,6 +331,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
○ |
✅ |
✅ |
@@ -335,6 +349,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
✗ |
✗ |
✗ |
@@ -350,6 +365,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
○ |
○ |
○ |
@@ -369,6 +385,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
○ |
| Unique ID |
@@ -382,6 +399,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
✗ |
✗ |
✗ |
@@ -399,6 +417,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
✅ |
✅ |
✅ |
+✅ |
✗ |
✗ |
✗ |
@@ -468,18 +487,19 @@ We have out-of-box support for many development boards including documentation.
NUCLEO-G431KB |
NUCLEO-G431RB |
NUCLEO-G474RE |
-NUCLEO-L152RE |
+NUCLEO-L031K6 |
+| NUCLEO-L152RE |
NUCLEO-L432KC |
NUCLEO-L452RE |
NUCLEO-L476RG |
-OLIMEXINO-STM32 |
+| OLIMEXINO-STM32 |
Raspberry Pi |
SAMD21-MINI |
STM32-F4VE |
-STM32F030-DEMO |
+| STM32F030-DEMO |
diff --git a/examples/nucleo_l031k6/blink/main.cpp b/examples/nucleo_l031k6/blink/main.cpp
new file mode 100644
index 0000000000..27b5693d5a
--- /dev/null
+++ b/examples/nucleo_l031k6/blink/main.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016-2017, Niklas Hauser
+ * Copyright (c) 2017, Nick Sarten
+ *
+ * This file is part of the modm project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include
+
+using namespace Board;
+
+int
+main()
+{
+ Board::initialize();
+ LedD13::setOutput();
+
+ // Use the logging streams to print some messages.
+ // Change MODM_LOG_LEVEL above to enable or disable these messages
+ MODM_LOG_DEBUG << "debug" << modm::endl;
+ MODM_LOG_INFO << "info" << modm::endl;
+ MODM_LOG_WARNING << "warning" << modm::endl;
+ MODM_LOG_ERROR << "error" << modm::endl;
+
+ uint32_t counter(0);
+
+ while (true)
+ {
+ LedD13::toggle();
+ modm::delay(Button::read() ? 100ms : 500ms);
+
+ MODM_LOG_INFO << "loop: " << counter++ << modm::endl;
+ }
+
+ return 0;
+}
diff --git a/examples/nucleo_l031k6/blink/project.xml b/examples/nucleo_l031k6/blink/project.xml
new file mode 100644
index 0000000000..b234525d07
--- /dev/null
+++ b/examples/nucleo_l031k6/blink/project.xml
@@ -0,0 +1,9 @@
+
+ modm:nucleo-l031k6
+
+
+
+
+ modm:build:scons
+
+
diff --git a/ext/modm-devices b/ext/modm-devices
index 462b3ed9ab..0bf0ab0789 160000
--- a/ext/modm-devices
+++ b/ext/modm-devices
@@ -1 +1 @@
-Subproject commit 462b3ed9ab25a6113f050f8cb6f467ed9b8a0e76
+Subproject commit 0bf0ab07895882e1d9181427f253149101d3f6a0
diff --git a/ext/st/device.hpp.in b/ext/st/device.hpp.in
index 193f3516c8..df9261628c 100644
--- a/ext/st/device.hpp.in
+++ b/ext/st/device.hpp.in
@@ -29,6 +29,31 @@
#include <{{ header }}>
%% endfor
+%% if target.family in ["g0"]
+// these defines are missing from the STM32G0 header files
+#define RCC_CFGR_SW_HSI (0UL) /*!< HSI selected as system clock */
+#define RCC_CFGR_SW_HSE (0x00000001UL) /*!< HSE selected as system clock */
+#define RCC_CFGR_SW_PLL (0x00000002UL) /*!< PLL selected as system clock */
+#define RCC_CFGR_SW_LSI (0x00000003UL) /*!< LSI selected as system clock */
+#define RCC_CFGR_SW_LSE (0x00000004UL) /*!< LSE selected as system clock */
+
+#define RCC_CFGR_HPRE_DIV1 (0x0UL) /*!< SYSCLK not divided */
+#define RCC_CFGR_HPRE_DIV2 (0x00000800UL) /*!< SYSCLK divided by 2 */
+#define RCC_CFGR_HPRE_DIV4 (0x00000900UL) /*!< SYSCLK divided by 4 */
+#define RCC_CFGR_HPRE_DIV8 (0x00000A00UL) /*!< SYSCLK divided by 8 */
+#define RCC_CFGR_HPRE_DIV16 (0x00000B00UL) /*!< SYSCLK divided by 16 */
+#define RCC_CFGR_HPRE_DIV64 (0x00000C00UL) /*!< SYSCLK divided by 64 */
+#define RCC_CFGR_HPRE_DIV128 (0x00000D00UL) /*!< SYSCLK divided by 128 */
+#define RCC_CFGR_HPRE_DIV256 (0x00000E00UL) /*!< SYSCLK divided by 256 */
+#define RCC_CFGR_HPRE_DIV512 (0x00000F00UL) /*!< SYSCLK divided by 512 */
+
+#define RCC_CFGR_PPRE_DIV1 (0x0UL) /*!< HCLK not divided */
+#define RCC_CFGR_PPRE_DIV2 (0x00004000UL) /*!< HCLK divided by 2 */
+#define RCC_CFGR_PPRE_DIV4 (0x00005000UL) /*!< HCLK divided by 4 */
+#define RCC_CFGR_PPRE_DIV8 (0x00006000UL) /*!< HCLK divided by 8 */
+#define RCC_CFGR_PPRE_DIV16 (0x00007000UL) /*!< HCLK divided by 16 */
+%% endif
+
/// @cond
// This is a hack to make the *_Typedef's known to GDB, so that you can debug
// the peripherals directly in GDB in any context.
diff --git a/ext/st/module.lb b/ext/st/module.lb
index d54d59d81d..e90bb805e0 100644
--- a/ext/st/module.lb
+++ b/ext/st/module.lb
@@ -152,6 +152,7 @@ def build(env):
env.substitutions.update({
"headers": [bprops["device_header"], bprops["system_header"]],
"defines": [bprops["define"]],
+ "target": env[":target"].identifier,
})
env.outbasepath = "modm/src/modm/platform"
env.template("device.hpp.in")
diff --git a/ext/st/stm32 b/ext/st/stm32
index 75a672b85f..4eeaf5fa97 160000
--- a/ext/st/stm32
+++ b/ext/st/stm32
@@ -1 +1 @@
-Subproject commit 75a672b85fd577b5eda0b56b0a80b373e8c9efbc
+Subproject commit 4eeaf5fa97b3a687dba73883966703f81c5da6af
diff --git a/repo.lb b/repo.lb
index fe886c7abb..91fd4c27b2 100644
--- a/repo.lb
+++ b/repo.lb
@@ -83,7 +83,7 @@ class DevicesCache(dict):
# roughly filter to supported devices
supported = ["stm32f0", "stm32f1", "stm32f2", "stm32f3", "stm32f4", "stm32f7",
"stm32g0", "stm32g4",
- "stm32l1", "stm32l4",
+ "stm32l0", "stm32l1", "stm32l4",
"at90", "attiny", "atmega",
"samd21",
"hosted"]
diff --git a/src/modm/board/nucleo32_arduino.hpp b/src/modm/board/nucleo32_arduino.hpp.in
similarity index 87%
rename from src/modm/board/nucleo32_arduino.hpp
rename to src/modm/board/nucleo32_arduino.hpp.in
index b728a1f968..f72d1fb8cd 100644
--- a/src/modm/board/nucleo32_arduino.hpp
+++ b/src/modm/board/nucleo32_arduino.hpp.in
@@ -19,8 +19,13 @@ using D3 = GpioB0;
using D4 = GpioB7;
using D5 = GpioB6;
using D6 = GpioB1;
+%% if has_gpio_c14_c15
+using D7 = GpioC14;
+using D8 = GpioC15;
+%% else
using D7 = GpioF0;
using D8 = GpioF1;
+%% endif
using D9 = GpioA8;
using D10 = GpioA11;
using D11 = GpioB5;
diff --git a/src/modm/board/nucleo_f031k6/module.lb b/src/modm/board/nucleo_f031k6/module.lb
index 2b04182bf6..af09b6d9bf 100644
--- a/src/modm/board/nucleo_f031k6/module.lb
+++ b/src/modm/board/nucleo_f031k6/module.lb
@@ -31,9 +31,10 @@ def build(env):
env.outbasepath = "modm/src/modm/board"
env.substitutions = {
"with_logger": True,
- "with_assert": env.has_module(":architecture:assert")
+ "with_assert": env.has_module(":architecture:assert"),
+ "has_gpio_c14_c15": False
}
env.template("../board.cpp.in", "board.cpp")
env.copy('.')
- env.copy("../nucleo32_arduino.hpp", "nucleo32_arduino.hpp")
+ env.template("../nucleo32_arduino.hpp.in", "nucleo32_arduino.hpp")
env.collect(":build:openocd.source", "board/st_nucleo_f0.cfg");
diff --git a/src/modm/board/nucleo_f042k6/module.lb b/src/modm/board/nucleo_f042k6/module.lb
index 2d81cf9123..81c39b3946 100644
--- a/src/modm/board/nucleo_f042k6/module.lb
+++ b/src/modm/board/nucleo_f042k6/module.lb
@@ -32,9 +32,10 @@ def build(env):
env.outbasepath = "modm/src/modm/board"
env.substitutions = {
"with_logger": True,
- "with_assert": env.has_module(":architecture:assert")
+ "with_assert": env.has_module(":architecture:assert"),
+ "has_gpio_c14_c15": False
}
env.template("../board.cpp.in", "board.cpp")
env.copy('.')
- env.copy("../nucleo32_arduino.hpp", "nucleo32_arduino.hpp")
+ env.template("../nucleo32_arduino.hpp.in", "nucleo32_arduino.hpp")
env.collect(":build:openocd.source", "board/st_nucleo_f0.cfg");
diff --git a/src/modm/board/nucleo_f303k8/module.lb b/src/modm/board/nucleo_f303k8/module.lb
index 09cd48e36a..5ad5d28b63 100644
--- a/src/modm/board/nucleo_f303k8/module.lb
+++ b/src/modm/board/nucleo_f303k8/module.lb
@@ -31,9 +31,10 @@ def build(env):
env.outbasepath = "modm/src/modm/board"
env.substitutions = {
"with_logger": True,
- "with_assert": env.has_module(":architecture:assert")
+ "with_assert": env.has_module(":architecture:assert"),
+ "has_gpio_c14_c15": False
}
env.template("../board.cpp.in", "board.cpp")
env.copy('.')
- env.copy("../nucleo32_arduino.hpp", "nucleo32_arduino.hpp")
+ env.template("../nucleo32_arduino.hpp.in", "nucleo32_arduino.hpp")
env.collect(":build:openocd.source", "board/st_nucleo_f3.cfg");
diff --git a/src/modm/board/nucleo_l031k6/board.hpp b/src/modm/board/nucleo_l031k6/board.hpp
new file mode 100644
index 0000000000..66fdf9733f
--- /dev/null
+++ b/src/modm/board/nucleo_l031k6/board.hpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016-2018, Niklas Hauser
+ * Copyright (c) 2017, Nick Sarten
+ * Copyright (c) 2017, Sascha Schade
+ * Copyright (c) 2021, Christopher Durand
+ *
+ * This file is part of the modm project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef MODM_STM32_NUCLEO_L031K6_HPP
+#define MODM_STM32_NUCLEO_L031K6_HPP
+
+#include
+#include
+#include
+/// @ingroup modm_board_nucleo_l031k6
+#define MODM_BOARD_HAS_LOGGER
+
+using namespace modm::platform;
+
+/// @ingroup modm_board_nucleo_l031k6
+namespace Board
+{
+using namespace modm::literals;
+
+/// STM32L031K6 running at 32MHz generated from 16 MHz HSI16 clock
+struct SystemClock
+{
+ static constexpr uint32_t Frequency = 32_MHz;
+ static constexpr uint32_t Ahb = Frequency;
+ static constexpr uint32_t Apb1 = Frequency;
+ static constexpr uint32_t Apb2 = Frequency;
+
+ static constexpr uint32_t Apb1Timer = Apb1;
+ static constexpr uint32_t Apb2Timer = Apb2;
+
+ static constexpr uint32_t Adc = Apb2;
+
+ static constexpr uint32_t Comp1 = Apb2;
+ static constexpr uint32_t Comp2 = Apb2;
+
+ static constexpr uint32_t I2c1 = Apb1;
+
+ static constexpr uint32_t Spi1 = Apb2;
+
+ static constexpr uint32_t Timer2 = Apb1Timer;
+ static constexpr uint32_t Timer21 = Apb2Timer;
+ static constexpr uint32_t Timer22 = Apb2Timer;
+
+ static constexpr uint32_t Usart2 = Apb1;
+
+ static bool inline
+ enable()
+ {
+ Rcc::enableInternalClock(); // 16MHz
+ // (internal clock / 1) * 4 / 2 = 32MHz
+ const Rcc::PllFactors pllFactors{
+ .pllMul = Rcc::PllMultiplier::Mul4,
+ .pllDiv = 2,
+ .enableHsiPrediv4 = false
+ };
+ Rcc::enablePll(Rcc::PllSource::Hsi16, pllFactors);
+ // set flash latency for 32MHz
+ Rcc::setFlashLatency();
+ // switch system clock to PLL output
+ Rcc::enableSystemClock(Rcc::SystemClockSource::Pll);
+ Rcc::setAhbPrescaler(Rcc::AhbPrescaler::Div1);
+ Rcc::setApb1Prescaler(Rcc::Apb1Prescaler::Div1);
+ Rcc::setApb2Prescaler(Rcc::Apb2Prescaler::Div1);
+ // update frequencies for busy-wait delay functions
+ Rcc::updateCoreFrequency();
+
+ return true;
+ }
+};
+
+// Arduino Nano Footprint
+#include "nucleo32_arduino.hpp"
+
+using Button = GpioUnused;
+using LedD13 = D13;
+
+using Leds = SoftwareGpioPort< LedD13 >;
+
+
+namespace stlink
+{
+using Rx = GpioInputA15;
+using Tx = GpioOutputA2;
+using Uart = Usart2;
+}
+
+using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockIfFull >;
+
+
+inline void
+initialize()
+{
+ SystemClock::enable();
+ SysTickTimer::initialize();
+
+ stlink::Uart::connect();
+ stlink::Uart::initialize();
+}
+
+}
+
+#endif // MODM_STM32_NUCLEO_L031K6_HPP
diff --git a/src/modm/board/nucleo_l031k6/board.xml b/src/modm/board/nucleo_l031k6/board.xml
new file mode 100644
index 0000000000..0c912ff18a
--- /dev/null
+++ b/src/modm/board/nucleo_l031k6/board.xml
@@ -0,0 +1,17 @@
+
+
+
+ ../../../../repo.lb
+
+
+
+
+
+
+
+
+
+
+ modm:board:nucleo-l031k6
+
+
diff --git a/src/modm/board/nucleo_l031k6/module.lb b/src/modm/board/nucleo_l031k6/module.lb
new file mode 100644
index 0000000000..e35f967e10
--- /dev/null
+++ b/src/modm/board/nucleo_l031k6/module.lb
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2016-2018, Niklas Hauser
+# Copyright (c) 2017, Fabian Greif
+# Copyright (c) 2021, Christopher Durand
+#
+# This file is part of the modm project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+# -----------------------------------------------------------------------------
+
+def init(module):
+ module.name = ":board:nucleo-l031k6"
+ module.description = """\
+# NUCLEO-L031K6
+
+[Nucleo kit for STM32L031K6](https://www.st.com/en/evaluation-tools/nucleo-l031k6.html)
+"""
+
+def prepare(module, options):
+ if not options[":target"].partname.startswith("stm32l031k6t"):
+ return False
+
+ module.depends(":platform:core", ":platform:gpio", ":platform:clock", ":platform:uart:2",
+ ":debug", ":architecture:clock", ":architecture:clock")
+ return True
+
+def build(env):
+ env.outbasepath = "modm/src/modm/board"
+ env.substitutions = {
+ "with_logger": True,
+ "with_assert": env.has_module(":architecture:assert"),
+ "has_gpio_c14_c15": True
+ }
+ env.template("../board.cpp.in", "board.cpp")
+ env.copy('.')
+ env.template("../nucleo32_arduino.hpp.in", "nucleo32_arduino.hpp")
+
+ env.outbasepath = "modm/openocd/modm/board/"
+ env.copy(repopath("tools/openocd/modm/st_nucleo_l0.cfg"), "st_nucleo_l0.cfg")
+ env.collect(":build:openocd.source", "modm/board/st_nucleo_l0.cfg");
diff --git a/src/modm/platform/clock/stm32/rcc.cpp.in b/src/modm/platform/clock/stm32/rcc.cpp.in
index b91b83b6cd..137c013398 100644
--- a/src/modm/platform/clock/stm32/rcc.cpp.in
+++ b/src/modm/platform/clock/stm32/rcc.cpp.in
@@ -62,12 +62,12 @@ modm::platform::Rcc::enableInternalClock(uint32_t waitCycles)
return retval;
}
-%% if target["family"] in ["l1", "l4"]
+%% if target["family"] in ["l0", "l1", "l4"]
bool
modm::platform::Rcc::enableMultiSpeedInternalClock(MsiFrequency msi_frequency, uint32_t waitCycles)
{
bool retval;
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
RCC->ICSCR = (RCC->ICSCR & ~RCC_ICSCR_MSIRANGE) | static_cast(msi_frequency);
RCC->CR |= RCC_CR_MSION;
while (not (retval = (RCC->CR & RCC_CR_MSIRDY)) and --waitCycles)
@@ -114,7 +114,7 @@ bool
modm::platform::Rcc::enableLowSpeedExternalClock(uint32_t waitCycles)
{
bool retval;
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
RCC->CSR |= RCC_CSR_LSEBYP | RCC_CSR_LSEON;
while (not (retval = (RCC->CSR & RCC_CSR_LSERDY)) and --waitCycles)
%% else
@@ -129,7 +129,7 @@ bool
modm::platform::Rcc::enableLowSpeedExternalCrystal(uint32_t waitCycles)
{
bool retval;
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
RCC->CSR = (RCC->CSR & ~RCC_CSR_LSEBYP) | RCC_CSR_LSEON;
while (not (retval = (RCC->CSR & RCC_CSR_LSERDY)) and --waitCycles)
%% else
@@ -224,7 +224,10 @@ modm::platform::Rcc::enablePll(PllSource source, const PllFactors& pllFactors, u
return tmp;
-%% elif target["family"] in ["l1"]
+%% elif target["family"] in ["l0", "l1"]
+%% if target["family"] == "l0"
+ setHsiPredivider4Enabled(pllFactors.enableHsiPrediv4);
+%% endif
uint32_t tmp = RCC->CFGR & ~(RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC | RCC_CFGR_PLLDIV);
// PLLSRC source for pll
@@ -349,6 +352,21 @@ modm::platform::Rcc::enableOverdriveMode(uint32_t waitCycles)
}
%% endif
+%% if target["family"] == "l0"
+bool
+modm::platform::Rcc::setHsiPredivider4Enabled(bool divideBy4, uint32_t waitCycles)
+{
+ const uint32_t enableFlag = divideBy4 ? RCC_CR_HSIDIVEN : 0;
+ RCC->CR = (RCC->CR & ~RCC_CR_HSIDIVEN) | enableFlag;
+
+ while (isHsiPredivider4Active() != divideBy4) {
+ if (waitCycles-- == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+%% endif
// ----------------------------------------------------------------------------
bool
diff --git a/src/modm/platform/clock/stm32/rcc.hpp.in b/src/modm/platform/clock/stm32/rcc.hpp.in
index b30549e076..6783758208 100644
--- a/src/modm/platform/clock/stm32/rcc.hpp.in
+++ b/src/modm/platform/clock/stm32/rcc.hpp.in
@@ -65,6 +65,13 @@ public:
InternalClock = Hsi,
/// High speed external clock (see HseConfig)
Hse = RCC_CFGR_PLLSRC,
+%% elif target["family"] == "l0"
+ /// High speed internal clock (16 MHz)
+ Hsi = 0,
+ Hsi16 = Hsi,
+ InternalClock = Hsi16,
+ /// High speed external clock
+ Hse = RCC_CFGR_PLLSRC,
%% endif
%% if hsi48
/// High speed internal clock (48 MHz)
@@ -79,7 +86,7 @@ public:
ExternalCrystal = Hse,
};
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
enum class
PllMultiplier : uint32_t
{
@@ -99,12 +106,15 @@ public:
SystemClockSource : uint32_t
{
Hsi = RCC_CFGR_SW_HSI,
+%% if target["family"] == "l0"
+ Hsi16 = Hsi,
+%% endif
Hse = RCC_CFGR_SW_HSE,
%% if hsi48
Hsi48 = RCC_CFGR_SW_HSI48,
InternalClockMHz48 = Hsi48,
%% endif
-%% if target["family"] in ["l4"]
+%% if target["family"] in ["l0", "l4"]
Msi = RCC_CFGR_SW_MSI,
MultiSpeedInternalClock = Msi,
%% endif
@@ -118,7 +128,7 @@ public:
enum class
RealTimeClockSource : uint32_t
{
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
Lsi = RCC_CSR_RTCSEL_1,
Lse = RCC_CSR_RTCSEL_0,
Hse = RCC_CSR_RTCSEL_0 | RCC_CSR_RTCSEL_1,
@@ -227,7 +237,7 @@ public:
Pll = RCC_CFGR_MCO2_1 | RCC_CFGR_MCO2_0,
};
%% endif
-%% elif target["family"] in ["l1", "l4", "g0", "g4"]
+%% elif target["family"] in ["l0", "l1", "l4", "g0", "g4"]
enum class
ClockOutputSource : uint32_t
{
@@ -236,7 +246,7 @@ public:
%% if target["family"] in ["l4"]
MultiSpeedInternalClock = (2 << RCC_CFGR_MCOSEL_Pos), // MSI
%% endif
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
InternalClock = (2 << RCC_CFGR_MCOSEL_Pos), // HSI16
MultiSpeedInternalClock = (3 << RCC_CFGR_MCOSEL_Pos), // MSI
%% else
@@ -265,7 +275,7 @@ public:
%% if target["family"] == "f1"
Pll = RCC_CFGR_MCO_PLLCLK_DIV2, ///< divided by 2
%% else
- Pll = RCC_CFGR_MCO_PLL, ///< divided by 2
+ Pll = RCC_CFGR_MCO_PLL,
%% endif
};
%% endif
@@ -284,11 +294,11 @@ public:
enableInternalClockMHz48(uint32_t waitCycles = 2048);
%% endif
-%% if target["family"] in ["l1", "l4"]
+%% if target["family"] in ["l0", "l1", "l4"]
enum class
MsiFrequency : uint32_t
{
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
kHz65 = RCC_ICSCR_MSIRANGE_0,
kHz131 = RCC_ICSCR_MSIRANGE_1,
kHz262 = RCC_ICSCR_MSIRANGE_2,
@@ -389,9 +399,12 @@ public:
const uint8_t pllP;
%% endif
const uint8_t pllQ = 0xff;
-%% elif target["family"] in ["l1"]
+%% elif target["family"] in ["l0", "l1"]
const PllMultiplier pllMul;
const uint8_t pllDiv;
+ %% if target["family"] == "l0"
+ const bool enableHsiPrediv4 = false;
+ %% endif
%% else
const uint8_t pllMul;
%% if pllprediv2
@@ -512,7 +525,7 @@ public:
};
return enablePll(source, pllFactors, waitCycles);
}
-%% else
+%% elif target["family"] in ["f0", "f1", "f3"]
[[deprecated("Use PllFactors as argument instead")]] static bool
enablePll(PllSource source,
uint8_t pllMul,
@@ -535,6 +548,16 @@ public:
return enablePll(source, pllFactors, waitCycles);
}
%% endif
+%% if target["family"] == "l0"
+ static inline bool
+ isHsiPredivider4Active()
+ {
+ return (RCC->CR & RCC_CR_HSIDIVF);
+ }
+
+ static bool
+ setHsiPredivider4Enabled(bool divideBy4, uint32_t waitCycles = 2048);
+%% endif
// sinks
static bool
@@ -543,7 +566,7 @@ public:
static inline bool
enableRealTimeClock(RealTimeClockSource src)
{
-%% if target["family"] in ["l1"]
+%% if target["family"] in ["l0", "l1"]
RCC->CSR = (RCC->CSR & ~RCC_CSR_RTCSEL) | RCC_CSR_RTCEN | uint32_t(src);
%% else
RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | RCC_BDCR_RTCEN | uint32_t(src);
@@ -587,7 +610,7 @@ public:
return true;
}
%% endif
-%% elif target["family"] in ["l1", "l4", "g0", "g4"]
+%% elif target["family"] in ["l0", "l1", "l4", "g0", "g4"]
enum class
ClockOutputPrescaler : uint32_t
{
diff --git a/src/modm/platform/clock/stm32/rcc_impl.hpp.in b/src/modm/platform/clock/stm32/rcc_impl.hpp.in
index 33eded4a0f..8460926573 100644
--- a/src/modm/platform/clock/stm32/rcc_impl.hpp.in
+++ b/src/modm/platform/clock/stm32/rcc_impl.hpp.in
@@ -80,6 +80,9 @@ Rcc::setFlashLatency()
FLASH->ACR |= FLASH_ACR_ACC64;
// enable flash prefetch
acr |= FLASH_ACR_PRFTEN;
+%% elif target["family"] == "l0"
+ // enable flash prefetch and pre-read
+ acr |= FLASH_ACR_PRFTEN | FLASH_ACR_PRE_READ;
%% else
// enable flash prefetch
acr |= FLASH_ACR_PRFTBE;
diff --git a/src/modm/platform/gpio/stm32/enable.cpp.in b/src/modm/platform/gpio/stm32/enable.cpp.in
index afe4255984..47297cc3c9 100644
--- a/src/modm/platform/gpio/stm32/enable.cpp.in
+++ b/src/modm/platform/gpio/stm32/enable.cpp.in
@@ -26,7 +26,7 @@ modm_gpio_enable(void)
%% set prefix = "IOP"
%% elif target["family"] in ["l4", "g4"]
%% set clock_tree = 'AHB2'
-%% elif target["family"] in ["g0"]
+%% elif target["family"] in ["g0", "l0"]
%% set clock_tree = 'IOP'
%% endif
diff --git a/src/modm/platform/timer/stm32/general_purpose.hpp.in b/src/modm/platform/timer/stm32/general_purpose.hpp.in
index af8be38f56..2bdef2faed 100644
--- a/src/modm/platform/timer/stm32/general_purpose.hpp.in
+++ b/src/modm/platform/timer/stm32/general_purpose.hpp.in
@@ -227,7 +227,7 @@ public:
}
-%% if target.family not in ["l1"]
+%% if target.family not in ["l0", "l1"]
static inline void
enableOutput()
{
diff --git a/src/modm/platform/timer/stm32/general_purpose_base.hpp.in b/src/modm/platform/timer/stm32/general_purpose_base.hpp.in
index e65e2edf46..7b9b84f249 100644
--- a/src/modm/platform/timer/stm32/general_purpose_base.hpp.in
+++ b/src/modm/platform/timer/stm32/general_purpose_base.hpp.in
@@ -33,8 +33,10 @@ public:
CaptureCompare2 = TIM_DIER_CC2DE,
CaptureCompare3 = TIM_DIER_CC3DE,
CaptureCompare4 = TIM_DIER_CC4DE,
-%% if target.family not in ["l1"]
+%% if target.family not in ["l0", "l1"]
COM = TIM_DIER_COMDE,
+%% endif
+%% if target.family not in ["l1"]
Trigger = TIM_DIER_TDE,
%% endif
};
@@ -47,7 +49,7 @@ public:
CaptureCompare3 = TIM_DIER_CC3IE,
CaptureCompare4= TIM_DIER_CC4IE,
Trigger = TIM_DIER_TIE,
-%% if target.family not in ["l1"]
+%% if target.family not in ["l0", "l1"]
COM = TIM_DIER_COMIE,
Break = TIM_DIER_BIE,
%% endif
@@ -66,7 +68,7 @@ public:
Overcapture2 = TIM_SR_CC2OF,
Overcapture3 = TIM_SR_CC3OF,
Overcapture4 = TIM_SR_CC4OF,
-%% if target.family not in ["l1"]
+%% if target.family not in ["l0", "l1"]
COM = TIM_SR_COMIF,
Break = TIM_SR_BIF,
%% endif
@@ -189,7 +191,7 @@ public:
Enable = 1,
};
-%% if target.family not in ["l1"]
+%% if target.family not in ["l0", "l1"]
/* Different Resolution Depending on DeadTime[7:5]: */
enum class DeadTimeResolution : uint32_t
{
@@ -201,7 +203,7 @@ public:
};
%% endif
-%% if target.family not in ["l1"]
+%% if target.family not in ["l0", "l1"]
enum class OffStateForRunMode : uint32_t
{
Disable = 0,
diff --git a/test/all/ignored.txt b/test/all/ignored.txt
index 7a0b65ef99..0b65650873 100644
--- a/test/all/ignored.txt
+++ b/test/all/ignored.txt
@@ -103,3 +103,81 @@ samd21e15c-uf
samd21e15c-uu
samd21e16c-uf
samd21e16c-uu
+# FIXME: Shared IRQs on UART, SPI, I2C
+stm32g0b0cet6
+stm32g0b0ket6
+stm32g0b0ret6
+stm32g0b0vet6
+stm32g0b1cbt6
+stm32g0b1cbt6n
+stm32g0b1cbu6
+stm32g0b1cbu6n
+stm32g0b1cct6
+stm32g0b1cct6n
+stm32g0b1ccu6
+stm32g0b1ccu6n
+stm32g0b1cet6
+stm32g0b1cet6n
+stm32g0b1ceu6
+stm32g0b1ceu6n
+stm32g0b1kbt6
+stm32g0b1kbt6n
+stm32g0b1kbu6
+stm32g0b1kbu6n
+stm32g0b1kct6
+stm32g0b1kct6n
+stm32g0b1kcu6
+stm32g0b1kcu6n
+stm32g0b1ket6
+stm32g0b1ket6n
+stm32g0b1keu6
+stm32g0b1keu6n
+stm32g0b1mbt6
+stm32g0b1mct6
+stm32g0b1met6
+stm32g0b1ney6
+stm32g0b1rbi6n
+stm32g0b1rbt6
+stm32g0b1rbt6n
+stm32g0b1rci6n
+stm32g0b1rct6
+stm32g0b1rct6n
+stm32g0b1rei6n
+stm32g0b1ret6
+stm32g0b1ret6n
+stm32g0b1vbi6
+stm32g0b1vbt6
+stm32g0b1vci6
+stm32g0b1vct6
+stm32g0b1vei6
+stm32g0b1vet6
+stm32g0c1cct6
+stm32g0c1cct6n
+stm32g0c1ccu6
+stm32g0c1ccu6n
+stm32g0c1cet6
+stm32g0c1cet6n
+stm32g0c1ceu6
+stm32g0c1ceu6n
+stm32g0c1kct6
+stm32g0c1kct6n
+stm32g0c1kcu6
+stm32g0c1kcu6n
+stm32g0c1ket6
+stm32g0c1ket6n
+stm32g0c1keu6
+stm32g0c1keu6n
+stm32g0c1mct6
+stm32g0c1met6
+stm32g0c1ney6
+stm32g0c1rci6n
+stm32g0c1rct6
+stm32g0c1rct6n
+stm32g0c1rei6n
+stm32g0c1ret6
+stm32g0c1ret6n
+stm32g0c1vci6
+stm32g0c1vct6
+stm32g0c1vei6
+stm32g0c1vet6
+
diff --git a/tools/openocd/modm/st_nucleo_l0.cfg b/tools/openocd/modm/st_nucleo_l0.cfg
new file mode 100644
index 0000000000..e3ec2e91da
--- /dev/null
+++ b/tools/openocd/modm/st_nucleo_l0.cfg
@@ -0,0 +1,11 @@
+# Should work with all STM32L0 Nucleo Dev Boards.
+# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html
+
+source [find interface/stlink.cfg]
+
+transport select hla_swd
+
+source [find target/stm32l0.cfg]
+
+# use hardware reset
+reset_config srst_only srst_nogate