aboutsummaryrefslogtreecommitdiffstats
path: root/src/rfm95.rs
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2018-09-04 09:20:59 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2018-09-04 09:20:59 +0200
commit359a6ebaf59aa19699cbd61b07406999e6732373 (patch)
treed758f8dad49094ac6a7aa15dd0e817b2cf3c1cc5 /src/rfm95.rs
parent4c9f3c8dbfc67d9e1f8479538ba9c9b6dc3be5c4 (diff)
downloadraspi-rfm95-kiss-master.tar.gz
raspi-rfm95-kiss-master.tar.bz2
raspi-rfm95-kiss-master.zip
Rework rfm95 and kissHEADmaster
Diffstat (limited to 'src/rfm95.rs')
-rw-r--r--src/rfm95.rs412
1 files changed, 206 insertions, 206 deletions
diff --git a/src/rfm95.rs b/src/rfm95.rs
index 2922652..a73191b 100644
--- a/src/rfm95.rs
+++ b/src/rfm95.rs
@@ -1,21 +1,19 @@
// Taken from rfm95_rust_pi, which is
// SPDX-License-Identifier: MIT
use std;
-use sysfs_gpio;
use sysfs_gpio::{Direction, Edge, Pin};
use spidev::{Spidev, SpidevTransfer, SpidevOptions, SPI_MODE_0};
use std::io;
use std::thread;
use std::time::Duration;
use std::io::{Read, Write, ErrorKind};
-use std::sync::mpsc::{Receiver};
-use std::sync::mpsc;
-use std::sync::atomic::{AtomicBool, Ordering};
const RST_BCM_PIN : u64 = 22;
const DIO_BCM_PIN : u64 = 25;
const CS_BCM_PIN : u64 = 8;
+pub const MAX_MTU: usize = 251;
+
const SPI_MAX_SPEED_HZ : u32 = 5_000_000;
#[derive(Copy, Clone)]
@@ -286,7 +284,7 @@ impl ToFlag for u8 {
pub enum RF95EventType {
None,
- DataReceived,
+ DataReceived(Vec<u8>),
DataSent,
ErrorPinConfig,
ErrorTimedOut,
@@ -302,39 +300,75 @@ pub struct RF95 {
crc_check_enabled : bool,
implicit_header_enabled : bool,
pwr_db : u8,
- thread_run : std::sync::Arc<AtomicBool>,
- thread_handle : Option<std::thread::JoinHandle<()>>,
rst_pin : Pin,
+ cs_pin : Pin,
+ dio_pin : Pin,
+ spi : Spidev,
}
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.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)))?;
+ tmp_rst_pin.export().map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot export pin {}", e)))?;
+ tmp_rst_pin.set_direction(Direction::Low)
+ .map_err(|e| io::Error::new(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)))?;
+ tmp_rst_pin.set_value(1).map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set value for pin {}", e)))?;
thread::sleep(Duration::from_millis(5));
- Ok(
- RF95 {
- ch : Channel::Ch10,
- bw,
- cr,
- sf,
- crc_check_enabled : false,
- implicit_header_enabled : false,
- pwr_db : 0,
- thread_run : std::sync::Arc::new(AtomicBool::new(false)),
- thread_handle : None,
- rst_pin : tmp_rst_pin,
- }
- )
+ let mut spi = Spidev::open("/dev/spidev0.0")?;
+ let spi_options = SpidevOptions::new()
+ .bits_per_word(8)
+ .max_speed_hz(SPI_MAX_SPEED_HZ)
+ .mode(SPI_MODE_0)
+ .build();
+ spi.configure(&spi_options)?;
+
+ let dio_pin = Pin::new(DIO_BCM_PIN);
+ dio_pin.export()
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot export pin {}", e)))?;
+ dio_pin.set_direction(Direction::In)
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?;
+ dio_pin.set_edge(Edge::RisingEdge)
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set edge for pin {}", e)))?;
+
+
+ let cs_pin = Pin::new(CS_BCM_PIN);
+ cs_pin.export()
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot export pin {}", e)))?;
+
+ let mut rf = RF95 {
+ ch : Channel::Ch10,
+ bw,
+ cr,
+ sf,
+ crc_check_enabled : false,
+ implicit_header_enabled : false,
+ pwr_db : 0,
+ rst_pin : tmp_rst_pin,
+ cs_pin : cs_pin,
+ dio_pin : dio_pin,
+ spi : spi,
+ };
+
+ let ver = rf.get_version()?;
+
+ if ver == 0 || ver == 0xff {
+ return Err(io::Error::new(ErrorKind::Other,
+ format!("Invalid chip version {}", ver)));
+ }
+
+ // We configure so that we can use the entire 256 byte FIFO for either
+ // receive or transmit, but not both at the same time.
+ rf.write_register(LoraRegister::RegFifoRxBaseAddr, 0)?;
+ rf.write_register(LoraRegister::RegFifoTxBaseAddr, 0)?;
+
+ Ok(rf)
}
pub fn get_version(&mut self) -> io::Result<u8> {
- let device_version = RF95::read_register(LoraRegister::RegVersion)?;
+ let device_version = self.read_register(LoraRegister::RegVersion)?;
Ok(device_version)
}
@@ -352,59 +386,59 @@ impl RF95 {
pub fn set_channel(&mut self, ch : Channel) -> io::Result<()> {
self.set_mode(LoraMode::Sleep)?;
self.ch = ch;
- RF95::write_register(LoraRegister::RegFrfMsb, ch.msb())?;
- RF95::write_register(LoraRegister::RegFrfMid, ch.mid())?;
- RF95::write_register(LoraRegister::RegFrfLsb, ch.lsb())
+ self.write_register(LoraRegister::RegFrfMsb, ch.msb())?;
+ self.write_register(LoraRegister::RegFrfMid, ch.mid())?;
+ self.write_register(LoraRegister::RegFrfLsb, ch.lsb())
}
pub fn set_spreading_factor(&mut self, sf : SpreadingFactor) -> io::Result<()> {
self.set_mode(LoraMode::Sleep)?;
self.sf = sf;
- let mut tmp = RF95::read_register(LoraRegister::RegModemConfig2)?;
+ let mut tmp = self.read_register(LoraRegister::RegModemConfig2)?;
tmp &= 0x0F;
tmp |= sf.as_u8() << 4;
- RF95::write_register(LoraRegister::RegModemConfig2, tmp)
+ self.write_register(LoraRegister::RegModemConfig2, tmp)
}
pub fn set_bandwidth(&mut self, bw : Bandwidth) -> io::Result<()> {
self.set_mode(LoraMode::Sleep)?;
self.bw = bw;
- let mut tmp = RF95::read_register(LoraRegister::RegModemConfig1)?;
+ let mut tmp = self.read_register(LoraRegister::RegModemConfig1)?;
tmp &= 0x0F;
tmp |= bw.as_u8() << 4;
- RF95::write_register(LoraRegister::RegModemConfig1, tmp)?;
+ self.write_register(LoraRegister::RegModemConfig1, tmp)?;
Ok(())
}
pub fn set_coding_rate(&mut self, cr : CodingRate) -> io::Result<()> {
self.set_mode(LoraMode::Sleep)?;
self.cr = cr;
- let mut tmp = RF95::read_register(LoraRegister::RegModemConfig1)?;
+ let mut tmp = self.read_register(LoraRegister::RegModemConfig1)?;
tmp &= 0xF1;
tmp |= cr.as_u8() << 1;
- RF95::write_register(LoraRegister::RegModemConfig1, tmp)
+ self.write_register(LoraRegister::RegModemConfig1, tmp)
}
pub fn enable_crc_check(&mut self, en : bool) -> io::Result<()> {
- let mut tmp = RF95::read_register(LoraRegister::RegModemConfig2)?;
+ let mut tmp = self.read_register(LoraRegister::RegModemConfig2)?;
if en {
tmp |= 1 << 2;
} else {
tmp &= !(1 << 2);
}
self.crc_check_enabled = en;
- RF95::write_register(LoraRegister::RegModemConfig2, tmp)
+ self.write_register(LoraRegister::RegModemConfig2, tmp)
}
pub fn enable_implicit_header(&mut self, en : bool) -> io::Result<()> {
- let mut tmp = RF95::read_register(LoraRegister::RegModemConfig1)?;
+ let mut tmp = self.read_register(LoraRegister::RegModemConfig1)?;
if en {
tmp |= 0x01;
} else {
tmp &= !0x01;
}
self.implicit_header_enabled = en;
- RF95::write_register(LoraRegister::RegModemConfig1, tmp)
+ self.write_register(LoraRegister::RegModemConfig1, tmp)
}
pub fn set_output_power(&mut self, pwr : u8) -> io::Result<()> {
@@ -414,241 +448,207 @@ impl RF95 {
}
self.pwr_db = pwr;
let out = (pwr - 2) & 0x0F;
- let mut tmp = RF95::read_register(LoraRegister::RegPaConfig)?;
+ let mut tmp = self.read_register(LoraRegister::RegPaConfig)?;
tmp |= 0x80;
tmp &= 0xF0;
tmp |= out & 0x0F;
- RF95::write_register(LoraRegister::RegPaConfig, tmp)
+ self.write_register(LoraRegister::RegPaConfig, tmp)
}
pub fn set_mode(&mut self, m : LoraMode) -> io::Result<()> {
- RF95::write_register(LoraRegister::RegOpMode, m.as_u8())
+ self.write_register(LoraRegister::RegOpMode, m.as_u8())
}
- pub fn listen_timed(&mut self, timeout : u32) -> io::Result<Receiver<RF95EventType>> {
- let (sender, receiver) = mpsc::channel();
- let input = Pin::new(DIO_BCM_PIN);
+ fn check_pending_events(&mut self) -> io::Result<Option<RF95EventType>> {
+ // TODO atomic read and clear of bits!
+ let mut regv = self.read_register(LoraRegister::RegIrqFlags)?;
+ if regv.flag_enabled(IrqFlagMasks::CadDetected) {
+ regv = regv & !IrqFlagMasks::CadDetected.as_u8();
+ }
+ if regv.flag_enabled(IrqFlagMasks::CadDone) {
+ regv = regv & !IrqFlagMasks::CadDone.as_u8();
+ }
+ if regv.flag_enabled(IrqFlagMasks::FhssChangeChannel) {
+ regv = regv & !IrqFlagMasks::FhssChangeChannel.as_u8();
+ }
+ if regv.flag_enabled(IrqFlagMasks::PayloadCrcError) {
+ regv = regv & !IrqFlagMasks::PayloadCrcError.as_u8();
+ self.write_register(LoraRegister::RegIrqFlags, regv)?;
+ return Ok(Some(RF95EventType::ErrorWrongCrc));
+ }
+ if regv.flag_enabled(IrqFlagMasks::RxDone) {
+ let len = self.read_register(LoraRegister::RegRxNbBytes)?;
- self.thread_run.store(true, Ordering::SeqCst);
- let run = self.thread_run.clone();
+ let curr_addr = self.read_register(LoraRegister::RegFifoRxCurrentAddr)?;
+ self.write_register(LoraRegister::RegFifoAddrPtr, curr_addr)?;
- self.thread_handle = Some(thread::spawn(move || {
- input.with_exported(|| {
- let timeout = std::time::Duration::from_secs(timeout as u64);
- let start = std::time::Instant::now();
- match input.set_direction(Direction::In) {
- Ok(_) => (),
- Err(e) => {
- sender.send(RF95EventType::ErrorPinConfig).unwrap();
- panic!("Error while setting DI0 pin direction : {:?}", e);
- },
- };
+ let mut buf = Vec::new();
- match input.set_edge(Edge::RisingEdge) {
- Ok(_) => (),
- Err(e) => {
- sender.send(RF95EventType::ErrorPinConfig).unwrap();
- panic!("Error while setting DI0 pin edge detection : {:?}", e);
- }
- };
+ self.read_buffer(LoraRegister::RegFifo, &mut buf, len)?;
+ regv = regv & !IrqFlagMasks::RxDone.as_u8();
- let mut poller = match input.get_poller() {
- Ok(p) => p,
- Err(e) => {
- sender.send(RF95EventType::ErrorPinConfig).unwrap();
- panic!("Error while creating poller on DI0 : {:?}", e);
- }
- };
-
- while run.load(Ordering::SeqCst) {
- match poller.poll(10).unwrap() {
- Some(_) => {
- let mut regv = match RF95::read_register(LoraRegister::RegIrqFlags) {
- Ok(r) => r,
- Err(_) => {
- sender.send(RF95EventType::ErrorCommBus).unwrap();
- return Err(sysfs_gpio::Error::from(io::Error::new(io::ErrorKind::Other, format!("Reading irq flag register"))));
- },
- };
- if regv.flag_enabled(IrqFlagMasks::CadDetected) {
- regv = regv & !IrqFlagMasks::CadDetected.as_u8();
- }
- if regv.flag_enabled(IrqFlagMasks::CadDone) {
- regv = regv & !IrqFlagMasks::CadDone.as_u8();
- }
- if regv.flag_enabled(IrqFlagMasks::FhssChangeChannel) {
- regv = regv & !IrqFlagMasks::FhssChangeChannel.as_u8();
- }
- if regv.flag_enabled(IrqFlagMasks::PayloadCrcError) {
- sender.send(RF95EventType::ErrorWrongCrc).unwrap();
- regv = regv & !IrqFlagMasks::PayloadCrcError.as_u8();
- }
- if regv.flag_enabled(IrqFlagMasks::RxDone) {
- sender.send(RF95EventType::DataSent).unwrap();
- regv = regv & !IrqFlagMasks::RxDone.as_u8();
- }
- if regv.flag_enabled(IrqFlagMasks::TxDone) {
- sender.send(RF95EventType::DataReceived).unwrap();
- regv = regv & !IrqFlagMasks::TxDone.as_u8();
- }
- if regv.flag_enabled(IrqFlagMasks::RxTimeout) {
- sender.send(RF95EventType::ErrorTimedOut).unwrap();
- regv = regv & !IrqFlagMasks::RxTimeout.as_u8();
- }
- if regv.flag_enabled(IrqFlagMasks::ValidHeader) {
- regv = regv & !IrqFlagMasks::ValidHeader.as_u8();
- }
- match RF95::write_register(LoraRegister::RegIrqFlags, regv) {
- Ok(_) => (),
- Err(_) => {
- sender.send(RF95EventType::ErrorCommBus).unwrap();
- return Err(sysfs_gpio::Error::from(io::Error::new(io::ErrorKind::Other, format!("Reading irq flag register"))));
- },
- };
- },
- None => (),
- };
- if timeout.as_secs() > 0 {
- if std::time::Instant::now().duration_since(start) > timeout {
- break;
- }
- }
- }
- Ok(())
- }).expect("Cannot export gpio");
- }));
+ self.write_register(LoraRegister::RegIrqFlags, regv)?;
+ return Ok(Some(RF95EventType::DataReceived(buf)));
+ }
+ if regv.flag_enabled(IrqFlagMasks::TxDone) {
+ regv = regv & !IrqFlagMasks::TxDone.as_u8();
+ self.write_register(LoraRegister::RegIrqFlags, regv)?;
+ return Ok(Some(RF95EventType::DataSent));
+ }
- Ok(receiver)
- }
+ if regv.flag_enabled(IrqFlagMasks::RxTimeout) {
+ regv = regv & !IrqFlagMasks::RxTimeout.as_u8();
- pub fn listen_continuous(&mut self) -> io::Result<Receiver<RF95EventType>> {
- self.listen_timed(0)
+ self.write_register(LoraRegister::RegIrqFlags, regv)?;
+ return Ok(Some(RF95EventType::ErrorTimedOut));
+ }
+
+ if regv.flag_enabled(IrqFlagMasks::ValidHeader) {
+ regv = regv & !IrqFlagMasks::ValidHeader.as_u8();
+ }
+
+ self.write_register(LoraRegister::RegIrqFlags, regv)?;
+ Ok(None)
}
- pub fn stop_listening(&mut self) -> Result<(), String> {
- self.thread_run.store(false, Ordering::SeqCst);
- match self.thread_handle.take() {
- Some(th) => {
- match th.join() {
- Ok(_) => return Ok(()),
- Err(_) => return Err(format!("Cannot join spawned thread")),
- };
- },
- None => return Err(format!("No thread spawned")),
- };
+ pub fn wait_for_event(&mut self, timeout : std::time::Duration) -> io::Result<RF95EventType> {
+ let start = std::time::Instant::now();
+ let mut poller = self.dio_pin.get_poller()
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot get poller for pin {}", e)))?;
+
+ loop {
+ match poller.poll(10).unwrap() {
+ Some(_) => {
+ if let Some(ev) = self.check_pending_events()? {
+ return Ok(ev);
+ }
+ }
+ None => (),
+ };
+
+ if timeout.as_secs() > 0 && std::time::Instant::now().duration_since(start) > timeout {
+ break;
+ }
+ }
+ Ok(RF95EventType::ErrorTimedOut)
}
pub fn get_snr(&mut self) -> io::Result<i16> {
- Ok((RF95::read_register(LoraRegister::RegPktSnrValue)? as i16) / 4)
+ Ok((self.read_register(LoraRegister::RegPktSnrValue)? as i16) / 4)
}
pub fn get_packet_rssi(&mut self) -> io::Result<i16> {
- Ok((RF95::read_register(LoraRegister::RegRssiValue)? as i16) - 137)
+ Ok((self.read_register(LoraRegister::RegRssiValue)? as i16) - 137)
}
pub fn get_rssi(&mut self) -> io::Result<i16> {
- Ok((RF95::read_register(LoraRegister::RegRssiValue)? as i16) - 137)
+ Ok((self.read_register(LoraRegister::RegRssiValue)? as i16) - 137)
}
pub fn reset(&mut self) -> io::Result<()> {
- self.rst_pin.set_direction(Direction::Low).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?;
+ self.rst_pin.set_direction(Direction::Low).map_err(|e| io::Error::new(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)))?;
+ self.rst_pin.set_value(1).map_err(|e| io::Error::new(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<()> {
- let prev_mode = RF95::read_register(LoraRegister::RegOpMode)?;
+ let prev_mode = self.read_register(LoraRegister::RegOpMode)?;
self.set_mode(LoraMode::StandbyOokFsk)?;
- let mut tmp = RF95::read_register(LoraRegister::RegDioMapping1)?;
+ let mut tmp = self.read_register(LoraRegister::RegDioMapping1)?;
tmp &= 0x3F;
if df.as_u8() == DioFunction::TxDone.as_u8() {
tmp |= 0x40;
}
- RF95::write_register(LoraRegister::RegDioMapping1, tmp)?;
- RF95::write_register(LoraRegister::RegOpMode, prev_mode)
+ self.write_register(LoraRegister::RegDioMapping1, tmp)?;
+ self.write_register(LoraRegister::RegOpMode, prev_mode)
}
- fn write_register(reg : LoraRegister, data : u8) -> io::Result<()> {
- let mut spi = Spidev::open("/dev/spidev0.0")?;
- let spi_options = SpidevOptions::new()
- .bits_per_word(8)
- .max_speed_hz(SPI_MAX_SPEED_HZ)
- .mode(SPI_MODE_0)
- .build();
- spi.configure(&spi_options)?;
+ fn write_register(&mut self, reg : LoraRegister, data : u8) -> io::Result<()> {
+ self.cs_pin.set_direction(Direction::Low)
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?;
- match spi.write(&[reg.as_u8(), data]) {
- Ok(_) => Ok(()),
- Err(_) => Err(io::Error::new(ErrorKind::Other, "Problem while writing to device"))
- }
+ self.spi.write(&[reg.as_u8(), data])?;
+
+ self.cs_pin.set_value(1)
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set value for pin {}", e)))
}
- fn write_buffer(reg : LoraRegister, buffer : Vec<u8>) -> io::Result<()> {
- let mut spi = Spidev::open("/dev/spidev0.0")?;
- let spi_options = SpidevOptions::new()
- .bits_per_word(8)
- .max_speed_hz(SPI_MAX_SPEED_HZ)
- .mode(SPI_MODE_0)
- .build();
- spi.configure(&spi_options)?;
+ pub fn send(&mut self, buffer : Vec<u8>) -> io::Result<()> {
+ if buffer.len() > MAX_MTU {
+ return Err(io::Error::new(ErrorKind::Other, "Message larger than MTU"));
+ }
+
+ // TODO waitpacketsent
+ self.set_mode(LoraMode::Standby)?;
+
+ // TODO waitCAD
+
+ self.write_register(LoraRegister::RegFifoAddrPtr, 0)?;
+ // TODO RadioHead header?
+ let len = buffer.len() as u8;
+ self.write_buffer(LoraRegister::RegFifo, buffer)?;
+ self.write_register(LoraRegister::RegPayloadLength, len)?;
+ self.set_mode(LoraMode::Tx)?;
+
+ // Wait for TX to complete
+ loop {
+ // TODO protect IRQ clearing against concurrent access
+ let mut regv = self.read_register(LoraRegister::RegIrqFlags)?;
+ if regv.flag_enabled(IrqFlagMasks::TxDone) {
+ regv = regv & !IrqFlagMasks::TxDone.as_u8();
+ self.write_register(LoraRegister::RegIrqFlags, regv)?;
+ break;
+ }
+
+ thread::sleep(Duration::from_millis(2));
+ }
+ Ok(())
+ }
- let cs_pin = Pin::new(CS_BCM_PIN);
- 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)))?;
+ fn write_buffer(&mut self, reg : LoraRegister, buffer : Vec<u8>) -> io::Result<()> {
+ self.cs_pin.set_direction(Direction::Low)
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?;
let mut v2 = buffer;
v2.insert(0, reg.as_u8());
- spi.write(&v2)?;
- cs_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e)))
+ self.spi.write(&v2)?;
+ self.cs_pin.set_value(1)
+ .map_err(|e| io::Error::new(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(SPI_MAX_SPEED_HZ)
- .mode(SPI_MODE_0)
- .build();
- spi.configure(&spi_options)?;
-
- let cs_pin = Pin::new(CS_BCM_PIN);
- 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)))?;
+ fn read_register(&mut self, reg : LoraRegister) -> io::Result<u8> {
+ self.cs_pin.set_direction(Direction::Low)
+ .map_err(|e| io::Error::new(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();
+ self.spi.transfer(&mut transfer).unwrap();
}
- cs_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e)))?;
+ self.cs_pin.set_value(1)
+ .map_err(|e| io::Error::new(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(SPI_MAX_SPEED_HZ)
- .mode(SPI_MODE_0)
- .build();
- spi.configure(&spi_options)?;
+ fn read_buffer(&mut self, reg : LoraRegister, buffer : &mut Vec<u8>, length : u8) -> io::Result<()> {
- let cs_pin = Pin::new(CS_BCM_PIN);
- 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)))?;
+ self.cs_pin.set_direction(Direction::Low)
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set direction for pin {}", e)))?;
let mut tmp : Vec<u8> = Vec::with_capacity(length as usize);
- spi.write(&[reg.as_u8()])?;
- spi.read(tmp.as_mut_slice())?;
+ self.spi.write(&[reg.as_u8()])?;
+ self.spi.read(tmp.as_mut_slice())?;
buffer.clear();
buffer.write(&tmp)?;
- cs_pin.set_value(1).map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Cannot set value for pin {}", e)))?;
+ self.cs_pin.set_value(1)
+ .map_err(|e| io::Error::new(ErrorKind::Other, format!("Cannot set value for pin {}", e)))?;
Ok(())
}
}