## diffname bitsy/devµc.c 2000/1021 ## diff -e /dev/null /n/emeliedump/2000/1021/sys/src/9/bitsy/devµc.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" enum{ Qbacklight = 1, Qbattery, Qbuttons, Qled, Qversion, /* command types */ BLversion= 0, BLbuttons= 2, /* button events */ BLtouch= 3, /* read touch screen events */ BLled= 8, /* turn LED on/off */ BLbattery= 9, /* read battery status */ BLbacklight= 0xd, /* backlight control */ SOF= 0x2, /* start of frame */ /* key definitions */ Up= 0xFF0E, Left= 0xFF11, Right= 0xFF12, Down= 0x8000, }; Dirtab µcdir[]={ "backlight", { Qbacklight, 0 }, 0, 0664, "battery", { Qbattery, 0 }, 0, 0664, "buttons", { Qbuttons, 0 }, 0, 0664, "led", { Qled, 0 }, 0, 0664, "version", { Qversion, 0 }, 0, 0664, }; static struct µcontroller { /* message being rcvd */ int state; uchar buf[16+4]; uchar n; /* for messages that require acks */ QLock; Rendez r; /* battery */ uchar acstatus; uchar voltage; ushort batstatus; uchar batchem; /* version string */ char version[16+2]; } ctlr; /* button map */ Rune bmap[4] = { Up, Right, Down, Left }; int µcputc(Queue*, int ch) { int i, len, b, up; uchar cksum; uchar *p; if(ctlr.n > sizeof(ctlr.buf)) panic("µcputc"); ctlr.buf[ctlr.n++] = (uchar)ch; for(;;){ /* message hasn't started yet */ if(ctlr.buf[0] != SOF){ ctlr.n = 0; break; } /* if it's too short, wait */ len = ctlr.buf[1] & 0xf; if(ctlr.n < 3 || ctlr.n < len+3) break; /* check the sum */ ctlr.buf[0] = ~SOF; cksum = 0; for(i = 1; i < len+2; i++) cksum += ctlr.buf[i]; /* ignore bad checksums */ if(ctlr.buf[len+2] != cksum){ p = memchr(ctlr.buf+1, SOF, ctlr.n); if(p == nil){ ctlr.n = 0; break; } else { ctlr.n -= p-ctlr.buf; memmove(ctlr.buf, p, ctlr.n); continue; } } /* parse resulting message */ p = ctlr.buf+2; switch(ctlr.buf[1] >> 4){ case BLversion: strncpy(ctlr.version, (char*)p, len); ctlr.version[len] = '0'; strcat(ctlr.version, "\n"); wakeup(&ctlr.r); break; case BLbuttons: if(len < 1) break; b = p[0] & 0x7f; up = p[0] & 80; if(b > 5){ /* rocker panel acts like arrow keys */ if(b < 10) kbdputc(kbdq, bmap[b-6]); } else { /* the rest like mouse buttons */ if(--b == 0) b = 5; penbutton(up, 1<= 5){ ctlr.acstatus = p[0]; ctlr.voltage = (p[3]<<8)|p[2]; ctlr.batstatus = p[4]; ctlr.batchem = p[1]; } wakeup(&ctlr.r); break; case BLbacklight: wakeup(&ctlr.r); break; } /* remove the message */ ctlr.n -= len+3; memmove(ctlr.buf, &ctlr.buf[len+3], ctlr.n); } return 0; } static void _sendmsg(uchar id, uchar *data, int len) { uchar buf[20]; uchar cksum; uchar c; uchar *p = buf; int i; /* create the message */ if(sizeof(buf) < len+4) return; cksum = (id<<4) | len; *p++ = SOF; *p++ = cksum; for(i = 0; i < len; i++){ c = data[i]; cksum += c; *p++ = c; } *p++ = cksum; /* send the message - there should be a more generic way to do this */ serialµcputs(buf, p-buf); } static void sendmsgwithack(uchar id, uchar *data, int len) { if(waserror()){ qunlock(&ctlr); nexterror(); } qlock(&ctlr); _sendmsg(id, data, len); tsleep(&ctlr.r, return0, 0, 100); qunlock(&ctlr); poperror(); } static void sendmsg(uchar id, uchar *data, int len) { if(waserror()){ qunlock(&ctlr); nexterror(); } qlock(&ctlr); _sendmsg(id, data, len); qunlock(&ctlr); poperror(); } void µcinit(void) { } static Chan* µcattach(char* spec) { return devattach('r', spec); } static int µcwalk(Chan* c, char* name) { return devwalk(c, name, µcdir, nelem(µcdir), devgen); } static void µcstat(Chan* c, char* dp) { devstat(c, dp, µcdir, nelem(µcdir), devgen); } static Chan* µcopen(Chan* c, int omode) { omode = openmode(omode); if(strcmp(up->user, eve)!=0) error(Eperm); return devopen(c, omode, µcdir, nelem(µcdir), devgen); } static void µcclose(Chan*) { } char* acstatus(int x) { if(x) return "attached"; else return "detached"; } char* batstatus(int x) { switch(x){ case 1: return "high"; case 2: return "low"; case 4: return "critical"; case 8: return "charging"; case 0x80: return "none"; } return "ok"; } static long µcread(Chan* c, void* a, long n, vlong off) { char buf[64]; if(c->qid.path & CHDIR) return devdirread(c, a, n, µcdir, nelem(µcdir), devgen); switch(c->qid.path){ case Qbattery: sendmsgwithack(BLbattery, nil, 0); /* send a battery request */ sprint(buf, "voltage: %d\nac: %s\nstatus: %s\n", ctlr.voltage, acstatus(ctlr.acstatus), batstatus(ctlr.batstatus)); return readstr(off, a, n, buf); case Qversion: sendmsgwithack(BLversion, nil, 0); /* send a battery request */ return readstr(off, a, n, ctlr.version); } error(Ebadarg); return 0; } #define PUTBCD(n,o) bcdclock[o] = (n % 10) | (((n / 10) % 10)<<4) static long µcwrite(Chan* c, void* a, long n, vlong off) { Cmdbuf *cmd; uchar data[16]; int i; if(off != 0) error(Ebadarg); cmd = parsecmd(a, n); if(cmd->nf > 15) error(Ebadarg); for(i = 0; i < cmd->nf; i++) data[i] = atoi(cmd->f[i]); switch(c->qid.path){ case Qled: sendmsgwithack(BLled, data, cmd->nf); break; case Qbacklight: sendmsgwithack(BLbacklight, data, cmd->nf); break; default: error(Ebadarg); } return n; } Dev µcdevtab = { 'r', "µc", devreset, µcinit, µcattach, devclone, µcwalk, µcstat, µcopen, devcreate, µcclose, µcread, devbread, µcwrite, devbwrite, devremove, devwstat, }; . ## diffname bitsy/devµc.c 2000/1022 ## diff -e /n/emeliedump/2000/1021/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1022/sys/src/9/bitsy/devµc.c 192a /* the tsleep takes care of lost acks */ . 98,110d 96a if(ctlr.buf[len+2] != cksum) continue; . 93c ctlr.buf[0] = ~SOF; /* make sure we process this msg exactly once */ . 87c /* whole msg? */ . 83,84c p = memchr(ctlr.buf, SOF, ctlr.n); if(p == nil){ ctlr.n = 0; break; } else { ctlr.n -= p-ctlr.buf; memmove(ctlr.buf, p, ctlr.n); } . 81c /* message hasn't started yet? */ . ## diffname bitsy/devµc.c 2000/1024 ## diff -e /n/emeliedump/2000/1022/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1024/sys/src/9/bitsy/devµc.c 121c if(b > 5) { . ## diffname bitsy/devµc.c 2000/1028 ## diff -e /n/emeliedump/2000/1024/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1028/sys/src/9/bitsy/devµc.c 119,120c up = p[0] & 0x80; . ## diffname bitsy/devµc.c 2000/1031 ## diff -e /n/emeliedump/2000/1028/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1031/sys/src/9/bitsy/devµc.c 316a case Qkbdin: if(n >= sizeof(str)) n = sizeof(str)-1; memmove(str, a, n); str[n] = 0; for(i = 0; i < n; i += j){ j = chartorune(&r, &str[i]); kbdputc(nil, r); } break; . 305c char str[64]; int i, j; Rune r; . 136a } . 133,135c if(len == 4) { if (samseq++ > 10) pentrackxy((p[0]<<8)|p[1], (p[2]<<8)|p[3]); } else { samseq = 0; . 73a static int samseq; . 36a "kbdin", { Qkbdin, 0 }, 0, 0664, . 12a Qkbdin, . ## diffname bitsy/devµc.c 2000/1101 ## diff -e /n/emeliedump/2000/1031/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1101/sys/src/9/bitsy/devµc.c 325,334d 315,316c if(c->qid.path == Qkbdin){ if(n >= sizeof(str)) n = sizeof(str)-1; memmove(str, a, n); str[n] = 0; for(i = 0; i < n; i += j){ j = chartorune(&r, &str[i]); kbdcr2nl(nil, r); } return n; } . ## diffname bitsy/devµc.c 2000/1102 ## diff -e /n/emeliedump/2000/1101/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1102/sys/src/9/bitsy/devµc.c 158a default: print("unknown µc message: %ux"); for(i = 0; i < len; i++) print(" %ux", p[i]); print("\n"); break; . ## diffname bitsy/devµc.c 2000/1103 ## diff -e /n/emeliedump/2000/1102/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1103/sys/src/9/bitsy/devµc.c 344a break; case Qcruft: lcdtweak(cmd); . 313c µcwrite(Chan* c, void* a, long n, vlong) . 160c print("unknown µc message: %ux", ctlr.buf[1] >> 4); . 37a "cruft", { Qcruft, 0 }, 0, 0664, . 12a Qcruft, . ## diffname bitsy/devµc.c 2000/1104 ## diff -e /n/emeliedump/2000/1103/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1104/sys/src/9/bitsy/devµc.c 140c pentrackxy((p[2]<<8)|p[3], (p[0]<<8)|p[1]); . ## diffname bitsy/devµc.c 2000/1106 ## diff -e /n/emeliedump/2000/1104/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1106/sys/src/9/bitsy/devµc.c 349c // lcdtweak(cmd); . ## diffname bitsy/devµc.c 2000/1207 ## diff -e /n/emeliedump/2000/1106/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1207/sys/src/9/bitsy/devµc.c 144a touching = 0; . 137a if(touching) break; touching = 1; . 135a buttoning = 0; . 122a buttoning = 1; . 121c if(len < 1 || buttoning) . 78a static int touching; /* guard against something we call going spllo() */ static int buttoning; /* guard against something we call going spllo() */ . 69c Kup, Kright, Kdown, Kleft . 28,32c /* from /sys/include/keyboard.h */ enum { KF= 0xF000, /* Rune: beginning of private Unicode space */ /* KF|1, KF|2, ..., KF|0xC is F1, F2, ..., F12 */ Khome= KF|0x0D, Kup= KF|0x0E, Kpgup= KF|0x0F, Kprint= KF|0x10, Kleft= KF|0x11, Kright= KF|0x12, Kdown= 0x80, Kview= 0x80, Kpgdown= KF|0x13, Kins= KF|0x14, Kend= '\r', /* [sic] */ Kalt= KF|0x15, Kshift= KF|0x16, Kctl= KF|0x17, . 26a }; . ## diffname bitsy/devµc.c 2000/1212 ## diff -e /n/emeliedump/2000/1207/sys/src/9/bitsy/devµc.c /n/emeliedump/2000/1212/sys/src/9/bitsy/devµc.c 146c if(b < 10 && !up) . 84c Kup, Kright, Kleft, Kdown . ## diffname bitsy/devµc.c 2001/0529 ## diff -e /n/emeliedump/2000/1212/sys/src/9/bitsy/devµc.c /n/emeliedump/2001/0529/sys/src/9/bitsy/devµc.c 387d 364c switch((ulong)c->qid.path){ . 320c switch((ulong)c->qid.path){ . 317c if(c->qid.path == Qdir) . 273c return devstat(c, dp, n, µcdir, nelem(µcdir), devgen); . 270,271c static int µcstat(Chan *c, uchar *dp, int n) . 267c return devwalk(c, nc, name, nname, µcdir, nelem(µcdir), devgen); . 264,265c static Walkqid* µcwalk(Chan *c, Chan *nc, char **name, int nname) . 63c int state; . 52,57c "battery", { Qbattery, 0 }, 0, 0664, "buttons", { Qbuttons, 0 }, 0, 0664, "cruft", { Qcruft, 0 }, 0, 0664, "kbdin", { Qkbdin, 0 }, 0, 0664, "led", { Qled, 0 }, 0, 0664, "version", { Qversion, 0 }, 0, 0664, . 50a ".", { Qdir, 0, QTDIR }, 0, DMDIR|0755, . 10c Qdir, Qbacklight, . ## diffname bitsy/devµc.c 2001/0605 ## diff -e /n/emeliedump/2001/0529/sys/src/9/bitsy/devµc.c /n/emeliedump/2001/0605/sys/src/9/bitsy/devµc.c 22c BLtouch= 3, /* read touch screen events */ . ## diffname bitsy/devµc.c 2001/0606 ## diff -e /n/emeliedump/2001/0605/sys/src/9/bitsy/devµc.c /n/emeliedump/2001/0606/sys/src/9/bitsy/devµc.c 103c . 96,97c static int touching; /* guard against something we call going spllo() */ static int buttoning; /* guard against something we call going spllo() */ . ## diffname bitsy/devµc.c 2001/0618 ## diff -e /n/emeliedump/2001/0606/sys/src/9/bitsy/devµc.c /n/emeliedump/2001/0618/sys/src/9/bitsy/devµc.c 381a void µcpower(int on) { uchar data[16]; if (on == 0) return; /* maybe dangerous, not holding the lock */ data[0]= 2; data[1]= 1; data[2]= 0x80; _sendmsg(0xd, data, 3); wakeup(&ctlr.r); } . ## diffname bitsy/devµc.c 2001/0621 ## diff -e /n/emeliedump/2001/0618/sys/src/9/bitsy/devµc.c /n/emeliedump/2001/0621/sys/src/9/bitsy/devµc.c 357a } if(c->qid.path == Qsuspend){ if(!iseve()) error(Eperm); if(strncmp(a, "suspend", 7) != 0) error(Ebadarg); powerflag = 1; wakeup(&powerr); . 346a extern Rendez powerr; extern ulong powerflag; . 59a "suspend", { Qsuspend, 0 }, 0, 0222, . 17a Qsuspend, . ## diffname bitsy/devµc.c 2001/1130 ## diff -e /n/emeliedump/2001/0621/sys/src/9/bitsy/devµc.c /n/emeliedump/2001/1130/sys/src/9/bitsy/devµc.c 165,166c if (samseq++ > 10){ if (landscape) pentrackxy((p[0]<<8)|p[1], (p[2]<<8)|p[3]); else pentrackxy((p[2]<<8)|p[3], (p[0]<<8)|p[1]); } . 90a extern int landscape; . ## diffname bitsy/devµc.c 2002/0109 ## diff -e /n/emeliedump/2001/1130/sys/src/9/bitsy/devµc.c /n/emeliedump/2002/0109/sys/src/9/bitsy/devµc.c 419a devshutdown, . ## diffname bitsy/devµc.c 2002/0119 ## diff -e /n/emeliedump/2002/0109/sys/src/9/bitsy/devµc.c /n/emeliedump/2002/0119/sys/src/9/bitsy/devµc.c 153c kbdputc(kbdq, bmap[landscape][b-6]); . 88c {Kup, Kright, Kleft, Kdown}, /* portrait mode */ {Kright, Kdown, Kup, Kleft}, /* landscape mode */ . 86c Rune bmap[2][4] = . ## diffname bitsy/devµc.c 2002/0604 ## diff -e /n/emeliedump/2002/0119/sys/src/9/bitsy/devµc.c /n/emeliedump/2002/0604/sys/src/9/bitsy/devµc.c 375,376c deepsleep(); return n; . 373c if(strncmp(a, "suspend", 7) == 0) *resumeaddr = (ulong)power_resume; else if(strncmp(a, "halt", 4) == 0) *resumeaddr = 0; else . 370c if(c->qid.path == Qpower){ . 356,357c extern ulong resumeaddr[]; extern void power_resume(void); . 61c "power", { Qpower, 0 }, 0, 0600, . 18c Qpower, . ## diffname bitsy/devµc.c 2002/1112 ## diff -e /n/emeliedump/2002/0604/sys/src/9/bitsy/devµc.c /n/emeliedump/2002/1112/sys/src/9/bitsy/devµc.c 412,414c if (lightdata[0] == 0){ data[0]= 2; data[1]= 1; data[2]= 0; } else memmove(data, lightdata, 16); . 393a memmove(lightdata, data, 16); . 377c else if(strncmp(a, "wakeup", 6) == 0){ cmd = parsecmd(a, n); if (cmd->nf != 2) error(Ebadarg); l = strtoul(cmd->f[1], 0, 0); rtcalarm(l); return n; } else . 354a ulong l; . 347a static uchar lightdata[16]; . 59c "led", { Qled, 0 }, 0, 0664, . 54c "backlight", { Qbacklight, 0 }, 0, 0664, .