diff --git a/esp-hal-procmacros/CHANGELOG.md b/esp-hal-procmacros/CHANGELOG.md index d56177b24..d8793c08a 100644 --- a/esp-hal-procmacros/CHANGELOG.md +++ b/esp-hal-procmacros/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added the `BuilderLite` derive macro which implements the Builder Lite pattern for a struct (#2614) + ### Fixed ### Changed diff --git a/esp-hal-procmacros/src/lib.rs b/esp-hal-procmacros/src/lib.rs index 88936f3cd..f03571c1d 100644 --- a/esp-hal-procmacros/src/lib.rs +++ b/esp-hal-procmacros/src/lib.rs @@ -52,7 +52,22 @@ use proc_macro::{Span, TokenStream}; use proc_macro2::Ident; use proc_macro_crate::{crate_name, FoundCrate}; use proc_macro_error2::abort; -use syn::{parse, parse::Error as ParseError, spanned::Spanned, Item, ItemFn, ReturnType, Type}; +use quote::{format_ident, quote}; +use syn::{ + parse, + parse::Error as ParseError, + spanned::Spanned, + Data, + DataStruct, + GenericArgument, + Item, + ItemFn, + Path, + PathArguments, + PathSegment, + ReturnType, + Type, +}; use self::interrupt::{check_attr_whitelist, WhiteListCaller}; @@ -238,8 +253,8 @@ pub fn ram(args: TokenStream, input: TokenStream) -> TokenStream { /// esp_hal::interrupt::Priority::Priority2)]`. /// /// If no priority is given, `Priority::min()` is assumed -#[proc_macro_error2::proc_macro_error] #[proc_macro_attribute] +#[proc_macro_error2::proc_macro_error] pub fn handler(args: TokenStream, input: TokenStream) -> TokenStream { #[derive(Debug, FromMeta)] struct MacroArgs { @@ -341,8 +356,8 @@ pub fn load_lp_code(input: TokenStream) -> TokenStream { /// Marks the entry function of a LP core / ULP program. #[cfg(any(feature = "is-lp-core", feature = "is-ulp-core"))] -#[proc_macro_error2::proc_macro_error] #[proc_macro_attribute] +#[proc_macro_error2::proc_macro_error] pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { lp_core::entry(args, input) } @@ -381,3 +396,127 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream { run(&args.meta, f, main()).unwrap_or_else(|x| x).into() } + +/// Automatically implement the [Builder Lite] pattern for a struct. +/// +/// This will create an `impl` which contains methods for each field of a +/// struct, allowing users to easily set the values. The generated methods will +/// be the field name prefixed with `with_`, and calls to these methods can be +/// chained as needed. +/// +/// ## Example +/// +/// ```rust, no_run +/// #[derive(Default)] +/// enum MyEnum { +/// #[default] +/// A, +/// B, +/// } +/// +/// #[derive(Default, BuilderLite)] +/// #[non_exhaustive] +/// struct MyStruct { +/// enum_field: MyEnum, +/// bool_field: bool, +/// option_field: Option, +/// } +/// +/// MyStruct::default() +/// .with_enum_field(MyEnum::B) +/// .with_bool_field(true) +/// .with_option_field(-5); +/// ``` +/// +/// [Builder Lite]: https://matklad.github.io/2022/05/29/builder-lite.html +#[proc_macro_derive(BuilderLite)] +pub fn builder_lite_derive(item: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(item as syn::DeriveInput); + + let span = input.span(); + let ident = input.ident; + + let mut fns = Vec::new(); + if let Data::Struct(DataStruct { fields, .. }) = &input.data { + for field in fields { + let field_ident = field.ident.as_ref().unwrap(); + let field_type = &field.ty; + + let function_ident = format_ident!("with_{}", field_ident); + + let maybe_path_type = extract_type_path(field_type) + .and_then(|path| extract_option_segment(path)) + .and_then(|path_seg| match path_seg.arguments { + PathArguments::AngleBracketed(ref params) => params.args.first(), + _ => None, + }) + .and_then(|generic_arg| match *generic_arg { + GenericArgument::Type(ref ty) => Some(ty), + _ => None, + }); + + let (field_type, field_assigns) = if let Some(inner_type) = maybe_path_type { + (inner_type, quote! { Some(#field_ident) }) + } else { + (field_type, quote! { #field_ident }) + }; + + fns.push(quote! { + #[doc = concat!(" Assign the given value to the `", stringify!(#field_ident) ,"` field.")] + pub fn #function_ident(mut self, #field_ident: #field_type) -> Self { + self.#field_ident = #field_assigns; + self + } + }); + + if maybe_path_type.is_some() { + let function_ident = format_ident!("with_{}_none", field_ident); + fns.push(quote! { + #[doc = concat!(" Set the value of `", stringify!(#field_ident), "` to `None`.")] + pub fn #function_ident(mut self) -> Self { + self.#field_ident = None; + self + } + }); + } + } + } else { + return ParseError::new( + span, + "#[derive(Builder)] is only defined for structs, not for enums or unions!", + ) + .to_compile_error() + .into(); + } + + let implementation = quote! { + #[automatically_derived] + impl #ident { + #(#fns)* + } + }; + + implementation.into() +} + +// https://stackoverflow.com/a/56264023 +fn extract_type_path(ty: &Type) -> Option<&Path> { + match *ty { + Type::Path(ref typepath) if typepath.qself.is_none() => Some(&typepath.path), + _ => None, + } +} + +// https://stackoverflow.com/a/56264023 +fn extract_option_segment(path: &Path) -> Option<&PathSegment> { + let idents_of_path = path.segments.iter().fold(String::new(), |mut acc, v| { + acc.push_str(&v.ident.to_string()); + acc.push('|'); + acc + }); + + vec!["Option|", "std|option|Option|", "core|option|Option|"] + .into_iter() + .find(|s| idents_of_path == *s) + .and_then(|_| path.segments.last()) +} diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 360c1427d..9f5925339 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `esp_hal::psram::psram_raw_parts` (#2546) - The timer drivers `OneShotTimer` & `PeriodicTimer` have `into_async` and `new_typed` methods (#2586) - `timer::Timer` trait has three new methods, `wait`, `async_interrupt_handler` and `peripheral_interrupt` (#2586) +- Configuration structs in the I2C, SPI, and UART drivers now implement the Builder Lite pattern (#2614) ### Changed @@ -42,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The timer drivers `OneShotTimer` & `PeriodicTimer` now have a `Mode` parameter and type erase the underlying driver by default (#2586) - `timer::Timer` has new trait requirements of `Into`, `'static` and `InterruptConfigurable` (#2586) - `systimer::etm::Event` no longer borrows the alarm indefinitely (#2586) +- A number of public enums and structs in the I2C, SPI, and UART drivers have been marked with `#[non_exhaustive]` (#2614) ### Fixed diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index f6e520f71..29b547470 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -28,11 +28,7 @@ //! //! let mut spi = Spi::new_with_config( //! peripherals.SPI2, -//! Config { -//! frequency: 100.kHz(), -//! mode: SpiMode::Mode0, -//! ..Config::default() -//! }, +//! Config::default().with_frequency(100.kHz()).with_mode(SpiMode::Mode0) //! ) //! .with_sck(sclk) //! .with_mosi(mosi) diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index 613da6dbe..4a9daed95 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -86,6 +86,7 @@ const MAX_ITERATIONS: u32 = 1_000_000; /// I2C-specific transmission errors #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum Error { /// The transmission exceeded the FIFO size. ExceedingFifo, @@ -106,14 +107,15 @@ pub enum Error { /// I2C-specific configuration errors #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum ConfigError {} -#[derive(PartialEq)] // This enum is used to keep track of the last/next operation that was/will be // performed in an embedded-hal(-async) I2c::transaction. It is used to // determine whether a START condition should be issued at the start of the // current operation and whether a read needs an ack or a nack for the final // byte. +#[derive(PartialEq)] enum OpKind { Write, Read, @@ -217,6 +219,7 @@ enum Ack { Ack = 0, Nack = 1, } + impl From for Ack { fn from(ack: u32) -> Self { match ack { @@ -226,6 +229,7 @@ impl From for Ack { } } } + impl From for u32 { fn from(ack: Ack) -> u32 { ack as u32 @@ -233,8 +237,9 @@ impl From for u32 { } /// I2C driver configuration -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, procmacros::BuilderLite)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub struct Config { /// The I2C clock frequency. pub frequency: HertzU32, diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 41084201e..4c5b943fc 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -45,11 +45,7 @@ //! //! let mut spi = Spi::new_with_config( //! peripherals.SPI2, -//! Config { -//! frequency: 100.kHz(), -//! mode: SpiMode::Mode0, -//! ..Config::default() -//! }, +//! Config::default().with_frequency(100.kHz()).with_mode(SpiMode::Mode0) //! ) //! .with_sck(sclk) //! .with_mosi(mosi) @@ -93,6 +89,7 @@ use crate::{ #[cfg(gdma)] #[derive(Debug, EnumSetType)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum SpiInterrupt { /// Indicates that the SPI transaction has completed successfully. /// @@ -423,8 +420,9 @@ impl Address { } /// SPI peripheral configuration -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, procmacros::BuilderLite)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub struct Config { /// SPI clock frequency pub frequency: HertzU32, diff --git a/esp-hal/src/spi/mod.rs b/esp-hal/src/spi/mod.rs index 7ac8b313a..f3546f65c 100644 --- a/esp-hal/src/spi/mod.rs +++ b/esp-hal/src/spi/mod.rs @@ -17,6 +17,7 @@ pub mod slave; /// SPI errors #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum Error { /// Error occurred due to a DMA-related issue. DmaError(DmaError), diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index bb0f3af42..8ec7f4b7c 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -244,6 +244,7 @@ const UART_FIFO_SIZE: u16 = 128; /// UART Error #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum Error { /// An invalid configuration argument was provided. /// @@ -289,21 +290,23 @@ impl embedded_io::Error for Error { // (outside of `config` module in order not to "use" it an extra time) /// UART clock source -#[derive(PartialEq, Eq, Copy, Clone, Debug)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ClockSource { /// APB_CLK clock source (default for UART on all the chips except of /// esp32c6 and esp32h2) + #[cfg_attr(not(any(esp32c6, esp32h2, lp_uart)), default)] Apb, - #[cfg(not(any(esp32, esp32s2)))] /// RC_FAST_CLK clock source (17.5 MHz) - RcFast, #[cfg(not(any(esp32, esp32s2)))] + RcFast, /// XTAL_CLK clock source (default for UART on esp32c6 and esp32h2 and /// LP_UART) + #[cfg(not(any(esp32, esp32s2)))] + #[cfg_attr(any(esp32c6, esp32h2, lp_uart), default)] Xtal, - #[cfg(any(esp32, esp32s2))] /// REF_TICK clock source (derived from XTAL or RC_FAST, 1MHz) + #[cfg(any(esp32, esp32s2))] RefTick, } @@ -317,7 +320,7 @@ const UART_TOUT_THRESH_DEFAULT: u8 = 10; /// This enum represents the various configurations for the number of data /// bits used in UART communication. The number of data bits defines the /// length of each transmitted or received data frame. -#[derive(PartialEq, Eq, Copy, Clone, Debug)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum DataBits { /// 5 data bits per frame. @@ -327,6 +330,7 @@ pub enum DataBits { /// 7 data bits per frame. DataBits7 = 2, /// 8 data bits per frame (most common). + #[default] DataBits8 = 3, } @@ -336,10 +340,11 @@ pub enum DataBits { /// ensure that the data has not been corrupted during transmission. The /// parity bit is added to the data bits to make the number of 1-bits /// either even or odd. -#[derive(PartialEq, Eq, Copy, Clone, Debug)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Parity { /// No parity bit is used (most common). + #[default] ParityNone, /// Even parity: the parity bit is set to make the total number of /// 1-bits even. @@ -354,10 +359,11 @@ pub enum Parity { /// The stop bit(s) signal the end of a data packet in UART communication. /// This enum defines the possible configurations for the number of stop /// bits. -#[derive(PartialEq, Eq, Copy, Clone, Debug)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum StopBits { /// 1 stop bit. + #[default] STOP1 = 1, /// 1.5 stop bits. STOP1P5 = 2, @@ -366,8 +372,9 @@ pub enum StopBits { } /// UART Configuration -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone, Copy, procmacros::BuilderLite)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub struct Config { /// The baud rate (speed) of the UART communication in bits per second /// (bps). @@ -467,18 +474,10 @@ impl Default for Config { fn default() -> Config { Config { baudrate: 115_200, - data_bits: DataBits::DataBits8, - parity: Parity::ParityNone, - stop_bits: StopBits::STOP1, - clock_source: { - cfg_if::cfg_if! { - if #[cfg(any(esp32c6, esp32h2, lp_uart))] { - ClockSource::Xtal - } else { - ClockSource::Apb - } - } - }, + data_bits: Default::default(), + parity: Default::default(), + stop_bits: Default::default(), + clock_source: Default::default(), rx_fifo_full_threshold: UART_FULL_THRESH_DEFAULT, rx_timeout: Some(UART_TOUT_THRESH_DEFAULT), } @@ -1158,6 +1157,7 @@ where /// List of exposed UART events. #[derive(Debug, EnumSetType)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] pub enum UartInterrupt { /// Indicates that the received has detected the configured /// [`Uart::set_at_cmd`] character. @@ -1589,12 +1589,13 @@ where } } -#[derive(EnumSetType, Debug)] +#[derive(Debug, EnumSetType)] pub(crate) enum TxEvent { TxDone, TxFiFoEmpty, } -#[derive(EnumSetType, Debug)] + +#[derive(Debug, EnumSetType)] pub(crate) enum RxEvent { FifoFull, CmdCharDetected, @@ -1705,6 +1706,7 @@ struct UartTxFuture { state: &'static State, registered: bool, } + impl UartTxFuture { fn new(uart: impl Peripheral

, events: impl Into>) -> Self { crate::into_ref!(uart); diff --git a/examples/src/bin/embassy_spi.rs b/examples/src/bin/embassy_spi.rs index 1d7e8f9fd..de95e0714 100644 --- a/examples/src/bin/embassy_spi.rs +++ b/examples/src/bin/embassy_spi.rs @@ -59,11 +59,9 @@ async fn main(_spawner: Spawner) { let mut spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_mosi(mosi) diff --git a/examples/src/bin/spi_loopback.rs b/examples/src/bin/spi_loopback.rs index 67ff6a9a7..191ebdee8 100644 --- a/examples/src/bin/spi_loopback.rs +++ b/examples/src/bin/spi_loopback.rs @@ -39,11 +39,9 @@ fn main() -> ! { let mut spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_miso(miso) // order matters diff --git a/examples/src/bin/spi_loopback_dma_psram.rs b/examples/src/bin/spi_loopback_dma_psram.rs index 72787eb40..02d53a002 100644 --- a/examples/src/bin/spi_loopback_dma_psram.rs +++ b/examples/src/bin/spi_loopback_dma_psram.rs @@ -90,11 +90,9 @@ fn main() -> ! { // output connection (because we are using the same pin to loop back) let mut spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_miso(miso) diff --git a/hil-test/tests/embassy_interrupt_spi_dma.rs b/hil-test/tests/embassy_interrupt_spi_dma.rs index 82ddbfd82..c59f51e54 100644 --- a/hil-test/tests/embassy_interrupt_spi_dma.rs +++ b/hil-test/tests/embassy_interrupt_spi_dma.rs @@ -120,11 +120,9 @@ mod test { let mut spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 10000.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(10000.kHz()) + .with_mode(SpiMode::Mode0), ) .with_miso(unsafe { mosi.clone_unchecked() }) .with_mosi(mosi) @@ -135,11 +133,9 @@ mod test { #[cfg(any(esp32, esp32s2, esp32s3))] let other_peripheral = Spi::new_with_config( peripherals.SPI3, - Config { - frequency: 10000.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(10000.kHz()) + .with_mode(SpiMode::Mode0), ) .with_dma(dma_channel2) .into_async(); @@ -231,11 +227,9 @@ mod test { let mut spi = Spi::new_with_config( peripherals.spi, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_dma(peripherals.dma_channel) .with_buffers(dma_rx_buf, dma_tx_buf) diff --git a/hil-test/tests/qspi.rs b/hil-test/tests/qspi.rs index 1c9f46fc3..95033daf6 100644 --- a/hil-test/tests/qspi.rs +++ b/hil-test/tests/qspi.rs @@ -202,11 +202,9 @@ mod tests { let spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ); Context { diff --git a/hil-test/tests/spi_full_duplex.rs b/hil-test/tests/spi_full_duplex.rs index 756833d9c..1a5517b84 100644 --- a/hil-test/tests/spi_full_duplex.rs +++ b/hil-test/tests/spi_full_duplex.rs @@ -73,16 +73,11 @@ mod tests { let (mosi_loopback_pcnt, mosi) = mosi.split(); // Need to set miso first so that mosi can overwrite the // output connection (because we are using the same pin to loop back) - let spi = Spi::new_with_config( - peripherals.SPI2, - Config { - frequency: 10.MHz(), - ..Config::default() - }, - ) - .with_sck(sclk) - .with_miso(unsafe { mosi.clone_unchecked() }) - .with_mosi(mosi); + let spi = + Spi::new_with_config(peripherals.SPI2, Config::default().with_frequency(10.MHz())) + .with_sck(sclk) + .with_miso(unsafe { mosi.clone_unchecked() }) + .with_mosi(mosi); let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(32000); @@ -487,10 +482,7 @@ mod tests { // This means that without working cancellation, the test case should // fail. ctx.spi - .apply_config(&Config { - frequency: 80.kHz(), - ..Config::default() - }) + .apply_config(&Config::default().with_frequency(80.kHz())) .unwrap(); // Set up a large buffer that would trigger a timeout @@ -513,10 +505,7 @@ mod tests { fn can_transmit_after_cancel(mut ctx: Context) { // Slow down. At 80kHz, the transfer is supposed to take a bit over 3 seconds. ctx.spi - .apply_config(&Config { - frequency: 80.kHz(), - ..Config::default() - }) + .apply_config(&Config::default().with_frequency(80.kHz())) .unwrap(); // Set up a large buffer that would trigger a timeout @@ -533,11 +522,8 @@ mod tests { transfer.cancel(); (spi, (dma_rx_buf, dma_tx_buf)) = transfer.wait(); - spi.apply_config(&Config { - frequency: 10.MHz(), - ..Config::default() - }) - .unwrap(); + spi.apply_config(&Config::default().with_frequency(10.MHz())) + .unwrap(); let transfer = spi .transfer(dma_rx_buf, dma_tx_buf) diff --git a/hil-test/tests/spi_half_duplex_read.rs b/hil-test/tests/spi_half_duplex_read.rs index c1c92da8b..27564c02a 100644 --- a/hil-test/tests/spi_half_duplex_read.rs +++ b/hil-test/tests/spi_half_duplex_read.rs @@ -48,11 +48,9 @@ mod tests { let spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_miso(miso) diff --git a/hil-test/tests/spi_half_duplex_write.rs b/hil-test/tests/spi_half_duplex_write.rs index fdd0cf43b..a58ea3c49 100644 --- a/hil-test/tests/spi_half_duplex_write.rs +++ b/hil-test/tests/spi_half_duplex_write.rs @@ -52,11 +52,9 @@ mod tests { let spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_mosi(mosi) diff --git a/hil-test/tests/spi_half_duplex_write_psram.rs b/hil-test/tests/spi_half_duplex_write_psram.rs index cb19aafd0..52fe8f75c 100644 --- a/hil-test/tests/spi_half_duplex_write_psram.rs +++ b/hil-test/tests/spi_half_duplex_write_psram.rs @@ -64,11 +64,9 @@ mod tests { let spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_mosi(mosi) diff --git a/hil-test/tests/uart.rs b/hil-test/tests/uart.rs index 38e3b9db4..85c5ab904 100644 --- a/hil-test/tests/uart.rs +++ b/hil-test/tests/uart.rs @@ -90,11 +90,11 @@ mod tests { let mut byte_to_write = 0xA5; for (baudrate, clock_source) in configs { ctx.uart - .apply_config(&uart::Config { - baudrate, - clock_source, - ..Default::default() - }) + .apply_config( + &uart::Config::default() + .with_baudrate(baudrate) + .with_clock_source(clock_source), + ) .unwrap(); ctx.uart.write(byte_to_write).ok(); let read = block!(ctx.uart.read()); diff --git a/qa-test/src/bin/lcd_dpi.rs b/qa-test/src/bin/lcd_dpi.rs index 6785ff0b8..7b3b0e04f 100644 --- a/qa-test/src/bin/lcd_dpi.rs +++ b/qa-test/src/bin/lcd_dpi.rs @@ -36,8 +36,7 @@ use esp_hal::{ delay::Delay, dma_loop_buffer, gpio::{Level, Output}, - i2c, - i2c::master::I2c, + i2c::{self, master::I2c}, lcd_cam::{ lcd::{ dpi::{Config, Dpi, Format, FrameTiming}, @@ -61,10 +60,7 @@ fn main() -> ! { let i2c = I2c::new( peripherals.I2C0, - i2c::master::Config { - frequency: 400.kHz(), - ..Default::default() - }, + i2c::master::Config::default().with_frequency(400.kHz()), ) .with_sda(peripherals.GPIO47) .with_scl(peripherals.GPIO48); diff --git a/qa-test/src/bin/qspi_flash.rs b/qa-test/src/bin/qspi_flash.rs index 861a3f4eb..7b960f9fd 100644 --- a/qa-test/src/bin/qspi_flash.rs +++ b/qa-test/src/bin/qspi_flash.rs @@ -77,11 +77,9 @@ fn main() -> ! { let mut spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_mosi(mosi) diff --git a/qa-test/src/bin/spi_halfduplex_read_manufacturer_id.rs b/qa-test/src/bin/spi_halfduplex_read_manufacturer_id.rs index 6ea46778f..3faae70ca 100644 --- a/qa-test/src/bin/spi_halfduplex_read_manufacturer_id.rs +++ b/qa-test/src/bin/spi_halfduplex_read_manufacturer_id.rs @@ -63,11 +63,9 @@ fn main() -> ! { let mut spi = Spi::new_with_config( peripherals.SPI2, - Config { - frequency: 100.kHz(), - mode: SpiMode::Mode0, - ..Config::default() - }, + Config::default() + .with_frequency(100.kHz()) + .with_mode(SpiMode::Mode0), ) .with_sck(sclk) .with_mosi(mosi)