159 lines
4.9 KiB
C++
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;
|