Implement userdata export.

A very simple implementation, as we are very short on remaining
block RAM. Simply blindly copies the entire userdata area to the
SD card. This may subject the SD card to some extra wear, as well
as potentially read-disturb some Flash memory pages, but this would
require more code.
This commit is contained in:
Ari Sundholm 2020-11-05 00:49:59 +02:00
parent 53eedc9d08
commit b890446e3d
7 changed files with 8633 additions and 9073 deletions

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@
//
#include <io.h>
#include <string.h>
#include "sdcard.h"
#include "flash.h"
#include "lcd.h"
@ -69,3 +70,33 @@ int copy_sd_to_flash(alt_u32 sd_blknum, alt_u32 flash_pagenum, alt_u32 length, a
return 0;
}
int copy_flash_to_sd(alt_u32 flash_pagenum, alt_u32 sd_blknum, alt_u32 length, alt_u8 *tmpbuf)
{
SDRESULTS res;
int retval;
alt_u32 bytes_to_rw;
while (length > 0) {
bytes_to_rw = (length < SD_BLK_SIZE) ? length : SD_BLK_SIZE;
retval = alt_epcq_controller_read(epcq_dev, flash_pagenum*PAGESIZE, tmpbuf, bytes_to_rw);
if (retval != 0)
return retval;
if (bytes_to_rw < SD_BLK_SIZE)
memset(tmpbuf+bytes_to_rw, 0, SD_BLK_SIZE-bytes_to_rw);
res = SD_Write(&sdcard_dev, tmpbuf, sd_blknum);
if (res != SD_OK) {
printf("Failed to write to SD card\n");
return -res;
}
++sd_blknum;
flash_pagenum += bytes_to_rw/PAGESIZE;
length -= bytes_to_rw;
}
return 0;
}

View File

@ -26,5 +26,6 @@
int check_sdcard(alt_u8 *databuf);
int copy_sd_to_flash(alt_u32 sd_blknum, alt_u32 flash_pagenum, alt_u32 length, alt_u8 *tmpbuf);
int copy_flash_to_sd(alt_u32 flash_pagenum, alt_u32 sd_blknum, alt_u32 length, alt_u8 *tmpbuf);
#endif /* SDCARD_H_ */

View File

@ -238,8 +238,9 @@ MENU(menu_settings, P99_PROTECT({ \
{ "OSD", OPT_AVCONFIG_SELECTION, { .sel = { &osd_enable_pre, OPT_WRAP, SETTING_ITEM(osd_enable_desc) } } },
{ "OSD status disp.", OPT_AVCONFIG_SELECTION, { .sel = { &osd_status_timeout_pre, OPT_WRAP, SETTING_ITEM(osd_status_desc) } } },
#ifndef DEBUG
{ "<Import sett. >", OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } },
{ LNG("<Fw. update >","<ファームウェアアップデート>"), OPT_FUNC_CALL, { .fun = { fw_update, NULL } } },
{ LNG("<Import sett. >","<セッテイヨミコミ >"), OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } },
{ LNG("<Export sett. >","<セッテイカキコミ >"), OPT_FUNC_CALL, { .fun = { export_userdata, NULL } } },
{ LNG("<Fw. update >","<ファームウェアアップデート>"), OPT_FUNC_CALL, { .fun = { fw_update, NULL } } },
#endif
}))

View File

@ -17,6 +17,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "userdata.h"
@ -26,6 +27,7 @@
#include "lcd.h"
#include "controls.h"
#include "av_controller.h"
#include "menu.h"
#include "altera_avalon_pio_regs.h"
extern alt_u16 rc_keymap[REMOTE_MAX_KEYS];
@ -42,7 +44,7 @@ extern alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
extern alt_u8 osd_enable_pre, osd_status_timeout_pre;
extern SD_DEV sdcard_dev;
extern alt_flash_dev *epcq_dev;
extern char menu_row2[LCD_ROW_LEN+1];
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
char target_profile_name[PROFILE_NAME_LEN+1];
@ -315,3 +317,75 @@ sd_disable:
return retval;
}
int export_userdata()
{
int retval;
char *errmsg;
alt_u8 databuf[SD_BLK_SIZE];
alt_u32 btn_vec;
retval = check_sdcard(databuf);
SPI_CS_High();
if (retval != 0) {
retval = -retval;
goto failure;
}
strncpy(menu_row1, "Profile export", LCD_ROW_LEN+1);
strncpy(menu_row2, "Export? 1=Y, 2=N", LCD_ROW_LEN+1);
ui_disp_menu(1);
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_EXPT_CANCELLED;
goto failure;
}
usleep(WAITLOOP_SLEEP_US);
}
strncpy(menu_row1, "Exporting", LCD_ROW_LEN+1);
menu_row2[0] = '\0';
ui_disp_menu(1);
/* This may wear the SD card a bit more than necessary... */
retval = copy_flash_to_sd(USERDATA_OFFSET/PAGESIZE, 512/SD_BLK_SIZE, (MAX_USERDATA_ENTRY + 1) * SECTORSIZE, databuf);
if (retval != 0)
goto failure;
SPI_CS_High();
strncpy(menu_row2, "Success", LCD_ROW_LEN+1);
ui_disp_menu(1);
return 1;
failure:
SPI_CS_High();
switch (retval) {
case SD_NOINIT:
errmsg = "No SD card det.";
break;
case -EINVAL:
errmsg = "Invalid params.";
break;
case UDATA_EXPT_CANCELLED:
errmsg = "Export cancelled";
break;
default:
errmsg = "SD/Flash error";
break;
}
strncpy(menu_row2, errmsg, LCD_ROW_LEN+1);
ui_disp_menu(1);
usleep(1000000);
render_osd_page();
return -1;
}

View File

@ -34,6 +34,7 @@
#define INIT_CONFIG_SLOT MAX_USERDATA_ENTRY
#define UDATA_IMPT_CANCELLED 104
#define UDATA_EXPT_CANCELLED 105
typedef enum {
UDE_INITCFG = 0,
@ -76,5 +77,6 @@ typedef struct {
int write_userdata(alt_u8 entry);
int read_userdata(alt_u8 entry, int dry_run);
int import_userdata();
int export_userdata();
#endif