#include "mbed.h" #include "ButtonThread.h" EventFlags buttonFlags; #define PUSH_FLAG 0b01 #define LIFT_FLAG 0b10 void button_onrise(void) { buttonFlags.set(PUSH_FLAG); } int readButtonPresses(void) { int pressed_count = 0; // Wait and track an initial press without timing out buttonFlags.wait_any(PUSH_FLAG); pressed_count++; while(true) { uint32_t flags = buttonFlags.wait_any(PUSH_FLAG, 1000); bool timed_out = flags == osFlagsErrorTimeout; bool had_any_error = flags & osFlagsError; if(timed_out) { break; } else if(had_any_error) { error("Uhh what the f?\n"); } else { pressed_count++; } } return pressed_count; } int buttonPressCount; Mutex buttonPressMutex; ConditionVariable cv(buttonPressMutex); void buttonTask(void) { InterruptIn buttonIRQ(BUTTON1); buttonIRQ.rise(button_onrise); while(true) { int presses = readButtonPresses(); buttonPressMutex.lock(); buttonPressCount = presses; cv.notify_one(); buttonPressMutex.unlock(); } } bool waitPressCondition(Kernel::Clock::time_point timeout) { // buttonPressCount is 0 if we have already read the current value while(buttonPressCount == 0) { if(cv.wait_until(timeout) == cv_status::timeout) { return false; } } return true; } // returns presses or -1 on timeout int waitForPresses(std::chrono::milliseconds wait_time) { Kernel::Clock::time_point timeout = Kernel::Clock::now() + wait_time; int presses = -1; buttonPressMutex.lock(); if(waitPressCondition(timeout)) { presses = buttonPressCount; buttonPressCount = 0; } buttonPressMutex.unlock(); return presses; }