Pi Firmware: CPLD Update Menu populated dynamically

Change-Id: Iaa1590970341fc73d1b60ea0874e734e87f5f4a2
embedded_cpld_programming
David Banks 2019-06-19 15:42:33 +01:00
rodzic 046560e557
commit 6c8fbbcb25
4 zmienionych plików z 94 dodań i 5 usunięć

Wyświetl plik

@ -217,6 +217,8 @@ typedef struct {
#define SYNC_BIT_MIXED_SYNC 0x08 // bit 3, indicates H and V syncs eored in CPLD
#define SYNC_BIT_MASK 0x07 // masks out bit 3
#define MAX_CPLD_FILENAMES 16
#define MAX_FILENAME_WIDTH 32
#define MAX_PROFILES 64
#define MAX_SUB_PROFILES 32
#define MAX_PROFILE_WIDTH 32

Wyświetl plik

@ -367,6 +367,38 @@ static int string_compare (const void * s1, const void * s2) {
return strcmp (s1, s2);
}
void scan_cpld_filenames(char cpld_filenames[MAX_CPLD_FILENAMES][MAX_FILENAME_WIDTH], char *path, int *count) {
FRESULT res;
DIR dir;
FILINFO fno;
*count = 0;
init_filesystem();
res = f_opendir(&dir, path);
if (res == FR_OK) {
while (1) {
res = f_readdir(&dir, &fno);
if (res != FR_OK || fno.fname[0] == 0 || *count == MAX_CPLD_FILENAMES) {
break;
}
if (!(fno.fattrib & AM_DIR)) {
if ((strlen(fno.fname) > 5) != 0) {
char* filetype = fno.fname + strlen(fno.fname)-5;
if (strcmp(filetype, ".xsvf") == 0) {
strncpy(cpld_filenames[*count], fno.fname, MAX_FILENAME_WIDTH);
cpld_filenames[*count][strlen(fno.fname) - 5] = 0;
(*count)++;
}
}
}
}
f_closedir(&dir);
qsort(cpld_filenames, *count, sizeof *cpld_filenames, string_compare);
}
close_filesystem();
}
void scan_profiles(char profile_names[MAX_PROFILES][MAX_PROFILE_WIDTH], int has_sub_profiles[MAX_PROFILES], char *path, size_t *count) {
FRESULT res;
DIR dir;

Wyświetl plik

@ -8,6 +8,7 @@ void capture_screenshot(capture_info_t *capinfo, char *profile);
void close_filesystem();
void scan_cpld_filenames(char cpld_filenames[MAX_CPLD_FILENAMES][MAX_FILENAME_WIDTH], char *path, int *count);
void scan_profiles(char profile_names[MAX_PROFILES][MAX_PROFILE_WIDTH], int has_sub_profiles[MAX_PROFILES], char *path, size_t *count);
void scan_sub_profiles(char sub_profile_names[MAX_SUB_PROFILES][MAX_PROFILE_WIDTH], char *sub_path, size_t *count);

Wyświetl plik

@ -31,6 +31,8 @@
#define MAX_MENU_DEPTH 4
#define CPLD_FIRMWARE_DIR "/cpld_firmware"
// =============================================================
// Definitions for the key press interface
// =============================================================
@ -319,7 +321,6 @@ static info_menu_item_t credits_ref = { I_INFO, "Credits",
static back_menu_item_t back_ref = { I_BACK, "Return"};
static action_menu_item_t save_ref = { I_SAVE, "Save Configuration"};
static action_menu_item_t restore_ref = { I_RESTORE, "Restore Default Configuration"};
static action_menu_item_t update_cpld_ref = { I_UPDATE, "Update CPLD"};
static menu_t info_menu = {
"Info Menu",
@ -478,14 +479,44 @@ static menu_t sampling_menu = {
}
};
static menu_t update_cpld_menu = {
"Update CPLD Menu",
{
// Allow space for max 20 params
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
}
};
static void rebuild_geometry_menu(menu_t *menu);
static void rebuild_sampling_menu(menu_t *menu);
static void rebuild_update_cpld_menu(menu_t *menu);
static child_menu_item_t info_menu_ref = { I_MENU, &info_menu , NULL};
static child_menu_item_t preferences_menu_ref = { I_MENU, &preferences_menu , NULL};
static child_menu_item_t settings_menu_ref = { I_MENU, &settings_menu , NULL};
static child_menu_item_t geometry_menu_ref = { I_MENU, &geometry_menu , rebuild_geometry_menu};
static child_menu_item_t sampling_menu_ref = { I_MENU, &sampling_menu , rebuild_sampling_menu};
static child_menu_item_t update_cpld_menu_ref = { I_MENU, &update_cpld_menu , rebuild_update_cpld_menu};
static menu_t main_menu = {
"Main Menu",
@ -498,7 +529,7 @@ static menu_t main_menu = {
(base_menu_item_t *) &sampling_menu_ref,
(base_menu_item_t *) &save_ref,
(base_menu_item_t *) &restore_ref,
(base_menu_item_t *) &update_cpld_ref,
(base_menu_item_t *) &update_cpld_menu_ref,
(base_menu_item_t *) &resolution_ref,
(base_menu_item_t *) &interpolation_ref,
(base_menu_item_t *) &autoswitch_ref,
@ -543,6 +574,9 @@ static uint32_t normal_size_map8_8bpp[0x1000 * 2];
// Temporary buffer for assembling OSD lines
static char message[80];
// Temporary filename for assembling OSD lines
static char filename[80];
// Is the OSD currently active
static int active = 0;
@ -813,6 +847,7 @@ static const char *item_name(base_menu_item_t *item) {
case I_FEATURE:
case I_GEOMETRY:
case I_PARAM:
case I_UPDATE:
return ((param_menu_item_t *)item)->param->label;
case I_INFO:
return ((info_menu_item_t *)item)->name;
@ -1015,6 +1050,23 @@ static void rebuild_sampling_menu(menu_t *menu) {
rebuild_menu(menu, I_PARAM, cpld->get_params());
}
static char cpld_filenames[MAX_CPLD_FILENAMES][MAX_FILENAME_WIDTH];
static param_t cpld_filename_params[MAX_CPLD_FILENAMES];
static void rebuild_update_cpld_menu(menu_t *menu) {
int i;
int count;
scan_cpld_filenames(cpld_filenames, CPLD_FIRMWARE_DIR, &count);
for (i = 0; i < count; i++) {
cpld_filename_params[i].key = i;
cpld_filename_params[i].label = cpld_filenames[i];
}
cpld_filename_params[i].key = -1;
rebuild_menu(menu, I_UPDATE, cpld_filename_params);
}
static void redraw_menu() {
menu_t *menu = current_menu[depth];
int current = current_item[depth];
@ -1038,7 +1090,7 @@ static void redraw_menu() {
item_ptr = menu->items;
while ((item = *item_ptr++)) {
int len = strlen(item_name(item));
if (((item)->type == I_FEATURE || (item)->type == I_GEOMETRY || (item)->type == I_PARAM) && (len > max)){
if (((item)->type == I_FEATURE || (item)->type == I_GEOMETRY || (item)->type == I_PARAM || (item)->type == I_UPDATE) && (len > max)){
max = len;
}
}
@ -1053,7 +1105,7 @@ static void redraw_menu() {
*mp++ = (osd_state != PARAM) ? sel_open : sel_none;
strcpy(mp, name);
mp += strlen(mp);
if ((item)->type == I_FEATURE || (item)->type == I_GEOMETRY || (item)->type == I_PARAM) {
if ((item)->type == I_FEATURE || (item)->type == I_GEOMETRY || (item)->type == I_PARAM || (item)->type == I_PARAM) {
int len = strlen(name);
while (len < max) {
*mp++ = ' ';
@ -2144,8 +2196,10 @@ int osd_key(int key) {
force_reinit();
break;
case I_UPDATE:
// Generate the CPLD filename from the menu item
sprintf(filename, "%s/%s.xsvf", CPLD_FIRMWARE_DIR, param_item->param->label);
// Reprograme the CPLD
update_cpld("/cpld.xsvf");
update_cpld(filename);
break;
}
} else if (key == key_menu_up) {