qmk

QMK Firmware
git clone git://git.z3bra.org/qmk.git
Log | Files | Refs | Submodules | LICENSE

satisfaction75.c (12094B)


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