diff --git a/main.c b/main.c index 0c055e2..83416b5 100644 --- a/main.c +++ b/main.c @@ -105,18 +105,16 @@ static bool checksum_ok(const uint8_t* data, uint16_t length) return (0 == checksum); } -// return if the current EDID is valid +// return if the current EDID its length (including extensions), or 0 if invalid /* from HDMI 1.3a specification * All Sinks shall contain an CEA-861-D compliant E-EDID data structure. - * A Source shall read the EDID 1.3 and first CEA Extension to determine the capabilities supported -by the Sink. - * The first 128 bytes of the E-EDID shall contain an EDID 1.3 structure. The contents of this -structure shall also meet the requirements of CEA-861-D. + * A Source shall read the EDID 1.3 and first CEA Extension to determine the capabilities supported by the Sink. + * The first 128 bytes of the E-EDID shall contain an EDID 1.3 structure. The contents of this structure shall also meet the requirements of CEA-861-D. * * HDMI 2.1 uses CTA-861-G * this uses EDID 1.4 structure * EDID 1.3/1.4 is 128 bytes long, and can point to 128 bytes extension - * EDID 2.0 with its 256 bytes does not seem to be used in HDMI at all + * EDID 2.0 with its 256 bytes does not seem to be used in HDMI at all (and is deprecated, replaced by E-EDID) * DisplayID with its variable-length structure meant to replace E-EDID only seems to be used in DisplayPort */ static uint16_t edid_length(const uint8_t* edid) @@ -129,28 +127,28 @@ static uint16_t edid_length(const uint8_t* edid) } if (1 == edid[18]) { // EDID 1.3/1.4 128-byte structure - if (checksum_ok(&edid[0], 128)) { - if (0 == edid[126]) { // no extension - puts("128 bytes\r\n"); - return 128; - } else { // extension available - // the usual extension is CEA EDID Timing Extension (with extension tag 02), but we allow others - // no idea how more than 1 extension is supported - if (checksum_ok(&edid[128], 128)) { - puts("256 bytes (with extension)\r\n"); - return 256; - } else { + if (checksum_ok(&edid[0], 128)) { // ensure checksum of base EDID is ok + const uint16_t length = 128 + (1 + edid[126]) * 128; // get length with all extensions + puts("(v1.4 "); + putn(edid[126] / 100); + putn((edid[126] / 10) % 10); + putn(edid[126] % 10); + puts(" extension) "); + for (uint16_t i = 128; i < length && i < 256; i += 128) { // verify checksum of each extension (we actually only support one extension) + if (!checksum_ok(&edid[i], 128)) { puts("extension CRC error\r\n"); return 0; // EDID is broken } } + puts("CRC ok\r\n"); + return length; } else { - puts("CRC error\r\n"); + puts("base CRC error\r\n"); return 0; } } else if (2 == edid[18]) { // EDID 2.0 256-byte structure if (checksum_ok(&edid[0], 256)) { - puts("256 bytes (no extension)\r\n"); + puts("(v2) CRC ok\r\n"); return 256; } else { puts("CRC error\r\n");