implement i2c write

This commit is contained in:
King Kévin 2022-08-19 15:56:00 +02:00
parent 695e5dc9f4
commit df482ca7c4
1 changed files with 15 additions and 17 deletions

32
main.c
View File

@ -48,8 +48,14 @@ static bool hpd_fwd = false; // if the I²C source line is connected to sink
// if an I²C transaction started // if an I²C transaction started
static volatile bool i2c_transaction_new = false; static volatile bool i2c_transaction_new = false;
// if an I²C transaction with new data started // if an I²C transaction with incoming data started
static volatile bool i2c_input_new = false; static volatile bool i2c_input_new = false;
// if the byte should be programmed
static volatile bool i2c_prog = false;
// the address of the byte to be read or programmed
static volatile uint8_t i2c_addr = 0;
// the data to be programmed
static volatile uint8_t i2c_data = 0;
// blocking wait (in 10 us steps, up to UINT32_MAX / 10) // blocking wait (in 10 us steps, up to UINT32_MAX / 10)
static void wait_10us(uint32_t us10) static void wait_10us(uint32_t us10)
@ -510,25 +516,21 @@ void awu(void) __interrupt(IRQ_AWU) // auto wakeup
void i2c(void) __interrupt(IRQ_I2C) // auto wakeup void i2c(void) __interrupt(IRQ_I2C) // auto wakeup
{ {
static uint8_t addr = 0; // EEPROM address to read
// make copies of status registers, since some bits might be cleared meanwhile // make copies of status registers, since some bits might be cleared meanwhile
const uint8_t sr1 = I2C_SR1; const uint8_t sr1 = I2C_SR1;
const uint8_t sr2 = I2C_SR2; const uint8_t sr2 = I2C_SR2;
const uint8_t sr3 = I2C_SR3; // clears ADDR after reading SR1 const uint8_t sr3 = I2C_SR3; // clears ADDR after reading SR1
if (sr1 & I2C_SR1_TXE) { // transmission buffer is empty if (sr1 & I2C_SR1_TXE) { // transmission buffer is empty
// transmit next byte I2C_DR = *(uint8_t*)(EEPROM_ADDR + i2c_addr++); // transmit next byte (even if invalid)
if (eeprom_valid) {
I2C_DR = *(uint8_t*)(EEPROM_ADDR + addr++);
} else {
I2C_DR = 0xff;
}
} }
if (sr1 & I2C_SR1_RXNE) { // receive buffer is full if (sr1 & I2C_SR1_RXNE) { // receive buffer is full
const uint8_t data = I2C_DR; // read data (also clears flag) i2c_data = I2C_DR; // read data (also clears flag)
if (I2C_CR2 & I2C_CR2_ACK) { if (i2c_input_new) { // we just received the first byte
addr = data; // we only take the first address byte i2c_addr = i2c_data; // we only take the first address byte
i2c_input_new = false; // next byte is not the first
} else { // received data byte
i2c_prog = true; // notify main loop data needs to be programmed
} }
I2C_CR2 &= I2C_CR2_ACK; // NACK next received byte
} }
if (sr1 & I2C_SR1_STOPF) { // stop received if (sr1 & I2C_SR1_STOPF) { // stop received
I2C_CR2 |= I2C_CR2_ACK; // this is just to clear the flag I2C_CR2 |= I2C_CR2_ACK; // this is just to clear the flag
@ -536,11 +538,7 @@ void i2c(void) __interrupt(IRQ_I2C) // auto wakeup
if (sr1 & I2C_SR1_ADDR) { // our slave address has been selected if (sr1 & I2C_SR1_ADDR) { // our slave address has been selected
i2c_transaction_new = true; // notify main loop transaction started i2c_transaction_new = true; // notify main loop transaction started
if (sr3 & I2C_SR3_TRA) { // start data transmission if (sr3 & I2C_SR3_TRA) { // start data transmission
if (eeprom_valid) { I2C_DR = *(uint8_t*)(EEPROM_ADDR + i2c_addr++); // transmit selected byte
I2C_DR = *(uint8_t*)(EEPROM_ADDR + addr++); // transmit selected byte
} else {
I2C_DR = 0xff;
}
i2c_input_new = false; // notify we send data i2c_input_new = false; // notify we send data
} else { // we will receive data } else { // we will receive data
I2C_CR2 |= I2C_CR2_ACK; // ACK next received byte I2C_CR2 |= I2C_CR2_ACK; // ACK next received byte