LEDs: unify common app-logic behavior into functions
In the entire code base, we basically use 4 LED scenarios: - all off - active slot green on - active slot green blinking - active slot red blinking Compacting this behaviour into 4 functions saves in total ~140B - which is huge. It's not an entirely clean solution, LEDs should not know anything about globals::ActiveSlot, but the savings are more important. Ideally, such an optimization could have been done by the compiler.main
parent
3aed994b9c
commit
b2dd038814
|
|
@ -212,7 +212,7 @@ void CommandBase::ErrDisengagingIdler() {
|
||||||
void CommandBase::GoToErrDisengagingIdler(ErrorCode deferredEC) {
|
void CommandBase::GoToErrDisengagingIdler(ErrorCode deferredEC) {
|
||||||
state = ProgressCode::ERRDisengagingIdler;
|
state = ProgressCode::ERRDisengagingIdler;
|
||||||
deferredErrorCode = deferredEC;
|
deferredErrorCode = deferredEC;
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::off, ml::blink0);
|
ml::leds.ActiveSlotError();
|
||||||
mi::idler.Disengage();
|
mi::idler.Disengage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ bool CutFilament::StepInner() {
|
||||||
// move selector aside - prepare the blade into active position
|
// move selector aside - prepare the blade into active position
|
||||||
state = ProgressCode::PreparingBlade;
|
state = ProgressCode::PreparingBlade;
|
||||||
mg::globals.SetFilamentLoaded(cutSlot, mg::FilamentLoadState::AtPulley);
|
mg::globals.SetFilamentLoaded(cutSlot, mg::FilamentLoadState::AtPulley);
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
ml::leds.ActiveSlotProcessing();
|
||||||
MoveSelector(cutSlot + 1);
|
MoveSelector(cutSlot + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +134,7 @@ bool CutFilament::StepInner() {
|
||||||
case ProgressCode::ReturningSelector:
|
case ProgressCode::ReturningSelector:
|
||||||
if (ms::selector.State() == ms::selector.Ready) {
|
if (ms::selector.State() == ms::selector.Ready) {
|
||||||
FinishedOK();
|
FinishedOK();
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::on, ml::off);
|
ml::leds.ActiveSlotDonePrimed();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProgressCode::OK:
|
case ProgressCode::OK:
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ void FeedToBondtech::Reset(uint8_t maxRetries) {
|
||||||
dbg_logic_P(PSTR("\nFeed to Bondtech\n\n"));
|
dbg_logic_P(PSTR("\nFeed to Bondtech\n\n"));
|
||||||
state = EngagingIdler;
|
state = EngagingIdler;
|
||||||
this->maxRetries = maxRetries;
|
this->maxRetries = maxRetries;
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
ml::leds.ActiveSlotProcessing();
|
||||||
mi::idler.Engage(mg::globals.ActiveSlot());
|
mi::idler.Engage(mg::globals.ActiveSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ bool FeedToBondtech::Step() {
|
||||||
dbg_logic_P(PSTR("Feed to Bondtech --> Idler disengaged"));
|
dbg_logic_P(PSTR("Feed to Bondtech --> Idler disengaged"));
|
||||||
dbg_logic_fP(PSTR("Pulley end steps %u"), mpu::pulley.CurrentPosition_mm());
|
dbg_logic_fP(PSTR("Pulley end steps %u"), mpu::pulley.CurrentPosition_mm());
|
||||||
state = OK;
|
state = OK;
|
||||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::on);
|
ml::leds.ActiveSlotDonePrimed();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case OK:
|
case OK:
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ bool FeedToFinda::Reset(bool feedPhaseLimited, bool haltAtEnd) {
|
||||||
state = EngagingIdler;
|
state = EngagingIdler;
|
||||||
this->feedPhaseLimited = feedPhaseLimited;
|
this->feedPhaseLimited = feedPhaseLimited;
|
||||||
this->haltAtEnd = haltAtEnd;
|
this->haltAtEnd = haltAtEnd;
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
ml::leds.ActiveSlotProcessing();
|
||||||
if (ms::selector.MoveToSlot(mg::globals.ActiveSlot()) != ms::Selector::OperationResult::Accepted) {
|
if (ms::selector.MoveToSlot(mg::globals.ActiveSlot()) != ms::Selector::OperationResult::Accepted) {
|
||||||
// We can't get any FINDA readings if the selector is at the wrong spot - move it accordingly if necessary
|
// We can't get any FINDA readings if the selector is at the wrong spot - move it accordingly if necessary
|
||||||
// And prevent issuing any commands to the idler in such an error state
|
// And prevent issuing any commands to the idler in such an error state
|
||||||
|
|
@ -68,7 +68,7 @@ bool FeedToFinda::Step() {
|
||||||
return true; // return immediately to allow for a seamless planning of another move (like feeding to bondtech)
|
return true; // return immediately to allow for a seamless planning of another move (like feeding to bondtech)
|
||||||
} else if (mm::motion.QueueEmpty()) { // all moves have been finished and FINDA didn't switch on
|
} else if (mm::motion.QueueEmpty()) { // all moves have been finished and FINDA didn't switch on
|
||||||
state = Failed;
|
state = Failed;
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::off, ml::blink0);
|
ml::leds.ActiveSlotError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,6 @@ void logic::LoadFilament::Reset2(bool feedPhaseLimited) {
|
||||||
if (!feed.Reset(feedPhaseLimited, true)) {
|
if (!feed.Reset(feedPhaseLimited, true)) {
|
||||||
// selector refused to move
|
// selector refused to move
|
||||||
GoToErrDisengagingIdler(ErrorCode::FINDA_FLICKERS);
|
GoToErrDisengagingIdler(ErrorCode::FINDA_FLICKERS);
|
||||||
} else {
|
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace logic {
|
||||||
void RetractFromFinda::Reset() {
|
void RetractFromFinda::Reset() {
|
||||||
dbg_logic_P(PSTR("\nRetract from FINDA\n\n"));
|
dbg_logic_P(PSTR("\nRetract from FINDA\n\n"));
|
||||||
state = EngagingIdler;
|
state = EngagingIdler;
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
ml::leds.ActiveSlotProcessing();
|
||||||
mi::idler.Engage(mg::globals.ActiveSlot());
|
mi::idler.Engage(mg::globals.ActiveSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,10 +33,10 @@ bool RetractFromFinda::Step() {
|
||||||
state = OK;
|
state = OK;
|
||||||
mg::globals.SetFilamentLoaded(mg::globals.ActiveSlot(), mg::FilamentLoadState::AtPulley);
|
mg::globals.SetFilamentLoaded(mg::globals.ActiveSlot(), mg::FilamentLoadState::AtPulley);
|
||||||
dbg_logic_fP(PSTR("Pulley end steps %u"), mpu::pulley.CurrentPosition_mm());
|
dbg_logic_fP(PSTR("Pulley end steps %u"), mpu::pulley.CurrentPosition_mm());
|
||||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
ml::leds.ActiveSlotDoneEmpty();
|
||||||
} else { // FINDA didn't switch off
|
} else { // FINDA didn't switch off
|
||||||
state = Failed;
|
state = Failed;
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::off, ml::blink0);
|
ml::leds.ActiveSlotError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -54,20 +54,19 @@ bool ToolChange::Reset(uint8_t param) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void logic::ToolChange::GoToFeedingToBondtech() {
|
void ToolChange::GoToFeedingToBondtech() {
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
|
||||||
james.Reset(3);
|
james.Reset(3);
|
||||||
state = ProgressCode::FeedingToBondtech;
|
state = ProgressCode::FeedingToBondtech;
|
||||||
error = ErrorCode::RUNNING;
|
error = ErrorCode::RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void logic::ToolChange::ToolChangeFinishedCorrectly() {
|
void ToolChange::ToolChangeFinishedCorrectly() {
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::on, ml::off);
|
ml::leds.ActiveSlotDonePrimed();
|
||||||
mui::userInput.SetPrinterInCharge(false);
|
mui::userInput.SetPrinterInCharge(false);
|
||||||
FinishedOK();
|
FinishedOK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void logic::ToolChange::GoToFeedingToFinda() {
|
void ToolChange::GoToFeedingToFinda() {
|
||||||
state = ProgressCode::FeedingToFinda;
|
state = ProgressCode::FeedingToFinda;
|
||||||
error = ErrorCode::RUNNING;
|
error = ErrorCode::RUNNING;
|
||||||
mg::globals.SetFilamentLoaded(plannedSlot, mg::FilamentLoadState::AtPulley);
|
mg::globals.SetFilamentLoaded(plannedSlot, mg::FilamentLoadState::AtPulley);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ void UnloadToFinda::Reset(uint8_t maxTries) {
|
||||||
state = EngagingIdler;
|
state = EngagingIdler;
|
||||||
mi::idler.PartiallyDisengage(mg::globals.ActiveSlot()); // basically prepare before the active slot - saves ~1s
|
mi::idler.PartiallyDisengage(mg::globals.ActiveSlot()); // basically prepare before the active slot - saves ~1s
|
||||||
started_ms = mt::timebase.Millis();
|
started_ms = mt::timebase.Millis();
|
||||||
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
ml::leds.ActiveSlotProcessing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,12 +77,12 @@ bool UnloadToFinda::Step() {
|
||||||
// This scenario should not be tried again - repeating it may cause more damage to filament + potentially more collateral damage
|
// This scenario should not be tried again - repeating it may cause more damage to filament + potentially more collateral damage
|
||||||
state = FailedFSensor;
|
state = FailedFSensor;
|
||||||
mm::motion.AbortPlannedMoves(); // stop rotating the pulley
|
mm::motion.AbortPlannedMoves(); // stop rotating the pulley
|
||||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
ml::leds.ActiveSlotDoneEmpty();
|
||||||
} else if (!mf::finda.Pressed()) {
|
} else if (!mf::finda.Pressed()) {
|
||||||
// detected end of filament
|
// detected end of filament
|
||||||
state = OK;
|
state = OK;
|
||||||
mm::motion.AbortPlannedMoves(); // stop rotating the pulley
|
mm::motion.AbortPlannedMoves(); // stop rotating the pulley
|
||||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
ml::leds.ActiveSlotDoneEmpty();
|
||||||
} else if (/*tmc2130_read_gstat() &&*/ mm::motion.QueueEmpty()) {
|
} else if (/*tmc2130_read_gstat() &&*/ mm::motion.QueueEmpty()) {
|
||||||
// we reached the end of move queue, but the FINDA didn't switch off
|
// we reached the end of move queue, but the FINDA didn't switch off
|
||||||
// two possible causes - grinded filament or malfunctioning FINDA
|
// two possible causes - grinded filament or malfunctioning FINDA
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ static void setup2() {
|
||||||
|
|
||||||
// activate the correct LED if filament is present
|
// activate the correct LED if filament is present
|
||||||
if (mg::globals.FilamentLoaded() > mg::FilamentLoadState::AtPulley) {
|
if (mg::globals.FilamentLoaded() > mg::FilamentLoadState::AtPulley) {
|
||||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::on);
|
ml::leds.ActiveSlotDonePrimed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "leds.h"
|
#include "leds.h"
|
||||||
#include "../hal/shr16.h"
|
#include "../hal/shr16.h"
|
||||||
#include "timebase.h"
|
#include "timebase.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
namespace modules {
|
namespace modules {
|
||||||
namespace leds {
|
namespace leds {
|
||||||
|
|
@ -68,5 +69,21 @@ void LEDs::SetAllOff() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LEDs::ActiveSlotProcessing() {
|
||||||
|
SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDs::ActiveSlotError() {
|
||||||
|
SetPairButOffOthers(mg::globals.ActiveSlot(), ml::off, ml::blink0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDs::ActiveSlotDoneEmpty() {
|
||||||
|
SetPairButOffOthers(mg::globals.ActiveSlot(), ml::off, ml::off);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LEDs::ActiveSlotDonePrimed() {
|
||||||
|
SetPairButOffOthers(mg::globals.ActiveSlot(), ml::on, ml::off);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace leds
|
} // namespace leds
|
||||||
} // namespace modules
|
} // namespace modules
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,14 @@ public:
|
||||||
/// Turn off all LEDs
|
/// Turn off all LEDs
|
||||||
void SetAllOff();
|
void SetAllOff();
|
||||||
|
|
||||||
|
/// Convenience functions - provide uniform implementation of LED behaviour through all the logic commands.
|
||||||
|
/// Intentionally not inlined to save quite some space (140B)
|
||||||
|
/// It's not a clean solution, LEDs should not know about mg::globals.ActiveSlot(), but the savings are important
|
||||||
|
void ActiveSlotProcessing();
|
||||||
|
void ActiveSlotError();
|
||||||
|
void ActiveSlotDoneEmpty();
|
||||||
|
void ActiveSlotDonePrimed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr static const uint8_t ledPairs = config::toolCount;
|
constexpr static const uint8_t ledPairs = config::toolCount;
|
||||||
/// pairs of LEDs:
|
/// pairs of LEDs:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
# define the test executable
|
# define the test executable
|
||||||
add_executable(
|
add_executable(
|
||||||
leds_tests ${CMAKE_SOURCE_DIR}/src/modules/leds.cpp ${MODULES_STUBS_DIR}/stub_shr16.cpp
|
leds_tests
|
||||||
${MODULES_STUBS_DIR}/stub_timebase.cpp test_leds.cpp
|
${CMAKE_SOURCE_DIR}/src/modules/leds.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/src/modules/globals.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/src/modules/permanent_storage.cpp
|
||||||
|
${MODULES_STUBS_DIR}/stub_shr16.cpp
|
||||||
|
${MODULES_STUBS_DIR}/stub_timebase.cpp
|
||||||
|
${MODULES_STUBS_DIR}/stub_eeprom.cpp
|
||||||
|
test_leds.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# define required search paths
|
# define required search paths
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue