Skip to content

Commit

Permalink
Merge pull request #42 from Ximea-GmbH/master
Browse files Browse the repository at this point in the history
Add function to query current SPI device configuration
  • Loading branch information
eldruin authored Sep 25, 2023
2 parents 473db93 + cecca4e commit 75c319b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

[Full Changelog](https://github.com/rust-embedded/rust-spidev/compare/0.6.0...HEAD)

- Added support for querying the configuration of a SPI device.

## 0.6.0 / 2023-08-03

[Full Changelog](https://github.com/rust-embedded/rust-spidev/compare/0.5.2...0.6.0)
Expand Down
31 changes: 31 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,37 @@ impl Spidev {
Ok(())
}

/// Read the current configuration from this device
pub fn query_configuration(&self) -> io::Result<SpidevOptions> {
let fd = self.devfile.as_raw_fd();

let bpw = spidevioctl::get_bits_per_word(fd)?;
let speed = spidevioctl::get_max_speed_hz(fd)?;
let lsb_first = (spidevioctl::get_lsb_first(fd)?) != 0;

// Try to get the mode as 32-bit (`RD_MODE32`). Older kernels may return
// `ENOTTY` indicating 32-bit is not supported. In that case we retry in
// 8-bit mode.
let mode_bits = spidevioctl::get_mode_u32(fd).or_else(|err| {
if err.raw_os_error() == Some(libc::ENOTTY) {
spidevioctl::get_mode(fd).map(|value| value as u32)
} else {
Err(err)
}
})?;

let mode = SpiModeFlags::from_bits_retain(mode_bits);

let options = SpidevOptions::new()
.bits_per_word(bpw)
.max_speed_hz(speed)
.lsb_first(lsb_first)
.mode(mode)
.build();

Ok(options)
}

/// Perform a single transfer
pub fn transfer(&self, transfer: &mut SpidevTransfer) -> io::Result<()> {
spidevioctl::transfer(self.devfile.as_raw_fd(), transfer)
Expand Down
6 changes: 6 additions & 0 deletions src/spidevioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ pub fn get_mode(fd: RawFd) -> io::Result<u8> {
Ok(mode)
}

pub fn get_mode_u32(fd: RawFd) -> io::Result<u32> {
let mut mode: u32 = 0;
from_nix_result(unsafe { ioctl::get_mode_u32(fd, &mut mode) })?;
Ok(mode)
}

pub fn set_mode(fd: RawFd, mode: SpiModeFlags) -> io::Result<()> {
// we will always use the 8-bit mode write unless bits not in
// the 8-bit mask are used. This is because WR_MODE32 was not
Expand Down

0 comments on commit 75c319b

Please sign in to comment.