Skip to content

Commit

Permalink
Merge branch 'master' into u0-dion
Browse files Browse the repository at this point in the history
  • Loading branch information
diondokter committed Apr 16, 2024
2 parents e224e6c + e38f101 commit c8c7c71
Show file tree
Hide file tree
Showing 57 changed files with 1,502 additions and 984 deletions.
1 change: 1 addition & 0 deletions .github/ci/test-nightly.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ mv rust-toolchain-nightly.toml rust-toolchain.toml

MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml
MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-executor/Cargo.toml --features nightly
MIRIFLAGS=-Zmiri-ignore-leaks cargo miri test --manifest-path ./embassy-sync/Cargo.toml
1 change: 1 addition & 0 deletions .github/ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export RUSTUP_HOME=/ci/cache/rustup
export CARGO_HOME=/ci/cache/cargo
export CARGO_TARGET_DIR=/ci/cache/target

cargo test --manifest-path ./embassy-futures/Cargo.toml
cargo test --manifest-path ./embassy-sync/Cargo.toml
cargo test --manifest-path ./embassy-embedded-hal/Cargo.toml
cargo test --manifest-path ./embassy-hal-internal/Cargo.toml
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
"rust-analyzer.cargo.target": "thumbv7em-none-eabi",
//"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf",
"rust-analyzer.cargo.features": [
"stm32f103c8",
"stm32f446re",
"time-driver-any",
"unstable-pac",
"exti",
"rt",
],
"rust-analyzer.linkedProjects": [
// Uncomment ONE line for the chip you want to work on.
Expand Down
3 changes: 3 additions & 0 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ rm out/tests/stm32f207zg/eth
# doesn't work, gives "noise error", no idea why. usart_dma does pass.
rm out/tests/stm32u5a5zj/usart

# flaky, perhaps bad wire
rm out/tests/stm32l152re/usart_rx_ringbuffered

if [[ -z "${TELEPROBE_TOKEN-}" ]]; then
echo No teleprobe token found, skipping running HIL tests
exit
Expand Down
10 changes: 8 additions & 2 deletions cyw43/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ impl<'a> Control<'a> {
self.set_iovar_u32("apsta", 1).await;

// read MAC addr.
let mut mac_addr = [0; 6];
assert_eq!(self.get_iovar("cur_etheraddr", &mut mac_addr).await, 6);
let mac_addr = self.address().await;
debug!("mac addr: {:02x}", Bytes(&mac_addr));

let country = countries::WORLD_WIDE_XX;
Expand Down Expand Up @@ -574,6 +573,13 @@ impl<'a> Control<'a> {
self.ioctl(IoctlType::Set, IOCTL_CMD_DISASSOC, 0, &mut []).await;
info!("Disassociated")
}

/// Gets the MAC address of the device
pub async fn address(&mut self) -> [u8; 6] {
let mut mac_addr = [0; 6];
assert_eq!(self.get_iovar("cur_etheraddr", &mut mac_addr).await, 6);
mac_addr
}
}

/// WiFi network scanner.
Expand Down
8 changes: 7 additions & 1 deletion embassy-futures/src/yield_now.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ use core::task::{Context, Poll};
/// hold, while still allowing other tasks to run concurrently (not monopolizing
/// the executor thread).
///
/// ```rust,no_run
/// ```rust
/// # use embassy_futures::{block_on, yield_now};
/// # async fn test_fn() {
/// # let mut iter_count: u32 = 0;
/// # let mut some_condition = || { iter_count += 1; iter_count > 10 };
/// while !some_condition() {
/// yield_now().await;
/// }
/// # }
/// # block_on(test_fn());
/// ```
///
/// The downside is this will spin in a busy loop, using 100% of the CPU, while
Expand Down
40 changes: 40 additions & 0 deletions embassy-nrf/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Changelog for embassy-nrf

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

- Drop `sealed` mod
- nrf52840: Add dcdc voltage parameter to configure REG0 regulator
- radio: Add support for IEEE 802.15.4 and BLE via radio peripheral
- spim: Reduce trace-level messages ("Copying SPIM tx buffer..")
- uart: Add support for rx- or tx-only BufferedUart
- uart: Implement splitting Rx/Tx
- spi: Allow specifying OutputDrive for SPI spins
- pdm: Fix gain register value derivation
- spim: Implement chunked DMA transfers
- spi: Add bounds checks for EasyDMA buffer size
- uarte: Add support for handling RX errors
- nrf51: Implement support for nrf51 chip
- pwm: Expose `duty` method
- pwm: Fix infinite loop
- spi: Add support for configuring bit order for bus
- pwm: Expose `pwm::PWM_CLK_HZ` and add `is_enabled` method
- gpio: Drop GPIO Pin generics (API break)

## 0.1.0 - 2024-01-12

- First release with support for following NRF chips:
- nrf52805
- nrf52810
- nrf52811
- nrf52820
- nrf52832
- nrf52833
- nrf52840
- nrf5340
- nrf9160

3 changes: 3 additions & 0 deletions embassy-stm32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ low-power-debug-with-sleep = []
## Automatically generate `memory.x` file using [`stm32-metapac`](https://docs.rs/stm32-metapac/)
memory-x = ["stm32-metapac/memory-x"]

## Use secure registers when TrustZone is enabled
trustzone-secure = []

## Re-export stm32-metapac at `embassy_stm32::pac`.
## This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.
## If this is an issue for you, you're encouraged to directly depend on a fixed version of the PAC.
Expand Down
1 change: 1 addition & 0 deletions embassy-stm32/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ fn main() {
#(pub use crate::pac::rcc::vals::#enum_names as #enum_names; )*

#[derive(Clone, Copy)]
#[non_exhaustive]
pub struct ClockMux {
#( #struct_fields, )*
}
Expand Down
3 changes: 3 additions & 0 deletions embassy-stm32/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ mod dmamux;
#[cfg(dmamux)]
pub use dmamux::*;

mod util;
pub(crate) use util::*;

pub(crate) mod ringbuffer;
pub mod word;

Expand Down
60 changes: 60 additions & 0 deletions embassy-stm32/src/dma/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use embassy_hal_internal::PeripheralRef;

use super::word::Word;
use super::{AnyChannel, Request, Transfer, TransferOptions};

/// Convenience wrapper, contains a channel and a request number.
///
/// Commonly used in peripheral drivers that own DMA channels.
pub(crate) struct ChannelAndRequest<'d> {
pub channel: PeripheralRef<'d, AnyChannel>,
pub request: Request,
}

impl<'d> ChannelAndRequest<'d> {
pub unsafe fn read<'a, W: Word>(
&'a mut self,
peri_addr: *mut W,
buf: &'a mut [W],
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options)
}

