Skip to content

Releases: esp-rs/esp-hal

0.22.0

20 Nov 09:41
bdfec37
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

Migration Guide

IO changes

GPIO pins are now accessible via Peripherals

 let peripherals = esp_hal::init(Default::default());
-let io = Io::new(peripherals.GPIO, peripherals.IOMUX);
-let pin = io.pins.gpio5;
+let pin = peripherals.GPIO5;

Io constructor changes

  • new_with_priority and new_no_bind_interrupts have been removed.
    Use set_priority to configure the GPIO interrupt priority.
    We no longer overwrite interrupt handlers set by user code during initialization.
  • new no longer takes peripherals.GPIO

Removed async-specific constructors

The following async-specific constuctors have been removed:

  • configure_for_async DMA channel constructors
  • TwaiConfiguration::new_async and TwaiConfiguration::new_async_no_transceiver
  • I2c::new_async
  • LcdCam::new_async
  • UsbSerialJtag::new_async
  • Rsa::new_async
  • Rmt::new_async
  • Uart::new_async, Uart::new_async_with_config
  • UartRx::new_async, UartRx::new_async_with_config
  • UartTx::new_async, UartTx::new_async_with_config

You can use the blocking counterparts, then call into_async on the returned peripheral instead.

-let mut config = twai::TwaiConfiguration::new_async(
+let mut config = twai::TwaiConfiguration::new(
     peripherals.TWAI0,
     loopback_pin.peripheral_input(),
     loopback_pin,
     twai::BaudRate::B1000K,
     TwaiMode::SelfTest,
-);
+).into_async();

Some drivers were implicitly configured to the asyncness of the DMA channel used to construct them.
This is no longer the case, and the following drivers will always be created in blocking mode:

  • i2s::master::I2s
  • spi::master::SpiDma and spi::master::SpiDmaBus

Peripheral types are now optional

You no longer have to specify the peripheral instance in the driver's type for the following
peripherals:

  • SPI (both master and slave)
  • I2S
  • I2C
  • TWAI
  • UART
-Spi<'static, SPI2, FullDuplexMode>
+Spi<'static, FullDuplexMode>

-SpiDma<'static, SPI2, HalfDuplexMode, Blocking>
+SpiDma<'static, HalfDuplexMode, Blocking>

-I2sTx<'static, I2S0, Async>
+I2sTx<'static, Async>

Note that you may still specify the instance if you need to. To do this, we provide _typed
versions of the constructors (for example: new_typed, new_half_duplex_typed). Please note that
the peripheral instance has been moved to the last generic parameter position.

let spi: Spi<'static, FullDuplexMode, SPI2> = Spi::new_typed(peripherals.SPI2, 1.MHz(), SpiMode::Mode0);

I2C changes

The I2C master driver and related types have been moved to esp_hal::i2c::master.

The with_timeout constructors have been removed. new and new_typed now take a Config struct
with the available configuration options.

  • The default configuration is now:
    • bus frequency: 100 kHz
    • timeout: about 10 bus clock cycles

The constructors no longer take pins. Use with_sda and with_scl instead.

-use esp_hal::i2c::I2c;
+use esp_hal::i2c::{Config, I2c};
-let i2c = I2c::new_with_timeout(peripherals.I2C0, io.pins.gpio4, io.pins.gpio5, 100.kHz(), timeout);
+I2c::new_with_config(
+    peripherals.I2C0,
+    {
+        let mut config = Config::default();
+        config.frequency = 100.kHz();
+        config.timeout = timeout;
+        config
+    },
+)
+.with_sda(io.pins.gpio4)
+.with_scl(io.pins.gpio5);

The calculation of I2C timeout has changed

Previously, I2C timeouts were counted in increments of I2C peripheral clock cycles. This meant that
the configure value meant different lengths of time depending on the device. With this update, the
I2C configuration now expects the timeout value in number of bus clock cycles, which is consistent
between devices.

ESP32 and ESP32-S2 use an exact number of clock cycles for its timeout. Other MCUs, however, use
the 2^timeout value internally, and the HAL rounds up the timeout to the next appropriate value.

Changes to half-duplex SPI

The HalfDuplexMode and FullDuplexMode type parameters have been removed from SPI master and slave
drivers. It is now possible to execute half-duplex and full-duplex operations on the same SPI bus.

Driver construction

  • The Spi::new_half_duplex constructor has been removed. Use new (or new_typed) instead.
  • The with_pins methods have been removed. Use the individual with_* functions instead.
  • The with_mosi and with_miso functions now take input-output peripheral signals to support half-duplex mode.
- let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
-     .with_pins(sck, mosi, miso, sio2, sio3, cs);
+ let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
+     .with_sck(sck)
+     .with_cs(cs)
+     .with_mosi(mosi)
+     .with_miso(miso)
+     .with_sio2(sio2)
+     .with_sio3(sio3);

Transfer functions

The Spi<'_, SPI, HalfDuplexMode>::read and Spi<'_, SPI, HalfDuplexMode>::write functions have been replaced by
half_duplex_read and half_duplex_write.

 let mut data = [0u8; 2];
 let transfer = spi
