summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Schodet2013-02-20 17:14:05 +0100
committerNicolas Schodet2019-10-06 23:29:59 +0200
commitc6e9a45e1c6e1568e58051c4f345a6b943383db7 (patch)
tree1b0689e2d616965a2724aefbdb5247c1422cdf3a
parent1b86157796e90e83b9a1580ef7fea13361421d85 (diff)
ucoolib/hal/i2c: wait for BTF at end of transmission
In master mode, wait for end of transmission before STOP bit is set.
-rw-r--r--ucoolib/hal/i2c/i2c_hard.stm32.cc28
1 files changed, 16 insertions, 12 deletions
diff --git a/ucoolib/hal/i2c/i2c_hard.stm32.cc b/ucoolib/hal/i2c/i2c_hard.stm32.cc
index 11baba6..7529953 100644
--- a/ucoolib/hal/i2c/i2c_hard.stm32.cc
+++ b/ucoolib/hal/i2c/i2c_hard.stm32.cc
@@ -252,20 +252,15 @@ I2cHard::ev_isr (int n)
}
i2c_trace ("<%d> master sr2=%04x", n, sr2);
}
- else if (sr1 & I2C_SR1_TxE)
+ else if (sr1 & I2C_SR1_TxE
+ && i2c.buf_index_ < i2c.buf_count_)
{
i2c_trace ("<%d> master tx index=%d", n, i2c.buf_index_);
- // Send next byte or stop.
- if (i2c.buf_index_ < i2c.buf_count_)
- I2C_DR (base) = i2c.master_buf_[i2c.buf_index_++];
- else
- {
- I2C_CR1 (base) = I2C_CR1_ACK | I2C_CR1_STOP | I2C_CR1_PE;
+ // Send next byte.
+ I2C_DR (base) = i2c.master_buf_[i2c.buf_index_++];
+ // Wait for BTF if last one.
+ if (i2c.buf_index_ == i2c.buf_count_)
I2C_CR2 (base) &= ~I2C_CR2_ITBUFEN;
- I2C_DR (base) = 0xff;
- i2c.master_ = false;
- i2c.master_status_ = i2c.buf_index_;
- }
}
else if (sr1 & I2C_SR1_RxNE
&& i2c.buf_count_ - i2c.buf_index_ > 3)
@@ -279,14 +274,23 @@ I2cHard::ev_isr (int n)
else if (sr1 & I2C_SR1_BTF)
{
i2c_trace ("<%d> master btf index=%d", n, i2c.buf_index_);
- if (i2c.buf_count_ - i2c.buf_index_ == 3)
+ if (!(i2c.master_slave_addr_ & 1))
+ {
+ // End of transmission.
+ I2C_CR1 (base) = I2C_CR1_ACK | I2C_CR1_STOP | I2C_CR1_PE;
+ i2c.master_ = false;
+ i2c.master_status_ = i2c.buf_index_;
+ }
+ else if (i2c.buf_count_ - i2c.buf_index_ == 3)
{
+ // Near end of reception.
I2C_CR1 (base) = I2C_CR1_PE;
i2c.master_buf_[i2c.buf_index_++] = I2C_DR (base);
// Wait for BTF.
}
else
{
+ // End of reception.
I2C_CR1 (base) = I2C_CR1_ACK | I2C_CR1_STOP | I2C_CR1_PE;
if (i2c.buf_count_ - i2c.buf_index_ == 2)
i2c.master_buf_[i2c.buf_index_++] = I2C_DR (base);