#pragma once #include "IrTxGateTypes.h" #include #include #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(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; };