Merge branch 'embassy-rs:main' into simplepwm-dma
This commit is contained in:
		
						commit
						f5a218a018
					
				@ -35,8 +35,7 @@ The <a href="https://docs.embassy.dev/embassy-net/">embassy-net</a> network stac
 | 
				
			|||||||
The <a href="https://github.com/embassy-rs/nrf-softdevice">nrf-softdevice</a> crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers.
 | 
					The <a href="https://github.com/embassy-rs/nrf-softdevice">nrf-softdevice</a> crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers.
 | 
				
			||||||
The <a href="https://github.com/embassy-rs/embassy/tree/main/embassy-stm32-wpan">embassy-stm32-wpan</a> crate provides Bluetooth Low Energy 5.x support for stm32wb microcontrollers.
 | 
					The <a href="https://github.com/embassy-rs/embassy/tree/main/embassy-stm32-wpan">embassy-stm32-wpan</a> crate provides Bluetooth Low Energy 5.x support for stm32wb microcontrollers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **LoRa** - 
 | 
					- **LoRa** - The <a href="https://github.com/lora-rs/lora-rs">lora-rs</a> project provides an async LoRa and LoRaWAN stack that works well on Embassy.
 | 
				
			||||||
<a href="hthttps://github.com/lora-rs/lora-rs">The lora-rs project</a> provides an async LoRa and LoRaWAN stack that works well on Embassy.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **USB** - 
 | 
					- **USB** - 
 | 
				
			||||||
<a href="https://docs.embassy.dev/embassy-usb/">embassy-usb</a> implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own.
 | 
					<a href="https://docs.embassy.dev/embassy-usb/">embassy-usb</a> implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								ci.sh
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								ci.sh
									
									
									
									
									
								
							@ -207,6 +207,9 @@ cargo batch  \
 | 
				
			|||||||
    $BUILD_EXTRA
 | 
					    $BUILD_EXTRA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# failed, a wire must've come loose, will check asap.
 | 
				
			||||||
 | 
					rm out/tests/rpi-pico/i2c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rm out/tests/stm32wb55rg/wpan_mac
 | 
					rm out/tests/stm32wb55rg/wpan_mac
 | 
				
			||||||
rm out/tests/stm32wb55rg/wpan_ble
 | 
					rm out/tests/stm32wb55rg/wpan_ble
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,7 @@ The link:https://docs.embassy.dev/embassy-net/[embassy-net] network stack implem
 | 
				
			|||||||
The link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers.
 | 
					The link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=== LoRa
 | 
					=== LoRa
 | 
				
			||||||
link:https://github.com/embassy-rs/lora-phy[lora-phy] and link:https://docs.embassy.dev/embassy-lora/[embassy-lora] supports LoRa networking on a wide range of LoRa radios, fully integrated with a Rust link:https://github.com/ivajloip/rust-lorawan[LoRaWAN] implementation.
 | 
					link:https://github.com/lora-rs/lora-rs[lora-rs] supports LoRa networking on a wide range of LoRa radios, fully integrated with a Rust LoRaWAN implementation. It provides four crates — lora-phy, lora-modulation, lorawan-encoding, and lorawan-device — and basic examples for various development boards. It has support for STM32WL wireless microcontrollers or Semtech SX127x transceivers, among others.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=== USB
 | 
					=== USB
 | 
				
			||||||
link:https://docs.embassy.dev/embassy-usb/[embassy-usb] implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own.
 | 
					link:https://docs.embassy.dev/embassy-usb/[embassy-usb] implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own.
 | 
				
			||||||
 | 
				
			|||||||
