Files
SigLed/src/SigLed.cpp
2025-03-10 18:31:21 +01:00

132 lines
2.5 KiB
C++

// Obsluha LED signalizace
#include "SigLed.h"
#include <Arduino.h>
#include <CriticalSection.hpp>
SigLED::SigLED(int pin, int ledon, int ledoff)
: _pin(pin), _ledon(ledon), _ledoff(ledoff), _state(LS_NOTINITIALIZED)
{}
uint8_t SigLED::getInstruction()
{
uint8_t instr;
if (_signal)
instr = *_ptr; // instrukce
else if (_psignal)
instr = pgm_read_byte(_pptr);
else
instr = LEDS_STOP;
return instr;
}
void SigLED::rtLed()
{
switch (_state) {
case LS_WAIT:
--_timer;
if (_timer != 0)
break;
_state = LS_RUN;
++_ptr;
++_pptr;
[[fallthrough]]; // no break - we fall through LS_RUN state
case LS_RUN: {
uint8_t instr = getInstruction();
if ((instr & 0xc0) == LEDS_RESTART) {
_ptr = _signal;
_pptr = _psignal;
instr = getInstruction();
}
switch (instr & 0xc0) {
case LEDS_ONFOR:
digitalWrite(_pin, _ledon);
_timer = (instr & 0x3F) + 1;
_state = LS_WAIT;
break;
case LEDS_OFFFOR:
digitalWrite(_pin, _ledoff);
_timer = (instr & 0x3F) + 1;
_state = LS_WAIT;
break;
case LEDS_STOP:
_state = LS_IDLE;
break;
}
} break;
default:
break;
}
}
void SigLED::prepare()
{
pinMode(_pin, OUTPUT);
digitalWrite(_pin, _ledoff);
_state = LS_IDLE;
_handler.attach_ms(100, lh, this);
}
void SigLED::set(const uint8_t * signal)
{
if (LS_NOTINITIALIZED == _state)
prepare();
CriticalSection cs;
_signal = signal;
_ptr = _signal;
_psignal = nullptr;
_state = LS_RUN;
}
void SigLED::set_P(PGM_P signal)
{
if (LS_NOTINITIALIZED == _state)
prepare();
CriticalSection cs;
_psignal = signal;
_pptr = _psignal;
_signal = nullptr;
_state = LS_RUN;
}
void SigLED::setup()
{
if (LS_NOTINITIALIZED == _state)
prepare();
CriticalSection cs;
_ptr = _signal;
_pptr = _psignal;
_state = LS_RUN;
}
void SigLED::lh(SigLED * ptr)
{
SigLED * pled = ptr;
pled->rtLed();
}
void SigLED::setInvert(bool invert)
{
if (_invert != invert) {
_invert = invert;
int temp = _ledon;
_ledon = _ledoff;
_ledoff = temp;
}
}