From 1f210c15bb6ecaa9f722322b613a93a391e93a65 Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Fri, 5 Jan 2024 23:56:23 +0100 Subject: [PATCH] [board] Enable TinyUSB on more STM32 dev boards --- examples/generic/usb/main.cpp | 2 + examples/generic/usb/project.xml | 38 ++++++++---- examples/stm32f429_discovery/blink/main.cpp | 15 ++++- examples/stm32f429_discovery/logger/main.cpp | 54 ----------------- .../stm32f429_discovery/logger/project.xml | 12 ---- src/modm/board/disco_f429zi/board.hpp | 54 ++++++++++++++--- src/modm/board/disco_f429zi/module.lb | 23 ++++++- src/modm/board/disco_f746ng/module.lb | 40 +++++++++++++ src/modm/board/nucleo_f429zi/board.hpp | 16 ++--- src/modm/board/nucleo_h723zg/board.hpp | 60 +++++++++++++++---- src/modm/board/nucleo_h723zg/module.lb | 11 +++- src/modm/board/nucleo_h743zi/board.hpp | 27 +++++---- 12 files changed, 232 insertions(+), 120 deletions(-) delete mode 100644 examples/stm32f429_discovery/logger/main.cpp delete mode 100644 examples/stm32f429_discovery/logger/project.xml diff --git a/examples/generic/usb/main.cpp b/examples/generic/usb/main.cpp index 38d6501c6a..56372dbfa0 100644 --- a/examples/generic/usb/main.cpp +++ b/examples/generic/usb/main.cpp @@ -39,6 +39,8 @@ int main() { Board::initialize(); Board::initializeUsbFs(); + // DISCO-F746NG also has a HS port: + // Board::initializeUsbHs(); tusb_init(); while (true) diff --git a/examples/generic/usb/project.xml b/examples/generic/usb/project.xml index aa57bea6b0..91e2aceba2 100644 --- a/examples/generic/usb/project.xml +++ b/examples/generic/usb/project.xml @@ -1,25 +1,39 @@ modm:blue-pill-f103 - - - - + + + + + + + + + - - - modm:build:scons - modm:tinyusb - modm:processing:timer - modm:io - - + + + + + + + + + modm:build:scons + modm:tinyusb + modm:processing:timer + modm:io + + + + + diff --git a/examples/stm32f429_discovery/blink/main.cpp b/examples/stm32f429_discovery/blink/main.cpp index c7a2e67843..bb109b0972 100644 --- a/examples/stm32f429_discovery/blink/main.cpp +++ b/examples/stm32f429_discovery/blink/main.cpp @@ -20,9 +20,18 @@ main() Board::initialize(); LedRed::set(); - usb::VBus::setOutput(modm::Gpio::Low); + usb::Vbus::setOutput(modm::Gpio::Low); usb::Overcurrent::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); + while (true) { LedRed::toggle(); @@ -30,10 +39,12 @@ main() modm::delay(Button::read() ? 125ms : 500ms); - usb::VBus::toggle(); + usb::Vbus::toggle(); usb::Overcurrent::toggle(); modm::delay(Button::read() ? 125ms : 500ms); + + MODM_LOG_INFO << "loop: " << counter++ << modm::endl; } return 0; diff --git a/examples/stm32f429_discovery/logger/main.cpp b/examples/stm32f429_discovery/logger/main.cpp deleted file mode 100644 index 64758c7795..0000000000 --- a/examples/stm32f429_discovery/logger/main.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2011, Fabian Greif - * Copyright (c) 2013, Kevin Läufer - * Copyright (c) 2013-2017, Niklas Hauser - * Copyright (c) 2014, Sascha Schade - * - * 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 - -// ---------------------------------------------------------------------------- -// Set the log level -#undef MODM_LOG_LEVEL -#define MODM_LOG_LEVEL modm::log::INFO - -// Create an IODeviceWrapper around the Uart Peripheral we want to use -modm::IODeviceWrapper< Usart1, modm::IOBuffer::BlockIfFull > 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() -{ - Board::initialize(); - - // initialize Uart2 for MODM_LOG_ - Usart1::connect(); - Usart1::initialize(); - - // 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; - - while (true) - { - } - - return 0; -} diff --git a/examples/stm32f429_discovery/logger/project.xml b/examples/stm32f429_discovery/logger/project.xml deleted file mode 100644 index 72e8229fd6..0000000000 --- a/examples/stm32f429_discovery/logger/project.xml +++ /dev/null @@ -1,12 +0,0 @@ - - modm:disco-f429zi - - - - - modm:debug - modm:platform:gpio - modm:platform:uart:1 - modm:build:scons - - diff --git a/src/modm/board/disco_f429zi/board.hpp b/src/modm/board/disco_f429zi/board.hpp index 5f76b349e2..2a859ac41e 100644 --- a/src/modm/board/disco_f429zi/board.hpp +++ b/src/modm/board/disco_f429zi/board.hpp @@ -16,19 +16,23 @@ #include #include +#include using namespace modm::platform; +/// @ingroup modm_board_disco_f429zi +#define MODM_BOARD_HAS_LOGGER + namespace Board { /// @ingroup modm_board_disco_f429zi /// @{ using namespace modm::literals; -/// STM32F429 running at 180MHz from the external 8MHz crystal +/// STM32F429 running at 168MHz from the external 8MHz crystal struct SystemClock { - static constexpr uint32_t Frequency = 180_MHz; + static constexpr uint32_t Frequency = 168_MHz; static constexpr uint32_t Apb1 = Frequency / 4; static constexpr uint32_t Apb2 = Frequency / 2; @@ -74,14 +78,17 @@ struct SystemClock static constexpr uint32_t Timer13 = Apb1Timer; static constexpr uint32_t Timer14 = Apb1Timer; + static constexpr uint32_t Usb = 48_MHz; + static bool inline enable() { Rcc::enableExternalCrystal(); // 8 MHz const Rcc::PllFactors pllFactors{ - .pllM = 4, // 8MHz / M=4 -> 2MHz - .pllN = 180, // 2MHz * N=180 -> 360MHz - .pllP = 2 // 360MHz / P=2 -> 180MHz = F_cpu + .pllM = 4, // 8MHz / M -> 2MHz + .pllN = 168, // 2MHz * N -> 336MHz + .pllP = 2, // 336MHz / P -> 168MHz = F_cpu + .pllQ = 7 // 336MHz / Q -> 48MHz = F_usb }; Rcc::enablePll(Rcc::PllSource::ExternalCrystal, pllFactors); // Required for 180 MHz clock @@ -222,20 +229,37 @@ using Id = GpioOutputB12; // OTG_FS_ID: USB_OTG_HS_ID using Overcurrent = GpioC5; // OTG_FS_OC [OTG_FS_OverCurrent]: GPXTI5 using Power = GpioOutputC4; // OTG_FS_PSO [OTG_FS_PowerSwitchOn] -using VBus = GpioB13; // VBUS_FS: USB_OTG_HS_VBUS -//using Device = UsbFs; +using Vbus = GpioB13; // VBUS_FS: USB_OTG_HS_VBUS + +using Device = UsbHs; +/// @} +} + +namespace stlink +{ +/// @ingroup modm_board_nucleo_h743zi +/// @{ +using Tx = GpioOutputA9; +using Rx = GpioInputA10; +using Uart = Usart1; /// @} } + /// @ingroup modm_board_disco_f429zi /// @{ +using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockIfFull >; + inline void initialize() { SystemClock::enable(); SysTickTimer::initialize(); + stlink::Uart::connect(); + stlink::Uart::initialize(); + LedGreen::setOutput(modm::Gpio::Low); LedRed::setOutput(modm::Gpio::Low); @@ -250,9 +274,23 @@ initializeL3g() l3g::Cs::setOutput(modm::Gpio::High); l3g::SpiMaster::connect(); - l3g::SpiMaster::initialize(); + l3g::SpiMaster::initialize(); l3g::SpiMaster::setDataMode(l3g::SpiMaster::DataMode::Mode3); } + +inline void +initializeUsbFs(uint8_t priority=3) +{ + Rcc::enable(); + usb::Device::initialize(priority); + usb::Device::connect(); + + usb::Overcurrent::setInput(); + usb::Vbus::setInput(); + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} /// @} } diff --git a/src/modm/board/disco_f429zi/module.lb b/src/modm/board/disco_f429zi/module.lb index 969231efc3..25e0b943e0 100644 --- a/src/modm/board/disco_f429zi/module.lb +++ b/src/modm/board/disco_f429zi/module.lb @@ -17,6 +17,22 @@ def init(module): # STM32F429IDISCOVERY [Discovery kit for STM32F429](https://www.st.com/en/evaluation-tools/32f429idiscovery.html) + +## Logging + +To use the logging, you need to close SB11 and SB15 and upgrade the STLINK/V2-B +firmware! See Section 6.3 "Embedded ST-LINK/V2-B" of UM1670. + +## TinyUSB + +To use the USB port, you must configure TinyUSB to use the HS port in FS mode: + +```xml + + + + +``` """ def prepare(module, options): @@ -24,18 +40,21 @@ def prepare(module, options): return False module.depends( + ":debug", ":architecture:clock", ":driver:l3gd20", ":platform:clock", ":platform:core", ":platform:gpio", - ":platform:spi:5") + ":platform:spi:5", + ":platform:uart:1", + ":platform:usb:hs") return True def build(env): env.outbasepath = "modm/src/modm/board" env.substitutions = { - "with_logger": False, + "with_logger": True, "with_assert": env.has_module(":architecture:assert") } env.template("../board.cpp.in", "board.cpp") diff --git a/src/modm/board/disco_f746ng/module.lb b/src/modm/board/disco_f746ng/module.lb index e80e42015e..c8a05a365b 100644 --- a/src/modm/board/disco_f746ng/module.lb +++ b/src/modm/board/disco_f746ng/module.lb @@ -17,6 +17,46 @@ def init(module): # STM32F7DISCOVERY [Discovery kit for STM32F746](https://www.st.com/en/evaluation-tools/32f746gdiscovery.html) + +## TinyUSB + +This board has two USB ports: one with Full Speed support and another with true +High Speed support. By default, TinyUSB runs the device classes on the FS port, +however, you can reassign it to HS via this option: + +```xml + + + + +``` + +Remember to initialize the HS instead of the FS port via the BSP: + +```cpp +Board::initialize(); +Board::initializeUsbHs(); +``` + +Note that can use TinyUSB with both the device and host classes at the same time +if you assign them to different ports: + +```xml +```xml + + + + + +``` + +You must initialize both ports via the BSP: + +```cpp +Board::initialize(); +Board::initializeUsbFs(); +Board::initializeUsbHs(); +``` """ def prepare(module, options): diff --git a/src/modm/board/nucleo_f429zi/board.hpp b/src/modm/board/nucleo_f429zi/board.hpp index 48ee4f59f0..256003a372 100644 --- a/src/modm/board/nucleo_f429zi/board.hpp +++ b/src/modm/board/nucleo_f429zi/board.hpp @@ -145,17 +145,17 @@ using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockI inline void initialize() { - SystemClock::enable(); - SysTickTimer::initialize(); + SystemClock::enable(); + SysTickTimer::initialize(); - stlink::Uart::connect(); - stlink::Uart::initialize(); + stlink::Uart::connect(); + stlink::Uart::initialize(); - LedGreen::setOutput(modm::Gpio::Low); - LedBlue::setOutput(modm::Gpio::Low); - LedRed::setOutput(modm::Gpio::Low); + LedGreen::setOutput(modm::Gpio::Low); + LedBlue::setOutput(modm::Gpio::Low); + LedRed::setOutput(modm::Gpio::Low); - Button::setInput(); + Button::setInput(); } inline void diff --git a/src/modm/board/nucleo_h723zg/board.hpp b/src/modm/board/nucleo_h723zg/board.hpp index ed286d3422..2b28ff010a 100644 --- a/src/modm/board/nucleo_h723zg/board.hpp +++ b/src/modm/board/nucleo_h723zg/board.hpp @@ -27,7 +27,7 @@ namespace Board /// @{ using namespace modm::literals; -/// STM32H723ZG running at 500MHz from PLL clock generated from 8 MHz HSE +/// STM32H723ZG running at 550MHz from PLL clock generated from 8 MHz HSE struct SystemClock { // Max 550MHz @@ -102,7 +102,7 @@ struct SystemClock static constexpr uint32_t Timer23 = Apb1Timer; static constexpr uint32_t Timer24 = Apb1Timer; - static constexpr uint32_t Usb = Ahb1; + static constexpr uint32_t Usb = 48_MHz; // From PLL3Q static bool inline enable() @@ -121,6 +121,16 @@ struct SystemClock .pllR = 2, // 550 MHz / 2 = 275 MHz }; Rcc::enablePll1(Rcc::PllSource::Hse, pllFactors1); + // Use PLL3 for USB 48MHz + const Rcc::PllFactors pllFactors3{ + .range = Rcc::PllInputRange::MHz4_8, + .pllM = 2, // 8MHz / M= 4MHz + .pllN = 60, // 4MHz * N= 240MHz + .pllP = 5, // 240MHz / P= 48MHz + .pllQ = 5, // 240MHz / Q= 48MHz = F_usb + .pllR = 5, // 240MHz / R= 48MHz + }; + Rcc::enablePll3(Rcc::PllSource::ExternalClock, pllFactors3); Rcc::setFlashLatency(); // max. 275MHz @@ -133,6 +143,7 @@ struct SystemClock // update clock frequencies Rcc::updateCoreFrequency(); + Rcc::enableUsbClockSource(Rcc::UsbClockSource::Pll3Q); // switch system clock to pll Rcc::enableSystemClock(Rcc::SystemClockSource::Pll1P); @@ -152,6 +163,22 @@ using LedRed = GpioOutputB14; using Leds = SoftwareGpioPort< LedRed, LedYellow, LedGreen >; /// @} +namespace usb +{ +/// @ingroup modm_board_nucleo_h723zg +/// @{ +using Vbus = GpioA9; +using Id = GpioA10; +using Dm = GpioA11; +using Dp = GpioA12; + +using Overcurrent = GpioInputG7; +using Power = GpioOutputG6; + +using Device = UsbHs; +/// @} +} + namespace stlink { /// @ingroup modm_board_nucleo_h723zg @@ -169,20 +196,31 @@ using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockI inline void initialize() { - SystemClock::enable(); - SysTickTimer::initialize(); + SystemClock::enable(); + SysTickTimer::initialize(); - stlink::Uart::connect(); - stlink::Uart::initialize(); + stlink::Uart::connect(); + stlink::Uart::initialize(); - LedGreen::setOutput(modm::Gpio::Low); - LedYellow::setOutput(modm::Gpio::Low); - LedRed::setOutput(modm::Gpio::Low); + LedGreen::setOutput(modm::Gpio::Low); + LedYellow::setOutput(modm::Gpio::Low); + LedRed::setOutput(modm::Gpio::Low); - Button::setInput(); + Button::setInput(); } -/// @} +inline void +initializeUsbFs(uint8_t priority=3) +{ + usb::Device::initialize(priority); + usb::Device::connect(); + + usb::Overcurrent::setInput(); + usb::Vbus::setInput(); + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBDEN; } /// @} +} + diff --git a/src/modm/board/nucleo_h723zg/module.lb b/src/modm/board/nucleo_h723zg/module.lb index 88ff9d2bf8..d484059a6c 100644 --- a/src/modm/board/nucleo_h723zg/module.lb +++ b/src/modm/board/nucleo_h723zg/module.lb @@ -17,6 +17,14 @@ def init(module): # NUCLEO-H723ZG [Nucleo kit for STM32H723ZG](https://www.st.com/en/evaluation-tools/nucleo-h723zg.html) + +## TinyUSB + +To use the USB port, you must configure TinyUSB to use the HS port in FS mode: + +```xml + +``` """ def prepare(module, options): @@ -29,7 +37,8 @@ def prepare(module, options): ":platform:core", ":platform:gpio", ":platform:clock", - ":platform:uart:3") + ":platform:uart:3", + ":platform:usb:hs") return True diff --git a/src/modm/board/nucleo_h743zi/board.hpp b/src/modm/board/nucleo_h743zi/board.hpp index bf206d9d63..9127839453 100644 --- a/src/modm/board/nucleo_h743zi/board.hpp +++ b/src/modm/board/nucleo_h743zi/board.hpp @@ -148,9 +148,12 @@ using LedGreen = GpioOutputB0; using LedBlue = GpioOutputB7; using LedRed = GpioOutputB14; using Leds = SoftwareGpioPort< LedRed, LedBlue, LedGreen >; +/// @} namespace usb { +/// @ingroup modm_board_nucleo_h743zi +/// @{ using Vbus = GpioA9; using Id = GpioA10; using Dm = GpioA11; @@ -160,41 +163,45 @@ using Overcurrent = GpioInputG7; // OTG_FS_OverCurrent using Power = GpioOutputG6; // OTG_FS_PowerSwitchOn using Device = UsbFs; +/// @} } namespace stlink { +/// @ingroup modm_board_nucleo_h743zi +/// @{ using Tx = GpioOutputD8; using Rx = GpioInputD9; using Uart = Usart3; +/// @} } +/// @ingroup modm_board_nucleo_h743zi +/// @{ using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockIfFull >; inline void initialize() { - SystemClock::enable(); - SysTickTimer::initialize(); + SystemClock::enable(); + SysTickTimer::initialize(); - stlink::Uart::connect(); - stlink::Uart::initialize(); + stlink::Uart::connect(); + stlink::Uart::initialize(); - LedGreen::setOutput(modm::Gpio::Low); - LedBlue::setOutput(modm::Gpio::Low); - LedRed::setOutput(modm::Gpio::Low); + LedGreen::setOutput(modm::Gpio::Low); + LedBlue::setOutput(modm::Gpio::Low); + LedRed::setOutput(modm::Gpio::Low); - Button::setInput(); + Button::setInput(); } -/// FIXME: USB does not work on this board. inline void initializeUsbFs(uint8_t priority=3) { usb::Device::initialize(priority); usb::Device::connect(); - usb::Id::configure(Gpio::InputType::Floating); usb::Overcurrent::setInput(); usb::Vbus::setInput();