Newer
Older
Tardis / src / ButtonThread.cpp
@Jookia Jookia on 19 Mar 2023 1 KB Initial commit
#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;
}