Пример #1
0
//*****************************************************************************
//
// Performs all necessary menu and control processing based on new button
// states.
//
// \param ucButtons contains the current state of each of the front panel
// buttons.  A 1 in a bit position indicates that the corresponding button
// is released while a 0 indicates that the button is pressed.
// \param ucChanged contains bit flags showing which button states changed
// since the last call to this function.  A 1 indicates that the corresponding
// button state changed while a 0 indicates that it remains unchanged.
// \param ucRepeat contains bit flags indicating whether a key autorepeat
// event is being signalled for each key.  A 1 indicates that an autorepeat is
// being signalled while a 0 indicates that it is not.
//
// This is the top level function called when any key changes state.  This
// updates the relevant control or controls on the screen and processes
// the key appropriately for the control that currently has focus.
//
// \return Returns \b true if the menu was dismissed as a result of this
// call (in which case the caller should refresh the main waveform
// display area) or any control reported that a display update is required.
// Returns \b false if the menu is still being displayed or if it
// was not being displayed when the function was called and no control
// reported needing a display update.
//
//*****************************************************************************
tBoolean
MenuProcess(unsigned char ucButtons, unsigned char ucChanged,
            unsigned char ucRepeat)
{
    tGroup *pFocusGroup;
    tBoolean bRetcode;
    tBoolean bRedrawNeeded;

    //
    // Assume we won't be dismissing the menu until we find out otherwise.
    //
    bRedrawNeeded = false;

    //
    // Which group has focus?
    //
    pFocusGroup = g_sMenu.ppcGroups[g_sMenu.ucFocusGroup];

    //
    // Is the menu currently visible?
    //
    if(!g_bMenuShown)
    {
        //
        // The menu is not currently shown.  First check to see if we need to
        // show it and, if so, do this.  We look for a release of the select
        // button to trigger the display of the menu.  Note that we
        // deliberately ignore all other key notifications that may be present
        // at the same time.
        //
        if(BUTTON_RELEASED(SELECT_BUTTON, ucButtons, ucChanged))
        {
            //
            // Draw the menu.
            //
            g_bMenuShown = MenuDisplay(&g_sMenu);

            //
            // Get rid of any alert message that may currently be displayed.
            //
            RendererClearAlert();
        }
        else
        {
            //
            // We were not being asked to show the menu so we pass the
            // various events on to the group for it to decide what to do
            // with them.  For the group, we pass on any button press or auto-
            // repeat indication.  We ignore button releases in this case.
            //

            //
            // Left button press or repeat.
            //
            if(BUTTON_PRESSED(LEFT_BUTTON, ucButtons, ucChanged) ||
               BUTTON_REPEAT(LEFT_BUTTON, ucRepeat))
            {
                bRetcode = pFocusGroup->pfnGroupEventProc(pFocusGroup,
                                                          MENU_EVENT_LEFT);
                if(bRetcode)
                {
                    bRedrawNeeded = true;
                }
            }

            //
            // Right button press or repeat.
            //
            if(BUTTON_PRESSED(RIGHT_BUTTON, ucButtons, ucChanged) ||
               BUTTON_REPEAT(RIGHT_BUTTON, ucRepeat))
            {
                bRetcode = pFocusGroup->pfnGroupEventProc(pFocusGroup,
                                                          MENU_EVENT_RIGHT);
                if(bRetcode)
                {
                    bRedrawNeeded = true;
                }
            }

            //
            // Left button released.
            //
            if(BUTTON_RELEASED(LEFT_BUTTON, ucButtons, ucChanged))
            {
                bRetcode = pFocusGroup->pfnGroupEventProc(pFocusGroup,
                                                     MENU_EVENT_LEFT_RELEASE);
                if(bRetcode)
                {
                    bRedrawNeeded = true;
                }
            }

            //
            // Right button released.
            //
            if(BUTTON_RELEASED(RIGHT_BUTTON, ucButtons, ucChanged))
            {
                bRetcode = pFocusGroup->pfnGroupEventProc(pFocusGroup,
                                                     MENU_EVENT_RIGHT_RELEASE);
                if(bRetcode)
                {
                    bRedrawNeeded = true;
                }
            }

            //
            // Up button press.
            //
            if(BUTTON_PRESSED(UP_BUTTON, ucButtons, ucChanged) ||
               BUTTON_REPEAT(UP_BUTTON, ucRepeat))
            {
                bRetcode = pFocusGroup->pfnGroupEventProc(pFocusGroup,
                                                          MENU_EVENT_UP);
                if(bRetcode)
                {
                    bRedrawNeeded = true;
                }
            }

            //
            // Down button press.
            //
            if(BUTTON_PRESSED(DOWN_BUTTON, ucButtons, ucChanged) ||
               BUTTON_REPEAT(DOWN_BUTTON, ucRepeat))
            {
                bRetcode = pFocusGroup->pfnGroupEventProc(pFocusGroup,
                                                          MENU_EVENT_DOWN);
                if(bRetcode)
                {
                    bRedrawNeeded = true;
                }
            }
        }
    }
    else
    {
        //
        // The menu is already visible so we ignore left and right keys and
        // use up/down/select only to change the focus group.
        //

        //
        // If this button press will result in a group focus change we need to
        // redraw the current group in its non-focused colors, update the
        // focus to the new group then send an activate event to the group.
        //
        if(BUTTON_PRESSED(DOWN_BUTTON, ucButtons, ucChanged) ||
           BUTTON_REPEAT(DOWN_BUTTON, ucRepeat) ||
           BUTTON_PRESSED(UP_BUTTON, ucButtons, ucChanged) ||
           BUTTON_REPEAT(UP_BUTTON, ucRepeat))
        {
            //
            // Redraw the current focus button in its original colors
            //
            MenuDrawGroupButton(&g_sMenu, g_sMenu.ucFocusGroup,
                                &g_psBtnColors);

            //
            // Update the group with the focus
            //
            if(BUTTON_PRESSED(DOWN_BUTTON, ucButtons, ucChanged) ||
               BUTTON_REPEAT(DOWN_BUTTON, ucRepeat))
            {
                if(g_sMenu.ucFocusGroup < (g_sMenu.ucNumGroups - 1))
                {
                    g_sMenu.ucFocusGroup++;
                }
            }
            else
            {
                if(g_sMenu.ucFocusGroup > 0)
                {
                    g_sMenu.ucFocusGroup--;
                }
            }

            //
            // Redraw the new focus button with the focus colors.
            //
            MenuDrawGroupButton(&g_sMenu, g_sMenu.ucFocusGroup,
                                &g_psFocusColors);

            //
            // Tell the new group that it has been activated.
            //
            pFocusGroup = g_sMenu.ppcGroups[g_sMenu.ucFocusGroup];
            bRetcode = (pFocusGroup->pfnGroupEventProc)(pFocusGroup,
                                                        MENU_EVENT_ACTIVATE);
            if(bRetcode)
            {
                bRedrawNeeded = true;
            }
        }

        //
        // Now look for a release of the SELECT key.  This indicates that we
        // must dismiss the menu.
        //
        if(BUTTON_RELEASED(SELECT_BUTTON, ucButtons, ucChanged))
        {
            //
            // We did receive a release message for the SELECT button so
            // tell the caller that the menu has been dismissed.
            //
            g_bMenuShown = false;
            bRedrawNeeded = true;
        }
    }

    //
    // Play the button click sound if any button was just pressed.
    //
    if((~ucButtons & ucChanged) && g_bClicksEnabled)
    {
        ClassDPlayADPCM(g_pucADPCMClick, sizeof(g_pucADPCMClick));
    }

    return(bRedrawNeeded);
}
Пример #2
0
//*****************************************************************************
//
// This is interrupt handler for the systick interrupt.
//
// This function handles the interrupts generated by the system tick.  These
// are used for button debouncing and updating the state of the buttons.
// The buttons are stored in a bitmask indicating which buttons have been
// release.  If a button is pressed twice, only one press will be seen.  There
// is no press and hold detection.
//
// \return None.
//
//*****************************************************************************
void
SysTickHandler(void)
{
    unsigned char ucButtons;
    unsigned char ucChanged;
    unsigned char ucRepeat;

    //
    // Determine the state of the pushbuttons.
    //
    ucButtons = ButtonsPoll(&ucChanged, &ucRepeat);

    //
    // Up button has been released.
    //
    if(BUTTON_RELEASED(UP_BUTTON, ucButtons, ucChanged))
    {
        g_ulButtons |= BUTTON_UP_CLICK;
    }

    //
    // Up button has been held.
    //
    if(BUTTON_REPEAT(UP_BUTTON, ucRepeat))
    {
        g_ulButtons |= BUTTON_UP_CLICK;
    }

    //
    // Down button has been released.
    //
    if(BUTTON_RELEASED(DOWN_BUTTON, ucButtons, ucChanged))
    {
        g_ulButtons |= BUTTON_DOWN_CLICK;
    }

    //
    // Down button has been held.
    //
    if(BUTTON_REPEAT(DOWN_BUTTON, ucRepeat))
    {
        g_ulButtons |= BUTTON_DOWN_CLICK;
    }

    //
    // Left button has been released.
    //
    if(BUTTON_RELEASED(LEFT_BUTTON, ucButtons, ucChanged))
    {
        g_ulButtons |= BUTTON_LEFT_CLICK;
    }

    //
    // Right button has been released.
    //
    if(BUTTON_RELEASED(RIGHT_BUTTON, ucButtons, ucChanged))
    {
        g_ulButtons |= BUTTON_RIGHT_CLICK;
    }

    //
    // Select button has been released.
    //
    if(BUTTON_RELEASED(SELECT_BUTTON, ucButtons, ucChanged))
    {
        g_ulButtons |= BUTTON_SELECT_CLICK;
    }
}
//*****************************************************************************
//
// This function handles updates due to the buttons.
//
// This function is called from the main loop each time the buttons need to
// be checked.  If it detects an update it will schedule an transfer to the
// host.
//
// Returns Returns \b true on success or \b false if an error is detected.
//
//*****************************************************************************
tBoolean
ButtonHandler(void)
{
    unsigned char ucButtons, ucChanged, ucRepeat;
    unsigned long ulRetcode;
    char cDeltaX, cDeltaY;
    tBoolean bSuccess;

    //
    // Determine the state of the pushbuttons.
    //
    ucButtons = ButtonsPoll(&ucChanged, &ucRepeat);

    //
    // Update the display to show which buttons are currently pressed.
    //
    UpdateDisplay(ucButtons);

    //
    // If we are connected to the host and the select button changed state or
    // we see a repeat message from any of the direction buttons, go ahead and
    // send a mouse state change to the host.
    //
    if((ucChanged & SELECT_BUTTON) || (ucRepeat & ~SELECT_BUTTON))
    {
        //
        // Assume no change in the position until we determine otherwise.
        //
        cDeltaX = 0;
        cDeltaY = 0;

        //
        // Up button is held down
        //
        if(BUTTON_REPEAT(UP_BUTTON, ucRepeat))
        {
            cDeltaY = MOUSE_MOVE_DEC;
        }

        //
        // Down button is held down.
        //
        if(BUTTON_REPEAT(DOWN_BUTTON, ucRepeat))
        {
            cDeltaY = MOUSE_MOVE_INC;
        }

        //
        // Left button is held down.
        //
        if(BUTTON_REPEAT(LEFT_BUTTON, ucRepeat))
        {
            cDeltaX = MOUSE_MOVE_DEC;
        }

        //
        // Right button is held down
        //
        if(BUTTON_REPEAT(RIGHT_BUTTON, ucRepeat))
        {
            cDeltaX = MOUSE_MOVE_INC;
        }

        //
        // Tell the HID driver to send this new report for us.  Note that a 0
        // in ucButtons indicates that the relevant button is pressed so we
        // set the MOUSE_REPORT_BUTTON_1 bit if SELECT_BUTTON is clear in
        // ucButtons.
        //
        DEBUG_PRINT("Sending (0x%02x, 0x%02x), button %s.\n", cDeltaX,
                    cDeltaY, ((ucButtons & SELECT_BUTTON) ? "released" :
                    "pressed"));

        g_eMouseState = MOUSE_STATE_SENDING;
        ulRetcode = USBDHIDMouseStateChange((void *)&g_sMouseDevice, cDeltaX,
                                            cDeltaY,
                                            ((ucButtons & SELECT_BUTTON) ? 0 :
                                            MOUSE_REPORT_BUTTON_1));

        //
        // Did we schedule the report for transmission?
        //
        if(ulRetcode == MOUSE_SUCCESS)
        {
            //
            // Wait for the host to acknowledge the transmission if all went
            // well.
            //
            bSuccess = WaitForSendIdle(MAX_SEND_DELAY);

            //
            // Did we time out waiting for the packet to be sent?
            //
            if (!bSuccess)
            {
                //
                // Yes - assume the host disconnected and go back to
                // waiting for a new connection.
                //
                DEBUG_PRINT("Send timed out!\n");
                g_bConnected = 0;
            }
        }
        else
        {
            //
            // An error was reported when trying to send the report. This may
            // be due to host disconnection but could also be due to a clash
            // between our attempt to send a report and the driver sending the
            // last report in response to an idle timer timeout so we don't
            // jump to the conclusion that we were disconnected in this case.
            //
            DEBUG_PRINT("Can't send report.\n");
            bSuccess = false;
        }
    }
    else
    {
        //
        // There was no change in the state of the buttons so we have nothing
        // to do.
        //
        bSuccess = true;
    }

    return(bSuccess);
}