pub unsafe fn read_raw<'a, W: Word>(
&'a mut self,
peri_addr: *mut W,
buf: *mut [W],
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options)
}

pub unsafe fn write<'a, W: Word>(
&'a mut self,
buf: &'a [W],
peri_addr: *mut W,
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options)
}

pub unsafe fn write_raw<'a, W: Word>(
&'a mut self,
buf: *const [W],
peri_addr: *mut W,
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options)
}

pub unsafe fn write_repeated<'a, W: Word>(
&'a mut self,
repeated: &'a W,
count: usize,
peri_addr: *mut W,
options: TransferOptions,
) -> Transfer<'a> {
Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options)
}
}
50 changes: 47 additions & 3 deletions embassy-stm32/src/flash/h50.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), E

interrupt::free(|_| {
pac::FLASH.nscr().modify(|w| {
w.set_bksel(match sector.bank {
FlashBank::Bank1 => Bksel::BANK1,
FlashBank::Bank2 => Bksel::BANK2,
// BKSEL ignores SWAP_BANK, so we must take it into account here
w.set_bksel(match (sector.bank, banks_swapped()) {
(FlashBank::Bank1, false) => Bksel::BANK1,
(FlashBank::Bank2, true) => Bksel::BANK1,
(FlashBank::Bank2, false) => Bksel::BANK2,
(FlashBank::Bank1, true) => Bksel::BANK2,
});
w.set_snb(sector.index_in_bank);
w.set_ser(true);
Expand Down Expand Up @@ -111,6 +114,47 @@ pub(crate) unsafe fn clear_all_err() {
})
}

/// Get the current SWAP_BANK option.
///
/// This value is only loaded on system or power-on reset. `perform_bank_swap()`
/// will not reflect here.
pub fn banks_swapped() -> bool {
pac::FLASH.optcr().read().swap_bank()
}

/// Logical, persistent swap of flash banks 1 and 2.
///
/// This allows the application to write a new firmware blob into bank 2, then
/// swap the banks and perform a reset, loading the new firmware.
///
/// Swap does not take effect until system or power-on reset.
///
/// PLEASE READ THE REFERENCE MANUAL - there are nuances to this feature. For
/// instance, erase commands and interrupt enables which take a flash bank as a
/// parameter ignore the swap!
pub fn perform_bank_swap() {
while busy() {}

unsafe {
clear_all_err();
}

// unlock OPTLOCK
pac::FLASH.optkeyr().write(|w| *w = 0x0819_2A3B);
pac::FLASH.optkeyr().write(|w| *w = 0x4C5D_6E7F);
while pac::FLASH.optcr().read().optlock() {}

// toggle SWAP_BANK option
pac::FLASH.optsr_prg().modify(|w| w.set_swap_bank(!banks_swapped()));

// load option bytes
pac::FLASH.optcr().modify(|w| w.set_optstrt(true));
while pac::FLASH.optcr().read().optstrt() {}

// re-lock OPTLOCK
pac::FLASH.optcr().modify(|w| w.set_optlock(true));
}

fn sr_busy(sr: Nssr) -> bool {
// Note: RM0492 sometimes incorrectly refers to WBNE as NSWBNE
sr.bsy() || sr.dbne() || sr.wbne()
Expand Down
39 changes: 39 additions & 0 deletions embassy-stm32/src/flash/u5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,43 @@ pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
}

pub(crate) unsafe fn lock() {
#[cfg(feature = "trustzone-secure")]
pac::FLASH.seccr().modify(|w| w.set_lock(true));
#[cfg(not(feature = "trustzone-secure"))]
pac::FLASH.nscr().modify(|w| w.set_lock(true));
}

pub(crate) unsafe fn unlock() {
#[cfg(feature = "trustzone-secure")]
if pac::FLASH.seccr().read().lock() {
pac::FLASH.seckeyr().write_value(0x4567_0123);
pac::FLASH.seckeyr().write_value(0xCDEF_89AB);
}
#[cfg(not(feature = "trustzone-secure"))]
if pac::FLASH.nscr().read().lock() {
pac::FLASH.nskeyr().write_value(0x4567_0123);
pac::FLASH.nskeyr().write_value(0xCDEF_89AB);
}
}

pub(crate) unsafe fn enable_blocking_write() {
assert_eq!(0, WRITE_SIZE % 4);

#[cfg(feature = "trustzone-secure")]
pac::FLASH.seccr().write(|w| {
w.set_pg(pac::flash::vals::SeccrPg::B_0X1);
});
#[cfg(not(feature = "trustzone-secure"))]
pac::FLASH.nscr().write(|w| {
w.set_pg(pac::flash::vals::NscrPg::B_0X1);
});
}

pub(crate) unsafe fn disable_blocking_write() {
#[cfg(feature = "trustzone-secure")]
pac::FLASH.seccr().write(|w| w.set_pg(pac::flash::vals::SeccrPg::B_0X0));
#[cfg(not(feature = "trustzone-secure"))]
pac::FLASH.nscr().write(|w| w.set_pg(pac::flash::vals::NscrPg::B_0X0));
}

pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> {
Expand All @@ -50,32 +67,54 @@ pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE])
}

pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> {
#[cfg(feature = "trustzone-secure")]
pac::FLASH.seccr().modify(|w| {
w.set_per(pac::flash::vals::SeccrPer::B_0X1);
w.set_pnb(sector.index_in_bank)
});
#[cfg(not(feature = "trustzone-secure"))]
pac::FLASH.nscr().modify(|w| {
w.set_per(pac::flash::vals::NscrPer::B_0X1);
w.set_pnb(sector.index_in_bank)
});

#[cfg(feature = "trustzone-secure")]
pac::FLASH.seccr().modify(|w| {
w.set_strt(true);
});
#[cfg(not(feature = "trustzone-secure"))]
pac::FLASH.nscr().modify(|w| {
w.set_strt(true);
});

let ret: Result<(), Error> = blocking_wait_ready();
#[cfg(feature = "trustzone-secure")]
pac::FLASH
.seccr()
.modify(|w| w.set_per(pac::flash::vals::SeccrPer::B_0X0));
#[cfg(not(feature = "trustzone-secure"))]
pac::FLASH
.nscr()
.modify(|w| w.set_per(pac::flash::vals::NscrPer::B_0X0));
clear_all_err();
ret
}

pub(crate) unsafe fn clear_all_err() {
// read and write back the same value.
// This clears all "write 1 to clear" bits.
#[cfg(feature = "trustzone-secure")]
pac::FLASH.secsr().modify(|_| {});
#[cfg(not(feature = "trustzone-secure"))]
pac::FLASH.nssr().modify(|_| {});
}

unsafe fn blocking_wait_ready() -> Result<(), Error> {
loop {
#[cfg(feature = "trustzone-secure")]
let sr = pac::FLASH.secsr().read();
#[cfg(not(feature = "trustzone-secure"))]
let sr = pac::FLASH.nssr().read();

if !sr.bsy() {
if sr.pgserr() {
Expand Down
Loading

0 comments on commit c8c7c71

Please sign in to comment.