USBaspLoader v0.97 stable release
[pub/USBaspLoader.git] / firmware / spminterface.h
index f61f216..6c7a895 100644 (file)
@@ -4,7 +4,7 @@
  * Creation Date: 2012-08-01
  * Copyright: (c) 2013 by Stephan Baerwolf
  * License: GNU GPL v2 (see License.txt)
- * Version: 0.96.1
+ * Version: 0.97
  */
 
 #ifndef SPMINTERFACE_H_f70ba6adf7624275947e859bdbff0599
@@ -88,9 +88,11 @@ ret
 *
 */ 
 
-#include <avr/io.h>
 #include "bootloaderconfig.h"
 
+#ifndef SREG
+#      include <avr/io.h>
+#endif
 
 
 /*
@@ -110,7 +112,9 @@ ret
       #define  funcaddr___bootloader__do_spm (&bootloader__do_spm)
     #endif  
   #else
-    #if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
+    #if defined (__AVR_ATmega8535__)
+      #define  funcaddr___bootloader__do_spm 0x182a
+    #elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
       #define  funcaddr___bootloader__do_spm 0x1826
     #elif defined (__AVR_ATmega16__)
       #define  funcaddr___bootloader__do_spm 0x3854
@@ -118,6 +122,8 @@ ret
       #define  funcaddr___bootloader__do_spm 0x7054
     #elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__) || defined (__AVR_ATmega88A__) || defined (__AVR_ATmega88PA__)  
       #define  funcaddr___bootloader__do_spm 0x1834
+    #elif defined (__AVR_ATmega162__)
+      #define  funcaddr___bootloader__do_spm 0x3870
     #elif defined (__AVR_ATmega164A__) || defined (__AVR_ATmega164P__) || defined (__AVR_ATmega164PA__)  
       #define  funcaddr___bootloader__do_spm 0x387c
     #elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__) || defined (__AVR_ATmega168A__) || defined (__AVR_ATmega168PA__)  
@@ -128,7 +134,9 @@ ret
       #define  funcaddr___bootloader__do_spm 0x7068
     #elif defined (__AVR_ATmega640__)
       #define  funcaddr___bootloader__do_spm 0xe0e4
-    #elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__)
+    #elif defined (__AVR_ATmega644__)
+      #define  funcaddr___bootloader__do_spm 0xe070
+    #elif defined (__AVR_ATmega644A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__)
       #define  funcaddr___bootloader__do_spm 0xe07c
     #elif defined (__AVR_ATmega128__)
       #define  funcaddr___bootloader__do_spm 0x1e08c
@@ -146,7 +154,7 @@ ret
       #error "unknown MCU - where is bootloader__do_spm located?"
     #endif
 
-    #if defined(_VECTORS_SIZE)
+    #if ((defined(_VECTORS_SIZE)) && (defined(BOOTLOADER_ADDRESS)))
       #if (funcaddr___bootloader__do_spm != (BOOTLOADER_ADDRESS+_VECTORS_SIZE))
        #error "bootloader__do_spm is not located after interrupts - sth. is very wrong here!" 
       #endif
@@ -173,17 +181,23 @@ ret
  * REMEMBER: interrupts have to be disabled! (otherwise code may crash non-deterministic)
  * 
  */
+
+#define __do_spm_Ex(arguments...)      __do_spm_GeneralEx(HAVE_SPMINTEREFACE_MAGICVALUE, ##arguments)
+
+
 #if HAVE_SPMINTEREFACE_MAGICVALUE
-#define __do_spm_Ex    __do_spm_Ex_magic
+#define __do_spm_GeneralEx     __do_spm_ExASMEx_magic
 #else
-#define __do_spm_Ex    __do_spm_Ex_
+#define __do_spm_GeneralEx     __do_spm_ExASMEx_
 #endif
 
+
 #if (defined(EIND) && ((FLASHEND)>131071))
   /*
   * Huge flash version using eicall (and EIND)
+  * MV defines the magic value to be send to bootloader_do_spm
   */