@ -49,7 +49,7 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut arg_names = Vec::new();
 | 
					    let mut args = Vec::new();
 | 
				
			||||||
    let mut fargs = f.sig.inputs.clone();
 | 
					    let mut fargs = f.sig.inputs.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for arg in fargs.iter_mut() {
 | 
					    for arg in fargs.iter_mut() {
 | 
				
			||||||
@ -59,8 +59,8 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            syn::FnArg::Typed(t) => match t.pat.as_mut() {
 | 
					            syn::FnArg::Typed(t) => match t.pat.as_mut() {
 | 
				
			||||||
                syn::Pat::Ident(id) => {
 | 
					                syn::Pat::Ident(id) => {
 | 
				
			||||||
                    arg_names.push(id.ident.clone());
 | 
					 | 
				
			||||||
                    id.mutability = None;
 | 
					                    id.mutability = None;
 | 
				
			||||||
 | 
					                    args.push((id.clone(), t.attrs.clone()));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                _ => {
 | 
					                _ => {
 | 
				
			||||||
                    ctxt.error_spanned_by(arg, "pattern matching in task arguments is not yet supported");
 | 
					                    ctxt.error_spanned_by(arg, "pattern matching in task arguments is not yet supported");
 | 
				
			||||||
@ -79,13 +79,24 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
 | 
				
			|||||||
    task_inner.vis = syn::Visibility::Inherited;
 | 
					    task_inner.vis = syn::Visibility::Inherited;
 | 
				
			||||||
    task_inner.sig.ident = task_inner_ident.clone();
 | 
					    task_inner.sig.ident = task_inner_ident.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // assemble the original input arguments,
 | 
				
			||||||
 | 
					    // including any attributes that may have
 | 
				
			||||||
 | 
					    // been applied previously
 | 
				
			||||||
 | 
					    let mut full_args = Vec::new();
 | 
				
			||||||
 | 
					    for (arg, cfgs) in args {
 | 
				
			||||||
 | 
					        full_args.push(quote!(
 | 
				
			||||||
 | 
					            #(#cfgs)*
 | 
				
			||||||
 | 
					            #arg
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(feature = "nightly")]
 | 
					    #[cfg(feature = "nightly")]
 | 
				
			||||||
    let mut task_outer: ItemFn = parse_quote! {
 | 
					    let mut task_outer: ItemFn = parse_quote! {
 | 
				
			||||||
        #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
 | 
					        #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
 | 
				
			||||||
            type Fut = impl ::core::future::Future + 'static;
 | 
					            type Fut = impl ::core::future::Future + 'static;
 | 
				
			||||||
            const POOL_SIZE: usize = #pool_size;
 | 
					            const POOL_SIZE: usize = #pool_size;
 | 
				
			||||||
            static POOL: ::embassy_executor::raw::TaskPool<Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new();
 | 
					            static POOL: ::embassy_executor::raw::TaskPool<Fut, POOL_SIZE> = ::embassy_executor::raw::TaskPool::new();
 | 
				
			||||||
            unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) }
 | 
					            unsafe { POOL._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    #[cfg(not(feature = "nightly"))]
 | 
					    #[cfg(not(feature = "nightly"))]
 | 
				
			||||||
@ -93,7 +104,7 @@ pub fn run(args: &[NestedMeta], f: syn::ItemFn) -> Result<TokenStream, TokenStre
 | 
				
			|||||||
        #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
 | 
					        #visibility fn #task_ident(#fargs) -> ::embassy_executor::SpawnToken<impl Sized> {
 | 
				
			||||||
            const POOL_SIZE: usize = #pool_size;
 | 
					            const POOL_SIZE: usize = #pool_size;
 | 
				
			||||||
            static POOL: ::embassy_executor::_export::TaskPoolRef = ::embassy_executor::_export::TaskPoolRef::new();
 | 
					            static POOL: ::embassy_executor::_export::TaskPoolRef = ::embassy_executor::_export::TaskPoolRef::new();
 | 
				
			||||||
            unsafe { POOL.get::<_, POOL_SIZE>()._spawn_async_fn(move || #task_inner_ident(#(#arg_names,)*)) }
 | 
					            unsafe { POOL.get::<_, POOL_SIZE>()._spawn_async_fn(move || #task_inner_ident(#(#full_args,)*)) }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -135,3 +135,17 @@ fn executor_task_self_wake_twice() {
 | 
				
			|||||||
        ]
 | 
					        ]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn executor_task_cfg_args() {
 | 
				
			||||||
 | 
					    // simulate cfg'ing away argument c
 | 
				
			||||||
 | 
					    #[task]
 | 
				
			||||||
 | 
					    async fn task1(a: u32, b: u32, #[cfg(any())] c: u32) {
 | 
				
			||||||
 | 
					        let (_, _) = (a, b);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[task]
 | 
				
			||||||
 | 
					    async fn task2(a: u32, b: u32, #[cfg(all())] c: u32) {
 | 
				
			||||||
 | 
					        let (_, _, _) = (a, b, c);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -222,6 +222,11 @@ impl<'a> UdpSocket<'a> {
 | 
				
			|||||||
    pub fn payload_send_capacity(&self) -> usize {
 | 
					    pub fn payload_send_capacity(&self) -> usize {
 | 
				
			||||||
        self.with(|s, _| s.payload_send_capacity())
 | 
					        self.with(|s, _| s.payload_send_capacity())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Set the hop limit field in the IP header of sent packets.
 | 
				
			||||||
 | 
					    pub fn set_hop_limit(&mut self, hop_limit: Option<u8>) {
 | 
				
			||||||
 | 
					        self.with_mut(|s, _| s.set_hop_limit(hop_limit))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Drop for UdpSocket<'_> {
 | 
					impl Drop for UdpSocket<'_> {
 | 
				
			||||||
 | 
				
			|||||||
@ -342,6 +342,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
 | 
				
			|||||||
        s.tx_count.store(0, Ordering::Relaxed);
 | 
					        s.tx_count.store(0, Ordering::Relaxed);
 | 
				
			||||||
        s.rx_started_count.store(0, Ordering::Relaxed);
 | 
					        s.rx_started_count.store(0, Ordering::Relaxed);
 | 
				
			||||||
        s.rx_ended_count.store(0, Ordering::Relaxed);
 | 
					        s.rx_ended_count.store(0, Ordering::Relaxed);
 | 
				
			||||||
 | 
					        s.rx_started.store(false, Ordering::Relaxed);
 | 
				
			||||||
        let len = tx_buffer.len();
 | 
					        let len = tx_buffer.len();
 | 
				
			||||||
        unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
 | 
					        unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
 | 
				
			||||||
        let len = rx_buffer.len();
 | 
					        let len = rx_buffer.len();
 | 
				
			||||||
 | 
				
			|||||||
@ -152,6 +152,12 @@ impl<'d, T: Pin> Output<'d, T> {
 | 
				
			|||||||
        self.pin.set_low()
 | 
					        self.pin.set_low()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Toggle the output level.
 | 
				
			||||||
 | 
					    #[inline]
 | 
				
			||||||
 | 
					    pub fn toggle(&mut self) {
 | 
				
			||||||
 | 
					        self.pin.toggle()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the output level.
 | 
					    /// Set the output level.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_level(&mut self, level: Level) {
 | 
					    pub fn set_level(&mut self, level: Level) {
 | 
				
			||||||
@ -310,6 +316,16 @@ impl<'d, T: Pin> Flex<'d, T> {
 | 
				
			|||||||
        self.pin.set_low()
 | 
					        self.pin.set_low()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Toggle the output level.
 | 
				
			||||||
 | 
					    #[inline]
 | 
				
			||||||
 | 
					    pub fn toggle(&mut self) {
 | 
				
			||||||
 | 
					        if self.is_set_low() {
 | 
				
			||||||
 | 
					            self.set_high()
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.set_low()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Set the output level.
 | 
					    /// Set the output level.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn set_level(&mut self, level: Level) {
 | 
					    pub fn set_level(&mut self, level: Level) {
 | 
				
			||||||
@ -538,6 +554,15 @@ mod eh02 {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl<'d, T: Pin> embedded_hal_02::digital::v2::ToggleableOutputPin for Output<'d, T> {
 | 
				
			||||||
 | 
					        type Error = Infallible;
 | 
				
			||||||
 | 
					        #[inline]
 | 
				
			||||||
 | 
					        fn toggle(&mut self) -> Result<(), Self::Error> {
 | 
				
			||||||
 | 
					            self.toggle();
 | 
				
			||||||
 | 
					            Ok(())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Implement [`embedded_hal_02::digital::v2::InputPin`] for [`Flex`];
 | 
					    /// Implement [`embedded_hal_02::digital::v2::InputPin`] for [`Flex`];
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// If the pin is not in input mode the result is unspecified.
 | 
					    /// If the pin is not in input mode the result is unspecified.
 | 
				
			||||||
@ -574,6 +599,15 @@ mod eh02 {
 | 
				
			|||||||
            Ok(self.ref_is_set_low())
 | 
					            Ok(self.ref_is_set_low())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl<'d, T: Pin> embedded_hal_02::digital::v2::ToggleableOutputPin for Flex<'d, T> {
 | 
				
			||||||
 | 
					        type Error = Infallible;
 | 
				
			||||||
 | 
					        #[inline]
 | 
				
			||||||
 | 
					        fn toggle(&mut self) -> Result<(), Self::Error> {
 | 
				
			||||||
 | 
					            self.toggle();
 | 
				
			||||||
 | 
					            Ok(())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
 | 
					impl<'d, T: Pin> embedded_hal_1::digital::ErrorType for Input<'d, T> {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,9 @@
 | 
				
			|||||||
 | 
					//! # I2Cv1
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! This implementation is used for STM32F1, STM32F2, STM32F4, and STM32L1 devices.
 | 
				
			||||||
 | 
					//!
 | 
				
			||||||
 | 
					//! All other devices (as of 2023-12-28) use [`v2`](super::v2) instead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use core::future::poll_fn;
 | 
					use core::future::poll_fn;
 | 
				
			||||||
use core::task::Poll;
 | 
					use core::task::Poll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -10,6 +16,17 @@ use crate::dma::Transfer;
 | 
				
			|||||||
use crate::pac::i2c;
 | 
					use crate::pac::i2c;
 | 
				
			||||||
use crate::time::Hertz;
 | 
					use crate::time::Hertz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// /!\                      /!\
 | 
				
			||||||
 | 
					// /!\ Implementation note! /!\
 | 
				
			||||||
 | 
					// /!\                      /!\
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// It's somewhat unclear whether using interrupts here in a *strictly* one-shot style is actually
 | 
				
			||||||
 | 
					// what we want! If you are looking in this file because you are doing async I2C and your code is
 | 
				
			||||||
 | 
					// just totally hanging (sometimes), maybe swing by this issue:
 | 
				
			||||||
 | 
					// <https://github.com/embassy-rs/embassy/issues/2372>.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// There's some more details there, and we might have a fix for you. But please let us know if you
 | 
				
			||||||
 | 
					// hit a case like this!
 | 
				
			||||||
pub unsafe fn on_interrupt<T: Instance>() {
 | 
					pub unsafe fn on_interrupt<T: Instance>() {
 | 
				
			||||||
    let regs = T::regs();
 | 
					    let regs = T::regs();
 | 
				
			||||||
    // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of
 | 
					    // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of
 | 
				
			||||||
@ -375,6 +392,9 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
                        T::regs().sr2().read();
 | 
					                        T::regs().sr2().read();
 | 
				
			||||||
                        Poll::Ready(Ok(()))
 | 
					                        Poll::Ready(Ok(()))
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        // If we need to go around, then re-enable the interrupts, otherwise nothing
 | 
				
			||||||
 | 
					                        // can wake us up and we'll hang.
 | 
				
			||||||
 | 
					                        Self::enable_interrupts();
 | 
				
			||||||
                        Poll::Pending
 | 
					                        Poll::Pending
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -208,32 +208,30 @@ pub fn init(config: Config) -> Peripherals {
 | 
				
			|||||||
        let p = Peripherals::take_with_cs(cs);
 | 
					        let p = Peripherals::take_with_cs(cs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #[cfg(dbgmcu)]
 | 
					        #[cfg(dbgmcu)]
 | 
				
			||||||
        if config.enable_debug_during_sleep {
 | 
					 | 
				
			||||||
        crate::pac::DBGMCU.cr().modify(|cr| {
 | 
					        crate::pac::DBGMCU.cr().modify(|cr| {
 | 
				
			||||||
            #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))]
 | 
					            #[cfg(any(dbgmcu_f0, dbgmcu_c0, dbgmcu_g0, dbgmcu_u5, dbgmcu_wba))]
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                    cr.set_dbg_stop(true);
 | 
					                cr.set_dbg_stop(config.enable_debug_during_sleep);
 | 
				
			||||||
                    cr.set_dbg_standby(true);
 | 
					                cr.set_dbg_standby(config.enable_debug_during_sleep);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            #[cfg(any(
 | 
					            #[cfg(any(
 | 
				
			||||||
                dbgmcu_f1, dbgmcu_f2, dbgmcu_f3, dbgmcu_f4, dbgmcu_f7, dbgmcu_g4, dbgmcu_f7, dbgmcu_l0, dbgmcu_l1,
 | 
					                dbgmcu_f1, dbgmcu_f2, dbgmcu_f3, dbgmcu_f4, dbgmcu_f7, dbgmcu_g4, dbgmcu_f7, dbgmcu_l0, dbgmcu_l1,
 | 
				
			||||||
                dbgmcu_l4, dbgmcu_wb, dbgmcu_wl
 | 
					                dbgmcu_l4, dbgmcu_wb, dbgmcu_wl
 | 
				
			||||||
            ))]
 | 
					            ))]
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                    cr.set_dbg_sleep(true);
 | 
					                cr.set_dbg_sleep(config.enable_debug_during_sleep);
 | 
				
			||||||
                    cr.set_dbg_stop(true);
 | 
					                cr.set_dbg_stop(config.enable_debug_during_sleep);
 | 
				
			||||||
                    cr.set_dbg_standby(true);
 | 
					                cr.set_dbg_standby(config.enable_debug_during_sleep);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            #[cfg(dbgmcu_h7)]
 | 
					            #[cfg(dbgmcu_h7)]
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                    cr.set_d1dbgcken(true);
 | 
					                cr.set_d1dbgcken(config.enable_debug_during_sleep);
 | 
				
			||||||
                    cr.set_d3dbgcken(true);
 | 
					                cr.set_d3dbgcken(config.enable_debug_during_sleep);
 | 
				
			||||||
                    cr.set_dbgsleep_d1(true);
 | 
					                cr.set_dbgsleep_d1(config.enable_debug_during_sleep);
 | 
				
			||||||
                    cr.set_dbgstby_d1(true);
 | 
					                cr.set_dbgstby_d1(config.enable_debug_during_sleep);
 | 
				
			||||||
                    cr.set_dbgstop_d1(true);
 | 
					                cr.set_dbgstop_d1(config.enable_debug_during_sleep);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #[cfg(not(any(stm32f1, stm32wb, stm32wl)))]
 | 
					        #[cfg(not(any(stm32f1, stm32wb, stm32wl)))]
 | 
				
			||||||
        peripherals::SYSCFG::enable_and_reset_with_cs(cs);
 | 
					        peripherals::SYSCFG::enable_and_reset_with_cs(cs);
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ use crate::time::Hertz;
 | 
				
			|||||||
    ),
 | 
					    ),
 | 
				
			||||||
    path = "v2.rs"
 | 
					    path = "v2.rs"
 | 
				
			||||||
)]
 | 
					)]
 | 
				
			||||||
#[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")]
 | 
					#[cfg_attr(any(rtc_v3, rtc_v3u5, rtc_v3l5), path = "v3.rs")]
 | 
				
			||||||
mod _version;
 | 
					mod _version;
 | 
				
			||||||
#[allow(unused_imports)]
 | 
					#[allow(unused_imports)]
 | 
				
			||||||
pub use _version::*;
 | 
					pub use _version::*;
 | 
				
			||||||
@ -43,7 +43,7 @@ pub(crate) enum WakeupPrescaler {
 | 
				
			|||||||
    Div16 = 16,
 | 
					    Div16 = 16,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4))]
 | 
					#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5))]
 | 
				
			||||||
impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
 | 
					impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
 | 
				
			||||||
    fn from(val: WakeupPrescaler) -> Self {
 | 
					    fn from(val: WakeupPrescaler) -> Self {
 | 
				
			||||||
        use crate::pac::rtc::vals::Wucksel;
 | 
					        use crate::pac::rtc::vals::Wucksel;
 | 
				
			||||||
@ -57,7 +57,7 @@ impl From<WakeupPrescaler> for crate::pac::rtc::vals::Wucksel {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4))]
 | 
					#[cfg(any(stm32wb, stm32f4, stm32l0, stm32g4, stm32l5))]
 | 
				
			||||||
impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
 | 
					impl From<crate::pac::rtc::vals::Wucksel> for WakeupPrescaler {
 | 
				
			||||||
    fn from(val: crate::pac::rtc::vals::Wucksel) -> Self {
 | 
					    fn from(val: crate::pac::rtc::vals::Wucksel) -> Self {
 | 
				
			||||||
        use crate::pac::rtc::vals::Wucksel;
 | 
					        use crate::pac::rtc::vals::Wucksel;
 | 
				
			||||||
@ -348,7 +348,7 @@ impl Rtc {
 | 
				
			|||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        use embassy_time::{Duration, TICK_HZ};
 | 
					        use embassy_time::{Duration, TICK_HZ};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
					        #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))]
 | 
				
			||||||
        use crate::pac::rtc::vals::Calrf;
 | 
					        use crate::pac::rtc::vals::Calrf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Panic if the rcc mod knows we're not using low-power rtc
 | 
					        // Panic if the rcc mod knows we're not using low-power rtc
 | 
				
			||||||
@ -375,7 +375,7 @@ impl Rtc {
 | 
				
			|||||||
                while !regs.isr().read().wutwf() {}
 | 
					                while !regs.isr().read().wutwf() {}
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
					            #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))]
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
 | 
					                regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
 | 
				
			||||||
                while !regs.icsr().read().wutwf() {}
 | 
					                while !regs.icsr().read().wutwf() {}
 | 
				
			||||||
@ -404,7 +404,7 @@ impl Rtc {
 | 
				
			|||||||
    /// was called, otherwise none
 | 
					    /// was called, otherwise none
 | 
				
			||||||
    pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> {
 | 
					    pub(crate) fn stop_wakeup_alarm(&self, cs: critical_section::CriticalSection) -> Option<embassy_time::Duration> {
 | 
				
			||||||
        use crate::interrupt::typelevel::Interrupt;
 | 
					        use crate::interrupt::typelevel::Interrupt;
 | 
				
			||||||
        #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
					        #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))]
 | 
				
			||||||
        use crate::pac::rtc::vals::Calrf;
 | 
					        use crate::pac::rtc::vals::Calrf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let instant = self.instant().unwrap();
 | 
					        let instant = self.instant().unwrap();
 | 
				
			||||||
@ -420,13 +420,19 @@ impl Rtc {
 | 
				
			|||||||
                ))]
 | 
					                ))]
 | 
				
			||||||
                regs.isr().modify(|w| w.set_wutf(false));
 | 
					                regs.isr().modify(|w| w.set_wutf(false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                #[cfg(any(rtc_v3, rtc_v3u5))]
 | 
					                #[cfg(any(rtc_v3, rtc_v3u5, rtc_v3l5))]
 | 
				
			||||||
                regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
 | 
					                regs.scr().write(|w| w.set_cwutf(Calrf::CLEAR));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                #[cfg(not(stm32l5))]
 | 
				
			||||||
                crate::pac::EXTI
 | 
					                crate::pac::EXTI
 | 
				
			||||||
                    .pr(0)
 | 
					                    .pr(0)
 | 
				
			||||||
                    .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
					                    .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                #[cfg(stm32l5)]
 | 
				
			||||||
 | 
					                crate::pac::EXTI
 | 
				
			||||||
 | 
					                    .fpr(0)
 | 
				
			||||||
 | 
					                    .modify(|w| w.set_line(RTC::EXTI_WAKEUP_LINE, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
 | 
					                <RTC as crate::rtc::sealed::Instance>::WakeupInterrupt::unpend();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -135,6 +135,12 @@ impl sealed::Instance for crate::peripherals::RTC {
 | 
				
			|||||||
    #[cfg(all(feature = "low-power", stm32g4))]
 | 
					    #[cfg(all(feature = "low-power", stm32g4))]
 | 
				
			||||||
    type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
 | 
					    type WakeupInterrupt = crate::interrupt::typelevel::RTC_WKUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(all(feature = "low-power", stm32l5))]
 | 
				
			||||||
 | 
					    const EXTI_WAKEUP_LINE: usize = 17;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(all(feature = "low-power", stm32l5))]
 | 
				
			||||||
 | 
					    type WakeupInterrupt = crate::interrupt::typelevel::RTC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
 | 
					    fn read_backup_register(_rtc: &Rtc, register: usize) -> Option<u32> {
 | 
				
			||||||
        #[allow(clippy::if_same_then_else)]
 | 
					        #[allow(clippy::if_same_then_else)]
 | 
				
			||||||
        if register < Self::BACKUP_REGISTER_COUNT {
 | 
					        if register < Self::BACKUP_REGISTER_COUNT {
 | 
				
			||||||
 | 
				
			|||||||
@ -743,7 +743,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
 | 
				
			|||||||
        T::enable_and_reset();
 | 
					        T::enable_and_reset();
 | 
				
			||||||
        T::enable_and_reset();
 | 
					        T::enable_and_reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Self::new_inner(peri, rx, tx, tx_dma, rx_dma, config)
 | 
					        Self::new_inner_configure(peri, rx, tx, tx_dma, rx_dma, config)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Create a new bidirectional UART with request-to-send and clear-to-send pins
 | 
					    /// Create a new bidirectional UART with request-to-send and clear-to-send pins
 | 
				
			||||||
@ -770,7 +770,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
 | 
				
			|||||||
            w.set_rtse(true);
 | 
					            w.set_rtse(true);
 | 
				
			||||||
            w.set_ctse(true);
 | 
					            w.set_ctse(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        Self::new_inner(peri, rx, tx, tx_dma, rx_dma, config)
 | 
					        Self::new_inner_configure(peri, rx, tx, tx_dma, rx_dma, config)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[cfg(not(any(usart_v1, usart_v2)))]
 | 
					    #[cfg(not(any(usart_v1, usart_v2)))]
 | 
				
			||||||
@ -795,10 +795,76 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
 | 
				
			|||||||
        T::regs().cr3().write(|w| {
 | 
					        T::regs().cr3().write(|w| {
 | 
				
			||||||
            w.set_dem(true);
 | 
					            w.set_dem(true);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        Self::new_inner(peri, rx, tx, tx_dma, rx_dma, config)
 | 
					        Self::new_inner_configure(peri, rx, tx, tx_dma, rx_dma, config)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn new_inner(
 | 
					    /// Create a single-wire half-duplex Uart transceiver on a single Tx pin.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// See [`new_half_duplex_on_rx`][`Self::new_half_duplex_on_rx`] if you would prefer to use an Rx pin.
 | 
				
			||||||
 | 
					    /// There is no functional difference between these methods, as both allow bidirectional communication.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The pin is always released when no data is transmitted. Thus, it acts as a standard
 | 
				
			||||||
 | 
					    /// I/O in idle or in reception.
 | 
				
			||||||
 | 
					    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
 | 
				
			||||||
 | 
					    /// on the line must be managed by software (for instance by using a centralized arbiter).
 | 
				
			||||||
 | 
					    #[cfg(not(any(usart_v1, usart_v2)))]
 | 
				
			||||||
 | 
					    #[doc(alias("HDSEL"))]
 | 
				
			||||||
 | 
					    pub fn new_half_duplex(
 | 
				
			||||||
 | 
					        peri: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
 | 
					        tx: impl Peripheral<P = impl TxPin<T>> + 'd,
 | 
				
			||||||
 | 
					        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
 | 
				
			||||||
 | 
					        tx_dma: impl Peripheral<P = TxDma> + 'd,
 | 
				
			||||||
 | 
					        rx_dma: impl Peripheral<P = RxDma> + 'd,
 | 
				
			||||||
 | 
					        mut config: Config,
 | 
				
			||||||
 | 
					    ) -> Result<Self, ConfigError> {
 | 
				
			||||||
 | 
					        // UartRx and UartTx have one refcount ea.
 | 
				
			||||||
 | 
					        T::enable_and_reset();
 | 
				
			||||||
 | 
					        T::enable_and_reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config.swap_rx_tx = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        into_ref!(peri, tx, tx_dma, rx_dma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::regs().cr3().write(|w| w.set_hdsel(true));
 | 
				
			||||||
 | 
					        tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Self::new_inner(peri, tx_dma, rx_dma, config)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Create a single-wire half-duplex Uart transceiver on a single Rx pin.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// See [`new_half_duplex`][`Self::new_half_duplex`] if you would prefer to use an Tx pin.
 | 
				
			||||||
 | 
					    /// There is no functional difference between these methods, as both allow bidirectional communication.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// The pin is always released when no data is transmitted. Thus, it acts as a standard
 | 
				
			||||||
 | 
					    /// I/O in idle or in reception.
 | 
				
			||||||
 | 
					    /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
 | 
				
			||||||
 | 
					    /// on the line must be managed by software (for instance by using a centralized arbiter).
 | 
				
			||||||
 | 
					    #[cfg(not(any(usart_v1, usart_v2)))]
 | 
				
			||||||
 | 
					    #[doc(alias("HDSEL"))]
 | 
				
			||||||
 | 
					    pub fn new_half_duplex_on_rx(
 | 
				
			||||||
 | 
					        peri: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
 | 
					        rx: impl Peripheral<P = impl RxPin<T>> + 'd,
 | 
				
			||||||
 | 
					        _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
 | 
				
			||||||
 | 
					        tx_dma: impl Peripheral<P = TxDma> + 'd,
 | 
				
			||||||
 | 
					        rx_dma: impl Peripheral<P = RxDma> + 'd,
 | 
				
			||||||
 | 
					        mut config: Config,
 | 
				
			||||||
 | 
					    ) -> Result<Self, ConfigError> {
 | 
				
			||||||
 | 
					        // UartRx and UartTx have one refcount ea.
 | 
				
			||||||
 | 
					        T::enable_and_reset();
 | 
				
			||||||
 | 
					        T::enable_and_reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config.swap_rx_tx = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        into_ref!(peri, rx, tx_dma, rx_dma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        T::regs().cr3().write(|w| w.set_hdsel(true));
 | 
				
			||||||
 | 
					        rx.set_as_af(rx.af_num(), AFType::OutputPushPull);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Self::new_inner(peri, tx_dma, rx_dma, config)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn new_inner_configure(
 | 
				
			||||||
        peri: impl Peripheral<P = T> + 'd,
 | 
					        peri: impl Peripheral<P = T> + 'd,
 | 
				
			||||||
        rx: impl Peripheral<P = impl RxPin<T>> + 'd,
 | 
					        rx: impl Peripheral<P = impl RxPin<T>> + 'd,
 | 
				
			||||||
        tx: impl Peripheral<P = impl TxPin<T>> + 'd,
 | 
					        tx: impl Peripheral<P = impl TxPin<T>> + 'd,
 | 
				
			||||||
@ -808,8 +874,6 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
 | 
				
			|||||||
    ) -> Result<Self, ConfigError> {
 | 
					    ) -> Result<Self, ConfigError> {
 | 
				
			||||||
        into_ref!(peri, rx, tx, tx_dma, rx_dma);
 | 
					        into_ref!(peri, rx, tx, tx_dma, rx_dma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let r = T::regs();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Some chips do not have swap_rx_tx bit
 | 
					        // Some chips do not have swap_rx_tx bit
 | 
				
			||||||
        cfg_if::cfg_if! {
 | 
					        cfg_if::cfg_if! {
 | 
				
			||||||
            if #[cfg(any(usart_v3, usart_v4))] {
 | 
					            if #[cfg(any(usart_v3, usart_v4))] {
 | 
				
			||||||
@ -827,6 +891,17 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Self::new_inner(peri, tx_dma, rx_dma, config)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn new_inner(
 | 
				
			||||||
 | 
					        peri: PeripheralRef<'d, T>,
 | 
				
			||||||
 | 
					        tx_dma: PeripheralRef<'d, TxDma>,
 | 
				
			||||||
 | 
					        rx_dma: PeripheralRef<'d, RxDma>,
 | 
				
			||||||
 | 
					        config: Config,
 | 
				
			||||||
 | 
					    ) -> Result<Self, ConfigError> {
 | 
				
			||||||
 | 
					        let r = T::regs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        configure(r, &config, T::frequency(), T::KIND, true, true)?;
 | 
					        configure(r, &config, T::frequency(), T::KIND, true, true)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        T::Interrupt::unpend();
 | 
					        T::Interrupt::unpend();
 | 
				
			||||||
 | 
				
			|||||||
@ -701,10 +701,10 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn wait_enabled(&mut self) {
 | 
					    async fn wait_enabled(&mut self) {
 | 
				
			||||||
        trace!("wait_enabled OUT WAITING");
 | 
					        trace!("wait_enabled IN WAITING");
 | 
				
			||||||
        let index = self.info.addr.index();
 | 
					        let index = self.info.addr.index();
 | 
				
			||||||
        poll_fn(|cx| {
 | 
					        poll_fn(|cx| {
 | 
				
			||||||
            EP_OUT_WAKERS[index].register(cx.waker());
 | 
					            EP_IN_WAKERS[index].register(cx.waker());
 | 
				
			||||||
            let regs = T::regs();
 | 
					            let regs = T::regs();
 | 
				
			||||||
            if regs.epr(index).read().stat_tx() == Stat::DISABLED {
 | 
					            if regs.epr(index).read().stat_tx() == Stat::DISABLED {
 | 
				
			||||||
                Poll::Pending
 | 
					                Poll::Pending
 | 
				
			||||||
@ -713,7 +713,7 @@ impl<'d, T: Instance> driver::Endpoint for Endpoint<'d, T, In> {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .await;
 | 
					        .await;
 | 
				
			||||||
        trace!("wait_enabled OUT OK");
 | 
					        trace!("wait_enabled IN OK");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
[toolchain]
 | 
					[toolchain]
 | 
				
			||||||
channel = "beta-2023-12-17"
 | 
					channel = "1.75"
 | 
				
			||||||
components = [ "rust-src", "rustfmt", "llvm-tools" ]
 | 
					components = [ "rust-src", "rustfmt", "llvm-tools" ]
 | 
				
			||||||
targets = [
 | 
					targets = [
 | 
				
			||||||
    "thumbv7em-none-eabi",
 | 
					    "thumbv7em-none-eabi",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user