aboutsummaryrefslogtreecommitdiff
path: root/src/i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i2c.c')
-rw-r--r--src/i2c.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/i2c.c b/src/i2c.c
new file mode 100644
index 0000000..cca68c6
--- /dev/null
+++ b/src/i2c.c
@@ -0,0 +1,103 @@
+#include <i2c.h>
+#include <hardware.h>
+
+#define SDA (1 << 0)
+#define SCL (1 << 1)
+
+void
+_delay_ms(uint8_t ms);
+
+void
+i2c_start_condition(void)
+{
+ port_a_data &= ~SDA;
+ _delay_ms(1);
+ port_a_data &= ~SCL;
+ _delay_ms(1);
+}
+
+void
+i2c_restart_condition(void)
+{
+ port_a_data |= SDA;
+ _delay_ms(1);
+ port_a_data |= SCL;
+ _delay_ms(1);
+ i2c_start_condition();
+}
+
+void
+i2c_stop_condition(void)
+{
+ port_a_data |= SCL;
+ _delay_ms(1);
+ port_a_data |= SDA;
+ _delay_ms(1);
+}
+
+void
+i2c_send(uint8_t b)
+{
+ uint8_t i;
+
+ for (i = 0; i < 8; ++i) {
+ if (b & 1)
+ port_a_data |= SDA;
+ else
+ port_a_data &= ~SDA;
+
+ port_a_data |= SCL;
+ _delay_ms(1);
+ port_a_data &= ~SCL;
+ _delay_ms(1);
+
+ b >>= 1;
+ }
+
+ port_a_ctrl = PIO_MODE_3;
+ port_a_ctrl = 0x7D;
+
+ // Read ack
+ port_a_data |= SCL;
+ _delay_ms(1);
+ port_a_data &= ~SCL;
+ _delay_ms(1);
+
+ port_a_ctrl = PIO_MODE_3;
+ port_a_ctrl = 0x7C;
+}
+
+uint8_t
+i2c_recv(uint8_t ack)
+{
+ uint8_t i;
+ uint8_t b = 0;
+
+ port_a_ctrl = PIO_MODE_3;
+ port_a_ctrl = 0x7D;
+
+ for (i = 0; i < 8; ++i) {
+ port_a_data |= SCL;
+ _delay_ms(1);
+ if (port_a_data & 1)
+ b |= 1;
+
+ port_a_data &= ~SCL;
+ _delay_ms(1);
+ b <<= 1;
+ }
+
+ port_a_ctrl = PIO_MODE_3;
+ port_a_ctrl = 0x7C;
+
+ if (ack)
+ port_a_data |= SDA;
+ else
+ port_a_data &= ~SDA;
+
+ port_a_data |= SCL;
+ _delay_ms(1);
+ port_a_data &= ~SCL;
+ _delay_ms(1);
+ return b;
+}