summaryrefslogtreecommitdiffstats
path: root/app/not/i2c_bb.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/not/i2c_bb.c')
-rw-r--r--app/not/i2c_bb.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/app/not/i2c_bb.c b/app/not/i2c_bb.c
new file mode 100644
index 0000000..3076605
--- /dev/null
+++ b/app/not/i2c_bb.c
@@ -0,0 +1,164 @@
+#include "project.h"
+
+#define SCL GPIO6
+#define SDA GPIO7
+
+static uint8_t
+set (uint8_t sda, uint8_t scl)
+{
+ uint8_t ret;
+ if (sda)
+ gpio_set (GPIOB, SDA);
+ else
+ gpio_clear (GPIOB, SDA);
+
+ if (scl)
+ gpio_set (GPIOB, SCL);
+ else
+ gpio_clear (GPIOB, SCL);
+
+ delay_us (10);
+ ret = (gpio_get (GPIOB, SDA) & SDA) ? 1 : 0;
+
+ return ret;
+}
+
+
+
+
+uint8_t
+i2cb_send (uint8_t wot)
+{
+ uint8_t i;
+
+ printf ("%02x", wot);
+
+ for (i = 0; i < 8; ++i)
+ {
+ set (wot & 0x80, 0);
+ set (wot & 0x80, 1);
+ set (wot & 0x80, 0);
+ wot <<= 1;
+ }
+ set (1, 0);
+ i = set (1, 1);
+ set (1, 0);
+
+ printf ("%c", i ? '!' : '.');
+ return i;
+}
+
+uint8_t
+i2cb_send_addr (uint8_t addr, uint8_t rnw)
+{
+ return i2cb_send (addr << 1 | rnw);
+}
+
+uint8_t
+i2cb_read (uint8_t ack)
+{
+ uint8_t i, wot = 0;
+
+ for (i = 0; i < 8; ++i)
+ {
+ wot <<= 1;
+ set (1, 0);
+ wot |= set (1, 1);
+ set (1, 0);
+ }
+ set (ack, 0);
+ set (ack, 1);
+ set (ack, 0);
+ return wot;
+}
+
+
+void
+i2cb_start (void)
+{
+ printf ("S");
+ set (1, 1);
+ set (0, 1);
+ set (0, 0);
+}
+
+void
+i2cb_stop (void)
+{
+ printf ("R\n");
+ set (0, 0);
+ set (0, 1);
+ set (1, 1);
+}
+
+
+int
+i2cb_start_transaction (uint8_t a, uint8_t rnw)
+{
+ i2cb_start ();
+ return i2cb_send_addr (a, rnw);
+
+}
+
+
+void
+i2cb_reset (void)
+{
+ i2cb_start ();
+ i2cb_stop ();
+ i2cb_start ();
+ i2cb_stop ();
+}
+
+
+
+void
+i2cb_scan (void)
+{
+ uint8_t r;
+ uint16_t i;
+
+ i2cb_reset ();
+
+ printf ("Probing bus\n");
+ for (i = 0; i < 128; ++i)
+ {
+ i2cb_start ();
+ i2cb_stop ();
+ i2cb_start ();
+ r = i2cb_send ((i << 1) | I2C_WRITE);
+ i2cb_stop ();
+
+ if (!r)
+ printf ("Found device at address 0x%x\n", i);
+ }
+ printf ("Done\n");
+ i2cb_reset ();
+
+}
+
+void
+i2cb_init (void)
+{
+ gpio_set_mode (GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
+ SCL);
+ gpio_set_mode (GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN,
+ SDA);
+
+ set (1, 1);
+#ifdef DEBUG_I2C
+ printf ("T11 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
+#endif
+ set (0, 1);
+#ifdef DEBUG_I2C
+ printf ("T01 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
+#endif
+ set (1, 0);
+#ifdef DEBUG_I2C
+ printf ("T10 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
+#endif
+ set (1, 1);
+#ifdef DEBUG_I2C
+ printf ("T11 %d:%d\n", !!(SDA_IN_REG & SDA_VAL), !!(SCL_IN_REG & SCL_VAL));
+#endif
+}