USBaspLoader v0.97 stable release
[pub/USBaspLoader.git] / updater / updater.c
index b1760fa..479df80 100644 (file)
@@ -2,6 +2,8 @@
   #define F_CPU 1000000UL /* 1 Mhz-Takt; hier richtigen Wert eintragen */
 #endif
 
+
+#include "../misc/iofixes.h"
 #include "../firmware/spminterface.h"
 #include "usbasploader.h"
 
@@ -15,7 +17,6 @@
 #endif
 
 
-#include <avr/io.h>
 #include <avr/interrupt.h>
 #include <avr/wdt.h>
 
 #include <util/delay.h>
 #include <string.h>
 
+#define        updater_pagefillcode    ((1<<SPMEN))
+#define        updater_pageerasecode   ((1<<PGERS) | (1<<SPMEN))
+#define        updater_pagewritecode   ((1<<PGWRT) | (1<<SPMEN))
+
+
 #include "../firmware/bootloaderconfig.h"
 #if !HAVE_SPMINTEREFACE
   #error "bootloader does not support updating itself! (HAVE_SPMINTEREFACE)"
@@ -124,6 +130,25 @@ void temp_do_spm(const uint32_t flash_byteaddress, const uint8_t spmcrval, const
 typedef uint32_t mypgm_addr_t;
 typedef void (*mypgm_spminterface)(const uint32_t flash_byteaddress, const uint8_t spmcrval, const uint16_t dataword);
 
+#if FLASHEND > 65535
+#      define  FULLCORRECTFLASHADDRESS(addr)   (((mypgm_addr_t)(addr)) | (((mypgm_addr_t)FLASHADDRESS) & ((mypgm_addr_t)0xffff0000)))
+#      define  mymemcpy_PF mymemcpy_PF_far
+void *mymemcpy_PF_far (void *dest, mypgm_addr_t src, size_t n) {
+  uint8_t      *pagedata       = (void*)dest;
+  mypgm_addr_t  pageaddr       = src;
+  size_t       i;
+
+  for (i=0;i<n;i+=1) {
+    pagedata[i]=pgm_read_byte_far(pageaddr);
+    pageaddr+=1;
+  }
+
+  return dest;
+}
+#else
+#      define  FULLCORRECTFLASHADDRESS(addr)   (addr)
+#      define  mymemcpy_PF memcpy_PF 
+#endif
 
 #if 0
 size_t mypgm_readpage(const mypgm_addr_t byteaddress,const void* buffer, const size_t bufferbytesize) {
@@ -134,7 +159,7 @@ size_t mypgm_readpage(const mypgm_addr_t byteaddress,const void* buffer, const s
   size_t       i;
   
   for (i=0;i<pagesize;i+=1) {
-    pagedata[i]=pgm_read_word(pageaddr);
+    pagedata[i]=pgm_read_word_far(pageaddr);
     pageaddr+=2;
   }
   
@@ -146,7 +171,7 @@ size_t mypgm_readpage(const mypgm_addr_t byteaddress,const void* buffer, const s
   size_t       result          = (bufferbytesize < SPM_PAGESIZE)?bufferbytesize:SPM_PAGESIZE;
   mypgm_addr_t pageaddr        = byteaddress - (byteaddress % SPM_PAGESIZE);
   
-  memcpy_PF((void*)buffer, (uint_farptr_t)pageaddr, result);
+  mymemcpy_PF((void*)buffer, (uint_farptr_t)pageaddr, result);
   
   return result;
 }
@@ -166,7 +191,11 @@ size_t mypgm_WRITEpage(const mypgm_addr_t byteaddress,const void* buffer, const
   
   // just check, if page needs a rewrite or an erase...
   for (i=0;i<pagesize;i+=1) {
+#if (FLASHEND > 65535)
+    deeword=pgm_read_word_far(pageaddr);
+#else
     deeword=pgm_read_word(pageaddr);
+#endif
 
     if (deeword != pagedata[i]) changed=1;
 
@@ -191,7 +220,7 @@ size_t mypgm_WRITEpage(const mypgm_addr_t byteaddress,const void* buffer, const
     
     if (needs_erase) {
       //do a page-erase, ATTANTION: flash only can be erased a limited number of times !
-      spmfunc(pageaddr_bakup, 0x3, 0);
+      spmfunc(pageaddr_bakup, updater_pageerasecode, 0);
     }
     
     // from now on, the page is assumed empty !! (hopefully our code is located somewhere else!)
@@ -199,12 +228,12 @@ size_t mypgm_WRITEpage(const mypgm_addr_t byteaddress,const void* buffer, const
     // ATTANTION: see comment on "do_spm" !
     pageaddr   = pageaddr_bakup;
     for (i=0;i<pagesize;i+=1) {
-      spmfunc(pageaddr, 0x1, pagedata[i]);
+      spmfunc(pageaddr, updater_pagefillcode, pagedata[i]);
       pageaddr+=2;
     }
     
     // so, now finally write the page to the FLASH
-    spmfunc(pageaddr_bakup, 0x5, 0);
+    spmfunc(pageaddr_bakup, updater_pagewritecode, 0);
   } else {
     // no change - no write...
     result = 0;
@@ -224,39 +253,67 @@ size_t mypgm_WRITEpage(const mypgm_addr_t byteaddress,const void* buffer, const
   size_t       i;
     
   //do a page-erase, ATTANTION: flash only can be erased a limited number of times !
-  spmfunc(pageaddr_bakup, 0x3, 0);
+  spmfunc(pageaddr_bakup, updater_pageerasecode, 0);
     
   // from now on, the page is assumed empty !! (hopefully our code is located somewhere else!)
   // now, fill the tempoary buffer
   // ATTANTION: see comment on "do_spm" !
   pageaddr     = pageaddr_bakup;
   for (i=0;i<pagesize;i+=1) {
-    spmfunc(pageaddr, 0x1, pagedata[i]);
+    spmfunc(pageaddr, updater_pagefillcode, pagedata[i]);
     pageaddr+=2;
   }
     
   // so, now finally write the page to the FLASH
-  spmfunc(pageaddr_bakup, 0x5, 0);
+  spmfunc(pageaddr_bakup, updater_pagewritecode, 0);
   
   return result;
 }
 #endif
 
+#if defined(UPDATECRC32)
+#include "crccheck.c"
+#endif
+
 // #pragma GCC diagnostic ignored "-Wno-pointer-to-int-cast"
 int main(void)
 {
+#if defined(UPDATECRC32)
+    uint32_t crcval;
+#endif
     size_t  i;
     uint8_t buffer[SPM_PAGESIZE];
     
     wdt_disable();
     cli();
 
+#if defined(UPDATECRC32)
+    // check if new firmware-image is corrupted
+    crcval = D_32;
+    for (i=0;i<SIZEOF_new_firmware;i+=1) {
+#if (FLASHEND > 65535)
+      crcval = update_crc_32(crcval, pgm_read_byte_far(FULLCORRECTFLASHADDRESS(&new_firmware[i])));
+#else
+      crcval = update_crc_32(crcval, pgm_read_byte(FULLCORRECTFLASHADDRESS(&new_firmware[i])));
+#endif
+    }
+    crcval ^= D_32;
+
+    // allow to change the firmware
+    if (crcval == ((uint32_t)UPDATECRC32)) {
+#endif
+
     // check if firmware would change...
     buffer[0]=0;
     for (i=0;i<SIZEOF_new_firmware;i+=2) {
       uint16_t a, b;
-      a=pgm_read_word((void*)&new_firmware[i]);
+#if (FLASHEND > 65535)
+      a=pgm_read_word_far(FULLCORRECTFLASHADDRESS(&new_firmware[i]));
+      b=pgm_read_word_far(NEW_BOOTLOADER_ADDRESS+i);
+#else
+      a=pgm_read_word(FULLCORRECTFLASHADDRESS(&new_firmware[i]));
       b=pgm_read_word(NEW_BOOTLOADER_ADDRESS+i);
+#endif
       if (a!=b) {
        buffer[0]=1;
        break;
@@ -268,7 +325,6 @@ int main(void)
     // need to change the firmware...
     if (buffer[0]) {
 
-
       // A
       // copy the current "bootloader__do_spm" to tempoary position via std. "bootloader__do_spm"
       for (i=0;i<TEMP_SPM_BLKSIZE;i+=SPM_PAGESIZE) {
@@ -282,7 +338,7 @@ int main(void)
 #ifdef CONFIG_UPDATER_CLEANMEMCLEAR
        memset((void*)buffer, 0xff, sizeof(buffer));
 #endif
-       memcpy_PF((void*)buffer, (uint_farptr_t)((void*)&new_firmware[i]), ((SIZEOF_new_firmware-i)>sizeof(buffer))?sizeof(buffer):(SIZEOF_new_firmware-i));
+       mymemcpy_PF((void*)buffer, (uint_farptr_t)(FULLCORRECTFLASHADDRESS(&new_firmware[i])), ((SIZEOF_new_firmware-i)>sizeof(buffer))?sizeof(buffer):(SIZEOF_new_firmware-i));
        
        mypgm_WRITEpage(NEW_BOOTLOADER_ADDRESS+i, buffer, sizeof(buffer), temp_do_spm);
        
@@ -295,7 +351,7 @@ int main(void)
 #ifdef CONFIG_UPDATER_CLEANMEMCLEAR
        memset((void*)buffer, 0xff, sizeof(buffer));
 #endif
-       memcpy_PF((void*)buffer, (uint_farptr_t)((void*)&new_firmware[i]), ((SIZEOF_new_firmware-i)>sizeof(buffer))?sizeof(buffer):(SIZEOF_new_firmware-i));
+       mymemcpy_PF((void*)buffer, (uint_farptr_t)(FULLCORRECTFLASHADDRESS(&new_firmware[i])), ((SIZEOF_new_firmware-i)>sizeof(buffer))?sizeof(buffer):(SIZEOF_new_firmware-i));
 
        mypgm_WRITEpage(NEW_BOOTLOADER_ADDRESS+i, buffer, sizeof(buffer), new_do_spm);
        
@@ -305,4 +361,9 @@ int main(void)
 
     }
 
+#if defined(UPDATECRC32)
+    }
+#endif
+
+    return 0;
 }