diff --git a/software/sys_controller/memory/flash.c b/software/sys_controller/memory/flash.c index 4561bf4..dd54dae 100644 --- a/software/sys_controller/memory/flash.c +++ b/software/sys_controller/memory/flash.c @@ -83,6 +83,32 @@ int write_flash_page(alt_u8 *pagedata, alt_u32 length, alt_u32 pagenum) return 0; } +int write_flash(alt_u8 *buf, alt_u32 length, alt_u32 pagenum, alt_u8 *tmpbuf) +{ + int retval; + alt_u32 bytes_to_w; + + while (length > 0) { + bytes_to_w = (length > PAGESIZE) ? PAGESIZE : length; + + // Use a temporary buffer if one was given. + // This is to avoid the original buffer from + // being overwritten by write_flash_page(). + if (tmpbuf) + memcpy(tmpbuf, buf, bytes_to_w); + + retval = write_flash_page(tmpbuf ? tmpbuf : buf, bytes_to_w, pagenum); + if (retval != 0) + return retval; + + buf += bytes_to_w; + length -= bytes_to_w; + ++pagenum; + } + + return 0; +} + int verify_flash(alt_u32 offset, alt_u32 length, alt_u32 golden_crc, alt_u8 *tmpbuf) { alt_u32 crcval=0, i, bytes_to_read; diff --git a/software/sys_controller/memory/flash.h b/software/sys_controller/memory/flash.h index f049726..fa1c8ea 100644 --- a/software/sys_controller/memory/flash.h +++ b/software/sys_controller/memory/flash.h @@ -44,6 +44,8 @@ int read_flash(alt_u32 offset, alt_u32 length, alt_u8 *dstbuf); int write_flash_page(alt_u8 *pagedata, alt_u32 length, alt_u32 pagenum); +int write_flash(alt_u8 *buf, alt_u32 length, alt_u32 pagenum, alt_u8 *tmpbuf); + int verify_flash(alt_u32 offset, alt_u32 length, alt_u32 golden_crc, alt_u8 *tmpbuf); #endif /* FLASH_H_ */ diff --git a/software/sys_controller/memory/sdcard.c b/software/sys_controller/memory/sdcard.c index 092bbbf..4ff172b 100644 --- a/software/sys_controller/memory/sdcard.c +++ b/software/sys_controller/memory/sdcard.c @@ -19,6 +19,7 @@ #include #include "sdcard.h" +#include "flash.h" #include "lcd.h" extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; @@ -36,3 +37,28 @@ int check_sdcard(alt_u8 *databuf) return SD_Read(&sdcard_dev, databuf, 0, 0, 512); } + +int copy_sd_to_flash(alt_u32 sd_blknum, alt_u32 flash_pagenum, alt_u32 length, alt_u8 *tmpbuf) +{ + int retval; + alt_u32 bytes_to_rw; + + while (length > 0) { + bytes_to_rw = (length < SD_BLK_SIZE) ? length : SD_BLK_SIZE; + retval = SD_Read(&sdcard_dev, tmpbuf, sd_blknum, 0, bytes_to_rw); + if (retval != 0) { + printf("Failed to read SD card\n"); + return -retval; + } + + retval = write_flash(tmpbuf, bytes_to_rw, flash_pagenum, NULL); + if (retval != 0) + return retval; + + ++sd_blknum; + flash_pagenum += bytes_to_rw/PAGESIZE; + length -= bytes_to_rw; + } + + return 0; +} diff --git a/software/sys_controller/memory/sdcard.h b/software/sys_controller/memory/sdcard.h index 5f4a78e..7b41794 100644 --- a/software/sys_controller/memory/sdcard.h +++ b/software/sys_controller/memory/sdcard.h @@ -25,5 +25,6 @@ #include "sd_io.h" int check_sdcard(alt_u8 *databuf); +int copy_sd_to_flash(alt_u32 sd_offset, alt_u32 flash_offset, alt_u32 length, alt_u8 *tmpbuf); #endif /* SDCARD_H_ */ diff --git a/software/sys_controller/ossc/firmware.c b/software/sys_controller/ossc/firmware.c index e480591..e18a2d2 100644 --- a/software/sys_controller/ossc/firmware.c +++ b/software/sys_controller/ossc/firmware.c @@ -163,24 +163,9 @@ update_init: strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); lcd_write_menu(); - for (i=0; i PAGESIZE) { - retval = write_flash_page(databuf+PAGESIZE, (bytes_to_rw-PAGESIZE), (i/PAGESIZE)+1); - if (retval != 0) - goto failure; - } - } + retval = copy_sd_to_flash(512/SD_BLK_SIZE, 0, fw_header.data_len, databuf); + if (retval != 0) + goto failure; strncpy(menu_row1, "Verifying flash", LCD_ROW_LEN+1); strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); diff --git a/software/sys_controller/ossc/userdata.c b/software/sys_controller/ossc/userdata.c index 3059584..5e9f804 100644 --- a/software/sys_controller/ossc/userdata.c +++ b/software/sys_controller/ossc/userdata.c @@ -87,15 +87,8 @@ int write_userdata(alt_u8 entry) write_flash_page(databuf, PAGESIZE, ((USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE)); // then write the rest - pageno = 1; - while (vm_to_write > 0) { - bytes_to_w = (vm_to_write > PAGESIZE) ? PAGESIZE : vm_to_write; - memcpy(databuf, (char*)video_modes+srcoffset, bytes_to_w); - write_flash_page(databuf, bytes_to_w, ((USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE) + pageno); - srcoffset += bytes_to_w; - vm_to_write -= bytes_to_w; - ++pageno; - } + if (vm_to_write > 0) + write_flash((alt_u8*)video_modes+srcoffset, vm_to_write, ((USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE) + 1, databuf); printf("Profile %u data written (%u bytes)\n", entry, sizeof(avconfig_t)+VIDEO_MODES_SIZE); break;