Add derive macro for BuilderLite, add #[non_exhaustive] to some enums and structs (#2614)
* Add a derive procmacro to implement the Builder Lite pattern for a struct * Add `#[non_exhaustive]` and derive `BuilderLite` where necessary in I2C module * Add `#[non_exhaustive]` and derive `BuilderLite` where necessary in UART module * Add `#[non_exhaustive]` and derive `BuilderLite` where necessary in SPI module * Update `CHANGELOG.md` * Fix build errors in HIL tests * Fix generated doc comments * Return a `ParseError` rather than panicking * Add a method to set the value to `None` for `Option` types
This commit is contained in:
parent
aeda6ac00a
commit
1a2bee6f1f
@ -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
|
||||
|
||||
@ -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<i32>,
|
||||
/// }
|
||||
///
|
||||
/// 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())
|
||||
}
|
||||
|
||||
@ -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<AnyTimer>`, `'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
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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<u32> for Ack {
|
||||
fn from(ack: u32) -> Self {
|
||||
match ack {
|
||||
@ -226,6 +229,7 @@ impl From<u32> for Ack {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ack> for u32 {
|
||||
fn from(ack: Ack) -> u32 {
|
||||
ack as u32
|
||||
@ -233,8 +237,9 @@ impl From<Ack> 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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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<P = impl Instance>, events: impl Into<EnumSet<TxEvent>>) -> Self {
|
||||
crate::into_ref!(uart);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user