-  #define __do_spm_Ex_(flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr)              \
+  #define __do_spm_ExASMEx_(MV, flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr)     \
   ({                                                                                                   \
       asm volatile (                                                                                   \
       "push r0\n\t"                                                                                    \
@@ -195,8 +209,8 @@ ret
                                                                                                        \
       /* prepare the EIND for following eicall */                                                      \
       "in r18, %[eind]\n\t"                                                                            \
-      "push r18\n\t"                                                                                   \
-      "ldi r18, %[spmfuncaddrEIND]\n\t"                                                                \
+      "push r18\n\t"                                                                                   \
+      "ldi r18, %[spmfuncaddrEIND]\n\t"                                                                        \
       "out %[eind], r18\n\t"                                                                           \
                                                                                                        \
       /* also load the spmcrval */                                                                     \
@@ -213,10 +227,10 @@ ret
                                                                                                        \
       /*                                                                                               \
       * bootloader__do_spm should change spmcrval (r18) to                                             \
-      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                \
+      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                        \
       */                                                                                               \
       "cpi r18, %[spmret]\n\t"                                                                         \
-      /* loop infitinte if not so, most likely we called an bootloader__do_spm                 \
+      /* loop infitinte if not so, most likely we called an bootloader__do_spm                         \
        * with wrong magic! To avoid calls to wrong initialized pages, better crash here...             \
        */                                                                                              \
   "loop%=: \n\t"                                                                                       \
@@ -237,16 +251,16 @@ ret
       );                                                                                               \
   })
 
-  #define __do_spm_Ex_magic(flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr) \
+  #define __do_spm_ExASMEx_magic(MV, flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr)        \
   ({                                                                                                   \
       asm volatile (                                                                                   \
       "push r0\n\t"                                                                                    \
       "push r1\n\t"                                                                                    \
                                                                                                        \
-      "ldi r23, %[magicD] \n\t"                                                                        \
-      "ldi r22, %[magicC] \n\t"                                                                        \
-      "ldi r21, %[magicB] \n\t"                                                                        \
-      "ldi r20, %[magicA] \n\t"                                                                        \
+      "ldi r23, %[magicD] \n\t"                                                                                \
+      "ldi r22, %[magicC] \n\t"                                                                                \
+      "ldi r21, %[magicB] \n\t"                                                                                \
+      "ldi r20, %[magicA] \n\t"                                                                                \
                                                                                                        \
       "mov r13, %B[flashaddress]\n\t"                                                                  \
       "mov r12, %A[flashaddress]\n\t"                                                                  \
@@ -255,7 +269,7 @@ ret
       /* prepare the EIND for following eicall */                                                      \
       "in r18, %[eind]\n\t"                                                                            \
       "push r18\n\t"                                                                                   \
-      "ldi r18, %[spmfuncaddrEIND]\n\t"                                                                \
+      "ldi r18, %[spmfuncaddrEIND]\n\t"                                                                        \
       "out %[eind], r18\n\t"                                                                           \
                                                                                                        \
       /* also load the spmcrval */                                                                     \
@@ -272,10 +286,10 @@ ret
                                                                                                        \
       /*                                                                                               \
       * bootloader__do_spm should change spmcrval (r18) to                                             \
-      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                \
+      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                        \
       */                                                                                               \
       "cpi r18, %[spmret]\n\t"                                                                         \
-      /* loop infitinte if not so, most likely we called an bootloader__do_spm                 \
+      /* loop infitinte if not so, most likely we called an bootloader__do_spm                         \
        * with wrong magic! To avoid calls to wrong initialized pages, better crash here...             \
        */                                                                                              \
   "loop%=: \n\t"                                                                                       \
@@ -285,17 +299,17 @@ ret
       "pop  r0\n\t"                                                                                    \
                                                                                                        \
       :                                                                                                        \
-      : [flashaddress] "r" (flash_wordaddress),                                                        \
+      : [flashaddress] "r" (flash_wordaddress),                                                                \
        [spmfunctionaddress] "z" ((uint16_t)(___bootloader__do_spm__ptr)),                              \
        [spmfuncaddrEIND]       "M" ((uint8_t)(___bootloader__do_spm__ptr>>16)),                        \
        [eind]                  "I" (_SFR_IO_ADDR(EIND)),                                               \
        [spmcrval] "r" (spmcrval),                                                                      \
        [data] "r" (dataword),                                                                          \
        [spmret] "M" ((1<<RWWSRE) | (1<<SPMEN)),                                                        \
-       [magicD] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>>24)&0xff),                                        \
-       [magicC] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>>16)&0xff),                                        \
-       [magicB] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 8)&0xff),                                        \
-       [magicA] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 0)&0xff)                                 \
+       [magicD] "M" (((MV)>>24)&0xff),                                                                 \
+       [magicC] "M" (((MV)>>16)&0xff),                                                                 \
+       [magicB] "M" (((MV)>> 8)&0xff),                                                                 \
+       [magicA] "M" (((MV)>> 0)&0xff)                                                                  \
       : "r0","r1","r11","r12","r13","r18","r20","r21","r22","r23"                                      \
       );                                                                                               \
   })
