From 293f877f1999df2e8397e38d44575b411a8271e7 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 27 Aug 2018 16:37:14 +0000 Subject: Get SPI transfers to work --- src/rfm95.rs | 76 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/rfm95.rs b/src/rfm95.rs index f4da72b..2922652 100644 --- a/src/rfm95.rs +++ b/src/rfm95.rs @@ -3,7 +3,7 @@ use std; use sysfs_gpio; use sysfs_gpio::{Direction, Edge, Pin}; -use spidev::{Spidev, SpidevOptions, SPI_MODE_0}; +use spidev::{Spidev, SpidevTransfer, SpidevOptions, SPI_MODE_0}; use std::io; use std::thread; use std::time::Duration; @@ -12,9 +12,11 @@ use std::sync::mpsc::{Receiver}; use std::sync::mpsc; use std::sync::atomic::{AtomicBool, Ordering}; -const RST_BCM_PIN : u64 = 17; -const DIO_BCM_PIN : u64 = 4; -const CS_BCM_PIN : u64 = 25; +const RST_BCM_PIN : u64 = 22; +const DIO_BCM_PIN : u64 = 25; +const CS_BCM_PIN : u64 = 8; + +const SPI_MAX_SPEED_HZ : u32 = 5_000_000; #[derive(Copy, Clone)] pub enum LoraRegister { @@ -309,9 +311,11 @@ pub struct RF95 { impl RF95 { pub fn new(bw : Bandwidth, cr : CodingRate, sf : SpreadingFactor) -> io::Result { let tmp_rst_pin = Pin::new(RST_BCM_PIN); - tmp_rst_pin.set_direction(Direction::Low).unwrap(); - thread::sleep(Duration::from_millis(10)); - tmp_rst_pin.set_value(1).unwrap(); + tmp_rst_pin.export().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot export pin {}", e)))?; + tmp_rst_pin.set_direction(Direction::Low).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?; + thread::sleep(Duration::from_millis(2)); + tmp_rst_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e)))?; + thread::sleep(Duration::from_millis(5)); Ok( RF95 { @@ -549,15 +553,11 @@ impl RF95 { } pub fn reset(&mut self) -> io::Result<()> { - match self.rst_pin.set_direction(Direction::Low) { - Ok(_) => (), - Err(_) => return Err(std::io::Error::new(ErrorKind::Other, "Problem setting value on gpio")), - }; - std::thread::sleep(Duration::new(0, 10000000)); - match self.rst_pin.set_value(1) { - Ok(_) => return Ok(()), - Err(_) => return Err(std::io::Error::new(ErrorKind::Other, "Problem setting value on gpio")), - }; + self.rst_pin.set_direction(Direction::Low).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?; + thread::sleep(Duration::from_millis(2)); + self.rst_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e)))?; + thread::sleep(Duration::from_millis(5)); + Ok(()) } pub fn set_dio_mapping(&mut self, df : DioFunction) -> io::Result<()> { @@ -576,7 +576,7 @@ impl RF95 { let mut spi = Spidev::open("/dev/spidev0.0")?; let spi_options = SpidevOptions::new() .bits_per_word(8) - .max_speed_hz(5_000_000) + .max_speed_hz(SPI_MAX_SPEED_HZ) .mode(SPI_MODE_0) .build(); spi.configure(&spi_options)?; @@ -591,66 +591,64 @@ impl RF95 { let mut spi = Spidev::open("/dev/spidev0.0")?; let spi_options = SpidevOptions::new() .bits_per_word(8) - .max_speed_hz(5_000_000) + .max_speed_hz(SPI_MAX_SPEED_HZ) .mode(SPI_MODE_0) .build(); spi.configure(&spi_options)?; let cs_pin = Pin::new(CS_BCM_PIN); - cs_pin.set_direction(Direction::High).unwrap(); + cs_pin.export().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot export pin {}", e)))?; + cs_pin.set_direction(Direction::Low).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?; let mut v2 = buffer; v2.insert(0, reg.as_u8()); - cs_pin.set_value(0).unwrap(); spi.write(&v2)?; - match cs_pin.set_value(1) { - Ok(_) => Ok(()), - Err(_) => Err(std::io::Error::new(ErrorKind::Other, "Problem setting value on gpio")), - } + cs_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e))) } fn read_register(reg : LoraRegister) -> io::Result { let mut spi = Spidev::open("/dev/spidev0.0")?; let spi_options = SpidevOptions::new() .bits_per_word(8) - .max_speed_hz(5_000_000) + .max_speed_hz(SPI_MAX_SPEED_HZ) .mode(SPI_MODE_0) .build(); spi.configure(&spi_options)?; let cs_pin = Pin::new(CS_BCM_PIN); - cs_pin.set_direction(Direction::High).unwrap(); + cs_pin.export().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot export pin {}", e)))?; + cs_pin.set_direction(Direction::Low).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?; + + let mut rx_buf = [0; 2]; + let tx_buf = vec![reg as u8, 0]; + { + let mut transfer = SpidevTransfer::read_write(&tx_buf, &mut rx_buf); + spi.transfer(&mut transfer).unwrap(); + } - let mut ret: [u8; 1] = [0; 1]; - cs_pin.set_value(0).unwrap(); - spi.write(&[reg.as_u8()])?; - spi.read(&mut ret).unwrap(); - match cs_pin.set_value(1) { - Ok(_) => (), - Err(_) => return Err(io::Error::new(ErrorKind::Other, "Problem setting value on gpio")), - }; - Ok(ret[0]) + cs_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e)))?; + Ok(rx_buf[1]) } fn read_buffer(reg : LoraRegister, buffer : &mut Vec, length : u8) -> io::Result<()> { let mut spi = Spidev::open("/dev/spidev0.0")?; let spi_options = SpidevOptions::new() .bits_per_word(8) - .max_speed_hz(5_000_000) + .max_speed_hz(SPI_MAX_SPEED_HZ) .mode(SPI_MODE_0) .build(); spi.configure(&spi_options)?; let cs_pin = Pin::new(CS_BCM_PIN); - cs_pin.set_direction(Direction::High).unwrap(); + cs_pin.export().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot export pin {}", e)))?; + cs_pin.set_direction(Direction::Low).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?; let mut tmp : Vec = Vec::with_capacity(length as usize); - cs_pin.set_value(0).unwrap(); spi.write(&[reg.as_u8()])?; spi.read(tmp.as_mut_slice())?; buffer.clear(); buffer.write(&tmp)?; - cs_pin.set_value(1).unwrap(); + cs_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e)))?; Ok(()) } } -- cgit v1.2.3