Profile saving system

pull/71/head
IanSB 2019-04-07 04:01:27 +01:00
rodzic b0209b53d8
commit 40d5491a1a
8 zmienionych plików z 556 dodań i 398 usunięć

Wyświetl plik

@ -438,6 +438,41 @@ int file_load(char *path, char *buffer, unsigned int buffer_size) {
return bytes_read; return bytes_read;
} }
int file_save(char *path, char *buffer, unsigned int buffer_size) {
FRESULT result;
FIL file;
unsigned int num_written = 0;
init_filesystem();
log_info("Saving file %s", path);
result = f_open(&file, path, FA_WRITE | FA_CREATE_ALWAYS);
if (result != FR_OK) {
log_warn("Failed to open %s (result = %d)", path, result);
close_filesystem();
return 0;
}
result = f_write(&file, buffer, buffer_size, &num_written);
if (result != FR_OK) {
log_warn("Failed to read %s (result = %d)", path, result);
close_filesystem();
return 0;
}
result = f_close(&file);
if (result != FR_OK) {
log_warn("Failed to close %s (result = %d)", path, result);
close_filesystem();
return 0;
}
close_filesystem();
log_info("%s writing complete", path);
return num_written;
}
int file_save_config(char *resolution_name, int interpolation) { int file_save_config(char *resolution_name, int interpolation) {
FRESULT result; FRESULT result;
char path[256]; char path[256];

Wyświetl plik

@ -15,4 +15,5 @@ unsigned int file_read_profile(char *profile_name, char *sub_profile_name, int u
void scan_resolutions(char resolution_names[MAX_RESOLUTION][MAX_RESOLUTION_WIDTH], char *path, size_t *count); void scan_resolutions(char resolution_names[MAX_RESOLUTION][MAX_RESOLUTION_WIDTH], char *path, size_t *count);
int file_save_config(char *resolution_name, int interpolation); int file_save_config(char *resolution_name, int interpolation);
int file_load(char *path, char *buffer, unsigned int buffer_size); int file_load(char *path, char *buffer, unsigned int buffer_size);
int file_save(char *path, char *buffer, unsigned int buffer_size);
#endif #endif

Wyświetl plik

@ -114,7 +114,9 @@ void geometry_set_mode(int mode) {
mode7 = mode; mode7 = mode;
geometry = mode ? &mode7_geometry : &default_geometry; geometry = mode ? &mode7_geometry : &default_geometry;
} }
int geometry_get_mode() {
return mode7;
}
int geometry_get_value(int num) { int geometry_get_value(int num) {
switch (num) { switch (num) {
case H_OFFSET: case H_OFFSET:

Wyświetl plik

@ -44,6 +44,7 @@ enum {
void geometry_init(int version); void geometry_init(int version);
void geometry_set_mode(int mode); void geometry_set_mode(int mode);
int geometry_get_mode();
int geometry_get_value(int num); int geometry_get_value(int num);
const char *geometry_get_value_string(int num); const char *geometry_get_value_string(int num);
void geometry_set_value(int num, int value); void geometry_set_value(int num, int value);

821
src/osd.c

Plik diff jest za duży Load Diff

Wyświetl plik

@ -16,9 +16,9 @@ extern int paletteFlags;
enum { enum {
HDMI_ORIGINAL, HDMI_ORIGINAL,
HDMI_EXACT,
HDMI_SLOW_2000PPM, HDMI_SLOW_2000PPM,
HDMI_SLOW_500PPM, HDMI_SLOW_500PPM,
HDMI_EXACT,
HDMI_FAST_500PPM, HDMI_FAST_500PPM,
HDMI_FAST_2000PPM HDMI_FAST_2000PPM
}; };
@ -81,8 +81,8 @@ enum {
enum { enum {
AUTOSWITCH_OFF, AUTOSWITCH_OFF,
AUTOSWITCH_MODE7,
AUTOSWITCH_PC, AUTOSWITCH_PC,
AUTOSWITCH_MODE7,
NUM_AUTOSWITCHES NUM_AUTOSWITCHES
}; };
@ -109,8 +109,10 @@ void osd_update_fast(uint32_t *osd_base, int bytes_per_line);
int osd_active(); int osd_active();
int osd_key(int key); int osd_key(int key);
void osd_update_palette(); void osd_update_palette();
void process_profile(int profile_number);
void process_sub_profile(int profile_number, int sub_profile_number); void process_sub_profile(int profile_number, int sub_profile_number);
void load_profiles(int profile_number); void load_profiles(int profile_number);
void process_single_profile(char *buffer);
uint32_t osd_get_palette(int index); uint32_t osd_get_palette(int index);
int autoswitch_detect(int one_line_time_ns, int lines_per_frame, int sync_type); int autoswitch_detect(int one_line_time_ns, int lines_per_frame, int sync_type);
int sub_profiles_available(); int sub_profiles_available();

Wyświetl plik

@ -65,6 +65,9 @@ static double pllh_clock = 0;
static int genlocked = 0; static int genlocked = 0;
static int resync_count = 0; static int resync_count = 0;
static int target_difference = 0; static int target_difference = 0;
static int source_vsync_freq_hz = 0;
static int display_vsync_freq_hz = 0;
static char status[256];
// ============================================================= // =============================================================
// OSD parameters // OSD parameters
@ -73,22 +76,22 @@ static int profile = 0;
static int subprofile = 0; static int subprofile = 0;
static int resolution = 0; static int resolution = 0;
static char resolution_name[MAX_RESOLUTION_WIDTH]; static char resolution_name[MAX_RESOLUTION_WIDTH];
static int interpolation = 1; static int interpolation = 0;
static int elk = 0; static int elk = 0;
static int debug = 0; static int debug = 0;
static int autoswitch = 1; static int autoswitch = 2;
static int scanlines = 0; static int scanlines = 0;
static int scanlines_intensity = 0; static int scanlines_intensity = 0;
static int deinterlace = 6; static int deinterlace = 6;
static int vsync = 0; static int vsync = 0;
static int vlockmode = 3; static int vlockmode = 1;
static int vlockline = 10; static int vlockline = 10;
static int vlockadj = 0; static int vlockadj = 0;
static int lines_per_frame = 0; static int lines_per_frame = 0;
static int one_line_time_ns = 0; static int one_line_time_ns = 0;
static int adjusted_clock; static int adjusted_clock;
static int reboot_required = 0; static int reboot_required = 0;
static int vlock_limited = 0; static int vlock_limited = 0;
#ifdef MULTI_BUFFER #ifdef MULTI_BUFFER
static int nbuffers = 0; static int nbuffers = 0;
#endif #endif
@ -488,32 +491,42 @@ static void recalculate_hdmi_clock(int vlockmode) { // use local vsyncmode, not
double display_vsync_freq = 1e6 * pixel_clock / ((double) htotal) / ((double) vtotal); double display_vsync_freq = 1e6 * pixel_clock / ((double) htotal) / ((double) vtotal);
double error = display_vsync_freq / source_vsync_freq; double error = display_vsync_freq / source_vsync_freq;
double error_ppm = 1e6 * (error - 1.0); double error_ppm = 1e6 * (error - 1.0);
double f2 = pllh_clock; double f2 = pllh_clock;
if (vlockmode > 0) { if (vlockmode != HDMI_ORIGINAL) {
f2 /= error; f2 /= error;
double divisor = 1000.0; switch (vlockmode) {
if (vlockmode == HDMI_SLOW_500PPM || vlockmode == HDMI_FAST_500PPM) { case HDMI_SLOW_2000PPM:
divisor = 2000.0; //workaround 1000PPM actually now 500PPM f2 /= 1.0 + ((double) 2 / 1000);
} break;
f2 /= 1.0 + ((double) (HDMI_EXACT - vlockmode)) / divisor; case HDMI_SLOW_500PPM:
f2 /= 1.0 + ((double) 1 / 2000);
break;
case HDMI_FAST_500PPM:
f2 /= 1.0 + ((double) -1 / 2000);
break;
case HDMI_FAST_2000PPM:
f2 /= 1.0 + ((double) -2 / 1000);
break;
}
} }
// Sanity check HDMI pixel clock // Sanity check HDMI pixel clock
pixel_clock = f2 / ((double) fixed_divider) / ((double) additional_divider); pixel_clock = f2 / ((double) fixed_divider) / ((double) additional_divider);
vlock_limited = 0; vlock_limited = 0;
if ((vlockadj == VLOCKADJ_NARROW) && (error_ppm < -50000 || error_ppm > 50000)) { if ((vlockadj == VLOCKADJ_NARROW) && (error_ppm < -50000 || error_ppm > 50000)) {
f2 = pllh_clock; f2 = pllh_clock;
vlock_limited = 1; vlock_limited = 1;
} }
int max_clock = MAX_PIXEL_CLOCK; int max_clock = MAX_PIXEL_CLOCK;
if (vlockadj == VLOCKADJ_260MHZ) { if (vlockadj == VLOCKADJ_260MHZ) {
max_clock = MAX_PIXEL_CLOCK_260; max_clock = MAX_PIXEL_CLOCK_260;
} }
if (pixel_clock < MIN_PIXEL_CLOCK) { if (pixel_clock < MIN_PIXEL_CLOCK) {
log_debug("Pixel clock of %.2lf MHz is too low; leaving unchanged", pixel_clock); log_debug("Pixel clock of %.2lf MHz is too low; leaving unchanged", pixel_clock);
f2 = pllh_clock; f2 = pllh_clock;
@ -529,7 +542,8 @@ static void recalculate_hdmi_clock(int vlockmode) { // use local vsyncmode, not
log_debug(" Vsync error: %lf ppm", error_ppm); log_debug(" Vsync error: %lf ppm", error_ppm);
log_debug(" Original PLLH: %lf MHz", pllh_clock); log_debug(" Original PLLH: %lf MHz", pllh_clock);
log_debug(" Target PLLH: %lf MHz", f2); log_debug(" Target PLLH: %lf MHz", f2);
source_vsync_freq_hz = (int) (source_vsync_freq + 0.5);
display_vsync_freq_hz = (int) (display_vsync_freq + 0.5);
// Calculate the new dividers // Calculate the new dividers
int div = (int) (f2 / 19.2); int div = (int) (f2 / 19.2);
int fract = (int) ((double)(1<<20) * (f2 / 19.2 - (double) div)); int fract = (int) ((double)(1<<20) * (f2 / 19.2 - (double) div));
@ -580,7 +594,7 @@ static void recalculate_hdmi_clock(int vlockmode) { // use local vsyncmode, not
gpioreg[PLLH_RCAL], gpioreg[PLLH_RCAL],
gpioreg[PLLH_PIX], gpioreg[PLLH_PIX],
gpioreg[PLLH_STS]); gpioreg[PLLH_STS]);
} }
static void recalculate_hdmi_clock_once(int vlockmode) { static void recalculate_hdmi_clock_once(int vlockmode) {
@ -596,14 +610,14 @@ int recalculate_hdmi_clock_line_locked_update() {
genlocked = 0; genlocked = 0;
target_difference = 0; target_difference = 0;
resync_count = 0; resync_count = 0;
recalculate_hdmi_clock_once(vlockmode); recalculate_hdmi_clock_once(vlockmode);
} else { } else {
if (vlock_limited) { if (vlock_limited) {
genlocked = 0; genlocked = 0;
target_difference = 0; target_difference = 0;
resync_count = 0; resync_count = 0;
recalculate_hdmi_clock_once(HDMI_ORIGINAL); recalculate_hdmi_clock_once(HDMI_ORIGINAL);
} else { } else {
signed int difference = vsync_line - (capinfo->nlines - vlockline); signed int difference = vsync_line - (capinfo->nlines - vlockline);
if (abs(difference) > (capinfo->nlines / 2)) { if (abs(difference) > (capinfo->nlines / 2)) {
difference = -difference; difference = -difference;
@ -1538,8 +1552,9 @@ void setup_profile() {
log_info("Window: H = %d to %d, V = %d to %d, S = %s", hsync_comparison_lo, hsync_comparison_hi, vsync_comparison_lo, vsync_comparison_hi, sync_names[capinfo->sync_type]); log_info("Window: H = %d to %d, V = %d to %d, S = %s", hsync_comparison_lo, hsync_comparison_hi, vsync_comparison_lo, vsync_comparison_hi, sync_names[capinfo->sync_type]);
} }
void set_status_message(char *msg) {
strcpy(status, msg);
}
void rgb_to_hdmi_main() { void rgb_to_hdmi_main() {
@ -1581,7 +1596,7 @@ void rgb_to_hdmi_main() {
} }
reboot(); reboot();
} }
while (1) { while (1) {
log_info("-----------------------LOOP------------------------"); log_info("-----------------------LOOP------------------------");
setup_profile(); setup_profile();
@ -1606,12 +1621,12 @@ void rgb_to_hdmi_main() {
osd_refresh(); osd_refresh();
// unsigned int *i; // unsigned int *i;
// for (i=(unsigned int *)(PERIPHERAL_BASE + 0x400000); i<(unsigned int *)(PERIPHERAL_BASE + 0x4000e4); i++) { // for (i=(unsigned int *)(PERIPHERAL_BASE + 0x400000); i<(unsigned int *)(PERIPHERAL_BASE + 0x4000e4); i++) {
// log_info(" Regs:%08x %08x = %02x",PERIPHERAL_BASE, i, *i); // log_info(" Regs:%08x %08x = %02x",PERIPHERAL_BASE, i, *i);
// } // }
do { do {
int flags = extra_flags() | mode7 | clear; int flags = extra_flags() | mode7 | clear;
if (autoswitch == AUTOSWITCH_MODE7) { if (autoswitch == AUTOSWITCH_MODE7) {
@ -1673,9 +1688,9 @@ void rgb_to_hdmi_main() {
log_info("Timing exceeds window: H = %d, V = %d, Lines = %d, VSync = %d", hsync_period, vsync_period, (int) (((double)vsync_period/hsync_period) + 0.5), (result & RET_VSYNC_POLARITY_CHANGED) ? 1 : 0); log_info("Timing exceeds window: H = %d, V = %d, Lines = %d, VSync = %d", hsync_period, vsync_period, (int) (((double)vsync_period/hsync_period) + 0.5), (result & RET_VSYNC_POLARITY_CHANGED) ? 1 : 0);
} }
clear = 0; clear = 0;
// Possibly the size or offset has been adjusted, so update current capinfo // Possibly the size or offset has been adjusted, so update current capinfo
memcpy(&last_capinfo, capinfo, sizeof last_capinfo); memcpy(&last_capinfo, capinfo, sizeof last_capinfo);
memcpy(&last_clkinfo, &clkinfo, sizeof last_clkinfo); memcpy(&last_clkinfo, &clkinfo, sizeof last_clkinfo);
@ -1715,18 +1730,24 @@ void rgb_to_hdmi_main() {
// Recalculate the HDMI clock (if the vlockmode property requires this) // Recalculate the HDMI clock (if the vlockmode property requires this)
recalculate_hdmi_clock_line_locked_update(); recalculate_hdmi_clock_line_locked_update();
} }
if (osd_active()) { if (osd_active()) {
if (clk_changed || (clkinfo.lines_per_frame != last_clkinfo.lines_per_frame) || (capinfo->sync_type < last_capinfo.sync_type)) { if (clk_changed || (clkinfo.lines_per_frame != last_clkinfo.lines_per_frame) || (capinfo->sync_type < last_capinfo.sync_type)) {
sprintf(osdline, "%dHz %dPPM %d %s", adjusted_clock, clock_error_ppm, lines_per_frame, sync_names[capinfo->detected_sync_type & SYNC_BIT_MASK]); sprintf(osdline, "%dHz %dPPM %d %s %dHz", adjusted_clock, clock_error_ppm, lines_per_frame, sync_names[capinfo->detected_sync_type & SYNC_BIT_MASK], source_vsync_freq_hz);
osd_set(1, 0, osdline); osd_set(1, 0, osdline);
} else { } else {
if (vlock_limited && (vlockmode != HDMI_ORIGINAL) && !reboot_required) { if (status[0] != 0) {
osd_set(1, 0, "V Lock disabled - Framerate/Profile mismatch"); osd_set(1, 0, status);
status[0] = 0;
} else {
if (vlock_limited && (vlockmode != HDMI_ORIGINAL) && !reboot_required) {
sprintf(osdline, "V Lock disabled: Src=%dHz, Disp=%dHz", source_vsync_freq_hz, display_vsync_freq_hz);
osd_set(1, 0, osdline);
}
} }
} }
} }
} while (!mode_changed && !fb_size_changed); } while (!mode_changed && !fb_size_changed);
osd_clear(); osd_clear();
} }

Wyświetl plik

@ -43,5 +43,6 @@ void action_calibrate_auto();
// Status // Status
int is_genlocked(); int is_genlocked();
void set_status_message(char *msg);
#endif #endif