summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/io/i2c_bitbang.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib/io/i2c_bitbang.cc')
-rw-r--r--gnuradio-core/src/lib/io/i2c_bitbang.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/io/i2c_bitbang.cc b/gnuradio-core/src/lib/io/i2c_bitbang.cc
new file mode 100644
index 000000000..eb801c68f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bitbang.cc
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "i2c_bitbang.h"
+
+i2c_bitbang::i2c_bitbang (i2c_bbio_sptr io)
+{
+ d_io = io;
+ d_io->lock ();
+
+ stop (); // get bus in known state
+
+ d_io->unlock ();
+}
+
+i2c_sptr
+make_i2c_bitbang (i2c_bbio_sptr io)
+{
+ return i2c_sptr (new i2c_bitbang (io));
+}
+
+
+// start:
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 0, SDA = 0
+
+void
+i2c_bitbang::start ()
+{
+ set_sda (1);
+ set_scl (1);
+ set_sda (0); // SDA high -> low while SCL high
+ set_scl (0);
+}
+
+
+// stop:
+// entry: SCL = X, SDA = X
+// exit: SCL = 1, SDA = 1
+
+void
+i2c_bitbang::stop ()
+{
+ set_scl (0);
+ set_sda (0);
+ set_scl (1);
+ set_sda (1); // SDA low -> high while SCL high
+}
+
+
+// write_bit:
+// entry: SCL = 0, SDA = X
+// exit: SCL = 0, SDA = X
+
+void
+i2c_bitbang::write_bit (bool bit)
+{
+ set_sda (bit);
+ set_scl (1);
+ set_scl (0);
+}
+
+
+// write_byte:
+// entry: SCL = 0, SDA = X
+// exit: SCL = 0, SDA = 1
+
+bool
+i2c_bitbang::write_byte (char t)
+{
+ int i;
+ bool ack_bit;
+
+ for (i = 0; i < 8; i++){
+ write_bit (t & 0x80);
+ t <<= 1;
+ }
+
+ // clock #9. This is the ACK bit.
+
+ set_sda (1); // tristate SDA
+ set_scl (1);
+ ack_bit = get_sda (); // slave should pull SDA line low
+ set_scl (0);
+
+ return ack_bit == 0;
+}
+
+
+// write: the high level entry point...
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 1, SDA = 1
+
+bool
+i2c_bitbang::write (int addr, const unsigned char *buf, int nbytes)
+{
+ bool ok = true;
+
+ d_io->lock ();
+ start ();
+ ok = write_byte ((addr << 1) | 0); // addr plus "read opcode"
+
+ for (int i = 0; i < nbytes; i++)
+ ok &= write_byte (buf[i]);
+
+ stop ();
+ d_io->unlock ();
+ return ok;
+}
+
+
+// read: the high level entry point...
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 1, SDA = 1
+
+int
+i2c_bitbang::read (int addr, unsigned char *buf, int max_bytes)
+{
+ d_io->lock ();
+
+ // FIXME
+
+ d_io->unlock ();
+ return -1;
+}