aboutsummaryrefslogtreecommitdiff
path: root/drivers/avr/ssd1306.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/avr/ssd1306.c')
-rw-r--r--drivers/avr/ssd1306.c174
1 files changed, 14 insertions, 160 deletions
diff --git a/drivers/avr/ssd1306.c b/drivers/avr/ssd1306.c
index e454f5437..03a909e9d 100644
--- a/drivers/avr/ssd1306.c
+++ b/drivers/avr/ssd1306.c
@@ -1,7 +1,6 @@
1#ifdef SSD1306OLED 1#ifdef SSD1306OLED
2 2
3#include "ssd1306.h" 3#include "ssd1306.h"
4#include "config.h"
5#include "i2c.h" 4#include "i2c.h"
6#include <string.h> 5#include <string.h>
7#include "print.h" 6#include "print.h"
@@ -13,18 +12,7 @@
13#include "lufa.h" 12#include "lufa.h"
14#endif 13#endif
15#include "sendchar.h" 14#include "sendchar.h"
16#include "pincontrol.h" 15#include "timer.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 16
29// Set this to 1 to help diagnose early startup problems 17// Set this to 1 to help diagnose early startup problems
30// when testing power-on with ble. Turn it off otherwise, 18// when testing power-on with ble. Turn it off otherwise,
@@ -32,26 +20,6 @@
32// with the matrix scan, causing keys to drop. 20// with the matrix scan, causing keys to drop.
33#define DEBUG_TO_SCREEN 0 21#define DEBUG_TO_SCREEN 0
34 22
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
48struct CharacterMatrix {
49 uint8_t display[MatrixRows][MatrixCols];
50 uint8_t *cursor;
51 bool dirty;
52};
53
54static struct CharacterMatrix display;
55//static uint16_t last_battery_update; 23//static uint16_t last_battery_update;
56//static uint32_t vbat; 24//static uint32_t vbat;
57//#define BatteryUpdateInterval 10000 /* milliseconds */ 25//#define BatteryUpdateInterval 10000 /* milliseconds */
@@ -61,54 +29,13 @@ static uint8_t displaying;
61#endif 29#endif
62static uint16_t last_flush; 30static uint16_t last_flush;
63 31
64enum 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. 32// Write command sequence.
106// Returns true on success. 33// Returns true on success.
107static inline bool _send_cmd1(uint8_t cmd) { 34static inline bool _send_cmd1(uint8_t cmd) {
108 bool res = false; 35 bool res = false;
109 36
110 if (i2c_start_write(i2cAddress)) { 37 if (i2c_start_write(SSD1306_ADDRESS)) {
111 xprintf("failed to start write to %d\n", i2cAddress); 38 xprintf("failed to start write to %d\n", SSD1306_ADDRESS);
112 goto done; 39 goto done;
113 } 40 }
114 41
@@ -153,8 +80,6 @@ static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
153#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} 80#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;} 81#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
155 82
156static void matrix_clear(struct CharacterMatrix *matrix);
157
158static void clear_display(void) { 83static void clear_display(void) {
159 matrix_clear(&display); 84 matrix_clear(&display);
160 85
@@ -163,7 +88,7 @@ static void clear_display(void) {
163 send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); 88 send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
164 send_cmd3(ColumnAddr, 0, DisplayWidth - 1); 89 send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
165 90
166 if (i2c_start_write(i2cAddress)) { 91 if (i2c_start_write(SSD1306_ADDRESS)) {
167 goto done; 92 goto done;
168 } 93 }
169 if (i2c_master_write(0x40)) { 94 if (i2c_master_write(0x40)) {
@@ -262,7 +187,7 @@ done:
262 return success; 187 return success;
263} 188}
264 189
265static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) { 190void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
266 *matrix->cursor = c; 191 *matrix->cursor = c;
267 ++matrix->cursor; 192 ++matrix->cursor;
268 193
@@ -275,7 +200,7 @@ static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
275 } 200 }
276} 201}
277 202
278static void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { 203void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
279 matrix->dirty = true; 204 matrix->dirty = true;
280 205
281 if (c == '\n') { 206 if (c == '\n') {
@@ -296,7 +221,7 @@ void iota_gfx_write_char(uint8_t c) {
296 matrix_write_char(&display, c); 221 matrix_write_char(&display, c);
297} 222}
298 223
299static void matrix_write(struct CharacterMatrix *matrix, const char *data) { 224void matrix_write(struct CharacterMatrix *matrix, const char *data) {
300 const char *end = data + strlen(data); 225 const char *end = data + strlen(data);
301 while (data < end) { 226 while (data < end) {
302 matrix_write_char(matrix, *data); 227 matrix_write_char(matrix, *data);
@@ -308,7 +233,7 @@ void iota_gfx_write(const char *data) {
308 matrix_write(&display, data); 233 matrix_write(&display, data);
309} 234}
310 235
311static void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { 236void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
312 while (true) { 237 while (true) {
313 uint8_t c = pgm_read_byte(data); 238 uint8_t c = pgm_read_byte(data);
314 if (c == 0) { 239 if (c == 0) {
@@ -323,7 +248,7 @@ void iota_gfx_write_P(const char *data) {
323 matrix_write_P(&display, data); 248 matrix_write_P(&display, data);
324} 249}
325 250
326static void matrix_clear(struct CharacterMatrix *matrix) { 251void matrix_clear(struct CharacterMatrix *matrix) {
327 memset(matrix->display, ' ', sizeof(matrix->display)); 252 memset(matrix->display, ' ', sizeof(matrix->display));
328 matrix->cursor = &matrix->display[0][0]; 253 matrix->cursor = &matrix->display[0][0];
329 matrix->dirty = true; 254 matrix->dirty = true;
@@ -333,7 +258,7 @@ void iota_gfx_clear_screen(void) {
333 matrix_clear(&display); 258 matrix_clear(&display);
334} 259}
335 260
336static void matrix_render(struct CharacterMatrix *matrix) { 261void matrix_render(struct CharacterMatrix *matrix) {
337 last_flush = timer_read(); 262 last_flush = timer_read();
338 iota_gfx_on(); 263 iota_gfx_on();
339#if DEBUG_TO_SCREEN 264#if DEBUG_TO_SCREEN
@@ -344,7 +269,7 @@ static void matrix_render(struct CharacterMatrix *matrix) {
344 send_cmd3(PageAddr, 0, MatrixRows - 1); 269 send_cmd3(PageAddr, 0, MatrixRows - 1);
345 send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); 270 send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
346 271
347 if (i2c_start_write(i2cAddress)) { 272 if (i2c_start_write(SSD1306_ADDRESS)) {
348 goto done; 273 goto done;
349 } 274 }
350 if (i2c_master_write(0x40)) { 275 if (i2c_master_write(0x40)) {
@@ -379,84 +304,13 @@ void iota_gfx_flush(void) {
379 matrix_render(&display); 304 matrix_render(&display);
380} 305}
381 306
382static void matrix_update(struct CharacterMatrix *dest, 307__attribute__((weak))
383 const struct CharacterMatrix *source) { 308void iota_gfx_task_user(void) {
384 if (memcmp(dest->display, source->display, sizeof(dest->display))) {
385 memcpy(dest->display, source->display, sizeof(dest->display));
386 dest->dirty = true;
387 }
388}
389
390static void render_status_info(void) {
391#if DEBUG_TO_SCREEN
392 if (debug_enable) {
393 return;
394 }
395#endif
396
397 struct CharacterMatrix matrix;
398
399 matrix_clear(&matrix);
400 matrix_write_P(&matrix, PSTR("USB: "));
401#ifdef PROTOCOL_LUFA
402 switch (USB_DeviceState) {
403 case DEVICE_STATE_Unattached:
404 matrix_write_P(&matrix, PSTR("Unattached"));
405 break;
406 case DEVICE_STATE_Suspended:
407 matrix_write_P(&matrix, PSTR("Suspended"));
408 break;
409 case DEVICE_STATE_Configured:
410 matrix_write_P(&matrix, PSTR("Connected"));
411 break;
412 case DEVICE_STATE_Powered:
413 matrix_write_P(&matrix, PSTR("Powered"));
414 break;
415 case DEVICE_STATE_Default:
416 matrix_write_P(&matrix, PSTR("Default"));
417 break;
418 case DEVICE_STATE_Addressed:
419 matrix_write_P(&matrix, PSTR("Addressed"));
420 break;
421 default:
422 matrix_write_P(&matrix, PSTR("Invalid"));
423 }
424#endif
425 309
426// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
427
428 char buf[40];
429 snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
430 matrix_write_P(&matrix, PSTR("\n\nLayer: "));
431 switch (layer_state) {
432 case _BASE:
433 matrix_write_P(&matrix, PSTR("Default"));
434 break;
435 case _RAISE:
436 matrix_write_P(&matrix, PSTR("Raise"));
437 break;
438 case _LOWER:
439 matrix_write_P(&matrix, PSTR("Lower"));
440 break;
441 case _ADJUST:
442 matrix_write_P(&matrix, PSTR("ADJUST"));
443 break;
444 default:
445 matrix_write(&matrix, buf);
446 }
447
448 // Host Keyboard LED Status
449 char led[40];
450 snprintf(led, sizeof(led), "\n%s %s %s",
451 (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
452 (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
453 (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
454 matrix_write(&matrix, led);
455 matrix_update(&display, &matrix);
456} 310}
457 311
458void iota_gfx_task(void) { 312void iota_gfx_task(void) {
459 render_status_info(); 313 iota_gfx_task_user();
460 314
461 if (display.dirty) { 315 if (display.dirty) {
462 iota_gfx_flush(); 316 iota_gfx_flush();