Skip to content

Commit a5579d7

Browse files
committed
Add GD32 TRNG support
Introduce a new `gd32::trng` wrapper with `Init()` and `Get()` helpers, plus the GD32F20X/GD32F4XX implementation. The new code enables the TRNG peripheral, waits for valid data with timeout handling, and reports clock/seed errors when random data is not ready or repeats.
1 parent 026ff4f commit a5579d7

2 files changed

Lines changed: 137 additions & 0 deletions

File tree

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/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)