Windows CE

Sunday, May 10, 2009

Multiple Key detection + PXA27x + Wince 6.0

Recently i had a chance to look into a keypad problem.We are using a development board having PXA270 processor.For a single key press we were getting the proper scan code, but when multiple key were pressed, we were still getting the 1st pressed key scan code.Second Key was getting ignored.

So,I checked the xllp code for keypad.

\WINCE600\PLATFORM\COMMON\SRC\SOC\PXA27X_MS_V1\XLLP\SOURCE\xllp_keypad.c

There i found that in function XllpKeyPadConfigure , IGNORE_MULTIPLE_KEY_PRESS bit was set in keypad control register. I cleared that bit and checked the scan code.Now i was able to get some scan code when the second key was pressed,without lifting the 1st key.It means Multiple key press was not ignored now.

But still the second key scan code was not proper.The scan code we were getting was not what we were expecting.So i checked function ReadScanCodeAutomatically.

There i found a comment for the part of the code when numOfKeysPressed > 1

// these keys are the "minor keys", the ones that needs top right and bottom left of the
// cooresponding 4 keys surrounding them to trigger the correct key. Doing a binary search
// there are 5 keys, the middle key reads 0x8, the first key reads 0x2 and the last reads 0x20.
// this needs to be done for each row.  This will be encorporated into a routine for the next
// upgrade of keypad.

I couldn't understand this what does this mean.But one thing was sure that the logic for determining the scan code for multikey press was not according to the PXA27x.

I rewrote the function as follows :

   1: XLLP_BOOL_T ReadScanCodeAutomatically(XLLP_KEYPAD_REGS *v_pKeyPadRegs,XLLP_UINT8_T *key)
   2: {
   3:    
   4:         /**
   5:             Check for Single Key press
   6:         **/
   7: if(numOfKeysPressed > 1)
   8:         {
   9:             c0 = v_pKeyPadRegs->kpAutoScanMultiKeyPress0 & 0xFF;
  10:             c1 = ((v_pKeyPadRegs->kpAutoScanMultiKeyPress0 >> 16) & 0xFF);
  11:             c2 = v_pKeyPadRegs->kpAutoScanMultiKeyPress1 & 0xFF;
  12:             c3 = ((v_pKeyPadRegs->kpAutoScanMultiKeyPress1 >> 16) & 0xFF);
  13:             c4 = v_pKeyPadRegs->kpAutoScanMultiKeyPress2 & 0xFF;
  14:             c5 = ((v_pKeyPadRegs->kpAutoScanMultiKeyPress2 >> 16) & 0xFF);
  15:             c6 = v_pKeyPadRegs->kpAutoScanMultiKeyPress3 & 0xFF;
  16:             c7 = ((v_pKeyPadRegs->kpAutoScanMultiKeyPress3 >> 16) & 0xFF);
  17:  
  18:             
  19:         if(c0!=0)
  20:         {
  21:             ReadMultipleKeyScanCode(c0,0,RowBit,Col);
  22:         }
  23:         if(c1!=0)
  24:         {
  25:             ReadMultipleKeyScanCode(c1,1,RowBit,Col);
  26:         }
  27:         if(c2!=0)
  28:         {
  29:             ReadMultipleKeyScanCode(c2,2,RowBit,Col);
  30:         }
  31:         if(c3!=0)
  32:         {
  33:             ReadMultipleKeyScanCode(c3,3,RowBit,Col);
  34:         }
  35:         if(c4!=0)
  36:         {
  37:             ReadMultipleKeyScanCode(c4,4,RowBit,Col);
  38:         }
  39:         if(c5!=0)
  40:         {
  41:             ReadMultipleKeyScanCode(c5,5,RowBit,Col);
  42:         }
  43:         if(c6!=0)
  44:         {
  45:             ReadMultipleKeyScanCode(c6,6,RowBit,Col);
  46:         }
  47:         if(c7!=0)
  48:         {
  49:             ReadMultipleKeyScanCode(c7,7,RowBit,Col);
  50:         }
  51:  
  52:         key1 = (unsigned char) (( RowBit[0] <<>
  53:         key2 = (unsigned char) (( RowBit[1] <<>
  54:        
  55:         if(key1 == PrevKey)
  56:         {
  57:             *key = key2 ;
  58:         }
  59:         else
  60:             *key = key1 ;
  61:  
  62:     }
  63:         else
  64:             *key = NO_KEY;
  65:  
  66:       retval = XLLP_TRUE;
  67:     }
  68:     NKDbgPrintfW(L"ReadScanCodeAutomatically<\r\n");
  69:     PrevKey = *key ;
  70:     return(retval);
  71: }
  72:  
  73: //---------------------------------------------------------------------------------------------------------------
  74: // Function: ReadMultipleKeyScanCode
  75: // Purpose:  This functions reads the Multiple key pressed scan code from the KeyPad controller triggered by setting of the ASACT bit
  76: //           in the KeyPad Control register. If there is a valid key detected then it returns the scan code.
  77: // Returns:  success/failure.
  78: //---------------------------------------------------------------------------------------------------------------
  79: XLLP_BOOL_T ReadMultipleKeyScanCode(XLLP_UINT32_T KPASMKPRegister,XLLP_UINT32_T col, XLLP_UINT32_T RowBit[] ,XLLP_UINT32_T Col[])
  80: {
  81:     int i = 0;
  82:     while (i <>
  83:     {
  84:         if((KPASMKPRegister & 0x01) == 0x01 )
  85:         {
  86:             if(RowBit[0] == 0)
  87:             {
  88:                 RowBit[0] = i ;
  89:                 Col[0]  = col ;
  90:             }
  91:             else
  92:             {
  93:                 RowBit[1] = i ;
  94:                 Col[1]  = col ;
  95:             }
  96:             NKDbgPrintfW(L"XLLP_NEW:ReadMultipleKeyScanCode bit no  %d>\r\n",i);
  97:         }
  98:  
  99:         KPASMKPRegister = KPASMKPRegister >> 1 ;
 100:         i++ ;
 101:  
 102:     }
 103:      return(XLLP_TRUE);
 104: }
 105:  

And it worked fine. I was getting the second key scan code properly.

Note : There is a limitation in above code.It can only read two key press properly.More than 2 keys pressed simultaneously cant be recognized, for example Ctrl+Alt+Del   ;) But this is not required for our project..

No comments: