use std::sync::{Arc, Mutex};
#[macro_use]
extern crate log;
#[macro_use]
extern crate bitflags;
extern crate byteorder;
extern crate embedded_hal;
pub use embedded_hal::spi::{Mode as SpiMode};
extern crate libusb;
use libusb::{Device as UsbDevice, DeviceDescriptor};
pub mod device;
pub use crate::device::{GpioMode, GpioLevel, SpiConfig, SpiClock};
use crate::device::*;
pub mod manager;
#[derive(Debug)]
pub enum Error {
Usb(libusb::Error),
NoLanguages,
Configurations,
Endpoint,
GpioInUse,
}
impl From<libusb::Error> for Error {
fn from(e: libusb::Error) -> Self {
Error::Usb(e)
}
}
pub struct Cp2130<'a> {
inner: Arc<Mutex<Inner<'a>>>,
info: Info,
}
pub trait Device {
fn spi_read(&self, buff: &mut [u8]) -> Result<usize, Error>;
fn spi_write(&self, buff: &[u8]) -> Result<(), Error>;
fn spi_write_read(&self, buff_out: &[u8], buff_in: &mut [u8]) -> Result<usize, Error>;
fn version(&self) -> Result<u16, Error> ;
fn set_gpio_mode_level(&self, pin: u8, mode: GpioMode, level: GpioLevel) -> Result<(), Error>;
fn get_gpio_values(&self) -> Result<GpioLevels, Error>;
fn get_gpio_level(&self, pin: u8) -> Result<bool, Error>;
}
impl <'a> Cp2130<'a> {
pub fn new(device: UsbDevice<'a>, descriptor: DeviceDescriptor) -> Result<Self, Error> {
let (inner, info) = Inner::new(device, descriptor)?;
let inner = Arc::new(Mutex::new(inner));
Ok(Self{info, inner})
}
pub fn info(&self) -> Info {
self.info.clone()
}
pub fn reset(&self) -> Result<(), Error> {
self.inner.lock().unwrap().reset()
}
pub fn spi(&self, channel: u8, config: SpiConfig) -> Result<Spi<'a>, Error> {
let mut inner = self.inner.lock().unwrap();
inner.spi_configure(channel, config)?;
Ok(Spi{inner: self.inner.clone(), channel})
}
pub fn gpio_out(&self, index: u8, mode: GpioMode, level: GpioLevel) -> Result<OutputPin<'a>, Error> {
let mut inner = self.inner.lock().unwrap();
if inner.gpio_allocated[index as usize] {
return Err(Error::GpioInUse)
}
inner.set_gpio_mode_level(index, mode, level)?;
inner.gpio_allocated[index as usize] = true;
Ok(OutputPin{index, mode, inner: self.inner.clone()})
}
pub fn gpio_in(&self, index: u8) -> Result<InputPin<'a>, Error> {
let mut inner = self.inner.lock().unwrap();
if inner.gpio_allocated[index as usize] {
return Err(Error::GpioInUse)
}
inner.set_gpio_mode_level(index, GpioMode::Input, GpioLevel::Low)?;
inner.gpio_allocated[index as usize] = true;
Ok(InputPin{index, inner: self.inner.clone()})
}
}
impl <'a> Device for Cp2130<'a> {
fn spi_read(&self, buff: &mut [u8]) -> Result<usize, Error> {
let mut inner = self.inner.lock().unwrap();
inner.spi_read(buff)
}
fn spi_write(&self, buff: &[u8]) -> Result<(), Error> {
let mut inner = self.inner.lock().unwrap();
inner.spi_write(buff)
}
fn spi_write_read(&self, buff_out: &[u8], buff_in: &mut [u8]) -> Result<usize, Error> {
let mut inner = self.inner.lock().unwrap();
inner.spi_write_read(buff_out, buff_in)
}
fn version(&self) -> Result<u16, Error> {
let mut inner = self.inner.lock().unwrap();
inner.version()
}
fn set_gpio_mode_level(&self, pin: u8, mode: GpioMode, level: GpioLevel) -> Result<(), Error> {
let mut inner = self.inner.lock().unwrap();
inner.set_gpio_mode_level(pin, mode, level)
}
fn get_gpio_values(&self) -> Result<GpioLevels, Error> {
let mut inner = self.inner.lock().unwrap();
inner.get_gpio_values()
}
fn get_gpio_level(&self, pin: u8) -> Result<bool, Error> {
let mut inner = self.inner.lock().unwrap();
inner.get_gpio_level(pin)
}
}
pub struct Spi<'a> {
channel: u8,
inner: Arc<Mutex<Inner<'a>>>,
}
use embedded_hal::blocking::spi::{Write, Transfer};
impl <'a> Transfer<u8> for Spi<'a> {
type Error = Error;
fn transfer<'w>(&mut self, words: &'w mut [u8] ) -> Result<&'w [u8], Self::Error> {
let out = words.to_vec();
let _n = self.inner.lock().unwrap().spi_write_read(&out, words)?;
Ok(words)
}
}
impl <'a> Write<u8> for Spi<'a> {
type Error = Error;
fn write(&mut self, words: &[u8] ) -> Result<(), Self::Error> {
let _n = self.inner.lock().unwrap().spi_write(words)?;
Ok(())
}
}
pub struct InputPin<'a> {
index: u8,
inner: Arc<Mutex<Inner<'a>>>,
}
impl <'a> embedded_hal::digital::v2::InputPin for InputPin<'a> {
type Error = Error;
fn is_high(&self) -> Result<bool, Self::Error> {
self.inner.lock().unwrap().get_gpio_level(self.index)
}
fn is_low(&self) -> Result<bool, Self::Error> {
let v = self.is_high()?;
Ok(!v)
}
}
pub struct OutputPin<'a> {
index: u8,
mode: GpioMode,
inner: Arc<Mutex<Inner<'a>>>,
}
impl <'a> embedded_hal::digital::v2::OutputPin for OutputPin<'a> {
type Error = Error;
fn set_high(&mut self) -> Result<(), Self::Error> {
self.inner.lock().unwrap().set_gpio_mode_level(self.index, self.mode, GpioLevel::High)
}
fn set_low(&mut self) -> Result<(), Self::Error> {
self.inner.lock().unwrap().set_gpio_mode_level(self.index, self.mode, GpioLevel::Low)
}
}