main: read I²C EEPROM until data is constent
This commit is contained in:
parent
c68bf6a324
commit
03d4874605
31
main.c
31
main.c
|
@ -180,14 +180,37 @@ static bool save_edid(void)
|
||||||
// return if succeeded
|
// return if succeeded
|
||||||
static bool read_edid(void)
|
static bool read_edid(void)
|
||||||
{
|
{
|
||||||
const uint8_t address[] = {0};
|
if (!i2c_master_setup(5)) {
|
||||||
if (!i2c_master_setup(false)) {
|
puts("I²C setup failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (I2C_MASTER_RC_NONE != i2c_master_address_read(I2C_SLAVE, false, address, ARRAY_LENGTH(address), edid, ARRAY_LENGTH(edid))) {
|
// read all pages
|
||||||
return false;
|
// in theory I could read the whole address space at once, but in practice short clock pulses appear after some bytes, corrupting the data flow. I have no idea what the cause of theses glitches is (I even used WFI to reduce EMI as recommended in the errata)
|
||||||
|
for (uint16_t i = 0; i < ARRAY_LENGTH(edid); i += I2C_EEPROM_PAGE_SIZE) {
|
||||||
|
const uint8_t address[] = {i}; // address of page to read
|
||||||
|
uint8_t data[I2C_EEPROM_PAGE_SIZE]; // data from page
|
||||||
|
bool same = false; // if the data read is the same
|
||||||
|
while (!same) { // read until the data is the same
|
||||||
|
const enum i2c_master_rc rc = i2c_master_address_read(I2C_SLAVE, false, address, ARRAY_LENGTH(address), data, ARRAY_LENGTH(data)); // read I²C EEPROM data
|
||||||
|
if (I2C_MASTER_RC_NONE != rc) {
|
||||||
|
puts("I²C read failed (");
|
||||||
|
putc('0' + rc);
|
||||||
|
putc(')');
|
||||||
|
i2c_master_reset(); // try to clear any I²C issue
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// check if the data is the same and copy it to EDID
|
||||||
|
same = true;
|
||||||
|
for (uint16_t j = 0; j < I2C_EEPROM_PAGE_SIZE; j++) {
|
||||||
|
if (data[j] != edid[i + j]) {
|
||||||
|
same = false;
|
||||||
|
}
|
||||||
|
edid[i + j] = data[j]; // save last read data
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i2c_master_release(); // release I²C again
|
i2c_master_release(); // release I²C again
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue