firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

at f6676c82689a4e7314b93c8eb98ddd08152fe708 126 lines 3.3 kB view raw
1pub mod image; 2pub mod input; 3pub mod program_upload; 4 5use std::fmt::{Display, Formatter}; 6use std::io; 7use std::io::{Read, Write}; 8use std::marker::PhantomData; 9use std::time::Duration; 10use serialport::SerialPort; 11use eepy_serial::{Response, SerialCommand, SerialError}; 12 13#[derive(Debug)] 14pub enum Error { 15 InvalidResponse, 16 DeserializeFailed(postcard::Error), 17 Serial(SerialError), 18 Io(io::Error), 19} 20 21impl From<SerialError> for Error { 22 fn from(value: SerialError) -> Self { 23 Self::Serial(value) 24 } 25} 26 27impl From<io::Error> for Error { 28 fn from(value: io::Error) -> Self { 29 Self::Io(value) 30 } 31} 32 33impl From<postcard::Error> for Error { 34 fn from(value: postcard::Error) -> Self { 35 Self::DeserializeFailed(value) 36 } 37} 38 39impl Display for Error { 40 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 41 match self { 42 Self::InvalidResponse => write!(f, "received invalid response"), 43 Self::DeserializeFailed(e) => e.fmt(f), 44 Self::Serial(e) => e.fmt(f), 45 Self::Io(e) => e.fmt(f), 46 } 47 } 48} 49 50impl std::error::Error for Error {} 51 52pub trait SerialState {} 53pub trait CanEnter<S: SerialState>: SerialState {} 54 55pub enum Unknown {} 56impl SerialState for Unknown {} 57impl CanEnter<Normal> for Unknown {} 58impl CanEnter<HostApp> for Unknown {} 59 60pub enum Normal {} 61impl SerialState for Normal {} 62impl CanEnter<HostApp> for Normal {} 63 64pub enum HostApp {} 65impl SerialState for HostApp {} 66impl CanEnter<Normal> for HostApp {} 67 68pub struct Serial<S: SerialState> { 69 port: Box<dyn SerialPort>, 70 _marker: PhantomData<S>, 71} 72 73impl<T: SerialState> Serial<T> { 74 pub(crate) fn write(&mut self, command: SerialCommand, data: &[u8]) -> Result<(), Error> { 75 self.port.write_all(&[command as u8])?; 76 self.port.write_all(data)?; 77 let mut response_buf = [0u8]; 78 self.port.read_exact(&mut response_buf)?; 79 Response::from_repr(response_buf[0]) 80 .map(|resp| Result::<(), SerialError>::from(resp).map_err(|e| Error::Serial(e))) 81 .ok_or(Error::InvalidResponse)? 82 } 83} 84 85impl Serial<Unknown> { 86 pub fn new(port: &str) -> Result<Self, serialport::Error> { 87 let port = serialport::new(port, 0) 88 .timeout(Duration::from_secs(60)) 89 .open()?; 90 91 Ok(Self { 92 port, 93 _marker: PhantomData::default(), 94 }) 95 } 96} 97 98impl<T: CanEnter<Normal>> Serial<T> { 99 pub fn normal(mut self) -> Result<Serial<Normal>, Error> { 100 let res = self.write(SerialCommand::ExitHostApp, &[]); 101 match res { 102 Ok(()) | Err(Error::Serial(SerialError::IncorrectMode)) => { 103 Ok(Serial { 104 port: self.port, 105 _marker: PhantomData::default(), 106 }) 107 }, 108 Err(e) => Err(e), 109 } 110 } 111} 112 113impl<T: CanEnter<HostApp>> Serial<T> { 114 pub fn host_app(mut self) -> Result<Serial<HostApp>, Error> { 115 let res = self.write(SerialCommand::EnterHostApp, &[]); 116 match res { 117 Ok(()) | Err(Error::Serial(SerialError::IncorrectMode)) => { 118 Ok(Serial { 119 port: self.port, 120 _marker: PhantomData::default(), 121 }) 122 }, 123 Err(e) => Err(e), 124 } 125 } 126}