summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobert-hh <robert@hammelrath.com>2022-06-05 21:08:37 +0200
committerDamien George <damien@micropython.org>2022-10-06 22:50:29 +1100
commit45bf25a0022033474b9fe699267297f882ca9772 (patch)
tree3074bc17fbf95735a96f64b7c5ff98395649c8f0
parent15212ae8d423dced7698219def0f2d13287a64b8 (diff)
samd/moduos: Add uos.urandom() for SAMD51.
Based on the hardware RNG.
-rw-r--r--ports/samd/boards/mpconfig_samd51.h3
-rw-r--r--ports/samd/moduos.c40
2 files changed, 43 insertions, 0 deletions
diff --git a/ports/samd/boards/mpconfig_samd51.h b/ports/samd/boards/mpconfig_samd51.h
index 1b67b1d02..d963fe1dd 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 b1118f019..e0237fd88 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);