summaryrefslogtreecommitdiffhomepage
path: root/digital/ucoolib/ucoolib/hal
diff options
context:
space:
mode:
authorNicolas Schodet2013-02-20 17:15:53 +0100
committerNicolas Schodet2013-02-20 17:15:53 +0100
commitce8581af2514e8d60c0ce14f4a2c39944b6ab988 (patch)
tree93b245c49226494f14686f2b12c10bddbd4d1d2e /digital/ucoolib/ucoolib/hal
parentcab54c77e772be0cce1d77439bdcbd63910c62be (diff)
digital/ucoolib/ucoolib/hal/i2c: add finished handler call
Diffstat (limited to 'digital/ucoolib/ucoolib/hal')
-rw-r--r--digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc6
-rw-r--r--digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc59
2 files changed, 65 insertions, 0 deletions
diff --git a/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc b/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc
index 75299535..f11006ba 100644
--- a/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc
+++ b/digital/ucoolib/ucoolib/hal/i2c/i2c_hard.stm32.cc
@@ -280,6 +280,8 @@ I2cHard::ev_isr (int n)
I2C_CR1 (base) = I2C_CR1_ACK | I2C_CR1_STOP | I2C_CR1_PE;
i2c.master_ = false;
i2c.master_status_ = i2c.buf_index_;
+ if (i2c.finished_handler_)
+ i2c.finished_handler_->finished (i2c.master_status_);
}
else if (i2c.buf_count_ - i2c.buf_index_ == 3)
{
@@ -297,6 +299,8 @@ I2cHard::ev_isr (int n)
i2c.master_buf_[i2c.buf_index_++] = I2C_DR (base);
i2c.master_ = false;
i2c.master_status_ = i2c.buf_index_;
+ if (i2c.finished_handler_)
+ i2c.finished_handler_->finished (i2c.master_status_);
}
}
else
@@ -381,6 +385,8 @@ I2cHard::er_isr (int n)
I2C_CR1 (base) = I2C_CR1_ACK | I2C_CR1_STOP | I2C_CR1_PE;
i2c.master_ = false;
i2c.master_status_ = i2c.buf_index_;
+ if (i2c.finished_handler_)
+ i2c.finished_handler_->finished (i2c.master_status_);
}
}
I2C_CR2 (base) &= ~I2C_CR2_ITBUFEN;
diff --git a/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc b/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc
index b870665b..8196b663 100644
--- a/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc
+++ b/digital/ucoolib/ucoolib/hal/i2c/test/test_i2c.cc
@@ -89,6 +89,65 @@ test_basic (ucoo::TestSuite &tsuite, ucoo::I2cMaster &m,
test_fail_break_unless (test, std::count (buf, buf + r, c) == r);
}
}
+ do {
+ ucoo::Test test (tsuite, "callback");
+ // Callback object will start a reception, then a transmission of what
+ // was received.
+ class TestCallback : public ucoo::I2cMaster::FinishedHandler
+ {
+ ucoo::I2cMaster &m_;
+ uint8_t addr_;
+ int step_;
+ char buf_[buffer_size];
+ public:
+ bool failed;
+ public:
+ TestCallback (ucoo::I2cMaster &m, uint8_t addr)
+ : m_ (m), addr_ (addr), step_ (0), failed (false) { }
+ void finished (int status)
+ {
+ if (status != buffer_size)
+ failed = true;
+ else
+ {
+ switch (step_)
+ {
+ case 0:
+ m_.recv (addr_, buf_, buffer_size);
+ step_++;
+ break;
+ case 1:
+ m_.send (addr_, buf_, buffer_size);
+ step_++;
+ break;
+ case 2:
+ // Nothing, stop.
+ break;
+ }
+ }
+ }
+ };
+ TestCallback callback (m, addr);
+ m.register_finished (callback);
+ // Set slave data.
+ char buf[buffer_size];
+ std::fill (buf, buf + sizeof (buf), 42);
+ d.update (buf, sizeof (buf));
+ // Start transfers.
+ std::fill (buf, buf + sizeof (buf), 21);
+ m.send (addr, buf, sizeof (buf));
+ // Will only return after the last transfer.
+ m.wait ();
+ m.unregister_finished ();
+ test_fail_break_unless (test, !callback.failed);
+ // Let some time for slave to finish reception.
+ ucoo::delay_ms (1);
+ // Check what is received by slave (master should have read 42 from
+ // slave and send it back).
+ int r = d.poll (buf, sizeof (buf));
+ test_fail_break_unless (test, r == buffer_size);
+ test_fail_break_unless (test, std::count (buf, buf + r, 42) == r);
+ } while (0);
}
int