|
@ -69,16 +69,16 @@ typedef struct __attribute__ (( packed )) { |
|
|
* blue, and white point, 10 bytes */ |
|
|
* blue, and white point, 10 bytes */ |
|
|
struct __attribute__ (( packed )) { |
|
|
struct __attribute__ (( packed )) { |
|
|
struct __attribute__ (( packed )) { |
|
|
struct __attribute__ (( packed )) { |
|
|
uint8_t red_x : 2; |
|
|
|
|
|
uint8_t red_y : 2; |
|
|
|
|
|
uint8_t green_x : 2; |
|
|
|
|
|
uint8_t green_y : 2; |
|
|
uint8_t green_y : 2; |
|
|
|
|
|
uint8_t green_x : 2; |
|
|
|
|
|
uint8_t red_y : 2; |
|
|
|
|
|
uint8_t red_x : 2; |
|
|
} red_green_lsbs; |
|
|
} red_green_lsbs; |
|
|
struct __attribute__ (( packed )) { |
|
|
struct __attribute__ (( packed )) { |
|
|
uint8_t blue_x : 2; |
|
|
|
|
|
uint8_t blue_y : 2; |
|
|
|
|
|
uint8_t white_x : 2; |
|
|
|
|
|
uint8_t white_y : 2; |
|
|
uint8_t white_y : 2; |
|
|
|
|
|
uint8_t white_x : 2; |
|
|
|
|
|
uint8_t blue_y : 2; |
|
|
|
|
|
uint8_t blue_x : 2; |
|
|
} blue_white_lsbs; |
|
|
} blue_white_lsbs; |
|
|
uint8_t red_x_msbs; |
|
|
uint8_t red_x_msbs; |
|
|
uint8_t red_y_msbs; |
|
|
uint8_t red_y_msbs; |
|
@ -88,7 +88,7 @@ typedef struct __attribute__ (( packed )) { |
|
|
uint8_t blue_y_msbs; |
|
|
uint8_t blue_y_msbs; |
|
|
uint8_t white_x_msbs; |
|
|
uint8_t white_x_msbs; |
|
|
uint8_t white_y_msbs; |
|
|
uint8_t white_y_msbs; |
|
|
} chromacity_cordinates; |
|
|
} chromaticity_coordinates; |
|
|
/*! Established timing bitmap. Supported bitmap for (formerly) very common
|
|
|
/*! Established timing bitmap. Supported bitmap for (formerly) very common
|
|
|
timing modes. 3 bytes */ |
|
|
timing modes. 3 bytes */ |
|
|
struct __attribute__ (( packed )) { |
|
|
struct __attribute__ (( packed )) { |
|
@ -122,6 +122,11 @@ typedef struct __attribute__ (( packed )) { |
|
|
uint8_t checksum; |
|
|
uint8_t checksum; |
|
|
} edid_t; |
|
|
} edid_t; |
|
|
|
|
|
|
|
|
|
|
|
static int stp_round(const float in) |
|
|
|
|
|
{ |
|
|
|
|
|
return (int)(in < 0 ? (in - 0.5) : (in + 0.5)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* @brief test function to show buffer |
|
|
* @brief test function to show buffer |
|
|
*/ |
|
|
*/ |
|
@ -162,13 +167,6 @@ static void generate_preamble(edid_t* edid) |
|
|
memset((uint8_t*)&(edid->header.preamble)+0, 0x00, 1); |
|
|
memset((uint8_t*)&(edid->header.preamble)+0, 0x00, 1); |
|
|
memset((uint8_t*)&(edid->header.preamble)+1, 0xFF, 6); |
|
|
memset((uint8_t*)&(edid->header.preamble)+1, 0xFF, 6); |
|
|
memset((uint8_t*)&(edid->header.preamble)+7, 0x00, 1); |
|
|
memset((uint8_t*)&(edid->header.preamble)+7, 0x00, 1); |
|
|
/*memset( edid + EDID_BYTES_OFFSET_HEADER_PREAMBLE,
|
|
|
|
|
|
0x00, 1); |
|
|
|
|
|
memset( edid + EDID_BYTES_OFFSET_HEADER_PREAMBLE + 1, |
|
|
|
|
|
0xFF, 6); |
|
|
|
|
|
memset( edid + EDID_BYTES_OFFSET_HEADER_PREAMBLE + 7, |
|
|
|
|
|
0x00, 1); |
|
|
|
|
|
*/ |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static int generate_header(edid_t* edid, unsigned char* json_str, size_t json_len) |
|
|
static int generate_header(edid_t* edid, unsigned char* json_str, size_t json_len) |
|
@ -234,17 +232,21 @@ static int generate_basic_display_parameters( edid_t* edid, |
|
|
|
|
|
|
|
|
if (edid && json_str) { |
|
|
if (edid && json_str) { |
|
|
// Input type analog or digital
|
|
|
// Input type analog or digital
|
|
|
json_scanf( json_str, json_len, "{video_input_parameters: {input_type: %Q}", |
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{basic_display_parameters: {video_input_parameters: \
|
|
|
|
|
|
{input_type: %Q}}}", |
|
|
&multi_use_str); |
|
|
&multi_use_str); |
|
|
if (strcmp(multi_use_str, "analog") == 0) { |
|
|
if (strcmp(multi_use_str, "analog") == 0) { |
|
|
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, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {levels: {upper: %f}}}", |
|
|
"{basic_display_parameters: {video_input_parameters: \
|
|
|
|
|
|
{levels: {upper: %f}}}", |
|
|
&multi_use_flt0); |
|
|
&multi_use_flt0); |
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {levels: {lower: %f}}}", |
|
|
"{basic_display_parameters: {video_input_parameters: \
|
|
|
|
|
|
{levels: {lower: %f}}}", |
|
|
&multi_use_flt1); |
|
|
&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; |
|
@ -262,31 +264,35 @@ static int generate_basic_display_parameters( edid_t* edid, |
|
|
.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}}", |
|
|
"{basic_display_parameters: {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}}", |
|
|
"{basic_display_parameters: {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}}", |
|
|
"{basic_display_parameters: {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}}", |
|
|
"{basic_display_parameters: {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: {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.blank_to_black = 0x1 & multi_use_bool; |
|
|
.analog.blank_to_black = 0x1 & multi_use_bool; |
|
@ -302,40 +308,40 @@ static int generate_basic_display_parameters( edid_t* edid, |
|
|
free(multi_use_str); |
|
|
free(multi_use_str); |
|
|
// Horizontal screen size
|
|
|
// Horizontal screen size
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {horizontal_screen_size: %d}}", |
|
|
"{basic_display_parameters: {horizontal_screen_size: %d}}", |
|
|
&multi_use_int); |
|
|
&multi_use_int); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.horizontal_screen_size = multi_use_int; |
|
|
.horizontal_screen_size = multi_use_int; |
|
|
// Vertical screen size
|
|
|
// Vertical screen size
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {vertical_screen_size: %d}}", |
|
|
"{basic_display_parameters: {vertical_screen_size: %d}}", |
|
|
&multi_use_int); |
|
|
&multi_use_int); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.vertical_screen_size = multi_use_int; |
|
|
.vertical_screen_size = multi_use_int; |
|
|
// Horizontal screen size
|
|
|
// Horizontal screen size
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {gamma: %f}}", |
|
|
"{basic_display_parameters: {gamma: %f}}", |
|
|
&multi_use_flt0); |
|
|
&multi_use_flt0); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.gamma = (multi_use_flt0-1)*100; |
|
|
.gamma = (multi_use_flt0-1)*100; |
|
|
// Display Power Management Signaling (DPMS)
|
|
|
// Display Power Management Signaling (DPMS)
|
|
|
// Standby
|
|
|
// Standby
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {features: {dpms: \
|
|
|
"{basic_display_parameters: {features: {dpms: \
|
|
|
{standby_supported: %B}}}}", |
|
|
{standby_supported: %B}}}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.features.dpms_standby_supported = 0x1 & multi_use_bool; |
|
|
.features.dpms_standby_supported = 0x1 & multi_use_bool; |
|
|
// Suspend
|
|
|
// Suspend
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {features: {dpms: \
|
|
|
"{basic_display_parameters: {features: {dpms: \
|
|
|
{suspend_supported: %B}}}}", |
|
|
{suspend_supported: %B}}}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.features.dpms_suspend_supported = 0x1 & multi_use_bool; |
|
|
.features.dpms_suspend_supported = 0x1 & multi_use_bool; |
|
|
// Active-off
|
|
|
// Active-off
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {features: {dpms: \
|
|
|
"{basic_display_parameters: {features: {dpms: \
|
|
|
{active_off_supported: %B}}}}", |
|
|
{active_off_supported: %B}}}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
@ -344,7 +350,7 @@ static int generate_basic_display_parameters( edid_t* edid, |
|
|
char a_str[] = "analog"; |
|
|
char a_str[] = "analog"; |
|
|
char d_str[] = "digital"; |
|
|
char d_str[] = "digital"; |
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {features: {display_type: %Q}}}", |
|
|
"{basic_display_parameters: {features: {display_type: %Q}}}", |
|
|
&multi_use_str); |
|
|
&multi_use_str); |
|
|
// Create substrings for comparison
|
|
|
// Create substrings for comparison
|
|
|
memcpy(a_str, multi_use_str, strlen(a_str)); |
|
|
memcpy(a_str, multi_use_str, strlen(a_str)); |
|
@ -380,19 +386,20 @@ static int generate_basic_display_parameters( edid_t* edid, |
|
|
free(multi_use_str); |
|
|
free(multi_use_str); |
|
|
// Standard sRGB
|
|
|
// Standard sRGB
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {features: {standard_srgb: %B}}}", |
|
|
"{basic_display_parameters: {features: {standard_srgb: %B}}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.features.standard_srgb = 0x1 & multi_use_bool; |
|
|
.features.standard_srgb = 0x1 & multi_use_bool; |
|
|
// Prefered timing mode
|
|
|
// Prefered timing mode
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {features: {preferred_timing_mode: %B}}}", |
|
|
"{basic_display_parameters: {features: \
|
|
|
|
|
|
{preferred_timing_mode: %B}}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.features.preferred_timing_mode = 0x1 & multi_use_bool; |
|
|
.features.preferred_timing_mode = 0x1 & multi_use_bool; |
|
|
// Continuous timings
|
|
|
// Continuous timings
|
|
|
json_scanf( json_str, json_len, |
|
|
json_scanf( json_str, json_len, |
|
|
"{video_input_parameters: {features: {continuous_timings: %B}}}", |
|
|
"{basic_display_parameters: {features: {continuous_timings: %B}}}", |
|
|
&multi_use_bool); |
|
|
&multi_use_bool); |
|
|
edid->basic_display_parameters |
|
|
edid->basic_display_parameters |
|
|
.features.continuous_timings = 0x1 & multi_use_bool; |
|
|
.features.continuous_timings = 0x1 & multi_use_bool; |
|
@ -403,6 +410,79 @@ static int generate_basic_display_parameters( edid_t* edid, |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int generate_chromaticity_coordinates( edid_t* edid, |
|
|
|
|
|
unsigned char* json_str, |
|
|
|
|
|
size_t json_len) |
|
|
|
|
|
{ |
|
|
|
|
|
float multi_use_flt; |
|
|
|
|
|
unsigned int multi_use_int; |
|
|
|
|
|
|
|
|
|
|
|
if (edid && json_str) { |
|
|
|
|
|
// Red x
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {red_x: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
edid->chromaticity_coordinates.red_green_lsbs.red_x = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.red_x_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
// Red y
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {red_y: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
edid->chromaticity_coordinates.red_green_lsbs.red_y = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.red_y_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
// Green x
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {green_x: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
edid->chromaticity_coordinates.red_green_lsbs.green_x = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.green_x_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
// Green y
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {green_y: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
edid->chromaticity_coordinates.red_green_lsbs.green_y = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.green_y_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
// Blue x
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {blue_x: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
edid->chromaticity_coordinates.blue_white_lsbs.blue_x = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.blue_x_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
// Blue y
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {blue_y: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
edid->chromaticity_coordinates.blue_white_lsbs.blue_y = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.blue_y_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
// White x
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {white_x: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
printf("white_y>%f, %d\n", multi_use_flt, multi_use_int); |
|
|
|
|
|
edid->chromaticity_coordinates.blue_white_lsbs.white_x = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.white_x_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
// White y
|
|
|
|
|
|
json_scanf( json_str, json_len, |
|
|
|
|
|
"{chromaticity_coordinates: {white_y: %f}}", |
|
|
|
|
|
&multi_use_flt); |
|
|
|
|
|
multi_use_int = stp_round(1024.0f * multi_use_flt); |
|
|
|
|
|
printf("white_y>%f, %d\n", multi_use_flt, multi_use_int); |
|
|
|
|
|
edid->chromaticity_coordinates.blue_white_lsbs.white_y = 0x3 & multi_use_int; |
|
|
|
|
|
edid->chromaticity_coordinates.white_y_msbs = 0xFF & multi_use_int >> 2; |
|
|
|
|
|
} else { |
|
|
|
|
|
printf("Error: One of either edid or json_str is NULL.\n"); |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int main(void) |
|
|
int main(void) |
|
|
{ |
|
|
{ |
|
|
//uint8_t edith[EDID_LENGTH];
|
|
|
//uint8_t edith[EDID_LENGTH];
|
|
@ -419,6 +499,7 @@ int main(void) |
|
|
} |
|
|
} |
|
|
generate_header(&edith, mystr, len); |
|
|
generate_header(&edith, mystr, len); |
|
|
generate_basic_display_parameters(&edith, mystr, len); |
|
|
generate_basic_display_parameters(&edith, mystr, len); |
|
|
|
|
|
generate_chromaticity_coordinates(&edith, mystr, len); |
|
|
disp_buf((uint8_t*)&edith, EDID_LENGTH); |
|
|
disp_buf((uint8_t*)&edith, EDID_LENGTH); |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|