diff options
| author | nerwalt <[email protected]> | 2024-07-01 10:03:24 -0600 |
|---|---|---|
| committer | nerwalt <[email protected]> | 2024-07-01 10:03:24 -0600 |
| commit | 98263ac220102a60c1f7cd3a882acafbb59b53f1 (patch) | |
| tree | 74166685aa25a5ef8a859ac966dfac0e071513da | |
| parent | e9bbfb349c15a39e8de4bf1831de0224a3d2bff0 (diff) | |
| parent | 3c6bf3a31a951fcea31e39390ba4f0f073144933 (diff) | |
Merge branch 'main' into nrf9151
| -rw-r--r-- | embassy-boot-nrf/src/lib.rs | 8 | ||||
| -rw-r--r-- | embassy-boot-rp/src/lib.rs | 8 | ||||
| -rw-r--r-- | embassy-boot-stm32/src/lib.rs | 8 | ||||
| -rw-r--r-- | embassy-boot/src/test_flash/asynch.rs | 2 | ||||
| -rw-r--r-- | embassy-net/src/tcp.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/egu.rs | 18 | ||||
| -rw-r--r-- | embassy-rp/src/i2c.rs | 38 | ||||
| -rw-r--r-- | embassy-stm32/src/can/bxcan/registers.rs | 20 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/asynch.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/common.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/f0.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/f1f3.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/f4.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/f7.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/g.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/h50.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/h7.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/l.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/u0.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/u5.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 32 | ||||
| -rw-r--r-- | examples/rp/src/bin/i2c_async_embassy.rs | 85 |
22 files changed, 189 insertions, 66 deletions
diff --git a/embassy-boot-nrf/src/lib.rs b/embassy-boot-nrf/src/lib.rs index d53e78895..e5bc870b5 100644 --- a/embassy-boot-nrf/src/lib.rs +++ b/embassy-boot-nrf/src/lib.rs | |||
| @@ -20,7 +20,13 @@ impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> { | |||
| 20 | pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>( | 20 | pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>( |
| 21 | config: BootLoaderConfig<ACTIVE, DFU, STATE>, | 21 | config: BootLoaderConfig<ACTIVE, DFU, STATE>, |
| 22 | ) -> Self { | 22 | ) -> Self { |
| 23 | Self::try_prepare::<ACTIVE, DFU, STATE>(config).expect("Boot prepare error") | 23 | if let Ok(loader) = Self::try_prepare::<ACTIVE, DFU, STATE>(config) { |
| 24 | loader | ||
| 25 | } else { | ||
| 26 | // Use explicit panic instead of .expect() to ensure this gets routed via defmt/etc. | ||
| 27 | // properly | ||
| 28 | panic!("Boot prepare error") | ||
| 29 | } | ||
| 24 | } | 30 | } |
| 25 | 31 | ||
| 26 | /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware | 32 | /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware |
diff --git a/embassy-boot-rp/src/lib.rs b/embassy-boot-rp/src/lib.rs index d0a393bed..3e1731f5e 100644 --- a/embassy-boot-rp/src/lib.rs +++ b/embassy-boot-rp/src/lib.rs | |||
| @@ -21,7 +21,13 @@ impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> { | |||
| 21 | pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>( | 21 | pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>( |
| 22 | config: BootLoaderConfig<ACTIVE, DFU, STATE>, | 22 | config: BootLoaderConfig<ACTIVE, DFU, STATE>, |
| 23 | ) -> Self { | 23 | ) -> Self { |
| 24 | Self::try_prepare::<ACTIVE, DFU, STATE>(config).expect("Boot prepare error") | 24 | if let Ok(loader) = Self::try_prepare::<ACTIVE, DFU, STATE>(config) { |
| 25 | loader | ||
| 26 | } else { | ||
| 27 | // Use explicit panic instead of .expect() to ensure this gets routed via defmt/etc. | ||
| 28 | // properly | ||
| 29 | panic!("Boot prepare error") | ||
| 30 | } | ||
| 25 | } | 31 | } |
| 26 | 32 | ||
| 27 | /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware | 33 | /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware |
diff --git a/embassy-boot-stm32/src/lib.rs b/embassy-boot-stm32/src/lib.rs index 708441835..387cc0ce5 100644 --- a/embassy-boot-stm32/src/lib.rs +++ b/embassy-boot-stm32/src/lib.rs | |||
| @@ -20,7 +20,13 @@ impl BootLoader { | |||
| 20 | pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>( | 20 | pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>( |
| 21 | config: BootLoaderConfig<ACTIVE, DFU, STATE>, | 21 | config: BootLoaderConfig<ACTIVE, DFU, STATE>, |
| 22 | ) -> Self { | 22 | ) -> Self { |
| 23 | Self::try_prepare::<ACTIVE, DFU, STATE, BUFFER_SIZE>(config).expect("Boot prepare error") | 23 | if let Ok(loader) = Self::try_prepare::<ACTIVE, DFU, STATE, BUFFER_SIZE>(config) { |
| 24 | loader | ||
| 25 | } else { | ||
| 26 | // Use explicit panic instead of .expect() to ensure this gets routed via defmt/etc. | ||
| 27 | // properly | ||
| 28 | panic!("Boot prepare error") | ||
| 29 | } | ||
| 24 | } | 30 | } |
| 25 | 31 | ||
| 26 | /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware | 32 | /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware |
diff --git a/embassy-boot/src/test_flash/asynch.rs b/embassy-boot/src/test_flash/asynch.rs index 3ac9e71ab..c67f2495c 100644 --- a/embassy-boot/src/test_flash/asynch.rs +++ b/embassy-boot/src/test_flash/asynch.rs | |||
| @@ -43,7 +43,7 @@ where | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | fn create_partition<T: NorFlash>(mutex: &Mutex<NoopRawMutex, T>) -> Partition<NoopRawMutex, T> { | 45 | fn create_partition<T: NorFlash>(mutex: &Mutex<NoopRawMutex, T>) -> Partition<NoopRawMutex, T> { |
| 46 | Partition::new(mutex, 0, mutex.try_lock().unwrap().capacity() as u32) | 46 | Partition::new(mutex, 0, unwrap!(mutex.try_lock()).capacity() as u32) |
| 47 | } | 47 | } |
| 48 | } | 48 | } |
| 49 | 49 | ||
diff --git a/embassy-net/src/tcp.rs b/embassy-net/src/tcp.rs index 906102bbf..4d6dc92de 100644 --- a/embassy-net/src/tcp.rs +++ b/embassy-net/src/tcp.rs | |||
| @@ -587,7 +587,7 @@ mod embedded_io_impls { | |||
| 587 | 587 | ||
| 588 | impl<'d> embedded_io_async::ReadReady for TcpSocket<'d> { | 588 | impl<'d> embedded_io_async::ReadReady for TcpSocket<'d> { |
| 589 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | 589 | fn read_ready(&mut self) -> Result<bool, Self::Error> { |
| 590 | Ok(self.io.with(|s, _| s.can_recv())) | 590 | Ok(self.io.with(|s, _| s.can_recv() || !s.may_recv())) |
| 591 | } | 591 | } |
| 592 | } | 592 | } |
| 593 | 593 | ||
diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs index c0cde8330..204446d29 100644 --- a/embassy-nrf/src/egu.rs +++ b/embassy-nrf/src/egu.rs | |||
| @@ -77,6 +77,24 @@ impl<'d, T: Instance> Trigger<'d, T> { | |||
| 77 | let regs = T::regs(); | 77 | let regs = T::regs(); |
| 78 | Event::from_reg(®s.events_triggered[nr]) | 78 | Event::from_reg(®s.events_triggered[nr]) |
| 79 | } | 79 | } |
| 80 | |||
| 81 | /// Enable interrupts for this trigger | ||
| 82 | pub fn enable_interrupt(&mut self) { | ||
| 83 | let regs = T::regs(); | ||
| 84 | unsafe { | ||
| 85 | regs.intenset | ||
| 86 | .modify(|r, w| w.bits(r.bits() | (1 << self.number as usize))) | ||
| 87 | }; | ||
| 88 | } | ||
| 89 | |||
| 90 | /// Enable interrupts for this trigger | ||
| 91 | pub fn disable_interrupt(&mut self) { | ||
| 92 | let regs = T::regs(); | ||
| 93 | unsafe { | ||
| 94 | regs.intenclr | ||
| 95 | .modify(|r, w| w.bits(r.bits() | (1 << self.number as usize))) | ||
| 96 | }; | ||
| 97 | } | ||
| 80 | } | 98 | } |
| 81 | 99 | ||
| 82 | /// Represents a trigger within an EGU. | 100 | /// Represents a trigger within an EGU. |
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 10ccca674..10d3c86b3 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs | |||
| @@ -313,25 +313,29 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | /// Read from address into buffer using DMA. | 315 | /// Read from address into buffer using DMA. |
| 316 | pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> { | 316 | pub async fn read_async(&mut self, addr: impl Into<u16>, buffer: &mut [u8]) -> Result<(), Error> { |
| 317 | Self::setup(addr)?; | 317 | Self::setup(addr.into())?; |
| 318 | self.read_async_internal(buffer, true, true).await | 318 | self.read_async_internal(buffer, true, true).await |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | /// Write to address from buffer using DMA. | 321 | /// Write to address from buffer using DMA. |
| 322 | pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator<Item = u8>) -> Result<(), Error> { | 322 | pub async fn write_async( |
| 323 | Self::setup(addr)?; | 323 | &mut self, |
| 324 | addr: impl Into<u16>, | ||
| 325 | bytes: impl IntoIterator<Item = u8>, | ||
| 326 | ) -> Result<(), Error> { | ||
| 327 | Self::setup(addr.into())?; | ||
| 324 | self.write_async_internal(bytes, true).await | 328 | self.write_async_internal(bytes, true).await |
| 325 | } | 329 | } |
| 326 | 330 | ||
| 327 | /// Write to address from bytes and read from address into buffer using DMA. | 331 | /// Write to address from bytes and read from address into buffer using DMA. |
| 328 | pub async fn write_read_async( | 332 | pub async fn write_read_async( |
| 329 | &mut self, | 333 | &mut self, |
| 330 | addr: u16, | 334 | addr: impl Into<u16>, |
| 331 | bytes: impl IntoIterator<Item = u8>, | 335 | bytes: impl IntoIterator<Item = u8>, |
| 332 | buffer: &mut [u8], | 336 | buffer: &mut [u8], |
| 333 | ) -> Result<(), Error> { | 337 | ) -> Result<(), Error> { |
| 334 | Self::setup(addr)?; | 338 | Self::setup(addr.into())?; |
| 335 | self.write_async_internal(bytes, false).await?; | 339 | self.write_async_internal(bytes, false).await?; |
| 336 | self.read_async_internal(buffer, true, true).await | 340 | self.read_async_internal(buffer, true, true).await |
| 337 | } | 341 | } |
| @@ -595,20 +599,20 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { | |||
| 595 | // ========================= | 599 | // ========================= |
| 596 | 600 | ||
| 597 | /// Read from address into buffer blocking caller until done. | 601 | /// Read from address into buffer blocking caller until done. |
| 598 | pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> { | 602 | pub fn blocking_read(&mut self, address: impl Into<u16>, read: &mut [u8]) -> Result<(), Error> { |
| 599 | Self::setup(address.into())?; | 603 | Self::setup(address.into())?; |
| 600 | self.read_blocking_internal(read, true, true) | 604 | self.read_blocking_internal(read, true, true) |
| 601 | // Automatic Stop | 605 | // Automatic Stop |
| 602 | } | 606 | } |
| 603 | 607 | ||
| 604 | /// Write to address from buffer blocking caller until done. | 608 | /// Write to address from buffer blocking caller until done. |
| 605 | pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> { | 609 | pub fn blocking_write(&mut self, address: impl Into<u16>, write: &[u8]) -> Result<(), Error> { |
| 606 | Self::setup(address.into())?; | 610 | Self::setup(address.into())?; |
| 607 | self.write_blocking_internal(write, true) | 611 | self.write_blocking_internal(write, true) |
| 608 | } | 612 | } |
| 609 | 613 | ||
| 610 | /// Write to address from bytes and read from address into buffer blocking caller until done. | 614 | /// Write to address from bytes and read from address into buffer blocking caller until done. |
| 611 | pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> { | 615 | pub fn blocking_write_read(&mut self, address: impl Into<u16>, write: &[u8], read: &mut [u8]) -> Result<(), Error> { |
| 612 | Self::setup(address.into())?; | 616 | Self::setup(address.into())?; |
| 613 | self.write_blocking_internal(write, false)?; | 617 | self.write_blocking_internal(write, false)?; |
| 614 | self.read_blocking_internal(read, true, true) | 618 | self.read_blocking_internal(read, true, true) |
| @@ -719,25 +723,15 @@ where | |||
| 719 | T: Instance + 'd, | 723 | T: Instance + 'd, |
| 720 | { | 724 | { |
| 721 | async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> { | 725 | async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> { |
| 722 | let addr: u16 = address.into(); | 726 | self.read_async(address, read).await |
| 723 | |||
| 724 | Self::setup(addr)?; | ||
| 725 | self.read_async_internal(read, false, true).await | ||
| 726 | } | 727 | } |
| 727 | 728 | ||
| 728 | async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> { | 729 | async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> { |
| 729 | let addr: u16 = address.into(); | 730 | self.write_async(address, write.iter().copied()).await |
| 730 | |||
| 731 | Self::setup(addr)?; | ||
| 732 | self.write_async_internal(write.iter().copied(), true).await | ||
| 733 | } | 731 | } |
| 734 | 732 | ||
| 735 | async fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { | 733 | async fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { |
| 736 | let addr: u16 = address.into(); | 734 | self.write_read_async(address, write.iter().copied(), read).await |
| 737 | |||
| 738 | Self::setup(addr)?; | ||
| 739 | self.write_async_internal(write.iter().cloned(), false).await?; | ||
| 740 | self.read_async_internal(read, true, true).await | ||
| 741 | } | 735 | } |
| 742 | 736 | ||
| 743 | async fn transaction( | 737 | async fn transaction( |
diff --git a/embassy-stm32/src/can/bxcan/registers.rs b/embassy-stm32/src/can/bxcan/registers.rs index 5f3d70e25..c5de1c683 100644 --- a/embassy-stm32/src/can/bxcan/registers.rs +++ b/embassy-stm32/src/can/bxcan/registers.rs | |||
| @@ -299,9 +299,9 @@ impl Registers { | |||
| 299 | mb.tdtr().write(|w| w.set_dlc(frame.header().len() as u8)); | 299 | mb.tdtr().write(|w| w.set_dlc(frame.header().len() as u8)); |
| 300 | 300 | ||
| 301 | mb.tdlr() | 301 | mb.tdlr() |
| 302 | .write(|w| w.0 = u32::from_ne_bytes(frame.data()[0..4].try_into().unwrap())); | 302 | .write(|w| w.0 = u32::from_ne_bytes(unwrap!(frame.data()[0..4].try_into()))); |
| 303 | mb.tdhr() | 303 | mb.tdhr() |
| 304 | .write(|w| w.0 = u32::from_ne_bytes(frame.data()[4..8].try_into().unwrap())); | 304 | .write(|w| w.0 = u32::from_ne_bytes(unwrap!(frame.data()[4..8].try_into()))); |
| 305 | let id: IdReg = frame.id().into(); | 305 | let id: IdReg = frame.id().into(); |
| 306 | mb.tir().write(|w| { | 306 | mb.tir().write(|w| { |
| 307 | w.0 = id.0; | 307 | w.0 = id.0; |
| @@ -321,7 +321,7 @@ impl Registers { | |||
| 321 | data[4..8].copy_from_slice(&mb.tdhr().read().0.to_ne_bytes()); | 321 | data[4..8].copy_from_slice(&mb.tdhr().read().0.to_ne_bytes()); |
| 322 | let len = mb.tdtr().read().dlc(); | 322 | let len = mb.tdtr().read().dlc(); |
| 323 | 323 | ||
| 324 | Some(Frame::new(Header::new(id.id(), len, id.rtr()), &data).unwrap()) | 324 | Some(unwrap!(Frame::new(Header::new(id.id(), len, id.rtr()), &data))) |
| 325 | } else { | 325 | } else { |
| 326 | // Abort request failed because the frame was already sent (or being sent) on | 326 | // Abort request failed because the frame was already sent (or being sent) on |
| 327 | // the bus. All mailboxes are now free. This can happen for small prescaler | 327 | // the bus. All mailboxes are now free. This can happen for small prescaler |
| @@ -404,12 +404,12 @@ impl Registers { | |||
| 404 | 404 | ||
| 405 | let rir = fifo.rir().read(); | 405 | let rir = fifo.rir().read(); |
| 406 | let id: embedded_can::Id = if rir.ide() == Ide::STANDARD { | 406 | let id: embedded_can::Id = if rir.ide() == Ide::STANDARD { |
| 407 | embedded_can::StandardId::new(rir.stid()).unwrap().into() | 407 | unwrap!(embedded_can::StandardId::new(rir.stid())).into() |
| 408 | } else { | 408 | } else { |
| 409 | let stid = (rir.stid() & 0x7FF) as u32; | 409 | let stid = (rir.stid() & 0x7FF) as u32; |
| 410 | let exid = rir.exid() & 0x3FFFF; | 410 | let exid = rir.exid() & 0x3FFFF; |
| 411 | let id = (stid << 18) | (exid); | 411 | let id = (stid << 18) | (exid); |
| 412 | embedded_can::ExtendedId::new(id).unwrap().into() | 412 | unwrap!(embedded_can::ExtendedId::new(id)).into() |
| 413 | }; | 413 | }; |
| 414 | let rdtr = fifo.rdtr().read(); | 414 | let rdtr = fifo.rdtr().read(); |
| 415 | let data_len = rdtr.dlc(); | 415 | let data_len = rdtr.dlc(); |
| @@ -422,7 +422,7 @@ impl Registers { | |||
| 422 | data[0..4].copy_from_slice(&fifo.rdlr().read().0.to_ne_bytes()); | 422 | data[0..4].copy_from_slice(&fifo.rdlr().read().0.to_ne_bytes()); |
| 423 | data[4..8].copy_from_slice(&fifo.rdhr().read().0.to_ne_bytes()); | 423 | data[4..8].copy_from_slice(&fifo.rdhr().read().0.to_ne_bytes()); |
| 424 | 424 | ||
| 425 | let frame = Frame::new(Header::new(id, data_len, rtr), &data).unwrap(); | 425 | let frame = unwrap!(Frame::new(Header::new(id, data_len, rtr), &data)); |
| 426 | let envelope = Envelope { ts, frame }; | 426 | let envelope = Envelope { ts, frame }; |
| 427 | 427 | ||
| 428 | rfr.modify(|v| v.set_rfom(true)); | 428 | rfr.modify(|v| v.set_rfom(true)); |
| @@ -484,13 +484,9 @@ impl IdReg { | |||
| 484 | /// Returns the identifier. | 484 | /// Returns the identifier. |
| 485 | fn id(self) -> embedded_can::Id { | 485 | fn id(self) -> embedded_can::Id { |
| 486 | if self.is_extended() { | 486 | if self.is_extended() { |
| 487 | embedded_can::ExtendedId::new(self.0 >> Self::EXTENDED_SHIFT) | 487 | unwrap!(embedded_can::ExtendedId::new(self.0 >> Self::EXTENDED_SHIFT)).into() |
| 488 | .unwrap() | ||
| 489 | .into() | ||
| 490 | } else { | 488 | } else { |
| 491 | embedded_can::StandardId::new((self.0 >> Self::STANDARD_SHIFT) as u16) | 489 | unwrap!(embedded_can::StandardId::new((self.0 >> Self::STANDARD_SHIFT) as u16)).into() |
| 492 | .unwrap() | ||
| 493 | .into() | ||
| 494 | } | 490 | } |
| 495 | } | 491 | } |
| 496 | 492 | ||
diff --git a/embassy-stm32/src/flash/asynch.rs b/embassy-stm32/src/flash/asynch.rs index 97eaece81..9468ac632 100644 --- a/embassy-stm32/src/flash/asynch.rs +++ b/embassy-stm32/src/flash/asynch.rs | |||
| @@ -117,7 +117,7 @@ pub(super) async unsafe fn write_chunked(base: u32, size: u32, offset: u32, byte | |||
| 117 | family::lock(); | 117 | family::lock(); |
| 118 | }); | 118 | }); |
| 119 | 119 | ||
| 120 | family::write(address, chunk.try_into().unwrap()).await?; | 120 | family::write(address, unwrap!(chunk.try_into())).await?; |
| 121 | address += WRITE_SIZE as u32; | 121 | address += WRITE_SIZE as u32; |
| 122 | } | 122 | } |
| 123 | Ok(()) | 123 | Ok(()) |
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs index f8561edb3..8ec4bb2a1 100644 --- a/embassy-stm32/src/flash/common.rs +++ b/embassy-stm32/src/flash/common.rs | |||
| @@ -125,7 +125,7 @@ pub(super) unsafe fn write_chunk_unlocked(address: u32, chunk: &[u8]) -> Result< | |||
| 125 | family::lock(); | 125 | family::lock(); |
| 126 | }); | 126 | }); |
| 127 | 127 | ||
| 128 | family::blocking_write(address, chunk.try_into().unwrap()) | 128 | family::blocking_write(address, unwrap!(chunk.try_into())) |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | pub(super) unsafe fn write_chunk_with_critical_section(address: u32, chunk: &[u8]) -> Result<(), Error> { | 131 | pub(super) unsafe fn write_chunk_with_critical_section(address: u32, chunk: &[u8]) -> Result<(), Error> { |
diff --git a/embassy-stm32/src/flash/f0.rs b/embassy-stm32/src/flash/f0.rs index e2f135208..402312f68 100644 --- a/embassy-stm32/src/flash/f0.rs +++ b/embassy-stm32/src/flash/f0.rs | |||
| @@ -37,7 +37,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 37 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 37 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 38 | let mut address = start_address; | 38 | let mut address = start_address; |
| 39 | for chunk in buf.chunks(2) { | 39 | for chunk in buf.chunks(2) { |
| 40 | write_volatile(address as *mut u16, u16::from_le_bytes(chunk.try_into().unwrap())); | 40 | write_volatile(address as *mut u16, u16::from_le_bytes(unwrap!(chunk.try_into()))); |
| 41 | address += chunk.len() as u32; | 41 | address += chunk.len() as u32; |
| 42 | 42 | ||
| 43 | // prevents parallelism errors | 43 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/flash/f1f3.rs b/embassy-stm32/src/flash/f1f3.rs index b16354a74..e66842e31 100644 --- a/embassy-stm32/src/flash/f1f3.rs +++ b/embassy-stm32/src/flash/f1f3.rs | |||
| @@ -37,7 +37,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 37 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 37 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 38 | let mut address = start_address; | 38 | let mut address = start_address; |
| 39 | for chunk in buf.chunks(2) { | 39 | for chunk in buf.chunks(2) { |
| 40 | write_volatile(address as *mut u16, u16::from_le_bytes(chunk.try_into().unwrap())); | 40 | write_volatile(address as *mut u16, u16::from_le_bytes(unwrap!(chunk.try_into()))); |
| 41 | address += chunk.len() as u32; | 41 | address += chunk.len() as u32; |
| 42 | 42 | ||
| 43 | // prevents parallelism errors | 43 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 2634fba37..d0bb957ee 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs | |||
| @@ -277,7 +277,7 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) | |||
| 277 | unsafe fn write_start(start_address: u32, buf: &[u8; WRITE_SIZE]) { | 277 | unsafe fn write_start(start_address: u32, buf: &[u8; WRITE_SIZE]) { |
| 278 | let mut address = start_address; | 278 | let mut address = start_address; |
| 279 | for val in buf.chunks(4) { | 279 | for val in buf.chunks(4) { |
| 280 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 280 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 281 | address += val.len() as u32; | 281 | address += val.len() as u32; |
| 282 | 282 | ||
| 283 | // prevents parallelism errors | 283 | // prevents parallelism errors |
| @@ -379,7 +379,7 @@ fn get_result(sr: Sr) -> Result<(), Error> { | |||
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | fn save_data_cache_state() { | 381 | fn save_data_cache_state() { |
| 382 | let dual_bank = get_flash_regions().last().unwrap().bank == FlashBank::Bank2; | 382 | let dual_bank = unwrap!(get_flash_regions().last()).bank == FlashBank::Bank2; |
| 383 | if dual_bank { | 383 | if dual_bank { |
| 384 | // Disable data cache during write/erase if there are two banks, see errata 2.2.12 | 384 | // Disable data cache during write/erase if there are two banks, see errata 2.2.12 |
| 385 | let dcen = pac::FLASH.acr().read().dcen(); | 385 | let dcen = pac::FLASH.acr().read().dcen(); |
| @@ -391,7 +391,7 @@ fn save_data_cache_state() { | |||
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | fn restore_data_cache_state() { | 393 | fn restore_data_cache_state() { |
| 394 | let dual_bank = get_flash_regions().last().unwrap().bank == FlashBank::Bank2; | 394 | let dual_bank = unwrap!(get_flash_regions().last()).bank == FlashBank::Bank2; |
| 395 | if dual_bank { | 395 | if dual_bank { |
| 396 | // Restore data cache if it was enabled | 396 | // Restore data cache if it was enabled |
| 397 | let dcen = DATA_CACHE_WAS_ENABLED.load(Ordering::Relaxed); | 397 | let dcen = DATA_CACHE_WAS_ENABLED.load(Ordering::Relaxed); |
| @@ -410,7 +410,7 @@ pub(crate) fn assert_not_corrupted_read(end_address: u32) { | |||
| 410 | 410 | ||
| 411 | #[allow(unused)] | 411 | #[allow(unused)] |
| 412 | let second_bank_read = | 412 | let second_bank_read = |
| 413 | get_flash_regions().last().unwrap().bank == FlashBank::Bank2 && end_address > (FLASH_SIZE / 2) as u32; | 413 | unwrap!(get_flash_regions().last()).bank == FlashBank::Bank2 && end_address > (FLASH_SIZE / 2) as u32; |
| 414 | 414 | ||
| 415 | #[cfg(any( | 415 | #[cfg(any( |
| 416 | feature = "stm32f427ai", | 416 | feature = "stm32f427ai", |
diff --git a/embassy-stm32/src/flash/f7.rs b/embassy-stm32/src/flash/f7.rs index 72de0b445..09ebe9db9 100644 --- a/embassy-stm32/src/flash/f7.rs +++ b/embassy-stm32/src/flash/f7.rs | |||
| @@ -40,7 +40,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 40 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 40 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 41 | let mut address = start_address; | 41 | let mut address = start_address; |
| 42 | for val in buf.chunks(4) { | 42 | for val in buf.chunks(4) { |
| 43 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 43 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 44 | address += val.len() as u32; | 44 | address += val.len() as u32; |
| 45 | 45 | ||
| 46 | // prevents parallelism errors | 46 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/flash/g.rs b/embassy-stm32/src/flash/g.rs index 6a5adc941..01a0c603f 100644 --- a/embassy-stm32/src/flash/g.rs +++ b/embassy-stm32/src/flash/g.rs | |||
| @@ -41,7 +41,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 41 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 41 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 42 | let mut address = start_address; | 42 | let mut address = start_address; |
| 43 | for val in buf.chunks(4) { | 43 | for val in buf.chunks(4) { |
| 44 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 44 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 45 | address += val.len() as u32; | 45 | address += val.len() as u32; |
| 46 | 46 | ||
| 47 | // prevents parallelism errors | 47 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/flash/h50.rs b/embassy-stm32/src/flash/h50.rs index 56ea7a421..82e77d130 100644 --- a/embassy-stm32/src/flash/h50.rs +++ b/embassy-stm32/src/flash/h50.rs | |||
| @@ -44,7 +44,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 44 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 44 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 45 | let mut address = start_address; | 45 | let mut address = start_address; |
| 46 | for val in buf.chunks(4) { | 46 | for val in buf.chunks(4) { |
| 47 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 47 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 48 | address += val.len() as u32; | 48 | address += val.len() as u32; |
| 49 | 49 | ||
| 50 | // prevents parallelism errors | 50 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/flash/h7.rs b/embassy-stm32/src/flash/h7.rs index e32a82eef..254915381 100644 --- a/embassy-stm32/src/flash/h7.rs +++ b/embassy-stm32/src/flash/h7.rs | |||
| @@ -62,7 +62,7 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) | |||
| 62 | let mut res = None; | 62 | let mut res = None; |
| 63 | let mut address = start_address; | 63 | let mut address = start_address; |
| 64 | for val in buf.chunks(4) { | 64 | for val in buf.chunks(4) { |
| 65 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 65 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 66 | address += val.len() as u32; | 66 | address += val.len() as u32; |
| 67 | 67 | ||
| 68 | res = Some(blocking_wait_ready(bank)); | 68 | res = Some(blocking_wait_ready(bank)); |
| @@ -71,7 +71,7 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) | |||
| 71 | w.set_eop(true); | 71 | w.set_eop(true); |
| 72 | } | 72 | } |
| 73 | }); | 73 | }); |
| 74 | if res.unwrap().is_err() { | 74 | if unwrap!(res).is_err() { |
| 75 | break; | 75 | break; |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| @@ -82,7 +82,7 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) | |||
| 82 | 82 | ||
| 83 | bank.cr().write(|w| w.set_pg(false)); | 83 | bank.cr().write(|w| w.set_pg(false)); |
| 84 | 84 | ||
| 85 | res.unwrap() | 85 | unwrap!(res) |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> { | 88 | pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> { |
diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs index b14224bff..a0bfeb395 100644 --- a/embassy-stm32/src/flash/l.rs +++ b/embassy-stm32/src/flash/l.rs | |||
| @@ -63,7 +63,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 63 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 63 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 64 | let mut address = start_address; | 64 | let mut address = start_address; |
| 65 | for val in buf.chunks(4) { | 65 | for val in buf.chunks(4) { |
| 66 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 66 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 67 | address += val.len() as u32; | 67 | address += val.len() as u32; |
| 68 | 68 | ||
| 69 | // prevents parallelism errors | 69 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/flash/u0.rs b/embassy-stm32/src/flash/u0.rs index dfc5a2f76..bfdbd15a5 100644 --- a/embassy-stm32/src/flash/u0.rs +++ b/embassy-stm32/src/flash/u0.rs | |||
| @@ -41,7 +41,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 41 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 41 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 42 | let mut address = start_address; | 42 | let mut address = start_address; |
| 43 | for val in buf.chunks(4) { | 43 | for val in buf.chunks(4) { |
| 44 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 44 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 45 | address += val.len() as u32; | 45 | address += val.len() as u32; |
| 46 | 46 | ||
| 47 | // prevents parallelism errors | 47 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/flash/u5.rs b/embassy-stm32/src/flash/u5.rs index ddd4d73ff..0601017ce 100644 --- a/embassy-stm32/src/flash/u5.rs +++ b/embassy-stm32/src/flash/u5.rs | |||
| @@ -56,7 +56,7 @@ pub(crate) unsafe fn disable_blocking_write() { | |||
| 56 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { | 56 | pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> { |
| 57 | let mut address = start_address; | 57 | let mut address = start_address; |
| 58 | for val in buf.chunks(4) { | 58 | for val in buf.chunks(4) { |
| 59 | write_volatile(address as *mut u32, u32::from_le_bytes(val.try_into().unwrap())); | 59 | write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into()))); |
| 60 | address += val.len() as u32; | 60 | address += val.len() as u32; |
| 61 | 61 | ||
| 62 | // prevents parallelism errors | 62 | // prevents parallelism errors |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index 0bf344c40..024c63cf5 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -138,11 +138,17 @@ impl RccInfo { | |||
| 138 | pub(crate) fn enable_and_reset_with_cs(&self, _cs: CriticalSection) { | 138 | pub(crate) fn enable_and_reset_with_cs(&self, _cs: CriticalSection) { |
| 139 | if self.refcount_idx_or_0xff != 0xff { | 139 | if self.refcount_idx_or_0xff != 0xff { |
| 140 | let refcount_idx = self.refcount_idx_or_0xff as usize; | 140 | let refcount_idx = self.refcount_idx_or_0xff as usize; |
| 141 | unsafe { | 141 | |
| 142 | crate::_generated::REFCOUNTS[refcount_idx] += 1; | 142 | // Use .get_mut instead of []-operator so that we control how bounds checks happen. |
| 143 | } | 143 | // Otherwise, core::fmt will be pulled in here in order to format the integer in the |
| 144 | if unsafe { crate::_generated::REFCOUNTS[refcount_idx] } > 1 { | 144 | // out-of-bounds error. |
| 145 | return; | 145 | if let Some(refcount) = unsafe { crate::_generated::REFCOUNTS.get_mut(refcount_idx) } { |
| 146 | *refcount += 1; | ||
| 147 | if *refcount > 1 { | ||
| 148 | return; | ||
| 149 | } | ||
| 150 | } else { | ||
| 151 | panic!("refcount_idx out of bounds: {}", refcount_idx) | ||
| 146 | } | 152 | } |
| 147 | } | 153 | } |
| 148 | 154 | ||
| @@ -196,11 +202,17 @@ impl RccInfo { | |||
| 196 | pub(crate) fn disable_with_cs(&self, _cs: CriticalSection) { | 202 | pub(crate) fn disable_with_cs(&self, _cs: CriticalSection) { |
| 197 | if self.refcount_idx_or_0xff != 0xff { | 203 | if self.refcount_idx_or_0xff != 0xff { |
| 198 | let refcount_idx = self.refcount_idx_or_0xff as usize; | 204 | let refcount_idx = self.refcount_idx_or_0xff as usize; |
| 199 | unsafe { | 205 | |
| 200 | crate::_generated::REFCOUNTS[refcount_idx] -= 1; | 206 | // Use .get_mut instead of []-operator so that we control how bounds checks happen. |
| 201 | } | 207 | // Otherwise, core::fmt will be pulled in here in order to format the integer in the |
| 202 | if unsafe { crate::_generated::REFCOUNTS[refcount_idx] } > 0 { | 208 | // out-of-bounds error. |
| 203 | return; | 209 | if let Some(refcount) = unsafe { crate::_generated::REFCOUNTS.get_mut(refcount_idx) } { |
| 210 | *refcount -= 1; | ||
| 211 | if *refcount > 0 { | ||
| 212 | return; | ||
| 213 | } | ||
| 214 | } else { | ||
| 215 | panic!("refcount_idx out of bounds: {}", refcount_idx) | ||
| 204 | } | 216 | } |
| 205 | } | 217 | } |
| 206 | 218 | ||
diff --git a/examples/rp/src/bin/i2c_async_embassy.rs b/examples/rp/src/bin/i2c_async_embassy.rs new file mode 100644 index 000000000..a65b71b9f --- /dev/null +++ b/examples/rp/src/bin/i2c_async_embassy.rs | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | //! This example shows how to communicate asynchronous using i2c with external chip. | ||
| 2 | //! | ||
| 3 | //! It's using embassy's functions directly instead of traits from embedded_hal_async::i2c::I2c. | ||
| 4 | //! While most of i2c devices are addressed using 7 bits, an extension allows 10 bits too. | ||
| 5 | |||
| 6 | #![no_std] | ||
| 7 | #![no_main] | ||
| 8 | |||
| 9 | use defmt::*; | ||
| 10 | use embassy_rp::i2c::InterruptHandler; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | // Our anonymous hypotetical temperature sensor could be: | ||
| 14 | // a 12-bit sensor, with 100ms startup time, range of -40*C - 125*C, and precision 0.25*C | ||
| 15 | // It requires no configuration or calibration, works with all i2c bus speeds, | ||
| 16 | // never stretches clock or does anything complicated. Replies with one u16. | ||
| 17 | // It requires only one write to take it out of suspend mode, and stays on. | ||
| 18 | // Often result would be just on 12 bits, but here we'll simplify it to 16. | ||
| 19 | |||
| 20 | enum UncomplicatedSensorId { | ||
| 21 | A(UncomplicatedSensorU8), | ||
| 22 | B(UncomplicatedSensorU16), | ||
| 23 | } | ||
| 24 | enum UncomplicatedSensorU8 { | ||
| 25 | First = 0x48, | ||
| 26 | } | ||
| 27 | enum UncomplicatedSensorU16 { | ||
| 28 | Other = 0x0049, | ||
| 29 | } | ||
| 30 | |||
| 31 | impl Into<u16> for UncomplicatedSensorU16 { | ||
| 32 | fn into(self) -> u16 { | ||
| 33 | self as u16 | ||
| 34 | } | ||
| 35 | } | ||
| 36 | impl Into<u16> for UncomplicatedSensorU8 { | ||
| 37 | fn into(self) -> u16 { | ||
| 38 | 0x48 | ||
| 39 | } | ||
| 40 | } | ||
| 41 | impl From<UncomplicatedSensorId> for u16 { | ||
| 42 | fn from(t: UncomplicatedSensorId) -> Self { | ||
| 43 | match t { | ||
| 44 | UncomplicatedSensorId::A(x) => x.into(), | ||
| 45 | UncomplicatedSensorId::B(x) => x.into(), | ||
| 46 | } | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | embassy_rp::bind_interrupts!(struct Irqs { | ||
| 51 | I2C1_IRQ => InterruptHandler<embassy_rp::peripherals::I2C1>; | ||
| 52 | }); | ||
| 53 | |||
| 54 | #[embassy_executor::main] | ||
| 55 | async fn main(_task_spawner: embassy_executor::Spawner) { | ||
| 56 | let p = embassy_rp::init(Default::default()); | ||
| 57 | let sda = p.PIN_14; | ||
| 58 | let scl = p.PIN_15; | ||
| 59 | let config = embassy_rp::i2c::Config::default(); | ||
| 60 | let mut bus = embassy_rp::i2c::I2c::new_async(p.I2C1, scl, sda, Irqs, config); | ||
| 61 | |||
| 62 | const WAKEYWAKEY: u16 = 0xBABE; | ||
| 63 | let mut result: [u8; 2] = [0, 0]; | ||
| 64 | // wait for sensors to initialize | ||
| 65 | embassy_time::Timer::after(embassy_time::Duration::from_millis(100)).await; | ||
| 66 | |||
| 67 | let _res_1 = bus | ||
| 68 | .write_async(UncomplicatedSensorU8::First, WAKEYWAKEY.to_be_bytes()) | ||
| 69 | .await; | ||
| 70 | let _res_2 = bus | ||
| 71 | .write_async(UncomplicatedSensorU16::Other, WAKEYWAKEY.to_be_bytes()) | ||
| 72 | .await; | ||
| 73 | |||
| 74 | loop { | ||
| 75 | let s1 = UncomplicatedSensorId::A(UncomplicatedSensorU8::First); | ||
| 76 | let s2 = UncomplicatedSensorId::B(UncomplicatedSensorU16::Other); | ||
| 77 | let sensors = [s1, s2]; | ||
| 78 | for sensor in sensors { | ||
| 79 | if bus.read_async(sensor, &mut result).await.is_ok() { | ||
| 80 | info!("Result {}", u16::from_be_bytes(result.into())); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | embassy_time::Timer::after(embassy_time::Duration::from_millis(200)).await; | ||
| 84 | } | ||
| 85 | } | ||
