implement button press/release with double check using coroutine

Dependencies:   mbed-dev

main.cpp

Committer:
mintisan
Date:
2016-08-28
Revision:
0:54509830df20

File content as of revision 0:54509830df20:

#include "mbed.h"
#include "coroutine.h"
//------------------------------------
// USER_KEY-PB_3 / USER_BUTTON-PC_13
//------------------------------------
DigitalIn mybutton(PB_3);
//------------------------------------
// LED1-PA5
//------------------------------------
DigitalOut myled(PA_5);
//------------------------------------
// Hyperterminal configuration
// 9600 bauds, 8-bit data, no parity
// SERIAL_TX-PA2, SERIAL_RX-PA3
//------------------------------------
Serial pc(PA_2, PA_3);

Ticker jitter;

#define entry()    pc.printf("func:%s\n", __FUNCTION__)

#define error()    pc.printf("Error! func:%s, line: %d\n", __FUNCTION__, __LINE__)

enum{OFF=0,ON=1};
enum{PRESS= 0, RELEASE = 1, UNKNOWN};
#define PRESS_JITTER_TIME       0.01    // 10ms
#define RELEASE_JITTER_TIME     0.02    // 20ms
uint8_t cur_flag_status = UNKNOWN;
uint8_t pre_flag_status = UNKNOWN;

volatile uint16_t cr_time_down;
volatile uint16_t cr_time_up;

void isr_ticker() {
    cr_time_down++;
    cr_time_up++;
}


void update_key_status(void)
{
    pre_flag_status = cur_flag_status;
    cur_flag_status = mybutton.read();
}

void key_down_status(void)
{
    update_key_status();
    if(cur_flag_status == PRESS){
        if(myled.read()!=ON){
           if(pre_flag_status == PRESS){
                myled = ON;
                pc.printf("Pressed\n");
           }
        }
    }
}

void key_up_status(void)
{
    update_key_status();
    if(cur_flag_status == RELEASE){
        if(myled.read()!=OFF){
            if(pre_flag_status == RELEASE){
                myled = OFF;
                pc.printf("Released\n");
           }
        }
    }
}

void user_thread_down(void)
{
    cr_start();
    
    // inital once each loop
    cr_time_down = 0;
    // waiting for condition is satisfied, or will be yield
    cr_yield(cr_time_down != 1);
    key_down_status();
    
    cr_end();    
}

void user_thread_up(void)
{
    cr_start();
    
    // inital once each loop
    cr_time_up = 0;
    // waiting for condition is satisfied, or will be yield
    cr_yield(cr_time_up != 2);
    key_up_status();

    cr_end();   
}

/* 
 *  one coroutine for down check;
 *  another coroutine for up check.
 */
int main(void)
{
    myled = OFF;
    jitter.attach(&isr_ticker, PRESS_JITTER_TIME);
    while(1) {
        user_thread_down();
        user_thread_up();
        // extend more task here
    }
}