diff --git a/documentation/API-GUIDELINES.md b/documentation/API-GUIDELINES.md index d92521a540..26de75d322 100644 --- a/documentation/API-GUIDELINES.md +++ b/documentation/API-GUIDELINES.md @@ -30,12 +30,17 @@ In general, the [Rust API Guidelines](https://rust-lang.github.io/api-guidelines - The peripheral instance type must default to a type that supports any of the peripheral instances. - The author must to use `crate::any_peripheral` to define the "any" peripheral instance type. - The driver must implement a `new` constructor that automatically converts the peripheral instance into the any type, and a `new_typed` that preserves the peripheral type. +- If a driver is configurable, configuration options should be implemented as a `Config` struct in the same module where the driver is located. + - The driver's constructor should take the config struct by value, and it should return `Result`. + - The `ConfigError` enum should be separate from other `Error` enums used by the driver. + - The driver should implement `fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError>`. + - In case the driver's configuration is infallible (all possible combinations of options are supported by the hardware), the `ConfigError` should be implemented as an empty `enum`. - If a driver only supports a single peripheral instance, no instance type parameter is necessary. - If a driver implements both blocking and async operations, or only implements blocking operations, but may support asynchronous ones in the future, the driver's type signature must include a `crate::Mode` type parameter. - By default, constructors must configure the driver for blocking mode. The driver must implement `into_async` (and a matching `into_blocking`) function that reconfigures the driver. - `into_async` must configure the driver and/or the associated DMA channels. This most often means enabling an interrupt handler. - `into_blocking` must undo the configuration done by `into_async`. -- The asynchronous driver implemntation must also expose the blocking methods (except for interrupt related functions). +- The asynchronous driver implementation must also expose the blocking methods (except for interrupt related functions). - Drivers must have a `Drop` implementation resetting the peripheral to idle state. There are some exceptions to this: - GPIO where common usage is to "set and drop" so they can't be changed - Where we don't want to disable the peripheral as it's used internally, for example SYSTIMER is used by `time::now()` API. See `KEEP_ENABLED` in src/system.rs diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 9f59253395..17af6b314d 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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) +- Added `I8080::apply_config`, `DPI::apply_config` and `Camera::apply_config` (#2610) ### Changed @@ -44,6 +45,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `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) +- Interrupt handling related functions are only provided for Blocking UART. (#2610) +- Changed how `Spi`, (split or unsplit) `Uart`, `LpUart`, `I8080`, `Camera`, `DPI` and `I2C` drivers are constructed (#2610) +- I8080, camera, DPI: The various standalone configuration options have been merged into `Config` (#2610) ### Fixed @@ -58,7 +62,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `FrozenUnit`, `AnyUnit`, `SpecificUnit`, `SpecificComparator`, `AnyComparator` have been removed from `systimer` (#2576) - `esp_hal::psram::psram_range` (#2546) - The `Dma` structure has been removed. (#2545) -- Remove `embedded-hal 0.2.x` impls and deps from `esp-hal` (#2593) +- Removed `embedded-hal 0.2.x` impls and deps from `esp-hal` (#2593) +- Removed `Camera::set_` functions (#2610) ## [0.22.0] - 2024-11-20 diff --git a/esp-hal/MIGRATING-0.22.md b/esp-hal/MIGRATING-0.22.md index 64ca5ea996..bb941d96f8 100644 --- a/esp-hal/MIGRATING-0.22.md +++ b/esp-hal/MIGRATING-0.22.md @@ -188,7 +188,7 @@ is enabled. To retrieve the address and size of the initialized external memory, The usage of `esp_alloc::psram_allocator!` remains unchanged. -### embedded-hal 0.2.* is not supported anymore. +## embedded-hal 0.2.* is not supported anymore. As per https://github.com/rust-embedded/embedded-hal/pull/640, our driver no longer implements traits from `embedded-hal 0.2.x`. Analogs of all traits from the above mentioned version are available in `embedded-hal 1.x.x` @@ -221,3 +221,49 @@ https://github.com/rust-embedded/embedded-hal/blob/master/docs/migrating-from-0. + use esp_hal::interrupt::InterruptConfigurable; + use esp_hal::interrupt::DEFAULT_INTERRUPT_HANDLER; ``` + +## Driver constructors now take a configuration and are fallible + +The old `new_with_config` constructor have been removed, and `new` constructors now always take +a configuration structure. They have also been updated to return a `ConfigError` if the configuration +is not compatible with the hardware. + +```diff +-let mut spi = Spi::new_with_config( ++let mut spi = Spi::new( + peripherals.SPI2, + Config { + frequency: 100.kHz(), + mode: SpiMode::Mode0, + ..Config::default() + }, +-); ++) ++.unwrap(); +``` + +```diff + let mut spi = Spi::new( + peripherals.SPI2, ++ Config::default(), +-); ++) ++.unwrap(); +``` + +### LCD_CAM configuration changes + +- `cam` now has a `Config` strurct that contains frequency, bit/byte order, VSync filter options. +- DPI, I8080: `frequency` has been moved into `Config`. + +```diff ++let mut cam_config = cam::Config::default(); ++cam_config.frequency = 1u32.MHz(); + cam::Camera::new( + lcd_cam.cam, + dma_rx_channel, + pins, +- 1u32.MHz(), ++ cam_config, + ) +``` diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index 29b5474706..419014720a 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -26,10 +26,11 @@ //! let mosi = peripherals.GPIO4; //! let cs = peripherals.GPIO5; //! -//! let mut spi = Spi::new_with_config( +//! let mut spi = Spi::new( //! peripherals.SPI2, //! Config::default().with_frequency(100.kHz()).with_mode(SpiMode::Mode0) //! ) +//! .unwrap() //! .with_sck(sclk) //! .with_mosi(mosi) //! .with_miso(miso) @@ -1688,10 +1689,11 @@ impl DmaChannelConvert for DEG { #[cfg_attr(pdma, doc = "let dma_channel = peripherals.DMA_SPI2;")] #[cfg_attr(gdma, doc = "let dma_channel = peripherals.DMA_CH0;")] #[doc = ""] -/// let spi = Spi::new_with_config( +/// let spi = Spi::new( /// peripherals.SPI2, /// Config::default(), -/// ); +/// ) +/// .unwrap(); /// /// let spi_dma = configures_spi_dma(spi, dma_channel); /// # } diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index 4a9daed950..5024ca81ab 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -25,6 +25,7 @@ //! peripherals.I2C0, //! Config::default(), //! ) +//! .unwrap() //! .with_sda(peripherals.GPIO1) //! .with_scl(peripherals.GPIO2); //! @@ -421,7 +422,10 @@ impl<'d> I2c<'d, Blocking> { /// Create a new I2C instance /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. - pub fn new(i2c: impl Peripheral

+ 'd, config: Config) -> Self { + pub fn new( + i2c: impl Peripheral

+ 'd, + config: Config, + ) -> Result { Self::new_typed(i2c.map_into(), config) } } @@ -433,7 +437,10 @@ where /// Create a new I2C instance /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. - pub fn new_typed(i2c: impl Peripheral

+ 'd, config: Config) -> Self { + pub fn new_typed( + i2c: impl Peripheral

+ 'd, + config: Config, + ) -> Result { crate::into_ref!(i2c); let guard = PeripheralGuard::new(i2c.info().peripheral); @@ -445,8 +452,9 @@ where guard, }; - unwrap!(i2c.driver().setup(&i2c.config)); - i2c + i2c.driver().setup(&i2c.config)?; + + Ok(i2c) } // TODO: missing interrupt APIs diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index ad772bf708..abe7d8c767 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -16,7 +16,7 @@ //! master mode. //! ```rust, no_run #![doc = crate::before_snippet!()] -//! # use esp_hal::lcd_cam::{cam::{Camera, RxEightBits}, LcdCam}; +//! # use esp_hal::lcd_cam::{cam::{Camera, Config, RxEightBits}, LcdCam}; //! # use fugit::RateExtU32; //! # use esp_hal::dma_rx_stream_buffer; //! @@ -37,15 +37,18 @@ //! peripherals.GPIO16, //! ); //! +//! let mut config = Config::default(); +//! config.frequency = 20.MHz(); +//! //! let lcd_cam = LcdCam::new(peripherals.LCD_CAM); //! let mut camera = Camera::new( //! lcd_cam.cam, //! peripherals.DMA_CH0, //! data_pins, -//! 20u32.MHz(), +//! config, //! ) -//! // Remove this for slave mode. -//! .with_master_clock(mclk_pin) +//! .unwrap() +//! .with_master_clock(mclk_pin) // Remove this for slave mode //! .with_pixel_clock(pclk_pin) //! .with_ctrl_pins(vsync_pin, href_pin); //! @@ -59,7 +62,7 @@ use core::{ ops::{Deref, DerefMut}, }; -use fugit::HertzU32; +use fugit::{HertzU32, RateExtU32}; use crate::{ clock::Clocks, @@ -70,7 +73,7 @@ use crate::{ OutputSignal, Pull, }, - lcd_cam::{calculate_clkm, BitOrder, ByteOrder}, + lcd_cam::{calculate_clkm, BitOrder, ByteOrder, ClockError}, peripheral::{Peripheral, PeripheralRef}, peripherals::LCD_CAM, system::{self, GenericPeripheralGuard}, @@ -109,6 +112,14 @@ pub enum VsyncFilterThreshold { Eight, } +/// Vsync Filter Threshold +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ConfigError { + /// The frequency is out of range. + Clock(ClockError), +} + /// Represents the camera interface. pub struct Cam<'d> { /// The LCD_CAM peripheral reference for managing the camera functionality. @@ -129,109 +140,86 @@ impl<'d> Camera<'d> { cam: Cam<'d>, channel: impl Peripheral

+ 'd, _pins: P, - frequency: HertzU32, - ) -> Self + config: Config, + ) -> Result where CH: RxChannelFor, P: RxPins, { let rx_channel = ChannelRx::new(channel.map(|ch| ch.degrade())); - let lcd_cam = cam.lcd_cam; + let mut this = Self { + lcd_cam: cam.lcd_cam, + rx_channel, + _guard: cam._guard, + }; + + this.lcd_cam + .cam_ctrl1() + .modify(|_, w| w.cam_2byte_en().bit(P::BUS_WIDTH == 2)); + + this.apply_config(&config)?; + + Ok(this) + } + + /// Applies the configuration to the camera interface. + pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> { let clocks = Clocks::get(); let (i, divider) = calculate_clkm( - frequency.to_Hz() as _, + config.frequency.to_Hz() as _, &[ clocks.xtal_clock.to_Hz() as _, clocks.cpu_clock.to_Hz() as _, clocks.crypto_pwm_clock.to_Hz() as _, ], - ); + ) + .map_err(ConfigError::Clock)?; - lcd_cam.cam_ctrl().write(|w| { + self.lcd_cam.cam_ctrl().write(|w| { // Force enable the clock for all configuration registers. unsafe { w.cam_clk_sel().bits((i + 1) as _); w.cam_clkm_div_num().bits(divider.div_num as _); w.cam_clkm_div_b().bits(divider.div_b as _); w.cam_clkm_div_a().bits(divider.div_a as _); - w.cam_vsync_filter_thres().bits(0); + if let Some(threshold) = config.vsync_filter_threshold { + w.cam_vsync_filter_thres().bits(threshold as _); + } + w.cam_byte_order() + .bit(config.byte_order != ByteOrder::default()); + w.cam_bit_order() + .bit(config.bit_order != BitOrder::default()); w.cam_vs_eof_en().set_bit(); w.cam_line_int_en().clear_bit(); w.cam_stop_en().clear_bit() } }); - lcd_cam.cam_ctrl1().write(|w| unsafe { + self.lcd_cam.cam_ctrl1().modify(|_, w| unsafe { w.cam_vh_de_mode_en().set_bit(); w.cam_rec_data_bytelen().bits(0); w.cam_line_int_num().bits(0); - w.cam_vsync_filter_en().clear_bit(); - w.cam_2byte_en().bit(P::BUS_WIDTH == 2); + w.cam_vsync_filter_en() + .bit(config.vsync_filter_threshold.is_some()); w.cam_clk_inv().clear_bit(); w.cam_de_inv().clear_bit(); w.cam_hsync_inv().clear_bit(); w.cam_vsync_inv().clear_bit() }); - lcd_cam + self.lcd_cam .cam_rgb_yuv() .write(|w| w.cam_conv_bypass().clear_bit()); - lcd_cam.cam_ctrl().modify(|_, w| w.cam_update().set_bit()); - - Self { - lcd_cam, - rx_channel, - _guard: cam._guard, - } - } -} - -impl<'d> Camera<'d> { - /// Configures the byte order for the camera data. - pub fn set_byte_order(&mut self, byte_order: ByteOrder) -> &mut Self { self.lcd_cam .cam_ctrl() - .modify(|_, w| w.cam_byte_order().bit(byte_order != ByteOrder::default())); - self - } - - /// Configures the bit order for the camera data. - pub fn set_bit_order(&mut self, bit_order: BitOrder) -> &mut Self { - self.lcd_cam - .cam_ctrl() - .modify(|_, w| w.cam_bit_order().bit(bit_order != BitOrder::default())); - self - } + .modify(|_, w| w.cam_update().set_bit()); - /// Configures the VSYNC filter threshold. - pub fn set_vsync_filter(&mut self, threshold: Option) -> &mut Self { - if let Some(threshold) = threshold { - let value = match threshold { - VsyncFilterThreshold::One => 0, - VsyncFilterThreshold::Two => 1, - VsyncFilterThreshold::Three => 2, - VsyncFilterThreshold::Four => 3, - VsyncFilterThreshold::Five => 4, - VsyncFilterThreshold::Six => 5, - VsyncFilterThreshold::Seven => 6, - VsyncFilterThreshold::Eight => 7, - }; - - self.lcd_cam - .cam_ctrl() - .modify(|_, w| unsafe { w.cam_vsync_filter_thres().bits(value) }); - self.lcd_cam - .cam_ctrl1() - .modify(|_, w| w.cam_vsync_filter_en().set_bit()); - } else { - self.lcd_cam - .cam_ctrl1() - .modify(|_, w| w.cam_vsync_filter_en().clear_bit()); - } - self + Ok(()) } +} +impl<'d> Camera<'d> { /// Configures the master clock (MCLK) pin for the camera interface. pub fn with_master_clock( self, @@ -605,3 +593,31 @@ impl RxPins for RxSixteenBits { pub trait RxPins { const BUS_WIDTH: usize; } + +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +/// Configuration settings for the Camera interface. +pub struct Config { + /// The pixel clock frequency for the camera interface. + pub frequency: HertzU32, + + /// The byte order for the camera data. + pub byte_order: ByteOrder, + + /// The bit order for the camera data. + pub bit_order: BitOrder, + + /// The Vsync filter threshold. + pub vsync_filter_threshold: Option, +} + +impl Default for Config { + fn default() -> Self { + Self { + frequency: 20.MHz(), + byte_order: Default::default(), + bit_order: Default::default(), + vsync_filter_threshold: None, + } + } +} diff --git a/esp-hal/src/lcd_cam/lcd/dpi.rs b/esp-hal/src/lcd_cam/lcd/dpi.rs index c7330a4482..368ae1c8ae 100644 --- a/esp-hal/src/lcd_cam/lcd/dpi.rs +++ b/esp-hal/src/lcd_cam/lcd/dpi.rs @@ -31,6 +31,7 @@ //! let lcd_cam = LcdCam::new(peripherals.LCD_CAM); //! //! let mut config = dpi::Config::default(); +//! config.frequency = 1.MHz(); //! config.clock_mode = ClockMode { //! polarity: Polarity::IdleLow, //! phase: Phase::ShiftLow, @@ -58,7 +59,7 @@ //! config.de_idle_level = Level::Low; //! config.disable_black_region = false; //! -//! let mut dpi = Dpi::new(lcd_cam.lcd, channel, 1.MHz(), config) +//! let mut dpi = Dpi::new(lcd_cam.lcd, channel, config).unwrap() //! .with_vsync(peripherals.GPIO3) //! .with_hsync(peripherals.GPIO46) //! .with_de(peripherals.GPIO17) @@ -99,7 +100,7 @@ use core::{ ops::{Deref, DerefMut}, }; -use fugit::HertzU32; +use fugit::{HertzU32, RateExtU32}; use crate::{ clock::Clocks, @@ -110,6 +111,7 @@ use crate::{ lcd::{ClockMode, DelayMode, Lcd, Phase, Polarity}, BitOrder, ByteOrder, + ClockError, }, peripheral::{Peripheral, PeripheralRef}, peripherals::LCD_CAM, @@ -117,6 +119,14 @@ use crate::{ Mode, }; +/// Errors that can occur when configuring the DPI peripheral. +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ConfigError { + /// Clock configuration error. + Clock(ClockError), +} + /// Represents the RGB LCD interface. pub struct Dpi<'d, DM: Mode> { lcd_cam: PeripheralRef<'d, LCD_CAM>, @@ -132,29 +142,41 @@ where pub fn new( lcd: Lcd<'d, DM>, channel: impl Peripheral

+ 'd, - frequency: HertzU32, config: Config, - ) -> Self + ) -> Result where CH: TxChannelFor, { let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade())); - let lcd_cam = lcd.lcd_cam; + let mut this = Self { + lcd_cam: lcd.lcd_cam, + tx_channel, + _mode: PhantomData, + }; + + this.apply_config(&config)?; + + Ok(this) + } + + /// Applies the configuration to the peripheral. + pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> { let clocks = Clocks::get(); // Due to https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf // the LCD_PCLK divider must be at least 2. To make up for this the user // provided frequency is doubled to match. let (i, divider) = calculate_clkm( - (frequency.to_Hz() * 2) as _, + (config.frequency.to_Hz() * 2) as _, &[ clocks.xtal_clock.to_Hz() as _, clocks.cpu_clock.to_Hz() as _, clocks.crypto_pwm_clock.to_Hz() as _, ], - ); + ) + .map_err(ConfigError::Clock)?; - lcd_cam.lcd_clock().write(|w| unsafe { + self.lcd_cam.lcd_clock().write(|w| unsafe { // Force enable the clock for all configuration registers. w.clk_en().set_bit(); w.lcd_clk_sel().bits((i + 1) as _); @@ -168,13 +190,15 @@ where w.lcd_ck_out_edge() .bit(config.clock_mode.phase == Phase::ShiftHigh) }); - lcd_cam.lcd_user().modify(|_, w| w.lcd_reset().set_bit()); + self.lcd_cam + .lcd_user() + .modify(|_, w| w.lcd_reset().set_bit()); - lcd_cam + self.lcd_cam .lcd_rgb_yuv() .write(|w| w.lcd_conv_bypass().clear_bit()); - lcd_cam.lcd_user().modify(|_, w| { + self.lcd_cam.lcd_user().modify(|_, w| { if config.format.enable_2byte_mode { w.lcd_8bits_order().bit(false); w.lcd_byte_order() @@ -197,7 +221,7 @@ where }); let timing = &config.timing; - lcd_cam.lcd_ctrl().modify(|_, w| unsafe { + self.lcd_cam.lcd_ctrl().modify(|_, w| unsafe { // Enable RGB mode, and input VSYNC, HSYNC, and DE signals. w.lcd_rgb_mode_en().set_bit(); @@ -208,7 +232,7 @@ where w.lcd_vt_height() .bits((timing.vertical_total_height as u16).saturating_sub(1)) }); - lcd_cam.lcd_ctrl1().modify(|_, w| unsafe { + self.lcd_cam.lcd_ctrl1().modify(|_, w| unsafe { w.lcd_vb_front() .bits((timing.vertical_blank_front_porch as u8).saturating_sub(1)); w.lcd_ha_width() @@ -216,7 +240,7 @@ where w.lcd_ht_width() .bits((timing.horizontal_total_width as u16).saturating_sub(1)) }); - lcd_cam.lcd_ctrl2().modify(|_, w| unsafe { + self.lcd_cam.lcd_ctrl2().modify(|_, w| unsafe { w.lcd_vsync_width() .bits((timing.vsync_width as u8).saturating_sub(1)); w.lcd_vsync_idle_pol().bit(config.vsync_idle_level.into()); @@ -228,7 +252,7 @@ where w.lcd_hsync_position().bits(timing.hsync_position as u8) }); - lcd_cam.lcd_misc().modify(|_, w| unsafe { + self.lcd_cam.lcd_misc().modify(|_, w| unsafe { // TODO: Find out what this field actually does. // Set the threshold for Async Tx FIFO full event. (5 bits) w.lcd_afifo_threshold_num().bits((1 << 5) - 1); @@ -244,13 +268,13 @@ where // Enable blank region when LCD sends data out. w.lcd_bk_en().bit(!config.disable_black_region) }); - lcd_cam.lcd_dly_mode().modify(|_, w| unsafe { + self.lcd_cam.lcd_dly_mode().modify(|_, w| unsafe { w.lcd_de_mode().bits(config.de_mode as u8); w.lcd_hsync_mode().bits(config.hsync_mode as u8); w.lcd_vsync_mode().bits(config.vsync_mode as u8); w }); - lcd_cam.lcd_data_dout_mode().modify(|_, w| unsafe { + self.lcd_cam.lcd_data_dout_mode().modify(|_, w| unsafe { w.dout0_mode().bits(config.output_bit_mode as u8); w.dout1_mode().bits(config.output_bit_mode as u8); w.dout2_mode().bits(config.output_bit_mode as u8); @@ -269,13 +293,11 @@ where w.dout15_mode().bits(config.output_bit_mode as u8) }); - lcd_cam.lcd_user().modify(|_, w| w.lcd_update().set_bit()); + self.lcd_cam + .lcd_user() + .modify(|_, w| w.lcd_update().set_bit()); - Self { - lcd_cam, - tx_channel, - _mode: PhantomData, - } + Ok(()) } /// Assign the VSYNC pin for the LCD_CAM. @@ -675,6 +697,9 @@ pub struct Config { /// Specifies the clock mode, including polarity and phase settings. pub clock_mode: ClockMode, + /// The frequency of the pixel clock. + pub frequency: HertzU32, + /// Format of the byte data sent out. pub format: Format, @@ -712,6 +737,7 @@ impl Default for Config { fn default() -> Self { Config { clock_mode: Default::default(), + frequency: 1.MHz(), format: Default::default(), timing: Default::default(), vsync_idle_level: Level::Low, diff --git a/esp-hal/src/lcd_cam/lcd/i8080.rs b/esp-hal/src/lcd_cam/lcd/i8080.rs index 21350a1d92..7cea535d76 100644 --- a/esp-hal/src/lcd_cam/lcd/i8080.rs +++ b/esp-hal/src/lcd_cam/lcd/i8080.rs @@ -33,13 +33,16 @@ //! ); //! let lcd_cam = LcdCam::new(peripherals.LCD_CAM); //! +//! let mut config = Config::default(); +//! config.frequency = 20.MHz(); +//! //! let mut i8080 = I8080::new( //! lcd_cam.lcd, //! peripherals.DMA_CH0, //! tx_pins, -//! 20.MHz(), -//! Config::default(), +//! config, //! ) +//! .unwrap() //! .with_ctrl_pins(peripherals.GPIO0, peripherals.GPIO47); //! //! dma_buf.fill(&[0x55]); @@ -55,7 +58,7 @@ use core::{ ops::{Deref, DerefMut}, }; -use fugit::HertzU32; +use fugit::{HertzU32, RateExtU32}; use crate::{ clock::Clocks, @@ -69,6 +72,7 @@ use crate::{ lcd::{ClockMode, DelayMode, Phase, Polarity}, BitOrder, ByteOrder, + ClockError, Instance, Lcd, LCD_DONE_WAKER, @@ -79,6 +83,14 @@ use crate::{ Mode, }; +/// A configuration error. +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ConfigError { + /// Clock configuration error. + Clock(ClockError), +} + /// Represents the I8080 LCD interface. pub struct I8080<'d, DM: Mode> { lcd_cam: PeripheralRef<'d, LCD_CAM>, @@ -95,30 +107,43 @@ where lcd: Lcd<'d, DM>, channel: impl Peripheral

+ 'd, mut pins: P, - frequency: HertzU32, config: Config, - ) -> Self + ) -> Result where CH: TxChannelFor, P: TxPins, { let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade())); - let lcd_cam = lcd.lcd_cam; + let mut this = Self { + lcd_cam: lcd.lcd_cam, + tx_channel, + _mode: PhantomData, + }; + + this.apply_config(&config)?; + pins.configure(); + + Ok(this) + } + + /// Applies configuration. + pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> { let clocks = Clocks::get(); // Due to https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf // the LCD_PCLK divider must be at least 2. To make up for this the user // provided frequency is doubled to match. let (i, divider) = calculate_clkm( - (frequency.to_Hz() * 2) as _, + (config.frequency.to_Hz() * 2) as _, &[ clocks.xtal_clock.to_Hz() as _, clocks.cpu_clock.to_Hz() as _, clocks.crypto_pwm_clock.to_Hz() as _, ], - ); + ) + .map_err(ConfigError::Clock)?; - lcd_cam.lcd_clock().write(|w| unsafe { + self.lcd_cam.lcd_clock().write(|w| unsafe { // Force enable the clock for all configuration registers. w.clk_en().set_bit(); w.lcd_clk_sel().bits((i + 1) as _); @@ -133,20 +158,20 @@ where .bit(config.clock_mode.phase == Phase::ShiftHigh) }); - lcd_cam + self.lcd_cam .lcd_ctrl() .write(|w| w.lcd_rgb_mode_en().clear_bit()); - lcd_cam + self.lcd_cam .lcd_rgb_yuv() .write(|w| w.lcd_conv_bypass().clear_bit()); - lcd_cam.lcd_user().modify(|_, w| { + self.lcd_cam.lcd_user().modify(|_, w| { w.lcd_8bits_order().bit(false); w.lcd_bit_order().bit(false); w.lcd_byte_order().bit(false); w.lcd_2byte_en().bit(false) }); - lcd_cam.lcd_misc().write(|w| unsafe { + self.lcd_cam.lcd_misc().write(|w| unsafe { // Set the threshold for Async Tx FIFO full event. (5 bits) w.lcd_afifo_threshold_num().bits(0); // Configure the setup cycles in LCD non-RGB mode. Setup cycles @@ -177,10 +202,10 @@ where // The default value of LCD_CD w.lcd_cd_idle_edge().bit(config.cd_idle_edge) }); - lcd_cam + self.lcd_cam .lcd_dly_mode() .write(|w| unsafe { w.lcd_cd_mode().bits(config.cd_mode as u8) }); - lcd_cam.lcd_data_dout_mode().write(|w| unsafe { + self.lcd_cam.lcd_data_dout_mode().write(|w| unsafe { w.dout0_mode().bits(config.output_bit_mode as u8); w.dout1_mode().bits(config.output_bit_mode as u8); w.dout2_mode().bits(config.output_bit_mode as u8); @@ -199,15 +224,11 @@ where w.dout15_mode().bits(config.output_bit_mode as u8) }); - lcd_cam.lcd_user().modify(|_, w| w.lcd_update().set_bit()); - - pins.configure(); + self.lcd_cam + .lcd_user() + .modify(|_, w| w.lcd_update().set_bit()); - Self { - lcd_cam, - tx_channel, - _mode: PhantomData, - } + Ok(()) } /// Configures the byte order for data transmission in 16-bit mode. @@ -523,6 +544,9 @@ pub struct Config { /// Specifies the clock mode, including polarity and phase settings. pub clock_mode: ClockMode, + /// The frequency of the pixel clock. + pub frequency: HertzU32, + /// Setup cycles expected, must be at least 1. (6 bits) pub setup_cycles: usize, @@ -548,6 +572,7 @@ impl Default for Config { fn default() -> Self { Self { clock_mode: Default::default(), + frequency: 20.MHz(), setup_cycles: 1, hold_cycles: 1, cd_idle_edge: false, diff --git a/esp-hal/src/lcd_cam/lcd/mod.rs b/esp-hal/src/lcd_cam/lcd/mod.rs index 66bd82a65c..53ec894bcd 100644 --- a/esp-hal/src/lcd_cam/lcd/mod.rs +++ b/esp-hal/src/lcd_cam/lcd/mod.rs @@ -11,11 +11,7 @@ //! - RGB is not supported yet use super::GenericPeripheralGuard; -use crate::{ - peripheral::PeripheralRef, - peripherals::LCD_CAM, - system::{self}, -}; +use crate::{peripheral::PeripheralRef, peripherals::LCD_CAM, system}; pub mod dpi; pub mod i8080; diff --git a/esp-hal/src/lcd_cam/mod.rs b/esp-hal/src/lcd_cam/mod.rs index 8806544631..b6f9320dcb 100644 --- a/esp-hal/src/lcd_cam/mod.rs +++ b/esp-hal/src/lcd_cam/mod.rs @@ -173,10 +173,18 @@ pub(crate) struct ClockDivider { pub div_a: usize, } +/// Clock configuration errors. +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ClockError { + /// Desired frequency was too low for the dividers to divide to + FrequencyTooLow, +} + pub(crate) fn calculate_clkm( desired_frequency: usize, source_frequencies: &[usize], -) -> (usize, ClockDivider) { +) -> Result<(usize, ClockDivider), ClockError> { let mut result_freq = 0; let mut result = None; @@ -191,7 +199,7 @@ pub(crate) fn calculate_clkm( } } - result.expect("Desired frequency was too low for the dividers to divide to") + result.ok_or(ClockError::FrequencyTooLow) } fn calculate_output_frequency(source_frequency: usize, divider: &ClockDivider) -> usize { @@ -257,15 +265,15 @@ fn calculate_closest_divider( } } else { let target = div_fraction; - let closest = farey_sequence(63) - .find(|curr| { - // https://en.wikipedia.org/wiki/Fraction#Adding_unlike_quantities - - let new_curr_num = curr.numerator * target.denominator; - let new_target_num = target.numerator * curr.denominator; - new_curr_num >= new_target_num - }) - .expect("The fraction must be between 0 and 1"); + let closest = farey_sequence(63).find(|curr| { + // https://en.wikipedia.org/wiki/Fraction#Adding_unlike_quantities + + let new_curr_num = curr.numerator * target.denominator; + let new_target_num = target.numerator * curr.denominator; + new_curr_num >= new_target_num + }); + + let closest = unwrap!(closest, "The fraction must be between 0 and 1"); ClockDivider { div_num, diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 4c5b943fc1..8f4538ba86 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -43,10 +43,11 @@ //! let mosi = peripherals.GPIO1; //! let cs = peripherals.GPIO5; //! -//! let mut spi = Spi::new_with_config( +//! let mut spi = Spi::new( //! peripherals.SPI2, //! Config::default().with_frequency(100.kHz()).with_mode(SpiMode::Mode0) //! ) +//! .unwrap() //! .with_sck(sclk) //! .with_mosi(mosi) //! .with_miso(miso) @@ -503,16 +504,11 @@ where impl<'d> Spi<'d, Blocking> { /// Constructs an SPI instance in 8bit dataframe mode. - pub fn new(spi: impl Peripheral

+ 'd) -> Spi<'d, Blocking> { - Self::new_with_config(spi, Config::default()) - } - - /// Constructs an SPI instance in 8bit dataframe mode. - pub fn new_with_config( + pub fn new( spi: impl Peripheral

+ 'd, config: Config, - ) -> Spi<'d, Blocking> { - Self::new_typed_with_config(spi.map_into(), config) + ) -> Result { + Self::new_typed(spi.map_into(), config) } /// Converts the SPI instance into async mode. @@ -558,15 +554,10 @@ where T: Instance, { /// Constructs an SPI instance in 8bit dataframe mode. - pub fn new_typed(spi: impl Peripheral

+ 'd) -> Spi<'d, M, T> { - Self::new_typed_with_config(spi, Config::default()) - } - - /// Constructs an SPI instance in 8bit dataframe mode. - pub fn new_typed_with_config( + pub fn new_typed( spi: impl Peripheral

+ 'd, config: Config, - ) -> Spi<'d, M, T> { + ) -> Result { crate::into_ref!(spi); let guard = PeripheralGuard::new(spi.info().peripheral); @@ -578,7 +569,7 @@ where }; this.driver().init(); - unwrap!(this.apply_config(&config)); // FIXME: update based on the resolution of https://github.com/esp-rs/esp-hal/issues/2416 + this.apply_config(&config)?; let this = this .with_mosi(NoPin) @@ -594,7 +585,7 @@ where unwrap!(this.driver().sio3_output).connect_to(NoPin); } - this + Ok(this) } /// Assign the MOSI (Master Out Slave In) pin for the SPI instance. diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 8ec7f4b7c0..9e5dc7ce61 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -22,10 +22,11 @@ //! //! ```rust, no_run #![doc = crate::before_snippet!()] -//! # use esp_hal::uart::Uart; +//! # use esp_hal::uart::{Config, Uart}; //! //! let mut uart1 = Uart::new( //! peripherals.UART1, +//! Config::default(), //! peripherals.GPIO1, //! peripherals.GPIO2, //! ).unwrap(); @@ -53,7 +54,7 @@ //! ```rust, no_run #![doc = crate::before_snippet!()] //! # use esp_hal::uart::{Config, Uart}; -//! # let mut uart1 = Uart::new_with_config( +//! # let mut uart1 = Uart::new( //! # peripherals.UART1, //! # Config::default(), //! # peripherals.GPIO1, @@ -68,7 +69,7 @@ //! ```rust, no_run #![doc = crate::before_snippet!()] //! # use esp_hal::uart::{Config, Uart}; -//! # let mut uart1 = Uart::new_with_config( +//! # let mut uart1 = Uart::new( //! # peripherals.UART1, //! # Config::default(), //! # peripherals.GPIO1, @@ -86,12 +87,13 @@ //! ### Inverting RX and TX Pins //! ```rust, no_run #![doc = crate::before_snippet!()] -//! # use esp_hal::uart::Uart; +//! # use esp_hal::uart::{Config, Uart}; //! //! let (rx, _) = peripherals.GPIO2.split(); //! let (_, tx) = peripherals.GPIO1.split(); //! let mut uart1 = Uart::new( //! peripherals.UART1, +//! Config::default(), //! rx.inverted(), //! tx.inverted(), //! ).unwrap(); @@ -101,10 +103,18 @@ //! ### Constructing RX and TX Components //! ```rust, no_run #![doc = crate::before_snippet!()] -//! # use esp_hal::uart::{UartTx, UartRx}; +//! # use esp_hal::uart::{Config, UartTx, UartRx}; //! -//! let tx = UartTx::new(peripherals.UART0, peripherals.GPIO1).unwrap(); -//! let rx = UartRx::new(peripherals.UART1, peripherals.GPIO2).unwrap(); +//! let tx = UartTx::new( +//! peripherals.UART0, +//! Config::default(), +//! peripherals.GPIO1, +//! ).unwrap(); +//! let rx = UartRx::new( +//! peripherals.UART1, +//! Config::default(), +//! peripherals.GPIO2, +//! ).unwrap(); //! # } //! ``` //! @@ -145,7 +155,7 @@ )] //! let config = Config::default().rx_fifo_full_threshold(30); //! -//! let mut uart0 = Uart::new_with_config( +//! let mut uart0 = Uart::new( //! peripherals.UART0, //! config, //! tx_pin, @@ -560,7 +570,7 @@ where self } - fn init(self, config: Config) -> Result, Error> { + fn init(self, config: Config) -> Result, ConfigError> { let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral); let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral); @@ -602,13 +612,23 @@ pub struct UartRx<'d, M, T = AnyUart> { guard: PeripheralGuard, } +/// A configuration error. +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ConfigError { + /// The requested timeout is not supported. + UnsupportedTimeout, + /// The requested fifo threshold is not supported. + UnsupportedFifoThreshold, +} + impl SetConfig for Uart<'_, M, T> where T: Instance, M: Mode, { type Config = Config; - type ConfigError = Error; + type ConfigError = ConfigError; fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { self.apply_config(config) @@ -621,7 +641,7 @@ where M: Mode, { type Config = Config; - type ConfigError = Error; + type ConfigError = ConfigError; fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { self.apply_config(config) @@ -634,7 +654,7 @@ where M: Mode, { type Config = Config; - type ConfigError = Error; + type ConfigError = ConfigError; fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { self.apply_config(config) @@ -658,9 +678,8 @@ where /// Change the configuration. /// /// Note that this also changes the configuration of the RX half. - pub fn apply_config(&mut self, config: &Config) -> Result<(), Error> { - self.uart.info().apply_config(config)?; - Ok(()) + pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> { + self.uart.info().apply_config(config) } /// Writes bytes @@ -748,20 +767,11 @@ where impl<'d> UartTx<'d, Blocking> { /// Create a new UART TX instance in [`Blocking`] mode. pub fn new( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - ) -> Result { - Self::new_typed(uart.map_into(), tx) - } - - /// Create a new UART TX instance with configuration options in - /// [`Blocking`] mode. - pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, tx: impl Peripheral

+ 'd, - ) -> Result { - Self::new_with_config_typed(uart.map_into(), config, tx) + ) -> Result { + Self::new_typed(uart.map_into(), config, tx) } } @@ -771,19 +781,10 @@ where { /// Create a new UART TX instance in [`Blocking`] mode. pub fn new_typed( - uart: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - ) -> Result { - Self::new_with_config_typed(uart, Config::default(), tx) - } - - /// Create a new UART TX instance with configuration options in - /// [`Blocking`] mode. - pub fn new_with_config_typed( uart: impl Peripheral

+ 'd, config: Config, tx: impl Peripheral

+ 'd, - ) -> Result { + ) -> Result { let (_, uart_tx) = UartBuilder::<'d, Blocking, T>::new(uart) .with_tx(tx) .init(config)? @@ -868,9 +869,8 @@ where /// Change the configuration. /// /// Note that this also changes the configuration of the TX half. - pub fn apply_config(&mut self, config: &Config) -> Result<(), Error> { - self.uart.info().apply_config(config)?; - Ok(()) + pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> { + self.uart.info().apply_config(config) } /// Fill a buffer with received bytes @@ -1006,20 +1006,11 @@ where impl<'d> UartRx<'d, Blocking> { /// Create a new UART RX instance in [`Blocking`] mode. pub fn new( - uart: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - ) -> Result { - UartRx::new_typed(uart.map_into(), rx) - } - - /// Create a new UART RX instance with configuration options in - /// [`Blocking`] mode. - pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, - ) -> Result { - UartRx::new_with_config_typed(uart.map_into(), config, rx) + ) -> Result { + UartRx::new_typed(uart.map_into(), config, rx) } } @@ -1029,19 +1020,10 @@ where { /// Create a new UART RX instance in [`Blocking`] mode. pub fn new_typed( - uart: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - ) -> Result { - Self::new_with_config_typed(uart, Config::default(), rx) - } - - /// Create a new UART RX instance with configuration options in - /// [`Blocking`] mode. - pub fn new_with_config_typed( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, - ) -> Result { + ) -> Result { let (uart_rx, _) = UartBuilder::new(uart).with_rx(rx).init(config)?.split(); Ok(uart_rx) @@ -1089,22 +1071,12 @@ where impl<'d> Uart<'d, Blocking> { /// Create a new UART instance in [`Blocking`] mode. pub fn new( - uart: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - ) -> Result { - Self::new_typed(uart.map_into(), rx, tx) - } - - /// Create a new UART instance with configuration options in - /// [`Blocking`] mode. - pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, - ) -> Result { - Self::new_with_config_typed(uart.map_into(), config, rx, tx) + ) -> Result { + Self::new_typed(uart.map_into(), config, rx, tx) } } @@ -1114,21 +1086,11 @@ where { /// Create a new UART instance in [`Blocking`] mode. pub fn new_typed( - uart: impl Peripheral

+ 'd, - rx: impl Peripheral

+ 'd, - tx: impl Peripheral

+ 'd, - ) -> Result { - Self::new_with_config_typed(uart, Config::default(), rx, tx) - } - - /// Create a new UART instance with configuration options in - /// [`Blocking`] mode. - pub fn new_with_config_typed( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, - ) -> Result { + ) -> Result { UartBuilder::new(uart).with_tx(tx).with_rx(rx).init(config) } @@ -1251,26 +1213,6 @@ where sync_regs(register_block); } - /// Listen for the given interrupts - pub fn listen(&mut self, interrupts: impl Into>) { - self.tx.uart.info().enable_listen(interrupts.into(), true) - } - - /// Unlisten the given interrupts - pub fn unlisten(&mut self, interrupts: impl Into>) { - self.tx.uart.info().enable_listen(interrupts.into(), false) - } - - /// Gets asserted interrupts - pub fn interrupts(&mut self) -> EnumSet { - self.tx.uart.info().interrupts() - } - - /// Resets asserted interrupts - pub fn clear_interrupts(&mut self, interrupts: EnumSet) { - self.tx.uart.info().clear_interrupts(interrupts) - } - /// Write a byte out over the UART pub fn write_byte(&mut self, word: u8) -> nb::Result<(), Error> { self.tx.write_byte(word) @@ -1287,13 +1229,13 @@ where } /// Change the configuration. - pub fn apply_config(&mut self, config: &Config) -> Result<(), Error> { + pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> { self.rx.apply_config(config)?; Ok(()) } #[inline(always)] - fn init(&mut self, config: Config) -> Result<(), Error> { + fn init(&mut self, config: Config) -> Result<(), ConfigError> { cfg_if::cfg_if! { if #[cfg(any(esp32, esp32s2))] { // Nothing to do @@ -1377,6 +1319,31 @@ where } } +impl Uart<'_, Blocking, T> +where + T: Instance, +{ + /// Listen for the given interrupts + pub fn listen(&mut self, interrupts: impl Into>) { + self.tx.uart.info().enable_listen(interrupts.into(), true) + } + + /// Unlisten the given interrupts + pub fn unlisten(&mut self, interrupts: impl Into>) { + self.tx.uart.info().enable_listen(interrupts.into(), false) + } + + /// Gets asserted interrupts + pub fn interrupts(&mut self) -> EnumSet { + self.tx.uart.info().interrupts() + } + + /// Resets asserted interrupts + pub fn clear_interrupts(&mut self, interrupts: EnumSet) { + self.tx.uart.info().clear_interrupts(interrupts) + } +} + impl ufmt_write::uWrite for Uart<'_, M, T> where T: Instance, @@ -2020,9 +1987,14 @@ pub mod lp_uart { } impl LpUart { - /// Initialize the UART driver using the default configuration + /// Initialize the UART driver using the provided configuration // TODO: CTS and RTS pins - pub fn new(uart: LP_UART, _tx: LowPowerOutput<'_, 5>, _rx: LowPowerInput<'_, 4>) -> Self { + pub fn new( + uart: LP_UART, + config: Config, + _tx: LowPowerOutput<'_, 5>, + _rx: LowPowerInput<'_, 4>, + ) -> Self { let lp_io = unsafe { crate::peripherals::LP_IO::steal() }; let lp_aon = unsafe { crate::peripherals::LP_AON::steal() }; @@ -2037,11 +2009,6 @@ pub mod lp_uart { lp_io.gpio(4).modify(|_, w| unsafe { w.mcu_sel().bits(1) }); lp_io.gpio(5).modify(|_, w| unsafe { w.mcu_sel().bits(1) }); - Self::new_with_config(uart, Config::default()) - } - - /// Initialize the UART driver using the provided configuration - pub fn new_with_config(uart: LP_UART, config: Config) -> Self { let mut me = Self { uart }; // Set UART mode - do nothing for LP @@ -2332,7 +2299,7 @@ impl Info { crate::interrupt::disable(crate::Cpu::current(), self.interrupt); } - fn apply_config(&self, config: &Config) -> Result<(), Error> { + fn apply_config(&self, config: &Config) -> Result<(), ConfigError> { self.set_rx_fifo_full_threshold(config.rx_fifo_full_threshold)?; self.set_rx_timeout(config.rx_timeout, config.symbol_length())?; self.change_baud(config.baudrate, config.clock_source); @@ -2350,13 +2317,13 @@ impl Info { /// Configures the RX-FIFO threshold /// /// # Errors - /// `Err(Error::InvalidArgument)` if provided value exceeds maximum value + /// [`Err(ConfigError::UnsupportedFifoThreshold)`][ConfigError::UnsupportedFifoThreshold] if provided value exceeds maximum value /// for SOC : /// - `esp32` **0x7F** /// - `esp32c6`, `esp32h2` **0xFF** /// - `esp32c3`, `esp32c2`, `esp32s2` **0x1FF** /// - `esp32s3` **0x3FF** - fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), Error> { + fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> { #[cfg(esp32)] const MAX_THRHD: u16 = 0x7F; #[cfg(any(esp32c6, esp32h2))] @@ -2367,7 +2334,7 @@ impl Info { const MAX_THRHD: u16 = 0x3FF; if threshold > MAX_THRHD { - return Err(Error::InvalidArgument); + return Err(ConfigError::UnsupportedFifoThreshold); } self.register_block() @@ -2384,12 +2351,13 @@ impl Info { /// triggering a timeout. Pass None to disable the timeout. /// /// # Errors - /// `Err(Error::InvalidArgument)` if the provided value exceeds the maximum - /// value for SOC : + /// [`Err(ConfigError::UnsupportedTimeout)`][ConfigError::UnsupportedTimeout] if the provided value exceeds + /// the maximum value for SOC : /// - `esp32`: Symbol size is fixed to 8, do not pass a value > **0x7F**. /// - `esp32c2`, `esp32c3`, `esp32c6`, `esp32h2`, esp32s2`, esp32s3`: The /// value you pass times the symbol size must be <= **0x3FF** - fn set_rx_timeout(&self, timeout: Option, _symbol_len: u8) -> Result<(), Error> { + // TODO: the above should be a per-chip doc line. + fn set_rx_timeout(&self, timeout: Option, _symbol_len: u8) -> Result<(), ConfigError> { cfg_if::cfg_if! { if #[cfg(esp32)] { const MAX_THRHD: u8 = 0x7F; // 7 bits @@ -2409,7 +2377,7 @@ impl Info { let timeout_reg = timeout as u16 * _symbol_len as u16; if timeout_reg > MAX_THRHD { - return Err(Error::InvalidArgument); + return Err(ConfigError::UnsupportedTimeout); } cfg_if::cfg_if! { diff --git a/examples/src/bin/embassy_serial.rs b/examples/src/bin/embassy_serial.rs index 643bac9285..bf552412eb 100644 --- a/examples/src/bin/embassy_serial.rs +++ b/examples/src/bin/embassy_serial.rs @@ -89,7 +89,7 @@ async fn main(spawner: Spawner) { let config = Config::default().rx_fifo_full_threshold(READ_BUF_SIZE as u16); - let mut uart0 = Uart::new_with_config(peripherals.UART0, config, rx_pin, tx_pin) + let mut uart0 = Uart::new(peripherals.UART0, config, rx_pin, tx_pin) .unwrap() .into_async(); uart0.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None)); diff --git a/examples/src/bin/embassy_spi.rs b/examples/src/bin/embassy_spi.rs index de95e0714f..1006ac47f2 100644 --- a/examples/src/bin/embassy_spi.rs +++ b/examples/src/bin/embassy_spi.rs @@ -57,12 +57,13 @@ async fn main(_spawner: Spawner) { let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); - let mut spi = Spi::new_with_config( + let mut spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_mosi(mosi) .with_miso(miso) diff --git a/examples/src/bin/ieee802154_sniffer.rs b/examples/src/bin/ieee802154_sniffer.rs index e8ac85cffd..05babb0c4f 100644 --- a/examples/src/bin/ieee802154_sniffer.rs +++ b/examples/src/bin/ieee802154_sniffer.rs @@ -8,7 +8,11 @@ #![no_main] use esp_backtrace as _; -use esp_hal::{prelude::*, reset::software_reset, uart::Uart}; +use esp_hal::{ + prelude::*, + reset::software_reset, + uart::{self, Uart}, +}; use esp_ieee802154::{Config, Ieee802154}; use esp_println::println; @@ -25,7 +29,13 @@ fn main() -> ! { } } - let mut uart0 = Uart::new(peripherals.UART0, &mut rx_pin, &mut tx_pin).unwrap(); + let mut uart0 = Uart::new( + peripherals.UART0, + uart::Config::default(), + &mut rx_pin, + &mut tx_pin, + ) + .unwrap(); // read two characters which get parsed as the channel let mut cnt = 0; diff --git a/examples/src/bin/spi_loopback.rs b/examples/src/bin/spi_loopback.rs index 191ebdee80..74b0ed963e 100644 --- a/examples/src/bin/spi_loopback.rs +++ b/examples/src/bin/spi_loopback.rs @@ -37,12 +37,13 @@ fn main() -> ! { let miso = unsafe { miso_mosi.clone_unchecked() }; - let mut spi = Spi::new_with_config( + let mut spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_miso(miso) // order matters .with_mosi(miso_mosi) // order matters diff --git a/examples/src/bin/spi_loopback_dma_psram.rs b/examples/src/bin/spi_loopback_dma_psram.rs index 02d53a0027..2d666807cb 100644 --- a/examples/src/bin/spi_loopback_dma_psram.rs +++ b/examples/src/bin/spi_loopback_dma_psram.rs @@ -88,12 +88,13 @@ fn main() -> ! { let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); // Need to set miso first so that mosi can overwrite the // output connection (because we are using the same pin to loop back) - let mut spi = Spi::new_with_config( + let mut spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_miso(miso) .with_mosi(mosi) diff --git a/hil-test/tests/embassy_interrupt_spi_dma.rs b/hil-test/tests/embassy_interrupt_spi_dma.rs index c59f51e543..a1dfc346ca 100644 --- a/hil-test/tests/embassy_interrupt_spi_dma.rs +++ b/hil-test/tests/embassy_interrupt_spi_dma.rs @@ -118,12 +118,13 @@ mod test { let (_, mosi) = hil_test::common_test_pins!(peripherals); - let mut spi = Spi::new_with_config( + let mut spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(10000.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_miso(unsafe { mosi.clone_unchecked() }) .with_mosi(mosi) .with_dma(dma_channel1) @@ -131,12 +132,13 @@ mod test { .into_async(); #[cfg(any(esp32, esp32s2, esp32s3))] - let other_peripheral = Spi::new_with_config( + let other_peripheral = Spi::new( peripherals.SPI3, Config::default() .with_frequency(10000.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_dma(dma_channel2) .into_async(); @@ -225,12 +227,13 @@ mod test { let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); - let mut spi = Spi::new_with_config( + let mut spi = Spi::new( peripherals.spi, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_dma(peripherals.dma_channel) .with_buffers(dma_rx_buf, dma_tx_buf) .into_async(); diff --git a/hil-test/tests/i2c.rs b/hil-test/tests/i2c.rs index 8f786717c9..b30980ab8b 100644 --- a/hil-test/tests/i2c.rs +++ b/hil-test/tests/i2c.rs @@ -41,6 +41,7 @@ mod tests { // Create a new peripheral object with the described wiring and standard // I2C clock speed: let i2c = I2c::new(peripherals.I2C0, Config::default()) + .unwrap() .with_sda(sda) .with_scl(scl); diff --git a/hil-test/tests/lcd_cam.rs b/hil-test/tests/lcd_cam.rs index c682ee25f7..1ff8942d7a 100644 --- a/hil-test/tests/lcd_cam.rs +++ b/hil-test/tests/lcd_cam.rs @@ -10,7 +10,7 @@ use esp_hal::{ dma_buffers, gpio::Level, lcd_cam::{ - cam::{Camera, RxEightBits}, + cam::{self, Camera, RxEightBits}, lcd::{ dpi, dpi::{Dpi, Format, FrameTiming}, @@ -77,6 +77,7 @@ mod tests { polarity: Polarity::IdleHigh, phase: Phase::ShiftLow, }; + config.frequency = 500u32.kHz(); config.format = Format { enable_2byte_mode: false, ..Default::default() @@ -100,7 +101,8 @@ mod tests { config.de_idle_level = Level::Low; config.disable_black_region = false; - let dpi = Dpi::new(lcd_cam.lcd, tx_channel, 500u32.kHz(), config) + let dpi = Dpi::new(lcd_cam.lcd, tx_channel, config) + .unwrap() .with_vsync(vsync_out) .with_hsync(hsync_out) .with_de(de_out) @@ -114,12 +116,16 @@ mod tests { .with_data6(d6_out) .with_data7(d7_out); + let mut cam_config = cam::Config::default(); + cam_config.frequency = 1u32.MHz(); + let camera = Camera::new( lcd_cam.cam, rx_channel, RxEightBits::new(d0_in, d1_in, d2_in, d3_in, d4_in, d5_in, d6_in, d7_in), - 1u32.MHz(), + cam_config, ) + .unwrap() .with_ctrl_pins_and_de(vsync_in, hsync_in, de_in) .with_pixel_clock(pclk_in); diff --git a/hil-test/tests/lcd_cam_i8080.rs b/hil-test/tests/lcd_cam_i8080.rs index 0ce6e842cd..1eb15a5ed7 100644 --- a/hil-test/tests/lcd_cam_i8080.rs +++ b/hil-test/tests/lcd_cam_i8080.rs @@ -75,7 +75,12 @@ mod tests { fn test_i8080_8bit(ctx: Context<'static>) { let pins = TxEightBits::new(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin); - let i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, 20.MHz(), Config::default()); + let i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, { + let mut config = Config::default(); + config.frequency = 20.MHz(); + config + }) + .unwrap(); let xfer = i8080.send(Command::::None, 0, ctx.dma_buf).unwrap(); xfer.wait().0.unwrap(); @@ -132,9 +137,14 @@ mod tests { NoPin, ); - let mut i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, 20.MHz(), Config::default()) - .with_cs(cs_signal) - .with_ctrl_pins(NoPin, NoPin); + let mut i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, { + let mut config = Config::default(); + config.frequency = 20.MHz(); + config + }) + .unwrap() + .with_cs(cs_signal) + .with_ctrl_pins(NoPin, NoPin); // This is to make the test values look more intuitive. i8080.set_bit_order(BitOrder::Inverted); @@ -244,9 +254,14 @@ mod tests { unit3_signal, ); - let mut i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, 20.MHz(), Config::default()) - .with_cs(cs_signal) - .with_ctrl_pins(NoPin, NoPin); + let mut i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, { + let mut config = Config::default(); + config.frequency = 20.MHz(); + config + }) + .unwrap() + .with_cs(cs_signal) + .with_ctrl_pins(NoPin, NoPin); // This is to make the test values look more intuitive. i8080.set_bit_order(BitOrder::Inverted); diff --git a/hil-test/tests/lcd_cam_i8080_async.rs b/hil-test/tests/lcd_cam_i8080_async.rs index f9c49f8f4f..f72d6dec89 100644 --- a/hil-test/tests/lcd_cam_i8080_async.rs +++ b/hil-test/tests/lcd_cam_i8080_async.rs @@ -51,7 +51,12 @@ mod tests { async fn test_i8080_8bit(ctx: Context<'static>) { let pins = TxEightBits::new(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin); - let i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, 20.MHz(), Config::default()); + let i8080 = I8080::new(ctx.lcd_cam.lcd, ctx.dma, pins, { + let mut config = Config::default(); + config.frequency = 20.MHz(); + config + }) + .unwrap(); let mut transfer = i8080.send(Command::::None, 0, ctx.dma_buf).unwrap(); diff --git a/hil-test/tests/qspi.rs b/hil-test/tests/qspi.rs index 95033daf63..0ac67b9391 100644 --- a/hil-test/tests/qspi.rs +++ b/hil-test/tests/qspi.rs @@ -200,12 +200,13 @@ mod tests { } } - let spi = Spi::new_with_config( + let spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), - ); + ) + .unwrap(); Context { spi, diff --git a/hil-test/tests/spi_full_duplex.rs b/hil-test/tests/spi_full_duplex.rs index 1a5517b841..76b09cf47f 100644 --- a/hil-test/tests/spi_full_duplex.rs +++ b/hil-test/tests/spi_full_duplex.rs @@ -73,11 +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::default().with_frequency(10.MHz())) - .with_sck(sclk) - .with_miso(unsafe { mosi.clone_unchecked() }) - .with_mosi(mosi); + let spi = Spi::new(peripherals.SPI2, Config::default().with_frequency(10.MHz())) + .unwrap() + .with_sck(sclk) + .with_miso(unsafe { mosi.clone_unchecked() }) + .with_mosi(mosi); let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(32000); diff --git a/hil-test/tests/spi_half_duplex_read.rs b/hil-test/tests/spi_half_duplex_read.rs index 27564c02a6..5daba6dc8f 100644 --- a/hil-test/tests/spi_half_duplex_read.rs +++ b/hil-test/tests/spi_half_duplex_read.rs @@ -46,12 +46,13 @@ mod tests { } } - let spi = Spi::new_with_config( + let spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_miso(miso) .with_dma(dma_channel); diff --git a/hil-test/tests/spi_half_duplex_write.rs b/hil-test/tests/spi_half_duplex_write.rs index a58ea3c497..d65e452a2b 100644 --- a/hil-test/tests/spi_half_duplex_write.rs +++ b/hil-test/tests/spi_half_duplex_write.rs @@ -50,12 +50,13 @@ mod tests { let (mosi_loopback, mosi) = mosi.split(); - let spi = Spi::new_with_config( + let spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_mosi(mosi) .with_dma(dma_channel); diff --git a/hil-test/tests/spi_half_duplex_write_psram.rs b/hil-test/tests/spi_half_duplex_write_psram.rs index 52fe8f75ca..ff3ad7fc20 100644 --- a/hil-test/tests/spi_half_duplex_write_psram.rs +++ b/hil-test/tests/spi_half_duplex_write_psram.rs @@ -62,12 +62,13 @@ mod tests { let (mosi_loopback, mosi) = mosi.split(); - let spi = Spi::new_with_config( + let spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_mosi(mosi) .with_dma(dma_channel); diff --git a/hil-test/tests/uart.rs b/hil-test/tests/uart.rs index 85c5ab9041..4fed45a776 100644 --- a/hil-test/tests/uart.rs +++ b/hil-test/tests/uart.rs @@ -31,7 +31,7 @@ mod tests { let (rx, tx) = pin.split(); - let uart = Uart::new(peripherals.UART1, rx, tx).unwrap(); + let uart = Uart::new(peripherals.UART1, uart::Config::default(), rx, tx).unwrap(); Context { uart } } diff --git a/hil-test/tests/uart_async.rs b/hil-test/tests/uart_async.rs index 7a36307c80..82eede75cb 100644 --- a/hil-test/tests/uart_async.rs +++ b/hil-test/tests/uart_async.rs @@ -6,7 +6,10 @@ #![no_std] #![no_main] -use esp_hal::{uart::Uart, Async}; +use esp_hal::{ + uart::{self, Uart}, + Async, +}; use hil_test as _; struct Context { @@ -24,7 +27,9 @@ mod tests { let (rx, tx) = hil_test::common_test_pins!(peripherals); - let uart = Uart::new(peripherals.UART0, rx, tx).unwrap().into_async(); + let uart = Uart::new(peripherals.UART0, uart::Config::default(), rx, tx) + .unwrap() + .into_async(); Context { uart } } diff --git a/hil-test/tests/uart_regression.rs b/hil-test/tests/uart_regression.rs index 841f17d7f2..a88124196d 100644 --- a/hil-test/tests/uart_regression.rs +++ b/hil-test/tests/uart_regression.rs @@ -11,7 +11,7 @@ mod tests { use esp_hal::{ gpio::OutputPin, prelude::*, - uart::{UartRx, UartTx}, + uart::{self, UartRx, UartTx}, }; use hil_test as _; use nb::block; @@ -23,7 +23,7 @@ mod tests { let (rx, mut tx) = hil_test::common_test_pins!(peripherals); - let mut rx = UartRx::new(peripherals.UART1, rx).unwrap(); + let mut rx = UartRx::new(peripherals.UART1, uart::Config::default(), rx).unwrap(); // start reception _ = rx.read_byte(); // this will just return WouldBlock @@ -31,7 +31,7 @@ mod tests { unsafe { tx.set_output_high(false, esp_hal::Internal::conjure()) }; // set up TX and send a byte - let mut tx = UartTx::new(peripherals.UART0, tx).unwrap(); + let mut tx = UartTx::new(peripherals.UART0, uart::Config::default(), tx).unwrap(); tx.flush_tx().unwrap(); tx.write_bytes(&[0x42]).unwrap(); diff --git a/hil-test/tests/uart_tx_rx.rs b/hil-test/tests/uart_tx_rx.rs index 8274a9043d..20c3fc1861 100644 --- a/hil-test/tests/uart_tx_rx.rs +++ b/hil-test/tests/uart_tx_rx.rs @@ -7,7 +7,7 @@ use esp_hal::{ prelude::*, - uart::{UartRx, UartTx}, + uart::{self, UartRx, UartTx}, Blocking, }; use hil_test as _; @@ -29,8 +29,8 @@ mod tests { let (rx, tx) = hil_test::common_test_pins!(peripherals); - let tx = UartTx::new(peripherals.UART0, tx).unwrap(); - let rx = UartRx::new(peripherals.UART1, rx).unwrap(); + let tx = UartTx::new(peripherals.UART0, uart::Config::default(), tx).unwrap(); + let rx = UartRx::new(peripherals.UART1, uart::Config::default(), rx).unwrap(); Context { rx, tx } } diff --git a/hil-test/tests/uart_tx_rx_async.rs b/hil-test/tests/uart_tx_rx_async.rs index 4f02cf63bd..8fbb0c226c 100644 --- a/hil-test/tests/uart_tx_rx_async.rs +++ b/hil-test/tests/uart_tx_rx_async.rs @@ -7,7 +7,7 @@ #![no_main] use esp_hal::{ - uart::{UartRx, UartTx}, + uart::{self, UartRx, UartTx}, Async, }; use hil_test as _; @@ -28,8 +28,12 @@ mod tests { let (rx, tx) = hil_test::common_test_pins!(peripherals); - let tx = UartTx::new(peripherals.UART0, tx).unwrap().into_async(); - let rx = UartRx::new(peripherals.UART1, rx).unwrap().into_async(); + let tx = UartTx::new(peripherals.UART0, uart::Config::default(), tx) + .unwrap() + .into_async(); + let rx = UartRx::new(peripherals.UART1, uart::Config::default(), rx) + .unwrap() + .into_async(); Context { rx, tx } } diff --git a/qa-test/src/bin/embassy_i2c.rs b/qa-test/src/bin/embassy_i2c.rs index e48f903944..45a58efcec 100644 --- a/qa-test/src/bin/embassy_i2c.rs +++ b/qa-test/src/bin/embassy_i2c.rs @@ -38,6 +38,7 @@ async fn main(_spawner: Spawner) { config.frequency = 400.kHz(); config }) + .unwrap() .with_sda(peripherals.GPIO4) .with_scl(peripherals.GPIO5) .into_async(); diff --git a/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs b/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs index 328ee3aa7b..77af5f4c76 100644 --- a/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs +++ b/qa-test/src/bin/embassy_i2c_bmp180_calibration_data.rs @@ -37,6 +37,7 @@ async fn main(_spawner: Spawner) { config.frequency = 400.kHz(); config }) + .unwrap() .with_sda(peripherals.GPIO4) .with_scl(peripherals.GPIO5) .into_async(); diff --git a/qa-test/src/bin/i2c_bmp180_calibration_data.rs b/qa-test/src/bin/i2c_bmp180_calibration_data.rs index 2d765fc31c..593765d16e 100644 --- a/qa-test/src/bin/i2c_bmp180_calibration_data.rs +++ b/qa-test/src/bin/i2c_bmp180_calibration_data.rs @@ -25,6 +25,7 @@ fn main() -> ! { // Create a new peripheral object with the described wiring and standard // I2C clock speed: let mut i2c = I2c::new(peripherals.I2C0, Config::default()) + .unwrap() .with_sda(peripherals.GPIO4) .with_scl(peripherals.GPIO5); diff --git a/qa-test/src/bin/i2c_display.rs b/qa-test/src/bin/i2c_display.rs index c950def05f..5c64ee40cb 100644 --- a/qa-test/src/bin/i2c_display.rs +++ b/qa-test/src/bin/i2c_display.rs @@ -38,6 +38,7 @@ fn main() -> ! { // Create a new peripheral object with the described wiring // and standard I2C clock speed let i2c = I2c::new(peripherals.I2C0, Config::default()) + .unwrap() .with_sda(peripherals.GPIO4) .with_scl(peripherals.GPIO5); diff --git a/qa-test/src/bin/lcd_cam_ov2640.rs b/qa-test/src/bin/lcd_cam_ov2640.rs index 14f8b69038..0a5c931464 100644 --- a/qa-test/src/bin/lcd_cam_ov2640.rs +++ b/qa-test/src/bin/lcd_cam_ov2640.rs @@ -34,7 +34,7 @@ use esp_hal::{ master::{Config, I2c}, }, lcd_cam::{ - cam::{Camera, RxEightBits}, + cam::{self, Camera, RxEightBits}, LcdCam, }, prelude::*, @@ -65,8 +65,12 @@ fn main() -> ! { peripherals.GPIO16, ); + let mut cam_config = cam::Config::default(); + cam_config.frequency = 20u32.MHz(); + let lcd_cam = LcdCam::new(peripherals.LCD_CAM); - let camera = Camera::new(lcd_cam.cam, peripherals.DMA_CH0, cam_data_pins, 20u32.MHz()) + let camera = Camera::new(lcd_cam.cam, peripherals.DMA_CH0, cam_data_pins, cam_config) + .unwrap() .with_master_clock(cam_xclk) .with_pixel_clock(cam_pclk) .with_ctrl_pins(cam_vsync, cam_href); @@ -76,6 +80,7 @@ fn main() -> ! { delay.delay_millis(500u32); let i2c = I2c::new(peripherals.I2C0, Config::default()) + .unwrap() .with_sda(cam_siod) .with_scl(cam_sioc); diff --git a/qa-test/src/bin/lcd_dpi.rs b/qa-test/src/bin/lcd_dpi.rs index 7b3b0e04fd..5b85b7ef16 100644 --- a/qa-test/src/bin/lcd_dpi.rs +++ b/qa-test/src/bin/lcd_dpi.rs @@ -62,6 +62,7 @@ fn main() -> ! { peripherals.I2C0, i2c::master::Config::default().with_frequency(400.kHz()), ) + .unwrap() .with_sda(peripherals.GPIO47) .with_scl(peripherals.GPIO48); @@ -137,6 +138,7 @@ fn main() -> ! { polarity: Polarity::IdleLow, phase: Phase::ShiftLow, }; + config.frequency = 16.MHz(); config.format = Format { enable_2byte_mode: true, ..Default::default() @@ -160,7 +162,8 @@ fn main() -> ! { config.de_idle_level = Level::Low; config.disable_black_region = false; - let mut dpi = Dpi::new(lcd_cam.lcd, tx_channel, 16.MHz(), config) + let mut dpi = Dpi::new(lcd_cam.lcd, tx_channel, config) + .unwrap() .with_vsync(vsync_pin) .with_hsync(peripherals.GPIO46) .with_de(peripherals.GPIO17) diff --git a/qa-test/src/bin/lcd_i8080.rs b/qa-test/src/bin/lcd_i8080.rs index 88d8c96aab..662201d1a9 100644 --- a/qa-test/src/bin/lcd_i8080.rs +++ b/qa-test/src/bin/lcd_i8080.rs @@ -67,14 +67,11 @@ fn main() -> ! { ); let lcd_cam = LcdCam::new(peripherals.LCD_CAM); - let i8080 = I8080::new( - lcd_cam.lcd, - peripherals.DMA_CH0, - tx_pins, - 20.MHz(), - Config::default(), - ) - .with_ctrl_pins(lcd_rs, lcd_wr); + let mut i8080_config = Config::default(); + i8080_config.frequency = 20.MHz(); + let i8080 = I8080::new(lcd_cam.lcd, peripherals.DMA_CH0, tx_pins, i8080_config) + .unwrap() + .with_ctrl_pins(lcd_rs, lcd_wr); // Note: This isn't provided in the HAL since different drivers may require // different considerations, like how to manage the CS pin, the CD pin, diff --git a/qa-test/src/bin/qspi_flash.rs b/qa-test/src/bin/qspi_flash.rs index 7b960f9fdd..04e8133e4a 100644 --- a/qa-test/src/bin/qspi_flash.rs +++ b/qa-test/src/bin/qspi_flash.rs @@ -75,12 +75,13 @@ fn main() -> ! { let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); - let mut spi = Spi::new_with_config( + let mut spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_mosi(mosi) .with_miso(miso) 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 3faae70cac..58b6feff24 100644 --- a/qa-test/src/bin/spi_halfduplex_read_manufacturer_id.rs +++ b/qa-test/src/bin/spi_halfduplex_read_manufacturer_id.rs @@ -61,12 +61,13 @@ fn main() -> ! { } } - let mut spi = Spi::new_with_config( + let mut spi = Spi::new( peripherals.SPI2, Config::default() .with_frequency(100.kHz()) .with_mode(SpiMode::Mode0), ) + .unwrap() .with_sck(sclk) .with_mosi(mosi) .with_miso(miso)