Skip to content

Commit 75c319b

Browse files
authored
Merge pull request #42 from Ximea-GmbH/master
Add function to query current SPI device configuration
2 parents 473db93 + cecca4e commit 75c319b

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

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

7+
- Added support for querying the configuration of a SPI device.
8+
79
## 0.6.0 / 2023-08-03
810

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

src/lib.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,37 @@ impl Spidev {
245245
Ok(())
246246
}
247247

248+
/// Read the current configuration from this device
249+
pub fn query_configuration(&self) -> io::Result<SpidevOptions> {
250+
let fd = self.devfile.as_raw_fd();
251+
252+
let bpw = spidevioctl::get_bits_per_word(fd)?;
253+
let speed = spidevioctl::get_max_speed_hz(fd)?;
254+
let lsb_first = (spidevioctl::get_lsb_first(fd)?) != 0;
255+
256+
// Try to get the mode as 32-bit (`RD_MODE32`). Older kernels may return
257+
// `ENOTTY` indicating 32-bit is not supported. In that case we retry in
258+
// 8-bit mode.
259+
let mode_bits = spidevioctl::get_mode_u32(fd).or_else(|err| {
260+
if err.raw_os_error() == Some(libc::ENOTTY) {
261+
spidevioctl::get_mode(fd).map(|value| value as u32)
262+
} else {
263+
Err(err)
264+
}
265+
})?;
266+
267+
let mode = SpiModeFlags::from_bits_retain(mode_bits);
268+
269+
let options = SpidevOptions::new()
270+
.bits_per_word(bpw)
271+
.max_speed_hz(speed)
272+
.lsb_first(lsb_first)
273+
.mode(mode)
274+
.build();
275+
276+
Ok(options)
277+
}
278+
248279
/// Perform a single transfer
249280
pub fn transfer(&self, transfer: &mut SpidevTransfer) -> io::Result<()> {
250281
spidevioctl::transfer(self.devfile.as_raw_fd(), transfer)

src/spidevioctl.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ pub fn get_mode(fd: RawFd) -> io::Result<u8> {
191191
Ok(mode)
192192
}
193193

194+
pub fn get_mode_u32(fd: RawFd) -> io::Result<u32> {
195+
let mut mode: u32 = 0;
196+
from_nix_result(unsafe { ioctl::get_mode_u32(fd, &mut mode) })?;
197+
Ok(mode)
198+
}
199+
194200
pub fn set_mode(fd: RawFd, mode: SpiModeFlags) -> io::Result<()> {
195201
// we will always use the 8-bit mode write unless bits not in
196202
// the 8-bit mask are used. This is because WR_MODE32 was not

0 commit comments

Comments
 (0)