profile
viewpoint
Ian McIntyre mciantyre Pittsburgh

mciantyre/teensy4-rs 69

Rust support for the Teensy 4

mciantyre/mock-smbus-arduino 5

Pretend like your Arduino is an SMBUS battery

imxrt-rs/imxrt-boot-gen 2

Generate data structures for booting iMXRT processors

mciantyre/ladderlogic 2

Ladder Logic graphical parser, written in Haskell

mciantyre/python-hospital-simulator 2

Teaching Python to BioEs, or teaching BioEs to Python

mciantyre/scipy-opencv-notebook 2

Jupyter's scipy-notebook Docker image from jupyter/docker-stacks, plus OpenCV

mciantyre/simple-stl-render 2

Simple STL viewer in the browser

ebelski/rust-copter 1

A quadcopter build using a Teensy running Rust and some other cool stuff that's yet to be determined.

mciantyre/LabVLC 1

Programmatic video playback and control in LabVIEW using VLC

mciantyre/teensy4-rs-template 1

A cargo-generate template for Teensy 4 projects

startedmciantyre/teensy4-rs

started time in 10 hours

startedmciantyre/teensy4-rs

started time in 19 hours

create barnchimxrt-rs/imxrt-async-hal

branch : gh-pages

created branch time in 2 days

startedmciantyre/teensy4-rs

started time in 2 days

push eventmciantyre/teensy4-rs

mciantyre

commit sha 6e2f6252ab233958021d8ade9b67431bc3c0c7ca

deploy: 71e860d9f0ef2ab3281bc88f4e6fe8048238339e

view details

push time in 3 days

push eventmciantyre/teensy4-rs

mciantyre

commit sha 33852a2ed98f1ee8ad05a0b13238c62934c8c66f

deploy: a5fd3e8ee9413527ce635f87b35b0bd65f3c022c

view details

push time in 6 days

startedmciantyre/teensy4-rs

started time in 7 days

PR opened imxrt-rs/imxrt-hal

Fix comment, don't preserve bad value in TRNG disable

Woke up today and almost immediately realized that 0 is not inside the range 1..=15. Woops.

I doubt this code change will actually matter, since users can't set a 0 retry count, but I didn't want to leave an incorrect comment laying around.

+1 -1

0 comment

1 changed file

pr created time in 9 days

issue commentimxrt-rs/imxrt-async-hal

Forgettable Futures

Requiring an Arc seems like the solution here to me

mciantyre

comment created time in 10 days

pull request commentimxrt-rs/imxrt-hal

Implement basic support for the TRNG

This looks good to me as well

AlyoshaVasilieva

comment created time in 11 days

PR opened imxrt-rs/imxrt-hal

Only allow HAL to create I2C/SPI config errors

These errors are only valid if the HAL is creating them, so don't allow users to create them. Pretty minor.

+9 -9

0 comment

2 changed files

pr created time in 12 days

pull request commentimxrt-rs/imxrt-hal

Implement basic support for the TRNG

My original expectation for disable is that a user might turn the TRNG on, grab some entropy, feed it into a PRNG, and then turn the TRNG off for the rest of operation to preserve some tiny amount of power. But it's possible they may want to turn it back on if they are doing cryptographic work and want more entropy. So, added preservation of settings. Rather than preserving them on the struct, I retrieve them from the registers during disable; this efficiency-complexity tradeoff may not be worth it, so I'll switch to just storing the settings on the TRNG struct if you'd prefer.

AlyoshaVasilieva

comment created time in 12 days

Pull request review commentimxrt-rs/imxrt-hal

Implement basic support for the TRNG