@@ -309,7 +323,7 @@ ret
     #error "Using inappropriate code for device with more than 128kib flash"
   #endif
   
-  #define __do_spm_Ex_(flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr)              \
+  #define __do_spm_ExASMEx_(MV, flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr)     \
   ({                                                                                                   \
       asm volatile (                                                                                   \
       "push r0\n\t"                                                                                    \
@@ -331,10 +345,10 @@ ret
                                                                                                        \
       /*                                                                                               \
       * bootloader__do_spm should change spmcrval (r18) to                                             \
-      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                \
+      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                        \
       */                                                                                               \
       "cpi r18, %[spmret]\n\t"                                                                         \
-      /* loop infitinte if not so, most likely we called an bootloader__do_spm                 \
+      /* loop infitinte if not so, most likely we called an bootloader__do_spm                         \
        * with wrong magic! To avoid calls to wrong initialized pages, better crash here...             \
        */                                                                                              \
   "loop%=: \n\t"                                                                                       \
@@ -344,25 +358,25 @@ ret
       "pop  r0\n\t"                                                                                    \
                                                                                                        \
       :                                                                                                        \
-      : [flashaddress] "r" (flash_wordaddress),                                                        \
+      : [flashaddress] "r" (flash_wordaddress),                                                                \
        [spmfunctionaddress] "z" ((uint16_t)(___bootloader__do_spm__ptr)),                              \
        [spmcrval] "r" (spmcrval),                                                                      \
        [data] "r" (dataword),                                                                          \
-       [spmret] "M" ((1<<RWWSRE) | (1<<SPMEN))                                                 \
+       [spmret] "M" ((1<<RWWSRE) | (1<<SPMEN))                                                         \
       : "r0","r1","r11","r12","r13","r18"                                                              \
       );                                                                                               \
   })
 
