|
|
|
@ -47,7 +47,13 @@ |
|
|
|
|
#define HD44780_DB7_PIN PD3 |
|
|
|
|
|
|
|
|
|
// the I²C address of this slave
|
|
|
|
|
#define I2C_ADDR 0x47U |
|
|
|
|
static uint8_t i2c_addr = 0x47U; |
|
|
|
|
#define A0_PORT GPIO_PD |
|
|
|
|
#define A0_PIN PD4 |
|
|
|
|
#define A1_PORT GPIO_PD |
|
|
|
|
#define A1_PIN PD5 |
|
|
|
|
#define A2_PORT GPIO_PD |
|
|
|
|
#define A2_PIN PD6 |
|
|
|
|
|
|
|
|
|
// the functions we can call over I²C
|
|
|
|
|
enum i2c_mode_t { |
|
|
|
@ -283,6 +289,29 @@ void main(void) |
|
|
|
|
HD44780_DB4_PORT->CR1.reg |= HD44780_DB4_PIN; // use in push-pull mode
|
|
|
|
|
hd44780_data_direction(false); // configure pins as output
|
|
|
|
|
|
|
|
|
|
// read I²C address bits
|
|
|
|
|
A0_PORT->DDR.reg &= ~A0_PIN; // switch pin to input
|
|
|
|
|
A0_PORT->CR1.reg |= A0_PIN; // enable pull-up
|
|
|
|
|
if (A0_PORT->IDR.reg & A0_PIN) { |
|
|
|
|
i2c_addr |= 0x01; |
|
|
|
|
} else { |
|
|
|
|
i2c_addr &= ~0x01; |
|
|
|
|
} |
|
|
|
|
A1_PORT->DDR.reg &= ~A1_PIN; // switch pin to input
|
|
|
|
|
A1_PORT->CR1.reg |= A1_PIN; // enable pull-up
|
|
|
|
|
if (A1_PORT->IDR.reg & A1_PIN) { |
|
|
|
|
i2c_addr |= 0x02; |
|
|
|
|
} else { |
|
|
|
|
i2c_addr &= ~0x02; |
|
|
|
|
} |
|
|
|
|
A2_PORT->DDR.reg &= ~A2_PIN; // switch pin to input
|
|
|
|
|
A2_PORT->CR1.reg |= A2_PIN; // enable pull-up
|
|
|
|
|
if (A2_PORT->IDR.reg & A2_PIN) { |
|
|
|
|
i2c_addr |= 0x04; |
|
|
|
|
} else { |
|
|
|
|
i2c_addr &= ~0x04; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// configure I²C
|
|
|
|
|
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
|
|
|
|
@ -298,7 +327,7 @@ void main(void) |
|
|
|
|
//I2C_CR1 |= I2C_CR1_ENGC; // enable general call (I was not able to have slave select with address 0x00 ACKed)
|
|
|
|
|
I2C_CR2 |= I2C_CR2_ACK; // enable acknowledgement if address matches
|
|
|
|
|
// since we are slave and not master, we don't have to set CCR
|
|
|
|
|
I2C_OARL = (I2C_ADDR << 1U); // set slave address
|
|
|
|
|
I2C_OARL = (i2c_addr << 1U); // set slave address
|
|
|
|
|
I2C_ITR |= (I2C_ITR_ITBUFEN | I2C_ITR_ITEVTEN); // enable buffer and event interrupts
|
|
|
|
|
|
|
|
|
|
// configure auto-wakeup (AWU) to be able to refresh the watchdog
|
|
|
|
|