Skip to content

Commit

Permalink
Clear I2C status on short slave reads
Browse files Browse the repository at this point in the history
Fixes #222

The HW needs to have the TXC_ABRT flag cleared when a slave transmission is
cut short by the master, or else it will effectively break the I2C bus and
never recover.
  • Loading branch information
earlephilhower committed Jun 26, 2021
1 parent 35c974d commit aac8146
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void TwoWire::begin(uint8_t addr) {
i2c_set_slave_mode(_i2c, true, addr);

// Our callback IRQ
_i2c->hw->intr_mask = (1 << 10) | (1 << 9) | (1 << 5) | (1 << 2);
_i2c->hw->intr_mask = (1 << 10) | (1 << 9) | (1 << 6) | (1 << 5) | (1 << 2);

int irqNo = I2C0_IRQ + i2c_hw_index(_i2c);
irq_set_exclusive_handler(irqNo, i2c_hw_index(_i2c) == 0 ? _handler0 : _handler1);
Expand All @@ -139,6 +139,7 @@ void TwoWire::begin(uint8_t addr) {
}

void TwoWire::onIRQ() {
Serial.printf("Wire.IRQ=%08x\n", _i2c->hw->intr_stat);
if (_i2c->hw->intr_stat & (1 << 10)) {
_buffLen = 0;
_buffOff = 0;
Expand All @@ -154,6 +155,10 @@ void TwoWire::onIRQ() {
_slaveStartDet = false;
_i2c->hw->clr_stop_det;
}
if (_i2c->hw->intr_stat & (1 << 6)) {
// TX_ABRT
_i2c->hw->clr_tx_abrt;
}
if (_i2c->hw->intr_stat & (1 << 5)) {
// RD_REQ
if (_onRequestCallback) {
Expand Down

0 comments on commit aac8146

Please sign in to comment.