#define F_CPU 1000000UL /* 1 Mhz-Takt; hier richtigen Wert eintragen */
#endif
+
+#include "../misc/iofixes.h"
#include "../firmware/spminterface.h"
#include "usbasploader.h"
#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)"
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) {
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;
}
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;
}
// 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;
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!)
// 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;
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;
// 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) {
#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);
#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);
}
+#if defined(UPDATECRC32)
+ }
+#endif
+
+ return 0;
}