diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 9de02e20ef..c6da2de592 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -153,7 +153,7 @@ jobs:
- name: Examples STM32G0 Series
if: always()
run: |
- (cd examples && ../tools/scripts/examples_compile.py nucleo_g071rb)
+ (cd examples && ../tools/scripts/examples_compile.py nucleo_g070rb nucleo_g071rb)
- name: Examples STM32L0 Series
if: always()
run: |
diff --git a/README.md b/README.md
index 5147d6d0c9..3d6b9e4338 100644
--- a/README.md
+++ b/README.md
@@ -657,40 +657,41 @@ We have out-of-box support for many development boards including documentation.
NUCLEO-F746ZG |
| NUCLEO-F767ZI |
+NUCLEO-G070RB |
NUCLEO-G071RB |
NUCLEO-G431KB |
-NUCLEO-G431RB |
+| NUCLEO-G431RB |
NUCLEO-G474RE |
NUCLEO-H723ZG |
NUCLEO-H743ZI |
-NUCLEO-L031K6 |
+| NUCLEO-L031K6 |
NUCLEO-L053R8 |
NUCLEO-L152RE |
NUCLEO-L432KC |
-NUCLEO-L452RE |
+| NUCLEO-L452RE |
NUCLEO-L476RG |
NUCLEO-L496ZG-P |
NUCLEO-L552ZE-Q |
-NUCLEO-U575ZI-Q |
+| NUCLEO-U575ZI-Q |
OLIMEXINO-STM32 |
Raspberry Pi Pico |
SAMD21-MINI |
-SAMD21-XPLAINED-PRO |
+| SAMD21-XPLAINED-PRO |
SAME54-XPLAINED-PRO |
SAME70-XPLAINED |
SAMG55-XPLAINED-PRO |
-SAMV71-XPLAINED-ULTRA |
+| SAMV71-XPLAINED-ULTRA |
Smart Response XE |
STM32-F4VE |
STM32F030-DEMO |
-THINGPLUS-RP2040 |
+| THINGPLUS-RP2040 |
diff --git a/examples/nucleo_g070rb/blink/main.cpp b/examples/nucleo_g070rb/blink/main.cpp
new file mode 100644
index 0000000000..a6f817cc72
--- /dev/null
+++ b/examples/nucleo_g070rb/blink/main.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019, Niklas Hauser
+ *
+ * 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
+#include
+
+using namespace Board;
+
+// ----------------------------------------------------------------------------
+int
+main()
+{
+ Board::initialize();
+ LedD13::setOutput(modm::Gpio::Low);
+
+ // 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};
+ modm::PeriodicTimer timer{500ms};
+
+ while (true)
+ {
+ if (timer.execute())
+ {
+ LedD13::toggle();
+
+ MODM_LOG_INFO << "loop: " << counter++ << modm::endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/examples/nucleo_g070rb/blink/project.xml b/examples/nucleo_g070rb/blink/project.xml
new file mode 100644
index 0000000000..001c5a5fc0
--- /dev/null
+++ b/examples/nucleo_g070rb/blink/project.xml
@@ -0,0 +1,11 @@
+
+ modm:nucleo-g070rb
+
+
+
+
+ modm:platform:gpio
+ modm:processing:timer
+ modm:build:scons
+
+
diff --git a/src/modm/board/nucleo_g070rb/board.hpp b/src/modm/board/nucleo_g070rb/board.hpp
new file mode 100644
index 0000000000..91957c0e92
--- /dev/null
+++ b/src/modm/board/nucleo_g070rb/board.hpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2019, Niklas Hauser
+ * Copyright (c) 2023, 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_G070RB_HPP
+#define MODM_STM32_NUCLEO_G070RB_HPP
+
+#include
+#include
+#include
+/// @ingroup modm_board_nucleo_g070rb
+#define MODM_BOARD_HAS_LOGGER
+
+using namespace modm::platform;
+
+namespace Board
+{
+/// @ingroup modm_board_nucleo_g070rb
+/// @{
+using namespace modm::literals;
+
+/// STM32G070RB running at 64MHz generated from the internal 16MHz oscillator
+struct SystemClock
+{
+ static constexpr uint32_t Frequency = 64_MHz;
+ static constexpr uint32_t Ahb = Frequency;
+ static constexpr uint32_t Apb = Frequency;
+
+ static constexpr uint32_t Rng = Ahb;
+ static constexpr uint32_t Crc = Ahb;
+ static constexpr uint32_t Flash = Ahb;
+ static constexpr uint32_t Exti = Ahb;
+ static constexpr uint32_t Rcc = Ahb;
+ static constexpr uint32_t Dmamux = Ahb;
+ static constexpr uint32_t Dma = Ahb;
+
+ static constexpr uint32_t Dbg = Apb;
+ static constexpr uint32_t Timer17 = Apb;
+ static constexpr uint32_t Timer16 = Apb;
+ static constexpr uint32_t Timer15 = Apb;
+ static constexpr uint32_t Usart1 = Apb;
+ static constexpr uint32_t Spi1 = Apb;
+ static constexpr uint32_t I2s1 = Apb;
+ static constexpr uint32_t Timer1 = Apb;
+ static constexpr uint32_t Adc1 = Apb;
+ static constexpr uint32_t ItLine = Apb;
+ static constexpr uint32_t SysCfg = Apb;
+ static constexpr uint32_t Tamp = Apb;
+ static constexpr uint32_t Bkp = Apb;
+ static constexpr uint32_t Ucpd2 = Apb;
+ static constexpr uint32_t Ucpd1 = Apb;
+ static constexpr uint32_t Dac = Apb;
+ static constexpr uint32_t Pwr = Apb;
+ static constexpr uint32_t I2c2 = Apb;
+ static constexpr uint32_t I2c1 = Apb;
+ static constexpr uint32_t Usart4 = Apb;
+ static constexpr uint32_t Usart3 = Apb;
+ static constexpr uint32_t Usart2 = Apb;
+ static constexpr uint32_t Spi2 = Apb;
+ static constexpr uint32_t Iwdg = Apb;
+ static constexpr uint32_t Wwdg = Apb;
+ static constexpr uint32_t Rtc = Apb;
+ static constexpr uint32_t Timer14 = Apb;
+ static constexpr uint32_t Timer7 = Apb;
+ static constexpr uint32_t Timer6 = Apb;
+ static constexpr uint32_t Timer3 = Apb;
+
+ static bool inline
+ enable()
+ {
+ Rcc::enableInternalClock(); // 16MHz
+ // (internal clock / 1_M) * 8_N / 2_R = 128MHz / 2 = 64MHz
+ const Rcc::PllFactors pllFactors{
+ .pllM = 1,
+ .pllN = 8,
+ .pllR = 2,
+ };
+ Rcc::enablePll(Rcc::PllSource::InternalClock, pllFactors);
+ Rcc::setFlashLatency();
+ // switch system clock to PLL output
+ Rcc::enableSystemClock(Rcc::SystemClockSource::Pll);
+ Rcc::setAhbPrescaler(Rcc::AhbPrescaler::Div1);
+ Rcc::setApbPrescaler(Rcc::ApbPrescaler::Div1);
+ // update frequencies for busy-wait delay functions
+ Rcc::updateCoreFrequency();
+
+ return true;
+ }
+};
+
+// Arduino Footprint
+using A0 = GpioA0;
+using A1 = GpioA1;
+using A2 = GpioA4;
+using A3 = GpioB1;
+using A4 = GpioB11;
+using A5 = GpioB12;
+
+using D0 = GpioC5;
+using D1 = GpioC4;
+using D2 = GpioA10;
+using D3 = GpioB3;
+using D4 = GpioB5;
+using D5 = GpioB4;
+using D6 = GpioB14;
+using D7 = GpioA8;
+using D8 = GpioA9;
+using D9 = GpioC7;
+using D10 = GpioB0;
+using D11 = GpioA7;
+using D12 = GpioA6;
+using D13 = GpioA5;
+using D14 = GpioB9;
+using D15 = GpioB8;
+
+using Button = GpioInverted;
+using LedD13 = D13;
+
+using Leds = SoftwareGpioPort< LedD13 >;
+/// @}
+
+namespace stlink
+{
+/// @ingroup modm_board_nucleo_g070rb
+/// @{
+using Rx = GpioInputA3;
+using Tx = GpioOutputA2;
+using Uart = Usart2;
+/// @}
+}
+
+/// @ingroup modm_board_nucleo_g070rb
+/// @{
+using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockIfFull >;
+
+inline void
+initialize()
+{
+ SystemClock::enable();
+ SysTickTimer::initialize();
+
+ stlink::Uart::connect();
+ stlink::Uart::initialize();
+
+ Button::setInput();
+}
+/// @}
+
+}
+
+#endif // MODM_STM32_NUCLEO_G070RB_HPP
diff --git a/src/modm/board/nucleo_g070rb/board.xml b/src/modm/board/nucleo_g070rb/board.xml
new file mode 100644
index 0000000000..2aa603ab34
--- /dev/null
+++ b/src/modm/board/nucleo_g070rb/board.xml
@@ -0,0 +1,15 @@
+
+
+
+ ../../../../repo.lb
+
+
+
+
+
+
+
+
+ modm:board:nucleo-g070rb
+
+
diff --git a/src/modm/board/nucleo_g070rb/module.lb b/src/modm/board/nucleo_g070rb/module.lb
new file mode 100644
index 0000000000..148f459ada
--- /dev/null
+++ b/src/modm/board/nucleo_g070rb/module.lb
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2019, Niklas Hauser
+# Copyright (c) 2023, 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-g070rb"
+ module.description = """\
+# NUCLEO-G070RB
+
+[Nucleo kit for STM32G070RB](https://www.st.com/en/evaluation-tools/nucleo-g070rb.html)
+"""
+
+def prepare(module, options):
+ if not options[":target"].partname.startswith("stm32g070rbt"):
+ return False
+
+ module.depends(":platform:core", ":platform:gpio", ":platform:clock", ":platform:uart:2",
+ ":debug", ":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")
+ }
+ env.template("../board.cpp.in", "board.cpp")
+ env.copy('.')
+
+ env.outbasepath = "modm/openocd/modm/board/"
+ env.copy(repopath("tools/openocd/modm/st_nucleo_g0.cfg"), "st_nucleo_g0.cfg")
+ env.collect(":build:openocd.source", "modm/board/st_nucleo_g0.cfg")