-    .read(
+    .half_duplex_read(
         SpiDataMode::Single,
         Command::Command8(0x90, SpiDataMode::Single),
         Address::Address24(0x000000, SpiDataMode::Single),
         0,
         &mut data,
     )
     .unwrap();

 let transfer = spi
-    .write(
+    .half_duplex_write(
         SpiDataMode::Quad,
         Command::Command8(write as u16, command_data_mode),
         Address::Address24(
             write as u32 | (write as u32) << 8 | (write as u32) << 16,
             SpiDataMode::Quad,
         ),
         0,
         dma_tx_buf,
     )
     .unwrap();

Slave-mode SPI

Driver construction

The constructors no longer accept pins. Use the with_pin_name setters instead.

 let mut spi = Spi::new(
     peripherals.SPI2,
-    sclk,
-    mosi,
-    miso,
-    cs,
     SpiMode::Mode0,
-);
+)
+.with_sclk(sclk)
+.with_mosi(mosi)
+.with_miso(miso)
+.with_cs(cs);

UART event listening

The following functions have been removed:

  • listen_at_cmd
  • unlisten_at_cmd
  • listen_tx_done
  • unlisten_tx_done
  • listen_rx_fifo_full
  • unlisten_rx_fifo_full
  • at_cmd_interrupt_set
  • tx_done_interrupt_set
  • rx_fifo_full_interrupt_set
  • reset_at_cmd_interrupt
  • reset_tx_done_interrupt
  • reset_rx_fifo_full_interrupt

You can now use the UartInterrupt enum and the corresponding listen, unlisten, interrupts and clear_interrupts functions.

Use interrupts in place of <INTERRUPT>_interrupt_set and clear_interrupts in place of the old reset_ functions.

UartInterrupt:

  • AtCmd
  • TxDone
  • RxFifoFull

Checking interrupt bits is now done using APIs provided by enumset. For example, to see if
a particular interrupt bit is set, use contains:

-serial.at_cmd_interrupt_set()
+serial.interupts().contains(UartInterrupt::AtCmd)

You can now listen/unlisten multiple interrupt bits at once:

-uart0.listen_at_cmd();
-uart0.listen_rx_fifo_full();
+uart0.listen(UartInterrupt::AtCmd | UartConterrupt::RxFifoFull);

I2S changes

The I2S driver has been moved to i2s::master

-use esp_hal::i2s::{DataFormat, I2s, Standard};
+use esp_hal::i2s::master::{DataFormat, I2s, Standard};

Removed i2s traits

The following traits have been removed:

  • I2sWrite
  • I2sWriteDma
  • I2sRead
  • I2sReadDma
  • I2sWriteDmaAsync
  • I2sReadDmaAsync

You no longer have to import these to access their respective APIs. If you used these traits
in your functions as generic parameters, you can use the I2s type directly instead.

For example:

-fn foo(i2s: &mut impl I2sWrite) {
+fn foo(i2s: &mut I2s<'_, I2S0, Blocking>) {
     // ...
 }

DMA related changes

Circular DMA transfer's available returns Result<usize, DmaError> now

In case of any error you should drop the transfer and restart it.

     loop {
-        let avail = transfer.available();
+        let avail = match transfer.available() {
+            Ok(avail) => avail,
+            Err(_) => {
+                core::mem::drop(transfer);
+                transfer = i2s_tx.write_dma_circular(&tx_buffer).unwrap();
+                continue;
+            },
+        };

Channel, ChannelRx and ChannelTx types have changed

  • Channel's Async/Blocking mode has been moved before the channel instance parameter.
  • ChannelRx and ChannelTx have gained a new Async/Blocking mode parameter.
-Channel<'d, DmaChannel0, Async>
+Channel<'d, Async, DmaChannel0>

-ChannelRx<'d, DmaChannel0>
+ChannelRx<'d, Async, DmaChannel0>

-ChannelTx<'d, DmaChannel0>
+ChannelTx<'d, Async, DmaChannel0>

Removed peripheral_input and into_peripheral_output from GPIO pin types

Creating peripheral interconnect signals now consume the GPIO pin used for the connection.

The previous signal function have been replaced by split. This change affects the following APIs:

  • GpioPin
  • AnyPin
-let input_signal = gpioN.peripheral_input();
-let output_signal = gpioN.into_peripheral_output();
+let (input_signal, output_signal) = gpioN.split();

into_peripheral_output, split (for output pins only) and peripheral_input have been added to
the GPIO drivers (Input, Output, OutputOpenDrain and Flex) instead.

ETM changes

  • The types are no longer prefixed with GpioEtm, TimerEtm or SysTimerEtm. You can still use
    import aliasses in case you ...
Read more

0.21.1

16 Oct 08:57
39c0baf
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

Changelog

Fixed

  • Restored blocking embedded_hal compatibility for async I2C driver (#2343)

0.21.0

10 Oct 11:13
5af3d9d
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

Migration Guides

Changelog

Added

  • Introduce traits for the DMA buffer objects (#1976, #2213)
  • Implement embedded-hal output pin traits for NoPin (#2019, #2133)
  • Added esp_hal::init to simplify HAL initialisation (#1970, #1999)
  • Added GpioPin::degrade to create ErasePins easily. Same for AnyPin by accident. (#2075)
  • Added missing functions to Flex: unlisten, is_interrupt_set, wakeup_enable, wait_for_high, wait_for_low, wait_for_rising_edge, wait_for_falling_edge, wait_for_any_edge. (#2075)
  • Flex now implements Wait. (#2075)
  • Added sleep and wakeup support for esp32c2 (#1922)
  • Input, Output, OutputOpenDrain and Flex now implement Peripheral. (#2094)
  • Previously unavailable memory is available via .dram2_uninit section (#2079)
  • You can now use Input, Output, OutputOpenDrain and Flex pins as EXTI and RTCIO wakeup sources (#2095)
  • Added Rtc::set_current_time to allow setting RTC time, and Rtc::current_time to getting RTC time while taking into account boot time (#1883)
  • Added APIs to allow connecting signals through the GPIO matrix. (#2128)
  • Allow I8080 transfers to be cancelled on the spot (#2191)
  • Implement TryFrom<u32> for ledc::timer::config::Duty (#1984)
  • Expose RtcClock::get_xtal_freq and RtcClock::get_slow_freq publically for all chips (#2183)
  • TWAI support for ESP32-H2 (#2199)
  • Make DmaDescriptor methods public (#2237)
  • Added a way to configure watchdogs in esp_hal::init (#2180)
  • Introduce DmaRxStreamBuf (#2242)
  • Implement embedded_hal_async::delay::DelayNs for TIMGx timers (#2084)
  • Added Efuse::read_bit (#2259)
  • Limited SPI slave support for ESP32 (Modes 1 and 3 only) (#2278)
  • Added Rtc::disable_rom_message_printing (S3 and H2 only) (#2280)
  • Added esp_hal::time::{Duration, Instant} (#2304)

Changed

  • Bump MSRV to 1.79.0 (#1971)
  • Make saving and restoring SHA digest state an explicit operation (#2049)
  • Reordered RX-TX pairs in all APIs to be consistent (#2074)
  • Make saving and restoring SHA digest state an explicit operation (#2049)
  • Delay::new() is now a const function (#1999)
  • Input, Output, OutputOpenDrain and Flex are now type-erased by default. Use the new new_typed constructor to keep using the ZST pin types. (#2075)
  • To avoid confusion with the Rtc::current_time wall clock time APIs, we've renamed esp_hal::time::current_time to esp_hal::time::now. (#2091)
  • Renamed touch::Continous to touch::Continuous. (#2094)
  • Faster SHA (#2112)
  • The (previously undocumented) ErasedPin enum has been replaced with the ErasedPin struct. (#2094)
  • Renamed and merged Rtc::get_time_us and Rtc::get_time_ms into Rtc::time_since_boot (#1883)
  • ESP32: Added support for touch sensing on GPIO32 and 33 (#2109)
  • Removed gpio pin generics from I8080 driver type. (#2171)
  • I8080 driver now decides bus width at transfer time rather than construction time. (#2171)
  • Migrate the I8080 driver to a move based API (#2191)
  • Replaced AnyPin with InputSignal and OutputSignal and renamed ErasedPin to AnyPin (#2128)
  • Replaced the ErasedTimer enum with the AnyTimer struct. (#2144)
  • Camera and AesDma now support erasing the DMA channel type (#2258)
  • Changed the parameters of Spi::with_pins to no longer be optional (#2133)
  • Renamed DummyPin to NoPin and removed all internal logic from it. (#2133)
  • The NO_PIN constant has been removed. (#2133)
  • Allow handling interrupts while trying to lock critical section on multi-core chips. (#2197)
  • Migrate Camera to a move based API (#2242).
  • Removed the PS-RAM related features, replaced by quad-psram/octal-psram, init_psram takes a configuration parameter, it's now possible to auto-detect PS-RAM size (#2178)
  • EspTwaiFrame constructors now accept any type that converts into esp_hal::twai::Id (#2207)
  • Change DmaTxBuf to support PSRAM on esp32s3 (#2161)
  • I2c transaction is now also available as a inherent function, lift size limit on write,read and write_read (#2262)
  • SPI transactions are now cancelled if the transfer object (or async Future) is dropped. (#2216)
  • The DMA channel types have been removed from peripherals (#2261)
  • I2C driver renamed to I2c (#2320)

Fixed

  • SHA driver can now be safely used in multiple contexts concurrently (#2049)
  • Fixed an issue with DMA transfers potentially not waking up the correct async task (#2065)
  • Fixed an issue with LCD_CAM i8080 where it would send double the clocks in 16bit mode (#2085)
  • Fix i2c embedded-hal transaction (#2028)
  • Fix some inconsistencies in DMA interrupt bits (#2169)
  • Fix SPI DMA alternating write and read for ESP32 and ESP32-S2 (#2131)
  • Fix I2C ending up in a state when only re-creating the peripheral makes it useable again (#2141)
  • Fix SpiBus::transfer transferring data twice in some cases (#2159)
  • Fixed UART freezing when using RcFast clock source on ESP32-C2/C3 (#2170)
  • I2S: on ESP32 and ESP32-S2 data is now output to the right (WS=1) channel first. (#2194)
  • SPI: Fixed an issue where unexpected data was written outside of the read buffer (#2179)
  • SPI: Fixed an issue where wait has returned before the DMA has finished writing the memory (#2179)
  • SPI: Fixed an issue where repeated calls to dma_transfer may end up looping indefinitely (#2179)
  • SPI: Fixed an issue that prevented correctly reading the first byte in a transaction (#2179)
  • SPI: ESP32: Send address with correct data mode even when no data is sent. (#2231)
  • SPI: ESP32: Allow using QSPI mode on SPI3. (#2245)
  • PARL_IO: Fixed an issue that caused garbage to be output at the start of some requests (#2211)
  • TWAI on ESP32 (#2207)
  • TWAI should no longer panic when receiving a non-compliant frame (#2255)
  • OneShotTimer: fixed delay_nanos behaviour (#2256)
  • Fixed unsoundness around Efuse (#2259)

Removed

  • Removed digest::Digest implementation from SHA (#2049)
  • Removed NoPinType in favour of DummyPin. (#2068)
  • Removed the async, embedded-hal-02, embedded-hal, embedded-io, embedded-io-async, and ufmt features (#2070)
  • Removed the GpioN type aliasses. Use GpioPin<N> instead. (#2073)
  • Removed Peripherals::take. Use esp_hal::init to obtain Peripherals (#1999)
  • Removed AnyInputOnlyPin in favour of AnyPin. (#2071)
  • Removed the following functions from GpioPin: is_high, is_low, set_high, set_low, set_state, is_set_high, is_set_low, toggle. (#2094)
  • Removed Rtc::get_time_raw (#1883)
  • Removed _with_default_pins UART constructors (#2132)
  • Removed transfer methods send, send_dma and send_dma_async from I8080 (#2191)
  • Removed uart::{DefaultRxPin, DefaultTxPin} (#2132)
  • Removed PcntSource and PcntInputConfig. (#2134)
  • Removed the place-spi-driver-in-ram feature, this is now enabled via esp-config (#2156)
  • Removed esp_hal::spi::slave::prelude (#2260)
  • Removed esp_hal::spi::slave::WithDmaSpiN traits (#2260)
  • The WithDmaAes trait has been removed (#2261)
  • The I2s::new_i2s1 constructor has been removed (#2261)

v0.20.1

30 Aug 11:32
aacc001
Compare
Choose a tag to compare

This is a patch release to fix a compilation issue, to view the full migration guide see the v0.20.0 release

Fixed

  • A build issue when including doc comment prelude (#2040)

0.20.0

29 Aug 19:52
5917275
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

Migration Guide

Peripheral driver constructors don't take InterruptHandlers anymore

Some peripherals used to take the interrupt handler via constructor. We have now unified this behaviour so that all peripherals use the same set_interrupt_handler method. We also have a new trait to abstract over this, InterruptConfigurable.

- Peripheral::new(/* params */, handler)
+ peripheral.set_interrupt_handler(handler);

OneShotTimer and PeriodicTimer structs now use PeripheralRef

This was something we missed on the initial impl. The migration is quite simple, there is a new lifetime parameter to contend with.

- OneShotTimer<ErasedTimer>;
+ OneShotTimer<'static, ErasedTimer>;

DMA buffer changes and SpiDma changes

To allow efficient queuing of DMA requests, we've changed how the DMA is interacted with. #1856 introduces new wrapper types DmaTxBuf, DmaRxBuf and DmaTxRxBuf. These are currently light wrappers around slices and descriptors, but allows us to do more complex checks for future devices and peripherals. Thanks to these changes, we have been able to remove the FlashSafeDma wrapper too.

let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(32000);
+ let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
+ let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();

We've also decoupled the DMA buffers and descriptors from the SpiDma struct itself, this means the end user can manage the queuing of DMA requests for more efficient operation. If you don't wish to manage this yourself and want to use the embedded_hal::spi::* traits, it's simple enough to opt back into the HAL buffer management like so.

let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
        .with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
        .with_dma(dma_channel.configure_for_async(false, DmaPriority::Priority0))
+       .with_buffers(dma_tx_buf, dma_rx_buf);

We also added inherent methods onto SpiDmaBus, which due to the way type inference works may introduce breaking changes if you were using the async API. You may need to fully qualify the trait method or call the new inherent _async methods.

- spi.transfer_in_place(&mut buf).await?;
+ spi.transfer_in_place_async(&mut buf).await?;

SystemTimer changes

  • The type signature of both SysTimer and Alarm has been changed to allow for creation of alarms in either Blocking or Async separately. We have provided a convenience method to create all alarms in the same mode, just as it behaved before this release.
- let syst = SystemTimer::new_async(peripherals.SYSTIMER);
+ let syst = SystemTimer::new(peripherals.SYSTIMER);
+ let alarms = syst.split_async::<esp_hal::timer::systimer::Target>()
  • SystemTimer::TICKS_PER_SECOND has been replaced by SystemTimer::ticks_per_second().

Sha state is now stored outside the Sha peripheral

The state is now stored separately to allow multiple Sha operations concurrently.

- sha.update(remaining).unwrap();
+ let mut sha1 = Sha1::new();
+ Sha::update(&mut sha1, remaining).unwrap();

Remove fn free(self) from HMAC

The fn free(self) method is no longer available, in favour of the PeripheralRef API.

RSA modular multiplication

RsaModularMultiplication has been consolidated for all targets.

ESP32 changes

 let r = compute_r(&BIGNUM_3);
 let mut mod_multi =
     RsaModularMultiplication::<Op512, Blocking>::new(
         &mut ctx.rsa,
+        BIGNUM_1.as_words(), // Operand A
         BIGNUM_3.as_words(), // Modulus
+        r.as_words(),
         compute_mprime(&BIGNUM_3),
     );
-mod_multi.start_step1(BIGNUM_1.as_words(), r.as_words()); // Operand A
-mod_multi.start_step2(BIGNUM_2.as_words()); // Operand B
+mod_multi.start_modular_multiplication(BIGNUM_2.as_words()); // Operand B
 mod_multi.read_results(&mut outbuf);

Non-ESP32 changes

 let r = compute_r(&BIGNUM_3);
 let mut mod_multi =
     RsaModularMultiplication::<operand_sizes::Op512, esp_hal::Blocking>::new(
         &mut ctx.rsa,
         BIGNUM_1.as_words(), // Operand A
-        BIGNUM_2.as_words(), // Operand B
         BIGNUM_3.as_words(), // Modulus
+        r.as_words(),
         compute_mprime(&BIGNUM_3),
     );
-mod_multi.start_modular_multiplication(r.as_words());
+mod_multi.start_modular_multiplication(BIGNUM_2.as_words()); // Operand B
 mod_multi.read_results(&mut outbuf);

Simpler way to initialise embassy and esp-wifi

You no longer have to spell out a bunch of type conversions, to initialize esp-wifi or embassy with a single timer. We provide conversions for TimerGroup times as well as SysTimer alarms.

Note that if you need to pass multiple timers to embassy, you will still need to do the conversions yourself.

AnyPin, AnyInputOnyPin and DummyPin are now accessible from gpio directly

- use esp_hal::gpio::any_pin::AnyPin;
- - use esp_hal::gpio::dummy_pin::DummyPin;
+ use esp_hal::gpio::AnyPin;
+ use esp_hal::gpio::DummyPin;

Initialising embassy

let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
-let timer0: ErasedTimer = timg0.timer0.into();
-let timers = [OneShotTimer::new(timer0)];
-let timers = mk_static!([OneShotTimer<ErasedTimer>; 1], timers);
-esp_hal_embassy::init(&clocks, timers);
+esp_hal_embassy::init(&clocks, timg0.timer0);
let systimer = SystemTimer::new(peripherals.SYSTIMER).split::<Target>();
-let alarm0: ErasedTimer = systimer.alarm0.into();
-let timers = [OneShotTimer::new(alarm0)];
-let timers = mk_static!([OneShotTimer<ErasedTimer>; 1], timers);
-esp_hal_embassy::init(&clocks, timers);
+esp_hal_embassy::init(&clocks, systimer.alarm0);

Initializing esp-wifi

let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
-let timer0: ErasedTimer = timg0.timer0.into();
-let timer = PeriodicTimer::new(timer0);

let init = initialize(
    EspWifiInitFor::Wifi,
-   timer,
+   timg0.timer0,
    Rng::new(peripherals.RNG),
    peripherals.RADIO_CLK,
    clocks,
)
.unwrap();
let systimer = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER).split::<esp_hal::timer::systimer::Target>();
-let alarm0: ErasedTimer = systimer.alarm0.into();
-let alarm = PeriodicTimer::new(alarm0);

let init = initialize(
    EspWifiInitFor::Wifi,
-   alarm,
+   systimer.alarm0,
    Rng::new(peripherals.RNG),
    peripherals.RADIO_CLK,
    clocks,
)
.unwrap();

Floating point support

Floating point operations in interrupt contexts are no longer allowed by default. If you experience Cp0Disabled panics, you should try enabling the float-save-restore feature on xtensa-lx-rt.

Changelog

Added

  • Introduce DMA buffer objects (#1856, #1985)
  • Added new Io::new_no_bind_interrupt constructor (#1861)
  • Added touch pad support for esp32 (#1873, #1956)
  • Allow configuration of period updating method for MCPWM timers (#1898)
  • Add self-testing mode for TWAI peripheral. (#1929)
  • Added a PeripheralClockControl::reset to the driver constructors where missing (#1893)
  • Added digest::Digest implementation to SHA (#1908)
  • Added debugger::debugger_connected. (#1961)
  • DMA: don't require Sealed to implement ReadBuffer and WriteBuffer (#1921)
  • Allow DMA to/from psram for esp32s3 (#1827)
  • Added missing methods to SpiDmaBus (#2016).
  • PARL_IO use ReadBuffer and WriteBuffer for Async DMA (#1996)

Changed

  • Peripheral driver constructors don't take InterruptHandlers anymore. Use set_interrupt_handler to explicitly set the interrupt handler now. (#1819)
  • Migrate SPI driver to use DMA buffer objects (#1856, #1985)
  • Use the peripheral ref pattern for OneShotTimer and PeriodicTimer (#1855)
  • Improve SYSTIMER API (#1871)
  • SHA driver now use specific structs for the hashing algorithm instead of a parameter. (#1908)
  • Remove fn free(self) in HMAC which goes against esp-hal API guidelines (#1972)
  • AnyPin, AnyInputOnyPin and DummyPin are now accessible from gpio module (#1918)
  • Changed the RSA modular multiplication API to be consistent across devices (#2002)

Fixed

  • Improve error detection in the I2C driver (#1847)
  • Fix I2S async-tx (#1833)
  • Fix PARL_IO async-rx (#1851)
  • SPI: Clear DMA interrupts before (not after) DMA starts (#1859)
  • SPI: disable and re-enable MISO and MOSI in start_transfer_dma, start_read_bytes_dma and start_write_bytes_dma accordingly (#1894)
  • TWAI: GPIO pins are not configured as input and output (#1906)
  • ESP32C6: Make ADC usable after TRNG deinicialization (#1945)
  • We should no longer generate 1GB .elf files for ESP32C2 and ESP32C3 (#1962)
  • Reset peripherals in driver constructors where missing (#1893, #1961)
  • Fixed ESP32-S2 systimer interrupts (#1979)
  • Software interrupt 3 is no longer available when it is required by esp-hal-embassy. (#2011)
  • ESP32: Fixed async RSA (#2002)

Removed

  • This package no longer re-exports the esp_hal_procmacros::main macro (#1828)
  • The AesFlavour trait no longer has the ENCRYPT_MODE/DECRYPT_MODE associated constants (#1849)
  • Removed FlashSafeDma (#1856)
  • Remove redundant WithDmaSpi traits (#1975)
  • IsFullDuplex and IsHalfDuplex traits (#1985)

0.19.0

15 Jul 22:45
eddcb73
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

Migration Guide

Coming Soon™️ (sorry, I forgot to write it 😅)

Changelog

Added

  • uart: Added with_cts/with_rtss methods to configure CTS, and RTS pins (#1592)
  • uart: Constructors now require TX and RX pins (#1592)
  • uart: Added Uart::new_with_default_pins constructor (#1592)
  • uart: Added UartTx and UartRx constructors (#1592)
  • Add Flex / AnyFlex GPIO pin driver (#1659)
  • Add new DmaError::UnsupportedMemoryRegion - used memory regions are checked when preparing a transfer now (#1670)
  • Add DmaTransactionTxOwned, DmaTransactionRxOwned, DmaTransactionTxRxOwned, functions to do owning transfers added to SPI half-duplex (#1672)
  • uart: Implement embedded_io::ReadReady for Uart and UartRx (#1702)
  • ESP32-S3: Expose optional HSYNC input in LCD_CAM (#1707)
  • ESP32-C6: Support lp-core as wake-up source (#1723)
  • Add support for GPIO wake-up source (#1724)
  • gpio: add DummyPin (#1769)
  • dma: add Mem2Mem to support memory to memory transfer (#1738)
  • Add uart wake source (#1727)
  • #[ram(persistent)] option to replace the unsound uninitialized option (#1677)
  • uart: Make rx_timeout optional in Config struct (#1759)
  • Add interrupt related functions to PeriodicTimer/OneShotTimer, added ErasedTimer (#1753)
  • Added blocking read_bytes method to Uart and UartRx (#1784)

Fixed

  • ESP32-S3: Fix DMA waiting check in LCD_CAM (#1707)
  • TIMG: Fix interrupt handler setup (#1714)
  • Fix sleep_light for ESP32-C6 (#1720)
  • ROM Functions: Fix address of ets_update_cpu_frequency_rom (#1722)
  • Fix regi2c_* functions for esp32h2 (#1737)
  • Improved #[ram(zeroed)] soundness by adding a bytemuck::Zeroable type bound (#1677)
  • EESP32-S2 / ESP32-S3: Fix UsbDm and UsbDp for Gpio19 and Gpio20
  • Fix reading/writing small buffers via SPI master async dma (#1760)
  • Remove unnecessary delay in rtc_ctnl (#1794)

Changed

  • Refactor Dac1/Dac2 drivers into a single Dac driver (#1661)
  • esp-hal-embassy: make executor code optional (but default) again
  • Improved interrupt latency on RISC-V based chips (#1679)
  • esp_wifi::initialize no longer requires running maximum CPU clock, instead check it runs above 80MHz. (#1688)
  • Move DMA descriptors from DMA Channel to each individual peripheral driver. (#1719)
  • Support DMA chunk sizes other than the default 4092 (#1758)
  • Improved interrupt latency on Xtensa based chips (#1735)
  • Improve PCNT api (#1765)

Removed

  • uart: Removed configure_pins methods (#1592)
  • Removed DmaError::Exhausted error by improving the implementation of the pop function (#1664)
  • Unsound #[ram(uninitialized)] option in favor of the new persistent option (#1677)

0.18.0

04 Jun 16:35
e50f663
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

Migration Guide

SystemControl

We have removed the SystemExt trait, meaning that the SYSTEM peripheral no longer has a split() method. Instead, we now instantiate a new SystemControl struct:

use esp_hal::{peripherals::Peripherals, system::SystemControl, clock::ClockControl};

let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();

Timers

There have been a number of changes to the various timer drivers in esp-hal, notable the reorganization of their modules. While previously we had systimer (SYSTIMER) and timer (TIMGx) modules, these have been combined into a common module, and are now available at timer::systimer and timer::timg0 respectively.

Additionally, there have been some minor changes in API relating to the introduction of the timer::Timer trait; these should be mostly straight forward to resolve, refer to the documentation.

GPIO

The GPIO system has been reworked to remove into_X methods, in favour of a concrete pin type.

Old into_X method New type
output Output
output open drain OutputOpenDrain
input Input

For example code such as io.pins.gpio18.into_push_pull_output() should be replaced with Output::new(io.pins.gpio18) for each respective case. To see more discussion and examples for this change, see the RFC and implementation PR.

esp-hal-embassy

As of this release, support for [Embassy] has been extracted from esp-hal into its own package, esp-hal-embassy. This is nearly a drop-in replacement, only a few small changes are required.

First, add the new dependency to your Cargo.toml:

[dependencies]
esp-hal-embassy = { version = "0.1.0", features = [
    "time-timg0",            # Compatible with all chips
    # "time-systimer-16mhz", # Compatible with all chips except ESP32 and ESP32-S2
    # "time-systimer-80mhz", # Compatible with ESP32-S2 only
] }

Note that in previous version, the time-systimer-* features were incorrectly named time-systick-*; this has now been rectified. Additionally, as of this release it is no longer required to select an executor via its Cargo feature; both the thread-mode and interrupt-mode executors are now available by default.

Next, simply replace any references to the esp_hal::embassy module and its children with the esp_hal_embassy package instead. This can likely be accomplished with a simple search-and-replace in your text editor.

Changelog

Added

  • i2c: implement I2C:transaction for embedded-hal and embedded-hal-async (#1505)
  • spi: implement with_bit_order (#1537)
  • ESP32-PICO-V3-02: Initial support (#1155)
  • time::current_time API (#1503)
  • ESP32-S3: Add LCD_CAM Camera driver (#1483)
  • embassy-usb support (#1517)
  • SPI Slave support for ESP32-S2 (#1562)
  • Add new generic OneShotTimer and PeriodicTimer drivers, plus new Timer trait which is implemented for TIMGx and SYSTIMER (#1570)

Fixed

  • i2c: i2c1_handler used I2C0 register block by mistake (#1487)
  • Removed ESP32 specific code for resolutions > 16 bit in ledc embedded_hal::pwm max_duty_cycle function. (#1441)
  • Fixed division by zero in ledc embedded_hal::pwm set_duty_cycle function and converted to set_duty_hw instead of set_duty to eliminate loss of granularity. (#1441)
  • Embassy examples now build on stable (#1485)
  • Fix delay on esp32h2 (#1535)
  • spi: fix dma wrong mode when using eh1 blocking api (#1541)
  • uart: make uart::UartRx::read_byte public (#1547)
  • Fix async serial-usb-jtag (#1561)
  • Feeding RWDT now actually works (#1645)

Changed

  • Removed unneeded generic parameters on Usb (#1469)
  • Created virtual peripherals for CPU control and radio clocks, rather than splitting them from SYSTEM (#1428)
  • IO, ADC, DAC, RTC*, LEDC, PWM and PCNT drivers have been converted to camel case format (#1473)
  • RNG is no longer TRNG, the CryptoRng implementation has been removed. To track this being re-added see #1499 (#1498)
  • Make software interrupts shareable (#1500)
  • The SystemParts struct has been renamed to SystemControl, and now has a constructor which takes the SYSTEM peripheral (#1495)
  • Timer abstraction: refactor systimer and timer modules into a common timer module (#1527)
  • Removed the embassy-executor-thread and embassy-executor-interrupt features, they are now enabled by default when embassy is enabled. (#1485)
  • Software interrupt 3 is now used instead of software interrupt 0 on the thread aware executor on multicore systems (#1485)
  • Timer abstraction: refactor systimer and timer modules into a common timer module (#1527)
  • Refactoring of GPIO module, have drivers for Input,Output,OutputOpenDrain, all drivers setup their GPIOs correctly (#1542)
  • DMA transactions are now found in the dma module (#1550)
  • Remove unnecessary generics from PARL_IO driver (#1545)
  • Use Level enum in GPIO constructors instead of plain bools (#1574)
  • rmt: make ChannelCreator public (#1597)

Removed

  • Removed the SystemExt trait (#1495)
  • Removed the GpioExt trait (#1496)
  • Embassy support (and all related features) has been removed, now available in the esp-hal-embassy package instead (#1595)

0.17.0

18 Apr 17:06
822bef1
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes. Read the full changelog entry for all the changes.

[email protected] Migration Guide

This release changes interrupt handler binding from link-time binding to runtime-binding. This increases flexibility of how interrupts can be used, but the main reason is two allow mixing mixing async and non-async drivers in the same application.

Key changes

The biggest change is the removal of the #[interrupt] macro. It has been replaced by the #[handler] macro which works differently slightly differently.

Now you have to bind the interrupt handler explicitly. The supported peripheral drivers either take a new optional parameter to their constructor or it will offer a set_interrupt_handler function. Don't worry, if you forget to do this, the compiler will emit an unused warning for the #[handler] function.

The second change is that most drivers will now have a MODE parameter with some new constructors to initialize a driver in Blocking or Async mode. You will need to account for this in your code.

Finally, most root level re-exports are now gone, instead, you should import from the specific module.

Below is a list of key changes you need to make to upgrade.


There is no longer a need to enable interrupts manually unless you are changing a priority later in the application. This change also means the interrupt is enabled once the interrupt is used, so please ensure that you have the proper ordering of initialization or critical sections to account for that.

- interrupt::enable(Interrupt::GPIO, Priority::Priority2).unwrap();

Use the new handler macro.

- #[interrupt]
+ #[handler]

Ensure you set the handler, depending on the peripheral this may be part of the constructor or a method such as the one below.

+ io.set_interrupt_handler(handler);

Interrupts are now tightly coupled to their priority, meaning you can pass a priority to the handler macro. The default unless specified is the lowest priority.

+ #[handler(priority = "Priority::max()")]

0.16.1

12 Mar 15:25
92e3ea5
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

Fixed

  • Resolved an issue with the defmt dependency/feature (#1264)

Changed

  • Use ROM memcpy over compiler builtins (#1255)
  • Do not ensure randomness or implement the CryptoRng trait for ESP32-P4/S2 (#1267)

0.16.0

08 Mar 14:13
e198f0e
Compare
Choose a tag to compare

Please note that only changes to the esp-hal package are tracked in these release notes.

[email protected] Migration Guide

This release consolidates the various chip-specific HAL packages into a single package, esp-hal. Projects which previously depended on the chip-specific packages (esp32-hal, esp32c3-hal, etc.) should be updated to use esp-hal instead.

We now have self-hosted documentation built for each supported chip! See https://docs.esp-rs.org/esp-hal/ for more details.

In order to migrate your project to the latest release, please follow the short guide below.

If you encounter any issues during the migration process, please open an issue, and we will do our best to resolve them as expediently as possible.

Migrating to esp-hal

In general, only two steps should be required for this migration:

  • Update your dependencies in the Cargo manifest
  • Update any references to the HAL in your project's source files

Depending on which features you are using, there may be some additional changes required. Please refer to the esp-hal documentation for a full list of features.

Updating Dependencies

First, update your dependencies in Cargo.toml and enable the appropriate feature for the chip being targeted.

For example, if your project previously depended on esp32c3-hal then open your project's Cargo.toml file and make the following change:

- esp32c3-hal = "0.15.0"
+ esp-hal = { version = "0.16.0", features = ["esp32c3"] }

Update Imports

Next, update any references to the chip-specific HAL package (e.g. esp32c3-hal) in your project's source files. This can likely be done with a global search-and-replace in your favourite text editor.

In general this will only affect imports, e.g.:

- use esp32c3_hal::*;
+ use esp_hal::*;

Changelog

Added

  • Add initial support for the ESP32-P4 (#1101)
  • Implement embedded_hal::pwm::SetDutyCycle trait for ledc::channel::Channel (#1097)
  • ESP32-P4: Add initial GPIO support (#1109)
  • ESP32-P4: Add initial support for interrupts (#1112)
  • ESP32-P4: Add efuse reading support (#1114)
  • ESP32-S3: Added LCD_CAM I8080 driver (#1086)
  • Allow for splitting of the USB Serial JTAG peripheral into tx/rx components (#1024)
  • RngCore trait is implemented (#1122)
  • Support Rust's stack-protector feature (#1135)
  • Adding clock support for ESP32-P4 (#1145)
  • Implementation OutputPin and InputPin for AnyPin (#1067)
  • Implement estimate_xtal_frequency for ESP32-C6 / ESP32-H2 (#1174)
  • A way to push into I2S DMA buffer via a closure (#1189)
  • Added basic LP-I2C driver for C6 (#1185)
  • Ensuring that the random number generator is TRNG. (#1200)
  • ESP32-C6: Add timer wakeup source for deepsleep (#1201)
  • Introduce InterruptExecutor::spawner() (#1211)

Fixed

  • Fix embassy-time tick rate not set when using systick as the embassy timebase (#1124)
  • Fix get_raw_core on Xtensa (#1126)
  • Fix docs.rs documentation builds (#1129)
  • Fix circular DMA (#1144)
  • Fix hello_rgb example for ESP32 (#1173)
  • Fixed the multicore critical section on Xtensa (#1175)
  • Fix timer now for esp32c3 and esp32c6 (#1178)
  • Wait for registers to get synced before reading the timer count for all chips (#1183)
  • Fix I2C error handling (#1184)
  • Fix circular DMA (#1189)
  • Fix esp32c3 uart initialization (#1156)
  • Fix ESP32-S2 I2C read (#1214)
  • Reset/init UART if it's not the console UART (#1213)

Changed

  • DmaDescriptor struct to better model the hardware (#1054)
  • DMA descriptor count no longer needs to be multiplied by 3 (#1054)
  • RMT channels no longer take the channel number as a generic param (#959)
  • The esp-hal-common package is now called esp-hal (#1131)
  • Refactor the Trace driver to be generic around its peripheral (#1140)
  • Auto detect crystal frequency based on RtcClock::estimate_xtal_frequency() (#1165)
  • ESP32-S3: Configure 32k ICACHE (#1169)
  • Lift the minimal buffer size requirement for I2S (#1189)

Removed

  • Remove xtal-26mhz and xtal-40mhz features (#1165)
  • All chip-specific HAL packages have been removed (#1196)

Breaking

  • ADC and DAC drivers now take virtual peripherals in their constructors, instead of splitting APB_SARADC/SENS (#1100)
  • The DAC driver's constructor is now new instead of dac, to be more consistent with other APIs (#1100)
  • The DMA peripheral is now called Dma for devices with both PDMA and GDMA controllers (#1125)
  • The ADC driver's constructor is now new instead of adc, to be more consistent with other APIs (#1133)
  • embassy-executor's integrated-timers is no longer enabled by default.
  • Renamed embassy-time-systick to embassy-time-systick-16mhz for use with all chips with a systimer, except esp32s2. Added embassy-time-systick-80mhz specifically for the esp32s2. (#1247)