check if HPD is forwarded

This commit is contained in:
King Kévin 2022-07-11 12:26:28 +02:00
parent 06c14750fc
commit 2859bb7a09
1 changed files with 26 additions and 17 deletions

43
main.c
View File

@ -26,6 +26,7 @@ static bool i2c_fwd = false; // if the I²C source lines are connected to sink
// hot plug detect pull up
#define HPD_PORT GPIO_PC
#define HPD_PIN PC6
static bool hpd_fwd = false; // if the I²C source line is connected to sink
// copy EDID setting
#define EDID_PORT GPIO_PC
#define EDID_PIN PC7
@ -136,13 +137,16 @@ void main(void)
SCL_PU_PORT->ODR.reg |= SCL_PU_PIN; // pull up SCL line
}
// configure external EEPROM (actually not used)
WP_PORT->DDR.reg |= WP_PIN; // switch pin to output
WP_PORT->CR1.reg &= ~WP_PIN; // switch pin to open drain
WP_PORT->ODR.reg |= WP_PIN; // let write protect pulled up
// configure I²C
if (!i2c_fwd) { // we will act as I²C slave EEPROM
/*
HDMI 1.3 spec:
The Sink shall be capable of responding with EDID 1.3 data and up to 255 extension blocks, each 128 bytes long (up to 32K bytes total E-EDID memory) whenever the Hot Plug Detect signal is asserted.
The Sink should be capable of providing E-EDID information over the Enhanced DDC channel whenever the +5V Power signal is provided. This should be available within 20msec after the +5V Power signal is provided.
firewall:
we will only be able to provide 1 extension block since we can only respond to one I²C address 0x50 for the EDID, and not to the 0x30 Segment Pointer (for the other pages/extension blocks)
*/
GPIO_PB->CR1.reg |= (PB4 | PB5); // enable internal pull-up on SCL/SDA
GPIO_PB->DDR.reg &= ~(PB4 | PB5); // set SCL/SDA as input before it is used as alternate function by the peripheral
I2C_CR1 |= I2C_CR1_PE; // enable I²C peripheral (must be done before any other register is written)
@ -159,20 +163,25 @@ void main(void)
I2C_ITR |= (I2C_ITR_ITBUFEN | I2C_ITR_ITEVTEN); // enable buffer and event interrupts
}
// configure external EEPROM (actually not used)
WP_PORT->DDR.reg |= WP_PIN; // switch pin to output
WP_PORT->CR1.reg &= ~WP_PIN; // switch pin to open drain
WP_PORT->ODR.reg |= WP_PIN; // let write protect pulled up
// configure hot plug detect
HPD_PORT->DDR.reg |= HPD_PIN; // switch pin to output
HPD_PORT->CR1.reg |= HPD_PIN; // switch pin to push pull
HPD_PORT->ODR.reg |= HPD_PIN; // pull up HPD line to indicate EDID is ready
// TODO check if connected to sink/monitor
/*
The Sink shall be capable of responding with EDID 1.3 data and up to 255 extension blocks, each
128 bytes long (up to 32K bytes total E-EDID memory) whenever the Hot Plug Detect signal is
asserted.
The Sink should be capable of providing E-EDID information over the Enhanced DDC channel
whenever the +5V Power signal is provided. This should be available within 20msec after the +5V
Power signal is provided.
*/
HPD_PORT->CR1.reg &= ~HPD_PIN; // switch pin to open drain
HPD_PORT->ODR.reg &= ~HPD_PIN; // drain line
wait_10us(0); // wait shortly to clear tristate
HPD_PORT->DDR.reg &= ~HPD_PIN; // switch pin to input (already floating)
if (HPD_PORT->IDR.reg & HPD_PIN) { // line is pulled up
hpd_fwd = true; // remember the HPD line is pulled up
}
if (!hpd_fwd) { // we have to pull up
HPD_PORT->DDR.reg |= HPD_PIN; // switch pin to output
HPD_PORT->CR1.reg |= HPD_PIN; // switch pin to push pull
HPD_PORT->ODR.reg |= HPD_PIN; // pull up HPD line to indicate EDID is ready
}
// check if EDID should be copied
EDID_PORT->DDR.reg &= ~EDID_PIN; // switch pin to output