aboutsummaryrefslogtreecommitdiff
path: root/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/cannonkeys/satisfaction75/satisfaction_oled.c')
-rw-r--r--keyboards/cannonkeys/satisfaction75/satisfaction_oled.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c b/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c
new file mode 100644
index 000000000..fff8b65bd
--- /dev/null
+++ b/keyboards/cannonkeys/satisfaction75/satisfaction_oled.c
@@ -0,0 +1,267 @@
1#include "satisfaction75.h"
2
3void draw_default(void);
4void draw_clock(void);
5
6#ifdef OLED_ENABLE
7
8oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return OLED_ROTATION_0; }
9
10bool oled_task_kb(void) {
11 if (!oled_task_user()) { return false; }
12 if (!oled_task_needs_to_repaint()) {
13 return false;
14 }
15 oled_clear();
16 if (clock_set_mode) {
17 draw_clock();
18 return false;;
19 }
20 switch (oled_mode) {
21 default:
22 case OLED_DEFAULT:
23 draw_default();
24 break;
25 case OLED_TIME:
26 draw_clock();
27 break;
28 }
29 return false;
30}
31
32// Request a repaint of the OLED image without resetting the OLED sleep timer.
33// Used for things like clock updates that should not keep the OLED turned on
34// if there is no other activity.
35void oled_request_repaint(void) {
36 if (is_oled_on()) {
37 oled_repaint_requested = true;
38 }
39}
40
41// Request a repaint of the OLED image and reset the OLED sleep timer.
42// Needs to be called after any activity that should keep the OLED turned on.
43void oled_request_wakeup(void) {
44 oled_wakeup_requested = true;
45}
46
47// Check whether oled_task_user() needs to repaint the OLED image. This
48// function should be called at the start of oled_task_user(); it also handles
49// the OLED sleep timer and the OLED_OFF mode.
50bool oled_task_needs_to_repaint(void) {
51 // In the OLED_OFF mode the OLED is kept turned off; any wakeup requests
52 // are ignored.
53 if ((oled_mode == OLED_OFF) && !clock_set_mode) {
54 oled_wakeup_requested = false;
55 oled_repaint_requested = false;
56 oled_off();
57 return false;
58 }
59
60 // If OLED wakeup was requested, reset the sleep timer and do a repaint.
61 if (oled_wakeup_requested) {
62 oled_wakeup_requested = false;
63 oled_repaint_requested = false;
64 oled_sleep_timer = timer_read32() + CUSTOM_OLED_TIMEOUT;
65 oled_on();
66 return true;
67 }
68
69 // If OLED repaint was requested, just do a repaint without touching the
70 // sleep timer.
71 if (oled_repaint_requested) {
72 oled_repaint_requested = false;
73 return true;
74 }
75
76 // If the OLED is currently off, skip the repaint (which would turn the
77 // OLED on if the image is changed in any way).
78 if (!is_oled_on()) {
79 return false;
80 }
81
82 // If the sleep timer has expired while the OLED was on, turn the OLED off.
83 if (timer_expired32(timer_read32(), oled_sleep_timer)) {
84 oled_off();
85 return false;
86 }
87
88 // Always perform a repaint if the OLED is currently on. (This can
89 // potentially be optimized to avoid unneeded repaints if all possible
90 // state changes are covered by oled_request_repaint() or
91 // oled_request_wakeup(), but then any missed calls to these functions
92 // would result in displaying a stale image.)
93 return true;
94}
95
96
97static void draw_line_h(uint8_t x, uint8_t y, uint8_t len) {
98 for (uint8_t i = 0; i < len; i++) {
99 oled_write_pixel(i + x, y, true);
100 }
101}
102
103static void draw_line_v(uint8_t x, uint8_t y, uint8_t len) {
104 for (uint8_t i = 0; i < len; i++) {
105 oled_write_pixel(x, i + y, true);
106 }
107}
108
109static char* get_enc_mode(void) {
110 switch (encoder_mode) {
111 default:
112 case ENC_MODE_VOLUME:
113 return "VOL";
114 case ENC_MODE_MEDIA:
115 return "MED";
116 case ENC_MODE_SCROLL:
117 return "SCR";
118 case ENC_MODE_BRIGHTNESS:
119 return "BRT";
120 case ENC_MODE_BACKLIGHT:
121 return "BKL";
122 case ENC_MODE_CLOCK_SET:
123 return "CLK";
124 case ENC_MODE_CUSTOM0:
125 return "CS0";
126 case ENC_MODE_CUSTOM1:
127 return "CS1";
128 case ENC_MODE_CUSTOM2:
129 return "CS2";
130 }
131}
132
133static char* get_time(void) {
134 uint8_t hour = last_minute / 60;
135 uint16_t minute = last_minute % 60;
136
137 if (encoder_mode == ENC_MODE_CLOCK_SET) {
138 hour = hour_config;
139 minute = minute_config;
140 }
141
142 bool is_pm = (hour / 12) > 0;
143 hour = hour % 12;
144 if (hour == 0) {
145 hour = 12;
146 }
147
148 static char time_str[8] = "";
149 sprintf(time_str, "%02d:%02d%s", hour, minute, is_pm ? "pm" : "am");
150
151 return time_str;
152}
153
154static char* get_date(void) {
155 int16_t year = last_timespec.year + 1980;
156 int8_t month = last_timespec.month;
157 int8_t day = last_timespec.day;
158
159 if (encoder_mode == ENC_MODE_CLOCK_SET) {
160 year = year_config + 1980;
161 month = month_config;
162 day = day_config;
163 }
164
165 static char date_str[11] = "";
166 sprintf(date_str, "%04d-%02d-%02d", year, month, day);
167
168 return date_str;
169}
170
171void draw_default() {
172 oled_write_P(PSTR("LAYER "), false);
173 oled_write_char(get_highest_layer(layer_state) + 0x30, true);
174
175 oled_write_P(PSTR(" ENC "), false);
176 oled_write(get_enc_mode(), true);
177
178 led_t led_state = host_keyboard_led_state();
179 oled_set_cursor(18, 0);
180 oled_write_P(PSTR("CAP"), led_state.caps_lock);
181 oled_set_cursor(18, 1);
182 oled_write_P(PSTR("SCR"), led_state.scroll_lock);
183
184 uint8_t mod_state = get_mods();
185 oled_set_cursor(6, 3);
186 oled_write_P(PSTR("S"), mod_state & MOD_MASK_SHIFT);
187 oled_advance_char();
188 oled_write_P(PSTR("C"), mod_state & MOD_MASK_CTRL);
189 oled_advance_char();
190 oled_write_P(PSTR("A"), mod_state & MOD_MASK_ALT);
191 oled_advance_char();
192 oled_write_P(PSTR("G"), mod_state & MOD_MASK_GUI);
193 oled_advance_char();
194
195 oled_write(get_time(), false);
196
197/* Matrix display is 12 x 12 pixels */
198#define MATRIX_DISPLAY_X 0
199#define MATRIX_DISPLAY_Y 18
200
201 // matrix
202 for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
203 for (uint8_t y = 0; y < MATRIX_COLS; y++) {
204 bool on = (matrix_get_row(x) & (1 << y)) > 0;
205 oled_write_pixel(MATRIX_DISPLAY_X + y + 2, MATRIX_DISPLAY_Y + x + 2, on);
206 }
207 }
208
209 // outline
210 draw_line_h(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y, 19);
211 draw_line_h(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y + 9, 19);
212 draw_line_v(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y, 9);
213 draw_line_v(MATRIX_DISPLAY_X + 19, MATRIX_DISPLAY_Y, 9);
214
215 // oled location
216 draw_line_h(MATRIX_DISPLAY_X + 14, MATRIX_DISPLAY_Y + 2, 3);
217
218 // bodge extra lines for invert layer and enc mode
219 draw_line_v(35, 0, 8);
220 draw_line_v(71, 0, 8);
221}
222
223void draw_clock() {
224 oled_set_cursor(0, 0);
225 oled_write(get_date(), false);
226 oled_set_cursor(0, 2);
227 oled_write(get_time(), false);
228
229 oled_set_cursor(12, 0);
230 oled_write_P(PSTR(" ENC "), false);
231 oled_write(get_enc_mode(), true);
232
233 oled_set_cursor(13, 1);
234 oled_write_P(PSTR("LAYER "), false);
235 oled_write_char(get_highest_layer(layer_state) + 0x30, true);
236
237 led_t led_state = host_keyboard_led_state();
238 oled_set_cursor(15, 3);
239 oled_write_P(PSTR("CAPS"), led_state.caps_lock);
240
241 if (clock_set_mode) {
242 switch (time_config_idx) {
243 case 0: // hour
244 default:
245 draw_line_h(0, 25, 10);
246 break;
247 case 1: // minute
248 draw_line_h(18, 25, 10);
249 break;
250 case 2: // year
251 draw_line_h(0, 9, 24);
252 break;
253 case 3: // month
254 draw_line_h(30, 9, 10);
255 break;
256 case 4: // day
257 draw_line_h(48, 9, 10);
258 break;
259 }
260 }
261
262 // bodge extra lines for invert layer and enc mode
263 draw_line_v(101, 0, 8);
264 draw_line_v(113, 8, 8);
265}
266
267#endif