gonzui


Format: Advanced Search

tkernel_2/driver/tef_em1d/lowkbpd/src/common.cbare sourcepermlink (0.04 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by T-Engine Forum at 2014/09/10.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: 
   16: /*
   17:         common.c        KB/PD real I/O drvier common part
   18:  *
   19:  */
   20: #include        "kbpd.h"
   21: #include        "scancode.h"
   22: 
   23: /*
   24:         event buffer
   25: */
   26: #define MAXRAWEVT       32
   27: LOCAL   RawEvt    evtbuf[MAXRAWEVT + 1];             /* the last entry is reserved */
   28: LOCAL   W evtbuf_init = 0;
   29: 
   30: /*
   31:         PD scaling data
   32: */
   33: #define RATIO_ONE       (24)
   34: #define ACC_RATE        (3)
   35: #define PDMOV_XMAX      512 /*640*/
   36: LOCAL   UB        sensetbl[] =
   37:         {6, 8, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168};
   38: LOCAL   UB        threshold[] = {0, 3, 7, 11, 15, 23, 39, 63};
   39: 
   40: /*
   41:         scan code conversion table when NumLock is OFF
   42: */
   43: LOCAL   UB        numtbl[] = {
   44:   /* 47-4A */   T_7,      T_8, T_9,    0x4a,      /* 7  8  9  -        */
   45:   /* 4B-4E */   T_4,      T_5, T_6,    0x4e,      /* 4  5  6  +        */
   46:   /* 4F-51 */   T_1,      T_2, T_3,            /* 1  2  3        */
   47:   /* 52-53 */   T_0,      T_PERIOD             /* 0  .            */
   48: };
   49: 
   50: /*
   51:         memory allocation / release
   52: */
   53: EXPORT  void*    MemAlloc(W size)
   54: {
   55: static  W        blksz = 0;
   56:         T_RSMB msts;
   57:         void*  ptr;
   58: 
   59:         if (blksz == 0) {
   60:                 if (tk_ref_smb(&msts) < E_OK) return NULL;
   61:                 blksz = msts.blksz;
   62:         }
   63:         if (tk_get_smb(&ptr, (size + blksz - 1) / blksz,
   64:                                 TA_RNG0) >= E_OK) return ptr;
   65:         return NULL;
   66: }
   67: EXPORT  void     MemFree(void *ptr)
   68: {
   69:         tk_rel_smb(ptr);
   70: }
   71: /*
   72:         event notification to upper KB/PD driver
   73: */
   74: EXPORT  ER       kpSendMsg(RawEvt *msg)
   75: {
   76:         ER     er;
   77:         W      i;
   78: 
   79:         if (evtbuf_init == 0) {        /* initialization */
   80:                 MEMSET(evtbuf, 0, sizeof(evtbuf));
   81:                 for (i = 0; i < MAXRAWEVT + 1; i++) evtbuf[i].p.stat.read = 1;
   82:                 evtbuf_init++;
   83:         }
   84: 
   85:         /* look for message buffer free space: the last one is reserved. */
   86:         for (i = 0; i < MAXRAWEVT && evtbuf[i].p.stat.read == 0; i++);
   87: 
   88:         /* if we can not even use the reserved slot in event buffer, then error */
   89:         if (i == MAXRAWEVT && evtbuf[i].p.stat.read == 0) {
   90:                 DP(("kpSendMsg: evtbuf overflow\n"));
   91:                 er = E_TMOUT;
   92:                 goto fin0;
   93:         }              
   94: 
   95:         /* set up event */
   96:         evtbuf[i] = *msg;
   97: 
   98:         /* set OVRRUN if we use the reserved slot */
   99:         if (i == MAXRAWEVT) {
  100:                 DP(("kpSendMsg: DEV_OVRRUN\n"));
  101:                 evtbuf[i].p.stat.err = DEV_OVRRUN;
  102:         }
  103: 
  104:         /* send event */
  105:         er = tk_snd_mbx(EvtMbx, (T_MSG*)&evtbuf[i]);
  106:         if (er < E_OK) {
  107:                 evtbuf[i].p.stat.read = 1;
  108:                 DP(("kpSendMsg: err=%#x\n", er));
  109:         }
  110:  fin0:
  111:         return er;
  112: }
  113: /*
  114:         Scaling based on PD sensitivity (for relative coordinate device)
  115: */
  116: EXPORT  void     kpScalingPos(RawEvt *evt, W x, W y, PNT *fract, W x_max)
  117: {
  118:         W      acc, sns, ax, ay, max_xy;
  119:         W      ratio, bias;
  120:         W      base = RATIO_ONE;
  121: 
  122:         sns = PdSense & PD_SNMSK;
  123:         acc = (PdSense & PD_ACMSK) >> 9;
  124: 
  125:         /* process acceleration */
  126:         if (acc != 0) {
  127:                 if ((ax = x) < 0) ax = - ax;
  128:                 if ((ay = y) < 0) ay = - ay;
  129:                 if ((max_xy = ax) < ay) max_xy = ay;
  130:                 if (max_xy > (bias = threshold[acc])) {
  131:                         bias *= (ACC_RATE - 1);
  132:                         ax = ax * ACC_RATE - (bias * ax / max_xy);
  133:                         ay = ay * ACC_RATE - (bias * ay / max_xy);
  134:                         x = (x < 0) ? (- ax) : (ax);
  135:                         y = (y < 0) ? (- ay) : (ay);
  136:                 }
  137:                 /* adjust magnification based on sensitivity */
  138:                 base += sns;
  139:         }
  140: 
  141:         /* magnification based on sensitivity : ratio / base */
  142:         ratio = sensetbl[sns];
  143: 
  144:         if (x_max > 0) {
  145:                 /* for tablet, the maximum movement along X-axis is PDMOV_XMAX
  146:                    and the sensitivity is adjusted to keep the maximum value to the above value. */
  147:                 ratio *= PDMOV_XMAX / base;
  148:                 base = x_max;
  149:         }
  150:         /* instead of correcting the residue accurately, if the residue is below 1,
  151:                         we accumulate the residue, then we achieve better behavior */
  152:         x = x * ratio + fract->x;
  153:         evt->p.xpos = x / base;
  154:         fract->x = (evt->p.xpos == 0) ? x : 0;
  155: 
  156:         y = y * ratio + fract->y;
  157:         evt->p.ypos = y / base;
  158:         fract->y = (evt->p.ypos == 0) ? y : 0;
  159: }
  160: /*
  161:         send PD event
  162: */
  163: EXPORT  void     kpSendPdEvt(RawEvt *evt, UW *lsts, RawEvt *last)
  164: {
  165:         union {
  166:                 PdInStat      stat;
  167:                 UW            uw;
  168:         } u;
  169: 
  170:         /* if there is a difference in events, send KB/PD event */
  171:         u.stat = evt->p.stat;
  172:         if (lsts[0] == u.uw &&
  173:                 evt->p.stat.inv == 0 && evt->p.stat.vst == 0) {
  174: 
  175:                 if (evt->p.stat.abs == 0) {   /* relative movement */
  176:                         if (evt->p.xpos == 0 && evt->p.ypos == 0) return;
  177:                 } else {                      /* absolute movement */
  178:                         if (evt->p.xpos == last->p.xpos &&
  179:                             evt->p.ypos == last->p.ypos) return;
  180:                 }
  181:         }
  182: 
  183:         /* save the event to send */
  184:         lsts[0] = u.uw;
  185:         *last = *evt;
  186: 
  187:         /* send event */
  188:         kpSendMsg(evt);
  189: }
  190: /*
  191:         send wheel event
  192: */
  193: EXPORT  void     kpSendWheelEvt(W z)
  194: {
  195:         RawEvt evt;
  196:         union {
  197:                 PdIn2Stat     stat;
  198:                 UW            uw;
  199:         } u;
  200: 
  201:         if (z != 0) {
  202:                 u.uw = 0;
  203:                 evt.p2.stat = u.stat;
  204:                 evt.p2.stat.cmd = INP_PD2;
  205:                 evt.p2.wheel = z;
  206:                 evt.p2.rsv = 0;
  207:                 kpSendMsg(&evt);
  208:         }
  209: }
  210: /*
  211:         send mouse event
  212: */
  213: EXPORT  void     kpSendMouseEvt(W but, W x, W y, W z, UW *lsts)
  214: {
  215:         RawEvt evt, dummy;
  216:         union {
  217:                 PdInStat      stat;
  218:                 UW            uw;
  219:         } u;
  220: 
  221:         /* send mouse wheel event */
  222:         kpSendWheelEvt(z);
  223: 
  224:         /* scaling processing based on sensitivity */
  225:         kpScalingPos(&evt, x, y, (PNT*)&lsts[1], 0);
  226: 
  227:         /* set up PD event information */
  228:         u.uw = 0;
  229:         evt.p.stat = u.stat;
  230:         evt.p.stat.cmd = INP_PD;
  231:         evt.p.stat.butrev = 1;
  232:         evt.p.stat.onebut = 1;
  233:         evt.p.stat.main = (but & 0x01) ? 1 : 0;
  234:         evt.p.stat.sub = (but & 0x02) ? 1 : 0;
  235:         evt.p.stat.qpress = (but & 0x04) ? 1 : 0;
  236: 
  237:         /* if there is a difference in events, send KB/PD event */
  238:         kpSendPdEvt(&evt, lsts, &dummy);
  239: }
  240: /*
  241:         send key event
  242: */
  243: EXPORT  void     kpSendKeyEvt(W sts, W keycode)
  244: {
  245:         RawEvt evt;
  246:         union {
  247:                 KeyInStat     stat;
  248:                 UW            uw;
  249:         } u;
  250: 
  251:         if (keycode <= 0) return;
  252: 
  253:         /* process NumLock key */
  254:         if (keycode == NumLock) {
  255:                 if (sts & 1) {        /* send command to reverse NumLock status */
  256:                         kpSendDrvCmd(InputModeCmd(
  257:                                 ((InpMode ^ NumLockON) & NumLockON) | 0x100));
  258:                 }
  259:                 return;
  260:         }
  261: 
  262:         u.uw = 0;
  263:         evt.k.stat = u.stat;
  264:         evt.k.stat.cmd = INP_KEY;
  265:         evt.k.stat.kbid = KbdId;
  266:         evt.k.stat.press = sts & 1;
  267: 
  268:         /* process ten key pad */
  269:         if (keycode >= NumLockLo && keycode <= NumLockHi) {
  270:                 if ((InpMode & NumLockON) == 0)
  271:                         keycode = numtbl[keycode - NumLockLo];
  272:                 evt.k.stat.tenkey = 1;
  273:         }
  274:         evt.k.keytop = keycode;
  275: 
  276:         /* send KB/PD event */
  277:         kpSendMsg(&evt);
  278: }
  279: /*
  280:         send command to command processing task (within this driver)
  281: */
  282: EXPORT  ER       kpSendDrvCmd(UW cmd)
  283: {
  284:         ER     er;
  285:         UINT   dmy;
  286: 
  287:         /* wait for ready to send command
  288:                         this is aborted by timeout in order to avoid deadlock */
  289:         er = tk_wai_flg(CmdFlg, DeviceCommandReady, TWF_ORW | TWF_CLR,
  290:                         &dmy, 200);
  291:         if (er >= E_OK) {      /* send command */
  292:                 er = tk_set_flg(CmdFlg, cmd);
  293:         }
  294:         if (er < E_OK) {
  295:                 DP(("kpSendDrvCmd: err=%#x\n", er));
  296:         }
  297:         return er;
  298: }
  299: /*
  300:         data receiving task
  301: */
  302: EXPORT  void     kpDataTask(void)
  303: {
  304:         InMsg  msg;
  305:         W      sz;
  306: 
  307:         for (;;) {     /* it never quits itself */
  308:                 /* data receive: ignored if error or suspended state is in effect. */
  309:                 if ((sz = tk_rcv_mbf(InpMbf, &msg, TMO_FEVR)) < E_OK) {
  310:                         continue;
  311:                 }
  312:                 if (sz != sizeof(msg)) continue;
  313:                 if (Suspended == TRUE) continue;
  314: 
  315:                 /* process received data */
  316:                 hwProc(&msg);
  317:         }
  318: }
  319: /*
  320:         command processing task
  321: */
  322: EXPORT  void     kpCmdTask(void)
  323: {
  324:         UW     dt;
  325:         UINT   cmd;
  326: 
  327:         for (;;) {     /* it never quits itself */
  328: 
  329:                 /* command receive permitted */
  330:                 if (tk_set_flg(CmdFlg, DeviceCommandReady) < E_OK) continue;
  331: 
  332:                 /* wait for receiving a command */
  333:                 if (tk_wai_flg(CmdFlg, ~DeviceCommandReady, TWF_ORW | TWF_CLR,
  334:                                &cmd, TMO_FEVR) < E_OK) continue;
  335: 
  336:                 /* do processing based on command */
  337:                 dt = cmd & 0x00ffffff;
  338:                 switch (cmd & 0xff000000) {
  339:                 case ScanRateCmd(0):  /* scan speed - unsupported */
  340:                         break;
  341: 
  342:                 case SenseCmd(0):     /* scan speed - unsupported */
  343:                         PdSense = dt;
  344:                         break;
  345: 
  346:                 case InputModeCmd(0): /* input mode */
  347:                         /* lower two bits control normal input mode, and the upper bits
  348:                            are for extended input mode (machine dependent), and these are set independently. */
  349:                         dt |= InpMode & ((dt & ~0x3) ? 0x3 : ~0x3);
  350:                         if ((dt &= 0xff) != InpMode) {
  351:                                 InpMode = dt;
  352:                                 if (Suspended == FALSE) {
  353:                                         hwImode(dt);
  354:                                 }
  355:                         }
  356:                         break;
  357: 
  358:                 case SuspendKBPD:     /* suspend / resume */
  359:                         if (cmd == SuspendKBPD) {    /* suspend */
  360:                                 if (Suspended == FALSE) {
  361:                                         Suspended = TRUE;
  362:                                         hwInit(DC_SUSPEND);
  363:                                 }
  364:                         } else {                     /* resume */
  365:                                 if (Suspended == TRUE) {
  366:                                         hwInit(DC_RESUME);
  367:                                         Suspended = FALSE;
  368:                                 }
  369:                         }
  370:                         break;
  371: 
  372:                 default:
  373:                         DP(("kpCmdTask: cmd=%#08x\n", cmd));
  374:                 }
  375:         }
  376: }