## 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<<b);
}
break;
case BLtouch:
if(len == 4)
pentrackxy((p[0]<<8)|p[1], (p[2]<<8)|p[3]);
else
pentrackxy(-1, -1);
break;
case BLled:
wakeup(&ctlr.r);
break;
case BLbattery:
if(len >= 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,
.
|