From 293f877f1999df2e8397e38d44575b411a8271e7 Mon Sep 17 00:00:00 2001
From: "Matthias P. Braendli" <matthias.braendli@mpb.li>
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(-)

(limited to 'src/rfm95.rs')

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<RF95> {
         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<u8> {
         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<u8>, 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<u8> = 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