Skip to content

Commit 6f04861

Browse files
committed
[board] Add WeAct-H523CE Core Board
1 parent 131aab2 commit 6f04861

File tree

8 files changed

+309
-1
lines changed

8 files changed

+309
-1
lines changed

.github/workflows/linux.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ jobs:
202202
- name: Examples STM32H5 Series
203203
if: always()
204204
run: |
205-
(cd examples && ../tools/scripts/examples_compile.py nucleo_h503rb weact_h503cb weact_h562rg)
205+
(cd examples && ../tools/scripts/examples_compile.py nucleo_h503rb weact_h503cb weact_h523ce weact_h562rg)
206206
- name: Examples STM32H7 Series
207207
if: always()
208208
run: |

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,8 +816,10 @@ We have out-of-box support for many development boards including documentation.
816816
<td align="center"><a href="https://modm.io/reference/config/modm-weact-g0b1cb">WEACT-G0B1CB</a></td>
817817
</tr><tr>
818818
<td align="center"><a href="https://modm.io/reference/config/modm-weact-h503cb">WEACT-H503CB</a></td>
819+
<td align="center"><a href="https://modm.io/reference/config/modm-weact-h523ce">WEACT-H523CE</a></td>
819820
<td align="center"><a href="https://modm.io/reference/config/modm-weact-h562rg">WEACT-H562RG</a></td>
820821
<td align="center"><a href="https://modm.io/reference/config/modm-weact-u585ci">WEACT-U585CI</a></td>
822+
</tr><tr>
821823
</tr>
822824
</table>
823825
<!--/bsptable-->

