diff options
-rw-r--r-- | keyboards/lets_split/common/glcdfont.c | 276 | ||||
-rw-r--r-- | keyboards/lets_split/i2c.c | 94 | ||||
-rw-r--r-- | keyboards/lets_split/i2c.h | 20 | ||||
-rw-r--r-- | keyboards/lets_split/matrix.c | 7 | ||||
-rw-r--r-- | keyboards/lets_split/rules.mk | 15 | ||||
-rw-r--r-- | keyboards/lets_split/split_util.c | 7 | ||||
-rw-r--r-- | keyboards/lets_split/split_util.h | 2 | ||||
-rw-r--r-- | keyboards/lets_split/ssd1306.c | 508 |
8 files changed, 908 insertions, 21 deletions
diff --git a/keyboards/lets_split/common/glcdfont.c b/keyboards/lets_split/common/glcdfont.c new file mode 100644 index 000000000..6f88bd23a --- /dev/null +++ b/keyboards/lets_split/common/glcdfont.c | |||
@@ -0,0 +1,276 @@ | |||
1 | // This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0. | ||
2 | // See gfxfont.h for newer custom bitmap font info. | ||
3 | |||
4 | #ifndef FONT5X7_H | ||
5 | #define FONT5X7_H | ||
6 | |||
7 | #ifdef __AVR__ | ||
8 | #include <avr/io.h> | ||
9 | #include <avr/pgmspace.h> | ||
10 | #elif defined(ESP8266) | ||
11 | #include <pgmspace.h> | ||
12 | #else | ||
13 | #define PROGMEM | ||
14 | #endif | ||
15 | |||
16 | // Standard ASCII 5x7 font | ||
17 | |||
18 | static const unsigned char font[] PROGMEM = { | ||
19 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
20 | 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, | ||
21 | 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, | ||
22 | 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, | ||
23 | 0x18, 0x3C, 0x7E, 0x3C, 0x18, | ||
24 | 0x1C, 0x57, 0x7D, 0x57, 0x1C, | ||
25 | 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, | ||
26 | 0x00, 0x18, 0x3C, 0x18, 0x00, | ||
27 | 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, | ||
28 | 0x00, 0x18, 0x24, 0x18, 0x00, | ||
29 | 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, | ||
30 | 0x30, 0x48, 0x3A, 0x06, 0x0E, | ||
31 | 0x26, 0x29, 0x79, 0x29, 0x26, | ||
32 | 0x40, 0x7F, 0x05, 0x05, 0x07, | ||
33 | 0x40, 0x7F, 0x05, 0x25, 0x3F, | ||
34 | 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, | ||
35 | 0x7F, 0x3E, 0x1C, 0x1C, 0x08, | ||
36 | 0x08, 0x1C, 0x1C, 0x3E, 0x7F, | ||
37 | 0x14, 0x22, 0x7F, 0x22, 0x14, | ||
38 | 0x5F, 0x5F, 0x00, 0x5F, 0x5F, | ||
39 | 0x06, 0x09, 0x7F, 0x01, 0x7F, | ||
40 | 0x00, 0x66, 0x89, 0x95, 0x6A, | ||
41 | 0x60, 0x60, 0x60, 0x60, 0x60, | ||
42 | 0x94, 0xA2, 0xFF, 0xA2, 0x94, | ||
43 | 0x08, 0x04, 0x7E, 0x04, 0x08, | ||
44 | 0x10, 0x20, 0x7E, 0x20, 0x10, | ||
45 | 0x08, 0x08, 0x2A, 0x1C, 0x08, | ||
46 | 0x08, 0x1C, 0x2A, 0x08, 0x08, | ||
47 | 0x1E, 0x10, 0x10, 0x10, 0x10, | ||
48 | 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, | ||
49 | 0x30, 0x38, 0x3E, 0x38, 0x30, | ||
50 | 0x06, 0x0E, 0x3E, 0x0E, 0x06, | ||
51 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
52 | 0x00, 0x00, 0x5F, 0x00, 0x00, | ||
53 | 0x00, 0x07, 0x00, 0x07, 0x00, | ||
54 | 0x14, 0x7F, 0x14, 0x7F, 0x14, | ||
55 | 0x24, 0x2A, 0x7F, 0x2A, 0x12, | ||
56 | 0x23, 0x13, 0x08, 0x64, 0x62, | ||
57 | 0x36, 0x49, 0x56, 0x20, 0x50, | ||
58 | 0x00, 0x08, 0x07, 0x03, 0x00, | ||
59 | 0x00, 0x1C, 0x22, 0x41, 0x00, | ||
60 | 0x00, 0x41, 0x22, 0x1C, 0x00, | ||
61 | 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, | ||
62 | 0x08, 0x08, 0x3E, 0x08, 0x08, | ||
63 | 0x00, 0x80, 0x70, 0x30, 0x00, | ||
64 | 0x08, 0x08, 0x08, 0x08, 0x08, | ||
65 | 0x00, 0x00, 0x60, 0x60, 0x00, | ||
66 | 0x20, 0x10, 0x08, 0x04, 0x02, | ||
67 | 0x3E, 0x51, 0x49, 0x45, 0x3E, | ||
68 | 0x00, 0x42, 0x7F, 0x40, 0x00, | ||
69 | 0x72, 0x49, 0x49, 0x49, 0x46, | ||
70 | 0x21, 0x41, 0x49, 0x4D, 0x33, | ||
71 | 0x18, 0x14, 0x12, 0x7F, 0x10, | ||
72 | 0x27, 0x45, 0x45, 0x45, 0x39, | ||
73 | 0x3C, 0x4A, 0x49, 0x49, 0x31, | ||
74 | 0x41, 0x21, 0x11, 0x09, 0x07, | ||
75 | 0x36, 0x49, 0x49, 0x49, 0x36, | ||
76 | 0x46, 0x49, 0x49, 0x29, 0x1E, | ||
77 | 0x00, 0x00, 0x14, 0x00, 0x00, | ||
78 | 0x00, 0x40, 0x34, 0x00, 0x00, | ||
79 | 0x00, 0x08, 0x14, 0x22, 0x41, | ||
80 | 0x14, 0x14, 0x14, 0x14, 0x14, | ||
81 | 0x00, 0x41, 0x22, 0x14, 0x08, | ||
82 | 0x02, 0x01, 0x59, 0x09, 0x06, | ||
83 | 0x3E, 0x41, 0x5D, 0x59, 0x4E, | ||
84 | 0x7C, 0x12, 0x11, 0x12, 0x7C, | ||
85 | 0x7F, 0x49, 0x49, 0x49, 0x36, | ||
86 | 0x3E, 0x41, 0x41, 0x41, 0x22, | ||
87 | 0x7F, 0x41, 0x41, 0x41, 0x3E, | ||
88 | 0x7F, 0x49, 0x49, 0x49, 0x41, | ||
89 | 0x7F, 0x09, 0x09, 0x09, 0x01, | ||
90 | 0x3E, 0x41, 0x41, 0x51, 0x73, | ||
91 | 0x7F, 0x08, 0x08, 0x08, 0x7F, | ||
92 | 0x00, 0x41, 0x7F, 0x41, 0x00, | ||
93 | 0x20, 0x40, 0x41, 0x3F, 0x01, | ||
94 | 0x7F, 0x08, 0x14, 0x22, 0x41, | ||
95 | 0x7F, 0x40, 0x40, 0x40, 0x40, | ||
96 | 0x7F, 0x02, 0x1C, 0x02, 0x7F, | ||
97 | 0x7F, 0x04, 0x08, 0x10, 0x7F, | ||
98 | 0x3E, 0x41, 0x41, 0x41, 0x3E, | ||
99 | 0x7F, 0x09, 0x09, 0x09, 0x06, | ||
100 | 0x3E, 0x41, 0x51, 0x21, 0x5E, | ||
101 | 0x7F, 0x09, 0x19, 0x29, 0x46, | ||
102 | 0x26, 0x49, 0x49, 0x49, 0x32, | ||
103 | 0x03, 0x01, 0x7F, 0x01, 0x03, | ||
104 | 0x3F, 0x40, 0x40, 0x40, 0x3F, | ||
105 | 0x1F, 0x20, 0x40, 0x20, 0x1F, | ||
106 | 0x3F, 0x40, 0x38, 0x40, 0x3F, | ||
107 | 0x63, 0x14, 0x08, 0x14, 0x63, | ||
108 | 0x03, 0x04, 0x78, 0x04, 0x03, | ||
109 | 0x61, 0x59, 0x49, 0x4D, 0x43, | ||
110 | 0x00, 0x7F, 0x41, 0x41, 0x41, | ||
111 | 0x02, 0x04, 0x08, 0x10, 0x20, | ||
112 | 0x00, 0x41, 0x41, 0x41, 0x7F, | ||
113 | 0x04, 0x02, 0x01, 0x02, 0x04, | ||
114 | 0x40, 0x40, 0x40, 0x40, 0x40, | ||
115 | 0x00, 0x03, 0x07, 0x08, 0x00, | ||
116 | 0x20, 0x54, 0x54, 0x78, 0x40, | ||
117 | 0x7F, 0x28, 0x44, 0x44, 0x38, | ||
118 | 0x38, 0x44, 0x44, 0x44, 0x28, | ||
119 | 0x38, 0x44, 0x44, 0x28, 0x7F, | ||
120 | 0x38, 0x54, 0x54, 0x54, 0x18, | ||
121 | 0x00, 0x08, 0x7E, 0x09, 0x02, | ||
122 | 0x18, 0xA4, 0xA4, 0x9C, 0x78, | ||
123 | 0x7F, 0x08, 0x04, 0x04, 0x78, | ||
124 | 0x00, 0x44, 0x7D, 0x40, 0x00, | ||
125 | 0x20, 0x40, 0x40, 0x3D, 0x00, | ||
126 | 0x7F, 0x10, 0x28, 0x44, 0x00, | ||
127 | 0x00, 0x41, 0x7F, 0x40, 0x00, | ||
128 | 0x7C, 0x04, 0x78, 0x04, 0x78, | ||
129 | 0x7C, 0x08, 0x04, 0x04, 0x78, | ||
130 | 0x38, 0x44, 0x44, 0x44, 0x38, | ||
131 | 0xFC, 0x18, 0x24, 0x24, 0x18, | ||
132 | 0x18, 0x24, 0x24, 0x18, 0xFC, | ||
133 | 0x7C, 0x08, 0x04, 0x04, 0x08, | ||
134 | 0x48, 0x54, 0x54, 0x54, 0x24, | ||
135 | 0x04, 0x04, 0x3F, 0x44, 0x24, | ||
136 | 0x3C, 0x40, 0x40, 0x20, 0x7C, | ||
137 | 0x1C, 0x20, 0x40, 0x20, 0x1C, | ||
138 | 0x3C, 0x40, 0x30, 0x40, 0x3C, | ||
139 | 0x44, 0x28, 0x10, 0x28, 0x44, | ||
140 | 0x4C, 0x90, 0x90, 0x90, 0x7C, | ||
141 | 0x44, 0x64, 0x54, 0x4C, 0x44, | ||
142 | 0x00, 0x08, 0x36, 0x41, 0x00, | ||
143 | 0x00, 0x00, 0x77, 0x00, 0x00, | ||
144 | 0x00, 0x41, 0x36, 0x08, 0x00, | ||
145 | 0x02, 0x01, 0x02, 0x04, 0x02, | ||
146 | 0x3C, 0x26, 0x23, 0x26, 0x3C, | ||
147 | 0x1E, 0xA1, 0xA1, 0x61, 0x12, | ||
148 | 0x3A, 0x40, 0x40, 0x20, 0x7A, | ||
149 | 0x38, 0x54, 0x54, 0x55, 0x59, | ||
150 | 0x21, 0x55, 0x55, 0x79, 0x41, | ||
151 | 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut | ||
152 | 0x21, 0x55, 0x54, 0x78, 0x40, | ||
153 | 0x20, 0x54, 0x55, 0x79, 0x40, | ||
154 | 0x0C, 0x1E, 0x52, 0x72, 0x12, | ||
155 | 0x39, 0x55, 0x55, 0x55, 0x59, | ||
156 | 0x39, 0x54, 0x54, 0x54, 0x59, | ||
157 | 0x39, 0x55, 0x54, 0x54, 0x58, | ||
158 | 0x00, 0x00, 0x45, 0x7C, 0x41, | ||
159 | 0x00, 0x02, 0x45, 0x7D, 0x42, | ||
160 | 0x00, 0x01, 0x45, 0x7C, 0x40, | ||
161 | 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut | ||
162 | 0xF0, 0x28, 0x25, 0x28, 0xF0, | ||
163 | 0x7C, 0x54, 0x55, 0x45, 0x00, | ||
164 | 0x20, 0x54, 0x54, 0x7C, 0x54, | ||
165 | 0x7C, 0x0A, 0x09, 0x7F, 0x49, | ||
166 | 0x32, 0x49, 0x49, 0x49, 0x32, | ||
167 | 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut | ||
168 | 0x32, 0x4A, 0x48, 0x48, 0x30, | ||
169 | 0x3A, 0x41, 0x41, 0x21, 0x7A, | ||
170 | 0x3A, 0x42, 0x40, 0x20, 0x78, | ||
171 | 0x00, 0x9D, 0xA0, 0xA0, 0x7D, | ||
172 | 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut | ||
173 | 0x3D, 0x40, 0x40, 0x40, 0x3D, | ||
174 | 0x3C, 0x24, 0xFF, 0x24, 0x24, | ||
175 | 0x48, 0x7E, 0x49, 0x43, 0x66, | ||
176 | 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, | ||
177 | 0xFF, 0x09, 0x29, 0xF6, 0x20, | ||
178 | 0xC0, 0x88, 0x7E, 0x09, 0x03, | ||
179 | 0x20, 0x54, 0x54, 0x79, 0x41, | ||
180 | 0x00, 0x00, 0x44, 0x7D, 0x41, | ||
181 | 0x30, 0x48, 0x48, 0x4A, 0x32, | ||
182 | 0x38, 0x40, 0x40, 0x22, 0x7A, | ||
183 | 0x00, 0x7A, 0x0A, 0x0A, 0x72, | ||
184 | 0x7D, 0x0D, 0x19, 0x31, 0x7D, | ||
185 | 0x26, 0x29, 0x29, 0x2F, 0x28, | ||
186 | 0x26, 0x29, 0x29, 0x29, 0x26, | ||
187 | 0x30, 0x48, 0x4D, 0x40, 0x20, | ||
188 | 0x38, 0x08, 0x08, 0x08, 0x08, | ||
189 | 0x08, 0x08, 0x08, 0x08, 0x38, | ||
190 | 0x2F, 0x10, 0xC8, 0xAC, 0xBA, | ||
191 | 0x2F, 0x10, 0x28, 0x34, 0xFA, | ||
192 | 0x00, 0x00, 0x7B, 0x00, 0x00, | ||
193 | 0x08, 0x14, 0x2A, 0x14, 0x22, | ||
194 | 0x22, 0x14, 0x2A, 0x14, 0x08, | ||
195 | 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code | ||
196 | 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block | ||
197 | 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block | ||
198 | 0x00, 0x00, 0x00, 0xFF, 0x00, | ||
199 | 0x10, 0x10, 0x10, 0xFF, 0x00, | ||
200 | 0x14, 0x14, 0x14, 0xFF, 0x00, | ||
201 | 0x10, 0x10, 0xFF, 0x00, 0xFF, | ||
202 | 0x10, 0x10, 0xF0, 0x10, 0xF0, | ||
203 | 0x14, 0x14, 0x14, 0xFC, 0x00, | ||
204 | 0x14, 0x14, 0xF7, 0x00, 0xFF, | ||
205 | 0x00, 0x00, 0xFF, 0x00, 0xFF, | ||
206 | 0x14, 0x14, 0xF4, 0x04, 0xFC, | ||
207 | 0x14, 0x14, 0x17, 0x10, 0x1F, | ||
208 | 0x10, 0x10, 0x1F, 0x10, 0x1F, | ||
209 | 0x14, 0x14, 0x14, 0x1F, 0x00, | ||
210 | 0x10, 0x10, 0x10, 0xF0, 0x00, | ||
211 | 0x00, 0x00, 0x00, 0x1F, 0x10, | ||
212 | 0x10, 0x10, 0x10, 0x1F, 0x10, | ||
213 | 0x10, 0x10, 0x10, 0xF0, 0x10, | ||
214 | 0x00, 0x00, 0x00, 0xFF, 0x10, | ||
215 | 0x10, 0x10, 0x10, 0x10, 0x10, | ||
216 | 0x10, 0x10, 0x10, 0xFF, 0x10, | ||
217 | 0x00, 0x00, 0x00, 0xFF, 0x14, | ||
218 | 0x00, 0x00, 0xFF, 0x00, 0xFF, | ||
219 | 0x00, 0x00, 0x1F, 0x10, 0x17, | ||
220 | 0x00, 0x00, 0xFC, 0x04, 0xF4, | ||
221 | 0x14, 0x14, 0x17, 0x10, 0x17, | ||
222 | 0x14, 0x14, 0xF4, 0x04, 0xF4, | ||
223 | 0x00, 0x00, 0xFF, 0x00, 0xF7, | ||
224 | 0x14, 0x14, 0x14, 0x14, 0x14, | ||
225 | 0x14, 0x14, 0xF7, 0x00, 0xF7, | ||
226 | 0x14, 0x14, 0x14, 0x17, 0x14, | ||
227 | 0x10, 0x10, 0x1F, 0x10, 0x1F, | ||
228 | 0x14, 0x14, 0x14, 0xF4, 0x14, | ||
229 | 0x10, 0x10, 0xF0, 0x10, 0xF0, | ||
230 | 0x00, 0x00, 0x1F, 0x10, 0x1F, | ||
231 | 0x00, 0x00, 0x00, 0x1F, 0x14, | ||
232 | 0x00, 0x00, 0x00, 0xFC, 0x14, | ||
233 | 0x00, 0x00, 0xF0, 0x10, 0xF0, | ||
234 | 0x10, 0x10, 0xFF, 0x10, 0xFF, | ||
235 | 0x14, 0x14, 0x14, 0xFF, 0x14, | ||
236 | 0x10, 0x10, 0x10, 0x1F, 0x00, | ||
237 | 0x00, 0x00, 0x00, 0xF0, 0x10, | ||
238 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
239 | 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, | ||
240 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, | ||
241 | 0x00, 0x00, 0x00, 0xFF, 0xFF, | ||
242 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, | ||
243 | 0x38, 0x44, 0x44, 0x38, 0x44, | ||
244 | 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta | ||
245 | 0x7E, 0x02, 0x02, 0x06, 0x06, | ||
246 | 0x02, 0x7E, 0x02, 0x7E, 0x02, | ||
247 | 0x63, 0x55, 0x49, 0x41, 0x63, | ||
248 | 0x38, 0x44, 0x44, 0x3C, 0x04, | ||
249 | 0x40, 0x7E, 0x20, 0x1E, 0x20, | ||
250 | 0x06, 0x02, 0x7E, 0x02, 0x02, | ||
251 | 0x99, 0xA5, 0xE7, 0xA5, 0x99, | ||
252 | 0x1C, 0x2A, 0x49, 0x2A, 0x1C, | ||
253 | 0x4C, 0x72, 0x01, 0x72, 0x4C, | ||
254 | 0x30, 0x4A, 0x4D, 0x4D, 0x30, | ||
255 | 0x30, 0x48, 0x78, 0x48, 0x30, | ||
256 | 0xBC, 0x62, 0x5A, 0x46, 0x3D, | ||
257 | 0x3E, 0x49, 0x49, 0x49, 0x00, | ||
258 | 0x7E, 0x01, 0x01, 0x01, 0x7E, | ||
259 | 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, | ||
260 | 0x44, 0x44, 0x5F, 0x44, 0x44, | ||
261 | 0x40, 0x51, 0x4A, 0x44, 0x40, | ||
262 | 0x40, 0x44, 0x4A, 0x51, 0x40, | ||
263 | 0x00, 0x00, 0xFF, 0x01, 0x03, | ||
264 | 0xE0, 0x80, 0xFF, 0x00, 0x00, | ||
265 | 0x08, 0x08, 0x6B, 0x6B, 0x08, | ||
266 | 0x36, 0x12, 0x36, 0x24, 0x36, | ||
267 | 0x06, 0x0F, 0x09, 0x0F, 0x06, | ||
268 | 0x00, 0x00, 0x18, 0x18, 0x00, | ||
269 | 0x00, 0x00, 0x10, 0x10, 0x00, | ||
270 | 0x30, 0x40, 0xFF, 0x01, 0x01, | ||
271 | 0x00, 0x1F, 0x01, 0x01, 0x1E, | ||
272 | 0x00, 0x19, 0x1D, 0x17, 0x12, | ||
273 | 0x00, 0x3C, 0x3C, 0x3C, 0x3C, | ||
274 | 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP | ||
275 | }; | ||
276 | #endif // FONT5X7_H | ||
diff --git a/keyboards/lets_split/i2c.c b/keyboards/lets_split/i2c.c index 084c890c4..038f37a4b 100644 --- a/keyboards/lets_split/i2c.c +++ b/keyboards/lets_split/i2c.c | |||
@@ -48,7 +48,7 @@ void i2c_master_init(void) { | |||
48 | // returns: 0 => success | 48 | // returns: 0 => success |
49 | // 1 => error | 49 | // 1 => error |
50 | uint8_t i2c_master_start(uint8_t address) { | 50 | uint8_t i2c_master_start(uint8_t address) { |
51 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA); | 51 | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); |
52 | 52 | ||
53 | i2c_delay(); | 53 | i2c_delay(); |
54 | 54 | ||
@@ -56,6 +56,7 @@ uint8_t i2c_master_start(uint8_t address) { | |||
56 | if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) | 56 | if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) |
57 | return 1; | 57 | return 1; |
58 | 58 | ||
59 | // send device address | ||
59 | TWDR = address; | 60 | TWDR = address; |
60 | TWCR = (1<<TWINT) | (1<<TWEN); | 61 | TWCR = (1<<TWINT) | (1<<TWEN); |
61 | 62 | ||
@@ -159,4 +160,95 @@ ISR(TWI_vect) { | |||
159 | // Reset everything, so we are ready for the next TWI interrupt | 160 | // Reset everything, so we are ready for the next TWI interrupt |
160 | TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); | 161 | TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); |
161 | } | 162 | } |
163 | |||
164 | // from SSD1306 | ||
165 | /* | ||
166 | void i2c_start_wait(unsigned char address) | ||
167 | { | ||
168 | uint8_t twst; | ||
169 | |||
170 | |||
171 | while ( 1 ) | ||
172 | { | ||
173 | // send START condition | ||
174 | TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); | ||
175 | |||
176 | // wait until transmission completed | ||
177 | while(!(TWCR & (1<<TWINT))); | ||
178 | |||
179 | // check value of TWI Status Register. Mask prescaler bits. | ||
180 | twst = TW_STATUS & 0xF8; | ||
181 | if ( (twst != TW_START) && (twst != TW_REP_START)) continue; | ||
182 | |||
183 | // send device address | ||
184 | TWDR = address; | ||
185 | TWCR = (1<<TWINT) | (1<<TWEN); | ||
186 | |||
187 | // wail until transmission completed | ||
188 | while(!(TWCR & (1<<TWINT))); | ||
189 | |||
190 | // check value of TWI Status Register. Mask prescaler bits. | ||
191 | twst = TW_STATUS & 0xF8; | ||
192 | if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) | ||
193 | { | ||
194 | // device busy, send stop condition to terminate write operation | ||
195 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); | ||
196 | |||
197 | // wait until stop condition is executed and bus released | ||
198 | while(TWCR & (1<<TWSTO)); | ||
199 | |||
200 | continue; | ||
201 | } | ||
202 | //if( twst != TW_MT_SLA_ACK) return 1; | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | }// i2c_start_wait | ||
207 | */ | ||
208 | /************************************************************************* | ||
209 | Issues a repeated start condition and sends address and transfer direction | ||
210 | |||
211 | Input: address and transfer direction of I2C device | ||
212 | |||
213 | Return: 0 device accessible | ||
214 | 1 failed to access device | ||
215 | *************************************************************************/ | ||
216 | /* | ||
217 | unsigned char i2c_rep_start(unsigned char address) | ||
218 | { | ||
219 | return i2c_master_start( address ); | ||
220 | |||
221 | }/* i2c_rep_start */ | ||
222 | /************************************************************************* | ||
223 | Read one byte from the I2C device, request more data from device | ||
224 | |||
225 | Return: byte read from I2C device | ||
226 | *************************************************************************/ | ||
227 | /* | ||
228 | unsigned char i2c_readAck(void) | ||
229 | { | ||
230 | TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); | ||
231 | while(!(TWCR & (1<<TWINT))); | ||
232 | |||
233 | return TWDR; | ||
234 | |||
235 | }/* i2c_readAck */ | ||
236 | |||
237 | |||
238 | /************************************************************************* | ||
239 | Read one byte from the I2C device, read is followed by a stop condition | ||
240 | |||
241 | Return: byte read from I2C device | ||
242 | ************************************************************************* | ||
243 | unsigned char i2c_readNak(void) | ||
244 | { | ||
245 | TWCR = (1<<TWINT) | (1<<TWEN); | ||
246 | while(!(TWCR & (1<<TWINT))); | ||
247 | |||
248 | return TWDR; | ||
249 | |||
250 | }/* i2c_readNak */ | ||
251 | |||
252 | |||
253 | |||
162 | #endif | 254 | #endif |
diff --git a/keyboards/lets_split/i2c.h b/keyboards/lets_split/i2c.h index 08ce4b009..c15b6bc50 100644 --- a/keyboards/lets_split/i2c.h +++ b/keyboards/lets_split/i2c.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define SLAVE_BUFFER_SIZE 0x10 | 16 | #define SLAVE_BUFFER_SIZE 0x10 |
17 | 17 | ||
18 | // i2c SCL clock frequency | 18 | // i2c SCL clock frequency |
19 | #define SCL_CLOCK 100000L | 19 | #define SCL_CLOCK 400000L |
20 | 20 | ||
21 | extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; | 21 | extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; |
22 | 22 | ||
@@ -28,4 +28,22 @@ uint8_t i2c_master_read(int); | |||
28 | void i2c_reset_state(void); | 28 | void i2c_reset_state(void); |
29 | void i2c_slave_init(uint8_t address); | 29 | void i2c_slave_init(uint8_t address); |
30 | 30 | ||
31 | |||
32 | static inline unsigned char i2c_start_read(unsigned char addr) { | ||
33 | return i2c_master_start((addr << 1) | I2C_READ); | ||
34 | } | ||
35 | |||
36 | static inline unsigned char i2c_start_write(unsigned char addr) { | ||
37 | return i2c_master_start((addr << 1) | I2C_WRITE); | ||
38 | } | ||
39 | |||
40 | // from SSD1306 scrips | ||
41 | extern unsigned char i2c_rep_start(unsigned char addr); | ||
42 | extern void i2c_start_wait(unsigned char addr); | ||
43 | extern unsigned char i2c_readAck(void); | ||
44 | extern unsigned char i2c_readNak(void); | ||
45 | extern unsigned char i2c_read(unsigned char ack); | ||
46 | |||
47 | #define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); | ||
48 | |||
31 | #endif | 49 | #endif |
diff --git a/keyboards/lets_split/matrix.c b/keyboards/lets_split/matrix.c index 138969004..b6e59cb7f 100644 --- a/keyboards/lets_split/matrix.c +++ b/keyboards/lets_split/matrix.c | |||
@@ -210,8 +210,9 @@ uint8_t matrix_scan(void) | |||
210 | if( serial_transaction() ) { | 210 | if( serial_transaction() ) { |
211 | #endif | 211 | #endif |
212 | // turn on the indicator led when halves are disconnected | 212 | // turn on the indicator led when halves are disconnected |
213 | TXLED1; | 213 | // TXLED1; |
214 | 214 | TXLED0; | |
215 | |||
215 | error_count++; | 216 | error_count++; |
216 | 217 | ||
217 | if (error_count > ERROR_DISCONNECT_COUNT) { | 218 | if (error_count > ERROR_DISCONNECT_COUNT) { |
@@ -226,9 +227,7 @@ uint8_t matrix_scan(void) | |||
226 | TXLED0; | 227 | TXLED0; |
227 | error_count = 0; | 228 | error_count = 0; |
228 | } | 229 | } |
229 | |||
230 | matrix_scan_quantum(); | 230 | matrix_scan_quantum(); |
231 | |||
232 | return ret; | 231 | return ret; |
233 | } | 232 | } |
234 | 233 | ||
diff --git a/keyboards/lets_split/rules.mk b/keyboards/lets_split/rules.mk index 0efa78550..ff159e0f0 100644 --- a/keyboards/lets_split/rules.mk +++ b/keyboards/lets_split/rules.mk | |||
@@ -1,7 +1,8 @@ | |||
1 | SRC += matrix.c \ | 1 | SRC += matrix.c \ |
2 | i2c.c \ | 2 | i2c.c \ |
3 | split_util.c \ | 3 | split_util.c \ |
4 | serial.c | 4 | serial.c\ |
5 | ssd1306.c | ||
5 | 6 | ||
6 | # MCU name | 7 | # MCU name |
7 | #MCU = at90usb1287 | 8 | #MCU = at90usb1287 |
@@ -73,15 +74,3 @@ USE_I2C ?= yes | |||
73 | SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend | 74 | SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend |
74 | 75 | ||
75 | CUSTOM_MATRIX = yes | 76 | CUSTOM_MATRIX = yes |
76 | |||
77 | avrdude: build | ||
78 | ls /dev/tty* > /tmp/1; \ | ||
79 | echo "Reset your Pro Micro now"; \ | ||
80 | while [[ -z $$USB ]]; do \ | ||
81 | sleep 1; \ | ||
82 | ls /dev/tty* > /tmp/2; \ | ||
83 | USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \ | ||
84 | done; \ | ||
85 | avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex | ||
86 | |||
87 | .PHONY: avrdude | ||
diff --git a/keyboards/lets_split/split_util.c b/keyboards/lets_split/split_util.c index 226dc1881..b87bae38b 100644 --- a/keyboards/lets_split/split_util.c +++ b/keyboards/lets_split/split_util.c | |||
@@ -21,8 +21,8 @@ static void setup_handedness(void) { | |||
21 | #ifdef EE_HANDS | 21 | #ifdef EE_HANDS |
22 | isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); | 22 | isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS); |
23 | #else | 23 | #else |
24 | // I2C_MASTER_RIGHT is deprecated use MASTER_RIGHT instead since this works for both serial and i2c | 24 | // I2c_MASTER_RIGHT ish deprecate use MASTER_RIGHT instead since this works for both serial and i2c: |
25 | #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT) | 25 | #if defined (I2C_MASTER_RIGHT) || defined (MASTER_RIGHT) |
26 | isLeftHand = !has_usb(); | 26 | isLeftHand = !has_usb(); |
27 | #else | 27 | #else |
28 | isLeftHand = has_usb(); | 28 | isLeftHand = has_usb(); |
@@ -33,6 +33,9 @@ static void setup_handedness(void) { | |||
33 | static void keyboard_master_setup(void) { | 33 | static void keyboard_master_setup(void) { |
34 | #ifdef USE_I2C | 34 | #ifdef USE_I2C |
35 | i2c_master_init(); | 35 | i2c_master_init(); |
36 | #ifdef SSD1306OLED | ||
37 | matrix_master_OLED_init (); | ||
38 | #endif | ||
36 | #else | 39 | #else |
37 | serial_master_init(); | 40 | serial_master_init(); |
38 | #endif | 41 | #endif |
diff --git a/keyboards/lets_split/split_util.h b/keyboards/lets_split/split_util.h index 6b896679c..3ae76c209 100644 --- a/keyboards/lets_split/split_util.h +++ b/keyboards/lets_split/split_util.h | |||
@@ -19,4 +19,6 @@ void split_keyboard_setup(void); | |||
19 | bool has_usb(void); | 19 | bool has_usb(void); |
20 | void keyboard_slave_loop(void); | 20 | void keyboard_slave_loop(void); |
21 | 21 | ||
22 | void matrix_master_OLED_init (void); | ||
23 | |||
22 | #endif | 24 | #endif |
diff --git a/keyboards/lets_split/ssd1306.c b/keyboards/lets_split/ssd1306.c new file mode 100644 index 000000000..c25a355bf --- /dev/null +++ b/keyboards/lets_split/ssd1306.c | |||
@@ -0,0 +1,508 @@ | |||
1 | #include "config.h" | ||
2 | #include "i2c.h" | ||
3 | #include <stdbool.h> | ||
4 | #include <string.h> | ||
5 | #include <stdio.h> | ||
6 | #include "print.h" | ||
7 | #include "lets_split.h" | ||
8 | #include "common/glcdfont.c" | ||
9 | #ifdef ADAFRUIT_BLE_ENABLE | ||
10 | #include "adafruit_ble.h" | ||
11 | #endif | ||
12 | #ifdef PROTOCOL_LUFA | ||
13 | #include "lufa.h" | ||
14 | #endif | ||
15 | #include "sendchar.h" | ||
16 | #include "pincontrol.h" | ||
17 | |||
18 | //assign the right code to your layers | ||
19 | #define _BASE 0 | ||
20 | #define _LOWER 8 | ||
21 | #define _RAISE 16 | ||
22 | #define _FNLAYER 64 | ||
23 | #define _NUMLAY 128 | ||
24 | #define _NLOWER 136 | ||
25 | #define _NFNLAYER 192 | ||
26 | #define _MOUSECURSOR 256 | ||
27 | #define _ADJUST 65560 | ||
28 | |||
29 | // Set this to 1 to help diagnose early startup problems | ||
30 | // when testing power-on with ble. Turn it off otherwise, | ||
31 | // as the latency of printing most of the debug info messes | ||
32 | // with the matrix scan, causing keys to drop. | ||
33 | #define DEBUG_TO_SCREEN 0 | ||
34 | |||
35 | // Controls the SSD1306 128x32 OLED display via i2c | ||
36 | |||
37 | #define i2cAddress 0x3C | ||
38 | |||
39 | #define DisplayHeight 32 | ||
40 | #define DisplayWidth 128 | ||
41 | |||
42 | #define FontHeight 8 | ||
43 | #define FontWidth 6 | ||
44 | |||
45 | #define MatrixRows (DisplayHeight / FontHeight) | ||
46 | #define MatrixCols (DisplayWidth / FontWidth) | ||
47 | |||
48 | struct CharacterMatrix { | ||
49 | uint8_t display[MatrixRows][MatrixCols]; | ||
50 | uint8_t *cursor; | ||
51 | bool dirty; | ||
52 | }; | ||
53 | |||
54 | static struct CharacterMatrix display; | ||
55 | //static uint16_t last_battery_update; | ||
56 | //static uint32_t vbat; | ||
57 | //#define BatteryUpdateInterval 10000 /* milliseconds */ | ||
58 | #define ScreenOffInterval 300000 /* milliseconds */ | ||
59 | #if DEBUG_TO_SCREEN | ||
60 | static uint8_t displaying; | ||
61 | #endif | ||
62 | static uint16_t last_flush; | ||
63 | |||
64 | enum ssd1306_cmds { | ||
65 | DisplayOff = 0xAE, | ||
66 | DisplayOn = 0xAF, | ||
67 | |||
68 | SetContrast = 0x81, | ||
69 | DisplayAllOnResume = 0xA4, | ||
70 | |||
71 | DisplayAllOn = 0xA5, | ||
72 | NormalDisplay = 0xA6, | ||
73 | InvertDisplay = 0xA7, | ||
74 | SetDisplayOffset = 0xD3, | ||
75 | SetComPins = 0xda, | ||
76 | SetVComDetect = 0xdb, | ||
77 | SetDisplayClockDiv = 0xD5, | ||
78 | SetPreCharge = 0xd9, | ||
79 | SetMultiPlex = 0xa8, | ||
80 | SetLowColumn = 0x00, | ||
81 | SetHighColumn = 0x10, | ||
82 | SetStartLine = 0x40, | ||
83 | |||
84 | SetMemoryMode = 0x20, | ||
85 | ColumnAddr = 0x21, | ||
86 | PageAddr = 0x22, | ||
87 | |||
88 | ComScanInc = 0xc0, | ||
89 | ComScanDec = 0xc8, | ||
90 | SegRemap = 0xa0, | ||
91 | SetChargePump = 0x8d, | ||
92 | ExternalVcc = 0x01, | ||
93 | SwitchCapVcc = 0x02, | ||
94 | |||
95 | ActivateScroll = 0x2f, | ||
96 | DeActivateScroll = 0x2e, | ||
97 | SetVerticalScrollArea = 0xa3, | ||
98 | RightHorizontalScroll = 0x26, | ||
99 | LeftHorizontalScroll = 0x27, | ||
100 | VerticalAndRightHorizontalScroll = 0x29, | ||
101 | VerticalAndLeftHorizontalScroll = 0x2a, | ||
102 | }; | ||
103 | |||
104 | |||
105 | // Write command sequence. | ||
106 | // Returns true on success. | ||
107 | static inline bool _send_cmd1(uint8_t cmd) { | ||
108 | bool res = false; | ||
109 | |||
110 | if (i2c_start_write(i2cAddress)) { | ||
111 | xprintf("failed to start write to %d\n", i2cAddress); | ||
112 | goto done; | ||
113 | } | ||
114 | |||
115 | if (i2c_master_write(0x0 /* command byte follows */)) { | ||
116 | print("failed to write control byte\n"); | ||
117 | |||
118 | goto done; | ||
119 | } | ||
120 | |||
121 | if (i2c_master_write(cmd)) { | ||
122 | xprintf("failed to write command %d\n", cmd); | ||
123 | goto done; | ||
124 | } | ||
125 | res = true; | ||
126 | done: | ||
127 | i2c_master_stop(); | ||
128 | return res; | ||
129 | } | ||
130 | |||
131 | // Write 2-byte command sequence. | ||
132 | // Returns true on success | ||
133 | static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) { | ||
134 | if (!_send_cmd1(cmd)) { | ||
135 | return false; | ||
136 | } | ||
137 | return _send_cmd1(opr); | ||
138 | } | ||
139 | |||
140 | // Write 3-byte command sequence. | ||
141 | // Returns true on success | ||
142 | static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) { | ||
143 | if (!_send_cmd1(cmd)) { | ||
144 | return false; | ||
145 | } | ||
146 | if (!_send_cmd1(opr1)) { | ||
147 | return false; | ||
148 | } | ||
149 | return _send_cmd1(opr2); | ||
150 | } | ||
151 | |||
152 | #define send_cmd1(c) if (!_send_cmd1(c)) {goto done;} | ||
153 | #define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} | ||
154 | #define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} | ||
155 | |||
156 | static void matrix_clear(struct CharacterMatrix *matrix); | ||
157 | |||
158 | static void clear_display(void) { | ||
159 | matrix_clear(&display); | ||
160 | |||
161 | // Clear all of the display bits (there can be random noise | ||
162 | // in the RAM on startup) | ||
163 | send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); | ||
164 | send_cmd3(ColumnAddr, 0, DisplayWidth - 1); | ||
165 | |||
166 | if (i2c_start_write(i2cAddress)) { | ||
167 | goto done; | ||
168 | } | ||
169 | if (i2c_master_write(0x40)) { | ||
170 | // Data mode | ||
171 | goto done; | ||
172 | } | ||
173 | for (uint8_t row = 0; row < MatrixRows; ++row) { | ||
174 | for (uint8_t col = 0; col < DisplayWidth; ++col) { | ||
175 | i2c_master_write(0); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | display.dirty = false; | ||
180 | |||
181 | done: | ||
182 | i2c_master_stop(); | ||
183 | } | ||
184 | |||
185 | #if DEBUG_TO_SCREEN | ||
186 | #undef sendchar | ||
187 | static int8_t capture_sendchar(uint8_t c) { | ||
188 | sendchar(c); | ||
189 | iota_gfx_write_char(c); | ||
190 | |||
191 | if (!displaying) { | ||
192 | iota_gfx_flush(); | ||
193 | } | ||
194 | return 0; | ||
195 | } | ||
196 | #endif | ||
197 | |||
198 | bool iota_gfx_init(void) { | ||
199 | bool success = false; | ||
200 | |||
201 | send_cmd1(DisplayOff); | ||
202 | send_cmd2(SetDisplayClockDiv, 0x80); | ||
203 | send_cmd2(SetMultiPlex, DisplayHeight - 1); | ||
204 | |||
205 | send_cmd2(SetDisplayOffset, 0); | ||
206 | |||
207 | |||
208 | send_cmd1(SetStartLine | 0x0); | ||
209 | send_cmd2(SetChargePump, 0x14 /* Enable */); | ||
210 | send_cmd2(SetMemoryMode, 0 /* horizontal addressing */); | ||
211 | |||
212 | /* Flips the display orientation 0 degrees | ||
213 | send_cmd1(SegRemap | 0x1); | ||
214 | send_cmd1(ComScanDec); | ||
215 | */ | ||
216 | // the following Flip the display orientation 180 degrees */ | ||
217 | send_cmd1(SegRemap); | ||
218 | send_cmd1(ComScanInc); | ||
219 | //end flip | ||
220 | send_cmd2(SetComPins, 0x2); | ||
221 | send_cmd2(SetContrast, 0x8f); | ||
222 | send_cmd2(SetPreCharge, 0xf1); | ||
223 | send_cmd2(SetVComDetect, 0x40); | ||
224 | send_cmd1(DisplayAllOnResume); | ||
225 | send_cmd1(NormalDisplay); | ||
226 | send_cmd1(DeActivateScroll); | ||
227 | send_cmd1(DisplayOn); | ||
228 | |||
229 | send_cmd2(SetContrast, 0); // Dim | ||
230 | |||
231 | clear_display(); | ||
232 | |||
233 | success = true; | ||
234 | |||
235 | iota_gfx_flush(); | ||
236 | |||
237 | #if DEBUG_TO_SCREEN | ||
238 | print_set_sendchar(capture_sendchar); | ||
239 | #endif | ||
240 | |||
241 | done: | ||
242 | return success; | ||
243 | } | ||
244 | |||
245 | bool iota_gfx_off(void) { | ||
246 | bool success = false; | ||
247 | |||
248 | send_cmd1(DisplayOff); | ||
249 | success = true; | ||
250 | |||
251 | done: | ||
252 | return success; | ||
253 | } | ||
254 | |||
255 | bool iota_gfx_on(void) { | ||
256 | bool success = false; | ||
257 | |||
258 | send_cmd1(DisplayOn); | ||
259 | success = true; | ||
260 | |||
261 | done: | ||
262 | return success; | ||
263 | } | ||
264 | |||
265 | static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { | ||
266 | *matrix->cursor = c; | ||
267 | ++matrix->cursor; | ||
268 | |||
269 | if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) { | ||
270 | // We went off the end; scroll the display upwards by one line | ||
271 | memmove(&matrix->display[0], &matrix->display[1], | ||
272 | MatrixCols * (MatrixRows - 1)); | ||
273 | matrix->cursor = &matrix->display[MatrixRows - 1][0]; | ||
274 | memset(matrix->cursor, ' ', MatrixCols); | ||
275 | } | ||
276 | } | ||
277 | |||
278 | static void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { | ||
279 | matrix->dirty = true; | ||
280 | |||
281 | if (c == '\n') { | ||
282 | // Clear to end of line from the cursor and then move to the | ||
283 | // start of the next line | ||
284 | uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; | ||
285 | |||
286 | while (cursor_col++ < MatrixCols) { | ||
287 | matrix_write_char_inner(matrix, ' '); | ||
288 | } | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | matrix_write_char_inner(matrix, c); | ||
293 | } | ||
294 | |||
295 | void iota_gfx_write_char(uint8_t c) { | ||
296 | matrix_write_char(&display, c); | ||
297 | } | ||
298 | |||
299 | static void matrix_write(struct CharacterMatrix *matrix, const char *data) { | ||
300 | const char *end = data + strlen(data); | ||
301 | while (data < end) { | ||
302 | matrix_write_char(matrix, *data); | ||
303 | ++data; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | void iota_gfx_write(const char *data) { | ||
308 | matrix_write(&display, data); | ||
309 | } | ||
310 | |||
311 | static void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { | ||
312 | while (true) { | ||
313 | uint8_t c = pgm_read_byte(data); | ||
314 | if (c == 0) { | ||
315 | return; | ||
316 | } | ||
317 | matrix_write_char(matrix, c); | ||
318 | ++data; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | void iota_gfx_write_P(const char *data) { | ||
323 | matrix_write_P(&display, data); | ||
324 | } | ||
325 | |||
326 | static void matrix_clear(struct CharacterMatrix *matrix) { | ||
327 | memset(matrix->display, ' ', sizeof(matrix->display)); | ||
328 | matrix->cursor = &matrix->display[0][0]; | ||
329 | matrix->dirty = true; | ||
330 | } | ||
331 | |||
332 | void iota_gfx_clear_screen(void) { | ||
333 | matrix_clear(&display); | ||
334 | } | ||
335 | |||
336 | static void matrix_render(struct CharacterMatrix *matrix) { | ||
337 | last_flush = timer_read(); | ||
338 | iota_gfx_on(); | ||
339 | #if DEBUG_TO_SCREEN | ||
340 | ++displaying; | ||
341 | #endif | ||
342 | |||
343 | // Move to the home position | ||
344 | send_cmd3(PageAddr, 0, MatrixRows - 1); | ||
345 | send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); | ||
346 | |||
347 | if (i2c_start_write(i2cAddress)) { | ||
348 | goto done; | ||
349 | } | ||
350 | if (i2c_master_write(0x40)) { | ||
351 | // Data mode | ||
352 | goto done; | ||
353 | } | ||
354 | |||
355 | for (uint8_t row = 0; row < MatrixRows; ++row) { | ||
356 | for (uint8_t col = 0; col < MatrixCols; ++col) { | ||
357 | const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1)); | ||
358 | |||
359 | for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) { | ||
360 | uint8_t colBits = pgm_read_byte(glyph + glyphCol); | ||
361 | i2c_master_write(colBits); | ||
362 | } | ||
363 | |||
364 | // 1 column of space between chars (it's not included in the glyph) | ||
365 | i2c_master_write(0); | ||
366 | } | ||
367 | } | ||
368 | |||
369 | matrix->dirty = false; | ||
370 | |||
371 | done: | ||
372 | i2c_master_stop(); | ||
373 | #if DEBUG_TO_SCREEN | ||
374 | --displaying; | ||
375 | #endif | ||
376 | } | ||
377 | |||
378 | void iota_gfx_flush(void) { | ||
379 | matrix_render(&display); | ||
380 | } | ||
381 | |||
382 | //#include "LUFA/Drivers/Peripheral/ADC.h" | ||
383 | |||
384 | /* Returns the battery voltage; returns the number of millivolts | ||
385 | static uint32_t read_battery_voltage(void) { | ||
386 | if (last_battery_update == 0 || | ||
387 | timer_elapsed(last_battery_update) > BatteryUpdateInterval) { | ||
388 | ADC_Init(ADC_SINGLE_CONVERSION | ADC_PRESCALE_32); | ||
389 | ADC_SetupChannel(12); | ||
390 | vbat = 2 * 3.3 * ADC_GetChannelReading(ADC_REFERENCE_AVCC | ADC_CHANNEL12); | ||
391 | |||
392 | last_battery_update = timer_read(); | ||
393 | } | ||
394 | return vbat; | ||
395 | } */ | ||
396 | |||
397 | static void matrix_update(struct CharacterMatrix *dest, | ||
398 | const struct CharacterMatrix *source) { | ||
399 | if (memcmp(dest->display, source->display, sizeof(dest->display))) { | ||
400 | memcpy(dest->display, source->display, sizeof(dest->display)); | ||
401 | dest->dirty = true; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | static void render_status_info(void) { | ||
406 | #if DEBUG_TO_SCREEN | ||
407 | if (debug_enable) { | ||
408 | return; | ||
409 | } | ||
410 | #endif | ||
411 | |||
412 | struct CharacterMatrix matrix; | ||
413 | |||
414 | matrix_clear(&matrix); | ||
415 | matrix_write_P(&matrix, PSTR("USB: ")); | ||
416 | #ifdef PROTOCOL_LUFA | ||
417 | switch (USB_DeviceState) { | ||
418 | case DEVICE_STATE_Unattached: | ||
419 | matrix_write_P(&matrix, PSTR("Unattached")); | ||
420 | break; | ||
421 | case DEVICE_STATE_Suspended: | ||
422 | matrix_write_P(&matrix, PSTR("Suspended")); | ||
423 | break; | ||
424 | case DEVICE_STATE_Configured: | ||
425 | matrix_write_P(&matrix, PSTR("Connected")); | ||
426 | break; | ||
427 | case DEVICE_STATE_Powered: | ||
428 | matrix_write_P(&matrix, PSTR("Powered")); | ||
429 | break; | ||
430 | case DEVICE_STATE_Default: | ||
431 | matrix_write_P(&matrix, PSTR("Default")); | ||
432 | break; | ||
433 | case DEVICE_STATE_Addressed: | ||
434 | matrix_write_P(&matrix, PSTR("Addressed")); | ||
435 | break; | ||
436 | default: | ||
437 | matrix_write_P(&matrix, PSTR("Invalid")); | ||
438 | } | ||
439 | #endif | ||
440 | |||
441 | // matrix_write_P(&matrix, (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? PSTR("\n NUMLOCK") : PSTR("\n")); | ||
442 | // matrix_write_P(&matrix, PSTR("\nBLE: ")); | ||
443 | //#ifdef ADAFRUIT_BLE_ENABLE | ||
444 | // matrix_write_P(&matrix, adafruit_ble_is_connected() ? PSTR("Connected") | ||
445 | // : PSTR("Not Connected")); | ||
446 | //#endif | ||
447 | |||
448 | // char buf[40]; | ||
449 | // snprintf(buf, sizeof(buf), "VBat: %4lumV\nLayer: 0x%04lx %s", | ||
450 | // read_battery_voltage(), layer_state, | ||
451 | // (host_keyboard_leds() & USB_LED_CAPS_LOCK) ? "CAPS" : ""); | ||
452 | // matrix_write(&matrix, buf); | ||
453 | |||
454 | char buf[40]; | ||
455 | snprintf(buf,sizeof(buf), "Undef-%ld", layer_state); | ||
456 | matrix_write_P(&matrix, PSTR("\n\nLayer: ")); | ||
457 | switch (layer_state) { | ||
458 | case _BASE: | ||
459 | matrix_write_P(&matrix, PSTR("Default")); | ||
460 | break; | ||
461 | case _RAISE: | ||
462 | matrix_write_P(&matrix, PSTR("Raise")); | ||
463 | break; | ||
464 | case _LOWER: | ||
465 | matrix_write_P(&matrix, PSTR("Lower")); | ||
466 | break; | ||
467 | case _MOUSECURSOR: | ||
468 | matrix_write_P(&matrix, PSTR("Mouse/Macro")); | ||
469 | break; | ||
470 | case _FNLAYER: | ||
471 | matrix_write_P(&matrix, PSTR("Symbols/Fn")); | ||
472 | break; | ||
473 | case _NUMLAY: | ||
474 | matrix_write_P(&matrix, PSTR("Numbers")); | ||
475 | break; | ||
476 | case _NLOWER: | ||
477 | matrix_write_P(&matrix, PSTR("Num + Lower")); | ||
478 | break; | ||
479 | case _NFNLAYER: | ||
480 | matrix_write_P(&matrix, PSTR("Num + FN")); | ||
481 | break; | ||
482 | case _ADJUST: | ||
483 | matrix_write_P(&matrix, PSTR("ADJUST")); | ||
484 | break; | ||
485 | default: | ||
486 | matrix_write(&matrix, buf); | ||
487 | } | ||
488 | |||
489 | char led[40]; | ||
490 | snprintf(led, sizeof(led), "\n%s %s %s", | ||
491 | (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ", | ||
492 | (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ", | ||
493 | (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " "); | ||
494 | matrix_write(&matrix, led); | ||
495 | matrix_update(&display, &matrix); | ||
496 | } | ||
497 | |||
498 | void iota_gfx_task(void) { | ||
499 | render_status_info(); | ||
500 | |||
501 | if (display.dirty) { | ||
502 | iota_gfx_flush(); | ||
503 | } | ||
504 | |||
505 | if (timer_elapsed(last_flush) > ScreenOffInterval) { | ||
506 | iota_gfx_off(); | ||
507 | } | ||
508 | } | ||