This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

how to enable long key pressed interrupt for tps65930 keypad on omap3530

Hi, all

In current source code in BSP_WINCE_ARM_A8_01_00_00 and previous bsp version, the keypad driver can detect key pressed event but could not dectect long key pressed event. In order to implement this function, could I  add another driver similar to current keypad driver or direct modify current keypad driver. If the latter is OK, how to do that? Thank you!

  • Hellen,

    Could you please explain why you want to enable long key press interrupt?

    How do you want to handle the long key event when it is triggered?

    Thanks,

    Tao

     

  • that is our customer/project needs. when short key pressed, it plays a role, and long key pressed, it plays another role.

    when long key event occurs, I send the event to application layer, and application layer excuted corresponding function.

  • Hellen,

    You can use the existing driver to enable long key press feature, here are the steps:

    1. Enable long key detection in hardware and corresponding interrupt in KPD_Init(), the following is code snippet.

        // Long Key detection initialization
        TWLReadRegs(pDevice->hTWL,TWL_KEYP_CTRL_REG, &regval, sizeof(regval));
        regval |= TWL_KBD_CTRL_LK_EN;
        TWLWriteRegs(pDevice->hTWL, TWL_KEYP_CTRL_REG, &regval, sizeof(regval));

        regval = (UINT8)(pDevice->LongKeyTimeOut & 0xFF);
        TWLWriteRegs(pDevice->hTWL, TWL_LONG_KEY_REG1, &regval, sizeof(regval));

        TWLReadRegs(pDevice->hTWL,TWL_LK_PTV_REG, &regval, sizeof(regval));
        regval &= 0xF0;
        regval |= (pDevice->LongKeyTimeOut >>8) & 0x0F;
        TWLWriteRegs(pDevice->hTWL, TWL_LK_PTV_REG, &regval, sizeof(regval));

        // Create long key interrupt event
        pDevice->hIntrEventLongKey = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (pDevice->hIntrEventLongKey == NULL)
            {
            DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: "
                L"Failed create Long key interrupt event\r\n"
                ));
            goto cleanUp;
            }

        // Associate event with TWL LK interrupt
        if (!TWLInterruptInitialize(pDevice->hTWL, TWL_INTR_ITLKI, pDevice->hIntrEventLongKey))
            {
            DEBUGMSG (ZONE_ERROR, (L"ERROR: KPD_Init: "
                L"Failed associate long key event with TWL LK interrupt\r\n"
                ));
            goto cleanUp;
            }

        // Enable LK event
        if (!TWLInterruptMask(pDevice->hTWL, TWL_INTR_ITLKI, FALSE))
            {
            DEBUGMSG (ZONE_ERROR, (L"ERROR: KPD_Init: "
                L"Failed associate long key event with TWL LK interrupt\r\n"
                ));
            }

    2. Create thread to handle long key press interrupt. There are two ways to do it.

        a. Create a new interrupt thread, and accociate the thread with long key event( Use key press event and its handling as an example). Implement long key event handling such as sending event to application.

        b. use existing key press interrupt handling thread - KPD_IntrThread(). The thread will handle two events, example code as follows:

            HANDLE hArray[2];
            DWORD event;
            BOOL longKey=FALSE;
           
            hArray[0]=pDevice->hIntrEventKeypad;
            hArray[1]=pDevice->hIntrEventLongKey;

            // Wait for events
            //WaitForSingleObject(pDevice->hIntrEventKeypad, timeout);
            event = WaitForMultipleObjects(2, hArray, FALSE, timeout); 
            if (pDevice->intrThreadExit) break;

          if (event == (WAIT_OBJECT_0 + 1))
                {
                RETAILMSG(1, (L"long key detected\r\n"));
                    longKey = TRUE;
                /* do your long key press related handling */     
                }

            if(event == WAIT_OBJECT_0)
            {
                 // NORMAL key up/down handling
            }

    3. in order to detect the long key press properly, pDevice->samplePeriod should be  bigger than pDevice->LongKeyTimeOut ( the time out value for longkey press)

    4. Following changes in tps659xx.cpp - ProcessSecondaryInterrupts_Keypad() are needed, so that the Long key event can be properly set when Longkey Interrupt is triggered.

        // read TWL_KEYPAD_ROWS amount of rows...
        ReadRegs(pDevice, TWL_FULL_CODE_7_0, matrix, TWL_KEYPAD_ROWS);
        // loop through and signal relevant events
        clearMask = status;
        interruptCount = pStatusRegister->interruptCount;
        while (interruptCount-- && status != 0)
        {
            if ((status & 0x01) && *rgEvents)
            {
                RETAILMSG(1, (L"INFO: ProcessSecondaryInterrupts "
                    L"rgEvent=%x:%x\r\n", rgEvents, *rgEvents));
               
             break;
            }
            status >>= 1;
            ++rgEvents;
        }

       
        WriteKeypadMatrixQueue(matrix, *rgEvents);
        WriteRegs(pDevice, pStatusRegister->statusSubaddress, &clearMask, sizeof(clearMask));

    Regards,

    Tao