| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -5,9 +5,6 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "frozen/frozen.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define EDID_LENGTH 128 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define EDID_BYTES_OFFSET_HEADER_PREAMBLE 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define EDID_BYTES_OFFSET_HEADER_MANUFACTURER_ID 8 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define EDID_BYTES_OFFSET_HEADER_PRODUCT_CODE 10 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					enum edid_analog_display_t { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_DISPLAY_TYPE_MONOCHROME_OR_GRAYSCALE = 0, | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -16,12 +13,79 @@ enum edid_analog_display_t { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_DISPLAY_TYPE_UNDEFINED               = 3 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					enum edid_aspect_ratio_t { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_ASPECT_RATIO_16_10 = 0, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_ASPECT_RATIO_4_3   = 1, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_ASPECT_RATIO_5_4   = 2, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_ASPECT_RATIO_16_9  = 3 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					enum edid_sync_mode_t { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_SYNC_MODE_ANALOG             = 0, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_SYNC_MODE_DIGITAL_COMPOSITE  = 2, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  EDID_SYNC_MODE_DIGITAL_SEPERATE   = 3 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					typedef  struct __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t resolution; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t image_aspect_ratio : 2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_frequency : 6; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t x_resolution; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_frequency:6; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t aspect_ratio      :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} standard_timing_information_t; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					typedef struct __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint16_t pixel_clock;                           // 0-1
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_active_pixels_lsbs;          // 2
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_blanking_pixels_lsbs;        // 3
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_blanking_pixels_msbs     :4; // 4
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_active_pixels_msbs       :4; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_active_lines_lsbs;             // 5
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_blanking_lines_lsbs;           // 6
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_blanking_lines_msbs        :4; // 7
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_active_lines_msbs          :4; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_front_porch_pixels_lsbs;     // 8
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_sync_pulse_pixels_lsbs;      // 9
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_sync_pulse_lines_lsbs      :4; // 10
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_front_porch_lines_lsbs     :4; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_sync_pulse_lines_msbs      :2; // 11
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_front_porch_lines_msbs     :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_sync_pulse_pixels_msbs   :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_front_porch_pixels_msbs  :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_image_size_lsbs;             // 12
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_image_size_lsbs; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_image_size_msbs            :4; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_image_size_msbs          :4; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t horizontal_border_pixels; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t vertical_border_lines; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  // Feature bitmap
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  union __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    struct __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t stereo_mode_lsb                 :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t sync_on_red_blue                :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t vertical_sync_serration         :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t sync_type                       :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t analog_sync                     :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t stereo_mode_msbs                :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t interlaced                      :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } analog; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    struct __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t stereo_mode_lsb                 :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t reserved                        :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t vertical_sync_polarity          :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t digital_composite_sync          :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t stereo_mode_msbs                :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t interlaced                      :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } digital_composite; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    struct __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t stereo_mode_lsb                 :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t horizontal_sync_polarity        :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t vertical_sync_serration         :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t digital_seperate_sync           :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t stereo_mode_msbs                :2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      uint8_t interlaced                      :1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } digital_seperate; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } features; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} detailed_timing_descriptor_t; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					typedef struct __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  /*! Header information, 20 bytes */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  struct __attribute__ (( packed )) { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -114,10 +178,13 @@ typedef struct __attribute__ (( packed )) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  /*! Standard timing information. Up to 8 2-byte fields describing standard
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      display modes. Unused fields are filled with 01 01 hex. 16 bytes */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  standard_timing_information_t timings[8]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t descriptor_1[18]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*  uint8_t descriptor_1[18];
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t descriptor_2[18]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t descriptor_3[18]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t descriptor_4[18]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					*/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  detailed_timing_descriptor_t detailed_timing_descriptor; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  detailed_timing_descriptor_t descriptors[3]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t number_extensions; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  uint8_t checksum; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} edid_t; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -563,6 +630,231 @@ static int generate_common_timing_modes(  edid_t* edid, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int generate_timings(edid_t* edid, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            unsigned char* json_str, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            size_t json_len) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  struct json_token multi_use_token; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  float multi_use_flt; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  int multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  char* multi_use_str; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if (edid && json_str) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    int i = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (i = 0; json_scanf_array_elem(json_str, json_len, ".timings", i, &multi_use_token) > 0; i++) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // t.type == JSON_TYPE_OBJECT
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // X resolution
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      json_scanf(multi_use_token.ptr, multi_use_token.len, "{x_resolution: %f}", &multi_use_flt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      edid->timings[i].x_resolution = stp_round(multi_use_flt/8-31); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      printf("res> %f\n", multi_use_flt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Aspect ratio
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      json_scanf(multi_use_token.ptr, multi_use_token.len, "{aspect_ratio: %Q}", &multi_use_str); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (strcmp(multi_use_str, "16:10") == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        edid->timings[i].aspect_ratio = 0x3 & EDID_ASPECT_RATIO_16_10; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else if (strcmp(multi_use_str, "4:3") == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        edid->timings[i].aspect_ratio = 0x3 & EDID_ASPECT_RATIO_4_3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else if (strcmp(multi_use_str, "5:4") == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        edid->timings[i].aspect_ratio = 0x3 & EDID_ASPECT_RATIO_5_4; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else if (strcmp(multi_use_str, "16:9") == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        edid->timings[i].aspect_ratio = 0x3 & EDID_ASPECT_RATIO_16_9; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        printf("Error: Aspect ratio not supported"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Free string that has been allocated in memory
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      free(multi_use_str); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Vertical frequency
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      json_scanf(multi_use_token.ptr, multi_use_token.len, "{vertical_frequency: %d}", &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (multi_use_int >= 60) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        edid->timings[i].vertical_frequency = multi_use_int-60; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        printf("Error: Vertical frequency cannot be lower than 60 Hz.\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    printf("Error: One of either edid or json_str is NULL.\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					static int generate_detailed_timing_descriptor( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  edid_t* edid, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned char* json_str, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  size_t json_len) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unsigned int multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  float multi_use_float; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  struct json_token multi_use_token; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  bool multi_use_bool; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  char* multi_use_str; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if (edid && json_str) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Pixel clock
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {pixel_clock_mhz: %f}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_float); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    /* The data is stored as 10 kHz unitsi in the EDID structure.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					       It is a float representing MHz in the JSON file. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor.pixel_clock = stp_round(multi_use_float/0.01f); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Horizontal active pixels
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {horizontal_active_pixels: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_active_pixels_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_active_pixels_msbs = 0x0F & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Horizontal blanking pixels
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {horizontal_blanking_pixels: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_blanking_pixels_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_blanking_pixels_msbs = 0x0F & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Vertical active lines
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {vertical_active_lines: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_active_lines_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_active_lines_msbs = 0x0F & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Vertical blanking lines
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {vertical_blanking_lines: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_blanking_lines_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_blanking_lines_msbs = 0x0F & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Horizontal front porch pixels
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {horizontal_front_porch_pixels: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_front_porch_pixels_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_front_porch_pixels_msbs = 0x03 & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Horizontal sync pulse pixels
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {horizontal_sync_pulse_pixels: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_sync_pulse_pixels_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_sync_pulse_pixels_msbs = 0x03 & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Vertical front porch lines
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {vertical_front_porch_lines: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_front_porch_lines_lsbs = 0x0F & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_front_porch_lines_msbs = 0x03 & (multi_use_int >> 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Vertical sync pulse lines
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {vertical_sync_pulse_lines: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_sync_pulse_lines_lsbs = 0x0F & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_sync_pulse_lines_msbs = 0x03 & (multi_use_int >> 4); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Horizontal image size
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {horizontal_image_size_mm: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_image_size_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_image_size_msbs = 0x0F & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Vertical image size
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {vertical_image_size_mm: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_image_size_lsbs = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_image_size_msbs = 0x0F & (multi_use_int >> 8); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Horizontal border pixels
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {horizontal_border_pixels: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .horizontal_border_pixels = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Vertical border lines
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {vertical_border_lines: %d}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_int); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .vertical_border_lines = 0xFF & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define PETER | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#ifdef PETER | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Sync features bitmap
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {stereo_mode: %Q}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_str); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (strcmp(multi_use_str, "none") == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      multi_use_int = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      printf("Error: This stereo mode is not implemented yet.\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    free(multi_use_str); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .features.digital_seperate.stereo_mode_lsb = 0x1 & multi_use_int; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .features.digital_seperate.stereo_mode_msbs = 0x3 & (multi_use_int >> 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Interlaced
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    json_scanf( json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                "{detailed_timing_descriptor: {interlaced: %B}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                &multi_use_bool); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      .features.digital_seperate.interlaced = multi_use_bool; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // Sync details
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (json_scanf(json_str, json_len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        "{detailed_timing_descriptor: { digital_seperate_sync: %T}}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        &multi_use_token) > 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Set sync mode
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .features.digital_seperate.digital_seperate_sync = 0x3 & EDID_SYNC_MODE_DIGITAL_SEPERATE; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Vertical sync serration
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      json_scanf( multi_use_token.ptr, multi_use_token.len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                  "{vertical_sync_serration: %B}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                  &multi_use_bool); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .features.digital_seperate.vertical_sync_serration = multi_use_bool; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // Horizontal sync polarity
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      json_scanf( multi_use_token.ptr, multi_use_token.len, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                  "{horizontal_sync_polarity: %Q}", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                  &multi_use_str); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (strcmp(multi_use_str, "positive") == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        multi_use_bool = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else if (strcmp(multi_use_str, "negative") == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        multi_use_bool = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        printf("Error: The horizontal sync polarity can either be positive or negative (JSON string).\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      edid->detailed_timing_descriptor | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        .features.digital_seperate.horizontal_sync_polarity = multi_use_bool; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      free(multi_use_str); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      printf("Error: Could not parse JSON file somewhere arround sync \
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              features in detailed timing descriptor.\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#endif | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    printf("Error: One of either edid or json_str is NULL.\n"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					int main(void) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  //uint8_t edith[EDID_LENGTH];
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -575,12 +867,13 @@ int main(void) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  if (mystr) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    printf("%s\n", mystr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    printf("len> %d\n", len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //free(mystr);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  generate_header(&edith, mystr, len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  generate_basic_display_parameters(&edith, mystr, len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  generate_chromaticity_coordinates(&edith, mystr, len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  generate_common_timing_modes(&edith, mystr, len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  generate_timings(&edith, mystr, len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  generate_detailed_timing_descriptor(&edith, mystr, len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  disp_buf((uint8_t*)&edith, EDID_LENGTH); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  free(mystr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  return 0; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |