check if I²C is forwarded
This commit is contained in:
parent
e2cdc89a30
commit
d247e2e1e8
22
main.c
22
main.c
|
@ -18,6 +18,7 @@
|
||||||
#define SDA_PU_PIN PC3
|
#define SDA_PU_PIN PC3
|
||||||
#define SCL_PU_PORT GPIO_PC
|
#define SCL_PU_PORT GPIO_PC
|
||||||
#define SCL_PU_PIN PC4
|
#define SCL_PU_PIN PC4
|
||||||
|
static bool i2c_fwd = false; // if the I²C source lines are connected to sink
|
||||||
// external EEPROM write protect pin
|
// external EEPROM write protect pin
|
||||||
#define WP_PORT GPIO_PC
|
#define WP_PORT GPIO_PC
|
||||||
#define WP_PIN PC5
|
#define WP_PIN PC5
|
||||||
|
@ -109,13 +110,30 @@ void main(void)
|
||||||
UART1->CR2.fields.TEN = 1; // enable TX
|
UART1->CR2.fields.TEN = 1; // enable TX
|
||||||
|
|
||||||
// configure I²C pull-ups
|
// configure I²C pull-ups
|
||||||
|
SDA_PU_PORT->DDR.reg |= SDA_PU_PIN; // switch pin to output
|
||||||
|
SDA_PU_PORT->CR1.reg &= ~SDA_PU_PIN; // switch pin to open-drain
|
||||||
|
SDA_PU_PORT->ODR.reg &= ~SDA_PU_PIN; // pull SDA line low
|
||||||
|
wait_10us(0); // wait shortly to clear tristate
|
||||||
|
SDA_PU_PORT->DDR.reg &= ~SDA_PU_PIN; // switch pin to input (already floating)
|
||||||
|
if (SDA_PU_PORT->IDR.reg & SDA_PU_PIN) { // line is pulled up
|
||||||
|
i2c_fwd = true; // remember the I²C line(s) are forwarded
|
||||||
|
}
|
||||||
|
SCL_PU_PORT->DDR.reg |= SCL_PU_PIN; // switch pin to output
|
||||||
|
SCL_PU_PORT->CR1.reg &= ~SCL_PU_PIN; // switch pin to open-drain
|
||||||
|
SCL_PU_PORT->ODR.reg &= ~SCL_PU_PIN; // pull SDA line low
|
||||||
|
wait_10us(0); // wait shortly to clear tristate
|
||||||
|
SCL_PU_PORT->DDR.reg &= ~SCL_PU_PIN; // switch pin to input (already floating)
|
||||||
|
if (SCL_PU_PORT->IDR.reg & SCL_PU_PIN) { // line is pulled up
|
||||||
|
i2c_fwd = true; // remember the I²C line(s) are forwarded
|
||||||
|
}
|
||||||
|
if (!i2c_fwd) { // I²C lines are not pulled up
|
||||||
SDA_PU_PORT->DDR.reg |= SDA_PU_PIN; // switch pin to output
|
SDA_PU_PORT->DDR.reg |= SDA_PU_PIN; // switch pin to output
|
||||||
SDA_PU_PORT->CR1.reg |= SDA_PU_PIN; // switch pin to push pull
|
SDA_PU_PORT->CR1.reg |= SDA_PU_PIN; // switch pin to push pull
|
||||||
SDA_PU_PORT->ODR.reg |= SDA_PU_PIN; // pull up SDA line
|
SDA_PU_PORT->ODR.reg |= SDA_PU_PIN; // pull up SDA line
|
||||||
SCL_PU_PORT->DDR.reg |= SCL_PU_PIN; // switch pin to output
|
SCL_PU_PORT->DDR.reg |= SCL_PU_PIN; // switch pin to output
|
||||||
SCL_PU_PORT->CR1.reg |= SCL_PU_PIN; // switch pin to push pull
|
SCL_PU_PORT->CR1.reg |= SCL_PU_PIN; // switch pin to push pull
|
||||||
SCL_PU_PORT->ODR.reg |= SCL_PU_PIN; // pull up SCL line
|
SCL_PU_PORT->ODR.reg |= SCL_PU_PIN; // pull up SCL line
|
||||||
// TODO verify if I²C lines are connected to monitor
|
}
|
||||||
|
|
||||||
// configure external EEPROM (actually not used)
|
// configure external EEPROM (actually not used)
|
||||||
WP_PORT->DDR.reg |= WP_PIN; // switch pin to output
|
WP_PORT->DDR.reg |= WP_PIN; // switch pin to output
|
||||||
|
@ -123,6 +141,7 @@ void main(void)
|
||||||
WP_PORT->ODR.reg |= WP_PIN; // let write protect pulled up
|
WP_PORT->ODR.reg |= WP_PIN; // let write protect pulled up
|
||||||
|
|
||||||
// configure I²C
|
// configure I²C
|
||||||
|
if (!i2c_fwd) { // we will act as I²C slave EEPROM
|
||||||
GPIO_PB->CR1.reg |= (PB4 | PB5); // enable internal pull-up on SCL/SDA
|
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
|
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)
|
I2C_CR1 |= I2C_CR1_PE; // enable I²C peripheral (must be done before any other register is written)
|
||||||
|
@ -137,6 +156,7 @@ void main(void)
|
||||||
// since we are slave and not master, we don't have to set CCR
|
// since we are slave and not master, we don't have to set CCR
|
||||||
I2C_OARL = (0x50U << 1U); // set slave address for EEPROM
|
I2C_OARL = (0x50U << 1U); // set slave address for EEPROM
|
||||||
I2C_ITR |= (I2C_ITR_ITBUFEN | I2C_ITR_ITEVTEN); // enable buffer and event interrupts
|
I2C_ITR |= (I2C_ITR_ITBUFEN | I2C_ITR_ITEVTEN); // enable buffer and event interrupts
|
||||||
|
}
|
||||||
|
|
||||||
// configure hot plug detect
|
// configure hot plug detect
|
||||||
HPD_PORT->DDR.reg |= HPD_PIN; // switch pin to output
|
HPD_PORT->DDR.reg |= HPD_PIN; // switch pin to output
|
||||||
|
|
Loading…
Reference in New Issue