diff options
| author | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
|---|---|---|
| committer | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
| commit | 78ee7d5717807e6ac779293d0d3c78341de6130a (patch) | |
| tree | a43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/mpc/devtouch.c | |
| parent | bdaf46cf45bbb59261da245d548a179d95a42768 (diff) | |
Move existing boards into subdits split per arch
Diffstat (limited to 'os/mpc/devtouch.c')
| -rw-r--r-- | os/mpc/devtouch.c | 497 |
1 files changed, 0 insertions, 497 deletions
diff --git a/os/mpc/devtouch.c b/os/mpc/devtouch.c deleted file mode 100644 index b11aecc8..00000000 --- a/os/mpc/devtouch.c +++ /dev/null @@ -1,497 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#define DPRINT if(0)print -#define THREEBUT 0 /* !=0, enable 3-button emulation (see below) */ - -/* - * DynaPro touch panel and Maxim MAX192 A/D converter on - * York Electronics Centre's BRD/98/024 (Version A) interface, - * accessed via mpc8xx SPI interface (see spi.c). - * - * The highest level of the driver is derived from the ARM/UCB touch panel driver, - * simplified because of the differences between the panels. - */ - -/* - * Values determined by interface board - */ -enum { - /* MAX192 control words */ - MeasureX = (1<<7)|(0<<6)|(1<<3)|(1<<2)|3, /* start, channel 0, unipolar, single-ended, external clock */ - MeasureY = (1<<7)|(1<<6)|(1<<3)|(1<<2)|3, /* start, channel 1, unipolar, single-ended, external clock */ - - /* port B bits */ - ADselect = IBIT(16), /* chip select to MAX192, active low */ - - /* port C bits */ - Xenable = 1<<2, /* PC13: TOUCH_XEN, active low */ - Yenable = 1<<3, /* PC12: TOUCH_YEN, active low */ - Touched = 1<<10, /* PC5: contact detect, active low */ - - /* interrupt control via port C */ - TouchIRQ= 2, /* parallel i/o - PC5 */ - TouchEnable= 1<<TouchIRQ, /* mask for cimr */ - - /* other parameters */ - Nconverge = 10, /* maximum iterations for convergence */ - MaxDelta = 2, /* acceptable change in X/Y between iterations */ -}; - -/* - * ADC interface via SPI (see MAX192 data sheet) - * select the ADC - * send 8-bit control word and two zero bytes to clock the conversion - * receive three data bytes - * deselect the ADC and return the result - */ -static int -getcoord(int cw) -{ - uchar tbuf[3], rbuf[3]; - IMM *io; - int nr; - - tbuf[0] = cw; - tbuf[1] = 0; - tbuf[2] = 0; - io = ioplock(); - io->pbdat &= ~ADselect; - iopunlock(); - nr = spioutin(tbuf, sizeof(tbuf), rbuf); - io = ioplock(); - io->pbdat |= ADselect; - iopunlock(); - if(nr != 3) - return -1; - return ((rbuf[1]<<8)|rbuf[2])>>5; -} - -/* - * keep reading the a/d until the value stabilises - */ -static int -dejitter(int enable, int cw) -{ - int i, diff, prev, v; - IMM *io; - - io = ioplock(); - io->pcdat &= ~enable; /* active low */ - iopunlock(); - - i = 0; - v = getcoord(cw); - do{ - prev = v; - v = getcoord(cw); - diff = v - prev; - if(diff < 0) - diff = -diff; - }while(diff >= MaxDelta && ++i <= Nconverge); - - io = ioplock(); - io->pcdat |= enable; - iopunlock(); - return v; -} - -static void -adcreset(void) -{ - IMM *io; - - /* select port pins */ - io = ioplock(); - io->pcdir &= ~(Xenable|Yenable); /* ensure set to input before changing state */ - io->pcpar &= ~(Xenable|Yenable); - io->pcdat |= Xenable|Yenable; - io->pcdir |= Xenable; /* change enable bits to output one at a time to avoid both being low at once (could damage panel) */ - io->pcdat |= Xenable; /* ensure it's high after making it an output */ - io->pcdir |= Yenable; - io->pcdat |= Yenable; /* ensure it's high after making it an output */ - io->pcso &= ~(Xenable|Yenable); - io->pbdat |= ADselect; - io->pbpar &= ~ADselect; - io->pbdir |= ADselect; - iopunlock(); -} - -/* - * high-level touch panel interface - */ - -/* to and from fixed point */ -#define FX(n) ((n)<<16) -#define XF(v) ((v)>>16) - -typedef struct Touch Touch; - -struct Touch { - Lock; - Rendez r; - int m[2][3]; /* transformation matrix */ - int rate; - int down; - int raw_count; - int valid_count; - int wake_time; - int sleep_time; -}; - -static Touch touch = { - {0}, - .r {0}, - .m {{FX(1), 0, 0},{0, FX(1), 0}}, /* default is 1:1 */ - .rate 20, /* milliseconds */ -}; - -/* - * panel-touched state and interrupt - */ - -static int -touching(void) -{ - eieio(); - return (m->iomem->pcdat & Touched) == 0; -} - -static int -ispendown(void*) -{ - return touch.down || touching(); -} - -static void -touchintr(Ureg*, void*) -{ - if((m->iomem->pcdat & Touched) == 0){ - m->iomem->cimr &= ~TouchEnable; /* mask interrupts when reading pen */ - touch.down = 1; - wakeup(&touch.r); - } -} - -static void -touchenable(void) -{ - IMM *io; - - io = ioplock(); - io->cimr |= TouchEnable; - iopunlock(); -} - -/* - * touchctl commands: - * X a b c - set X transformation - * Y d e f - set Y transformation - * s<delay> - set sample delay in millisec per sample - * r<delay> - set read delay in microsec - * R<l2nr> - set log2 of number of readings to average - */ - -enum{ - Qdir, - Qtouchctl, - Qtouchstat, - Qtouch, -}; - -Dirtab touchdir[]={ - ".", {Qdir, 0, QTDIR}, 0, 0555, - "touchctl", {Qtouchctl, 0}, 0, 0666, - "touchstat", {Qtouchstat, 0}, 0, 0444, - "touch", {Qtouch, 0}, 0, 0444, -}; - -static int -ptmap(int *m, int x, int y) -{ - return XF(m[0]*x + m[1]*y + m[2]); -} - -/* - * read a point from the touch panel; - * returns true iff the point is valid, otherwise x, y aren't changed - */ -static int -touchreadxy(int *fx, int *fy) -{ - int rx, ry; - - if(touching()){ - rx = dejitter(Xenable, MeasureX); - ry = dejitter(Yenable, MeasureY); - microdelay(40); - if(rx >=0 && ry >= 0){ - if(0) - print("touch %d %d\n", rx, ry); - *fx = ptmap(touch.m[0], rx, ry); - *fy = ptmap(touch.m[1], rx, ry); - touch.raw_count++; - return 1; - } - } - return 0; -} - -#define timer_start() 0 /* could use TBL if necessary */ -#define tmr2us(n) 0 - -static void -touchproc(void*) -{ - int b, i, x, y; - ulong t1, t2; - - t1 = timer_start(); - b = 1; - for(;;) { - //setpri(PriHi); - do{ - touch.down = 0; - touch.wake_time += (t2 = timer_start())-t1; - touchenable(); - sleep(&touch.r, ispendown, nil); - touch.sleep_time += (t1 = timer_start())-t2; - }while(!touchreadxy(&x, &y)); - - /* 640x480-specific 3-button emulation hack: */ - if(THREEBUT){ - if(y > 481) { - b = ((639-x) >> 7); - continue; - } else if(y < -2) { - b = (x >> 7)+3; - continue; - } - } - - DPRINT("#%d %d", x, y); - mousetrack(b, x, y, 0); - setpri(PriNormal); - while(touching()) { - for(i=0; i<3; i++) - if(touchreadxy(&x, &y)) { - DPRINT("*%d %d", x, y); - mousetrack(b, x, y, 0); - break; - } - touch.wake_time += (t2 = timer_start())-t1; - tsleep(&touch.r, return0, nil, touch.rate); - touch.sleep_time += (t1 = timer_start())-t2; - } - mousetrack(0, x, y, 0); - b = 1; /* go back to just button one for next press */ - } -} - -static void -touchreset(void) -{ - IMM *io; - - spireset(); - adcreset(); - intrenable(VectorCPIC+TouchIRQ, touchintr, &touch, BUSUNKNOWN, "touch"); - - /* set i/o pin to interrupt when panel touched */ - io = ioplock(); - io->pcdat &= ~Touched; - io->pcpar &= ~Touched; - io->pcdir &= ~Touched; - io->pcso &= ~Touched; - io->pcint |= Touched; /* high-to-low trigger */ - io->cimr &= ~TouchEnable; /* touchproc will enable when ready */ - iopunlock(); -} - -static void -touchinit(void) -{ - static int done; - - if(!done){ - done = 1; - kproc( "touchscreen", touchproc, nil, 0); - } -} - -static Chan* -touchattach(char* spec) -{ - return devattach('T', spec); -} - -static Walkqid* -touchwalk(Chan* c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, touchdir, nelem(touchdir), devgen); -} - -static int -touchstat(Chan* c, uchar* dp, int n) -{ - return devstat(c, dp, n, touchdir, nelem(touchdir), devgen); -} - -static Chan* -touchopen(Chan* c, int omode) -{ - omode = openmode(omode); - switch((ulong)c->qid.path){ - case Qtouchctl: - case Qtouchstat: - if(!iseve()) - error(Eperm); - break; - } - return devopen(c, omode, touchdir, nelem(touchdir), devgen); -} - -static void -touchclose(Chan*) -{ -} - -static long -touchread(Chan* c, void* buf, long n, vlong offset) -{ - char *tmp; - int x, y; - - if(c->qid.type & QTDIR) - return devdirread(c, buf, n, touchdir, nelem(touchdir), devgen); - - tmp = malloc(READSTR); - if(waserror()){ - free(tmp); - nexterror(); - } - switch((ulong)c->qid.path){ - case Qtouch: - if(!touchreadxy(&x, &y)) - x = y = -1; - snprint(tmp, READSTR, "%d %d", x, y); - break; - case Qtouchctl: - snprint(tmp, READSTR, "s%d\nr%d\nR%d\nX %d %d %d\nY %d %d %d\n", - touch.rate, 0, 1, - touch.m[0][0], touch.m[0][1], touch.m[0][2], - touch.m[1][0], touch.m[1][1], touch.m[1][2]); - break; - case Qtouchstat: - snprint(tmp, READSTR, "%d %d\n%d %d\n", - touch.raw_count, touch.valid_count, tmr2us(touch.sleep_time), tmr2us(touch.wake_time)); - touch.raw_count = 0; - touch.valid_count = 0; - touch.sleep_time = 0; - touch.wake_time = 0; - break; - default: - error(Ebadarg); - return 0; - } - n = readstr(offset, buf, n, tmp); - poperror(); - free(tmp); - return n; -} - -static void -dotouchwrite(Chan *c, char *buf) -{ - char *field[8]; - int nf, cmd, pn, m[3], n; - - nf = getfields(buf, field, nelem(field), 1, " \t\n"); - if(nf <= 0) - return; - switch((ulong)c->qid.path){ - case Qtouchctl: - cmd = *(field[0])++; - pn = *field[0] == 0; - switch(cmd) { - case 's': - n = strtol(field[pn], 0, 0); - if(n <= 0) - error(Ebadarg); - touch.rate = n; - break; - case 'r': - /* touch read delay */ - break; - case 'X': - case 'Y': - if(nf < pn+2) - error(Ebadarg); - m[0] = strtol(field[pn], 0, 0); - m[1] = strtol(field[pn+1], 0, 0); - m[2] = strtol(field[pn+2], 0, 0); - memmove(touch.m[cmd=='Y'], m, sizeof(touch.m[0])); - break; - case 'c': - case 'C': - case 'v': - case 't': - case 'e': - /* not used */ - /* break; */ - default: - error(Ebadarg); - } - break; - default: - error(Ebadarg); - return; - } -} - -static long -touchwrite(Chan* c, void* vp, long n, vlong) -{ - char buf[64]; - char *cp, *a; - int n0 = n; - int bn; - - a = vp; - while(n) { - bn = (cp = memchr(a, '\n', n))!=nil ? cp-a+1 : n; - n -= bn; - bn = bn > sizeof(buf)-1 ? sizeof(buf)-1 : bn; - memmove(buf, a, bn); - buf[bn] = '\0'; - a = cp; - dotouchwrite(c, buf); - } - return n0-n; -} - -Dev touchdevtab = { - 'T', - "touch", - - touchreset, - touchinit, - devshutdown, - touchattach, - touchwalk, - touchstat, - touchopen, - devcreate, - touchclose, - touchread, - devbread, - touchwrite, - devbwrite, - devremove, - devwstat, -}; |
