diff --git a/app/application.cpp b/app/application.cpp index c6dca81..4e9e831 100644 --- a/app/application.cpp +++ b/app/application.cpp @@ -2,7 +2,7 @@ #include "twi.h" uint8_t edidbuf[] = { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x34, 0xa9, 0x76, 0xd0, +/* 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x34, 0xa9, 0x76, 0xd0, 0x11, 0x00, 0x46, 0x14, 0x00, 0x11, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78, 0x0a, 0x69, 0xbe, 0xa6, 0x57, 0x53, 0xa6, 0x23, 0x0c, 0x48, 0x55, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, @@ -23,12 +23,56 @@ uint8_t edidbuf[] = { 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00, 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28, 0x55, 0x40, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xa6 + 0x00, 0x00, 0x00, 0xa6*/ +/* 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0xd8, 0x30, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x16, 0x01, 0x03, 0x80, 0x73, 0x41, 0x78, + 0x0a, 0xcf, 0x74, 0xa3, 0x57, 0x4c, 0xb0, 0x23, 0x09, 0x48, 0x4c, 0x21, + 0x08, 0x00, 0x81, 0x80, 0x45, 0x40, 0x61, 0x40, 0x95, 0x00, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, + 0x56, 0x5e, 0x00, 0xa0, 0xa0, 0xa0, 0x29, 0x50, 0x30, 0x20, 0x36, 0x00, + 0x5f, 0x59, 0x21, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x48, + 0x44, 0x4d, 0x49, 0x20, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x0a, + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, 0x4b, 0x1e, 0x50, 0x17, 0x00, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x80, 0x02, 0x03, 0x2e, 0xf2, + 0x4d, 0x01, 0x03, 0x04, 0x05, 0x07, 0x90, 0x12, 0x13, 0x14, 0x16, 0x9f, + 0x20, 0x22, 0x26, 0x09, 0x07, 0x07, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, + 0x00, 0x70, 0x03, 0x0c, 0x00, 0x22, 0x00, 0xb8, 0x44, 0x20, 0xa0, 0x82, + 0x01, 0x02, 0x03, 0x04, 0x01, 0x41, 0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0, + 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x18, + 0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20, 0x0c, 0x40, 0x55, 0x00, + 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x18, 0x01, 0x1d, 0x00, 0xbc, 0x52, 0xd0, + 0x1e, 0x20, 0xb8, 0x28, 0x55, 0x40, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, + 0x01, 0x1d, 0x80, 0xd0, 0x72, 0x1c, 0x16, 0x20, 0x10, 0x2c, 0x25, 0x80, + 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x9e, 0x56, 0x5e, 0x00, 0xa0, 0xa0, 0xa0, + 0x29, 0x50, 0x30, 0xa7*/ + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x34, 0xa9, 0x76, 0xd0, + 0x11, 0x00, 0x46, 0x14, 0x00, 0x11, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78, + 0x0a, 0x69, 0xbe, 0xa6, 0x57, 0x53, 0xa6, 0x23, 0x0c, 0x48, 0x55, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1d, 0x80, 0x18, 0x71, 0x1c, + 0x16, 0x20, 0x58, 0x2c, 0x25, 0x00, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x9e, + 0x01, 0x1d, 0x80, 0xd0, 0x72, 0x1c, 0x16, 0x20, 0x10, 0x2c, 0x25, 0x80, + 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x48, + 0x61, 0x63, 0x6b, 0x41, 0x56, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3d, 0x1c, 0x44, 0x0f, 0x00, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xb1, 0x02, 0x03, 0x16, 0x71, + 0x4a, 0x05, 0x14, 0x04, 0x13, 0x20, 0x02, 0x11, 0x01, 0x10, 0x1f, 0x66, + 0x03, 0x0c, 0x00, 0x20, 0x00, 0x00, 0x01, 0x1d, 0x80, 0x3e, 0x73, 0x38, + 0x2d, 0x40, 0x7e, 0x2c, 0x45, 0x80, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, + 0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, + 0x13, 0x8e, 0x21, 0x00, 0x00, 0x18, 0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, + 0x31, 0x20, 0x0c, 0x40, 0x55, 0x00, 0x13, 0x8e, 0x21, 0x00, 0x00, 0x18, + 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00, + 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, 0x01, 0x1d, 0x00, 0xbc, 0x52, 0xd0, + 0x1e, 0x20, 0xb8, 0x28, 0x55, 0x40, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56 }; class EP9442Matrix { Timer pollTimer; - + bool initialized = false; enum reg49_sel { PRIMARY=0, SECONDARY }; struct { @@ -80,29 +124,6 @@ class EP9442Matrix { return Wire.read(); } - uint8_t setEDID(uint8_t port, uint8_t* edid) - { - uint8_t err, address; - - if ((err = i2cWrite(0x64, 0x42, port)) != 0) { - debugf("start error occured: %d", err); - return err; - } - - uint8_t edidData[257]; - edidData[0] = 0xff; - memcpy(edidData+1, edid, 256); - if ((err = twi_writeTo(0x64, edidData, 257, true)) != 0) { - debugf("Edid write failed: %d", err); - } - - if ((err = i2cWrite(0x64, 0x42, 0x3c)) != 0) { - debugf("end error occured: %d", err); - return err; - } - - return 0; - } public: EP9442Matrix() { } @@ -112,6 +133,7 @@ public: Wire.begin(4, 5); Wire.setClock(300000); Wire.setClockStretchLimit(5*230); + if (0) { debugf("basic registers"); // Disable RX on all inputs @@ -148,6 +170,26 @@ public: if ((err = twi_writeTo(0x64, txphy, sizeof(txphy), true)) != 0) { debugf("tx phy settings failed: %d", err); } + } + + pinMode(0, OUTPUT); + digitalWrite(0, LOW); + delay(50); + digitalWrite(0, HIGH); + // ...let it boot + pollTimer.initializeMs(9000, TimerDelegate(&EP9442Matrix::finalizeInit, this)).start(); + } + + void finalizeInit() { + initialized = true; + + digitalWrite(0, LOW); + delay(50); + + debugf("Enable output 0"); + enableOutput(0); + debugf("Enable output 1"); + enableOutput(1); debugf("setting edid..."); for (int i = 0; i < 4; i++) { @@ -156,20 +198,9 @@ public: debugf("updating routing..."); updateRouting(); debugf("done"); - } - pinMode(0, OUTPUT); - digitalWrite(0, LOW); - delay(50); - digitalWrite(0, HIGH); - // ...let it boot - pollTimer.initializeMs(10000, TimerDelegate(&EP9442Matrix::finalizeInit, this)).start(); - } - - void finalizeInit() { Serial.println("Init end"); - digitalWrite(0, LOW); - pollTimer.initializeMs(3000, TimerDelegate(&EP9442Matrix::pollStatus, this)).start(); + pollTimer.initializeMs(1000, TimerDelegate(&EP9442Matrix::pollStatus, this)).start(); } void testOut2() { @@ -202,9 +233,13 @@ public: debugf("rx phy settings failed: %d", err); } + // FIXME: this seems to be the issue with TX1? check this + /* + uint8_t status = i2cRead(0x65, 0x07); + i2cWrite(0x65, 0x07, (status & 0b11111011) | (target << 2)); if ((err = twi_writeTo(0x64, txphy, sizeof(txphy), true)) != 0) { debugf("tx phy settings failed: %d", err); - } + }*/ if (target == 0) { reg49.tx0_oe = 1; @@ -219,27 +254,52 @@ public: uint8_t new_reg = *(uint8_t*)®49; i2cWrite(0x64, 0x49, new_reg); debugf("new reg49: %02x", new_reg); + debugf("unmute audio..."); + i2cWrite(0x64, 0x43, 0x00); + } + + struct rx_port_status { + bool online = false; + }; + // portStatus[4]; + + struct rx_port_status rxPortStatus(int port) { + struct rx_port_status portStatus; + Serial.printf("RX Port %d: ", port); + i2cWrite(0x65, 0x07, port); + uint8_t status = i2cRead(0x65, 0x07); + if (status & 0x80) Serial.printf("online "); + if (status & 0x40) Serial.printf("de "); + if (status & 0x20) Serial.printf("hdmi "); + if (status & 0x10) Serial.printf("enc "); + + uint8_t status2 = i2cRead(0x65, 0x08); + if (status2 & 0x40) Serial.printf("vsync "); + + Serial.printf("[%02x ", i2cRead(0x65, 0x07)); + Serial.printf("%02x ", i2cRead(0x65, 0x08)); + Serial.printf("%02x ", i2cRead(0x65, 0x09)); + Serial.printf("%02x ", i2cRead(0x65, 0x0a)); + Serial.printf("%02x ", i2cRead(0x65, 0x0e)); + Serial.printf("%02x] \r\n", i2cRead(0x65, 0x0f)); + + portStatus.online = status & 0x80; + + return portStatus; } void pollStatus() { + debugf("0x43: %02x", i2cRead(0x64, 0x43)); + i2cWrite(0x64, 0x43, 0x00); + i2cWrite(0x64, 0x45, 0x15); + debugf("0x44: %02x", i2cRead(0x64, 0x44)); + debugf("0x45: %02x", i2cRead(0x64, 0x45)); for (int port = 0; port < 4; port++) { - Serial.printf("RX Port %d: ", port); - i2cWrite(0x65, 0x07, port); - uint8_t status = i2cRead(0x65, 0x07); - if (status & 0x80) Serial.printf("online "); - if (status & 0x40) Serial.printf("de "); - if (status & 0x20) Serial.printf("hdmi "); - if (status & 0x10) Serial.printf("enc "); - - uint8_t status2 = i2cRead(0x65, 0x08); - if (status2 & 0x40) Serial.printf("vsync "); - - Serial.printf("[%02x ", i2cRead(0x65, 0x07)); - Serial.printf("%02x ", i2cRead(0x65, 0x08)); - Serial.printf("%02x ", i2cRead(0x65, 0x09)); - Serial.printf("%02x ", i2cRead(0x65, 0x0a)); - Serial.printf("%02x ", i2cRead(0x65, 0x0e)); - Serial.printf("%02x] \r\n", i2cRead(0x65, 0x0f)); + rxPortStatus(port); + /*if (portStatus[port].online != status & 0x80) { + portStatus[port].online = status & 0x80; + notify("rx" + String(port) + "_online", portStatus[port].online ? "true" : "false"); + }*/ } for (int port = 0; port < 2; port++) { @@ -260,6 +320,7 @@ public: uint8_t status5 = i2cRead(0x65, 0x0e); if (status5 & 0x01) Serial.printf("hdmi "); + i2cWrite(0x65, 0x0e, status5 | 0x01); Serial.printf("[%02x ", i2cRead(0x65, 0x07)); Serial.printf("%02x ", i2cRead(0x65, 0x08)); @@ -289,7 +350,35 @@ public: reg49.secondary_sel = source; } - updateRouting(); + if (initialized) + updateRouting(); + } + + uint8_t setEDID(uint8_t port, uint8_t* edid) + { + uint8_t err, address; + + if (!initialized) + return 255; + + if ((err = i2cWrite(0x64, 0x42, port)) != 0) { + debugf("start error occured: %d", err); + return err; + } + + uint8_t edidData[257]; + edidData[0] = 0xff; + memcpy(edidData+1, edid, 256); + if ((err = twi_writeTo(0x64, edidData, 257, true)) != 0) { + debugf("Edid write failed: %d", err); + } + + if ((err = i2cWrite(0x64, 0x42, 0x3c)) != 0) { + debugf("end error occured: %d", err); + return err; + } + + return 0; } }; @@ -310,13 +399,27 @@ public: //matrix.init(); } + int hexval(char b) { + if (b >= '0' && b <= '9') { + return b - '0'; + } else if (b >= 'a' && b <= 'f') { + return b - 'a' + 10; + } else if (b >= 'A' && b <= 'F') { + return b - 'A' + 10; + } else { + return 0; + } + } + EndpointResult onValue(String property, String value) { if (property == "sourceA") { matrix.routeVideo(value.toInt(), 0); + return 200; } if (property == "sourceB") { matrix.routeVideo(value.toInt(), 1); + return 200; } if (property == "audioSource") { @@ -330,6 +433,26 @@ public: source = 1; matrix.routeAudio(source); + return 200; + } + + if (property.startsWith("edid")) { + uint8_t portID = property[4] - '0'; + debugf("Setting for port: %d", portID); + uint8_t edidbuf[256]; + if (value.length() == 256) { + debugf("Binary"); + } else if (value.length() == 512) { + debugf("Hex encoding"); + for (int i = 0; i < 256; i++) { + edidbuf[i] = (hexval(value[2*i]) << 4) | hexval(value[2*i+1]); + } + + matrix.setEDID(portID, edidbuf); + } else { + debugf("Invalid length: %d", value.length()); + } + return 200; } return 400;