firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
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}