diff options
Diffstat (limited to 'keyboards/cannonkeys/satisfaction75/satisfaction_oled.c')
-rw-r--r-- | keyboards/cannonkeys/satisfaction75/satisfaction_oled.c | 267 |
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 | |||
3 | void draw_default(void); | ||
4 | void draw_clock(void); | ||
5 | |||
6 | #ifdef OLED_ENABLE | ||
7 | |||
8 | oled_rotation_t oled_init_kb(oled_rotation_t rotation) { return OLED_ROTATION_0; } | ||
9 | |||
10 | bool 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. | ||
35 | void 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. | ||
43 | void 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. | ||
50 | bool 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 | |||
97 | static 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 | |||
103 | static 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 | |||
109 | static 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 | |||
133 | static 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 | |||
154 | static 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 | |||
171 | void 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 | |||
223 | void 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 | ||