mciantyre / teensy4-rs

Rust support for the Teensy 4
Apache License 2.0
271 stars 31 forks source link

`Trng` keeps delivering the same 16 numbers #138

Closed Finomnis closed 1 year ago

Finomnis commented 1 year ago

Describe the bug The Trng keeps delivering the same 16 u32 values.

To Reproduce The following code is used to reproduce the problem:

#![no_std]
#![no_main]

use teensy4_bsp as bsp;
use teensy4_panic as _;

use bsp::board;

/// How frequently (milliseconds) should we make a random number?
const MAKE_LOG_INTERVAL_MS: u32 = board::PERCLK_FREQUENCY / 1_000 * 250;

const ENABLE_WORKAROUND: bool = false;

#[bsp::rt::entry]
fn main() -> ! {
    let board::Resources {
        pit: (_, _, mut make_log, _),
        trng,
        mut dma,
        lpuart2,
        pins,
        mut gpio2,
        mut ccm,
        ..
    } = board::t40(board::instances());

    let led = board::led(&mut gpio2, pins.p13);

    let log_dma = dma[0].take().unwrap();
    let log_uart = board::lpuart(lpuart2, pins.p14, pins.p15, 115200);

    let mut poller =
        imxrt_log::log::lpuart(log_uart, log_dma, imxrt_log::Interrupts::Enabled).unwrap();

    make_log.set_load_timer_value(MAKE_LOG_INTERVAL_MS);
    make_log.set_interrupt_enable(false);
    make_log.enable();

    bsp::hal::ccm::clock_gate::trng().set(&mut ccm, bsp::hal::ccm::clock_gate::ON);

    let mut trng = if ENABLE_WORKAROUND {
        let rng = trng.release_disabled();
        bsp::hal::trng::Trng::new(rng, Default::default(), Default::default())
    } else {
        trng
    };

    loop {
        poller.poll();
        if make_log.is_elapsed() {
            led.toggle();
            while make_log.is_elapsed() {
                make_log.clear_elapsed();
            }

            let random = trng.next_u32();
            log::info!("Random number: {random:?}");
            log::info!("Rng: {:?}", trng);
        }
    }
}

In my case, this produces:

[INFO rng_base]: Random number: Ok(568509518)
[INFO rng_base]: Rng: TRNG { block: [568509518, 2577880531, 4243065456, 1025543875, 646633278, 4068880148, 3799665949, 2924340652, 1575603316, 2839279256, 928035811, 2823418292, 1945690789, 2591390730, 892649315, 58194871], index: 1 }
[INFO rng_base]: Random number: Ok(2577880531)
[INFO rng_base]: Rng: TRNG { block: [568509518, 2577880531, 4243065456, 1025543875, 646633278, 4068880148, 3799665949, 2924340652, 1575603316, 2839279256, 928035811, 2823418292, 1945690789, 2591390730, 892649315, 58194871], index: 2 }

...

[INFO rng_base]: Random number: Ok(58194871)
[INFO rng_base]: Rng: TRNG { block: [568509518, 2577880531, 4243065456, 1025543875, 646633278, 4068880148, 3799665949, 2924340652, 1575603316, 2839279256, 928035811, 2823418292, 1945690789, 2591390730, 892649315, 58194871], index: 16 }
[INFO rng_base]: Random number: Ok(568509518)
[INFO rng_base]: Rng: TRNG { block: [568509518, 2577880531, 4243065456, 1025543875, 646633278, 4068880148, 3799665949, 2924340652, 1575603316, 2839279256, 928035811, 2823418292, 628674660, 671426372, 226385925, 161814576], index: 1 }
[INFO rng_base]: Random number: Ok(2577880531)
[INFO rng_base]: Rng: TRNG { block: [568509518, 2577880531, 4243065456, 1025543875, 646633278, 4068880148, 3799665949, 2924340652, 1575603316, 2839279256, 928035811, 2823418292, 628674660, 671426372, 226385925, 161814576], index: 2 }

... repeats ...

Expected behavior The expectation is that whenever the index reaches 16, new random numbers get generated.

Additional context It seems that configuring the Trng before its clock gate is enabled causes it to misbehave.

Setting ENABLE_WORKAROUND to true in the example fixes the problem by re-initializing the Trng.