gonzui


Format: Advanced Search

tkernel_2/driver/tef_em1d/kbpd/src/statmach.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:  *      statmach.c
   18:  *
   19:  *       KB/PD device manager
   20:  *       entry to the enableware function (state machine)
   21:  */
   22: 
   23: #include "kbpd.h"
   24: 
   25: /*
   26:  * send messages used only inside manager
   27:  */
   28: EXPORT ER kpSendPseudoMsg( T_MSG *msg )
   29: {
   30:         ER     ercd;
   31: 
   32:         ercd = tk_snd_mbx(kpMgrInfo.dataMbx, msg);
   33:         if ( ercd != E_OK ) {
   34:                 DEBUG_PRINT(("kpSendPseudoMsg err = %d\n", ercd));
   35:                 return ercd;
   36:         }
   37: 
   38:         return E_OK;
   39: }
   40: 
   41: /*
   42:  * alarm handler
   43:  */
   44: LOCAL void alarmHandler( void *exinf )
   45: {
   46:         AlarmState     *alm = (AlarmState*)exinf;
   47:         TimeoutMsg     *msg;
   48:         SYSTIM         time;
   49:         ER             ercd;
   50:         int            i;
   51: 
   52:         /* look for message buffer free space */
   53:         for ( i = 0; i < NumOfAlmMsgBuf; ++i ) {
   54:                 if ( alm->msg[i].stat.read != 0 ) break;
   55:         }
   56:         if ( i >= NumOfAlmMsgBuf ) {
   57:                 /* try notifying that the message buffer has become full. */
   58:                 for ( i = 0; i < NumOfAlmMsgBuf; ++i ) {
   59:                         alm->msg[i].stat.err = DEV_OVRRUN;
   60:                 }
   61:                 DEBUG_PRINT(("alarmHandler, over run error\n"));
   62:                 return;
   63:         }
   64: 
   65:         /* set up message */
   66:         msg = &alm->msg[i];
   67:         msg->stat.read = 0;
   68:         msg->stat.err = DEV_OK;
   69: 
   70:         /* set current time */
   71:         ercd = tk_get_tim(&time);
   72:         if ( ercd != E_OK ) {
   73:                 DEBUG_PRINT(("alarmHandler, tk_get_tim err = %d\n", ercd));
   74:                 msg->stat.err = DEV_SYSERR;
   75:         }
   76:         msg->time = time.lo;
   77: 
   78:         /* send timeout message */
   79:         kpSendPseudoMsg((T_MSG*)msg);
   80: }
   81: 
   82: /*
   83:  * set alarm
   84:  */
   85: EXPORT ER kpSetAlarm( AlarmState *alm, MSEC offsetTime )
   86: {
   87:         SYSTIM         time;
   88:         ER             ercd;
   89: 
   90:         /* stop alarm (necessary) */
   91:         ercd = tk_stp_alm(alm->almno);
   92:         if ( ercd != E_OK ) {
   93:                 DEBUG_PRINT(("kpSetAlarm, tk_stp_alm err = %d\n", ercd));
   94:                 return ercd;
   95:         }
   96: 
   97:         /* current time */
   98:         ercd = tk_get_tim(&time);
   99:         if ( ercd != E_OK ) {
  100:                 DEBUG_PRINT(("kpSetAlarm, tk_get_tim err = %d\n", ercd));
  101:                 return ercd;
  102:         }
  103:         alm->setTime = time.lo;
  104: 
  105:         /* start alarm handler */
  106:         ercd = tk_sta_alm(alm->almno, offsetTime);
  107:         if ( ercd != E_OK ) {
  108:                 DEBUG_PRINT(("kpSetAlarm, tk_sta_alm err = %d\n", ercd));
  109:                 return ercd;
  110:         }
  111: 
  112:         return E_OK;
  113: }
  114: 
  115: /*
  116:  * check the validity of timeout messages
  117:  *       if valid, return TRUE, and if invalid, return FALSE.
  118:  */
  119: EXPORT BOOL kpChkAlarm( AlarmState *alm, TimeoutMsg *msg )
  120: {
  121:         return ( alm->setTime <= msg->time )? TRUE: FALSE;
  122: }
  123: 
  124: /*
  125:  * initialize alarm management information
  126:  */
  127: LOCAL ER initAlmStat( AlarmState *alm, TimeoutKind kind )
  128: {
  129:         ER     ercd;
  130:         int    i;
  131:         T_CALM calm;
  132: 
  133:         /* obtain alarm handler number */
  134:         calm.exinf  = alm;
  135:         calm.almatr = TA_HLNG;
  136:         calm.almhdr = alarmHandler;
  137:         ercd = tk_cre_alm(&calm);
  138:         if ( ercd < E_OK ) {
  139:                 DEBUG_PRINT(("initAlmStat, tk_cre_alm err = %d\n", ercd));
  140:                 return ercd;
  141:         }
  142:         alm->almno = (ID)ercd;
  143: 
  144:         for ( i = 0; i < NumOfAlmMsgBuf; ++i ) {
  145:                 alm->msg[i].stat.read = 1;
  146:                 alm->msg[i].stat.cmd = PIC_TIMEOUT;
  147:                 alm->msg[i].stat.kind = kind;
  148:         }
  149: 
  150:         return E_OK;
  151: }
  152: 
  153: /*
  154:  * release alarm handler
  155:  */
  156: LOCAL ER finishAlarm( AlarmState *alm )
  157: {
  158:         ER     ercd;
  159: 
  160:         if ( alm->almno != InvalidHNO ) {
  161: 
  162:                 /* cancel alarm handler */
  163:                 ercd  = tk_stp_alm(alm->almno);
  164:                 ercd |= tk_del_alm(alm->almno);
  165:                 if ( ercd != E_OK ) {
  166:                         DEBUG_PRINT(("finishAlarm, err = %d\n", ercd));
  167:                         return ercd;
  168:                 }
  169:         }
  170: 
  171:         return E_OK;
  172: }
  173: 
  174: /* ------------------------------------------------------------------------ */
  175: 
  176: /*
  177:  * initialize state machine
  178:  */
  179: EXPORT ER kpInitializeStateMachine( void )
  180: {
  181:         ER     err;
  182:         int    i;
  183: 
  184:         /* key */
  185:         QueInit(&StatMach.useq);
  186:         QueInit(&StatMach.freq);
  187:         for ( i = 0; i < MaxKey; ++i ) {
  188:                 err = initAlmStat(&StatMach.key[i].alm, KeyTmoutKind(i));
  189:                 if ( err != E_OK ) return err;
  190:                 QueInsert((QUEUE*)&StatMach.key[i], &StatMach.freq);
  191:         }
  192:         StatMach.spressMsg.cmd.read = 1;
  193:         StatMach.spressMsg.cmd.cmd = PIC_SPRESS;
  194:         StatMach.keyupMsg.cmd.read = 1;
  195:         StatMach.keyupMsg.cmd.cmd = PIC_KEYUP;
  196: 
  197:         /* PD button */
  198:         for ( i = 0; i < NumOfPdBut; ++i ) {
  199:                 StatMach.pdBut[i].state = BS_RELEASE;
  200:                 err = initAlmStat(&StatMach.pdBut[i].alm, PdButTmoutKind(i));
  201:                 if ( err != E_OK ) return err;
  202:                 StatMach.pdBut[i].button = PdButKind(i);
  203:         }
  204: 
  205:         return E_OK;
  206: }
  207: 
  208: /*
  209:  * epilog processing of state machine
  210:  */
  211: EXPORT void kpFinishStateMachine( void )
  212: {
  213:         int    i;
  214: 
  215:         /* direct key input */
  216:         for ( i = 0; i < MaxKey; ++i ) {
  217:                 finishAlarm(&StatMach.key[i].alm);
  218:         }
  219: 
  220:         /* PD button */
  221:         for ( i = 0; i < NumOfPdBut; ++i ) {
  222:                 finishAlarm(&StatMach.pdBut[i].alm);
  223:         }
  224: }
  225: 
  226: /*
  227:  * release KeyState
  228:  */
  229: EXPORT void kpReleaseKey( KeyState *ks )
  230: {
  231:         QueRemove((QUEUE*)ks);
  232:         QueInsert((QUEUE*)ks, &StatMach.freq);
  233: }
  234: 
  235: /*
  236:  * processing of INP_KEY
  237:  */
  238: LOCAL BOOL execINP_KEY( InnerEvent *evt, ReceiveData *msg )
  239: {
  240:         KeyTop         keytop;
  241:         UW             kbsel;
  242:         KeyState       *ks;
  243: 
  244:         if ( msg->head.cmd.err != DEV_OK ) {
  245:                 /* resetting key state due to error */
  246:                 kpAllResetKeyMap();
  247: 
  248:                 if ( isQueEmpty(&StatMach.useq) ) return FALSE;
  249: 
  250:                 kpExecKeyStateMachine((KeyState*)StatMach.useq.next, evt, msg);
  251: 
  252:                 return !isQueEmpty(&StatMach.useq);
  253:         }
  254: 
  255:         keytop = toKeyTop(&msg->kb);
  256: 
  257:         /* look for KeyState that matches keytop */
  258:         ks = (KeyState*)QueSearch(&StatMach.useq, &StatMach.useq,
  259:                                 keytop.w, offsetof(KeyState, keytop.w));
  260: 
  261:         kbsel = ( ks == (KeyState*)&StatMach.useq )?
  262:                 kpMgrInfo.kpState.stat.kbsel: ks->kbsel;
  263: 
  264:         /* change keymap */
  265:         kpSetOrResetKeyMap(keytop, kbsel, msg->kb.stat.press);
  266: 
  267:         if ( ks == (KeyState*)&StatMach.useq ) {
  268:                 /* search empty KeyState */
  269:                 ks = (KeyState*)QueRemoveNext(&StatMach.freq);
  270:                 if ( ks == NULL ) return FALSE;
  271: 
  272:                 /* initialize KeyState */
  273:                 ks->keytop = keytop;
  274:                 ks->kbsel = kbsel;
  275:                 ks->state = ( kpGetKeyKind(keytop) <= NormalKey )?
  276:                                         KS_RELEASE: SS_RELEASE;
  277:                 MEMSET(&ks->u, 0, sizeof(ks->u));
  278:                 QueInsert((QUEUE*)ks, &StatMach.useq);
  279:         }
  280: 
  281:         /* execute the state machine */
  282:         kpExecKeyStateMachine(ks, evt, msg);
  283: 
  284:         return FALSE;
  285: }
  286: 
  287: /*
  288:  * execute the state machine
  289:  *       if repetition is necessary, return TRUE
  290:  *       As long as TRUE is returned, evt needs to be processed, and calling must be repeated with the
  291:  * the same set of parameters.
  292:  *       (If multiple internal events, evt, are generated, this type of situation can arise.)
  293:  */
  294: EXPORT BOOL kpExecStateMachine( InnerEvent *evt, ReceiveData *msg )
  295: {
  296:         BOOL           cont = FALSE;
  297:         W              kind;
  298:         KeyState       *ks;
  299: 
  300:         evt->type = IE_NULL;
  301: 
  302:         switch ( msg->head.cmd.cmd ) {
  303:           case INP_PD:
  304:                 kpPdPreProcess(&msg->pd); /* preprocessing (left-handed mode, etc.) */
  305:                 kpExecPdButStateMachine(evt, msg, BK_ALL);
  306:                 break;
  307: 
  308:           case INP_KEY:
  309:                 cont = execINP_KEY(evt, msg);
  310:                 break;
  311: 
  312:           case PIC_TIMEOUT:
  313:                 switch ( kind = msg->tmout.stat.kind ) {
  314:                   case TMO_MAIN:      /* main button */
  315:                         kpExecPdButStateMachine(evt, msg, BK_MAIN);
  316:                         break;
  317:                   case TMO_SUB:               /* subbutton */
  318:                         kpExecPdButStateMachine(evt, msg, BK_SUB);
  319:                         break;
  320:                   default:            /* key */
  321:                         kpExecKeyStateMachine(&StatMach.key[kind], evt, msg);
  322:                         break;
  323:                 }
  324:                 break;
  325: 
  326:           case PIC_KEYUP:
  327:                 ks = (KeyState*)QueSearchH(&StatMach.useq, &StatMach.useq,
  328:                                 KS_RELEASE, offsetof(KeyState, state));
  329:                 if ( ks != (KeyState*)&StatMach.useq ) {
  330:                         kpExecKeyStateMachine(ks, evt, msg);
  331:                 }
  332:                 break;
  333: 
  334:           case PIC_SPRESS:
  335:                 /* this msg does not generate evt, and
  336:                    we need to repeat as many times as necessary */
  337:                 for ( ks = (KeyState*)StatMach.useq.next;
  338:                                         ks != (KeyState*)&StatMach.useq;
  339:                                         ks = (KeyState*)ks->q.next ) {
  340:                         if ( ks->state == KS_CONTIME ) {
  341:                                 kpExecKeyStateMachine(ks, evt, msg);
  342:                         }
  343:                 }
  344:                 break;
  345: 
  346:           default:
  347:                 DEBUG_PRINT(("unknown cmd(%d)\n", msg->head.cmd.cmd));
  348:                 return FALSE;
  349:         }
  350: 
  351:         return cont;
  352: }
  353: 
  354: /*
  355:  * request forced up of keys and buttons
  356:  * (used for entering suspeneded state)
  357:  */
  358: EXPORT ER kpKeyAndButtonForceUp( void )
  359: {
  360:         static KeyInput        keymsg;
  361:         static PdInput pdmsg;
  362:         ER             err, error = E_OK;
  363: 
  364:         /* key up request */
  365:         keymsg.stat.read = 0;
  366:         keymsg.stat.cmd  = INP_KEY;
  367:         keymsg.stat.err  = DEV_RESET;
  368:         err = kpSendPseudoMsg((T_MSG*)&keymsg);
  369:         if ( err < E_OK ) error = err;
  370: 
  371:         /* button up request */
  372:         pdmsg.stat.read = 0;
  373:         pdmsg.stat.cmd  = INP_PD;
  374:         pdmsg.stat.err  = DEV_RESET;
  375:         err = kpSendPseudoMsg((T_MSG*)&pdmsg);
  376:         if ( err < E_OK ) error = err;
  377: 
  378: DO_DEBUG(
  379:         if ( error < E_OK )
  380:                 DEBUG_PRINT(("kpKeyAndButtonForceUp err = %d\n", error));
  381: )
  382:         return error;
  383: }