diff options
| -rw-r--r-- | embassy-stm32/src/rng.rs | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 30816e436..0979dce8c 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs | |||
| @@ -119,7 +119,31 @@ impl<'d, T: Instance> Rng<'d, T> { | |||
| 119 | 119 | ||
| 120 | pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { | 120 | pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { |
| 121 | for chunk in dest.chunks_mut(4) { | 121 | for chunk in dest.chunks_mut(4) { |
| 122 | let bits = T::regs().sr().read(); | 122 | let mut bits = T::regs().sr().read(); |
| 123 | if !bits.seis() && !bits.ceis() && !bits.drdy() { | ||
| 124 | // wait for interrupt | ||
| 125 | poll_fn(|cx| { | ||
| 126 | // quick check to avoid registration if already done. | ||
| 127 | let bits = T::regs().sr().read(); | ||
| 128 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 129 | return Poll::Ready(()); | ||
| 130 | } | ||
| 131 | RNG_WAKER.register(cx.waker()); | ||
| 132 | T::regs().cr().modify(|reg| reg.set_ie(true)); | ||
| 133 | // Need to check condition **after** `register` to avoid a race | ||
| 134 | // condition that would result in lost notifications. | ||
| 135 | let bits = T::regs().sr().read(); | ||
| 136 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 137 | Poll::Ready(()) | ||
| 138 | } else { | ||
| 139 | Poll::Pending | ||
| 140 | } | ||
| 141 | }) | ||
| 142 | .await; | ||
| 143 | |||
| 144 | // Re-read the status register after wait. | ||
| 145 | bits = T::regs().sr().read() | ||
| 146 | } | ||
| 123 | if bits.seis() { | 147 | if bits.seis() { |
| 124 | // in case of noise-source or seed error we try to recover here | 148 | // in case of noise-source or seed error we try to recover here |
| 125 | // but we must not use the data in DR and we return an error | 149 | // but we must not use the data in DR and we return an error |
| @@ -143,26 +167,6 @@ impl<'d, T: Instance> Rng<'d, T> { | |||
| 143 | for (dest, src) in chunk.iter_mut().zip(random_word.to_be_bytes().iter()) { | 167 | for (dest, src) in chunk.iter_mut().zip(random_word.to_be_bytes().iter()) { |
| 144 | *dest = *src | 168 | *dest = *src |
| 145 | } | 169 | } |
| 146 | } else { | ||
| 147 | // wait for interrupt | ||
| 148 | poll_fn(|cx| { | ||
| 149 | // quick check to avoid registration if already done. | ||
| 150 | let bits = T::regs().sr().read(); | ||
| 151 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 152 | return Poll::Ready(()); | ||
| 153 | } | ||
| 154 | RNG_WAKER.register(cx.waker()); | ||
| 155 | T::regs().cr().modify(|reg| reg.set_ie(true)); | ||
| 156 | // Need to check condition **after** `register` to avoid a race | ||
| 157 | // condition that would result in lost notifications. | ||
| 158 | let bits = T::regs().sr().read(); | ||
| 159 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 160 | Poll::Ready(()) | ||
| 161 | } else { | ||
| 162 | Poll::Pending | ||
| 163 | } | ||
| 164 | }) | ||
| 165 | .await; | ||
| 166 | } | 170 | } |
| 167 | } | 171 | } |
| 168 | 172 | ||
