]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/cannonkeys/satisfaction75/satisfaction75.c
Update keyboards/kbdfans/kbd67/readme.md
[qmk_firmware.git] / keyboards / cannonkeys / satisfaction75 / satisfaction75.c
1 #include "satisfaction75.h"
2 #include "print.h"
3 #include "debug.h"
4
5 #include "ch.h"
6 #include "hal.h"
7
8 // #ifdef QWIIC_MICRO_OLED_ENABLE
9 #include "micro_oled.h"
10 #include "qwiic.h"
11
12 #include "timer.h"
13
14 #include "raw_hid.h"
15 #include "dynamic_keymap.h"
16 #include "tmk_core/common/eeprom.h"
17
18 // HACK
19 #include "keyboards/zeal60/zeal60_api.h" // Temporary hack
20 #include "keyboards/zeal60/zeal60_keycodes.h" // Temporary hack
21
22
23 /* Artificial delay added to get media keys to work in the encoder*/
24 #define MEDIA_KEY_DELAY 10
25
26 uint16_t last_flush;
27
28 volatile uint8_t led_numlock = false;
29 volatile uint8_t led_capslock = false;
30 volatile uint8_t led_scrolllock = false;
31
32 uint8_t layer;
33
34 bool queue_for_send = false;
35 bool clock_set_mode = false;
36 uint8_t oled_mode = OLED_DEFAULT;
37 bool oled_sleeping = false;
38
39 uint8_t encoder_value = 32;
40 uint8_t encoder_mode = ENC_MODE_VOLUME;
41 uint8_t enabled_encoder_modes = 0x1F;
42
43 RTCDateTime last_timespec;
44 uint16_t last_minute = 0;
45
46 uint8_t time_config_idx = 0;
47 int8_t hour_config = 0;
48 int16_t minute_config = 0;
49 int8_t year_config = 0;
50 int8_t month_config = 0;
51 int8_t day_config = 0;
52 uint8_t previous_encoder_mode = 0;
53
54 backlight_config_t kb_backlight_config = {
55   .enable = true,
56   .breathing = true,
57   .level = BACKLIGHT_LEVELS
58 };
59
60 bool eeprom_is_valid(void)
61 {
62         return (eeprom_read_word(((void*)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC &&
63                         eeprom_read_byte(((void*)EEPROM_VERSION_ADDR)) == EEPROM_VERSION);
64 }
65
66 void eeprom_set_valid(bool valid)
67 {
68         eeprom_update_word(((void*)EEPROM_MAGIC_ADDR), valid ? EEPROM_MAGIC : 0xFFFF);
69         eeprom_update_byte(((void*)EEPROM_VERSION_ADDR), valid ? EEPROM_VERSION : 0xFF);
70 }
71
72 void eeprom_reset(void)
73 {
74         // Set the Zeal60 specific EEPROM state as invalid.
75         eeprom_set_valid(false);
76         // Set the TMK/QMK EEPROM state as invalid.
77         eeconfig_disable();
78 }
79
80 #ifdef RAW_ENABLE
81
82 void raw_hid_receive( uint8_t *data, uint8_t length )
83 {
84         uint8_t *command_id = &(data[0]);
85         uint8_t *command_data = &(data[1]);
86         switch ( *command_id )
87         {
88                 case id_get_protocol_version:
89                 {
90                         command_data[0] = PROTOCOL_VERSION >> 8;
91                         command_data[1] = PROTOCOL_VERSION & 0xFF;
92                         break;
93                 }
94                 case id_get_keyboard_value:
95                 {
96                         if ( command_data[0] == id_uptime )
97                         {
98                                 uint32_t value = timer_read32();
99                                 command_data[1] = (value >> 24 ) & 0xFF;
100                                 command_data[2] = (value >> 16 ) & 0xFF;
101                                 command_data[3] = (value >> 8 ) & 0xFF;
102                                 command_data[4] = value & 0xFF;
103                         }
104                         else
105                         {
106                                 *command_id = id_unhandled;
107                         }
108                         break;
109                 }
110 #ifdef DYNAMIC_KEYMAP_ENABLE
111                 case id_dynamic_keymap_get_keycode:
112                 {
113                         uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
114                         command_data[3] = keycode >> 8;
115                         command_data[4] = keycode & 0xFF;
116                         break;
117                 }
118                 case id_dynamic_keymap_set_keycode:
119                 {
120                         dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
121                         break;
122                 }
123                 case id_dynamic_keymap_reset:
124                 {
125                         dynamic_keymap_reset();
126                         break;
127                 }
128                 case id_dynamic_keymap_macro_get_count:
129                 {
130                         command_data[0] = dynamic_keymap_macro_get_count();
131                         break;
132                 }
133                 case id_dynamic_keymap_macro_get_buffer_size:
134                 {
135                         uint16_t size = dynamic_keymap_macro_get_buffer_size();
136                         command_data[0] = size >> 8;
137                         command_data[1] = size & 0xFF;
138                         break;
139                 }
140                 case id_dynamic_keymap_macro_get_buffer:
141                 {
142                         uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
143                         uint16_t size = command_data[2]; // size <= 28
144                         dynamic_keymap_macro_get_buffer( offset, size, &command_data[3] );
145                         break;
146                 }
147                 case id_dynamic_keymap_macro_set_buffer:
148                 {
149                         uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
150                         uint16_t size = command_data[2]; // size <= 28
151                         dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
152                         break;
153                 }
154                 case id_dynamic_keymap_macro_reset:
155                 {
156                         dynamic_keymap_macro_reset();
157                         break;
158                 }
159                 case id_dynamic_keymap_get_layer_count:
160                 {
161                         command_data[0] = dynamic_keymap_get_layer_count();
162                         break;
163                 }
164                 case id_dynamic_keymap_get_buffer:
165                 {
166                         uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
167                         uint16_t size = command_data[2]; // size <= 28
168                         dynamic_keymap_get_buffer( offset, size, &command_data[3] );
169                         break;
170                 }
171                 case id_dynamic_keymap_set_buffer:
172                 {
173                         uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
174                         uint16_t size = command_data[2]; // size <= 28
175                         dynamic_keymap_set_buffer( offset, size, &command_data[3] );
176                         break;
177                 }
178 #endif // DYNAMIC_KEYMAP_ENABLE
179                 case id_eeprom_reset:
180                 {
181                         eeprom_reset();
182                         break;
183                 }
184                 case id_bootloader_jump:
185                 {
186                         // Need to send data back before the jump
187                         // Informs host that the command is handled
188                         raw_hid_send( data, length );
189                         // Give host time to read it
190                         wait_ms(100);
191                         bootloader_jump();
192                         break;
193                 }
194                 default:
195                 {
196                         // Unhandled message.
197                         *command_id = id_unhandled;
198                         break;
199                 }
200         }
201
202         // Return same buffer with values changed
203         raw_hid_send( data, length );
204
205 }
206
207 #endif
208
209
210 void read_host_led_state(void) {
211   uint8_t leds = host_keyboard_leds();
212   if (leds & (1 << USB_LED_NUM_LOCK))    {
213     if (led_numlock == false){
214     led_numlock = true;}
215     } else {
216     if (led_numlock == true){
217     led_numlock = false;}
218     }
219   if (leds & (1 << USB_LED_CAPS_LOCK))   {
220     if (led_capslock == false){
221     led_capslock = true;}
222     } else {
223     if (led_capslock == true){
224     led_capslock = false;}
225     }
226   if (leds & (1 << USB_LED_SCROLL_LOCK)) {
227     if (led_scrolllock == false){
228     led_scrolllock = true;}
229     } else {
230     if (led_scrolllock == true){
231     led_scrolllock = false;}
232     }
233 }
234
235 uint32_t layer_state_set_kb(uint32_t state) {
236   state = layer_state_set_user(state);
237   layer = biton32(state);
238   queue_for_send = true;
239   return state;
240 }
241
242 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
243   queue_for_send = true;
244   switch (keycode) {
245     case OLED_TOGG:
246       if (record->event.pressed) {
247         oled_mode = (oled_mode + 1) % _NUM_OLED_MODES;
248         draw_ui();
249       }
250       return false;
251     case CLOCK_SET:
252       if (record->event.pressed) {
253         if(clock_set_mode){
254           pre_encoder_mode_change();
255           clock_set_mode = false;
256           encoder_mode = previous_encoder_mode;
257           post_encoder_mode_change();
258
259         }else{
260           previous_encoder_mode = encoder_mode;
261           pre_encoder_mode_change();
262           clock_set_mode = true;
263           encoder_mode = ENC_MODE_CLOCK_SET;
264           post_encoder_mode_change();
265         }
266       }
267       return false;
268     case ENC_PRESS:
269       if (record->event.pressed) {
270         uint16_t mapped_code = handle_encoder_press();
271         uint16_t held_keycode_timer = timer_read();
272         if(mapped_code != 0){
273           register_code(mapped_code);
274           while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
275           unregister_code(mapped_code);
276         }
277       } else {
278         // Do something else when release
279       }
280       return false;
281     default:
282       break;
283   }
284
285 #ifdef DYNAMIC_KEYMAP_ENABLE
286         // Handle macros
287         if (record->event.pressed) {
288                 if ( keycode >= MACRO00 && keycode <= MACRO15 )
289                 {
290                         uint8_t id = keycode - MACRO00;
291                         dynamic_keymap_macro_send(id);
292                         return false;
293                 }
294         }
295 #endif //DYNAMIC_KEYMAP_ENABLE
296
297   return process_record_user(keycode, record);
298 }
299
300
301 void encoder_update_kb(uint8_t index, bool clockwise) {
302   encoder_value = (encoder_value + (clockwise ? 1 : -1)) % 64;
303   queue_for_send = true;
304   if (index == 0) {
305     if (layer == 0){
306       uint16_t mapped_code = 0;
307       if (clockwise) {
308         mapped_code = handle_encoder_clockwise();
309       } else {
310         mapped_code = handle_encoder_ccw();
311       }
312       uint16_t held_keycode_timer = timer_read();
313       if(mapped_code != 0){
314         register_code(mapped_code);
315         while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
316         unregister_code(mapped_code);
317       }
318     } else {
319       if(clockwise){
320         change_encoder_mode(false);
321       } else {
322         change_encoder_mode(true);
323       }
324     }
325   }
326 }
327
328 void eeprom_init_kb(void)
329 {
330         // If the EEPROM has the magic, the data is good.
331         // OK to load from EEPROM.
332         if (eeprom_is_valid()) {
333                 //backlight_config_load();
334         } else  {
335                 // If the EEPROM has not been saved before, or is out of date,
336                 // save the default values to the EEPROM. Default values
337                 // come from construction of the zeal_backlight_config instance.
338                 //backlight_config_save();
339 #ifdef DYNAMIC_KEYMAP_ENABLE
340                 // This resets the keymaps in EEPROM to what is in flash.
341                 dynamic_keymap_reset();
342                 // This resets the macros in EEPROM to nothing.
343                 dynamic_keymap_macro_reset();
344 #endif
345                 // Save the magic number last, in case saving was interrupted
346                 eeprom_set_valid(true);
347         }
348 }
349
350 void matrix_init_kb(void)
351 {
352         eeprom_init_kb();
353   rtcGetTime(&RTCD1, &last_timespec);
354   queue_for_send = true;
355   backlight_init_ports();
356         matrix_init_user();
357 }
358
359
360 void matrix_scan_kb(void) {
361   rtcGetTime(&RTCD1, &last_timespec);
362   uint16_t minutes_since_midnight = last_timespec.millisecond / 1000 / 60;
363
364   if (minutes_since_midnight != last_minute){
365     last_minute = minutes_since_midnight;
366     if(!oled_sleeping){
367       queue_for_send = true;
368     }
369   }
370
371   if (queue_for_send && oled_mode != OLED_OFF) {
372     oled_sleeping = false;
373     read_host_led_state();
374     draw_ui();
375     queue_for_send = false;
376   }
377   if (timer_elapsed(last_flush) > ScreenOffInterval && !oled_sleeping) {
378     send_command(DISPLAYOFF);      /* 0xAE */
379     oled_sleeping = true;
380   }
381 }
382