2 * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 i2c_slave_address: u8,
40 let x = ptr::read_volatile(&r);
41 ptr::write_volatile(&mut r, x - 1);
50 let x = ptr::read_volatile(&a);
51 ptr::write_volatile(&mut a, x + 1);
66 let x = ptr::read_volatile(&r);
67 ptr::write_volatile(&mut r, x - 1);
77 pub fn new(reset_gpio: u32, reset_gpio_pin: u32, i2c_slave_address: u8) -> Display {
79 reset_gpio: reset_gpio,
80 reset_gpio_pin: reset_gpio_pin,
81 i2c_slave_address: i2c_slave_address,
85 pub fn init(&mut self) {
86 let init_sequence : [u8; 18] = [
107 gpio::clear(self.reset_gpio, self.reset_gpio_pin);
109 gpio::set(self.reset_gpio, self.reset_gpio_pin);
112 for &b in init_sequence.iter() {
113 self.write_command(b);
117 pub fn clear(&mut self) {
120 for _ in 0..(32 * 128) {
121 self.write_data(0x00);
125 pub fn draw(&mut self, screen: &screen::Screen) {
126 let mut mask : u8 = 0x80;
128 for col in 0..screen::WIDTH_PX {
129 mask = mask.rotate_left(1);
131 // Rotate by 90 degrees.
133 // Also skip special columns 0..8 which we don't consider
134 // to be part of the screen (they hold the icon area).
135 self.seek(screen::WIDTH_PX - 1 - col, 9);
137 // We'll draw eight pixels at once.
138 for row in 0..(screen::HEIGHT_PX / 8) {
139 let mut combined = 0;
142 let index = ((row as usize * 8) + sub) * screen::WIDTH_BYTES
143 + (col as usize / 8);
144 let pixel = screen.pixel(index);
148 if (pixel & mask) != 0 {
153 self.write_data(combined);
158 fn write_command(&self, c: u8) {
159 i2c::tx16(i2c::I2C0, self.i2c_slave_address, 0x80 | ((c as u16) << 8));
163 fn write_data(&self, d: u8) {
164 i2c::tx16(i2c::I2C0, self.i2c_slave_address, 0xc0 | ((d as u16) << 8));
168 fn seek(&self, row: usize, col: usize) {
169 self.write_command(0x00 | ((row >> 0) & 0x0f) as u8);
170 self.write_command(0x10 | ((row >> 4) & 0x07) as u8);
171 self.write_command(0xc0 | ((col >> 0) & 0x1f) as u8);