diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-09-04 09:20:59 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2018-09-04 09:20:59 +0200 |
commit | 359a6ebaf59aa19699cbd61b07406999e6732373 (patch) | |
tree | d758f8dad49094ac6a7aa15dd0e817b2cf3c1cc5 /src/rfm95.rs | |
parent | 4c9f3c8dbfc67d9e1f8479538ba9c9b6dc3be5c4 (diff) | |
download | raspi-rfm95-kiss-master.tar.gz raspi-rfm95-kiss-master.tar.bz2 raspi-rfm95-kiss-master.zip |
Diffstat (limited to 'src/rfm95.rs')
-rw-r--r-- | src/rfm95.rs | 412 |
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(()) } } |