Skip to content

Commit 2c354bf

Browse files
committed
[stm32wb_rng, rng] Implement RNG device type. Implement RNG driver and test for stm32wb
1 parent 7fa52da commit 2c354bf

12 files changed

Lines changed: 415 additions & 1 deletion

File tree

examples/stm32wb/stm32wb55xx_nucleo.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,12 @@ whal_Flash g_whalFlash = {
9797
.size = 0x100000,
9898
},
9999
};
100+
101+
whal_Rng g_whalRng = {
102+
WHAL_STM32WB55_RNG_DEVICE,
103+
104+
.cfg = &(whal_Stm32wbRng_Cfg) {
105+
.clkCtrl = &g_whalClock,
106+
.clk = &(whal_Stm32wbRcc_Clk) {WHAL_STM32WB55_RNG_CLOCK},
107+
},
108+
};

examples/stm32wb/stm32wb55xx_nucleo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,7 @@ extern whal_Uart g_whalUart;
3030
/* Flash controller instance. */
3131
extern whal_Flash g_whalFlash;
3232

33+
/* RNG instance. */
34+
extern whal_Rng g_whalRng;
3335

3436
#endif /* STM32WB55XX_NUCLEO_H */

src/clock/stm32wb_rcc.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/* Clock Control Register - oscillator enables and status */
1919
#define ST_RCC_CR_REG 0x000
2020
#define ST_RCC_CR_MSIRANGE WHAL_MASK_RANGE(7, 4) /* MSI frequency range */
21+
#define ST_RCC_CR_HSION_MASK WHAL_MASK(8) /* HSI enable */
2122
#define ST_RCC_CR_PLLON_MASK WHAL_MASK(24) /* PLL enable */
2223

2324
/* Clock Configuration Register - clock source and prescaler selection */
@@ -73,6 +74,11 @@
7374
#define ST_RCC_APB1ENR2_LPUART1EN WHAL_MASK(0) /* LPUART1 clock enable */
7475
#define ST_RCC_APB1ENR2_LPTIM2EN WHAL_MASK(5) /* LPTIM2 clock enable */
7576

