diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/bootloader.c | 100 | ||||
-rw-r--r-- | common/bootmagic.c | 45 | ||||
-rw-r--r-- | common/bootmagic.h | 39 | ||||
-rw-r--r-- | common/command.c | 4 | ||||
-rw-r--r-- | common/keyboard.c | 25 |
5 files changed, 164 insertions, 49 deletions
diff --git a/common/bootloader.c b/common/bootloader.c index 6e04efbbd..77fa1b30a 100644 --- a/common/bootloader.c +++ b/common/bootloader.c @@ -1,15 +1,16 @@ +#include <stdint.h> +#include <stdbool.h> #include <avr/io.h> #include <avr/interrupt.h> +#include <avr/wdt.h> #include <util/delay.h> #include "bootloader.h" -/* Start Bootloader from Application - * See - * http://www.pjrc.com/teensy/jump_to_bootloader.html - * http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/_page__software_bootloader_start.html - */ +#ifdef PROTOCOL_LUFA +#include <LUFA/Drivers/USB/USB.h> +#endif + -// TODO: support usbasp /* Boot Section Size in bytes * Teensy halfKay 512 * Atmel DFU loader 4096 @@ -18,28 +19,82 @@ #ifndef BOOT_SIZE #define BOOT_SIZE 512 #endif - #define FLASH_SIZE (FLASHEND + 1) -#define BOOTLOADER_START (FLASHEND - BOOT_SIZE) +#define BOOTLOADER_START (FLASH_SIZE - BOOT_SIZE) + +/* + * Entering the Bootloader via Software + * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html + */ +#define BOOTLOADER_RESET_KEY 0xB007B007 +uint32_t reset_key __attribute__ ((section (".noinit"))); + +/* initialize MCU status by watchdog reset */ void bootloader_jump(void) { +#ifdef PROTOCOL_LUFA + USB_Disable(); cli(); + _delay_ms(2000); +#endif - // - //Teensy - // -#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) - // disable watchdog, if enabled - // disable all peripherals +#ifdef PROTOCOL_PJRC + cli(); UDCON = 1; - USBCON = (1<<FRZCLK); // disable USB + USBCON = (1<<FRZCLK); UCSR1B = 0; _delay_ms(5); -#else - // This makes custom USBasploader come up. - MCUSR = 0; #endif + // watchdog reset + reset_key = BOOTLOADER_RESET_KEY; + wdt_enable(WDTO_250MS); + for (;;); +} + + +/* this runs before main() */ +void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3"))); +void bootloader_jump_after_watchdog_reset(void) +{ + if ((MCUSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { + + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) + // This makes custom USBasploader come up. + MCUSR = 0; + #endif + + reset_key = 0; + ((void (*)(void))BOOTLOADER_START)(); + } +} + + +#if 0 +/* Jumping To The Bootloader + * http://www.pjrc.com/teensy/jump_to_bootloader.html + * + * This method doen't work when using LUFA. idk why. + * - needs to initialize more regisers or interrupt setting? + */ +void bootloader_jump(void) { +#ifdef PROTOCOL_LUFA + USB_Disable(); + cli(); + _delay_ms(2000); +#endif + +#ifdef PROTOCOL_PJRC + cli(); + UDCON = 1; + USBCON = (1<<FRZCLK); + UCSR1B = 0; + _delay_ms(5); +#endif + + /* + * Initialize + */ #if defined(__AVR_AT90USB162__) EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0; @@ -62,10 +117,9 @@ void bootloader_jump(void) { PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; #endif - - // - //USBasp - // + /* + * USBaspLoader + */ #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) // This makes custom USBasploader come up. MCUSR = 0; @@ -81,7 +135,7 @@ void bootloader_jump(void) { ADCSRA = 0; TWCR = 0; UCSR0B = 0; #endif - // start Bootloader ((void (*)(void))BOOTLOADER_START)(); } +#endif diff --git a/common/bootmagic.c b/common/bootmagic.c new file mode 100644 index 000000000..31b8ae5e6 --- /dev/null +++ b/common/bootmagic.c @@ -0,0 +1,45 @@ +#include <stdint.h> +#include <stdbool.h> +#include <util/delay.h> +#include "matrix.h" +#include "keymap.h" +#include "eeconfig.h" +#include "bootloader.h" +#include "bootmagic.h" + + +void bootmagic(void) +{ + /* do scans in case of bounce */ + uint8_t scan = 100; + while (scan--) { matrix_scan(); _delay_ms(1); } + + if (!BOOTMAGIC_IS_ENABLE()) { return; } + + if (bootmagic_scan_keycode(BOOTMAGIC_BOOTLOADER_KEY)) { + bootloader_jump(); + } + + if (bootmagic_scan_keycode(BOOTMAGIC_DEBUG_ENABLE_KEY)) { + eeconfig_write_debug(eeconfig_read_debug() ^ EECONFIG_DEBUG_ENABLE); + } + + if (bootmagic_scan_keycode(BOOTMAGIC_EEPROM_CLEAR_KEY)) { + eeconfig_init(); + } +} + +bool bootmagic_scan_keycode(uint8_t keycode) +{ + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + matrix_row_t matrix_row = matrix_get_row(r); + for (uint8_t c = 0; c < MATRIX_COLS; c++) { + if (matrix_row & ((matrix_row_t)1<<c)) { + if (keycode == keymap_key_to_keycode(0, (key_t){ .row = r, .col = c })) { + return true; + } + } + } + } + return false; +} diff --git a/common/bootmagic.h b/common/bootmagic.h new file mode 100644 index 000000000..7aa224def --- /dev/null +++ b/common/bootmagic.h @@ -0,0 +1,39 @@ +#ifndef BOOTMAGIC_H +#define BOOTMAGIC_H + + +#ifndef BOOTMAGIC_IS_ENABLE +#define BOOTMAGIC_IS_ENABLE() true +#endif + +/* bootloader */ +#ifndef BOOTMAGIC_BOOTLOADER_KEY +#define BOOTMAGIC_BOOTLOADER_KEY KC_B +#endif +/* debug enable */ +#ifndef BOOTMAGIC_DEBUG_ENABLE_KEY +#define BOOTMAGIC_DEBUG_ENABLE_KEY KC_D +#endif +/* eeprom clear */ +#ifndef BOOTMAGIC_EEPROM_CLEAR_KEY +#define BOOTMAGIC_EEPROM_CLEAR_KEY KC_BSPACE +#endif + +/* change default layer */ +#ifndef BOOTMAGIC_DEFAULT_LAYER_0_KEY +#define BOOTMAGIC_DEFAULT_LAYER_0_KEY KC_0 +#endif +#ifndef BOOTMAGIC_DEFAULT_LAYER_1_KEY +#define BOOTMAGIC_DEFAULT_LAYER_1_KEY KC_1 +#endif +#ifndef BOOTMAGIC_DEFAULT_LAYER_2_KEY +#define BOOTMAGIC_DEFAULT_LAYER_2_KEY KC_2 +#endif +#ifndef BOOTMAGIC_DEFAULT_LAYER_3_KEY +#define BOOTMAGIC_DEFAULT_LAYER_3_KEY KC_3 +#endif + +void bootmagic(void); +bool bootmagic_scan_keycode(uint8_t keycode); + +#endif diff --git a/common/command.c b/common/command.c index 40932e050..b82d1884c 100644 --- a/common/command.c +++ b/common/command.c @@ -109,7 +109,7 @@ static void command_common_help(void) print("v: print device version & info\n"); print("t: print timer count\n"); print("s: print status\n"); - print("e: print eeprom config\n"); + print("e: print eeprom boot config\n"); #ifdef NKRO_ENABLE print("n: toggle NKRO\n"); #endif @@ -127,8 +127,6 @@ static void print_eeprom_config(void) { uint8_t eebyte; - print("magic: "); print_hex16(eeprom_read_word((uint16_t)0)); print("\n"); - eebyte = eeconfig_read_debug(); print("debug: "); print_hex8(eebyte); print("\n"); diff --git a/common/keyboard.c b/common/keyboard.c index 2206f1675..0a0bacd43 100644 --- a/common/keyboard.c +++ b/common/keyboard.c @@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "command.h" #include "util.h" #include "sendchar.h" -#include "bootloader.h" +#include "bootmagic.h" #ifdef MOUSEKEY_ENABLE #include "mousekey.h" #endif @@ -64,27 +64,7 @@ void keyboard_init(void) ps2_mouse_init(); #endif - /* matrix scan for boot magic keys */ -#ifdef DEBOUNCE - uint8_t scan = DEBOUNCE * 2; - while (scan--) { matrix_scan(); _delay_ms(1); } -#else - matrix_scan(); -#endif - - /* boot magic keys */ -#ifdef IS_BOOTMAGIC_BOOTLOADER - /* kick up bootloader */ - if (IS_BOOTMAGIC_BOOTLOADER()) bootloader_jump(); -#endif -#ifdef IS_BOOTMAGIC_DEBUG - if (IS_BOOTMAGIC_DEBUG()) { - eeconfig_write_debug(eeconfig_read_debug() ^ EECONFIG_DEBUG_ENABLE); - } -#endif -#ifdef IS_BOOTMAGIC_EEPROM_CLEAR - if (IS_BOOTMAGIC_EEPROM_CLEAR()) eeconfig_init(); -#endif + bootmagic(); if (eeconfig_initialized()) { uint8_t config; @@ -96,7 +76,6 @@ void keyboard_init(void) } else { eeconfig_init(); } - } /* |