Skip to content

Commit 653d36b

Browse files
committed
Add GD32 TRNG support utility
Introduce a new `gd32::trng` module for GD32F20X/F4XX with init, readiness checks, timeout/error reporting, and random value retrieval with duplicate-value detection. Also clean up small platform utilities by centralizing `board::SysName()` storage in a constant and updating `DelayUs` for lint/style compliance (`while(true)`, IWYU keep, and swap-parameter suppression).
1 parent 72a9572 commit 653d36b

5 files changed

Lines changed: 143 additions & 7 deletions

File tree

lib-gd32/.cproject

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/gd32f20x/CMSIS/GD/GD32F20x/Include}&quot;"/>
2929
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/gd32f20x/GD32F20x_standard_peripheral/Include}&quot;"/>
3030
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/include}&quot;"/>
31-
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-hal/include}&quot;"/>
3231
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-network/include}&quot;"/>
3332
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/include}&quot;"/>
3433
</option>
@@ -49,7 +48,6 @@
4948
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/gd32f20x/CMSIS/GD/GD32F20x/Include}&quot;"/>
5049
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/gd32f20x/GD32F20x_standard_peripheral/Include}&quot;"/>
5150
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/include}&quot;"/>
52-
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-hal/include}&quot;"/>
5351
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-network/include}&quot;"/>
5452
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/include}&quot;"/>
5553
</option>
@@ -81,7 +79,6 @@
8179
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/gd32f20x/CMSIS/GD/GD32F20x/Include}&quot;"/>
8280
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/gd32f20x/GD32F20x_standard_peripheral/Include}&quot;"/>
8381
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-gd32/include}&quot;"/>
84-
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-hal/include}&quot;"/>
8582
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib-network/include}&quot;"/>
8683
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/include}&quot;"/>
8784
</option>

lib-gd32/include/gd32_trng.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @file gd32_trng.h
3+
*
4+
*/
5+
/* Copyright (C) 2026 by Arjan van Vught mailto:info@gd32-dmx.org
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
26+
#ifndef GD32_TRNG_H_
27+
#define GD32_TRNG_H_
28+
29+
#if defined(GD32F10X) || defined(GD32F30X)
30+
#errror MCU is not supported
31+
#endif
32+
33+
#include <cstdint>
34+
35+
namespace gd32::trng {
36+
bool Init();
37+
bool Get(uint32_t& out);
38+
} // namespace gd32::trng
39+
40+
#endif // GD32_TRNG_H_

lib-gd32/src/board.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace board {
2929
static constexpr float kCoreTemperatureMin = -40.0;
3030
static constexpr float kCoreTemperatureMax = +85.0;
3131
static constexpr const char kWebsite[] = "https://gd32-dmx.org";
32+
static constexpr char kSysName[] = "Embedded";
3233

3334
const char* Website() {
3435
return kWebsite;
@@ -57,7 +58,7 @@ const char* CpuName(uint8_t& length) {
5758
}
5859

5960
const char* SysName(uint8_t& length) {
60-
length = 8;
61-
return "Embedded";
61+
length = sizeof(kSysName) - 1U;
62+
return kSysName;
6263
}
6364
} // namespace board

lib-gd32/src/delayus.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include <cstdint>
3434
#include <cassert>
3535

36-
#include "gd32.h"
36+
#include "gd32.h" // IWYU pragma: keep
3737

3838
static constexpr auto kTicksPerUs = (MCU_CLOCK_FREQ / 1000000U);
3939

@@ -46,6 +46,7 @@ void UdelayInit() {
4646
}
4747

4848
namespace timing {
49+
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
4950
void DelayUs(uint32_t micros, uint32_t offset_micros) {
5051
const auto kTicks = micros * kTicksPerUs;
5152

@@ -58,7 +59,7 @@ void DelayUs(uint32_t micros, uint32_t offset_micros) {
5859
ticks_previous = offset_micros;
5960
}
6061

61-
while (1) {
62+
while (true) {
6263
const auto kTicksNow = DWT->CYCCNT;
6364

6465
if (kTicksNow != ticks_previous) {

lib-gd32/src/gd32_trng.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#if defined(GD32F20X) || defined(GD32F4XX)
2+
/**
3+
* @file gd32_trng.h
4+
*
5+
*/
6+
/* Copyright (C) 2026 by Arjan van Vught mailto:info@gd32-dmx.org
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#if defined(DEBUG_GD32_TRNG)
28+
#undef NDEBUG
29+
#endif
30+
31+
#include <cstdint>
32+
#include <cstdio>
33+
34+
#include "gd32_trng.h"
35+
#include "gd32.h" // IWYU pragma: keep
36+
#include "firmware/debug/debug_debug.h"
37+
38+
namespace gd32::trng {
39+
static constexpr uint32_t kTimeout = 0xFFFF;
40+
41+
static bool ReadyCheck() {
42+
uint32_t timeout = 0;
43+
FlagStatus trng_flag = RESET;
44+
45+
// check wherther the random data is valid
46+
do {
47+
timeout++;
48+
trng_flag = trng_flag_get(TRNG_FLAG_DRDY);
49+
} while ((RESET == trng_flag) && (kTimeout > timeout));
50+
51+
if (RESET == trng_flag) [[unlikely]] {
52+
// ready check timeout
53+
printf("Error: TRNG can't ready \r\n");
54+
trng_flag = trng_flag_get(TRNG_FLAG_CECS);
55+
printf("Clock error current status: %d \r\n", trng_flag);
56+
trng_flag = trng_flag_get(TRNG_FLAG_SECS);
57+
printf("Seed error current status: %d \r\n", trng_flag);
58+
return false;
59+
}
60+
61+
return true;
62+
}
63+
64+
bool Init() {
65+
DEBUG_ENTRY();
66+
67+
// TRNG module clock enable
68+
rcu_periph_clock_enable(RCU_TRNG);
69+
// TRNG registers reset
70+
trng_deinit();
71+
trng_enable();
72+
// check TRNG work status
73+
const auto kReturn= ReadyCheck();
74+
75+
DEBUG_PRINTF("%s", kReturn ? "Success" : "Error");
76+
DEBUG_EXIT();
77+
return kReturn;
78+
}
79+
80+
static uint32_t out_last = 0;
81+
82+
bool Get(uint32_t& out) {
83+
if (ReadyCheck()) {
84+
out = trng_get_true_random_data();
85+
if (out != out_last) {
86+
out_last = out;
87+
return true;
88+
}
89+
// the random data is invalid
90+
puts("Error: Get the random data is same");
91+
}
92+
93+
return false;
94+
}
95+
} // namespace gd32::trng
96+
97+
#endif

0 commit comments

Comments
 (0)