shithub: util

ref: 284d1ce2d7f4992ef2edee3eaaeeecca70e535cd
dir: /lsm303dlhc.c/

View raw version
#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);
}