kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Pi Firmware: CPLD Update Menu populated dynamically
Change-Id: Iaa1590970341fc73d1b60ea0874e734e87f5f4a2embedded_cpld_programming
rodzic
046560e557
commit
6c8fbbcb25
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
64
src/osd.c
64
src/osd.c
|
@ -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) {
|
||||
|
|
Ładowanie…
Reference in New Issue