From 85910497f7248d4eb8cb59d1f0bc12ea29fcec61 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Fri, 18 Jun 2021 07:27:43 +0200 Subject: [PATCH] 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) --- src/logic/feed_to_finda.cpp | 7 ++++-- src/modules/buttons.cpp | 13 ++++------ src/modules/buttons.h | 12 ++++----- tests/unit/logic/stubs/main_loop_stub.cpp | 12 ++++----- tests/unit/modules/buttons/test_buttons.cpp | 28 +++++++++++---------- 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/logic/feed_to_finda.cpp b/src/logic/feed_to_finda.cpp index ffa73a2..2634930 100644 --- a/src/logic/feed_to_finda.cpp +++ b/src/logic/feed_to_finda.cpp @@ -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 diff --git a/src/modules/buttons.cpp b/src/modules/buttons.cpp index 923a6a4..c9d6308 100644 --- a/src/modules/buttons.cpp +++ b/src/modules/buttons.cpp @@ -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); } } diff --git a/src/modules/buttons.h b/src/modules/buttons.h index 15a5bd5..5db2a1d 100644 --- a/src/modules/buttons.h +++ b/src/modules/buttons.h @@ -1,7 +1,6 @@ #pragma once #include -#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; diff --git a/tests/unit/logic/stubs/main_loop_stub.cpp b/tests/unit/logic/stubs/main_loop_stub.cpp index cc56a14..663250c 100644 --- a/tests/unit/logic/stubs/main_loop_stub.cpp +++ b/tests/unit/logic/stubs/main_loop_stub.cpp @@ -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() { diff --git a/tests/unit/modules/buttons/test_buttons.cpp b/tests/unit/modules/buttons/test_buttons.cpp index b2daa00..aa4a1fd 100644 --- a/tests/unit/modules/buttons/test_buttons.cpp +++ b/tests/unit/modules/buttons/test_buttons.cpp @@ -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));