-  #define __do_spm_Ex_magic(flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr) \
+  #define __do_spm_ExASMEx_magic(MV, flash_wordaddress, spmcrval, dataword, ___bootloader__do_spm__ptr)        \
   ({                                                                                                   \
       asm volatile (                                                                                   \
       "push r0\n\t"                                                                                    \
       "push r1\n\t"                                                                                    \
                                                                                                        \
-      "ldi r23, %[magicD] \n\t"                                                                        \
-      "ldi r22, %[magicC] \n\t"                                                                        \
-      "ldi r21, %[magicB] \n\t"                                                                        \
-      "ldi r20, %[magicA] \n\t"                                                                        \
+      "ldi r23, %[magicD] \n\t"                                                                                \
+      "ldi r22, %[magicC] \n\t"                                                                                \
+      "ldi r21, %[magicB] \n\t"                                                                                \
+      "ldi r20, %[magicA] \n\t"                                                                                \
                                                                                                        \
       "mov r13, %B[flashaddress]\n\t"                                                                  \
       "mov r12, %A[flashaddress]\n\t"                                                                  \
@@ -380,11 +394,11 @@ ret
                                                                                                        \
       /*                                                                                               \
       * bootloader__do_spm should change spmcrval (r18) to                                             \
-      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                \
+      * "((1<<RWWSRE) | (1<<SPMEN))" in case of success                                                        \
       */                                                                                               \
       "cpi r18, %[spmret]\n\t"                                                                         \
-      /* loop infitinte if not so, most likely we called an bootloader__do_spm                 \
-       * with wrong magic! To avoid calls to wrong initialized pages, better crash here...     \
+      /* loop infitinte if not so, most likely we called an bootloader__do_spm                         \
+       * with wrong magic! To avoid calls to wrong initialized pages, better crash here...             \
        */                                                                                              \
   "loop%=: \n\t"                                                                                       \
       "brne loop%= \n\t"                                                                               \
@@ -393,15 +407,15 @@ ret
       "pop  r0\n\t"                                                                                    \
                                                                                                        \
       :                                                                                                        \
-      : [flashaddress] "r" (flash_wordaddress),                                                        \
+      : [flashaddress] "r" (flash_wordaddress),                                                                \
        [spmfunctionaddress] "z" ((uint16_t)(___bootloader__do_spm__ptr)),                              \
        [spmcrval] "r" (spmcrval),                                                                      \
        [data] "r" (dataword),                                                                          \
        [spmret] "M" ((1<<RWWSRE) | (1<<SPMEN)),                                                        \
-       [magicD] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>>24)&0xff),                                        \
-       [magicC] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>>16)&0xff),                                        \
-       [magicB] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 8)&0xff),                                        \
-       [magicA] "M" ((HAVE_SPMINTEREFACE_MAGICVALUE>> 0)&0xff)                                 \
+       [magicD] "M" (((MV)>>24)&0xff),                                                                 \
+       [magicC] "M" (((MV)>>16)&0xff),                                                                 \
+       [magicB] "M" (((MV)>> 8)&0xff),                                                                 \
+       [magicA] "M" (((MV)>> 0)&0xff)                                                                  \
       : "r0","r1","r11","r12","r13","r18","r20","r21","r22","r23"                                      \
       );                                                                                               \
   })
@@ -423,17 +437,14 @@ void do_spm(const uint32_t flash_byteaddress, const uint8_t spmcrval, const uint
 
 /*
  * insert architecture dependend "bootloader_do_spm"-code
- * 
- * try to make this array as big as possible
- * (so bootloader always uses 2kbytes flash)
  */
-#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__)
+#if defined (__AVR_ATmega8535__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega162__) || defined (__AVR_ATmega32__)
 
-#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
+#if defined (__AVR_ATmega8535__) || defined (__AVR_ATmega8__) || defined (__AVR_ATmega8A__) || defined (__AVR_ATmega8HVA__)
   #if (BOOTLOADER_ADDRESS != 0x1800)
     #error BOOTLOADER_ADDRESS!=0x1800, on current MCU "funcaddr___bootloader__do_spm" might be currupted - please edit spminterface.h for nonstandard use
   #endif
-#elif defined (__AVR_ATmega16__)
+#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega162__)
   #if (BOOTLOADER_ADDRESS != 0x3800)
     #error BOOTLOADER_ADDRESS!=0x3800, on current MCU "funcaddr___bootloader__do_spm" might be currupted - please edit spminterface.h for nonstandard use
   #endif
@@ -762,4 +773,4 @@ const uint16_t bootloader__do_spm[16] BOOTLIBLINK = {
 #endif
 
 #endif
-                                                
\ No newline at end of file
+