ref: 64d934dd3248b39915c703630a07396885604a36
parent: db1281e257bbe741e3e678b7e5c63c301d4b1696
author: glenda <glenda>
date: Wed Oct 1 21:50:26 EDT 2025
lsm303dlhc i²c chip
--- /dev/null
+++ b/lsm303dlhc.c
@@ -1,0 +1,243 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+#define DATA "%s/i2c.%x.data"
+#define CTL "%s/i2c.%x.ctl"
+
+char *i2cdir = "/dev/i2c1";
+
+enum {+ AccelAddr= 0x19,
+ CtrlReg1= 0x20,
+ CtrlReg2= 0x21,
+ CtrlReg3= 0x22,
+ CtrlReg4= 0x23,
+ CtrlReg5= 0x24,
+ CtrlReg6= 0x25,
+ FifoCtrlReg= 0x2E,
+ StatusReg= 0x27,
+ Int1Cfg= 0x30,
+ Int2Cfg= 0x34,
+ AccelXHigh= 0x29,
+ AccelXLow= 0x28,
+ AccelYHigh= 0x2B,
+ AccelYLow= 0x2A,
+ AccelZHigh= 0x2D,
+ AccelZLow= 0x2C,
+ MagnetAddr= 0x1e,
+ CraReg= 0x00,
+ CrbReg= 0x01,
+ MrReg= 0x02,
+ IraReg= 0x0A,
+ IrbReg= 0x0B,
+ IrcReg= 0x0C,
+ MagnetXHigh= 0x03,
+ MagnetXLow= 0x04,
+ MagnetYHigh= 0x05,
+ MagnetYLow= 0x06,
+ MagnetZHigh= 0x07,
+ MagnetZLow= 0x08,
+ TempHigh= 0x31,
+ TempLow= 0x32,
+ Ok= 0x00,
+ Err= 0xFF,
+};
+
+void
+ewrite(char *fname, char *buf, int n)
+{+ int fd;
+
+ fd = open(fname, OWRITE);
+ if (fd == -1)
+ sysfatal("open: %r");+
+ if (write(fd, buf, n) != n)
+ sysfatal("write: %r");+
+ close(fd);
+}
+
+void
+eread(char *fname, char *reg, int r, char *buf, int n)
+{+ int fd;
+
+ fd = open(fname, ORDWR);
+ if (fd == -1)
+ sysfatal("open: %r");+
+ if (write(fd, reg, r) != r)
+ sysfatal("write: %r");+
+ if (read(fd, buf, n) != n)
+ sysfatal("read: %r");+
+ close(fd);
+}
+
+void
+fsread(Req *r)
+{+ char *data;
+ char reg[1];
+ char out[1];
+ short x, y, z;
+
+ switch ((intptr)(r->fid->file->aux)) {+ case 1:
+ data = smprint(DATA, i2cdir, AccelAddr);
+ if (data == nil)
+ sysfatal("smprint: %r");+
+ reg[0] = AccelXHigh;
+ eread(data, reg, 1, out, 1);
+ x = out[0] << 8;
+ reg[0] = AccelXLow;
+ eread(data, reg, 1, out, 1);
+ x |= out[0];
+
+ reg[0] = AccelYHigh;
+ eread(data, reg, 1, out, 1);
+ y = out[0] << 8;
+ reg[0] = AccelYLow;
+ eread(data, reg, 1, out, 1);
+ y |= out[0];
+
+ reg[0] = AccelZHigh;
+ eread(data, reg, 1, out, 1);
+ z = out[0] << 8;
+ reg[0] = AccelZLow;
+ eread(data, reg, 1, out, 1);
+ z |= out[0];
+
+ free(data);
+
+ data = smprint("%11d %11d %11d\n", x, y, z);+ if (data == nil)
+ sysfatal("smprint: %r");+
+ readstr(r, data);
+ respond(r, nil);
+
+ free(data);
+ break;
+ case 2:
+ data = smprint(DATA, i2cdir, MagnetAddr);
+ if (data == nil)
+ sysfatal("smprint: %r");+
+ reg[0] = MagnetXHigh;
+ eread(data, reg, 1, out, 1);
+ x = out[0] << 8;
+ reg[0] = MagnetXLow;
+ eread(data, reg, 1, out, 1);
+ x |= out[0];
+
+ reg[0] = MagnetYHigh;
+ eread(data, reg, 1, out, 1);
+ y = out[0] << 8;
+ reg[0] = MagnetYLow;
+ eread(data, reg, 1, out, 1);
+ y |= out[0];
+
+ reg[0] = MagnetZHigh;
+ eread(data, reg, 1, out, 1);
+ z = out[0] << 8;
+ reg[0] = MagnetZLow;
+ eread(data, reg, 1, out, 1);
+ z |= out[0];
+
+ free(data);
+
+ data = smprint("%11d %11d %11d\n", x, y, z);+ if (data == nil)
+ sysfatal("smprint: %r");+
+ readstr(r, data);
+ respond(r, nil);
+
+ free(data);
+ break;
+ default:
+ respond(r, "error");
+ break;
+ }
+}
+
+Srv fs = {+.read = fsread,
+};
+
+void
+init(void)
+{+ char *data;
+ char buf[2];
+
+ data = smprint(DATA, i2cdir, AccelAddr);
+ if (data == nil)
+ sysfatal("smprint: %r");+
+ buf[0] = CtrlReg1;
+ buf[1] = 0x27;
+ ewrite(data, buf, 2);
+
+ buf[0] = CtrlReg4;
+ buf[1] = 0x40;
+ ewrite(data, buf, 2);
+
+ buf[0] = CtrlReg5;
+ buf[1] = 0x40;
+ ewrite(data, buf, 2);
+
+ buf[0] = FifoCtrlReg;
+ buf[1] = 0x80;
+ ewrite(data, buf, 2);
+
+ free(data);
+
+ data = smprint(DATA, i2cdir, MagnetAddr);
+ if (data == nil)
+ sysfatal("smprint: %r");+
+ buf[0] = CraReg;
+ buf[1] = 0x9C;
+ ewrite(data, buf, 2);
+
+ buf[0] = CrbReg;
+ buf[1] = 0x20;
+ ewrite(data, buf, 2);
+
+ buf[0] = MrReg;
+ buf[1] = 0x00;
+ ewrite(data, buf, 2);
+
+ buf[0] = IraReg;
+ buf[1] = 0x48;
+ ewrite(data, buf, 2);
+
+ buf[0] = IrbReg;
+ buf[1] = 0x34;
+ ewrite(data, buf, 2);
+
+ buf[0] = IrcReg;
+ buf[1] = 0x33;
+ ewrite(data, buf, 2);
+
+ free(data);
+}
+
+void
+main()
+{+ init();
+
+ fs.tree = alloctree("lsm303dlhc", "lsm303dlhc", DMDIR|0555, nil);+ createfile(fs.tree->root, "accel", "lsm303dlhc", 0444, (void*)1);
+ createfile(fs.tree->root, "compass", "lsm303dlhc", 0444, (void*)2);
+ postmountsrv(&fs, "lsm303dlhc", "/dev", MBEFORE);
+}
--
⑨