Modified version to work with EventQueue (outside of ISR)

MultiClick.cpp

Committer:
ohtsuka
Date:
2016-06-13
Revision:
3:c7f97bebf2f7
Parent:
2:6af39916a4a2
Child:
4:8d6883cdc3c8

File content as of revision 3:c7f97bebf2f7:

#include "MultiClick.h"

MultiClick::MultiClick(PinName p, PinMode m)
{
    _iin = new InterruptIn(p);
    _mode = m;
    
    _iin->mode(_mode);

    if(_mode == PullUp) {
         DBG_PRINT("isr fall.\r\n");
        _iin->fall(this, &MultiClick::isr_pressed);
        _iin->rise(this, &MultiClick::isr_released);
    } else {
         DBG_PRINT("isr rise.\r\n");
        _iin->fall(this, &MultiClick::isr_released);
        _iin->rise(this, &MultiClick::isr_pressed);
    }
    
    _timeout = new Timeout();
    _debounce_timeout = new Timeout();
    _longpress_timeout = new Timeout();
    _t = new Timer();
    _t->start();

    _click_interval_us = 300*1000;
    _debounce_ignore_us = 100*1000;
    _longpress_us = 1000*1000;
    _debounce_ignore = false;
    _longpressed = false;
}

void MultiClick::isr_pressed( void )
{
    
    // --- 長押し検出用タイマーを停止
    _longpress_timeout->detach();
    _longpressed = false;
    
    // --- チャタリング(debounce)チェック ------------------------------------------------
    if(_debounce_ignore == true) {
        DBG_PRINT("isr_pressed: bounce. ");
        fflush(stdout);
    } else {
        DBG_PRINT("isr_pressed called:\r\n");
        fflush(stdout);
        
        // 長押し検出用タイマー開始
        _longpress_timeout->attach_us(this, &MultiClick::longpress_timeout, _longpress_us );
    }

}

void MultiClick::isr_released( void )
{
    // 長押し検出用タイマーを停止    
    _longpress_timeout->detach();
    
    // --- チャタリング(debounce)チェック ------------------------------------------------
    if(_debounce_ignore == true) {
        DBG_PRINT("isr_released: bounce. ");
        fflush(stdout);
        
        return;
    } else if(_longpressed == true) { // 長押しチェック 
        DBG_PRINT("isr_released: _longpressed. ");
        fflush(stdout);

        _longpressed = false;
        return;
    } else {
        DBG_PRINT("isr_released called:\r\n");
        fflush(stdout);
    }    
    
    // クリック認定
    _click_times++;
    switch( _click_times ) {
    case 0:
        DBG_PRINT("error!");
        break;
    
    case 1:
        if(_c_callback_clicked != 0) {
            (*_c_callback_clicked)();
        }
        break;

    case 2:
        if(_c_callback_doubleclicked != 0) {
            (*_c_callback_doubleclicked)();
        }
        break;
    default:
        if(_c_callback_n_clicked != 0) {
            (*_c_callback_n_clicked)(_click_times);
        }
    }
    
    // チャタリングチェック期間を開始する設定(初回、押し下げ後一定時間は、押し下げを無視)
    _debounce_ignore = true;
    _debounce_timeout->detach();
    _debounce_timeout->attach_us(this, &MultiClick::debounce_timeout, _debounce_ignore_us );

    // マルチクリック検出用タイマーを設定
    _timeout->detach();
    _timeout->attach_us(this, &MultiClick::click_timeout, _click_interval_us );


}

void MultiClick::debounce_timeout( void )
{
    DBG_PRINT("--- debounce T.O.\r\n");
    _debounce_ignore = false;
}

void MultiClick::click_timeout( void )
{
    DBG_PRINT("===== multiclick T.O.\r\n\r\n");
    _click_times = 0;    
}

void MultiClick::longpress_timeout( void )
{
    DBG_PRINT("===== longpress T.O.\r\n\r\n");

    if(_c_callback_longpressed != 0) {
        (*_c_callback_longpressed)();
    }

    _longpressed = true;    
}


void MultiClick::attach_clicked(void (*function)(void) = 0) { _c_callback_clicked = function; }

void MultiClick::attach_doubleclicked(void (*function)(void) = 0) { _c_callback_doubleclicked = function; }

void MultiClick::attach_n_clicked(void (*function)(int) = 0) { _c_callback_n_clicked = function; }

void MultiClick::attach_longpressed(void (*function)(void) = 0) { _c_callback_longpressed = function; }