#spi #devices #linux-kernel #transfer #interface #access #full-duplex

spidev

Provides access to the Linux spidev interface. This interface allows for configuration of the spidev device, half-duplex SPI access, and full-duplex SPI access.

10 releases (5 breaking)

0.6.0 Aug 9, 2023
0.5.1 Nov 22, 2021
0.4.1 Feb 21, 2021
0.4.0 Jun 7, 2019
0.1.0 May 21, 2015

#42 in Unix APIs

Download history 4307/week @ 2023-11-20 3948/week @ 2023-11-27 4305/week @ 2023-12-04 4587/week @ 2023-12-11 4977/week @ 2023-12-18 1510/week @ 2023-12-25 2380/week @ 2024-01-01 4086/week @ 2024-01-08 4682/week @ 2024-01-15 4283/week @ 2024-01-22 4067/week @ 2024-01-29 4103/week @ 2024-02-05 4575/week @ 2024-02-12 4449/week @ 2024-02-19 5499/week @ 2024-02-26 5534/week @ 2024-03-04

20,240 downloads per month
Used in 150 crates (23 directly)

MIT/Apache

26KB
311 lines

Rust Spidev

Build Status Version License Minimum Supported Rust Version

Documentation

The Rust spidev seeks to provide full access to the Linux spidev device in Rust without the need to wrap any C code or directly make low-level system calls. The documentation for the spidev interace can be found at https://www.kernel.org/doc/Documentation/spi/spidev.

Example/API

The following is not an exhaustive demonstration of the Spidev interface but provides a pretty good idea of how to use the library in practice.

extern crate spidev;
use std::io;
use std::io::prelude::*;
use spidev::{Spidev, SpidevOptions, SpidevTransfer, SpiModeFlags};

fn create_spi() -> io::Result<Spidev> {
    let mut spi = Spidev::open("/dev/spidev0.0")?;
    let options = SpidevOptions::new()
         .bits_per_word(8)
         .max_speed_hz(20_000)
         .mode(SpiModeFlags::SPI_MODE_0)
         .build();
    spi.configure(&options)?;
    Ok(spi)
}

/// perform half duplex operations using Read and Write traits
fn half_duplex(spi: &mut Spidev) -> io::Result<()> {
    let mut rx_buf = [0_u8; 10];
    spi.write(&[0x01, 0x02, 0x03])?;
    spi.read(&mut rx_buf)?;
    println!("{:?}", rx_buf);
    Ok(())
}

/// Perform full duplex operations using Ioctl
fn full_duplex(spi: &mut Spidev) -> io::Result<()> {
    // "write" transfers are also reads at the same time with
    // the read having the same length as the write
    let tx_buf = [0x01, 0x02, 0x03];
    let mut rx_buf = [0; 3];
    {
        let mut transfer = SpidevTransfer::read_write(&tx_buf, &mut rx_buf);
        spi.transfer(&mut transfer)?;
    }
    println!("{:?}", rx_buf);
    Ok(())
}

fn main() {
    let mut spi = create_spi().unwrap();
    println!("{:?}", half_duplex(&mut spi).unwrap());
    println!("{:?}", full_duplex(&mut spi).unwrap());
}

Features

The following features are implemented and planned for the library:

  • Implement the Read trait
  • Implement the Write trait
  • Support for full-duplex transfers
  • Support for configuring spidev device
  • Support for querying spidev configuration state

Minimum Supported Rust Version (MSRV)

This crate is guaranteed to compile on stable Rust 1.56.1 and up. It might compile with older versions but that may change in any new patch release.

Cross Compiling

Most likely, the machine you are running on is not your development machine (although it could be). In those cases, you will need to cross-compile. The following basic instructions should work for the raspberry pi or beaglebone black:

  1. Install rust and cargo
  2. Install an appropriate cross compiler. On an Ubuntu system, this can be done by doing sudo apt-get install g++-arm-linux-gnueabihf.
  3. Build or install rust for your target. This is necessary in order to have libstd available for your target. For arm-linux-gnueabihf, you can find binaries at https://github.com/japaric/ruststrap. With this approach or building it yourself, you will need to copy the ${rust}/lib/rustlib/arm-unknown-linux-gnueabihf to your system rust library folder (it is namespaced by triple, so it shouldn't break anything).
  4. Tell cargo how to link by adding the lines below to your ~/.cargo/config file.
  5. Run your build cargo build --target=arm-unknown-linux-gnueabi.

The following snippet added to my ~/.cargo/config worked for me:

[target.arm-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Code of Conduct

Contribution to this crate is organized under the terms of the Rust Code of Conduct, the maintainer of this crate, the Embedded Linux Team, promises to intervene to uphold that code of conduct.

Dependencies

~1.5MB
~34K SLoC