132 lines
2.5 KiB
C++
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;
|
|
}
|
|
} |