From a5b329584ebd19d3d9684da30bb15a7d5986a9d3 Mon Sep 17 00:00:00 2001 From: Ari Sundholm Date: Fri, 3 Nov 2017 17:07:44 +0200 Subject: [PATCH 1/2] Factor writing to Flash memory and SD->Flash copying into functions This is in preparation for the feature to import settings from the SD card. --- software/sys_controller/memory/flash.c | 26 +++++++++++++++++++++++++ software/sys_controller/memory/flash.h | 2 ++ software/sys_controller/memory/sdcard.c | 26 +++++++++++++++++++++++++ software/sys_controller/memory/sdcard.h | 1 + software/sys_controller/ossc/firmware.c | 21 +++----------------- software/sys_controller/ossc/userdata.c | 11 ++--------- 6 files changed, 60 insertions(+), 27 deletions(-) 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; From 4984ecf41861946d8fa7964c0bd444b302845cf4 Mon Sep 17 00:00:00 2001 From: Ari Sundholm Date: Thu, 2 Nov 2017 17:08:30 +0200 Subject: [PATCH 2/2] Implement loading settings from SD card --- software/sys_controller/ossc/menu.c | 1 + software/sys_controller/ossc/userdata.c | 87 +++++++++++++++++++++++++ software/sys_controller/ossc/userdata.h | 3 + 3 files changed, 91 insertions(+) diff --git a/software/sys_controller/ossc/menu.c b/software/sys_controller/ossc/menu.c index a5cc849..ce3cffa 100644 --- a/software/sys_controller/ossc/menu.c +++ b/software/sys_controller/ossc/menu.c @@ -179,6 +179,7 @@ MENU(menu_settings, P99_PROTECT({ \ { LNG("","<セッテイオショキカ >"), OPT_FUNC_CALL, { .fun = { set_default_avconfig, NULL } } }, { LNG("Link prof->input","Link prof->input"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.link_av, OPT_WRAP, AV1_RGBs, AV_LAST, link_av_desc } } }, { LNG("Link input->prof","Link input->prof"), OPT_AVCONFIG_SELECTION, { .sel = { &profile_link, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, + { "", OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } }, { LNG("Initial input","ショキニュウリョク"), OPT_AVCONFIG_SELECTION, { .sel = { &def_input, OPT_WRAP, SETTING_ITEM(avinput_str) } } }, { "LCD BL timeout", OPT_AVCONFIG_SELECTION, { .sel = { &lcd_bl_timeout, OPT_WRAP, SETTING_ITEM(lcd_bl_timeout_desc) } } }, { LNG("","<ファームウェアアップデート>"), OPT_FUNC_CALL, { .fun = { fw_update, NULL } } }, diff --git a/software/sys_controller/ossc/userdata.c b/software/sys_controller/ossc/userdata.c index 5e9f804..2f985ed 100644 --- a/software/sys_controller/ossc/userdata.c +++ b/software/sys_controller/ossc/userdata.c @@ -18,11 +18,15 @@ // #include +#include #include "userdata.h" #include "flash.h" +#include "sdcard.h" #include "firmware.h" +#include "lcd.h" #include "controls.h" #include "av_controller.h" +#include "altera_avalon_pio_regs.h" extern alt_u16 rc_keymap[REMOTE_MAX_KEYS]; extern avmode_t cm; @@ -34,6 +38,8 @@ extern alt_u8 input_profiles[AV_LAST]; extern alt_u8 profile_sel; extern alt_u8 def_input, profile_link; extern alt_u8 lcd_bl_timeout; +extern SD_DEV sdcard_dev; +extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1]; int write_userdata(alt_u8 entry) { @@ -185,3 +191,84 @@ int read_userdata(alt_u8 entry) return 0; } + +int import_userdata() +{ + int retval; + char *errmsg; + alt_u8 databuf[SD_BLK_SIZE]; + ude_hdr header; + alt_u32 btn_vec; + + retval = check_sdcard(databuf); + SPI_CS_High(); + if (retval != 0) + goto failure; + + strncpy(menu_row1, "Import? 1=Y, 2=N", LCD_ROW_LEN+1); + *menu_row2 = '\0'; + lcd_write_menu(); + + while (1) { + btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK; + + if (btn_vec == rc_keymap[RC_BTN1]) { + break; + } else if (btn_vec == rc_keymap[RC_BTN2]) { + retval = UDATA_IMPT_CANCELLED; + goto failure; + } + + usleep(WAITLOOP_SLEEP_US); + } + + strncpy(menu_row1, "Loading settings", LCD_ROW_LEN+1); + strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1); + lcd_write_menu(); + + // Import the userdata + for (int n=0; n<=MAX_USERDATA_ENTRY; ++n) { + retval = SD_Read(&sdcard_dev, &header, (512+n*SECTORSIZE)/SD_BLK_SIZE, 0, sizeof(header)); + if (retval != 0) { + printf("Failed to read SD card\n"); + retval = -retval; + goto failure; + } + + if (strncmp(header.userdata_key, "USRDATA", 8)) { + printf("Not an userdata entry at %u\n", profile); + continue; + } + + if ((header.version_major != FW_VER_MAJOR) || (header.version_minor != FW_VER_MINOR)) { + printf("Data version %u.%u does not match fw\n", header->version_major, header->version_minor); + continue; + } + + if (header.type > UDE_PROFILE) { + printf("Unknown userdata entry\n", header->type); + continue; + } + + // Just blindly write the entry to flash + retval = copy_sd_to_flash((512+n*SECTORSIZE)/SD_BLK_SIZE, (n*PAGES_PER_SECTOR)+(USERDATA_OFFSET/PAGESIZE), + (header.type == UDE_PROFILE) ? sizeof(ude_profile) : sizeof(ude_initcfg), databuf); + if (retval != 0) { + printf("Copy from SD to flash failed (error %d)\n", retval); + goto failure; + } + } + + SPI_CS_High(); + + read_userdata(INIT_CONFIG_SLOT); + profile_sel = input_profiles[target_input]; + read_userdata(profile_sel); + + return 0; + +failure: + SPI_CS_High(); + + return -1; +} diff --git a/software/sys_controller/ossc/userdata.h b/software/sys_controller/ossc/userdata.h index 93b539e..2e08903 100644 --- a/software/sys_controller/ossc/userdata.h +++ b/software/sys_controller/ossc/userdata.h @@ -31,6 +31,8 @@ #define MAX_PROFILE 9 #define INIT_CONFIG_SLOT MAX_USERDATA_ENTRY +#define UDATA_IMPT_CANCELLED 104 + typedef enum { UDE_INITCFG = 0, UDE_PROFILE, @@ -64,5 +66,6 @@ typedef struct { int write_userdata(alt_u8 entry); int read_userdata(alt_u8 entry); +int import_userdata(); #endif