mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-04-28 03:08:08 +00:00
88 lines
2.4 KiB
C++
88 lines
2.4 KiB
C++
#pragma once
|
||
|
||
#include "IrTxGateTypes.h"
|
||
#include <cstddef>
|
||
#include <cstdint>
|
||
|
||
#if defined(__GNUC__)
|
||
#define IR_TX_BSRR_WAVE_HOT __attribute__((always_inline)) inline
|
||
#else
|
||
#define IR_TX_BSRR_WAVE_HOT inline
|
||
#endif
|
||
|
||
/**
|
||
* Генерация потока 32-бит слов для GPIO BSRR из RLE-сегментов IrTxGateRun.
|
||
* За один период несущей — multiply физических тиков; при gate — powerN из них HIGH (N ≤ multiply/2).
|
||
*/
|
||
class IrTxBsrrWave {
|
||
public:
|
||
void configure(uint32_t setW, uint32_t resetW, IrTxGateRun* r, size_t n, uint16_t multiply, uint16_t powerN) {
|
||
setWord = setW;
|
||
resetWord = resetW;
|
||
runs = r;
|
||
runCount = n;
|
||
multiply_ = multiply < 2 ? 2 : multiply;
|
||
const uint16_t cap = static_cast<uint16_t>(multiply_ / 2U);
|
||
powerN_ = (powerN > cap) ? cap : powerN;
|
||
resetWave();
|
||
}
|
||
|
||
void resetWave() {
|
||
runIndex_ = 0;
|
||
slotInPeriod_ = 0;
|
||
ticksLeftInRun_ = 0;
|
||
if (runCount > 0U && runs != nullptr) {
|
||
ticksLeftInRun_ = runs[0].lenTicks;
|
||
}
|
||
}
|
||
|
||
IR_TX_BSRR_WAVE_HOT uint32_t nextWord() {
|
||
if (runIndex_ >= runCount) {
|
||
return resetWord;
|
||
}
|
||
const bool gate = runs[runIndex_].gate;
|
||
uint32_t out;
|
||
if (!gate) {
|
||
slotInPeriod_ = 0;
|
||
out = resetWord;
|
||
} else {
|
||
out = (slotInPeriod_ < powerN_) ? setWord : resetWord;
|
||
slotInPeriod_++;
|
||
if (slotInPeriod_ >= multiply_) {
|
||
slotInPeriod_ = 0;
|
||
}
|
||
}
|
||
|
||
if (ticksLeftInRun_ > 0) {
|
||
ticksLeftInRun_--;
|
||
}
|
||
if (ticksLeftInRun_ == 0) {
|
||
runIndex_++;
|
||
if (runIndex_ < runCount) {
|
||
ticksLeftInRun_ = runs[runIndex_].lenTicks;
|
||
}
|
||
}
|
||
return out;
|
||
}
|
||
|
||
IR_TX_BSRR_WAVE_HOT void fill(uint32_t* dst, uint16_t count) {
|
||
if (dst == nullptr || count == 0) {
|
||
return;
|
||
}
|
||
do {
|
||
*dst++ = nextWord();
|
||
} while (--count != 0);
|
||
}
|
||
|
||
private:
|
||
uint32_t setWord = 0;
|
||
uint32_t resetWord = 0;
|
||
IrTxGateRun* runs = nullptr;
|
||
size_t runCount = 0;
|
||
uint16_t multiply_ = 2;
|
||
uint16_t powerN_ = 1;
|
||
size_t runIndex_ = 0;
|
||
uint16_t ticksLeftInRun_ = 0;
|
||
uint16_t slotInPeriod_ = 0;
|
||
};
|