examples/generic/usb/project.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<!-- <extends>modm:weact-u585ci</extends> -->
2323
<!-- <extends>modm:nucleo-h503rb</extends> -->
2424
<!-- <extends>modm:weact-h503cb</extends> -->
25+
<!-- <extends>modm:weact-h523ce</extends> -->
2526
<!-- <extends>modm:weact-h562rg</extends> -->
2627
<!-- <extends>modm:nucleo-u385rg-q</extends> -->
2728
<options>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2017, Niklas Hauser
3+
* Copyright (c) 2017, Sascha Schade
4+
*
5+
* This file is part of the modm project.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
10+
*/
11+
#include <modm/board.hpp>
12+
13+
int main()
14+
{
15+
Board::initialize();
16+
Board::Leds::setOutput();
17+
18+
while (true)
19+
{
20+
Board::Leds::toggle();
21+
modm::delay(Board::Button::read() ? 250ms : 500ms);
22+
static uint32_t counter(0);
23+
MODM_LOG_INFO << "Loop counter: " << (counter++) << modm::endl;
24+
}
25+
return 0;
26+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<library>
2+
<extends>modm:weact-h523ce</extends>
3+
<options>
4+
<option name="modm:build:build.path">../../../build/weact_h523ce/blink</option>
5+
<option name="modm:board:weact-h523ce:with_rtt">yes</option>
6+
</options>
7+
<modules>
8+
<module>modm:architecture:delay</module>
9+
<module>modm:build:scons</module>
10+
</modules>
11+
<collectors>
12+
<collect name="modm:build:openocd.source">interface/stlink-dap.cfg</collect>
13+
</collectors>
14+
</library>
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright (c) 2026, Niklas Hauser
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#pragma once
13+
14+
#include <modm/platform.hpp>
15+
#include <modm/architecture.hpp>
16+
#include <modm/debug.hpp>
17+
18+
using namespace modm::platform;
19+
%#
20+
%% if with_logger
21+
/// @ingroup modm_board_weact_h523ce
22+
#define MODM_BOARD_HAS_LOGGER
23+
%#
24+
%% endif
25+
namespace Board
26+
{
27+
/// @ingroup modm_board_weact_h523ce
28+
/// @{
29+
using namespace modm::literals;
30+
31+
/// STM32H523Cx running at 250MHz from PLL clock generated from 8 MHz HSE
32+
struct SystemClock
33+
{
34+
static constexpr uint32_t Hse = 8_MHz;
35+
static constexpr uint32_t Lse = 32.768_kHz;
36+
37+
static constexpr Rcc::PllConfig pll1
38+
{
39+
.range = Rcc::PllInputRange::MHz2_4,
40+
.M = 4, // 8 MHz / 4 = 2 MHz
41+
.N = 250, // 2 MHz * 120 = 500 MHz
42+
.P = 2, // 500 MHz / 2 = 250 MHz = F_cpu
43+
};
44+
static constexpr uint32_t Pll1P = Hse / pll1.M * pll1.N / pll1.P;
45+
static_assert(Pll1P == Rcc::MaxFrequency);
46+
47+
static constexpr Rcc::PllConfig pll3
48+
{
49+
.range = Rcc::PllInputRange::MHz8_16,
50+
.M = 1, // 8 MHz / 1 = 8 MHz
51+
.N = 18, // 8 MHz * 18 = 144 MHz
52+
.Q = 3, // 144 MHz / 3 = 48 MHz = F_usb
53+
};
54+
static constexpr uint32_t Pll3Q = Hse / pll3.M * pll3.N / pll3.Q;
55+
56+
static constexpr uint32_t SysClk = Pll1P;
57+
static constexpr uint32_t Frequency = SysClk;
58+
59+
// AHB Bus - Max 250MHz
60+
static constexpr uint32_t Hclk = SysClk / 1;
61+
static constexpr uint32_t Ahb = Hclk;
62+
63+
// APB Buses - Max 250MHz
64+
static constexpr uint32_t Apb1 = Hclk / 1;
65+
static constexpr uint32_t Apb2 = Hclk / 1;
66+
static constexpr uint32_t Apb3 = Hclk / 1;
67+
68+
// Peripherals on AHB2
69+
static constexpr uint32_t Adc1 = Hclk;
70+
static constexpr uint32_t Dac1 = Hclk;
71+
72+
// Peripherals on APB2
73+
static constexpr uint32_t Spi1 = Apb2;
74+
static constexpr uint32_t Usart1 = Apb2;
75+
76+
// Peripherals on APB1
77+
static constexpr uint32_t Spi2 = Apb1;
78+
static constexpr uint32_t Spi3 = Apb1;
79+
static constexpr uint32_t Usart2 = Apb1;
80+
static constexpr uint32_t Usart3 = Apb1;
81+
static constexpr uint32_t Fdcan1 = Apb1;
82+
83+
// Peripherals on APB3
84+
static constexpr uint32_t LpUart1 = Apb3;
85+
86+
// Timer Clocks
87+
static constexpr uint32_t Apb1Timer = Apb1 * 1;
88+
static constexpr uint32_t Apb2Timer = Apb2 * 1;
89+
90+
static constexpr uint32_t Timer1 = Apb2Timer;
91+
static constexpr uint32_t Timer2 = Apb1Timer;
92+
static constexpr uint32_t Timer3 = Apb1Timer;
93+
static constexpr uint32_t Timer6 = Apb1Timer;
94+
static constexpr uint32_t Timer7 = Apb1Timer;
95+
96+
static constexpr uint32_t Rtc = Lse;
97+
static constexpr uint32_t Usb = Pll3Q;
98+
static constexpr uint32_t Iwdg = Rcc::LsiFrequency;
99+
100+
static bool inline
101+
enable()
102+
{
103+
Rcc::enableLseCrystal();
104+
Rcc::enableHseCrystal();
105+
106+
Rcc::setVoltageScaling(Rcc::VoltageScaling::Scale0);
107+
Rcc::setFlashLatency<Frequency>();
108+
109+
Rcc::enablePll1(Rcc::PllSource::Hse, pll1);
110+
Rcc::enablePll3(Rcc::PllSource::Hse, pll3);
111+
112+
Rcc::setAhbPrescaler(Rcc::AhbPrescaler::Div1);
113+
Rcc::setApb1Prescaler(Rcc::ApbPrescaler::Div1);
114+
Rcc::setApb2Prescaler(Rcc::ApbPrescaler::Div1);
115+
Rcc::setApb3Prescaler(Rcc::ApbPrescaler::Div1);
116+
117+
Rcc::updateCoreFrequency<Frequency>();
118+
119+
Rcc::enableSystemClock(Rcc::SystemClockSource::Pll1P);
120+
Rcc::setUsbClockSource(Rcc::UsbClockSource::Pll3Q);
121+
Rcc::setRealTimeClockSource(Rcc::RealTimeClockSource::Lse);
122+
123+
return true;
124+
}
125+
};
126+
127+
using Button = GpioInverted<GpioInputA0>;
128+
129+
using Led = GpioInverted<GpioOutputC13>;
130+
using Leds = SoftwareGpioPort< Led >;
131+
/// @}
132+
133+
namespace usb
134+
{
135+
/// @ingroup modm_board_weact_h523ce
136+
/// @{
137+
using Dm = GpioA11;
138+
using Dp = GpioA12;
139+
140+
using Device = UsbFs;
141+
/// @}
142+
}
143+
144+
/// @ingroup modm_board_weact_h523ce
145+
/// @{
146+
%% if with_logger
147+
using LoggerDevice = modm::IODeviceWrapper< Rtt<0>, modm::IOBuffer::DiscardIfFull >;
148+
%#
149+
%% endif
150+
inline void
151+
initialize()
152+
{
153+
SystemClock::enable();
154+
SysTickTimer::initialize<SystemClock>();
155+
156+
Led::setOutput(modm::Gpio::Low);
157+
Button::setInput(Gpio::InputType::PullUp);
158+
}
159+
160+
inline void
161+
initializeUsb(uint8_t priority=3)
162+
{
163+
usb::Device::initialize<SystemClock>(priority);
164+
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp>();
165+
}
166+
/// @}
167+
168+
}
169+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<library>
2+
<repositories>
3+
<repository>
4+
<path>../../../../repo.lb</path>
5+
</repository>
6+
</repositories>
7+
8+
<options>
9+
<option name="modm:target">stm32h523cet6</option>
10+
</options>
11+
<modules>
12+
<module>modm:board:weact-h523ce</module>
13+
</modules>
14+
</library>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Copyright (c) 2026, Niklas Hauser
5+
#
6+
# This file is part of the modm project.
7+
#
8+
# This Source Code Form is subject to the terms of the Mozilla Public
9+
# License, v. 2.0. If a copy of the MPL was not distributed with this
10+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
11+
# -----------------------------------------------------------------------------
12+
13+
def init(module):
14+
module.name = ":board:weact-h523ce"
15+
module.description = """
16+
# WeAct Studio STM32H523Cx Core Board
17+
18+
[Documentation](https://github.com/WeActStudio/WeActStudio.STM32H523CoreBoard)
19+
20+
Cheap and bread-board-friendly board for the STM32H523 series.
21+
22+
23+
## Programming
24+
25+
Since the board has no St-Link programmer on the board,
26+
you must use DFU (Device Firmware Update (via USB)) to program the board.
27+
A DFU command is integrated into the `modm:build:scons` tool:
28+
29+
```
30+
scons program-dfu
31+
```
32+
33+
Note that you need to manually reset the board due to a bug in the DFU
34+
implementation.
35+
36+
37+
## Logging
38+
39+
To log via RTT attach a debugger to the SWD port and select the RTT option:
40+
41+
```xml
42+
<option name="modm:board:weact-h523ce:with_rtt">yes</option>
43+
```
44+
45+
Then log using:
46+
47+
```sh
48+
scons log-rtt
49+
```
50+
"""
51+
52+
def prepare(module, options):
53+
if not options[":target"].partname.startswith("stm32h523c"):
54+
return False
55+
56+
module.depends(
57+
":debug",
58+
":architecture:clock",
59+
":platform:core",
60+
":platform:gpio",
61+
":platform:clock",
62+
":platform:usb")
63+
64+
module.add_option(
65+
BooleanOption(name="with_rtt", description="Log using RTT", default=False,
66+
dependencies=lambda v: ":platform:rtt" if v else None))
67+
68+
return True
69+
70+
def build(env):
71+
env.outbasepath = "modm/src/modm/board"
72+
env.substitutions = {
73+
"with_logger": env["with_rtt"],
74+
"with_assert": env.has_module(":architecture:assert"),
75+
}
76+
env.template("../board.cpp.in", "board.cpp")
77+
env.template("board.hpp.in")
78+
79+
env.outbasepath = "modm/openocd/modm/board/"
80+
env.template(repopath("tools/openocd/modm/stm32_swd.cfg.in"), "board.cfg",
81+
substitutions={"target": "stm32h5x"})
82+
env.collect(":build:openocd.source", "modm/board/board.cfg")

0 commit comments

Comments
 (0)