1extern crate i2cdev;
2
3use std;
4use std::time::Duration;
5use super::devices::I2CMasterDevice;
6
7const NUM_LEDS: usize = 16;
8
9type LedVec = [bool; NUM_LEDS];
10
11static LED_ADDRESSES : [u8; NUM_LEDS] = [
12 0x3A, 0x37, 0x35, 0x34,
13 0x28, 0x29, 0x23, 0x24,
14 0x16, 0x1B, 0x11, 0x10,
15 0x0E, 0x0D, 0x0C, 0x02
16];
17
18static BUTTON_ADDRESSES : [u8; NUM_LEDS] = [
19 0x07, 0x04, 0x02, 0x22,
20 0x05, 0x06, 0x00, 0x01,
21 0x03, 0x10, 0x30, 0x21,
22 0x13, 0x12, 0x11, 0x31
23];
24
25#[derive(PartialEq, Debug, Copy, Clone)]
28pub enum Col {
29 A, B, C, D
30}
31
32#[derive(PartialEq, Debug, Copy, Clone)]
35pub enum Row {
36 R0, R1, R2, R3
37}
38
39#[derive(PartialEq, Debug, Copy, Clone)]
43pub struct LedButton {
44 pub col: Col,
45 pub row: Row
46}
47
48#[derive(Debug)]
54pub struct ButtonEvent {
55 pub buttons_pressed: Vec<LedButton>
56}
57
58
59impl ButtonEvent {
60 pub fn empty() -> ButtonEvent {
62 return ButtonEvent{buttons_pressed: vec![]}
63 }
64}
65
66pub type EventLoopHandler = Box<FnMut(&mut Trellis, ButtonEvent) -> bool>;
68
69fn row_to_num(row: Row) -> u8 {
72 match row {
73 Row::R0 => 0,
74 Row::R1 => 1,
75 Row::R2 => 2,
76 Row::R3 => 3
77 }
78}
79
80fn num_to_row(num: usize) -> Row {
81 match num {
82 0 => Row::R0,
83 1 => Row::R1,
84 2 => Row::R2,
85 3 => Row::R3,
86 _ => panic!("illegal row")
87 }
88}
89
90fn col_to_num(col: Col) -> u8 {
91 match col {
92 Col::A => 0,
93 Col::B => 1,
94 Col::C => 2,
95 Col::D => 3,
96 }
97}
98
99fn num_to_col(num: usize) -> Col {
100 match num {
101 0 => Col::A,
102 1 => Col::B,
103 2 => Col::C,
104 3 => Col::D,
105 _ => panic!("illegal column")
106 }
107}
108
109fn num_to_led_button(num: usize) -> LedButton {
110 let col_num = num % 4;
111 let row_num = num / 4;
112 return LedButton{col: num_to_col(col_num), row: num_to_row(row_num)};
113}
114
115fn led_index(col:Col, row:Row) -> usize {
116 return (row_to_num(row)*4 + col_to_num(col)) as usize;
117}
118
119fn to_button_state(dev_data: Vec<u8>) -> LedVec {
120 let mut result = [false; NUM_LEDS];
121 for i in 0..NUM_LEDS {
122 let addr = BUTTON_ADDRESSES[i];
123 result[i] = (dev_data[(addr >> 4) as usize] & (1 << (addr & 0x0F))) > 0;
124 }
125 return result;
126}
127
128fn button_event(old: LedVec, new: LedVec) -> ButtonEvent {
129 let mut pressed = Vec::new();
130 for i in 0..NUM_LEDS {
131 if new[i] && !old[i] {
132 pressed.push(num_to_led_button(i));
133 }
134 }
135 return ButtonEvent{buttons_pressed:pressed};
136}
137
138pub struct Trellis {
142 display_buffer: LedVec,
143 button_state: LedVec,
144 device : Box<I2CMasterDevice>
145}
146
147impl Trellis {
148
149 pub fn new(dev: Box<I2CMasterDevice>) -> Trellis {
156 return Trellis { display_buffer: [false; NUM_LEDS],
157 button_state: [false; NUM_LEDS],
158 device: dev};
159 }
160
161 pub fn init(&mut self) {
164 let empty_array:[u8;0] = [];
165 self.device.write_block(0x21, &empty_array).unwrap();
166 self.device.write_block(0x80 | 0x01 | 0 << 1, &empty_array).unwrap();
168 self.device.write_block(0xE0 | 15, &empty_array).unwrap();
170 self.device.write_block(0xA1, &empty_array).unwrap();
172 }
173
174 pub fn set_led(&mut self, col:Col, row: Row) {
176 self.display_buffer[led_index(col, row)] = true;
177 }
178
179 pub fn clear_led(&mut self, col:Col, row:Row) {
181 self.display_buffer[led_index(col, row)] = false;
182 }
183
184 pub fn is_led_set(&mut self, col:Col, row: Row) -> bool {
188 return self.display_buffer[led_index(col, row)];
189 }
190
191 pub fn write_display(&mut self) {
195 let mut data:[u16; 8] = [0; 8];
196 for l in 0..NUM_LEDS {
197 let led_addr = LED_ADDRESSES[l];
198 if self.display_buffer[l] {
199 data[(led_addr >> 4) as usize] |= 1 << (led_addr & 0x0F);
200 } else {
201 data[(led_addr >> 4) as usize] &= !(1 << (led_addr & 0x0F));
202 }
203 }
204
205 let mut w:[u8; 16] = [0; 16];
206 for i in 0..8 {
207 w[i*2] = (data[i] & 0xFF) as u8;
208 w[i*2+1] = (data[i] >> 8) as u8;
209 }
210
211 self.device.write_block(0x0, &w).unwrap();
212 }
213
214 pub fn button_evt_loop(&mut self, mut hnd: EventLoopHandler) {
218 loop {
219 let new_button_state = to_button_state(self.device.read_block(0x40, 6).unwrap());
220 let event = button_event(self.button_state, new_button_state);
221
222 self.button_state = new_button_state;
223
224 let handler_result = hnd(self, event);
225 if handler_result {
226 break;
227 }
228 std::thread::sleep(Duration::from_millis(30));
229 }
230 }
231}