|
@ -9,6 +9,12 @@ |
|
|
#define EDID_BYTES_OFFSET_HEADER_MANUFACTURER_ID 8 |
|
|
#define EDID_BYTES_OFFSET_HEADER_MANUFACTURER_ID 8 |
|
|
#define EDID_BYTES_OFFSET_HEADER_PRODUCT_CODE 10 |
|
|
#define EDID_BYTES_OFFSET_HEADER_PRODUCT_CODE 10 |
|
|
|
|
|
|
|
|
|
|
|
enum edid_analog_display_t { |
|
|
|
|
|
EDID_DISPLAY_TYPE_MONOCHROME_OR_GRAYSCALE = 0, |
|
|
|
|
|
EDID_DISPLAY_TYPE_RGB_COLOR = 1, |
|
|
|
|
|
EDID_DISPLAY_TYPE_NON_RGB_COLOR = 2, |
|
|
|
|
|
EDID_DISPLAY_TYPE_UNDEFINED = 3 |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
typedef struct __attribute__ (( packed )) { |
|
|
typedef struct __attribute__ (( packed )) { |
|
|
uint8_t resolution; |
|
|
uint8_t resolution; |
|
@ -46,17 +52,17 @@ typedef struct __attribute__ (( packed )) { |
|
|
uint8_t input_type : 1; // 0 for analog
|
|
|
uint8_t input_type : 1; // 0 for analog
|
|
|
} analog; |
|
|
} analog; |
|
|
} video_input_parameters; // 1 byte
|
|
|
} video_input_parameters; // 1 byte
|
|
|
uint8_t h_screen_size; |
|
|
uint8_t horizontal_screen_size; |
|
|
uint8_t v_screen_size; |
|
|
uint8_t vertical_screen_size; |
|
|
uint8_t gamma; |
|
|
uint8_t gamma; |
|
|
struct __attribute__ (( packed )) { |
|
|
struct __attribute__ (( packed )) { |
|
|
uint8_t dpms_standby : 1; |
|
|
uint8_t continuous_timings : 1; |
|
|
uint8_t dpms_suspend : 1; |
|
|
uint8_t preferred_timing_mode : 1; |
|
|
uint8_t dpms_active_off : 1; |
|
|
uint8_t standard_srgb : 1; |
|
|
uint8_t display_type : 2; |
|
|
uint8_t display_type : 2; |
|
|
uint8_t standard_srgb : 1; |
|
|
uint8_t dpms_active_off_supported : 1; |
|
|
uint8_t preferred_timing_mode : 1; |
|
|
uint8_t dpms_suspend_supported : 1; |
|
|
uint8_t continuous_timings : 1; |
|
|
uint8_t dpms_standby_supported : 1; |
|
|
} features; |
|
|
} features; |
|
|
} basic_display_parameters; |
|
|
} basic_display_parameters; |
|
|
/*! Chromaticity coordinates. 10-bit CIE 1931 xy coordinates for red, green,
|
|
|
/*! Chromaticity coordinates. 10-bit CIE 1931 xy coordinates for red, green,
|
|
@ -187,6 +193,8 @@ static int generate_header(edid_t* edid, unsigned char* json_str, size_t json_le |
|
|
ID.\n"); |
|
|
ID.\n"); |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
// %Q mallocs a string
|
|
|
|
|
|
free(multi_use_str); |
|
|
// Product code
|
|
|
// Product code
|
|
|
json_scanf(json_str, json_len, "{header: {product_code: %d}", &multi_use_int); |
|
|
json_scanf(json_str, json_len, "{header: {product_code: %d}", &multi_use_int); |
|
|
edid->header.product_code = 0xFFFF & multi_use_int; |
|
|
edid->header.product_code = 0xFFFF & multi_use_int; |
|
@ -214,9 +222,9 @@ static int generate_header(edid_t* edid, unsigned char* json_str, size_t json_le |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static int generate_video_input_parameters( edid_t* edid, |
|
|
static int generate_basic_display_parameters( edid_t* edid, |
|
|
unsigned char* json_str, |
|
|
unsigned char* json_str, |
|
|
size_t json_len) |
|
|
size_t json_len) |
|
|
{ |
|
|
{ |
|
|
char* multi_use_str; |
|
|
char* multi_use_str; |
|
|
float multi_use_flt0; |
|
|
float multi_use_flt0; |
|
@ -232,10 +240,12 @@ static int generate_video_input_parameters( edid_t* edid, |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
.analog.input_type = 0; |
|
|
.analog.input_type = 0; |
|
|
// Levels
|
|
|
// Levels
|
|
|
json_scanf( json_str, json_len, "{video_input_parameters: {levels: {upper: %f}}}", |
|
|
json_scanf( json_str, json_len, |
|
|
&multi_use_flt0); |
|
|
"{video_input_parameters: {levels: {upper: %f}}}", |
|
|
json_scanf( json_str, json_len, "{video_input_parameters: {levels: {lower: %f}}}", |
|
|
&multi_use_flt0); |
|
|
&multi_use_flt1); |
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {levels: {lower: %f}}}", |
|
|
|
|
|
&multi_use_flt1); |
|
|
if (multi_use_flt0 == 0.7f && multi_use_flt1 == -0.3f) { |
|
|
if (multi_use_flt0 == 0.7f && multi_use_flt1 == -0.3f) { |
|
|
multi_use_int = 0; |
|
|
multi_use_int = 0; |
|
|
} else if (multi_use_flt0 == 0.714f && multi_use_flt1 == -0.286f) { |
|
|
} else if (multi_use_flt0 == 0.714f && multi_use_flt1 == -0.286f) { |
|
@ -248,36 +258,35 @@ static int generate_video_input_parameters( edid_t* edid, |
|
|
printf("Error: The levels %f/%f are not conforming to the standard.\n", |
|
|
printf("Error: The levels %f/%f are not conforming to the standard.\n", |
|
|
multi_use_flt0, multi_use_flt1); |
|
|
multi_use_flt0, multi_use_flt1); |
|
|
} |
|
|
} |
|
|
printf("level> %d\n", multi_use_int); |
|
|
|
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
.analog.levels = 0x3 & multi_use_int; |
|
|
.analog.levels = 0x3 & multi_use_int; |
|
|
// Blank to black
|
|
|
// Blank to black
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {blank_to_black: %B}", |
|
|
"{video_input_parameters: {blank_to_black: %B}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
.analog.blank_to_black = 0x1 & multi_use_bool; |
|
|
.analog.blank_to_black = 0x1 & multi_use_bool; |
|
|
// Seperate sync
|
|
|
// Seperate sync
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {seperate_sync: %B}", |
|
|
"{video_input_parameters: {seperate_sync: %B}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
.analog.seperate_sync = 0x1 & multi_use_bool; |
|
|
.analog.seperate_sync = 0x1 & multi_use_bool; |
|
|
// Composite sync
|
|
|
// Composite sync
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {composite_sync: %B}", |
|
|
"{video_input_parameters: {composite_sync: %B}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
.analog.composite_sync = 0x1 & multi_use_bool; |
|
|
.analog.composite_sync = 0x1 & multi_use_bool; |
|
|
// Sync on green
|
|
|
// Sync on green
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {sync_on_green: %B}", |
|
|
"{video_input_parameters: {sync_on_green: %B}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
.analog.sync_on_green = 0x1 & multi_use_bool; |
|
|
.analog.sync_on_green = 0x1 & multi_use_bool; |
|
|
// Vsync serrated
|
|
|
// Vsync serrated
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {blank_to_black: %B}", |
|
|
"{video_input_parameters: {blank_to_black: %B}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
edid->basic_display_parameters.video_input_parameters |
|
|
.analog.blank_to_black = 0x1 & multi_use_bool; |
|
|
.analog.blank_to_black = 0x1 & multi_use_bool; |
|
@ -289,9 +298,107 @@ static int generate_video_input_parameters( edid_t* edid, |
|
|
the video input params.\n"); |
|
|
the video input params.\n"); |
|
|
return 2; |
|
|
return 2; |
|
|
} |
|
|
} |
|
|
|
|
|
// %Q mallocs a string
|
|
|
|
|
|
free(multi_use_str); |
|
|
|
|
|
// Horizontal screen size
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {horizontal_screen_size: %d}}", |
|
|
|
|
|
&multi_use_int); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.horizontal_screen_size = multi_use_int; |
|
|
|
|
|
// Vertical screen size
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {vertical_screen_size: %d}}", |
|
|
|
|
|
&multi_use_int); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.vertical_screen_size = multi_use_int; |
|
|
|
|
|
// Horizontal screen size
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {gamma: %f}}", |
|
|
|
|
|
&multi_use_flt0); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.gamma = (multi_use_flt0-1)*100; |
|
|
|
|
|
// Display Power Management Signaling (DPMS)
|
|
|
|
|
|
// Standby
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {features: {dpms: \
|
|
|
|
|
|
{standby_supported: %B}}}}", |
|
|
|
|
|
&multi_use_bool); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.dpms_standby_supported = 0x1 & multi_use_bool; |
|
|
|
|
|
// Suspend
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {features: {dpms: \
|
|
|
|
|
|
{suspend_supported: %B}}}}", |
|
|
|
|
|
&multi_use_bool); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.dpms_suspend_supported = 0x1 & multi_use_bool; |
|
|
|
|
|
// Active-off
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {features: {dpms: \
|
|
|
|
|
|
{active_off_supported: %B}}}}", |
|
|
|
|
|
&multi_use_bool); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.dpms_active_off_supported = 0x1 & multi_use_bool; |
|
|
|
|
|
// Display type
|
|
|
|
|
|
char a_str[] = "analog"; |
|
|
|
|
|
char d_str[] = "digital"; |
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {features: {display_type: %Q}}}", |
|
|
|
|
|
&multi_use_str); |
|
|
|
|
|
// Create substrings for comparison
|
|
|
|
|
|
memcpy(a_str, multi_use_str, strlen(a_str)); |
|
|
|
|
|
memcpy(d_str, multi_use_str, strlen(d_str)); |
|
|
|
|
|
if (strcmp(a_str, "analog") == 0) { |
|
|
|
|
|
// Remove "analog_"
|
|
|
|
|
|
memcpy( multi_use_str, multi_use_str+strlen(a_str)+1, |
|
|
|
|
|
strlen(multi_use_str)-strlen(a_str)); |
|
|
|
|
|
if (strcmp(multi_use_str, "monochrome_or_grayscale") == 0) { |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.display_type = 0x3 & EDID_DISPLAY_TYPE_MONOCHROME_OR_GRAYSCALE; |
|
|
|
|
|
} else if (strcmp(multi_use_str, "rgb_color") == 0) { |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.display_type = 0x3 & ~EDID_DISPLAY_TYPE_RGB_COLOR; |
|
|
|
|
|
} else if (strcmp(multi_use_str, "non_rgb_color") == 0) { |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.display_type = 0x3 & ~EDID_DISPLAY_TYPE_NON_RGB_COLOR; |
|
|
|
|
|
} else if (strcmp(multi_use_str, "undefined") == 0) { |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.display_type = 0x3 & EDID_DISPLAY_TYPE_UNDEFINED; |
|
|
|
|
|
} else { |
|
|
|
|
|
printf("Error: Unknown analog display_type.\n"); |
|
|
|
|
|
return 3; |
|
|
|
|
|
} |
|
|
|
|
|
} else if (strcmp(d_str, "digital") == 0) { |
|
|
|
|
|
printf("Error: Digital format is not supported yet.\n"); |
|
|
|
|
|
return 4; |
|
|
|
|
|
} else { |
|
|
|
|
|
printf("Error: JSON format is wrong. First word needs of display_type \
|
|
|
|
|
|
should either be analog or digital.\n"); |
|
|
|
|
|
} |
|
|
|
|
|
// %Q mallocs a string, which needs to be freed
|
|
|
|
|
|
free(multi_use_str); |
|
|
|
|
|
// Standard sRGB
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {features: {standard_srgb: %B}}}", |
|
|
|
|
|
&multi_use_bool); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.standard_srgb = 0x1 & multi_use_bool; |
|
|
|
|
|
// Prefered timing mode
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {features: {preferred_timing_mode: %B}}}", |
|
|
|
|
|
&multi_use_bool); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.preferred_timing_mode = 0x1 & multi_use_bool; |
|
|
|
|
|
// Continuous timings
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{video_input_parameters: {features: {continuous_timings: %B}}}", |
|
|
|
|
|
&multi_use_bool); |
|
|
|
|
|
edid->basic_display_parameters |
|
|
|
|
|
.features.continuous_timings = 0x1 & multi_use_bool; |
|
|
} else { |
|
|
} else { |
|
|
printf("One of either edid or json_str is NULL.\n"); |
|
|
printf("Error: One of either edid or json_str is NULL.\n"); |
|
|
return 3; |
|
|
return 5; |
|
|
} |
|
|
} |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
@ -304,14 +411,14 @@ int main(void) |
|
|
printf("size> %d bytes\n", sizeof(edith)); |
|
|
printf("size> %d bytes\n", sizeof(edith)); |
|
|
generate_preamble(&edith); |
|
|
generate_preamble(&edith); |
|
|
unsigned char* mystr = NULL; |
|
|
unsigned char* mystr = NULL; |
|
|
size_t len = file_to_str(&mystr, "edid.json"); |
|
|
size_t len = file_to_str(&mystr, "edid_stockach.json"); |
|
|
if (mystr) { |
|
|
if (mystr) { |
|
|
printf("%s\n", mystr); |
|
|
printf("%s\n", mystr); |
|
|
printf("len> %d\n", len); |
|
|
printf("len> %d\n", len); |
|
|
//free(mystr);
|
|
|
//free(mystr);
|
|
|
} |
|
|
} |
|
|
generate_header(&edith, mystr, len); |
|
|
generate_header(&edith, mystr, len); |
|
|
generate_video_input_parameters(&edith, mystr, len); |
|
|
generate_basic_display_parameters(&edith, mystr, len); |
|
|
disp_buf((uint8_t*)&edith, EDID_LENGTH); |
|
|
disp_buf((uint8_t*)&edith, EDID_LENGTH); |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|