+//! True Random Number Generator (TRNG)+//!+//! Provides basic support for the True Random Number Generator. The TRNG generates truly random+//! data and is intended for use as a generator of entropy.+//!+//! The TRNG is fairly slow - 15 minutes to an hour to generate 1 megabyte - so it probably+//! should only be used to generate a relatively small amount of entropy for a cryptographic+//! algorithm. Occasionally retrieving entropy from it won't necessarily need to block, as+//! this driver retrieves 512 bits at a time.+//!+//! ## RngCore Support+//!+//! When the crate feature `rand_core` is enabled, the TRNG can be wrapped in a struct that+//! implements [`rand_core`][rand_core]'s `RngCore` trait (via `into_rng()`). The [`rand`][rand]+//! crate's `Rng` trait automatically implements high-level functions on top of `RngCore`.+//!+//! This feature is opt-in because Cargo's current feature resolution may trigger a build failure+//! (or require the use of an [unstable Cargo feature][nfr]) if any dev-dependency has enabled the+//! `std` feature of `rand_core`.+//!+//! Note that only the `try_fill_bytes` function of `RngCore` allows reporting an error. The others+//! will panic if the TRNG reports an error. Errors appear to be extremely rare in the default+//! configuration (none were seen over 3GB of data), but it's possible they will be more common in+//! certain situations, such as extreme temperatures or an inconsistent power supply. The non-public+//! Security Reference Manual may have more information.+//!+//! If you intend to use the `RngCore` wrapper, you should increase the+//! [retry count](Unclocked::set_retry_count) before clocking the TRNG.+//!+//! [rand_core]: https://crates.io/crates/rand_core+//! [rand]: https://crates.io/crates/rand+//! [nfr]: https://github.com/rust-lang/cargo/issues/7916++use core::fmt;++use embedded_hal::blocking::rng::Read;++use crate::ccm;+use crate::ral::trng::{self, Instance};+use crate::ral::{self, modify_reg, read_reg, write_reg};++/// The TRNG, not yet enabled.+pub struct Unclocked {+    reg: Instance,+    sample_mode: SampleMode,+    retry_count: u32,+}++impl Unclocked {+    pub(crate) fn new(trng: Instance) -> Self {+        Unclocked {+            reg: trng,+            sample_mode: Default::default(),+            retry_count: 1, // _DEFAULT_RETRY_COUNT+        }+    }++    /// Set the `SampleMode`.+    pub fn set_sample_mode(&mut self, mode: SampleMode) {+        self.sample_mode = mode;+    }++    /// Set the number of times to retry after a test failure before an error is declared.+    ///+    /// Valid range `1..=15`. Defaults to `1`.+    pub fn set_retry_count(&mut self, retry_count: u32) -> Result<(), InvalidRetryCountError> {+        if (1..=15).contains(&retry_count) {+            self.retry_count = retry_count;+            Ok(())+        } else {+            Err(InvalidRetryCountError)+        }+    }++    /// Clock and configure the True Random Number Generator with default settings,+    /// plus the settings contained in this `Unclocked` struct.+    pub fn clock(self, ccm: &mut ccm::Handle) -> TRNG {+        // Not supported: locking TRNG to prevent programmability.+        // A number of things here are likely configurable if you have access to the SRM.+        // Without it only limited configuration is safe. Garbage configs lead to endless errors.++        let (ccm, _) = ccm.raw();+        modify_reg!(ral::ccm, ccm, CCGR6, CG6: 0b11); // trng_clk_enable+        modify_reg!(trng, self.reg, MCTL, PRGM: 1);+        modify_reg!(trng, self.reg, MCTL, RST_DEF: 1);+        // enter program mode and reset to defaults+        // it isn't clear what defaults it actually sets, so let's set the tests manually++        // All these values are sourced only from the #defines in the MCUXpresso TRNG driver for the+        // IMXRT1062. The doc comments contain both typos and completely wrong values.++        write_reg!(trng, self.reg, SCMISC, RTY_CT: self.retry_count, LRUN_MAX: 34); // _RUN_MAX_LIMIT++        // Note: The SDK uses _MAX and _MIN for values, but the registers use the max value and a+        // range. The SDK _MIN values are expressed as (max - range), making it easy to ensure+        // that these values are correct.+        write_reg!(trng, self.reg, SCM, MONO_MAX: 1384, MONO_RNG: 268); // _MONOBIT_+        write_reg!(trng, self.reg, SCR1, RUN1_MAX: 405, RUN1_RNG: 178); // _RUNBIT1_+        write_reg!(trng, self.reg, SCR2, RUN2_MAX: 220, RUN2_RNG: 122); // _RUNBIT2_+        write_reg!(trng, self.reg, SCR3, RUN3_MAX: 125, RUN3_RNG: 88); // _RUNBIT3_+        write_reg!(trng, self.reg, SCR4, RUN4_MAX: 75, RUN4_RNG: 64); // _RUNBIT4_+        write_reg!(trng, self.reg, SCR5, RUN5_MAX: 47, RUN5_RNG: 46); // _RUNBIT5_+        write_reg!(trng, self.reg, SCR6P, RUN6P_MAX: 47, RUN6P_RNG: 46); // _RUNBIT6PLUS_++        write_reg!(trng, self.reg, PKR, PKR_MAX: 26912); // _POKER_MAXIMUM+        write_reg!(trng, self.reg, PKRRNG, PKR_RNG: 2467);++        write_reg!(trng, self.reg, FRQ, FRQ_MAX: 25600); // _FREQUENCY_MAXIMUM+        write_reg!(trng, self.reg, FRQMIN, FRQ_MIN: 1600); // _FREQUENCY_MINIMUM++        write_reg!(trng, self.reg, SDCTL, SAMP_SIZE: 2500, ENT_DLY: 3200); // _SAMPLE_SIZE, _ENTROPY_DELAY+        write_reg!(trng, self.reg, SBLIM, SB_LIM: 63); // _SPARSE_BIT_LIMIT++        // set sample mode, exit program mode+        modify_reg!(trng, self.reg, MCTL, SAMP_MODE: self.sample_mode as u32);+        modify_reg!(trng, self.reg, MCTL, PRGM: 0);+        // for 1015, 1021, maybe other non i.MX chips: set TRNG_ACC to 1 here+        read_reg!(trng, self.reg, ENT15);+        // reading ENT15 triggers new entropy generation+        TRNG::new(self.reg)+    }+}++/// TRNG sampling mode+#[derive(Copy, Clone, Debug, PartialEq, Eq)]+#[repr(u32)]+pub enum SampleMode {+    /// von Neumann data in both entropy shifter and statistical checks. Approximately 4x slower+    /// than the other modes.+    VonNeumann = trng::MCTL::SAMP_MODE::RW::SAMP_MODE_0,+    /// Raw data in both entropy shifter and statistical checks. Likely lower quality than the+    /// other two modes.+    Raw = trng::MCTL::SAMP_MODE::RW::SAMP_MODE_1,+    /// von Neumann data in entropy shifter, raw data in statistical checks+    VonNeumannRaw = trng::MCTL::SAMP_MODE::RW::SAMP_MODE_2,+}++impl Default for SampleMode {+    /// Returns `VonNeumannRaw`.+    fn default() -> Self {+        // "Set sample mode of the TRNG ring oscillator to Von Neumann, for better random data.+        // It is optional." <- SDK, explaining why they set sample mode to 0 (VN)+        // Teensyduino uses VNRaw, the reason appears to be this post:+        // https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=195000&viewfull=1#post195000+        // VNRaw appears to produce equivalent quality output and is ~4x faster than VN.+        // As such, VonNeumannRaw is the default SampleMode here.+        Self::VonNeumannRaw+    }+}++/// The True Random Number Generator.+pub struct TRNG {+    reg: Instance,+    block: [u32; 16],+    index: usize,+}++impl fmt::Debug for TRNG {+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {+        f.debug_struct("TRNG")+            .field("block", &self.block)+            .field("index", &self.index)+            .finish()+    }+}++impl TRNG {+    fn new(reg: Instance) -> Self {+        Self {+            reg,+            block: [0; 16],+            index: 16, // equal to len, to trigger immediate retrieval+        }+    }++    /// Return the next `u32` available. May need to retrieve another block of random numbers.+    pub fn next_u32(&mut self) -> nb::Result<u32, Error> {+        self.retrieve_if_needed()?;+        let data = nb::Result::Ok(self.block[self.index]);+        self.index += 1;+        data+    }++    /// Retrieve another block of random numbers if we've used them all up.+    fn retrieve_if_needed(&mut self) -> nb::Result<(), Error> {+        if self.index >= self.block.len() {+            self.retrieve()?;+            self.index = 0;+        }+        Ok(())+    }++    /// Retrieve another block of random numbers.+    fn retrieve(&mut self) -> nb::Result<(), Error> {+        let mctl = read_reg!(trng, self.reg, MCTL);+        if (mctl & trng::MCTL::ERR::mask) != 0 {+            let flags = self.get_error_flags();+            write_reg!(trng, self.reg, MCTL, mctl); // write reg back to clear error+            return Err(nb::Error::Other(Error(flags)));+        }+        if (mctl & trng::MCTL::ENT_VAL::mask) == 0 {+            return Err(nb::Error::WouldBlock); // not ready to read entropy+        }+        self.block[0] = read_reg!(trng, self.reg, ENT0);+        self.block[1] = read_reg!(trng, self.reg, ENT1);+        self.block[2] = read_reg!(trng, self.reg, ENT2);+        self.block[3] = read_reg!(trng, self.reg, ENT3);+        self.block[4] = read_reg!(trng, self.reg, ENT4);+        self.block[5] = read_reg!(trng, self.reg, ENT5);+        self.block[6] = read_reg!(trng, self.reg, ENT6);+        self.block[7] = read_reg!(trng, self.reg, ENT7);+        self.block[8] = read_reg!(trng, self.reg, ENT8);+        self.block[9] = read_reg!(trng, self.reg, ENT9);+        self.block[10] = read_reg!(trng, self.reg, ENT10);+        self.block[11] = read_reg!(trng, self.reg, ENT11);+        self.block[12] = read_reg!(trng, self.reg, ENT12);+        self.block[13] = read_reg!(trng, self.reg, ENT13);+        self.block[14] = read_reg!(trng, self.reg, ENT14);+        self.block[15] = read_reg!(trng, self.reg, ENT15);+        // this can probably be written as a loop with unsafe code+        read_reg!(trng, self.reg, ENT0);+        // SDK (fsl_trng.c):+        //     Dummy read. Defect workaround.+        //     TRNG could not clear ENT_VAL flag automatically, application+        //     had to do a dummy reading operation for anyone TRNG register+        //     to clear it firstly, then to read the RTENT0 to RTENT15 again+        // This appears unnecessary on the 1062? done anyway in case it's necessary for another chip+        Ok(())+    }++    /// Retrieve all known error flags.+    fn get_error_flags(&self) -> ErrorFlags {+        let status = read_reg!(trng, self.reg, STATUS) & 0xFFFF;+        // all the error flags in STATUS are in the low 16 bits+        let mut flags = ErrorFlags::from_bits_truncate(status);+        flags.set(+            ErrorFlags::FCT_FAIL,+            read_reg!(trng, self.reg, MCTL, FCT_FAIL) == 1,+        );+        flags+    }++    /// Disable the TRNG and its clock.+    pub fn disable(self, ccm: &mut ccm::Handle) -> Unclocked {+        let (ccm, _) = ccm.raw();+        modify_reg!(trng, self.reg, MCTL, PRGM: 1);+        while read_reg!(trng, self.reg, MCTL, TSTOP_OK) == 0 {+            core::sync::atomic::spin_loop_hint();+        }+        // need to wait for TSTOP_OK before disabling clock or the ring oscillator will keep running+        modify_reg!(ral::ccm, ccm, CCGR6, CG6: 0); // disable trng clock+        Unclocked::new(self.reg)+    }++    /// Wrap the TRNG in a struct that implements `rand_core`'s `RngCore` trait.+    #[cfg(feature = "rand_core")]+    pub fn into_rng(self) -> RngCoreWrapper {+        RngCoreWrapper(self)+    }+}++/// Wrapper struct around [`TRNG`] that implements `RngCore`.+#[cfg(feature = "rand_core")]+pub struct RngCoreWrapper(TRNG);++#[cfg(feature = "rand_core")]+impl RngCoreWrapper {+    /// Deconstruct this wrapper and return the TRNG struct.+    pub fn into_inner(self) -> TRNG {+        self.0+    }+}++#[cfg(feature = "rand_core")]+impl rand_core::RngCore for RngCoreWrapper {+    /// Return the next random `u32`.+    ///+    /// # Panics+    ///+    /// Panics if the TRNG returns an error.+    fn next_u32(&mut self) -> u32 {+        let mut bytes = [0; 4];+        self.fill_bytes(&mut bytes);+        u32::from_be_bytes(bytes)+    }++    /// Return the next random `u64`.+    ///+    /// # Panics+    ///+    /// Panics if the TRNG returns an error.+    fn next_u64(&mut self) -> u64 {+        let mut bytes = [0; 8];+        self.fill_bytes(&mut bytes);+        u64::from_be_bytes(bytes)+    }++    /// Fill `dest` with random data.+    ///+    /// # Panics+    ///+    /// Panics if the TRNG returns an error.+    fn fill_bytes(&mut self, dest: &mut [u8]) {+        self.try_fill_bytes(dest).expect("TRNG returned an error")+    }++    /// Fill `dest` with random data.+    ///+    /// If an error occurs, the error's `code` will be identical to the [`ErrorFlags`] that this+    /// driver would have reported. If none of them were set, the `code` will have only the highest+    /// bit set (which does not correspond to any flag).+    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {+        // defer to Read implementation, converting error to rand_core's Error+        self.0.read(dest).map_err(|e| {+            let code = if e.0.bits == 0 { 1 << 31 } else { e.0.bits };+            // Safety: Highest bit is set above if no flags were set.+            unsafe { core::num::NonZeroU32::new_unchecked(code).into() }+        })+    }+}++impl Read for TRNG {+    type Error = Error;+    // e-h RNG Read is a *blocking* trait, so no WouldBlock here+    // Read is part of the unproven API and will likely be changed in the future++    fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> {+        let mut data = [0; 4];+        let mut index = 4;+        for b in buffer.iter_mut() {+            if index == 4 {+                data = nb::block!(self.next_u32())?.to_be_bytes();+                index = 0;+            }+            *b = data[index];+            index += 1;+        }+        Ok(())+    }+}++/// A TRNG error occurred, such as a statistical test failing.+#[derive(Copy, Clone, Debug, PartialEq)]+pub struct Error(pub ErrorFlags);++bitflags::bitflags! {+    /// Specific errors that may occur during entropy generation+    pub struct ErrorFlags : u32 {+        // STATUS register starts here (automatically set from bits)+        /// 1-bit run sampling 0s test failed+        const TF1BR0 = 1 << 0;+        /// 1-bit run sampling 1s test failed+        const TF1BR1 = 1 << 1;+        /// 2-bit run sampling 0s test failed+        const TF2BR0 = 1 << 2;+        /// 2-bit run sampling 1s test failed+        const TF2BR1 = 1 << 3;+        /// 3-bit run sampling 0s test failed+        const TF3BR0 = 1 << 4;+        /// 3-bit run sampling 1s test failed+        const TF3BR1 = 1 << 5;+        /// 4-bit run sampling 0s test failed+        const TF4BR0 = 1 << 6;+        /// 4-bit run sampling 1s test failed+        const TF4BR1 = 1 << 7;+        /// 5-bit run sampling 0s test failed+        const TF5BR0 = 1 << 8;+        /// 5-bit run sampling 1s test failed+        const TF5BR1 = 1 << 9;+        /// 6-plus-bit run sampling 0s test failed+        const TF6PBR0 = 1 << 10;+        /// 6-plus-bit run sampling 1s test failed+        const TF6PBR1 = 1 << 11;+        /// Sparse bit test failed+        const TFSB = 1 << 12;+        /// Long run test failed+        const TFLR = 1 << 13;+        /// Poker test failed+        const TFP = 1 << 14;+        /// Mono bit test failed+        const TFMB = 1 << 15;+        // MCTL register starts here (set manually)+        /// Count taken during entropy generation was outside the defined range of FRQ_MIN to FRQ_MAX+        const FCT_FAIL = 1 << 16;+    }+}++impl fmt::Display for Error {+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {+        write!(f, "An error occurred in the TRNG module")+    }+}++/// The specified retry count was outside of the valid range of `1..=15`.+#[derive(Copy, Clone, Debug)]+pub struct InvalidRetryCountError;

