#![no_std]
use embedded_hal as hal;
use hal::digital::v2::OutputPin;
use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand};
fn send_u8<SPI: hal::blocking::spi::Write<u8>>(
spi: &mut SPI,
words: DataFormat<'_>,
) -> Result<(), DisplayError> {
match words {
DataFormat::U8(slice) => spi.write(slice).map_err(|_| DisplayError::BusWriteError),
DataFormat::U16(slice) => {
use byte_slice_cast::*;
spi.write(slice.as_byte_slice())
.map_err(|_| DisplayError::BusWriteError)
}
DataFormat::U16LE(slice) => {
use byte_slice_cast::*;
for v in slice.as_mut() {
*v = v.to_le();
}
spi.write(slice.as_byte_slice())
.map_err(|_| DisplayError::BusWriteError)
}
DataFormat::U16BE(slice) => {
use byte_slice_cast::*;
for v in slice.as_mut() {
*v = v.to_be();
}
spi.write(slice.as_byte_slice())
.map_err(|_| DisplayError::BusWriteError)
}
DataFormat::U8Iter(iter) => {
let mut buf = [0; 32];
let mut i = 0;
for v in iter.into_iter() {
buf[i] = v;
i += 1;
if i == buf.len() {
spi.write(&buf).map_err(|_| DisplayError::BusWriteError)?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i])
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}
DataFormat::U16LEIter(iter) => {
use byte_slice_cast::*;
let mut buf = [0; 32];
let mut i = 0;
for v in iter.map(u16::to_le) {
buf[i] = v;
i += 1;
if i == buf.len() {
spi.write(&buf.as_byte_slice())
.map_err(|_| DisplayError::BusWriteError)?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i].as_byte_slice())
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}
DataFormat::U16BEIter(iter) => {
use byte_slice_cast::*;
let mut buf = [0; 64];
let mut i = 0;
let len = buf.len();
for v in iter.map(u16::to_be) {
buf[i] = v;
i += 1;
if i == len {
spi.write(&buf.as_byte_slice())
.map_err(|_| DisplayError::BusWriteError)?;
i = 0;
}
}
if i > 0 {
spi.write(&buf[..i].as_byte_slice())
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}
_ => Err(DisplayError::DataFormatNotImplemented),
}
}
pub struct SPIInterface<SPI, DC, CS> {
spi: SPI,
dc: DC,
cs: CS,
}
impl<SPI, DC, CS> SPIInterface<SPI, DC, CS>
where
SPI: hal::blocking::spi::Write<u8>,
DC: OutputPin,
CS: OutputPin,
{
pub fn new(spi: SPI, dc: DC, cs: CS) -> Self {
Self { spi, dc, cs }
}
pub fn release(self) -> (SPI, DC, CS) {
(self.spi, self.dc, self.cs)
}
}
impl<SPI, DC, CS> WriteOnlyDataCommand for SPIInterface<SPI, DC, CS>
where
SPI: hal::blocking::spi::Write<u8>,
DC: OutputPin,
CS: OutputPin,
{
fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
self.cs.set_low().map_err(|_| DisplayError::CSError)?;
self.dc.set_low().map_err(|_| DisplayError::DCError)?;
let err = send_u8(&mut self.spi, cmds);
self.cs.set_high().ok();
err
}
fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
self.cs.set_low().map_err(|_| DisplayError::CSError)?;
self.dc.set_high().map_err(|_| DisplayError::DCError)?;
let err = send_u8(&mut self.spi, buf);
self.cs.set_high().ok();
err
}
}
pub struct SPIInterfaceNoCS<SPI, DC> {
spi: SPI,
dc: DC,
}
impl<SPI, DC> SPIInterfaceNoCS<SPI, DC>
where
SPI: hal::blocking::spi::Write<u8>,
DC: OutputPin,
{
pub fn new(spi: SPI, dc: DC) -> Self {
Self { spi, dc }
}
pub fn release(self) -> (SPI, DC) {
(self.spi, self.dc)
}
}
impl<SPI, DC> WriteOnlyDataCommand for SPIInterfaceNoCS<SPI, DC>
where
SPI: hal::blocking::spi::Write<u8>,
DC: OutputPin,
{
fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
self.dc.set_low().map_err(|_| DisplayError::DCError)?;
send_u8(&mut self.spi, cmds)
}
fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
self.dc.set_high().map_err(|_| DisplayError::DCError)?;
send_u8(&mut self.spi, buf)
}
}