1use crate::error::Error;
2use crate::LCD1602;
3
4use crate::error::Error::UnsupportedBusWidth;
5use crate::lcd1602::BusWidth::FourBits;
6use crate::lcd1602::Direction::RightToLeft;
7use core::time::Duration;
8use embedded_hal::digital::v2::OutputPin;
9use embedded_hal::timer::CountDown;
10use nb::block;
11
12impl<EN, RS, D4, D5, D6, D7, Timer, E> LCD1602<EN, RS, D4, D5, D6, D7, Timer>
13where
14 EN: OutputPin<Error = E>,
15 RS: OutputPin<Error = E>,
16 D4: OutputPin<Error = E>,
17 D5: OutputPin<Error = E>,
18 D6: OutputPin<Error = E>,
19 D7: OutputPin<Error = E>,
20 Timer: CountDown<Time = Duration>,
21{
22 pub fn new(
23 en: EN,
24 rs: RS,
25 d4: D4,
26 d5: D5,
27 d6: D6,
28 d7: D7,
29 timer: Timer,
30 ) -> Result<LCD1602<EN, RS, D4, D5, D6, D7, Timer>, Error<E>> {
31 let mut lcd = LCD1602 {
32 en,
33 rs,
34 d4,
35 d5,
36 d6,
37 d7,
38 timer,
39 };
40 lcd.init()?;
41 Ok(lcd)
42 }
43
44 fn init(&mut self) -> Result<(), Error<E>> {
45 self.delay(50000)?;
46 self.set_bus_width(FourBits)?;
47
48 self.command(0x0C)?; self.clear()?;
50 self.set_entry_mode(RightToLeft, false)?;
51 Ok(())
52 }
53
54 pub fn set_bus_width(&mut self, bus_width: BusWidth) -> Result<(), Error<E>> {
55 match bus_width {
56 FourBits => {
57 self.write_bus(0x02)?;
58 self.delay(39)
59 }
60 _ => Err(UnsupportedBusWidth),
61 }
62 }
63 pub fn set_entry_mode(
64 &mut self,
65 text_direction: Direction,
66 screen_edge_tracking: bool,
67 ) -> Result<(), Error<E>> {
68 let mut cmd = 0x04;
69 if text_direction == Direction::RightToLeft {
70 cmd |= 0x02;
71 }
72 if screen_edge_tracking {
73 cmd |= 0x01;
74 }
75 self.command(cmd)?;
76 self.delay(39)
77 }
78
79 pub fn clear(&mut self) -> Result<(), Error<E>> {
80 self.command(0x01)?;
81 self.delay(1530)
82 }
83
84 pub fn home(&mut self) -> Result<(), Error<E>> {
85 self.command(0x02)?;
86 self.delay(1530)
87 }
88
89 fn command(&mut self, cmd: u8) -> Result<(), Error<E>> {
90 self.rs.set_low()?;
91 self.write_bus((cmd & 0xF0) >> 4)?;
92 self.write_bus(cmd & 0x0F)?; Ok(())
94 }
95
96 fn write_char(&mut self, ch: u8) -> Result<(), Error<E>> {
97 self.rs.set_high()?;
98 self.write_bus((ch & 0xF0) >> 4)?;
99 self.write_bus(ch & 0x0F)?; Ok(())
101 }
102
103 pub fn print(&mut self, s: &str) -> Result<(), Error<E>> {
104 for ch in s.chars() {
105 self.delay(320)?; self.write_char(ch as u8)?;
107 }
108 Ok(())
109 }
110
111 fn write_bus(&mut self, data: u8) -> Result<(), Error<E>> {
112 self.en.set_low()?;
113 match (data & 0x1) > 0 {
114 true => self.d4.set_high()?,
115 false => self.d4.set_low()?,
116 };
117 match (data & 0x2) > 0 {
118 true => self.d5.set_high()?,
119 false => self.d5.set_low()?,
120 };
121 match (data & 0x4) > 0 {
122 true => self.d6.set_high()?,
123 false => self.d6.set_low()?,
124 };
125 match (data & 0x8) > 0 {
126 true => self.d7.set_high()?,
127 false => self.d7.set_low()?,
128 };
129 self.en.set_high()?;
130 self.en.set_low()?;
131 Ok(())
132 }
133
134 pub fn delay(&mut self, interval_us: u64) -> Result<(), Error<E>> {
135 self.timer.start(Duration::from_micros(interval_us));
136 match block!(self.timer.wait()) {
137 Ok(_) => Ok(()),
138 Err(_) => Err(Error::TimerError),
139 }
140 }
141}
142
143#[derive(PartialEq)]
144pub enum Direction {
145 LeftToRight,
146 RightToLeft,
147}
148
149#[derive(PartialEq)]
150pub enum BusWidth {
151 FourBits,
152 EightBits,
153}