add EDID check
This commit is contained in:
parent
2859bb7a09
commit
e345b61860
68
main.c
68
main.c
|
@ -77,6 +77,73 @@ void puth(uint8_t h)
|
|||
putn(h & 0x0f);
|
||||
}
|
||||
|
||||
// verify (E-)EDID checksums
|
||||
// the sum of the bytes (including checksum at the end) must be 0
|
||||
static bool checksum_ok(const uint8_t* data, uint16_t length)
|
||||
{
|
||||
uint8_t checksum = 0;
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
checksum += data[i];
|
||||
}
|
||||
return (0 == checksum);
|
||||
}
|
||||
|
||||
// return if the current EDID is valid
|
||||
/* 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.
|
||||
*
|
||||
* 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
|
||||
* DisplayID with its variable-length structure meant to replace E-EDID only seems to be used in DisplayPort
|
||||
*/
|
||||
static uint16_t edid_length(uint8_t* edid)
|
||||
{
|
||||
puts("EDID check: ");
|
||||
// check EDID 1.3/1.4 fixed pattern header
|
||||
if (0x00 != edid[0] || 0xff != edid[1] || 0xff != edid[2] || 0xff != edid[3] || 0xff != edid[4] || 0xff != edid[5] || 0xff != edid[6] || 0x00 != edid[7]) {
|
||||
puts("invalid header\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 {
|
||||
puts("extension CRC error\r\n");
|
||||
return 0; // EDID is broken
|
||||
}
|
||||
}
|
||||
} else {
|
||||
puts("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");
|
||||
return 256;
|
||||
} else {
|
||||
puts("CRC error\r\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
sim(); // disable interrupts (while we reconfigure them)
|
||||
|
@ -229,6 +296,7 @@ i2c_end:
|
|||
softi2c_master_stop();
|
||||
if (i2c_success) {
|
||||
puts("success\r\n");
|
||||
const uint16_t edid_len = edid_length(edid_sink); // get length
|
||||
} else {
|
||||
puts("fail\r\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue