124 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | |
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |
| 
 | |
| #include "drashna.h"
 | |
| #ifdef __AVR__
 | |
| #    include <avr/wdt.h>
 | |
| #endif
 | |
| 
 | |
| userspace_config_t userspace_config;
 | |
| 
 | |
| /**
 | |
|  * @brief Handle registering a keycode, with optional modifer based on timed event
 | |
|  *
 | |
|  * @param code keycode to send to host
 | |
|  * @param mod_code modifier to send with code, if held for tapping term or longer
 | |
|  * @param pressed the press/release event (can use "record->event.pressed" for this)
 | |
|  * @return true exits function
 | |
|  * @return false exits function
 | |
|  */
 | |
| bool mod_key_press_timer(uint16_t code, uint16_t mod_code, bool pressed) {
 | |
|     static uint16_t this_timer;
 | |
|     mod_key_press(code, mod_code, pressed, this_timer);
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief Handle registation of keycode, with optional modifier based on custom timer
 | |
|  *
 | |
|  * @param code keycode to send to host
 | |
|  * @param mod_code modifier keycode to send with code, if held for tapping term or longer
 | |
|  * @param pressed the press/release event
 | |
|  * @param this_timer custom timer to use
 | |
|  * @return true
 | |
|  * @return false
 | |
|  */
 | |
| bool mod_key_press(uint16_t code, uint16_t mod_code, bool pressed, uint16_t this_timer) {
 | |
|     if (pressed) {
 | |
|         this_timer = timer_read();
 | |
|     } else {
 | |
|         if (timer_elapsed(this_timer) < TAPPING_TERM) {
 | |
|             tap_code(code);
 | |
|         } else {
 | |
|             register_code(mod_code);
 | |
|             tap_code(code);
 | |
|             unregister_code(mod_code);
 | |
|         }
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief Performs exact match for modifier values
 | |
|  *
 | |
|  * @param value the modifer varible (get_mods/get_oneshot_mods/get_weak_mods)
 | |
|  * @param mask the modifier mask to check for
 | |
|  * @return true Has the exact modifiers specifed
 | |
|  * @return false Does not have the exact modifiers specified
 | |
|  */
 | |
| bool hasAllBitsInMask(uint8_t value, uint8_t mask) {
 | |
|     value &= 0xF;
 | |
|     mask &= 0xF;
 | |
| 
 | |
|     return (value & mask) == mask;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief Tap keycode, with no mods
 | |
|  *
 | |
|  * @param kc keycode to use
 | |
|  */
 | |
| void tap_code16_nomods(uint16_t kc) {
 | |
|     uint8_t temp_mod = get_mods();
 | |
|     clear_mods();
 | |
|     clear_oneshot_mods();
 | |
|     tap_code16(kc);
 | |
|     set_mods(temp_mod);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief Run shutdown routine and soft reboot firmware.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifdef HAPTIC_ENABLE
 | |
| #    include "haptic.h"
 | |
| #endif
 | |
| 
 | |
| #ifdef AUDIO_ENABLE
 | |
| #    ifndef GOODBYE_SONG
 | |
| #        define GOODBYE_SONG SONG(GOODBYE_SOUND)
 | |
| #    endif
 | |
| float reset_song[][2] = GOODBYE_SONG;
 | |
| #endif
 | |
| 
 | |
| void software_reset(void) {
 | |
|     clear_keyboard();
 | |
| #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
 | |
|     process_midi_all_notes_off();
 | |
| #endif
 | |
| #ifdef AUDIO_ENABLE
 | |
| #    ifndef NO_MUSIC_MODE
 | |
|     music_all_notes_off();
 | |
| #    endif
 | |
|     uint16_t timer_start = timer_read();
 | |
|     PLAY_SONG(reset_song);
 | |
|     shutdown_user();
 | |
|     while (timer_elapsed(timer_start) < 250) wait_ms(1);
 | |
|     stop_all_notes();
 | |
| #else
 | |
|     shutdown_user();
 | |
|     wait_ms(250);
 | |
| #endif
 | |
| #ifdef HAPTIC_ENABLE
 | |
|     haptic_shutdown();
 | |
| #endif
 | |
| 
 | |
| #if defined(PROTOCOL_LUFA)
 | |
|     wdt_enable(WDTO_250MS);
 | |
| #elif defined(PROTOCOL_CHIBIOS)
 | |
| #    if defined(MCU_STM32) || defined(MCU_KINETIS)
 | |
|     NVIC_SystemReset();
 | |
| #    endif
 | |
| #endif
 | |
| }
 | 
