Prusa-Firmware-MMU/src/modules/buttons.cpp

75 lines
1.7 KiB
C++

#include "buttons.h"
#include "../hal/adc.h"
namespace modules {
uint16_t Buttons::tmpTiming = 0;
// original idea from: https://www.eeweb.com/debouncing-push-buttons-using-a-state-machine-approach
void Button::Step(uint16_t time, bool press) {
switch (state) {
case State::Waiting:
if (press) {
state = State::Detected;
timeLastChange = time;
tmp = press;
}
break;
case State::Detected:
if (tmp == press) {
if (time - timeLastChange > debounce) {
state = State::WaitForRelease;
}
} else {
state = State::Waiting;
}
break;
case State::WaitForRelease:
if (!press) {
state = State::Update;
}
break;
case State::Update:
pressed = tmp;
state = State::Waiting;
timeLastChange = time;
tmp = false;
break;
default:
state = State::Waiting;
timeLastChange = time;
tmp = false;
pressed = false;
}
}
int8_t Buttons::Sample() {
// decode 3 buttons' levels from one ADC
uint16_t raw = hal::ADC::ReadADC(0);
// Button 1 - 0
// Button 2 - 344
// Button 3 - 516
// Doesn't handle multiple pressed buttons at once
if (raw < 10)
return 0;
else if (raw > 320 && raw < 360)
return 1;
else if (raw > 500 && raw < 530)
return 2;
return -1;
}
void Buttons::Step() {
// @@TODO temporary timing
++tmpTiming;
int8_t currentState = Sample();
for (uint_fast8_t b = 0; b < N; ++b) {
// this button was pressed if b == currentState, released otherwise
buttons[b].Step(tmpTiming, b == currentState);
}
}
} // namespace modules