Unify buttons' API with other modules

- accepts millis() instead of doing the timing internally (which has
been a temporary solution just for the tests until now)
pull/26/head
D.R.racer 2021-06-18 07:27:43 +02:00 committed by DRracer
parent b338949acb
commit 85910497f7
5 changed files with 37 additions and 35 deletions

View File

@ -35,8 +35,10 @@ bool FeedToFinda::Step() {
mm::motion.PlanMove(feedPhaseLimited ? 1500 : 32767, 0, 0, 4000, 0, 0); //@@TODO constants
}
return false;
case PushingFilament:
if (mf::finda.Pressed() || (feedPhaseLimited && mb::buttons.AnyButtonPressed())) { // @@TODO probably also a command from the printer
case PushingFilament: {
bool fp = mf::finda.Pressed();
bool abp = mb::buttons.AnyButtonPressed();
if (fp || (feedPhaseLimited && abp)) { // @@TODO probably also a command from the printer
mm::motion.AbortPlannedMoves(); // stop pushing filament
// FINDA triggered - that means it works and detected the filament tip
state = UnloadBackToPTFE;
@ -47,6 +49,7 @@ bool FeedToFinda::Step() {
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::green, ml::off);
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::red, ml::blink0);
}
}
return false;
case UnloadBackToPTFE:
if (mm::motion.QueueEmpty()) { // all moves have been finished

View File

@ -1,13 +1,12 @@
#include "buttons.h"
#include "../hal/adc.h"
namespace modules {
namespace buttons {
Buttons buttons;
uint16_t Buttons::tmpTiming = 0;
int8_t Buttons::Sample(uint16_t rawADC) {
int8_t Buttons::DecodeADC(uint16_t rawADC) {
// decode 3 buttons' levels from one ADC
// Button 1 - 0
// Button 2 - 344
@ -23,13 +22,11 @@ int8_t Buttons::Sample(uint16_t rawADC) {
return -1;
}
void Buttons::Step(uint16_t rawADC) {
// @@TODO temporary timing
++tmpTiming;
int8_t currentState = Sample(rawADC);
void Buttons::Step(uint16_t millis) {
int8_t currentState = DecodeADC(hal::adc::ReadADC(0));
for (uint_fast8_t b = 0; b < N; ++b) {
// this button was pressed if b == currentState, released otherwise
buttons[b].Step(tmpTiming, b == currentState);
buttons[b].Step(millis, b == currentState);
}
}

View File

@ -1,7 +1,6 @@
#pragma once
#include <stdint.h>
#include "../hal/adc.h"
#include "debouncer.h"
/// Buttons are built on top of the raw ADC API
@ -28,17 +27,18 @@ enum {
class Buttons {
constexpr static const uint8_t N = 3; ///< number of buttons currently supported
constexpr static const uint8_t adc = 1; ///< ADC index - will be some define or other constant later on
static uint16_t tmpTiming; ///< subject to removal when we have timers implemented - now used for the unit tests
public:
inline constexpr Buttons() = default;
/// State machine step - reads the ADC, processes debouncing, updates states of individual buttons
void Step(uint16_t rawADC);
void Step(uint16_t millis);
/// @return true if button at index is pressed
/// @returns true if button at index is pressed
/// @@TODO add range checking if necessary
inline bool ButtonPressed(uint8_t index) const { return buttons[index].Pressed(); }
/// @returns true if any of the button is pressed
inline bool AnyButtonPressed() const {
for (uint8_t i = 0; i < N; ++i) {
if (ButtonPressed(i))
@ -50,9 +50,9 @@ public:
private:
Button buttons[N];
/// Call to the ADC and decode its output into a button index
/// Decode ADC output into a button index
/// @returns index of the button pressed or -1 in case no button is pressed
static int8_t Sample(uint16_t rawADC);
static int8_t DecodeADC(uint16_t rawADC);
};
extern Buttons buttons;

View File

@ -17,19 +17,19 @@
logic::CommandBase *currentCommand = nullptr;
// just like in the real FW, step all the known automata
uint16_t tmpTiming = 0;
uint16_t millis = 0;
void main_loop() {
modules::buttons::buttons.Step(hal::adc::ReadADC(0));
modules::leds::leds.Step(tmpTiming);
modules::finda::finda.Step(tmpTiming);
modules::fsensor::fsensor.Step(tmpTiming);
modules::buttons::buttons.Step(millis);
modules::leds::leds.Step(millis);
modules::finda::finda.Step(millis);
modules::fsensor::fsensor.Step(millis);
modules::idler::idler.Step();
modules::selector::selector.Step();
modules::motion::motion.Step();
if (currentCommand)
currentCommand->Step();
++tmpTiming;
++millis;
}
void ForceReinitAllAutomata() {

View File

@ -4,21 +4,23 @@
using Catch::Matchers::Equals;
uint16_t millis = 0;
bool Step_Basic_One_Button_Test(modules::buttons::Buttons &b, uint8_t oversampleFactor, uint8_t testedButtonIndex, uint8_t otherButton1, uint8_t otherButton2) {
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // should detect the press but remain in detected state - wait for debounce
b.Step(++millis); // should detect the press but remain in detected state - wait for debounce
CHECK(!b.ButtonPressed(testedButtonIndex));
CHECK(!b.ButtonPressed(otherButton1));
CHECK(!b.ButtonPressed(otherButton2));
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // reset to waiting
b.Step(++millis); // reset to waiting
CHECK(b.ButtonPressed(testedButtonIndex));
CHECK(!b.ButtonPressed(otherButton1));
CHECK(!b.ButtonPressed(otherButton2));
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // pressed again, still in debouncing state
b.Step(++millis); // pressed again, still in debouncing state
CHECK(!b.ButtonPressed(testedButtonIndex));
CHECK(!b.ButtonPressed(otherButton1));
CHECK(!b.ButtonPressed(otherButton2));
@ -29,7 +31,7 @@ bool Step_Basic_One_Button_Test(modules::buttons::Buttons &b, uint8_t oversample
/// This test verifies the behaviour of a single button. The other buttons must remain intact.
bool Step_Basic_One_Button(hal::adc::TADCData &&d, uint8_t testedButtonIndex) {
using namespace modules::buttons;
millis = 0;
Buttons b;
// need to oversample the data as debouncing takes 100 cycles to accept a pressed button
@ -98,63 +100,63 @@ TEST_CASE("buttons::Step-debounce-one-button", "[buttons]") {
// 5
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // should detect the press but remain in detected state - wait for debounce
b.Step(++millis); // should detect the press but remain in detected state - wait for debounce
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 1023
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // reset to waiting
b.Step(++millis); // reset to waiting
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 5
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // pressed again, still in debouncing state
b.Step(++millis); // pressed again, still in debouncing state
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 9
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // no change
b.Step(++millis); // no change
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 6
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // no change
b.Step(++millis); // no change
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 7
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // one step from "pressed"
b.Step(++millis); // one step from "pressed"
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 8
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // fifth set of samples - should report "pressed" finally
b.Step(++millis); // fifth set of samples - should report "pressed" finally
CHECK(b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 1023
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // sixth set of samples - button released (no debouncing on release)
b.Step(++millis); // sixth set of samples - button released (no debouncing on release)
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));
// 1023
for (uint8_t i = 0; i < oversampleFactor; ++i)
b.Step(hal::adc::ReadADC(0)); // seventh set of samples - still released
b.Step(++millis); // seventh set of samples - still released
CHECK(!b.ButtonPressed(0));
CHECK(!b.ButtonPressed(1));
CHECK(!b.ButtonPressed(2));