ref: 284d1ce2d7f4992ef2edee3eaaeeecca70e535cd
parent: 7ad5e3ef8905ce04b9cdb3dca8e11732ec932ba9
author: glenda <glenda@kingship>
date: Fri Oct 17 19:26:07 EDT 2025
mcp7940x oscillator trim register
--- a/mcp7940x.c
+++ b/mcp7940x.c
@@ -20,6 +20,10 @@
Year= 6,
Nbcd= 7,
+ Control= 7,
+ CrsTrim= 1<<2,
+ OscTrim= 8,
+
/* Hours register may be in 12-hour or 24-hour mode */
Twelvehr= 0x40,
Pm= 0x20,
@@ -184,10 +188,12 @@
char buf[256];
ulong t;
char *data;
+ int sign;
+ int trim;
clk[0] = 0;
- if ((intptr)(r->fid->file->aux) == 173) {+ if ((intptr)(r->fid->file->aux) == 1) {data = smprint(DATA, i2cdir);
if (data == nil)
sysfatal("smprint: %r");@@ -220,6 +226,32 @@
snprint(buf, 256, "%12lud", t);
readstr(r, buf);
respond(r, nil);
+ } else if ((intptr)(r->fid->file->aux) == 2) {+ data = smprint(DATA, i2cdir);
+ if (data == nil)
+ sysfatal("smprint: %r");+ fd = open(data, ORDWR);
+ if (fd < 0)
+ sysfatal("open: %r");+ free(data);
+
+ clk[0] = OscTrim;
+ write(fd, clk, 1);
+ read(fd, clk, 1);
+ close(fd);
+
+ sign = 1;
+ if ((clk[0] & 0x80) == 0) {+ sign = -1;
+ }
+
+ trim = clk[0] & 0x7F;
+ trim <<= 1;
+ trim *= sign;
+
+ snprint(buf, 256, "%12d", trim);
+ readstr(r, buf);
+ respond(r, nil);
} else {respond(r, "file not found");
}
@@ -232,12 +264,15 @@
{Rtc rtc;
ulong secs;
+ int sign;
uchar bcdclock[1+Nbcd];
char *p, *ep;
int fd;
char *data;
+ long trim;
+ uchar reg[2];
- if ((intptr)(r->fid->file->aux) == 173) {+ if ((intptr)(r->fid->file->aux) == 1) {p = r->ifcall.data;
ep = p + r->ifcall.count;
@@ -273,6 +308,45 @@
close(fd);
respond(r, nil);
+ } else if ((intptr)(r->fid->file->aux) == 2) {+ p = r->ifcall.data;
+ ep = p + r->ifcall.count;
+
+ sign = 1;
+ while(p < ep) {+ if (*p == '-')
+ sign = -1;
+ else if (*p >= '0' && *p <= '9')
+ break;
+ p++;
+ }
+
+ trim = strtol(p, 0, 0);
+ if (trim < 0 || trim > 254) {+ respond(r, "invalid trim value");
+ return;
+ }
+
+ trim >>= 1;
+
+ reg[0] = OscTrim;
+ reg[1] = 0;
+ if (sign == 1)
+ reg[1] = 0x80;
+ reg[1] |= (uchar)trim;
+
+ data = smprint(DATA, i2cdir);
+ if (data == nil)
+ sysfatal("smprint: %r");+ fd = open(data, ORDWR);
+ if (fd < 0)
+ sysfatal("open: %r");+ free(data);
+
+ if (write(fd, reg, 2) != 2)
+ sysfatal("write: %r");+
+ close(fd);
} else {respond(r, "file not found");
}
@@ -286,10 +360,35 @@
void
main()
{+ char *data;
+ int fd;
+ uchar reg;
+ uchar buf[2];
+
ctl("size 10"); ctl("subaddress 0");+ data = smprint(DATA, i2cdir);
+ if (data == nil)
+ sysfatal("smprint: %r");+ fd = open(data, ORDWR);
+ if (fd < 0)
+ sysfatal("open: %r");+ free(data);
+ reg = Control;
+ if (write(fd, ®, 1) != 1)
+ sysfatal("write: %r");+ if (read(fd, ®, 1) != 1)
+ sysfatal("read: %r");+ reg |= CrsTrim;
+ buf[0] = Control;
+ buf[1] = reg;
+ if (write(fd, buf, 2) != 2)
+ sysfatal("write: %r");+ close(fd);
+
fs.tree = alloctree("mcp7940x", "mcp7940x", DMDIR|0555, nil);- createfile(fs.tree->root, "rtc", "mcp7940x", 0666, (void*)173);
+ createfile(fs.tree->root, "rtc", "mcp7940x", 0666, (void*)1);
+ createfile(fs.tree->root, "rtctrim", "mcp7940x", 0666, (void*)2);
postmountsrv(&fs, "mcp7940x", "/dev", MBEFORE);
}
--
⑨