77+
/* Clock Recovery RC Register - HSI48 oscillator control */
78+
#define ST_RCC_CRRCR_REG 0x098
79+
#define ST_RCC_CRRCR_HSI48ON_MASK WHAL_MASK(0) /* HSI48 oscillator enable */
80+
#define ST_RCC_CRRCR_HSI48RDY_MASK WHAL_MASK(1) /* HSI48 oscillator ready */
81+
7682
whal_Error whal_Stm32wbRccPll_Init(whal_Clock *clkDev)
7783
{
7884
whal_Error err;
@@ -303,6 +309,27 @@ whal_Error whal_Stm32wbRccMsi_GetRate(whal_Clock *clkDev, size_t *rateOut)
303309

304310
return WHAL_SUCCESS;
305311
}
312+
313+
whal_Error whal_Stm32wbRcc_Ext_EnableHsi48(whal_Clock *clkDev, uint8_t enable)
314+
{
315+
if (!clkDev) {
316+
return WHAL_EINVAL;
317+
}
318+
319+
whal_Reg_Update(clkDev->regmap.base, ST_RCC_CRRCR_REG, ST_RCC_CRRCR_HSI48ON_MASK,
320+
whal_SetBits(ST_RCC_CRRCR_HSI48ON_MASK, enable));
321+
322+
if (enable) {
323+
size_t rdy;
324+
do {
325+
whal_Reg_Get(clkDev->regmap.base, ST_RCC_CRRCR_REG,
326+
ST_RCC_CRRCR_HSI48RDY_MASK, &rdy);
327+
} while (!rdy);
328+
}
329+
330+
return WHAL_SUCCESS;
331+
}
332+
306333
const whal_ClockDriver whal_Stm32wbRccPll_Driver = {
307334
.Init = whal_Stm32wbRccPll_Init,
308335
.Deinit = whal_Stm32wbRccPll_Deinit,

src/rng/rng.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <stdint.h>
2+
#include <wolfHAL/rng/rng.h>
3+
#include <wolfHAL/error.h>
4+
5+
inline whal_Error whal_Rng_Init(whal_Rng *rngDev)
6+
{
7+
if (!rngDev || !rngDev->driver || !rngDev->driver->Init) {
8+
return WHAL_EINVAL;
9+
}
10+
11+
return rngDev->driver->Init(rngDev);
12+
}
13+
14+
inline whal_Error whal_Rng_Deinit(whal_Rng *rngDev)
15+
{
16+
if (!rngDev || !rngDev->driver || !rngDev->driver->Deinit) {
17+
return WHAL_EINVAL;
18+
}
19+
20+
return rngDev->driver->Deinit(rngDev);
21+
}
22+
23+
inline whal_Error whal_Rng_Generate(whal_Rng *rngDev, uint8_t *rngData, size_t rngDataSz)
24+
{
25+
if (!rngDev || !rngDev->driver || !rngDev->driver->Generate || !rngData) {
26+
return WHAL_EINVAL;
27+
}
28+
29+
return rngDev->driver->Generate(rngDev, rngData, rngDataSz);
30+
}

src/rng/stm32wb_rng.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include <stdint.h>
2+
#include <wolfHAL/rng/stm32wb_rng.h>
3+
#include <wolfHAL/rng/rng.h>
4+
#include <wolfHAL/clock/clock.h>
5+
#include <wolfHAL/error.h>
6+
#include <wolfHAL/regmap.h>
7+
#include <wolfHAL/bitops.h>
8+
9+
/*
10+
* STM32WB RNG Register Definitions
11+
*
12+
* The RNG peripheral uses an analog noise source to produce 32-bit
13+
* random values. One value is available at a time in DR, signaled
14+
* by the DRDY flag in SR.
15+
*/
16+
17+
/* Control Register */
18+
#define SRNG_CR_REG 0x00
19+
#define SRNG_CR_RNGEN WHAL_MASK(2) /* RNG enable */
20+
#define SRNG_CR_CED WHAL_MASK(5) /* Clock error detection disable */
21+
22+
/* Status Register */
23+
#define SRNG_SR_REG 0x04
24+
#define SRNG_SR_DRDY WHAL_MASK(0) /* Data ready */
25+
#define SRNG_SR_CECS WHAL_MASK(1) /* Clock error current status */
26+
#define SRNG_SR_SECS WHAL_MASK(2) /* Seed error current status */
27+
#define SRNG_SR_CEIS WHAL_MASK(5) /* Clock error interrupt status */
28+
#define SRNG_SR_SEIS WHAL_MASK(6) /* Seed error interrupt status */
29+
30+
/* Data Register - 32-bit random value */
31+
#define SRNG_DR_REG 0x08
32+
33+
whal_Error whal_Stm32wbRng_Init(whal_Rng *rngDev)
34+
{
35+
whal_Error err;
36+
whal_Stm32wbRng_Cfg *cfg;
37+
38+
cfg = (whal_Stm32wbRng_Cfg *)rngDev->cfg;
39+
40+
err = whal_Clock_Enable(cfg->clkCtrl, cfg->clk);
41+
if (err != WHAL_SUCCESS) {
42+
return err;
43+
}
44+
45+
return WHAL_SUCCESS;
46+
}
47+
48+
whal_Error whal_Stm32wbRng_Deinit(whal_Rng *rngDev)
49+
{
50+
whal_Error err;
51+
whal_Stm32wbRng_Cfg *cfg = (whal_Stm32wbRng_Cfg *)rngDev->cfg;
52+
53+
err = whal_Clock_Disable(cfg->clkCtrl, cfg->clk);
54+
if (err) {
55+
return err;
56+
}
57+
58+
return WHAL_SUCCESS;
59+
}
60+
61+
whal_Error whal_Stm32wbRng_Generate(whal_Rng *rngDev, uint8_t *rngData, size_t rngDataSz)
62+
{
63+
whal_Error err = WHAL_SUCCESS;
64+
const whal_Regmap *reg = &rngDev->regmap;
65+
size_t status;
66+
size_t offset = 0;
67+
68+
/* Enable the RNG peripheral */
69+
whal_Reg_Update(reg->base, SRNG_CR_REG, SRNG_CR_RNGEN,
70+
whal_SetBits(SRNG_CR_RNGEN, 1));
71+
72+
while (offset < rngDataSz) {
73+
/* Wait for a random value to be ready */
74+
do {
75+
/* Check for seed or clock error */
76+
whal_Reg_Get(reg->base, SRNG_SR_REG, SRNG_SR_SECS, &status);
77+
if (status) {
78+
err = WHAL_EINVAL;
79+
goto exit;
80+
}
81+
whal_Reg_Get(reg->base, SRNG_SR_REG, SRNG_SR_CECS, &status);
82+
if (status) {
83+
err = WHAL_EINVAL;
84+
goto exit;
85+
}
86+
87+
whal_Reg_Get(reg->base, SRNG_SR_REG, SRNG_SR_DRDY, &status);
88+
} while (!status);
89+
90+
/* Read 32-bit random value */
91+
uint32_t rnd = *(volatile uint32_t *)(reg->base + SRNG_DR_REG);
92+
93+
/* Copy bytes into output buffer */
94+
for (size_t i = 0; i < 4 && offset < rngDataSz; i++, offset++) {
95+
rngData[offset] = (uint8_t)(rnd >> (i * 8));
96+
}
97+
}
98+
99+
exit:
100+
/* Disable the RNG peripheral */
101+
whal_Reg_Update(reg->base, SRNG_CR_REG, SRNG_CR_RNGEN,
102+
whal_SetBits(SRNG_CR_RNGEN, 0));
103+
104+
return err;
105+
}
106+
107+
const whal_RngDriver whal_Stm32wbRng_Driver = {
108+
.Init = whal_Stm32wbRng_Init,
109+
.Deinit = whal_Stm32wbRng_Deinit,
110+
.Generate = whal_Stm32wbRng_Generate,
111+
};

tests/stm32wb/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LDFLAGS = --omagic -static
1010
DEPDIR = .deps/
1111

1212
# Test sources
13-
TEST_SRC = test_main.c test_clock.c test_gpio.c test_flash.c test_timer.c
13+
TEST_SRC = test_main.c test_clock.c test_gpio.c test_flash.c test_timer.c test_rng.c
1414

1515
# Board config and IVT from the example
1616
BOARD_SRC = $(EXAMPLE_DIR)/stm32wb55xx_nucleo.c \

tests/stm32wb/test_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void test_clock(void);
4040
void test_gpio(void);
4141
void test_flash(void);
4242
void test_timer(void);
43+
void test_rng(void);
4344

4445
void main(void)
4546
{
@@ -84,6 +85,7 @@ void main(void)
8485
test_gpio();
8586
test_flash();
8687
test_timer();
88+
test_rng();
8789

8890
WHAL_TEST_SUMMARY();
8991

tests/stm32wb/test_rng.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <stdint.h>
2+
#include <wolfHAL/wolfHAL.h>
3+
#include <wolfHAL/clock/stm32wb_rcc.h>
4+
#include <wolfHAL/rng/stm32wb_rng.h>
5+
#include <wolfHAL/bitops.h>
6+
#include "stm32wb55xx_nucleo.h"
7+
#include "../test.h"
8+
9+
static void test_rng_init_deinit(void)
10+
{
11+
WHAL_ASSERT_EQ(whal_Rng_Init(&g_whalRng), WHAL_SUCCESS);
12+
WHAL_ASSERT_EQ(whal_Rng_Deinit(&g_whalRng), WHAL_SUCCESS);
13+
}
14+
15+
static void test_rng_generate_nonzero(void)
16+
{
17+
uint8_t buf[16] = {0};
18+
int allZero = 1;
19+
20+
whal_Stm32wbRcc_Ext_EnableHsi48(&g_whalClock, 1);
21+
WHAL_ASSERT_EQ(whal_Rng_Init(&g_whalRng), WHAL_SUCCESS);
22+
WHAL_ASSERT_EQ(whal_Rng_Generate(&g_whalRng, buf, sizeof(buf)), WHAL_SUCCESS);
23+
WHAL_ASSERT_EQ(whal_Rng_Deinit(&g_whalRng), WHAL_SUCCESS);
24+
whal_Stm32wbRcc_Ext_EnableHsi48(&g_whalClock, 0);
25+
26+
for (size_t i = 0; i < sizeof(buf); i++) {
27+
if (buf[i] != 0) {
28+
allZero = 0;
29+
break;
30+
}
31+
}
32+
33+
/* 16 zero bytes from a TRNG is astronomically unlikely */
34+
WHAL_ASSERT_EQ(allZero, 0);
35+
}
36+
37+
static void test_rng_generate_unique(void)
38+
{
39+
uint8_t buf1[16] = {0};
40+
uint8_t buf2[16] = {0};
41+
int same = 1;
42+
43+
whal_Stm32wbRcc_Ext_EnableHsi48(&g_whalClock, 1);
44+
WHAL_ASSERT_EQ(whal_Rng_Init(&g_whalRng), WHAL_SUCCESS);
45+
WHAL_ASSERT_EQ(whal_Rng_Generate(&g_whalRng, buf1, sizeof(buf1)), WHAL_SUCCESS);
46+
WHAL_ASSERT_EQ(whal_Rng_Generate(&g_whalRng, buf2, sizeof(buf2)), WHAL_SUCCESS);
47+
WHAL_ASSERT_EQ(whal_Rng_Deinit(&g_whalRng), WHAL_SUCCESS);
48+
whal_Stm32wbRcc_Ext_EnableHsi48(&g_whalClock, 0);
49+
50+
for (size_t i = 0; i < sizeof(buf1); i++) {
51+
if (buf1[i] != buf2[i]) {
52+
same = 0;
53+
break;
54+
}
55+
}
56+
57+
/* Two consecutive 16-byte outputs should differ */
58+
WHAL_ASSERT_EQ(same, 0);
59+
}
60+
61+
void test_rng(void)
62+
{
63+
WHAL_TEST_SUITE_START("rng");
64+
WHAL_TEST(test_rng_init_deinit);
65+
WHAL_TEST(test_rng_generate_nonzero);
66+
WHAL_TEST(test_rng_generate_unique);
67+
WHAL_TEST_SUITE_END();
68+
}

wolfHAL/platform/st/stm32wb55xx.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <wolfHAL/gpio/stm32wb_gpio.h>
88
#include <wolfHAL/uart/stm32wb_uart.h>
99
#include <wolfHAL/flash/stm32wb_flash.h>
10+
#include <wolfHAL/rng/stm32wb_rng.h>
1011

1112
/*
1213
* @file stm32wb55xx.h
@@ -55,6 +56,13 @@
5556
}, \
5657
.driver = &whal_Stm32wbRccPll_Driver
5758

59+
#define WHAL_STM32WB55_RNG_DEVICE \
60+
.regmap = { \
61+
.base = 0x58001000, \
62+
.size = 0x400, \
63+
}, \
64+
.driver = &whal_Stm32wbRng_Driver
65+
5866
#define WHAL_STM32WB55_FLASH_DEVICE \
5967
.regmap = { \
6068
.base = 0x58004000, \
@@ -75,6 +83,10 @@
7583
.regOffset = 0x4C, \
7684
.enableMask = (1 << 1)
7785

86+
#define WHAL_STM32WB55_RNG_CLOCK \
87+
.regOffset = 0x50, \
88+
.enableMask = (1 << 18)
89+
7890
#define WHAL_STM32WB55_FLASH_CLOCK \
7991
.regOffset = 0x50, \
8092
.enableMask = (1 << 25)

0 commit comments

Comments
 (0)