Skip to content

Commit

Permalink
samd: Add uos.urandom() for SAMD51.
Browse files Browse the repository at this point in the history
Based on the hardware RNG.
  • Loading branch information
robert-hh committed Jun 5, 2022
1 parent 74f18c5 commit 0032510
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ports/samd/boards/mpconfig_samd51.h
Expand Up @@ -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)
Expand Down
42 changes: 42 additions & 0 deletions ports/samd/moduos.c
Expand Up @@ -34,6 +34,48 @@
#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_str_from_vstr(&mp_type_bytes, &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);
Expand Down

0 comments on commit 0032510

Please sign in to comment.