Skip to content

Instantly share code, notes, and snippets.

@kemerelab
Created March 3, 2025 14:26
Snippet of code which generates a random number using the MSPM0+ TRNG module
__STATIC_INLINE void update_reg(
volatile uint32_t *reg, uint32_t val, uint32_t mask)
{
uint32_t tmp;
tmp = *reg;
tmp = tmp & ~mask;
*reg = tmp | (val & mask);
}
uint32_t GenerateRandomNumber()
{
int randomNumber = 0;
// Power on and initialize TRNG
TRNG->GPRCM.RSTCTL = TRNG_RSTCTL_RESETASSERT_ASSERT | TRNG_RSTCTL_KEY_UNLOCK_W;
TRNG->GPRCM.PWREN = TRNG_PWREN_KEY_UNLOCK_W | TRNG_PWREN_ENABLE_ENABLE;
delay_cycles(POWER_STARTUP_DELAY);
TRNG->CLKDIVIDE = (uint32_t) TRNG_CLKDIVIDE_RATIO_DIV_BY_2;
// Send "Normal Function" command and then wait for it to complete
update_reg(&TRNG->CTL, (uint32_t) TRNG_CTL_CMD_NORM_FUNC, TRNG_CTL_CMD_MASK);
while (!((TRNG->CPU_INT.RIS & TRNG_RIS_IRQ_CMD_DONE_MASK) ==
TRNG_RIS_IRQ_CMD_DONE_SET));
TRNG->CPU_INT.ICLR = TRNG_IMASK_IRQ_CMD_DONE_MASK; // clear interrupt status
update_reg(&TRNG->CTL,
((uint32_t) 0x3 << TRNG_CTL_DECIM_RATE_OFS), // set clock to decimate by 4
TRNG_CTL_DECIM_RATE_MASK);
/* Setup and start a capture, then wait for the result */
while (!((TRNG->CPU_INT.RIS & TRNG_RIS_IRQ_CAPTURED_RDY_MASK) ==
TRNG_RIS_IRQ_CAPTURED_RDY_SET));
TRNG->CPU_INT.ICLR = TRNG_IMASK_IRQ_CAPTURED_RDY_MASK; // clear interrupt status
randomNumber = TRNG->DATA_CAPTURE; // here is our random number!!!
/* Power off the TRNG peripheral */
TRNG->GPRCM.PWREN = TRNG_PWREN_KEY_UNLOCK_W | TRNG_PWREN_ENABLE_DISABLE;
}
@kemerelab
Copy link
Author

The technical reference manual also suggests a number of tests after power on before trying to generate!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment