Skip to content

Commit

Permalink
Add HDMI mode setting
Browse files Browse the repository at this point in the history
  • Loading branch information
IanSB committed Jan 8, 2021
1 parent 6b3767b commit 3b4eb56
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 44 deletions.
1 change: 1 addition & 0 deletions src/defs.h
Expand Up @@ -289,6 +289,7 @@ typedef struct {
#define AUTO_RESOLUTION "Auto@50Hz-60Hz"
#define DEFAULT_SCALING 0
#define DEFAULT_FILTERING 8
#define DEFAULT_HDMI_MODE 0

#if defined(RPI4)
#define LINE_TIMEOUT (100 * 1500/1000 * 1024)
Expand Down
11 changes: 10 additions & 1 deletion src/filesystem.c
Expand Up @@ -877,7 +877,7 @@ int file_restore(char *dirpath, char *name) {
return 1;
}

int file_save_config(char *resolution_name, int scaling, int filtering, int current_frontend) {
int file_save_config(char *resolution_name, int scaling, int filtering, int current_frontend, int current_hdmi_mode) {
FRESULT result;
char path[256];
char buffer [16384];
Expand Down Expand Up @@ -910,6 +910,15 @@ int file_save_config(char *resolution_name, int scaling, int filtering, int curr
close_filesystem();
return 0;
}
if (current_hdmi_mode == 0) {
sprintf((char*)(buffer + bytes_read), "\r\nhdmi_drive=1\r\n");
} else {
sprintf((char*)(buffer + bytes_read), "\r\nhdmi_drive=2\r\n");
bytes_read += strlen((char*) (buffer + bytes_read));
sprintf((char*)(buffer + bytes_read), "hdmi_pixel_encoding=%d\r\n", current_hdmi_mode - 1);
}
bytes_read += strlen((char*) (buffer + bytes_read));

sprintf((char*)(buffer + bytes_read), "\r\n#resolution=%s\r\n", resolution_name);
bytes_read += strlen((char*) (buffer + bytes_read));
sprintf(path, "/Resolutions/%s.txt", resolution_name);
Expand Down
2 changes: 1 addition & 1 deletion src/filesystem.h
Expand Up @@ -15,7 +15,7 @@ void scan_sub_profiles(char sub_profile_names[MAX_SUB_PROFILES][MAX_PROFILE_WIDT

unsigned int file_read_profile(char *profile_name, char *sub_profile_name, int updatecmd, char *command_string, unsigned int buffer_size);
void scan_names(char names[MAX_NAMES][MAX_NAMES_WIDTH], char *path, char *type, size_t *count);
int file_save_config(char *resolution_name, int scaling, int filtering, int current_frontend);
int file_save_config(char *resolution_name, int scaling, int filtering, int current_frontend, int current_hdmi_mode);
int file_load(char *path, char *buffer, unsigned int buffer_size);
int file_save(char *dirpath, char *name, char *buffer, unsigned int buffer_size);
int file_restore(char *dirpath, char *name);
Expand Down
46 changes: 44 additions & 2 deletions src/osd.c
Expand Up @@ -275,13 +275,23 @@ static const char *phase_names[] = {
"270"
};

static const char *hdmi_names[] = {
"DVI Compatible",
"HDMI (Auto RGB/YUV)",
"HDMI (RGB limited)",
"HDMI (RGB full)",
"HDMI (YUV limited)",
"HDMI (YUV full)"
};

// =============================================================
// Feature definitions
// =============================================================

enum {
F_AUTOSWITCH,
F_RESOLUTION,
F_HDMI,
F_SCALING,
F_FRONTEND,
F_PROFILE,
Expand Down Expand Up @@ -327,6 +337,7 @@ enum {
static param_t features[] = {
{ F_AUTOSWITCH, "Auto Switch", "auto_switch", 0, NUM_AUTOSWITCHES - 1, 1 },
{ F_RESOLUTION, "Resolution", "resolution", 0, 0, 1 },
{ F_HDMI, "HDMI Mode", "hdmi_mode", 0, NUM_HDMIS - 1, 1 },
{ F_SCALING, "Scaling", "scaling", 0, NUM_SCALING - 1, 1 },
{ F_FRONTEND, "Interface", "interface", 0, NUM_FRONTENDS - 1, 1 },
{ F_PROFILE, "Profile", "profile", 0, 0, 1 },
Expand Down Expand Up @@ -514,6 +525,7 @@ static menu_t info_menu = {
static param_menu_item_t profile_ref = { I_FEATURE, &features[F_PROFILE] };
static param_menu_item_t subprofile_ref = { I_FEATURE, &features[F_SUBPROFILE] };
static param_menu_item_t resolution_ref = { I_FEATURE, &features[F_RESOLUTION] };
static param_menu_item_t hdmi_ref = { I_FEATURE, &features[F_HDMI] };
static param_menu_item_t scaling_ref = { I_FEATURE, &features[F_SCALING] };
static param_menu_item_t frontend_ref = { I_FEATURE, &features[F_FRONTEND] };
static param_menu_item_t overscan_ref = { I_FEATURE, &features[F_OVERSCAN] };
Expand Down Expand Up @@ -748,6 +760,7 @@ static menu_t main_menu = {
(base_menu_item_t *) &restore_ref,
(base_menu_item_t *) &cal_sampling_ref,
(base_menu_item_t *) &test_50hz_ref,
(base_menu_item_t *) &hdmi_ref,
(base_menu_item_t *) &resolution_ref,
(base_menu_item_t *) &scaling_ref,
(base_menu_item_t *) &frontend_ref,
Expand All @@ -759,7 +772,7 @@ static menu_t main_menu = {
}
};

#define DIRECTION_INDEX 18
#define DIRECTION_INDEX 19

// =============================================================
// Static local variables
Expand Down Expand Up @@ -953,6 +966,8 @@ static int get_feature(int num) {
return get_subprofile();
case F_RESOLUTION:
return get_resolution();
case F_HDMI:
return get_hdmi();
case F_SCALING:
return get_scaling();
case F_FRONTEND:
Expand Down Expand Up @@ -1055,6 +1070,9 @@ static void set_feature(int num, int value) {
case F_RESOLUTION:
set_resolution(value, resolution_names[value], 1);
break;
case F_HDMI:
set_hdmi(value, 1);
break;
case F_SCALING:
set_scaling(value, 1);
break;
Expand Down Expand Up @@ -1277,6 +1295,8 @@ static const char *get_param_string(param_menu_item_t *param_item) {
return sub_profile_names[value];
case F_RESOLUTION:
return resolution_names[value];
case F_HDMI:
return hdmi_names[value];
case F_SCALING:
return scaling_names[value];
case F_FRONTEND:
Expand Down Expand Up @@ -5231,14 +5251,36 @@ void osd_init() {

int cbytes = file_load("/config.txt", config_buffer, MAX_CONFIG_BUFFER_SIZE);

if (cbytes) {
prop = get_prop_no_space(config_buffer, "hdmi_drive");
}
if (!prop || !cbytes) {
prop = "1";
}
log_info("HDMI drive: %s", prop);
int val = (atoi(prop) - 1) & 1;

if (val !=0 ) {
if (cbytes) {
prop = get_prop_no_space(config_buffer, "hdmi_pixel_encoding");
}
if (!prop || !cbytes) {
prop = "0";
}
log_info("HDMI pixel encoding: %s", prop);
val += atoi(prop);
}

set_hdmi(val, 0);

if (cbytes) {
prop = get_prop_no_space(config_buffer, "#force_genlock_range");
}
if (!prop || !cbytes) {
prop = "0";
}
log_info("Read force_genlock_range: %s", prop);
int val = atoi(prop);
val = atoi(prop);

if (val == GENLOCK_RANGE_EDID && Vrefresh_lo > 50) {
val = GENLOCK_RANGE_NORMAL;
Expand Down
11 changes: 11 additions & 0 deletions src/osd.h
Expand Up @@ -198,6 +198,17 @@ enum {
GENLOCK_RANGE_SET_DEFAULT
};

enum {
HDMI_DVI,
HDMI_AUTO,
HDMI_RGB_LIMITED,
HDMI_RGB_FULL,
HDMI_YUV_LIMITED,
HDMI_YUV_FULL,
NUM_HDMIS
};


void osd_init();
void osd_clear();
void osd_set(int line, int attr, char *text);
Expand Down
67 changes: 33 additions & 34 deletions src/rgb_to_hdmi.c
Expand Up @@ -201,6 +201,8 @@ static int profile = 0;
static int subprofile = 0;
static int resolution = -1;
static int old_resolution = -1;
static int hdmi_mode = 0;
static int old_hdmi_mode = -1;
//static int x_resolution = 0;
//static int y_resolution = 0;
static char resolution_name[MAX_NAMES_WIDTH];
Expand Down Expand Up @@ -2284,39 +2286,36 @@ void set_force_genlock_range(int value) {
force_genlock_range = value;
}

void set_resolution(int mode, const char *name, int reboot) {
//char osdline[80];

/*
char temp_resolution_name[MAX_NAMES_WIDTH];
strcpy(temp_resolution_name, name);
char *ch;
ch = strtok(temp_resolution_name, "x");
if (ch != NULL) {
x_resolution = atoi(ch);
} else {
x_resolution = 1920;
}
ch = strtok(NULL, "@");
if (ch != NULL) {
y_resolution = atoi(ch);
} else {
y_resolution = 1080;
}
void set_hdmi(int value, int reboot) {
hdmi_mode = value;
if (reboot == 0) {
old_hdmi_mode = hdmi_mode;
} else {
if (hdmi_mode != old_hdmi_mode) {
reboot_required |= 0x04;
log_info("Requesting reboot %d", hdmi_mode);
resolution_warning = 1;
} else {
reboot_required &= ~0x04;
resolution_warning = 0;
}
}
if (reboot) {
file_save_config(resolution_name, scaling, filtering, frontend, hdmi_mode);
}
}

log_info("Screen res - %d x %d", x_resolution, y_resolution);
*/
int get_hdmi() {
return hdmi_mode;
}

void set_resolution(int mode, const char *name, int reboot) {
resolution = mode;
strcpy(resolution_name, name);
if (reboot == 0) {
old_resolution = resolution;
} else {
if (reboot !=0 && resolution != old_resolution) {
// if (osd_active()) {
// sprintf(osdline, "New setting requires reboot on menu exit");
// osd_set(1, 0, osdline);
// }
if (resolution != old_resolution) {
reboot_required |= 0x01;
resolution_warning = 1;
} else {
Expand All @@ -2325,7 +2324,7 @@ void set_resolution(int mode, const char *name, int reboot) {
}
}
if (reboot) {
file_save_config(resolution_name, scaling, filtering, frontend);
file_save_config(resolution_name, scaling, filtering, frontend, hdmi_mode);
}
}

Expand Down Expand Up @@ -2424,7 +2423,7 @@ void set_scaling(int mode, int reboot) {
reboot_required &= ~0x02;
}
if (reboot == 1 || (reboot == 2 && reboot_required)) {
file_save_config(resolution_name, scaling, filtering, frontend);
file_save_config(resolution_name, scaling, filtering, frontend, hdmi_mode);
}
}

Expand All @@ -2445,7 +2444,7 @@ void set_frontend(int value, int save) {
}
}
if (save != 0) {
file_save_config(resolution_name, scaling, filtering, frontend);
file_save_config(resolution_name, scaling, filtering, frontend, hdmi_mode);
}
cpld->set_frontend(frontend);
}
Expand Down Expand Up @@ -2808,17 +2807,17 @@ void rgb_to_hdmi_main() {
sw1_power_up = 1;
force_genlock_range = GENLOCK_RANGE_INHIBIT;
if (simple_detected) {
if ((strcmp(resolution_name, AUTO_RESOLUTION) != 0)) {
if ((strcmp(resolution_name, AUTO_RESOLUTION) != 0) || hdmi_mode != DEFAULT_HDMI_MODE ) {
log_info("Resetting output resolution to Auto@50Hz-60Hz");
file_save_config(AUTO_RESOLUTION, DEFAULT_SCALING, DEFAULT_FILTERING, frontend);
file_save_config(AUTO_RESOLUTION, DEFAULT_SCALING, DEFAULT_FILTERING, frontend, DEFAULT_HDMI_MODE);
// Wait a while to allow UART time to empty
delay_in_arm_cycles_cpu_adjust(100000000);
reboot();
}
} else {
if ((strcmp(resolution_name, DEFAULT_RESOLUTION) != 0)) {
if ((strcmp(resolution_name, DEFAULT_RESOLUTION) != 0) || hdmi_mode != DEFAULT_HDMI_MODE ) {
log_info("Resetting output resolution to Default@EDID");
file_save_config(DEFAULT_RESOLUTION, DEFAULT_SCALING, DEFAULT_FILTERING, frontend);
file_save_config(DEFAULT_RESOLUTION, DEFAULT_SCALING, DEFAULT_FILTERING, frontend, DEFAULT_HDMI_MODE);
// Wait a while to allow UART time to empty
delay_in_arm_cycles_cpu_adjust(100000000);
reboot();
Expand Down Expand Up @@ -2977,7 +2976,7 @@ void rgb_to_hdmi_main() {
// Wait a while to allow UART time to empty
delay_in_arm_cycles_cpu_adjust(100000000);
if (resolution_warning != 0) {
osd_set_clear(0, 0, "If there is no display at new resolution:");
osd_set_clear(0, 0, "If there is no display with new setting:");
osd_set(1, 0, "Hold menu button during reset until you");
osd_set(2, 0, "see the 50Hz disabled recovery message");

Expand Down
2 changes: 2 additions & 0 deletions src/rgb_to_hdmi.h
Expand Up @@ -11,6 +11,8 @@ int get_paletteControl();
void set_force_genlock_range(int value);
void set_resolution(int mode, const char *name, int reboot);
int get_resolution();
void set_hdmi(int value, int reboot);
int get_hdmi();
void set_scaling(int mode, int reboot);
int get_scaling();
void set_frontend(int value, int save);
Expand Down
3 changes: 0 additions & 3 deletions src/scripts/config.txt
Expand Up @@ -30,9 +30,6 @@ enable_uart=1
# Common video settings
# =====================================================================

# Use "DVI mode", so the TV's external audio inputs will be activiated
hdmi_drive=1

# Allow framebuffer to have it's aspect ratio warped when scaling
# (needed for mode 7, 504x540 with 4/3 aspect ratio pixels)
framebuffer_aspect=-1
Expand Down
3 changes: 0 additions & 3 deletions src/scripts/default_config.txt
Expand Up @@ -30,9 +30,6 @@ enable_uart=1
# Common video settings
# =====================================================================

# Use "DVI mode", so the TV's external audio inputs will be activiated
hdmi_drive=1

# Allow framebuffer to have it's aspect ratio warped when scaling
# (needed for mode 7, 504x540 with 4/3 aspect ratio pixels)
framebuffer_aspect=-1
Expand Down

0 comments on commit 3b4eb56

Please sign in to comment.