Thanks for catching that! Wasn't paying enough attention.

The config errors of I2C and SPI (ClockSpeedError, PinLowTimeoutError, BusIdleTimeoutError, ModeError) are also missing the private empty tuple. (I think I just mimicked them without using my brain.) Will make a PR to also make those unconstructible.

Added a slightly modified version of that test. With the (()) suffix it passed on both the wrongly constructible error and the correct private error.

AlyoshaVasilieva

comment created time in 12 days

startedmciantyre/teensy4-rs

started time in 12 days

pull request commentimxrt-rs/imxrt-hal

Implement basic support for the TRNG

Added optional RngCore impl. Open to opinions on the struct's name. (Can't be an optional implementation on the original TRNG struct unless the original next_u32 has its name changed, maybe to try_next_u32; that's also one way forward.)

I used intradoc links in a couple places of the documentation. They aren't stable yet, but their stabilization is occurring with Rust 1.48 (around five days from now). TRNG docs render fine on beta.

AlyoshaVasilieva

comment created time in 13 days

pull request commentimxrt-rs/imxrt-hal

Implement basic support for the TRNG

There's two issues with supporting RngCore that I know of:

  1. Cargo's current feature resolver unifies dependency features, so a dev-dep that enables rand_core's std feature (apparently fairly common) will cause a build failure unless using Cargo's unstable new feature resolver is used. Easy workaround: Make the RngCore implementation opt-in by a crate feature, with a note somewhere to warn users.
  2. The only function in RngCore that allows reporting errors is try_fill_bytes. While I never saw a TRNG error unless triggering one with bad settings, I don't know how rare they really are. Error handling would therefore be limited to either panicking on error or looping to wait for an Ok result. Maybe retry a few times then panic?

