Skip to content

Commit

Permalink
[board] Enable TinyUSB on more STM32 dev boards
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Jan 4, 2024
1 parent fe474ae commit e4dfeba
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 45 deletions.
2 changes: 2 additions & 0 deletions examples/generic/usb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ int main()
{
Board::initialize();
Board::initializeUsbFs();
// DISCO-F746NG also has a HS port:
// Board::initializeUsbHs();
tusb_init();

while (true)
Expand Down
26 changes: 22 additions & 4 deletions examples/generic/usb/project.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
<library>
<extends>modm:blue-pill-f103</extends>
<!-- <extends>modm:disco-f072rb</extends> -->
<!-- <extends>modm:black-pill-f401</extends> -->
<!-- <extends>modm:black-pill-f411</extends> -->
<!-- <extends>modm:feather-m0</extends> -->
<!-- <extends>modm:samd21-mini</extends> -->
<!-- <extends>modm:nucleo-f429zi</extends> -->
<!-- <extends>modm:disco-f072rb</extends> -->
<!-- <extends>modm:disco-f303vc</extends> -->
<!-- <extends>modm:disco-f407vg</extends> -->
<!-- <extends>modm:disco-f429zi</extends> -->
<!-- <extends>modm:disco-f469ni</extends> -->
<!-- <extends>modm:disco-f746ng</extends> -->
<!-- <extends>modm:disco-l476vg</extends> -->
<!-- <extends>modm:feather-m0</extends> -->
<!-- <extends>modm:nucleo-f429zi</extends> -->
<!-- <extends>modm:nucleo-h723zg</extends> -->
<!-- <extends>modm:nucleo-h743zi</extends> -->
<!-- <extends>modm:rp-pico</extends> -->
<!-- <extends>modm:samd21-mini</extends> -->
<options>
<option name="modm:build:build.path">../../../build/generic/usb</option>
<option name="modm:build:openocd.cfg">openocd.cfg</option>
<option name="modm:tinyusb:config">device.cdc,device.msc</option>

<!-- Alternative configuration: -->
<!-- <option name="modm:tinyusb:config">device.cdc,device.midi</option> -->

<!-- Option required on DISCO-F429ZI: -->
<!-- <option name="modm:tinyusb:device:port">hs</option> -->

<!-- Option required on NUCLEO-H723ZG, DISCO-F429ZI: -->
<!-- <option name="modm:tinyusb:speed">full</option> -->

<!-- DISCO-F746NG can use both HS and FS port at the same time! -->
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:tinyusb</module>
<module>modm:processing:timer</module>
<module>modm:io</module>
</modules>
<collectors>
<!-- <collect name="modm:build:cppdefines">CFG_TUSB_DEBUG=3</collect> -->
</collectors>
</library>
54 changes: 46 additions & 8 deletions src/modm/board/disco_f429zi/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@

#include <modm/platform.hpp>
#include <modm/architecture/interface/clock.hpp>
#include <modm/debug/logger.hpp>

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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<SystemClock>();

stlink::Uart::connect<stlink::Tx::Tx, stlink::Rx::Rx>();
stlink::Uart::initialize<SystemClock, 115200_Bd>();

LedGreen::setOutput(modm::Gpio::Low);
LedRed::setOutput(modm::Gpio::Low);

Expand All @@ -250,9 +274,23 @@ initializeL3g()
l3g::Cs::setOutput(modm::Gpio::High);

l3g::SpiMaster::connect<l3g::Sck::Sck, l3g::Mosi::Mosi, l3g::Miso::Miso>();
l3g::SpiMaster::initialize<SystemClock, 11.25_MHz>();
l3g::SpiMaster::initialize<SystemClock, 10.5_MHz>();
l3g::SpiMaster::setDataMode(l3g::SpiMaster::DataMode::Mode3);
}

inline void
initializeUsbFs(uint8_t priority=3)
{
Rcc::enable<Peripheral::Usbotgfs>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

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;
}
/// @}

}
Expand Down
23 changes: 21 additions & 2 deletions src/modm/board/disco_f429zi/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,44 @@ 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
<option name="modm:tinyusb:speed">full</option>
<!-- place either the device or host classes on the HS port -->
<option name="modm:tinyusb:device:port">hs</option>
<option name="modm:tinyusb:host:port">hs</option>
```
"""

def prepare(module, options):
if not options[":target"].partname.startswith("stm32f429zit"):
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")
Expand Down
16 changes: 8 additions & 8 deletions src/modm/board/nucleo_f429zi/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,17 @@ using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockI
inline void
initialize()
{
SystemClock::enable();
SysTickTimer::initialize<SystemClock>();
SystemClock::enable();
SysTickTimer::initialize<SystemClock>();

stlink::Uart::connect<stlink::Tx::Tx, stlink::Rx::Rx>();
stlink::Uart::initialize<SystemClock, 115200_Bd>();
stlink::Uart::connect<stlink::Tx::Tx, stlink::Rx::Rx>();
stlink::Uart::initialize<SystemClock, 115200_Bd>();

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
Expand Down
62 changes: 50 additions & 12 deletions src/modm/board/nucleo_h723zg/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -113,14 +113,24 @@ struct SystemClock

Rcc::enableExternalClock(); // 8 MHz
const Rcc::PllFactors pllFactors1{
.range = Rcc::PllInputRange::MHz1_2,
.range = Rcc::PllInputRange::MHz4_8,
.pllM = 4, // 8 MHz / 4 = 2 MHz
.pllN = 275, // 2 MHz * 275 = 550 MHz
.pllP = 1, // 550 MHz / 1 = 550 MHz
.pllQ = 4, // 550 MHz / 4 = 137.5 MHz
.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<Ahb>();

// max. 275MHz
Expand All @@ -133,6 +143,7 @@ struct SystemClock

// update clock frequencies
Rcc::updateCoreFrequency<Frequency>();
Rcc::enableUsbClockSource(Rcc::UsbClockSource::Pll3Q);
// switch system clock to pll
Rcc::enableSystemClock(Rcc::SystemClockSource::Pll1P);

Expand All @@ -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
Expand All @@ -169,20 +196,31 @@ using LoggerDevice = modm::IODeviceWrapper< stlink::Uart, modm::IOBuffer::BlockI
inline void
initialize()
{
SystemClock::enable();
SysTickTimer::initialize<SystemClock>();
SystemClock::enable();
SysTickTimer::initialize<SystemClock>();

stlink::Uart::connect<stlink::Tx::Tx, stlink::Rx::Rx>();
stlink::Uart::initialize<SystemClock, 115200_Bd>();
stlink::Uart::connect<stlink::Tx::Tx, stlink::Rx::Rx>();
stlink::Uart::initialize<SystemClock, 115200_Bd>();

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<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

usb::Overcurrent::setInput();
usb::Vbus::setInput();
// Enable VBUS sense (B device) via pin PA9
USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBDEN;
}
/// @}

}

11 changes: 10 additions & 1 deletion src/modm/board/nucleo_h723zg/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -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
<option name="modm:tinyusb:speed">full</option>
```
"""

def prepare(module, options):
Expand All @@ -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

Expand Down
Loading

0 comments on commit e4dfeba

Please sign in to comment.