]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - tmk_core/common/avr/bootloader.c
Move defines for RGB to after the config.h include
[qmk_firmware.git] / tmk_core / common / avr / bootloader.c
index cda295b1811e92f90baea342084b37a07139bcc1..34db8d0b0aa66c18538f978fac66e44f9938ed5c 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <avr/io.h>
+#include <avr/eeprom.h>
 #include <avr/interrupt.h>
 #include <avr/wdt.h>
 #include <util/delay.h>
 #endif
 
 
-/* Boot Section Size in *BYTEs*
- *   Teensy   halfKay    512
- *   Teensy++ halfKay    1024
- *   Atmel DFU loader    4096
- *   LUFA bootloader     4096
- *   USBaspLoader        2048
+/* Bootloader Size in *bytes*
+ *
+ * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet.
+ * Note that 'Word'(2 bytes) size and address are used in datasheet while TMK uses 'Byte'.
+ *
+ *
+ * Size of Bootloaders in bytes:
+ *   Atmel DFU loader(ATmega32U4)   4096
+ *   Atmel DFU loader(AT90USB128)   8192
+ *   LUFA bootloader(ATmega32U4)    4096
+ *   Arduino Caterina(ATmega32U4)   4096
+ *   USBaspLoader(ATmega***)        2048
+ *   Teensy   halfKay(ATmega32U4)   512
+ *   Teensy++ halfKay(AT90USB128)   1024
+ *
+ *
+ * AVR Boot section is located at the end of Flash memory like the followings.
+ *
+ *
+ * byte     Atmel/LUFA(ATMega32u4)          byte     Atmel(AT90SUB128)
+ * 0x0000   +---------------+               0x00000  +---------------+
+ *          |               |                        |               |
+ *          |               |                        |               |
+ *          |  Application  |                        |  Application  |
+ *          |               |                        |               |
+ *          =               =                        =               =
+ *          |               | 32KB-4KB               |               | 128KB-8KB
+ * 0x7000   +---------------+               0x1E000  +---------------+
+ *          |  Bootloader   | 4KB                    |  Bootloader   | 8KB
+ * 0x7FFF   +---------------+               0x1FFFF  +---------------+
+ *
+ *
+ * byte     Teensy(ATMega32u4)              byte     Teensy++(AT90SUB128)
+ * 0x0000   +---------------+               0x00000  +---------------+
+ *          |               |                        |               |
+ *          |               |                        |               |
+ *          |  Application  |                        |  Application  |
+ *          |               |                        |               |
+ *          =               =                        =               =
+ *          |               | 32KB-512B              |               | 128KB-1KB
+ * 0x7E00   +---------------+               0x1FC00  +---------------+
+ *          |  Bootloader   | 512B                   |  Bootloader   | 1KB
+ * 0x7FFF   +---------------+               0x1FFFF  +---------------+
  */
 #ifndef BOOTLOADER_SIZE
 #warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h.
@@ -27,8 +65,8 @@
 #define BOOTLOADER_START    (FLASH_SIZE - BOOTLOADER_SIZE)
 
 
-/* 
- * Entering the Bootloader via Software 
+/*
+ * Entering the Bootloader via Software
  * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
  */
 #define BOOTLOADER_RESET_KEY 0xB007B007
@@ -36,26 +74,57 @@ 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
+    #ifndef CATERINA_BOOTLOADER
 
-#ifdef PROTOCOL_PJRC
-    cli();
-    UDCON = 1;
-    USBCON = (1<<FRZCLK);
-    UCSR1B = 0;
-    _delay_ms(5);
-#endif
+        #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
+
+        #ifdef BOOTLOADHID_BOOTLOADER
+            // force bootloadHID to stay in bootloader mode, so that it waits
+            // for a new firmware to be flashed
+            eeprom_write_byte((uint8_t *)1, 0x00);
+        #endif
+
+        // watchdog reset
+        reset_key = BOOTLOADER_RESET_KEY;
+        wdt_enable(WDTO_250MS);
+        for (;;);
+
+    #else
+        // this block may be optional
+        // TODO: figure it out
+
+        uint16_t *const bootKeyPtr = (uint16_t *)0x0800;
 
-    // watchdog reset
-    reset_key = BOOTLOADER_RESET_KEY;
-    wdt_enable(WDTO_250MS);
-    for (;;);
+        // Value used by Caterina bootloader use to determine whether to run the
+        // sketch or the bootloader programmer.
+        uint16_t bootKey = 0x7777;
+
+        *bootKeyPtr = bootKey;
+
+        // setup watchdog timeout
+        wdt_enable(WDTO_60MS);
+
+        while(1) {} // wait for watchdog timer to trigger
+
+    #endif
 }
 
+#ifdef __AVR_ATmega32A__
+// MCUSR is actually called MCUCSR in ATmega32A
+#define MCUSR MCUCSR
+#endif
 
 /* this runs before main() */
 void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3")));
@@ -80,7 +149,7 @@ void bootloader_jump_after_watchdog_reset(void)
 #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?
  */