From 021fa618989f5eb48f76b2bdc3cd28e2b626ff89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Ebeling?= Date: Sun, 22 Sep 2024 14:07:05 +0200 Subject: [PATCH] WIP Add custom STM32C031 board examples --- .github/workflows/linux.yml | 4 + examples/stm32c0x/adc-sequence/main.cpp | 81 ++++++++++++++++ examples/stm32c0x/adc-sequence/project.xml | 27 ++++++ examples/stm32c0x/adc-simple/main.cpp | 57 +++++++++++ examples/stm32c0x/adc-simple/project.xml | 27 ++++++ examples/stm32c0x/blink-clock/main.cpp | 36 +++++++ examples/stm32c0x/blink-clock/project.xml | 21 ++++ examples/stm32c0x/blink-delay/main.cpp | 28 ++++++ examples/stm32c0x/blink-delay/project.xml | 21 ++++ examples/stm32c0x/blink-timer/main.cpp | 73 ++++++++++++++ examples/stm32c0x/blink-timer/project.xml | 23 +++++ examples/stm32c0x/custom-board.hpp | 108 +++++++++++++++++++++ 12 files changed, 506 insertions(+) create mode 100644 examples/stm32c0x/adc-sequence/main.cpp create mode 100644 examples/stm32c0x/adc-sequence/project.xml create mode 100644 examples/stm32c0x/adc-simple/main.cpp create mode 100644 examples/stm32c0x/adc-simple/project.xml create mode 100644 examples/stm32c0x/blink-clock/main.cpp create mode 100644 examples/stm32c0x/blink-clock/project.xml create mode 100644 examples/stm32c0x/blink-delay/main.cpp create mode 100644 examples/stm32c0x/blink-delay/project.xml create mode 100644 examples/stm32c0x/blink-timer/main.cpp create mode 100644 examples/stm32c0x/blink-timer/project.xml create mode 100644 examples/stm32c0x/custom-board.hpp diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1d0d4cdca6..b46e164b5a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -187,6 +187,10 @@ jobs: if: always() run: | (cd examples && ../tools/scripts/examples_compile.py nucleo_h743zi nucleo_h723zg stm32h750vbt6_devebox) + - name: Examples STM32C0 Series + if: always() + run: | + (cd examples && ../tools/scripts/examples_compile.py stm32c0x) stm32f4-examples-1: runs-on: ubuntu-22.04 diff --git a/examples/stm32c0x/adc-sequence/main.cpp b/examples/stm32c0x/adc-sequence/main.cpp new file mode 100644 index 0000000000..b85cea3df1 --- /dev/null +++ b/examples/stm32c0x/adc-sequence/main.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024, Jörg Ebeling + * + * 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 "../custom-board.hpp" + +using namespace Board; +using namespace std::chrono_literals; + +#undef MODM_LOG_LEVEL +#define MODM_LOG_LEVEL modm::log::DEBUG + +// Create an IODeviceWrapper around the Uart Peripheral we want to use +modm::IODeviceWrapper loggerDevice; +// Set all four logger streams to use the UART +modm::log::Logger modm::log::debug(loggerDevice); +modm::log::Logger modm::log::info(loggerDevice); +modm::log::Logger modm::log::warning(loggerDevice); +modm::log::Logger modm::log::error(loggerDevice); + +std::array adc_data_buf = {}; + +static void +adc_handler() +{ + static uint8_t adc_data_idx = 0; + + if (Adc1::getInterruptFlags() & Adc1::InterruptFlag::EndOfConversion) + { + Adc1::acknowledgeInterruptFlags(Adc1::InterruptFlag::EndOfConversion); + adc_data_buf.at(adc_data_idx) = Adc1::getValue(); + adc_data_idx++; + } + if (Adc1::getInterruptFlags() & Adc1::InterruptFlag::EndOfSequence) + { + Adc1::acknowledgeInterruptFlags(Adc1::InterruptFlag::EndOfSequence); + adc_data_idx = 0; + } +} + +// ---------------------------------------------------------------------------- +int +main() +{ + Board::initialize(); + MODM_LOG_INFO << "Board initialized" << modm::endl << modm::flush; + + Adc1::connect(); + Adc1::initialize(); // 24MHz/160.5 sample time=6.6us (fulfill Ts_temp of 5us) + Adc1::setResolution(Adc1::Resolution::Bits12); + Adc1::setRightAdjustResult(); + Adc1::setSampleTime(Adc1::SampleTime::Cycles160_5); + + const Adc1::Channel sequence[4] = {Adc1::Channel::InternalReference, Adc1::Channel::In2, + Adc1::Channel::In1, Adc1::Channel::Temperature}; + Adc1::setChannels(sequence); + + Adc1::enableInterruptVector(15); + Adc1::enableInterrupt(Adc1::Interrupt::EndOfConversion | Adc1::Interrupt::EndOfSequence); + AdcInterrupt1::attachInterruptHandler(adc_handler); + Adc1::enableFreeRunningMode(); + Adc1::startConversion(); + + while (true) + { + LedGn::toggle(); + modm::delay(500ms); + + MODM_LOG_INFO << "ADC data "; + for (size_t i = 0; auto value : adc_data_buf) { MODM_LOG_INFO << i << "=" << value << " "; } + MODM_LOG_INFO << modm::endl << modm::flush; + } + return 0; +} diff --git a/examples/stm32c0x/adc-sequence/project.xml b/examples/stm32c0x/adc-sequence/project.xml new file mode 100644 index 0000000000..f423cf8c41 --- /dev/null +++ b/examples/stm32c0x/adc-sequence/project.xml @@ -0,0 +1,27 @@ + + + + ../../../repo.lb + + + + + + + + + interface/stlink.cfg + target/stm32c0x.cfg + + + modm:architecture:clock + modm:build:scons + modm:debug + modm:platform:clock + modm:platform:core + modm:platform:gpio + modm:platform:adc + modm:platform:uart:1 + modm:platform:uart:2 + + diff --git a/examples/stm32c0x/adc-simple/main.cpp b/examples/stm32c0x/adc-simple/main.cpp new file mode 100644 index 0000000000..f95a672892 --- /dev/null +++ b/examples/stm32c0x/adc-simple/main.cpp @@ -0,0 +1,57 @@ +/* + * 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 "../custom-board.hpp" + +using namespace Board; +using namespace std::chrono_literals; + +#undef MODM_LOG_LEVEL +#define MODM_LOG_LEVEL modm::log::DEBUG + +// Create an IODeviceWrapper around the Uart Peripheral we want to use +modm::IODeviceWrapper loggerDevice; +// Set all four logger streams to use the UART +modm::log::Logger modm::log::debug(loggerDevice); +modm::log::Logger modm::log::info(loggerDevice); +modm::log::Logger modm::log::warning(loggerDevice); +modm::log::Logger modm::log::error(loggerDevice); + +// ---------------------------------------------------------------------------- +int +main() +{ + uint16_t vref; + + Board::initialize(); + Adc1::connect(); + Adc1::initialize(); // 24MHz/160.5 sample time=6.6us (fulfill Ts_temp of 5us) + + Adc1::setResolution(Adc1::Resolution::Bits12); + Adc1::setSampleTime(Adc1::SampleTime::Cycles160_5); + Adc1::setRightAdjustResult(); + Adc1::enableOversampling(Adc1::OversampleRatio::x16, Adc1::OversampleShift::Div16); + + while (true) + { + LedGn::toggle(); + modm::delay(500ms); + + vref = Adc1::readInternalVoltageReference(); + MODM_LOG_INFO << "vref=" << vref << "mV " + << "temperature=" << Adc1::readTemperature(vref) << "deg.C " + << "ch1=" << (vref * Adc1::readChannel(Adc1::Channel::In1) / 4096U) << "mV " + << "ch2=" << (vref * Adc1::readChannel(Adc1::Channel::In2) / 4096U) << "mV " + << modm::endl + << modm::flush; + } + return 0; +} diff --git a/examples/stm32c0x/adc-simple/project.xml b/examples/stm32c0x/adc-simple/project.xml new file mode 100644 index 0000000000..c2ca8ea5a7 --- /dev/null +++ b/examples/stm32c0x/adc-simple/project.xml @@ -0,0 +1,27 @@ + + + + ../../../repo.lb + + + + + + + + + interface/stlink.cfg + target/stm32c0x.cfg + + + modm:architecture:clock + modm:build:scons + modm:debug + modm:platform:clock + modm:platform:core + modm:platform:gpio + modm:platform:adc + modm:platform:uart:1 + modm:platform:uart:2 + + diff --git a/examples/stm32c0x/blink-clock/main.cpp b/examples/stm32c0x/blink-clock/main.cpp new file mode 100644 index 0000000000..4e671840bd --- /dev/null +++ b/examples/stm32c0x/blink-clock/main.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, Jörg Ebeling + * + * 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 "../custom-board.hpp" + +#define BLINK_MILLIS 1000 + +using namespace modm::platform; +using namespace std::chrono_literals; + +uint32_t next_blink = modm::Clock::now().time_since_epoch().count() + BLINK_MILLIS; + +int +main() +{ + Board::initialize(); + Board::LedGn::set(); + while (true) + { + if (modm::Clock::now().time_since_epoch().count() >= next_blink) + { + next_blink += BLINK_MILLIS; + Board::LedGn::toggle(); + Board::LedRd::toggle(); + } + } +} diff --git a/examples/stm32c0x/blink-clock/project.xml b/examples/stm32c0x/blink-clock/project.xml new file mode 100644 index 0000000000..02aed6c567 --- /dev/null +++ b/examples/stm32c0x/blink-clock/project.xml @@ -0,0 +1,21 @@ + + + + ../../../repo.lb + + + + + + + + modm:debug + modm:platform:core + modm:platform:rcc + modm:platform:gpio + modm:platform:uart:1 + modm:platform:uart:2 + modm:architecture:clock + modm:build:scons + + diff --git a/examples/stm32c0x/blink-delay/main.cpp b/examples/stm32c0x/blink-delay/main.cpp new file mode 100644 index 0000000000..01d04178bd --- /dev/null +++ b/examples/stm32c0x/blink-delay/main.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024, Jörg Ebeling + * + * 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 "../custom-board.hpp" + +using namespace modm::platform; +using namespace std::chrono_literals; + +int +main() +{ + Board::initialize(); + Board::LedGn::set(); + while (true) + { + Board::LedGn::toggle(); + Board::LedRd::toggle(); + modm::delay(0.5s); + } +} diff --git a/examples/stm32c0x/blink-delay/project.xml b/examples/stm32c0x/blink-delay/project.xml new file mode 100644 index 0000000000..0163329852 --- /dev/null +++ b/examples/stm32c0x/blink-delay/project.xml @@ -0,0 +1,21 @@ + + + + ../../../repo.lb + + + + + + + + modm:debug + modm:platform:core + modm:platform:rcc + modm:platform:gpio + modm:platform:uart:1 + modm:platform:uart:2 + modm:architecture:delay + modm:build:scons + + diff --git a/examples/stm32c0x/blink-timer/main.cpp b/examples/stm32c0x/blink-timer/main.cpp new file mode 100644 index 0000000000..4a0b2ba896 --- /dev/null +++ b/examples/stm32c0x/blink-timer/main.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024, Jörg Ebeling + * + * 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 + +#include "../custom-board.hpp" + +using namespace Board; +using namespace std::chrono_literals; + +// --- UART Debugging --- +#undef MODM_LOG_LEVEL +#define MODM_LOG_LEVEL modm::log::DEBUG +// Create an IODeviceWrapper around the Uart Peripheral we want to use +modm::IODeviceWrapper loggerDevice; +// Set all four logger streams to use the UART +modm::log::Logger modm::log::debug(loggerDevice); +modm::log::Logger modm::log::info(loggerDevice); +modm::log::Logger modm::log::warning(loggerDevice); +modm::log::Logger modm::log::error(loggerDevice); + + +MODM_ISR(TIM14) +{ + Timer14::acknowledgeInterruptFlags(Timer14::InterruptFlag::Update); + MODM_LOG_DEBUG << "Toggle green LED" << modm::endl; + LedGn::toggle(); +} + +MODM_ISR(TIM16) +{ + Timer16::acknowledgeInterruptFlags(Timer16::InterruptFlag::Update); + MODM_LOG_DEBUG << "Toggle red LED" << modm::endl; + LedRd::toggle(); +} + +int +main() +{ + Board::initialize(); + + // Initialize prototyping-UART for MODM_LOG_* + proto_uart::Uart::connect(); + proto_uart::Uart::initialize(); + + MODM_LOG_INFO << "Board & Logger initialized" << modm::endl; + + Timer14::enable(); + Timer14::setMode(Timer14::Mode::UpCounter); + Timer14::setPeriod(1000ms); + Timer14::applyAndReset(); + Timer14::start(); + Timer14::enableInterrupt(Timer14::Interrupt::Update); + Timer14::enableInterruptVector(true, 5); + + Timer16::enable(); + Timer16::setMode(Timer16::Mode::UpCounter); + Timer16::setPeriod(250ms); + Timer16::applyAndReset(); + Timer16::start(); + Timer16::enableInterrupt(Timer16::Interrupt::Update); + Timer16::enableInterruptVector(true, 5); + + while (true) {} +} diff --git a/examples/stm32c0x/blink-timer/project.xml b/examples/stm32c0x/blink-timer/project.xml new file mode 100644 index 0000000000..f6a80e5062 --- /dev/null +++ b/examples/stm32c0x/blink-timer/project.xml @@ -0,0 +1,23 @@ + + + + ../../../repo.lb + + + + + + + + modm:architecture:clock + modm:build:scons + modm:debug + modm:platform:core + modm:platform:rcc + modm:platform:gpio + modm:platform:timer:14 + modm:platform:timer:16 + modm:platform:uart:1 + modm:platform:uart:2 + + diff --git a/examples/stm32c0x/custom-board.hpp b/examples/stm32c0x/custom-board.hpp new file mode 100644 index 0000000000..dfa96250a2 --- /dev/null +++ b/examples/stm32c0x/custom-board.hpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024, Jörg Ebeling + * + * 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_CUSTOM_STM32C0X_HPP +#define MODM_STM32_CUSTOM_STM32C0X_HPP + +#include +#include +#include +/// @ingroup modm_board_custom_stm32c0x modm_board_custom_stm32c0x +#define MODM_BOARD_HAS_LOGGER + +using namespace modm::platform; + +namespace Board +{ +/// @ingroup modm_board_custom_stm32c0x modm_board_custom_stm32c0x +/// @{ +using namespace modm::literals; + +struct SystemClock +{ + static constexpr uint32_t Frequency = 48_MHz; // 48MHz generated from internal RC + static constexpr uint32_t Ahb = Frequency; + static constexpr uint32_t Apb = Frequency; + + static constexpr uint32_t Adc1 = Frequency; + static constexpr uint32_t Crc = Ahb; + static constexpr uint32_t Exti = Ahb; + static constexpr uint32_t Flash = Ahb; + static constexpr uint32_t Rcc = Ahb; + static constexpr uint32_t Timer1 = Apb; + static constexpr uint32_t Timer3 = Apb; + static constexpr uint32_t Timer14 = Apb; + static constexpr uint32_t Timer16 = Apb; + static constexpr uint32_t Timer17 = Apb; + static constexpr uint32_t Usart1 = Ahb; + static constexpr uint32_t Usart2 = Ahb; + + static bool inline enable() + { + Rcc::enableInternalClock(); // 48MHz generated from internal RC + Rcc::setHsiSysDivider(Rcc::HsiSysDivider::Div1); // = 48MHz HSISYS + Rcc::setFlashLatency(); + Rcc::setAhbPrescaler(Rcc::AhbPrescaler::Div1); // = 48MHz HCLK + Rcc::setApbPrescaler(Rcc::ApbPrescaler::Div1); // = 48MHz PCLK/APB Timer Clocks + Rcc::updateCoreFrequency(); // update frequencies for busy-wait delay functions + + return true; + } +}; + +using LedGn = GpioC15; +using LedRd = GpioC14; + +using Leds = SoftwareGpioPort; +/// @} + +namespace om_uart +{ +/// @ingroup modm_board_custom_stm32c0x +/// @{ +using Tx = GpioOutputA9; +using Rx = GpioInputA10; +using Uart = BufferedUart>; +/// @} +} // namespace om_uart + +namespace proto_uart +{ +/// @ingroup modm_board_custom_stm32c0x +/// @{ +using Tx = GpioOutputA4; +using Rx = GpioInputA5; +using Uart = BufferedUart>; +/// @} +} // namespace proto_uart + +/// @ingroup modm_board_nucleo_g071rb modm_board_nucleo_g070rb +/// @{ +using LoggerDevice = modm::IODeviceWrapper; + +inline void +initialize() +{ + SystemClock::enable(); + SysTickTimer::initialize(); + + // Remap om_uart GPIOs + GpioA9::remap(); // Remap A9 -> A11 + GpioA10::remap(); // Remap A10 -> A12 + + Leds::setOutput(modm::Gpio::Low); + + proto_uart::Uart::connect(); + proto_uart::Uart::initialize(); +} + +} // namespace Board + +#endif // MODM_STM32_CUSTOM_STM32C0X_HPP