Prusa-Firmware-MMU/src/modules/leds.h

159 lines
4.9 KiB
C++

/// @file leds.h
#pragma once
#include "../config/config.h"
#include <stdint.h>
namespace modules {
/// @brief The leds namespace provides all necessary facilities related to the logical model of the sets of LEDs on the MMU unit.
///
/// We have 5 pairs of LEDs. In each pair there is a green and a red LED.
///
/// A typical scenario in the past was visualization of error states.
/// The combination of colors with blinking frequency had a specific meaning.
///
/// The physical connection is not important on this level (i.e. how and what shall be sent into the shift registers).
///
/// LEDS are physically connected to a pair of shift registers along with some other signals.
/// The physical write operations are handled by hal::shr16.
namespace leds {
/// Enum of LED modes
/// blink0 and blink1 allow for interlaced blinking of LEDs (one is on and the other off)
enum Mode : uint8_t {
off,
on,
blink0, ///< start blinking at even periods
blink1 ///< start blinking at odd periods
};
/// Enum of LEDs color - green or red
enum Color : uint8_t {
red = 0,
green = 1
};
/// A single LED
class LED {
public:
constexpr inline LED() = default;
/// Sets the mode of the LED
/// @param mode to set
void SetMode(leds::Mode mode);
/// @returns the currently active mode of the LED
inline leds::Mode Mode() const { return (leds::Mode)state.mode; }
/// @returns true if the LED shines
/// @param oddPeriod LEDs class operates this parameter based on blinking period based on elapsed real time
bool Step(bool oddPeriod);
/// @returns true if the LED shines
inline bool On() const { return state.on; }
private:
struct State {
uint8_t on : 1;
uint8_t mode : 2;
constexpr inline State()
: on(0)
, mode(leds::Mode::off) {}
};
State state;
};
/// The main LEDs API takes care of the whole set of LEDs
class LEDs {
public:
constexpr inline LEDs() = default;
/// step LED automaton
void Step();
/// @returns the number of LED pairs
inline constexpr uint8_t LedPairsCount() const { return ledPairs; }
/// Sets the mode of a LED in a pair
/// @param slot index of filament slot (index of the LED pair)
/// @param color green or red LED
/// @param mode to set
inline void SetMode(uint8_t slot, Color color, Mode mode) {
SetMode(slot * 2 + color, mode);
}
/// Sets the mode of a LED in a pair
/// @param index - raw index of the LED in the internal leds array
/// @param mode to set
inline void SetMode(uint8_t index, Mode mode) {
leds[index].SetMode(mode);
}
/// @returns the currently active mode of a LED in a pair
/// @param slot index of filament slot (index of the LED pair)
/// @param color green or red LED
inline leds::Mode Mode(uint8_t slot, Color color) {
return Mode(slot * 2 + color);
}
/// @returns the currently active mode of a LED
/// @param index - raw index of the LED in the internal leds array
inline leds::Mode Mode(uint8_t index) {
return leds[index].Mode();
}
/// @returns true if a LED is shining
/// @param index - raw index of the LED in the internal leds array
inline bool LedOn(uint8_t index) const {
return leds[index].On();
}
/// @returns true if a LED is shining
/// @param slot index of filament slot (index of the LED pair)
/// @param color green or red LED
inline bool LedOn(uint8_t slot, Color color) const {
return leds[slot * 2 + color].On();
}
/// Sets active slot LEDs to some mode and turns off all the others
void SetPairButOffOthers(uint8_t activeSlot, modules::leds::Mode greenMode, modules::leds::Mode redMode);
/// Turn off all LEDs
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:
constexpr static const uint8_t ledPairs = config::toolCount;
/// pairs of LEDs:
/// [0] - green LED slot 0
/// [1] - red LED slot 0
/// [2] - green LED slot 1
/// [3] - red LED slot 1
/// [4] - green LED slot 2
/// [5] - red LED slot 2
/// [6] - green LED slot 3
/// [7] - red LED slot 3
/// [8] - green LED slot 4
/// [9] - red LED slot 4
LED leds[ledPairs * 2];
/// Cache for avoiding duplicit writes into the shift registers (may reduce LED flickering on some boards)
uint16_t cachedState = 0;
};
/// The one and only instance of FINDA in the FW
extern LEDs leds;
} // namespace LEDs
} // namespace modules
namespace ml = modules::leds;