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,
48 let x = ptr::read_volatile(&r);
49 ptr::write_volatile(&mut r, x - 1);
58 let x = ptr::read_volatile(&a);
59 ptr::write_volatile(&mut a, x + 1);
74 let x = ptr::read_volatile(&r);
75 ptr::write_volatile(&mut r, x - 1);
84 const ICON_COLUMN: usize = 8;
87 pub fn new(reset_gpio: u32, reset_gpio_pin: u32, i2c_slave_address: u8) -> Display {
89 reset_gpio: reset_gpio,
90 reset_gpio_pin: reset_gpio_pin,
91 i2c_slave_address: i2c_slave_address,
95 pub fn init(&mut self) {
96 let init_sequence : [u8; 18] = [
117 gpio::clear(self.reset_gpio, self.reset_gpio_pin);
119 gpio::set(self.reset_gpio, self.reset_gpio_pin);
122 for &b in init_sequence.iter() {
123 self.write_command(b);
127 fn icon_row(&self, icon: Icon) -> usize {
129 Icon::SatelliteBody => 31,
130 Icon::SatelliteWave1 => 29,
131 Icon::SatelliteWave2 => 27,
137 pub fn show_icon(&mut self, icon: Icon) {
138 let row = self.icon_row(icon);
140 self.seek(row, ICON_COLUMN);
141 self.write_data(0x80);
144 pub fn hide_icon(&mut self, icon: Icon) {
145 let row = self.icon_row(icon);
147 self.seek(row, ICON_COLUMN);
148 self.write_data(0x00);
151 pub fn clear(&mut self) {
154 for _ in 0..(32 * 128) {
155 self.write_data(0x00);
159 pub fn draw(&mut self, screen: &screen::Screen) {
160 let mut mask : u8 = 0x01;
162 for col in 0..screen::WIDTH_PX {
163 mask = mask.rotate_right(1);
165 // Rotate by 90 degrees.
167 // Also skip special columns 0..8 which we don't consider
168 // to be part of the screen (they hold the icon area).
169 self.seek(screen::WIDTH_PX - 1 - col, 9);
171 // We'll draw eight pixels at once.
172 for row in 0..(screen::HEIGHT_PX / 8) {
173 let mut combined = 0;
176 let index = ((row as usize * 8) + sub) * screen::WIDTH_BYTES
177 + (col as usize / 8);
178 let pixel = screen.pixel(index);
182 if (pixel & mask) != 0 {
187 self.write_data(combined);
192 fn write_command(&self, c: u8) {
193 i2c::tx16(i2c::I2C0, self.i2c_slave_address, 0x80 | ((c as u16) << 8));
197 fn write_data(&self, d: u8) {
198 i2c::tx16(i2c::I2C0, self.i2c_slave_address, 0xc0 | ((d as u16) << 8));
202 fn seek(&self, row: usize, col: usize) {
203 self.write_command(0x00 | ((row >> 0) & 0x0f) as u8);
204 self.write_command(0x10 | ((row >> 4) & 0x07) as u8);
205 self.write_command(0xc0 | ((col >> 0) & 0x1f) as u8);