The unified diff between revisions [7ac10cd3..] and [5ddceb38..] is displayed below. It can also be downloaded as a raw diff.

This diff has been restricted to the following files: 'i2c.c'

#
# old_revision [7ac10cd34167baa43683a09e9e9e6778e691171d]
# new_revision [5ddceb38e22c73a2d7c630837716676d5ff14a38]
#
# add_file "i2c.c"
#  content [1d978ba6c211e6b68c567fa852d9cbefe8ebad13]
#
============================================================
--- /dev/null	
+++ i2c.c	1d978ba6c211e6b68c567fa852d9cbefe8ebad13
@@ -0,0 +1,120 @@
+
+#include "i2c.h"
+
+#define I2CBASE  0xE001C000
+
+#define I2CONSET 0x00
+#define I2STAT   0x04
+#define I2DAT    0x08
+#define I2ADR    0x0c
+#define I2SCLH   0x10
+#define I2SCLL   0x14
+#define I2CONCLR 0x18
+
+#define IREG(x) (((volatile unsigned char *)I2CBASE)[x])
+#define IWREG(x) (((volatile unsigned int *)I2CBASE)[(x)/sizeof(unsigned int)])
+
+#define AAFLAG (1<<2)
+#define SIFLAG (1<<3)
+#define STOFLAG (1<<4)
+#define STAFLAG (1<<5)
+
+#define SI (IREG(I2CONSET) & SIFLAG)
+
+void init_i2c(void)
+{
+	IREG(I2CONSET) = 0x40; /* Enable I2C ready for Master Tx */
+	/* Set up for just under 400kHz */
+#if 0
+	IWREG(I2SCLL) = (25 * 100);
+	IWREG(I2SCLH) = (12 * 100);
+#else
+# if 0
+	IWREG(I2SCLL) = 1475; /* ~5kHz */
+	IWREG(I2SCLH) = 1475;
+# else
+	IWREG(I2SCLL) = 73; /* ~100kHz */
+	IWREG(I2SCLH) = 73;
+# endif
+#endif
+}
+
+int i2cstat;
+
+int i2c_wait(void)
+{
+	int stat;
+	while (!SI);
+	stat = IREG(I2STAT);
+	i2cstat = stat;
+	return stat;
+}
+
+int i2c_conreg(void)
+{
+	return IREG(I2CONSET);
+}
+
+int i2c_statreg(void)
+{
+	return IREG(I2STAT);
+}
+
+bool i2c_send_start(void)
+{
+	IREG(I2CONCLR) = STOFLAG | STAFLAG;
+	IREG(I2CONSET) = STAFLAG;
+	switch (i2c_wait()) {
+	case 0x08:
+	case 0x10:
+		return TRUE;
+	default:
+		i2c_send_stop();
+		return FALSE;
+	}
+}
+
+bool i2c_send_address(int addr, bool write)
+{
+	return i2c_send_data((addr<<1) + (write?0:1));
+}
+
+bool i2c_send_data(unsigned int data)
+{
+	IREG(I2DAT) = data;
+	IREG(I2CONCLR) = STAFLAG | STOFLAG | SIFLAG;
+	switch (i2c_wait()) {
+	case 0x18:
+	case 0x28:
+	case 0x40:
+		return TRUE;
+	default:
+		i2c_send_stop();
+		return FALSE;
+	}
+}
+
+bool i2c_receive_data(unsigned int *data, bool last)
+{
+	if (!last)
+		IREG(I2CONSET) = AAFLAG;
+	IREG(I2CONCLR) = STAFLAG | STOFLAG | SIFLAG | (last?AAFLAG:0);
+	switch (i2c_wait()) {
+	case 0x50:
+	case 0x58:
+		*data = IREG(I2DAT);
+		return TRUE;
+	default:
+		i2c_send_stop();
+		return FALSE;
+	}
+}
+
+void i2c_send_stop(void)
+{
+	IREG(I2CONCLR) = STAFLAG | AAFLAG;
+	IREG(I2CONSET) = STOFLAG;
+	IREG(I2CONCLR) = SIFLAG;
+	/* Don't think we need to wait here. Could be wrong. */
+}
+