summaryrefslogtreecommitdiff
path: root/ucoo/hal/i2c/i2c_soft.cc
diff options
context:
space:
mode:
authorNicolas Schodet2016-09-19 11:36:13 +0200
committerNicolas Schodet2019-10-09 23:05:51 +0200
commiteda5cf5e3ba38eb8eb7c0c3f0110db886bae93b4 (patch)
tree2d7db1bc4da801b9be7405b54bf5a5e0103d61a1 /ucoo/hal/i2c/i2c_soft.cc
parent01585a368762caa2e5acb077f48f477339f7ed67 (diff)
ucoo/{intf, hal/i2c}: add send/recv with restart
Diffstat (limited to 'ucoo/hal/i2c/i2c_soft.cc')
-rw-r--r--ucoo/hal/i2c/i2c_soft.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/ucoo/hal/i2c/i2c_soft.cc b/ucoo/hal/i2c/i2c_soft.cc
index 130d425..ac65dff 100644
--- a/ucoo/hal/i2c/i2c_soft.cc
+++ b/ucoo/hal/i2c/i2c_soft.cc
@@ -94,6 +94,45 @@ I2cSoft::recv (uint8_t addr, char *buf, int count)
finished_handler_->finished (recv);
}
+void
+I2cSoft::send_recv (uint8_t addr, const char *send_buf, int send_count,
+ char *recv_buf, int recv_count)
+{
+ bool nack;
+ int sent = 0, recv = 0;
+ // Start.
+ send_start ();
+ // Send SLA+W.
+ nack = send_byte (addr);
+ // Send data.
+ for (; !nack && sent < send_count; sent++)
+ nack = send_byte (send_buf[sent]);
+ // Update status, there is no background task.
+ if (sent != send_count)
+ {
+ current_status_ = STATUS_ERROR;
+ if (finished_handler_)
+ finished_handler_->finished (STATUS_ERROR);
+ return;
+ }
+ // Restart.
+ send_restart ();
+ // Send SLA+R.
+ nack = send_byte (addr | 1);
+ if (!nack)
+ {
+ // Receive data, send nack in last byte.
+ for (; recv < recv_count; recv++)
+ recv_buf[recv] = recv_byte (recv == recv_count - 1 ? true : false);
+ }
+ // Stop.
+ send_stop ();
+ // Update status, there is no background task.
+ current_status_ = recv;
+ if (finished_handler_)
+ finished_handler_->finished (recv);
+}
+
int
I2cSoft::status ()
{
@@ -130,6 +169,17 @@ I2cSoft::send_start ()
}
void
+I2cSoft::send_restart ()
+{
+ sda_.input ();
+ delay ();
+ scl_.input ();
+ wait_scl ();
+ delay ();
+ send_start ();
+}
+
+void
I2cSoft::send_stop ()
{
sda_.output ();