diff options
Diffstat (limited to 'embassy-mcxa/src/trng.rs')
| -rw-r--r-- | embassy-mcxa/src/trng.rs | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/embassy-mcxa/src/trng.rs b/embassy-mcxa/src/trng.rs index ed11019cd..889adee51 100644 --- a/embassy-mcxa/src/trng.rs +++ b/embassy-mcxa/src/trng.rs | |||
| @@ -177,6 +177,8 @@ impl<'d> Trng<'d> { | |||
| 177 | regs().mctl().modify(|_, w| w.prgm().disable()); | 177 | regs().mctl().modify(|_, w| w.prgm().disable()); |
| 178 | 178 | ||
| 179 | let _ = regs().ent(7).read().bits(); | 179 | let _ = regs().ent(7).read().bits(); |
| 180 | |||
| 181 | Self::start(); | ||
| 180 | } | 182 | } |
| 181 | 183 | ||
| 182 | fn start() { | 184 | fn start() { |
| @@ -188,7 +190,11 @@ impl<'d> Trng<'d> { | |||
| 188 | } | 190 | } |
| 189 | 191 | ||
| 190 | fn blocking_wait_for_generation() { | 192 | fn blocking_wait_for_generation() { |
| 191 | while regs().mctl().read().ent_val().bit_is_clear() {} | 193 | while regs().mctl().read().ent_val().bit_is_clear() { |
| 194 | if regs().mctl().read().err().bit_is_set() { | ||
| 195 | regs().mctl().modify(|_, w| w.err().clear_bit_by_one()); | ||
| 196 | } | ||
| 197 | } | ||
| 192 | } | 198 | } |
| 193 | 199 | ||
| 194 | fn fill_chunk(chunk: &mut [u8]) { | 200 | fn fill_chunk(chunk: &mut [u8]) { |
| @@ -211,45 +217,36 @@ impl<'d> Trng<'d> { | |||
| 211 | return; // nothing to fill | 217 | return; // nothing to fill |
| 212 | } | 218 | } |
| 213 | 219 | ||
| 214 | Self::start(); | ||
| 215 | for chunk in buf.chunks_mut(32) { | 220 | for chunk in buf.chunks_mut(32) { |
| 216 | Self::blocking_wait_for_generation(); | 221 | Self::blocking_wait_for_generation(); |
| 217 | Self::fill_chunk(chunk); | 222 | Self::fill_chunk(chunk); |
| 218 | } | 223 | } |
| 219 | Self::stop(); | ||
| 220 | } | 224 | } |
| 221 | 225 | ||
| 222 | /// Return a random u32, blocking version. | 226 | /// Return a random u32, blocking version. |
| 223 | pub fn blocking_next_u32(&mut self) -> u32 { | 227 | pub fn blocking_next_u32(&mut self) -> u32 { |
| 224 | Self::start(); | ||
| 225 | Self::blocking_wait_for_generation(); | 228 | Self::blocking_wait_for_generation(); |
| 226 | let result = regs().ent(0).read().bits(); | ||
| 227 | |||
| 228 | // New random bytes are generated only after reading ENT7 | 229 | // New random bytes are generated only after reading ENT7 |
| 229 | let _ = regs().ent(7).read().bits(); | 230 | regs().ent(7).read().bits() |
| 230 | Self::stop(); | ||
| 231 | |||
| 232 | result | ||
| 233 | } | 231 | } |
| 234 | 232 | ||
| 235 | /// Return a random u64, blocking version. | 233 | /// Return a random u64, blocking version. |
| 236 | pub fn blocking_next_u64(&mut self) -> u64 { | 234 | pub fn blocking_next_u64(&mut self) -> u64 { |
| 237 | Self::start(); | ||
| 238 | Self::blocking_wait_for_generation(); | 235 | Self::blocking_wait_for_generation(); |
| 239 | 236 | ||
| 240 | let mut result = u64::from(regs().ent(0).read().bits()) << 32; | 237 | let mut result = u64::from(regs().ent(6).read().bits()) << 32; |
| 241 | result |= u64::from(regs().ent(1).read().bits()); | ||
| 242 | |||
| 243 | // New random bytes are generated only after reading ENT7 | 238 | // New random bytes are generated only after reading ENT7 |
| 244 | let _ = regs().ent(7).read().bits(); | 239 | result |= u64::from(regs().ent(7).read().bits()); |
| 245 | Self::stop(); | ||
| 246 | |||
| 247 | result | 240 | result |
| 248 | } | 241 | } |
| 249 | } | 242 | } |
| 250 | 243 | ||
| 251 | impl Drop for Trng<'_> { | 244 | impl Drop for Trng<'_> { |
| 252 | fn drop(&mut self) { | 245 | fn drop(&mut self) { |
| 246 | // wait until allowed to stop | ||
| 247 | while regs().mctl().read().tstop_ok().bit_is_clear() {} | ||
| 248 | // stop | ||
| 249 | Self::stop(); | ||
| 253 | // reset the TRNG | 250 | // reset the TRNG |
| 254 | regs().mctl().write(|w| w.rst_def().set_bit()); | 251 | regs().mctl().write(|w| w.rst_def().set_bit()); |
| 255 | } | 252 | } |
| @@ -394,10 +391,8 @@ impl<'d> AsyncTrng<'d> { | |||
| 394 | pub async fn async_next_u32(&mut self) -> Result<u32, Error> { | 391 | pub async fn async_next_u32(&mut self) -> Result<u32, Error> { |
| 395 | Trng::start(); | 392 | Trng::start(); |
| 396 | Self::wait_for_generation().await?; | 393 | Self::wait_for_generation().await?; |
| 397 | let result = regs().ent(0).read().bits(); | ||
| 398 | |||
| 399 | // New random bytes are generated only after reading ENT7 | 394 | // New random bytes are generated only after reading ENT7 |
| 400 | let _ = regs().ent(7).read().bits(); | 395 | let result = regs().ent(7).read().bits(); |
| 401 | Trng::stop(); | 396 | Trng::stop(); |
| 402 | 397 | ||
| 403 | Ok(result) | 398 | Ok(result) |
| @@ -408,11 +403,10 @@ impl<'d> AsyncTrng<'d> { | |||
| 408 | Trng::start(); | 403 | Trng::start(); |
| 409 | Self::wait_for_generation().await?; | 404 | Self::wait_for_generation().await?; |
| 410 | 405 | ||
| 411 | let mut result = u64::from(regs().ent(0).read().bits()) << 32; | 406 | let mut result = u64::from(regs().ent(6).read().bits()) << 32; |
| 412 | result |= u64::from(regs().ent(1).read().bits()); | ||
| 413 | |||
| 414 | // New random bytes are generated only after reading ENT7 | 407 | // New random bytes are generated only after reading ENT7 |
| 415 | let _ = regs().ent(7).read().bits(); | 408 | result |= u64::from(regs().ent(7).read().bits()); |
| 409 | |||
| 416 | Trng::stop(); | 410 | Trng::stop(); |
| 417 | 411 | ||
| 418 | Ok(result) | 412 | Ok(result) |
| @@ -508,7 +502,6 @@ impl Handler<typelevel::TRNG0> for InterruptHandler { | |||
| 508 | .intg_flt() | 502 | .intg_flt() |
| 509 | .clear_bit() | 503 | .clear_bit() |
| 510 | }); | 504 | }); |
| 511 | |||
| 512 | WAIT_CELL.wake(); | 505 | WAIT_CELL.wake(); |
| 513 | } | 506 | } |
| 514 | } | 507 | } |
