pcd8544_hal/
lib.rs

1#![deny(unsafe_code)]
2#![deny(warnings)]
3#![no_std]
4
5mod font;
6mod pcd8544_gpio;
7mod pcd8544_spi;
8
9pub use pcd8544_gpio::Pcd8544Gpio;
10pub use pcd8544_spi::Pcd8544Spi;
11
12const DISPLAY_WIDTH: usize = 84;
13const DISPLAY_HEIGHT: usize = 6;
14const BUFFER_SIZE: usize = DISPLAY_WIDTH * DISPLAY_HEIGHT;
15
16pub trait Pcd8544 {
17    fn command(&mut self, command: u8);
18    fn data(&mut self, data: &[u8]);
19
20    fn init(&mut self) {
21        // chip active (PD=0); horizontal addressing mode (V = 0); use extended instruction set (H = 1)
22        self.command(0x21);
23        // try 0xB1 (for 3.3V red SparkFun), 0xB8 (for 3.3V blue SparkFun), 0xBF if your display is too dark, or 0x80 to 0xFF if experimenting
24        self.command(0xB1);
25        // temp coefficient (0)
26        self.command(0x04);
27        // LCD bias mode 1:48
28        self.command(0x13);
29
30        // we must send 0x20 before modifying the display control mode
31        self.command(0x20);
32        // set display control to normal mode (pixels are on when data is 1), inverse mode=0x0D
33        self.command(0x0C);
34
35        self.clear();
36    }
37
38    fn print_char(&mut self, c: u8) {
39        let i = (c as usize) - 0x20;
40
41        self.data(&font::ASCII[i]);
42        self.data(&[0x00]);
43    }
44
45    fn print(&mut self, s: &str) {
46        for byte in s.bytes() {
47            match byte {
48                // printable ASCII byte or newline
49                0x20..=0x7e => self.print_char(byte),
50                // not part of printable ASCII range
51                _ => self.print_char(b'?'),
52            }
53        }
54    }
55
56    fn set_position(&mut self, x: u8, y: u8) {
57        assert!(usize::from(x) < DISPLAY_WIDTH);
58        assert!(usize::from(y) < DISPLAY_HEIGHT);
59
60        self.command(0x40 + y);
61        self.command(0x80 + x);
62    }
63
64    // note: data direction is vertical: [1 2 3 4 5 6]
65    // 1 3 5
66    // 2 4 6
67    fn draw_buffer(&mut self, buffer: &[u8; 6 * 84]) {
68        self.command(0x22); // vertical addressing
69        self.set_position(0, 0);
70        self.data(buffer);
71        self.command(0x20); // horizontal addressing
72        self.set_position(0, 0);
73    }
74
75    fn clear(&mut self) {
76        self.set_position(0, 0);
77        self.data(&[0u8; BUFFER_SIZE]);
78        self.set_position(0, 0);
79    }
80}