Skip to content

Commit f575fda

Browse files
authored
F1: I2C: Fix STOP condition on I2C Master for Bus Error and Timeout
Merge pull request #804 from dewhisna/Wire_Stop_Fix
2 parents d60ff19 + fa6c360 commit f575fda

File tree

1 file changed

+20
-6
lines changed
  • STM32F1/cores/maple/libmaple

1 file changed

+20
-6
lines changed

STM32F1/cores/maple/libmaple/i2c.c

+20-6
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,24 @@ int32 i2c_master_xfer(i2c_dev *dev,
409409
// with state changes in the IRQ handlers:
410410
dev->state = I2C_STATE_ERROR;
411411
if (rc == I2C_ERROR_TIMEOUT) dev->error_flags |= I2C_SR1_TIMEOUT;
412+
if (!(dev->config_flags & I2C_SLAVE_MODE) &&
413+
(dev->error_flags & (I2C_SR1_AF | I2C_SR1_BERR | I2C_SR1_TIMEOUT))
414+
) { // In Master Mode, we need to abort the transmission with a STOP
415+
// for NACK, Bus Error, or Timeout
416+
uint32 cr1;
417+
while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
418+
I2C_CR1_STOP |
419+
I2C_CR1_PEC)) {
420+
; // Must wait for pending start/stop/pec before setting stop to avoid
421+
// accidental restart condition. See ST RM0008 Note in 26.6.1 (I2C_CR1)
422+
}
423+
dev->regs->CR1 |= I2C_CR1_STOP;
424+
while ((cr1 = dev->regs->CR1) & (I2C_CR1_START |
425+
I2C_CR1_STOP |
426+
I2C_CR1_PEC)) {
427+
;
428+
}
429+
}
412430
} else {
413431
dev->state = I2C_STATE_IDLE;
414432
}
@@ -782,14 +800,10 @@ void _i2c_irq_error_handler(i2c_dev *dev) {
782800
dev->state = I2C_STATE_IDLE;
783801
return;
784802
}
785-
} else {
786-
// Master should send a STOP on NACK:
787-
if (sr1 & I2C_SR1_AF) {
788-
dev->regs->CR1 |= I2C_CR1_STOP;
789-
}
790803
}
791804

792-
/* Catch any other strange errors while in slave mode.
805+
/* Catch any other strange errors while in slave mode and
806+
* all errors in master mode (which are handled by outer loop).
793807
* I have seen BERR caused by an over fast master device
794808
* as well as several overflows and arbitration failures.
795809
* We are going to reset SR flags and carry on at this point which

0 commit comments

Comments
 (0)