diff options
author | tmk <nobody@nowhere> | 2013-03-09 11:22:27 +0900 |
---|---|---|
committer | tmk <nobody@nowhere> | 2013-03-09 11:22:27 +0900 |
commit | 4d64fd8faa8b1a0ceb9019446ba6915aaf1812ea (patch) | |
tree | 25410ede4bbf7d5a8994bb385e6c7ee4ad2f4c0c | |
parent | 359b68d35f0763ab0cafa2fb800e0a3497291f95 (diff) | |
download | firmware-4d64fd8faa8b1a0ceb9019446ba6915aaf1812ea.tar.gz firmware-4d64fd8faa8b1a0ceb9019446ba6915aaf1812ea.tar.bz2 firmware-4d64fd8faa8b1a0ceb9019446ba6915aaf1812ea.zip |
Add bootmagic.c and fix bootloader_jump
-rw-r--r-- | common.mk | 1 | ||||
-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 | ||||
-rw-r--r-- | keyboard/gh60/keymap.c | 6 | ||||
-rw-r--r-- | protocol/lufa.mk | 4 | ||||
-rw-r--r-- | protocol/pjrc.mk | 8 |
9 files changed, 178 insertions, 54 deletions
@@ -10,6 +10,7 @@ SRC += $(COMMON_DIR)/host.c \ $(COMMON_DIR)/print.c \ $(COMMON_DIR)/debug.c \ $(COMMON_DIR)/bootloader.c \ + $(COMMON_DIR)/bootmagic.c \ $(COMMON_DIR)/eeconfig.c \ $(COMMON_DIR)/util.c 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(); } - } /* diff --git a/keyboard/gh60/keymap.c b/keyboard/gh60/keymap.c index 1f5344d4c..d6af16961 100644 --- a/keyboard/gh60/keymap.c +++ b/keyboard/gh60/keymap.c @@ -231,7 +231,8 @@ uint8_t keymap_key_to_keycode(uint8_t layer, key_t key) if (layer < OVERLAYS_SIZE) { return pgm_read_byte(&overlays[(layer)][(key.row)][(key.col)]); } else { - debug("key_to_keycode: overlay "); debug_dec(layer); debug(" is invalid.\n"); + // XXX: this may cuaes bootlaoder_jump incositent fail. + //debug("key_to_keycode: overlay "); debug_dec(layer); debug(" is invalid.\n"); return KC_TRANSPARENT; } } @@ -240,8 +241,9 @@ uint8_t keymap_key_to_keycode(uint8_t layer, key_t key) if (layer < KEYMAPS_SIZE) { return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]); } else { + // XXX: this may cuaes bootlaoder_jump incositent fail. + //debug("key_to_keycode: base "); debug_dec(layer); debug(" is invalid.\n"); // fall back to layer 0 - debug("key_to_keycode: base "); debug_dec(layer); debug(" is invalid.\n"); return pgm_read_byte(&keymaps[0][(key.row)][(key.col)]); } } diff --git a/protocol/lufa.mk b/protocol/lufa.mk index 443b85344..8ea071afb 100644 --- a/protocol/lufa.mk +++ b/protocol/lufa.mk @@ -39,4 +39,6 @@ LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENAB OPT_DEFS += -DF_USB=$(F_USB)UL OPT_DEFS += -DARCH=ARCH_$(ARCH) OPT_DEFS += $(LUFA_OPTS) -OPT_DEFS += -DHOST_LUFA + +# This indicates using LUFA stack +OPT_DEFS += -DPROTOCOL_LUFA diff --git a/protocol/pjrc.mk b/protocol/pjrc.mk index cccdf6204..f5693ba99 100644 --- a/protocol/pjrc.mk +++ b/protocol/pjrc.mk @@ -1,7 +1,5 @@ PJRC_DIR = protocol/pjrc -OPT_DEFS += -DHOST_PJRC - SRC += $(PJRC_DIR)/main.c \ $(PJRC_DIR)/pjrc.c \ $(PJRC_DIR)/usb_keyboard.c \ @@ -19,3 +17,9 @@ endif # Search Path VPATH += $(TOP_DIR)/$(PJRC_DIR) + +# This indicates using LUFA stack +# TODO: remove HOST_PJRC +OPT_DEFS += -DHOST_PJRC +OPT_DEFS += -DPROTOCOL_PJRC + |