use core::{
str::FromStr,
};
use embedded_hal::{
blocking::{
delay::{DelayMs, DelayUs},
i2c,
spi,
},
digital::v2,
};
use crate::{
close, ioctl, read, usleep, write,
i2c_msg_s, i2c_transfer_s, size_t, ssize_t,
GPIOC_WRITE, I2CIOC_TRANSFER, I2C_M_READ, O_RDWR,
String,
};
impl i2c::Read for I2c {
type Error = i32;
fn read(&mut self, _addr: u8, _buf: &mut [u8]) -> Result<(), Self::Error> {
panic!();
}
}
impl i2c::Write for I2c {
type Error = i32;
fn write(&mut self, addr: u8, buf: &[u8]) -> Result<(), Self::Error> {
let mut buf2 = [0 ; 64];
assert!(buf.len() <= buf2.len());
buf2[..buf.len()].copy_from_slice(buf);
let mut rbuf = [0 ; 1];
let msg = [
i2c_msg_s {
frequency: self.frequency, addr: addr as u16, buffer: buf2.as_mut_ptr(), length: buf.len() as ssize_t,
#[cfg(target_arch = "riscv32")] flags: crate::I2C_M_NOSTOP,
#[cfg(not(target_arch = "riscv32"))] flags: 0,
},
i2c_msg_s {
frequency: self.frequency, addr: addr as u16, buffer: rbuf.as_mut_ptr(), length: rbuf.len() as ssize_t, flags: I2C_M_READ, },
];
let xfer = i2c_transfer_s {
msgv: msg.as_ptr(), msgc: msg.len() as size_t, };
let ret = unsafe {
ioctl(
self.fd, I2CIOC_TRANSFER, &xfer )
};
assert!(ret >= 0);
Ok(())
}
}
impl i2c::WriteRead for I2c {
type Error = i32;
fn write_read(&mut self, addr: u8, wbuf: &[u8], rbuf: &mut [u8]) -> Result<(), Self::Error> {
assert_eq!(wbuf.len(), 1);
let reg_id = wbuf[0];
let mut start = [reg_id ; 1];
let msg = [
i2c_msg_s {
frequency: self.frequency, addr: addr as u16, buffer: start.as_mut_ptr(), length: start.len() as ssize_t,
#[cfg(target_arch = "riscv32")] flags: crate::I2C_M_NOSTOP,
#[cfg(not(target_arch = "riscv32"))] flags: 0,
},
i2c_msg_s {
frequency: self.frequency, addr: addr as u16, buffer: rbuf.as_mut_ptr(), length: rbuf.len() as ssize_t, flags: I2C_M_READ, },
];
let xfer = i2c_transfer_s {
msgv: msg.as_ptr(), msgc: msg.len() as size_t, };
let ret = unsafe {
ioctl(
self.fd,
I2CIOC_TRANSFER,
&xfer
)
};
assert!(ret >= 0);
Ok(())
}
}
impl spi::Transfer<u8> for Spi {
type Error = i32;
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
let bytes_written = unsafe {
write(self.fd, words.as_ptr(), words.len() as u32)
};
assert_eq!(bytes_written, words.len() as i32);
let bytes_read = unsafe {
read(self.fd, words.as_mut_ptr(), words.len() as u32)
};
assert_eq!(bytes_read, words.len() as i32);
Ok(words)
}
}
impl spi::Write<u8> for Spi{
type Error = i32;
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
let bytes_written = unsafe {
write(self.fd, words.as_ptr(), words.len() as u32)
};
assert_eq!(bytes_written, words.len() as i32);
Ok(())
}
}
impl v2::OutputPin for OutputPin {
type Error = i32;
fn set_high(&mut self) -> Result<(), Self::Error> {
let ret = unsafe {
ioctl(self.fd, GPIOC_WRITE, 1)
};
assert!(ret >= 0);
Ok(())
}
fn set_low(&mut self) -> Result<(), Self::Error> {
let ret = unsafe {
ioctl(self.fd, GPIOC_WRITE, 0)
};
assert!(ret >= 0);
Ok(())
}
}
impl v2::InputPin for InputPin {
type Error = i32;
fn is_high(&self) -> Result<bool, Self::Error> {
let mut invalue: i32 = 0;
let addr: *mut i32 = &mut invalue;
let ret = unsafe {
ioctl(self.fd, crate::GPIOC_READ, addr)
};
assert!(ret >= 0);
match invalue {
0 => Ok(false),
_ => Ok(true),
}
}
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(!self.is_high()?)
}
}
impl v2::InputPin for InterruptPin {
type Error = i32;
fn is_high(&self) -> Result<bool, Self::Error> {
let mut invalue: i32 = 0;
let addr: *mut i32 = &mut invalue;
let ret = unsafe {
ioctl(self.fd, crate::GPIOC_READ, addr)
};
assert!(ret >= 0);
match invalue {
0 => Ok(false),
_ => Ok(true),
}
}
fn is_low(&self) -> Result<bool, Self::Error> {
Ok(!self.is_high()?)
}
}
impl v2::OutputPin for UnusedPin {
type Error = i32;
fn set_high(&mut self) -> Result<(), Self::Error> {
Ok(())
}
fn set_low(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl DelayUs<u8> for Delay {
fn delay_us(&mut self, us: u8) {
unsafe { usleep(us as u32); }
}
}
impl DelayUs<u16> for Delay {
fn delay_us(&mut self, us: u16) {
unsafe { usleep(us as u32); }
}
}
impl DelayUs<u32> for Delay {
fn delay_us(&mut self, us: u32) {
unsafe { usleep(us); }
}
}
impl DelayMs<u8> for Delay {
fn delay_ms(&mut self, ms: u8) {
unsafe { usleep(ms as u32 * 1000); }
}
}
impl DelayMs<u16> for Delay {
fn delay_ms(&mut self, ms: u16) {
unsafe { usleep(ms as u32 * 1000); }
}
}
impl DelayMs<u32> for Delay {
fn delay_ms(&mut self, ms: u32) {
unsafe { usleep(ms * 1000); }
}
}
impl I2c {
pub fn new(path: &str, frequency: u32) -> Result<Self, i32> {
let fd = open(path, O_RDWR);
if fd < 0 { return Err(fd) }
Ok(Self { fd, frequency })
}
}
impl Spi {
pub fn new(path: &str) -> Result<Self, i32> {
let fd = open(path, O_RDWR);
if fd < 0 { return Err(fd) }
Ok(Self { fd })
}
}
impl InputPin {
pub fn new(path: &str) -> Result<Self, i32> {
let fd = open(path, O_RDWR);
if fd < 0 { return Err(fd) }
Ok(Self { fd })
}
}
impl OutputPin {
pub fn new(path: &str) -> Result<Self, i32> {
let fd = open(path, O_RDWR);
if fd < 0 { return Err(fd) }
Ok(Self { fd })
}
}
impl InterruptPin {
pub fn new(path: &str) -> Result<Self, i32> {
let fd = open(path, O_RDWR);
if fd < 0 { return Err(fd) }
Ok(Self { fd })
}
}
impl UnusedPin {
pub fn new() -> Result<Self, i32> {
Ok(Self {})
}
}
impl Drop for I2c {
fn drop(&mut self) {
unsafe { close(self.fd) };
}
}
impl Drop for Spi {
fn drop(&mut self) {
unsafe { close(self.fd) };
}
}
impl Drop for InputPin {
fn drop(&mut self) {
unsafe { close(self.fd) };
}
}
impl Drop for OutputPin {
fn drop(&mut self) {
unsafe { close(self.fd) };
}
}
impl Drop for InterruptPin {
fn drop(&mut self) {
unsafe { close(self.fd) };
}
}
pub struct I2c {
fd: i32,
frequency: u32,
}
pub struct Spi {
fd: i32,
}
pub struct InputPin {
fd: i32,
}
pub struct OutputPin {
fd: i32,
}
pub struct InterruptPin {
fd: i32,
}
pub struct UnusedPin {
}
pub struct Delay;
fn open(path: &str, oflag: i32) -> i32 {
use crate::open;
let mut s_with_null = String::from_str(path) .expect("open conversion failed");
s_with_null.push('\0')
.expect("open overflow");
let p = s_with_null.as_str().as_ptr();
unsafe { open(p, oflag)
}
}