290 lines
9.0 KiB
C++
290 lines
9.0 KiB
C++
#include <user_config.h>
|
|
#include <SmingCore/SmingCore.h>
|
|
#include "twi.h"
|
|
|
|
Timer procTimer;
|
|
|
|
uint8_t reg49_shadow = 0xc0;
|
|
uint8_t input_a = 0;
|
|
uint8_t input_b = 0;
|
|
|
|
static uint8_t get_reg49_value(void) {
|
|
uint8_t val;
|
|
|
|
// Enable only plugged-in ouputs.
|
|
//val = (P0 & 0xc) << 4;
|
|
val = 0xc << 4;
|
|
|
|
// Prefer existing routings.
|
|
if (input_a == ((reg49_shadow >> 2) & 3)) {
|
|
val |= 0x10; // Select secondary RX for output A
|
|
}
|
|
if (input_b == ((reg49_shadow >> 2) & 3)) {
|
|
val |= 0x20; // Select secondary RX for output B
|
|
}
|
|
|
|
// Update routing.
|
|
switch (val & 0x30) {
|
|
case 0x00:
|
|
if (input_a == input_b) {
|
|
val |= input_a;
|
|
val |= (~input_a & 3) << 2;
|
|
} else {
|
|
if (input_a == ((reg49_shadow >> 2) & 3)) {
|
|
val |= input_b;
|
|
val |= input_a << 2;
|
|
val |= 0x10; // Select secondary RX for output A
|
|
} else {
|
|
val |= input_a;
|
|
val |= input_b << 2;
|
|
val |= 0x20; // Select secondary RX for output B
|
|
}
|
|
}
|
|
break;
|
|
case 0x30:
|
|
val |= ~input_a & 3;
|
|
val |= input_a << 2;
|
|
break;
|
|
case 0x10:
|
|
val |= input_b;
|
|
val |= input_a << 2;
|
|
break;
|
|
case 0x20:
|
|
val |= input_a;
|
|
val |= input_b << 2;
|
|
break;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
uint8_t edidbuf[256] = {
|
|
//0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 'x', 'D', 0x00
|
|
/*0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x13, 0x02, 0x31, 0x32, 0x50, 0x44,
|
|
0x2a, 0x11, 0x01, 0x03, 0x80, 0x00, 0x00, 0x78, 0x2a, 0xee, 0x95, 0xa3, 0x54, 0x4c, 0x99, 0x26,
|
|
0x0f, 0x50, 0x54, 0x21, 0x08, 0x00, 0x61, 0x40, 0x81, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
|
0x19, 0x64, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0xa0, 0x18, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
|
|
0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x1e,
|
|
0x00, 0x00, 0x00, 0xfc, 0x00, 'M' , 'a' , 't' , 'r' , 'i' , 'x' , 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x00, 0x00, 0x00, 0xfd, 0x00, 0x17, 0x48, 0x01, 0xff, 0x1a, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
0x01, 0xdc,
|
|
|
|
0x02, 0x03, 0x1b, 0xc1,
|
|
0x46, 0x84, 0x02, 0x03, 0x11, 0x12, 0x01,
|
|
0x23, 0x09, 0x07, 0x07,
|
|
0x83, 0x01, 0x00, 0x00,
|
|
0x67, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x80, 0x1e,
|
|
0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x1e,
|
|
0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20, 0x0c, 0x40, 0x55, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x18,
|
|
0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20, 0x0c, 0x40, 0x55, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x18,
|
|
0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x18,
|
|
0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x18,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7,*/
|
|
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, 0x41,
|
|
0x58, 0x2d, 0x32, 0x30, 0x30, 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, 0x67, 0x02, 0x03, 0x16, 0x31,
|
|
0x4a, 0x05, 0x14, 0x04, 0x13, 0x20, 0x02, 0x11, 0x01, 0x10, 0x1f, 0x66,
|
|
0x03, 0x0c, 0x00, 0x10, 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, 0xa6
|
|
};
|
|
|
|
uint8_t i2cWrite(uint8_t addr, uint8_t reg, uint8_t value) {
|
|
uint8_t err;
|
|
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(reg);
|
|
Wire.write(value);
|
|
|
|
if ((err = Wire.endTransmission()) != 0) {
|
|
debugf("i2c: write %02x:%02x = %02x - error %02x\r\n", addr, reg, value, err);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
uint8_t i2cRead(uint8_t addr, uint8_t reg, uint8_t cnt = 1) {
|
|
Wire.beginTransmission(addr);
|
|
Wire.write(reg);
|
|
if (Wire.endTransmission(false) != 0) {
|
|
Serial.println("transmission end failed?");
|
|
}
|
|
Wire.requestFrom((int) addr, (int) cnt);
|
|
//Serial.printf("Available: %d\r\n", Wire.available());
|
|
return Wire.read();
|
|
}
|
|
|
|
uint8_t setEDID(uint8_t port, uint8_t* edid)
|
|
{
|
|
byte err, address;
|
|
int nDevices;
|
|
|
|
if ((err = i2cWrite(0x64, 0x42, port)) != 0) {
|
|
Serial.print("start error occured: ");
|
|
Serial.println(err);
|
|
return err;
|
|
}
|
|
|
|
uint8_t edidData[257];
|
|
edidData[0] = 0xff;
|
|
memcpy(edidData+1, edid, 256);
|
|
if ((err = twi_writeTo(0x64, edidData, 257, true)) != 0) {
|
|
Serial.printf("Edid write failed: %d\r\n", err);
|
|
}
|
|
|
|
if ((err = i2cWrite(0x64, 0x42, 0x3c)) != 0) {
|
|
Serial.print("end error occured: ");
|
|
Serial.println(err);
|
|
return err;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void select_output(char output)
|
|
{
|
|
if (output == 0) {
|
|
// Output A
|
|
if (reg49_shadow & 0x10) {
|
|
i2cWrite(0x65, 0x07, 0x02);
|
|
} else {
|
|
i2cWrite(0x65, 0x07, 0x00);
|
|
}
|
|
} else {
|
|
// Output B
|
|
if (reg49_shadow & 0x20) {
|
|
i2cWrite(0x65, 0x07, 0x03);
|
|
} else {
|
|
i2cWrite(0x65, 0x07, 0x01);
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t matrixInit() {
|
|
setEDID(0, edidbuf);
|
|
setEDID(1, edidbuf);
|
|
setEDID(2, edidbuf);
|
|
setEDID(3, edidbuf);
|
|
|
|
i2cWrite(0x64, 0x2d, 0x82);
|
|
i2cWrite(0x64, 0x40, 0x00);
|
|
//i2cWrite(0x64, 0x49, 0xc0);
|
|
i2cWrite(0x64, 0x4b, 0x06);
|
|
i2cWrite(0x64, 0x4c, 0x76);
|
|
|
|
|
|
/*debugf("reg49: %02x", get_reg49_value());
|
|
reg49_shadow = get_reg49_value();
|
|
i2cWrite(0x64, 0x49, reg49_shadow);*/
|
|
|
|
//select_output(0);
|
|
//i2cWrite(0x64, 0x0e, 0x01);
|
|
//select_output(1);
|
|
//i2cWrite(0x64, 0x0e, 0x01);
|
|
|
|
// selectOutput(0);
|
|
/*for (int i = 0; i < 4; i++) {
|
|
i2cWrite(0x65, 0x07, i);
|
|
i2cWrite(0x65, 0x0e, 0x01);
|
|
}*/
|
|
|
|
//i2cWrite(0x64, 0x49, 0xc0);
|
|
//i2cWrite(0x64, 0x4a, 0b11000000);
|
|
i2cWrite(0x65, 0x0f, 0x10);
|
|
i2cWrite(0x64, 0x4a, 0b11101111);
|
|
}
|
|
|
|
void i2cDump(uint8_t addr) {
|
|
for (int i = 0; i < 0x80; i++) {
|
|
if (i % 16 == 0) Serial.printf("\r\n%02x: ", i);
|
|
|
|
Serial.printf("%02x ", i2cRead(addr, i));
|
|
}
|
|
|
|
Serial.println();
|
|
}
|
|
|
|
void init()
|
|
{
|
|
Serial.begin(SERIAL_BAUD_RATE); // 115200 by default
|
|
Serial.systemDebugOutput(true); // Disable debug output
|
|
|
|
WDT.enable(false); // First (but not the best) option: fully disable watch dog timer
|
|
|
|
// Default I2C pins (SDA: 2, SCL:0)
|
|
|
|
// You can change pins:
|
|
//Wire.pins(14, 12); // SDA, SCL
|
|
|
|
Wire.begin(4, 5);
|
|
Wire.setClock(300000);
|
|
Wire.setClockStretchLimit(5*230);
|
|
|
|
for ( int i = 0 ; i < 2; i++) {
|
|
Serial.printf("Doing things in %d...\r\n", 2-i);
|
|
delay(1000);
|
|
}
|
|
|
|
matrixInit();
|
|
|
|
procTimer.initializeMs(3000, *[]() {
|
|
Serial.println(millis());
|
|
Serial.println("Hello!");
|
|
debugf(" int: %02x %02x %02x", i2cRead(0x64, 0x29, 3), Wire.read(), Wire.read());
|
|
debugf("stat0: %02x", i2cRead(0x64, 0x3c));
|
|
debugf("stat1: %02x", i2cRead(0x64, 0x3d));
|
|
debugf("stat2: %02x", i2cRead(0x64, 0x3f));
|
|
debugf("ctrl0: %02x", i2cRead(0x64, 0x40));
|
|
debugf("ctrl1: %02x", i2cRead(0x64, 0x41));
|
|
debugf("ctrl2: %02x", i2cRead(0x64, 0x42));
|
|
debugf("ctrl3: %02x", i2cRead(0x64, 0x43));
|
|
debugf("ctrl4: %02x", i2cRead(0x64, 0x44));
|
|
debugf("ctrl5: %02x", i2cRead(0x64, 0x45));
|
|
debugf("ctrl6: %02x", i2cRead(0x64, 0x46));
|
|
debugf("ctrl7: %02x", i2cRead(0x64, 0x47));
|
|
debugf("ctrl8: %02x", i2cRead(0x64, 0x48));
|
|
debugf("ctrl9: %02x", i2cRead(0x64, 0x49));
|
|
debugf("ctrl10: %02x", i2cRead(0x64, 0x4a));
|
|
debugf("ctrl11: %02x", i2cRead(0x64, 0x4b));
|
|
|
|
|
|
//i2cDump(0x64);
|
|
|
|
/*setEDID(0, edidbuf);
|
|
setEDID(1, edidbuf);
|
|
setEDID(2, edidbuf);
|
|
setEDID(3, edidbuf);*/
|
|
|
|
|
|
Serial.println("====\n\n0x65 (0):");
|
|
//select_output(0);
|
|
//i2cDump(0x65);
|
|
|
|
Serial.printf("%02x ", i2cRead(0x65, 0x07));
|
|
Serial.printf("%02x ", i2cRead(0x65, 0x09));
|
|
Serial.printf("%02x \r\n", i2cRead(0x65, 0x0f));
|
|
Serial.println("====\n\n0x65 (1):");
|
|
//select_output(1);
|
|
//i2cDump(0x65);
|
|
|
|
Serial.printf("%02x ", i2cRead(0x65, 0x07));
|
|
Serial.printf("%02x ", i2cRead(0x65, 0x09));
|
|
Serial.printf("%02x \r\n", i2cRead(0x65, 0x0f));
|
|
}).start();
|
|
}
|