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]. - + @@ -108,6 +108,7 @@ Please [discover modm's peripheral drivers for your specific device][discover]. + @@ -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]. + @@ -226,6 +233,7 @@ Please [discover modm's peripheral drivers for your specific device][discover]. + @@ -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]. + @@ -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]. + @@ -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. - + + - + - +
STM32STM32 SAM AT
F7 G0 G4L0 L1 L4 D21
External Interrupt
External Memory
I2C
Unique ID NUCLEO-G431KB NUCLEO-G431RB NUCLEO-G474RENUCLEO-L152RENUCLEO-L031K6
NUCLEO-L152RE NUCLEO-L432KC NUCLEO-L452RE NUCLEO-L476RGOLIMEXINO-STM32
OLIMEXINO-STM32 Raspberry Pi SAMD21-MINI STM32-F4VESTM32F030-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