diff --git a/ports/samd/boards/mpconfig_samd51.h b/ports/samd/boards/mpconfig_samd51.h index 1b67b1d02d..d963fe1dd2 100644 --- a/ports/samd/boards/mpconfig_samd51.h +++ b/ports/samd/boards/mpconfig_samd51.h @@ -5,6 +5,9 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_MATH (0) #define MICROPY_PY_CMATH (0) +#define MICROPY_PY_UOS_URANDOM (1) +#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (trng_random_u32()) +unsigned long trng_random_u32(void); // Due to a limitation in the TC counter for us, the ticks period is 2**29 #define MICROPY_PY_UTIME_TICKS_PERIOD (0x20000000) diff --git a/ports/samd/moduos.c b/ports/samd/moduos.c index b1118f0195..e0237fd88f 100644 --- a/ports/samd/moduos.c +++ b/ports/samd/moduos.c @@ -34,6 +34,46 @@ #include "modmachine.h" #include "sam.h" +#if defined(MCU_SAMD51) +static bool initialized = false; + +STATIC void trng_start(void) { + if (!initialized) { + MCLK->APBCMASK.bit.TRNG_ = 1; + REG_TRNG_CTRLA = TRNG_CTRLA_ENABLE; + initialized = true; + } +} + +uint32_t trng_random_u32(void) { + trng_start(); + while ((REG_TRNG_INTFLAG & TRNG_INTFLAG_DATARDY) == 0) { + } + return REG_TRNG_DATA; +} + +#if MICROPY_PY_UOS_URANDOM +STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { + mp_int_t n = mp_obj_get_int(num); + vstr_t vstr; + vstr_init_len(&vstr, n); + uint32_t rngval = 0; + + trng_start(); + for (int i = 0; i < n; i++) { + if ((i % 4) == 0) { + rngval = trng_random_u32(); + } + vstr.buf[i] = rngval & 0xff; + rngval >>= 8; + } + return mp_obj_new_bytes_from_vstr(&vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); + +#endif // MICROPY_PY_UOS_URANDOM +#endif // defined(MCU_SAMD51) + #if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream) { const mp_obj_type_t *type = mp_obj_get_type(stream);