this locks like shit

Dependencies:   MenuLCD mbed

Fork of MenuLCD_copy by Vinícius Alves

menbed/menbedButtonHandler.cpp

Committer:
ViniR
Date:
2017-05-19
Revision:
0:92357d1220f3

File content as of revision 0:92357d1220f3:

#include "mbed.h"
#include "include/menbedNavigator.h"
#include "include/menbedButtonHandlerTimespec.h"
#include "include/menbedButtonHandler.h"

MenbedButtonHandler::MenbedButtonHandler (PinName selectPin, PinName downPin, 
    PinName upPin, PinName cancelPin, MenbedButtonHandlerTimespec *timespec,
    MenbedNavigator *navigator) : 
    //select(select), down(down), up(up), cancel(cancel),
    timespec(timespec), navigator(navigator)
{
    select = new DigitalIn(selectPin);
    down = new DigitalIn(downPin);
    up = new DigitalIn(upPin);
    cancel = new DigitalIn(cancelPin);

    numButtons = 4;
    
    select->mode (PullDown);
    down->mode (PullDown);
    up->mode (PullDown);
    cancel->mode (PullDown);
    
    init();
}


MenbedButtonHandler::MenbedButtonHandler (PinName selectPin, PinName downPin, 
    PinName upPin, MenbedButtonHandlerTimespec *timespec,
    MenbedNavigator *navigator) :
    timespec(timespec), navigator(navigator)
{
    select = new DigitalIn(selectPin);
    down = new DigitalIn(downPin);
    up = new DigitalIn(upPin);

    numButtons = 3;
    
    select->mode (PullDown);
    down->mode (PullDown);
    up->mode (PullDown);
    
    init();
}


MenbedButtonHandler::MenbedButtonHandler (PinName selectPin, PinName downPin, 
    MenbedButtonHandlerTimespec *timespec,
    MenbedNavigator *navigator) : 
    timespec(timespec), navigator(navigator)
{
    select = new DigitalIn(selectPin);
    down = new DigitalIn(downPin);

    numButtons = 2;
    
    select->mode (PullDown);
    down->mode (PullDown);
    
    init();
}


void MenbedButtonHandler::init()
{
    for (int i=0; i<4; i++)
    {
        buttonDebounced[i] = false;
        buttonAlreadyDepressed[i] = false;
    }
    
    currentTime_us = 0;
    ticker.attach_us (this, &MenbedButtonHandler::tick, 
        timespec->scanPeriod_us);
}


void MenbedButtonHandler::tick (void)
{
    // Accumulated amount of time that buttons have been continuously depressed
    uint32_t buttonDepressedTime_us;
    bool buttonCurrentlyDepressed;
    
    MenbedButtonEvent buttonEvent;
    buttonEvent.numButtons = numButtons;
    
    currentTime_us += timespec->scanPeriod_us;

    // Cycle through each of the buttons
    for (int i=MenbedButtonEvent::ButtonSelect; 
        (i<=MenbedButtonEvent::ButtonCancel) && (i<numButtons);
        i++)
    {
        buttonEvent.name = (MenbedButtonEvent::ButtonName)i;
        buttonCurrentlyDepressed = 
            isButtonDepressed((MenbedButtonEvent::ButtonName)i);

        // The amount of time the current button has been depressed is
        // the current time minus the time which the button was first
        // depressed.
        buttonDepressedTime_us = currentTime_us - buttonPushedTime_us[i];

        if (buttonCurrentlyDepressed && buttonAlreadyDepressed[i])
        {
            if ((buttonDepressedTime_us >= timespec->typematicX10Delay_us) &&
                    (currentTime_us - buttonLastTypematicTime_us[i] >=
                        timespec->typematicX10Period_us ))
            {
                buttonLastTypematicTime_us[i] = currentTime_us;
                buttonEvent.action = MenbedButtonEvent::BUTTON_ACTION_PUSHED;
                navigator->handleButtonEvent (buttonEvent);
            }
            else if ((buttonDepressedTime_us >=
                    timespec->typematicPeriod_us)
                    && (currentTime_us - buttonLastTypematicTime_us[i] >=
                            timespec->typematicPeriod_us))
            {
                buttonLastTypematicTime_us[i] = currentTime_us;
                buttonEvent.action = MenbedButtonEvent::BUTTON_ACTION_PUSHED;
                navigator->handleButtonEvent (buttonEvent);
            }
            else if ((buttonDepressedTime_us >= timespec->debounceDelay_us)
                    && (!buttonDebounced[i]))
            {
                buttonLastTypematicTime_us[i] = currentTime_us;
                buttonDebounced[i] = true;
                buttonEvent.action = MenbedButtonEvent::BUTTON_ACTION_PUSHED;
                navigator->handleButtonEvent (buttonEvent);
            }

            if (buttonDebounced[i] &&
                    (buttonDepressedTime_us >= 
                        timespec->longReleaseDelay_us))
            {
                buttonEvent.action = MenbedButtonEvent::BUTTON_ACTION_HELD_LONG;
                navigator->handleButtonEvent (buttonEvent);
            }

            buttonAlreadyDepressed[i] = true;
        }
        // Otherwise, if the button was just depressed, we indicate that it
        // has not yet debounced and record the time so that we know when it
        // was first pressed.
        else if (buttonCurrentlyDepressed && !buttonAlreadyDepressed[i])
        {
            buttonDebounced[i] = false;
            buttonPushedTime_us[i] = currentTime_us;

            buttonAlreadyDepressed[i] = true;
        }
        // Otherwise, if the button is not depressed but it was previously
        // depressed and the amount of time it was depressed exceeds the
        // debounce time, then we say the button has been released.
        else if (!buttonCurrentlyDepressed && buttonAlreadyDepressed[i])
        {
            if (buttonDebounced[i])
            {
                if (buttonDepressedTime_us >=
                        timespec->longReleaseDelay_us)
                {
                    buttonEvent.action = MenbedButtonEvent::BUTTON_ACTION_RELEASED_LONG;
                    navigator->handleButtonEvent (buttonEvent);
                }
                else
                {
                    buttonEvent.action = MenbedButtonEvent::BUTTON_ACTION_RELEASED_SHORT;
                       navigator->handleButtonEvent (buttonEvent);
                }
            }

            buttonAlreadyDepressed[i] = false;
        }
    }
}


bool MenbedButtonHandler::isButtonDepressed (MenbedButtonEvent::ButtonName name)
{
    switch (name)
    {
    case MenbedButtonEvent::ButtonSelect:
        return *select;
    case MenbedButtonEvent::ButtonDown:
        if (numButtons >= 2)
            return *down;
        else
            return false;
    case MenbedButtonEvent::ButtonUp:
        if (numButtons >= 3)
            return *up;
        else
            return false;
    case MenbedButtonEvent::ButtonCancel:
        if (numButtons == 4)
            return *cancel;
        else
            return false;
    }
    
    return false;
}