Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use upstream nix #16

Merged
merged 3 commits into from
May 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: rust
sudo: false
rust:
- 1.22.1
- 1.26.0 # MSRV
- stable
- beta

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to test both beta and nightly? anything to decrease CI load is good atm

- nightly
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

name = "spidev"
version = "0.3.0"
version = "0.4.0"
authors = ["Paul Osborne <[email protected]>"]
license = "MIT/Apache-2.0"
repository = "https://github.com/rust-embedded/rust-spidev"
Expand All @@ -14,6 +14,6 @@ half-duplex SPI access, and full-duplex SPI access.
"""

[dependencies]
libc = "0.2.2"
bitflags = "0.3.3"
nix = "0.6.0"
libc = "0.2"
bitflags = "1.0"
nix = "0.14"
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ The following features are implemented and planned for the library:
- [x] 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.26 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
Expand Down
4 changes: 2 additions & 2 deletions examples/spidev-bidir.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extern crate spidev;
use spidev::{Spidev, SpidevOptions, SPI_MODE_0};
use spidev::{Spidev, SpidevOptions, SpiModeFlags};
use spidev::spidevioctl::SpidevTransfer;

fn main() {
Expand All @@ -8,7 +8,7 @@ fn main() {
.bits_per_word(8)
.max_speed_hz(5000)
.lsb_first(false)
.mode(SPI_MODE_0)
.mode(SpiModeFlags::SPI_MODE_0)
.build();
spidev.configure(&options).unwrap();

Expand Down
47 changes: 23 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
//! extern crate spidev;
//! use std::io;
//! use std::io::prelude::*;
//! use spidev::{Spidev, SpidevOptions, SpidevTransfer, SPI_MODE_0};
//! use spidev::{Spidev, SpidevOptions, SpidevTransfer, SpiModeFlags};
//!
//! fn create_spi() -> io::Result<Spidev> {
//! let mut spi = try!(Spidev::open("/dev/spidev0.0"));
//! let options = SpidevOptions::new()
//! .bits_per_word(8)
//! .max_speed_hz(20_000)
//! .mode(SPI_MODE_0)
//! .mode(SpiModeFlags::SPI_MODE_0)
//! .build();
//! try!(spi.configure(&options));
//! Ok(spi)
Expand Down Expand Up @@ -85,40 +85,40 @@ use std::os::unix::prelude::*;

// Constants extracted from linux/spi/spidev.h
bitflags! {
flags SpiModeFlags: u32 {
pub struct SpiModeFlags: u32 {
/// Clock Phase
const SPI_CPHA = 0x01,
const SPI_CPHA = 0x01;
/// Clock Polarity
const SPI_CPOL = 0x02,
const SPI_CPOL = 0x02;
/// Chipselect Active High?
const SPI_CS_HIGH = 0x04,
const SPI_CS_HIGH = 0x04;
/// Per-word Bits On Wire
const SPI_LSB_FIRST = 0x08,
const SPI_LSB_FIRST = 0x08;
/// SI/SO Signals Shared
const SPI_3WIRE = 0x10,
const SPI_3WIRE = 0x10;
/// Loopback Mode
const SPI_LOOP = 0x20,
/// 1 dev/bus, no chipselect
const SPI_NO_CS = 0x40,
const SPI_LOOP = 0x20;
/// 1 dev/bus; no chipselect
const SPI_NO_CS = 0x40;
/// Slave pulls low to pause
const SPI_READY = 0x80,
const SPI_READY = 0x80;

// Common Configurations
const SPI_MODE_0 = 0x00,
const SPI_MODE_1 = SPI_CPHA.bits,
const SPI_MODE_2 = SPI_CPOL.bits,
const SPI_MODE_3 = (SPI_CPOL.bits | SPI_CPHA.bits),
const SPI_MODE_0 = 0x00;
const SPI_MODE_1 = Self::SPI_CPHA.bits;
const SPI_MODE_2 = Self::SPI_CPOL.bits;
const SPI_MODE_3 = (Self::SPI_CPOL.bits | Self::SPI_CPHA.bits);

// == Only Supported with 32-bits ==

/// Transmit with 2 wires
const SPI_TX_DUAL = 0x100,
const SPI_TX_DUAL = 0x100;
/// Transmit with 4 wires
const SPI_TX_QUAD = 0x200,
const SPI_TX_QUAD = 0x200;
/// Receive with 2 wires
const SPI_RX_DUAL = 0x400,
const SPI_RX_DUAL = 0x400;
/// Receive with 4 wires
const SPI_RX_QUAD = 0x800,
const SPI_RX_QUAD = 0x800;
}
}

Expand Down Expand Up @@ -290,21 +290,20 @@ impl Write for Spidev {

#[cfg(test)]
mod test {

use super::{SpidevOptions, SPI_MODE_0};
use super::{SpidevOptions, SpiModeFlags};

#[test]
fn test_spidev_options_all() {
let options = SpidevOptions::new()
.bits_per_word(8)
.max_speed_hz(20_000)
.lsb_first(false)
.mode(SPI_MODE_0)
.mode(SpiModeFlags::SPI_MODE_0)
.build();
assert_eq!(options.bits_per_word, Some(8));
assert_eq!(options.max_speed_hz, Some(20_000));
assert_eq!(options.lsb_first, Some(false));
assert_eq!(options.spi_mode, Some(SPI_MODE_0));
assert_eq!(options.spi_mode, Some(SpiModeFlags::SPI_MODE_0));
}

#[test]
Expand Down
36 changes: 17 additions & 19 deletions src/spidevioctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

#![allow(dead_code)]

use nix;
use std::io;
use std::marker::PhantomData;
use std::mem;
use std::os::unix::prelude::*;
use super::SpiModeFlags;

fn from_nix_error(err: ::nix::Error) -> io::Error {
io::Error::from_raw_os_error(err.errno() as i32)
io::Error::from_raw_os_error(err.as_errno().unwrap_or_else(|| nix::errno::Errno::UnknownErrno) as i32)
}

fn from_nix_result<T>(res: ::nix::Result<T>) -> io::Result<T> {
Expand Down Expand Up @@ -123,26 +123,26 @@ mod ioctl {
const SPI_IOC_NR_MAX_SPEED_HZ: u8 = 4;
const SPI_IOC_NR_MODE32: u8 = 5;

ioctl!(read get_mode_u8 with SPI_IOC_MAGIC, SPI_IOC_NR_MODE; u8);
ioctl!(read get_mode_u32 with SPI_IOC_MAGIC, SPI_IOC_NR_MODE; u32);
ioctl!(write set_mode_u8 with SPI_IOC_MAGIC, SPI_IOC_NR_MODE; u8);
ioctl!(write set_mode_u32 with SPI_IOC_MAGIC, SPI_IOC_NR_MODE32; u32);
ioctl_read!(get_mode_u8, SPI_IOC_MAGIC, SPI_IOC_NR_MODE, u8);
ioctl_read!(get_mode_u32, SPI_IOC_MAGIC, SPI_IOC_NR_MODE32, u32);
ioctl_write_ptr!(set_mode, SPI_IOC_MAGIC, SPI_IOC_NR_MODE, u8);
ioctl_write_ptr!(set_mode32, SPI_IOC_MAGIC, SPI_IOC_NR_MODE32, u32);

ioctl!(read get_lsb_first with SPI_IOC_MAGIC, SPI_IOC_NR_LSB_FIRST; u8);
ioctl!(write set_lsb_first with SPI_IOC_MAGIC, SPI_IOC_NR_LSB_FIRST; u8);
ioctl_read!(get_lsb_first, SPI_IOC_MAGIC, SPI_IOC_NR_LSB_FIRST, u8);
ioctl_write_ptr!(set_lsb_first, SPI_IOC_MAGIC, SPI_IOC_NR_LSB_FIRST, u8);

ioctl!(read get_bits_per_word with SPI_IOC_MAGIC, SPI_IOC_NR_BITS_PER_WORD; u8);
ioctl!(write set_bits_per_word with SPI_IOC_MAGIC, SPI_IOC_NR_BITS_PER_WORD; u8);
ioctl_read!(get_bits_per_word, SPI_IOC_MAGIC, SPI_IOC_NR_BITS_PER_WORD, u8);
ioctl_write_ptr!(set_bits_per_word, SPI_IOC_MAGIC, SPI_IOC_NR_BITS_PER_WORD, u8);

ioctl!(read get_max_speed_hz with SPI_IOC_MAGIC, SPI_IOC_NR_MAX_SPEED_HZ; u32);
ioctl!(write set_max_speed_hz with SPI_IOC_MAGIC, SPI_IOC_NR_MAX_SPEED_HZ; u32);
ioctl_read!(get_max_speed_hz, SPI_IOC_MAGIC, SPI_IOC_NR_MAX_SPEED_HZ, u32);
ioctl_write_ptr!(set_max_speed_hz, SPI_IOC_MAGIC, SPI_IOC_NR_MAX_SPEED_HZ, u32);

// NOTE: this macro works for single transfers but cannot properly
// calculate size for multi transfer whose length we will not know
// until runtime. We fallback to using the underlying ioctl for that
// use case.
ioctl!(write spidev_transfer with SPI_IOC_MAGIC, SPI_IOC_NR_TRANSFER; spi_ioc_transfer);
ioctl!(write buf spidev_transfer_buf with SPI_IOC_MAGIC, SPI_IOC_NR_TRANSFER; spi_ioc_transfer);
ioctl_write_ptr!(spidev_transfer, SPI_IOC_MAGIC, SPI_IOC_NR_TRANSFER, spi_ioc_transfer);
ioctl_write_buf!(spidev_transfer_buf, SPI_IOC_MAGIC, SPI_IOC_NR_TRANSFER, spi_ioc_transfer);
}

/// Representation of a spidev transfer that is shared
Expand All @@ -161,10 +161,10 @@ pub fn set_mode(fd: RawFd, mode: SpiModeFlags) -> io::Result<()> {
// added until later kernels. This provides a reasonable story
// for forwards and backwards compatibility
if (mode.bits & 0xFFFFFF00) != 0 {
try!(from_nix_result(unsafe { ioctl::set_mode_u32(fd, &mode.bits) }));
try!(from_nix_result(unsafe { ioctl::set_mode32(fd, &mode.bits) }));
} else {
let bits: u8 = mode.bits as u8;
try!(from_nix_result(unsafe { ioctl::set_mode_u8(fd, &bits) }));
try!(from_nix_result(unsafe { ioctl::set_mode(fd, &bits) }));
}
Ok(())
}
Expand Down Expand Up @@ -215,10 +215,8 @@ pub fn transfer(fd: RawFd, transfer: &mut SpidevTransfer) -> io::Result<()> {
}

pub fn transfer_multiple(fd: RawFd, transfers: &mut [SpidevTransfer]) -> io::Result<()> {
let tot_size = transfers.len() * mem::size_of::<SpidevTransfer>();

try!(from_nix_result(unsafe {
ioctl::spidev_transfer_buf(fd, transfers.as_mut_ptr(), tot_size)
ioctl::spidev_transfer_buf(fd, transfers)
}));
Ok(())
}