Skip to content

Commit

Permalink
spi: Tolerate variations introduced by previously untested CPUs
Browse files Browse the repository at this point in the history
Merges: #144
  • Loading branch information
chrysn authored Jan 13, 2025
2 parents 8a41b4a + 24e2ca1 commit 4861e4e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
# info-applications` that is probably relevant; more is covered when
# riot-wrappers are updated in RIOT.
example: [examples/rust-hello-world, examples/rust-gcoap, examples/rust-async, tests/rust_minimal, tests/rust_libs]
board: [native, sltb001a, samr21-xpro, stk3700]
board: [native, sltb001a, samr21-xpro, stk3700, stm32f429i-disc1, usb-kw41z]
steps:
# common steps start here
- name: Check out riot-wrappers
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
container: riot/riotbuild
strategy:
matrix:
board: [native, sltb001a, samr21-xpro, stk3700]
board: [native, sltb001a, samr21-xpro, stk3700, stm32f429i-disc1, usb-kw41z]
testdir: ${{ fromJSON(needs.enumerate-wrappers-tests.outputs.list) }}
steps:
# common steps start here (kept in sync even though we wouldn't need to patch RIOT's .cargo/config.toml)
Expand Down
9 changes: 9 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ fn main() {
.into();
println!("cargo:rerun-if-env-changed=RIOTBASE");

// FIXME: We're trying to get rid of that dependency in
// <https://github.com/RIOT-OS/rust-riot-sys/pull/38>, but for this one, there are no good
// alternatives.
let bindgen_output_file = std::env::var("DEP_RIOT_SYS_BINDGEN_OUTPUT_FILE").unwrap();
let emulate_accessible = [
// It's a static inline function and riot-sys currently only gives the file for the bindgen
// output, not the c2rust output. Using coap_build_udp_hdr presence as a stand-in.
Expand All @@ -164,6 +168,11 @@ fn main() {
&"sys/include/net/nanocoap.h",
&"coap_pkt_set_code",
),
(
&"spi_clk_t_SPI_CLK_100KHZ",
&bindgen_output_file.as_str(),
&"spi_clk_t_SPI_CLK_100KHZ",
),
];

for (rust_name, header_file, header_search_string) in emulate_accessible {
Expand Down
40 changes: 33 additions & 7 deletions src/spi/for_embedded_hal_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ use core::convert::Infallible;
use core::num::NonZero;
use embedded_hal::spi::{ErrorType, Mode, Operation};

// The way that cpu/stm32/include/periph/cpu_spi.h defines its enum values through a macro causes
// them to be unprefixed for unknown reasons.
//
// This may become better when running a bindgen update, or when going with
// <https://github.com/RIOT-OS/rust-riot-sys/pull/32>.
#[cfg(accessible_riot_sys_spi_clk_t_SPI_CLK_100KHZ)]
mod frequency {
pub(super) const SPI_CLK_100KHZ: riot_sys::spi_clk_t = riot_sys::spi_clk_t_SPI_CLK_100KHZ;
pub(super) const SPI_CLK_400KHZ: riot_sys::spi_clk_t = riot_sys::spi_clk_t_SPI_CLK_400KHZ;
pub(super) const SPI_CLK_1MHZ: riot_sys::spi_clk_t = riot_sys::spi_clk_t_SPI_CLK_1MHZ;
pub(super) const SPI_CLK_5MHZ: riot_sys::spi_clk_t = riot_sys::spi_clk_t_SPI_CLK_5MHZ;
pub(super) const SPI_CLK_10MHZ: riot_sys::spi_clk_t = riot_sys::spi_clk_t_SPI_CLK_10MHZ;
}
#[cfg(not(accessible_riot_sys_spi_clk_t_SPI_CLK_100KHZ))]
mod frequency {
pub(super) const SPI_CLK_100KHZ: riot_sys::spi_clk_t = riot_sys::SPI_CLK_100KHZ;
pub(super) const SPI_CLK_400KHZ: riot_sys::spi_clk_t = riot_sys::SPI_CLK_400KHZ;
pub(super) const SPI_CLK_1MHZ: riot_sys::spi_clk_t = riot_sys::SPI_CLK_1MHZ;
pub(super) const SPI_CLK_5MHZ: riot_sys::spi_clk_t = riot_sys::SPI_CLK_5MHZ;
pub(super) const SPI_CLK_10MHZ: riot_sys::spi_clk_t = riot_sys::SPI_CLK_10MHZ;
}
use frequency::*;

/// A RIOT SPI device combined with complete with mode and clock configuration, but no particular
/// CS pin.
///
Expand Down Expand Up @@ -55,7 +78,7 @@ impl SpiBus {
Self {
bus,
mode: riot_sys::spi_mode_t_SPI_MODE_0,
clk: riot_sys::spi_clk_t_SPI_CLK_100KHZ,
clk: SPI_CLK_100KHZ,
}
}

Expand All @@ -73,39 +96,39 @@ impl SpiBus {
/// Sets the speed to 100KHz.
pub fn with_speed_100khz(self) -> Self {
Self {
clk: riot_sys::spi_clk_t_SPI_CLK_100KHZ,
clk: SPI_CLK_100KHZ,
..self
}
}

/// Sets the speed to 400KHz.
pub fn with_speed_400khz(self) -> Self {
Self {
clk: riot_sys::spi_clk_t_SPI_CLK_400KHZ,
clk: SPI_CLK_400KHZ,
..self
}
}

/// Sets the speed to 1MHz.
pub fn with_speed_1mhz(self) -> Self {
Self {
clk: riot_sys::spi_clk_t_SPI_CLK_1MHZ,
clk: SPI_CLK_1MHZ,
..self
}
}

/// Sets the speed to 5MHz.
pub fn with_speed_5mhz(self) -> Self {
Self {
clk: riot_sys::spi_clk_t_SPI_CLK_5MHZ,
clk: SPI_CLK_5MHZ,
..self
}
}

/// Sets the speed to 10MHz.
pub fn with_speed_10mhz(self) -> Self {
Self {
clk: riot_sys::spi_clk_t_SPI_CLK_10MHZ,
clk: SPI_CLK_10MHZ,
..self
}
}
Expand Down Expand Up @@ -184,7 +207,10 @@ impl SpiDevice {
/// and its CS GPIO pin
#[cfg(riot_module_periph_gpio)]
pub fn new(bus: SpiBus, cs: crate::gpio::GPIO) -> Result<Self, NumericError> {
let cs = cs.to_c();
// spi_cs_t can be many things, but as the `spi_init_cs` documentation says that one can
// put a GPIO_PIN value in there, let's hope that this is only used where integer promotion
// actually makes sense (and where it makes sense, there is a .into()).
let cs: riot_sys::spi_cs_t = cs.to_c().into();
(unsafe { riot_sys::spi_init_cs(bus.bus, cs) }).negative_to_error()?;
Ok(Self { bus, cs })
}
Expand Down

0 comments on commit 4861e4e

Please sign in to comment.