Skip to content

0.20.0

Compare
Choose a tag to compare
@MabezDev MabezDev released this 29 Aug 19:52
· 528 commits to main since this release
5917275

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)