I'll add an RngCore implementation (probably as a wrapper created by into_rng on the TRNG struct) sometime soon, since interoperability with a more common RNG abstraction is useful. Do you have an opinion on which method to use for error handling? I'll probably go for a limited number of retries (some approximate fraction of a second) followed by a panic.

AlyoshaVasilieva

comment created time in 13 days

push eventimxrt-rs/imxrt-hal

Tom Burdick

commit sha cadd785e428664132195bad014e9cc727069d8dc

Update README.md Updates README.md for a imxrt-ral free repo, a repo renamed imxrt-hal

view details

push time in 14 days

delete branch imxrt-rs/imxrt-rs

delete branch : remove_imxrt_ral

delete time in 14 days

push eventimxrt-rs/imxrt-rs

Tom Burdick

commit sha 8b902f27087db4b8afac786a2e5f1fcc664c0d87

Removes imxrt-ral from repo and splits out This does not remove the imxrt-ral history

view details

push time in 14 days

PR merged imxrt-rs/imxrt-rs

Removes imxrt-ral from repo and splits out

This does not remove the imxrt-ral history from this repo as its intertwined anyways. The new imxrt-ral repo used filter-repo to only keep imxrt-ral history though.

fixes #95

+10 -2246373

0 comment

568 changed files

bfrog

