aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-08-28 21:38:54 +0000
committerGitHub <[email protected]>2023-08-28 21:38:54 +0000
commita4d78a655217fadcf005b0ae835eb115594dc2b2 (patch)
treeb0a525793d8dcbb75cbd9916970f005370754e50
parentf503417f4c828948db0ea7309da35f733037e1d1 (diff)
parentfd739250ea8b830f06f8a78a272874faa888d42c (diff)
Merge pull request #1835 from oll3/fix/stm32-rng
stm32: fix wait for RNG data
-rw-r--r--embassy-stm32/src/rng.rs46
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