kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Profile saving system
rodzic
b0209b53d8
commit
40d5491a1a
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,5 +43,6 @@ void action_calibrate_auto();
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
int is_genlocked();
|
int is_genlocked();
|
||||||
|
void set_status_message(char *msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Ładowanie…
Reference in New Issue