pr closed time in 14 days

issue closedimxrt-rs/imxrt-rs

Move imxrt-ral into its own repository

#94 will separate the imxrt-iomuxc crate into a separate repo. We'll also publish foundational, chip-specific crates into separate imxrt-rs repositories. See the issue to understand what a foundational, chip-specific crate means.

Once #94 is complete, this repository will contain a variety of HALs, and imxrt-ral, or the "RAL." #94 notes that maintaining the RAL in this repository is inconsistent with the rest of our organization. So, we may consider moving it into its own repository.

Move imxrt-ral into imxrt-rs/imxrt-ral so that its development, testing, and release may be managed separate of the HALs.

closed time in 14 days

mciantyre

pull request commentimxrt-rs/imxrt-rs

Implement basic support for the TRNG

Very cool addition! I wonder if this could implement std::rand::RngCore so it could be used with the std rand module? Doesn't seem too far off, would need an impl for next_u64, fill_bytes, and try_fill_bytes in addition to the already existing next_u32

https://docs.rs/rand/0.7.3/rand/trait.RngCore.html

AlyoshaVasilieva

comment created time in 14 days

PR opened imxrt-rs/imxrt-rs

Implement basic support for the TRNG

This adds support for the True Random Number Generator. It has a bunch of configurable things, few of which are safe to touch without reading the Security Reference Manual. The SRM requires a licensing agreement (and NDA) with NXP, so this is written with reference to the MCUXpresso SDK.

I think this driver should work for any i.MX chip other than the 1015 and 1021, which need TRNG_ACC in MCTL set to 1 after entering run mode. That field doesn't exist on other i.MX RT chips (it's UNUSED5). I think everything else is identical for the imxrt chips.

The output passes dieharder and practrand (out to 2GB, anyway). The TRNG is very slow and it took weeks to generate that much data.

This retrieves all 512 bits of entropy at once from the TRNG, rather than reading 32 bits at a time. This is done for two reasons:

  1. I don't know how to cleanly write it that way
  2. Reading the final register triggers new entropy generation, so this way using the entropy slowly won't ever actually block. Cost: 68 bytes of RAM.

Includes support for embedded-hal's RNG Read trait, which may change in 1.0.

Disabling the TRNG is slightly weird so I implemented support for that.

Hopefully I didn't miss anything in this.

+317 -0

0 comment

2 changed files

pr created time in 14 days

issue commentimxrt-rs/imxrt-rs

Clock configuration for i.MX RT 1011, 1015, and 1021

I don't think this is really an issue here anymore but in the imxrt-ccm repo

bfrog

comment created time in 14 days

issue closedimxrt-rs/imxrt-rs

Clock configuration for i.MX RT 1011, 1015, and 1021

Currently clock configuration is pretty specific to imxrt106x series chips (perhaps works with 105x)

For 101x there is no PLL_ARM, and the DCDC is set incorrectly, it should be setup to 1.5V

The mcuxpresso sdk has good examples of clock config that can be used for the logic flow to accomodate that.

closed time in 14 days

bfrog

issue openedimxrt-rs/imxrt-ral

Move issues related to RAL here

created time in 14 days

PR opened imxrt-rs/imxrt-rs

Reviewers
Removes imxrt-ral from repo and splits out

This does not remove the imxrt-ral history from this repo as its intertwined anyways. The new imxrt-ral repo used filter-repo to only keep imxrt-ral history though.

fixes #95

+10 -2246373

0 comment

568 changed files

pr created time in 15 days

create barnchimxrt-rs/imxrt-rs

branch : remove_imxrt_ral

created branch time in 15 days

push eventimxrt-rs/imxrt-ral

Tom Burdick

commit sha aae64342e2cb7491707776fd9cc70b100f8d00c9

Github action fixes for split repo

view details

push time in 15 days

created tagimxrt-rs/imxrt-ral

tag0.4.1

Register Access Layer for i.MX RT Microcontrollers

created time in 15 days

more