add brightness controll

This commit is contained in:
2026-04-17 09:45:32 +03:00
parent 8daff9c46a
commit d788358ac8
8 changed files with 426 additions and 70 deletions

View File

@ -1,6 +1,7 @@
#pragma once
#include "IR_Encoder.h"
#include "IrTxBsrrWave.h"
#if defined(ARDUINO_ARCH_STM32) && defined(STM32G4xx)
@ -16,7 +17,7 @@
#include "stm32g4xx_hal.h"
/**
* STM32G4: ИК TX через DMA в GPIO BSRR, такт от TIM UPDATE (carrierFrec×2).
* STM32G4: ИК TX через DMA в GPIO BSRR, такт от TIM UPDATE (carrierFrec × IR_Encoder::carrierMultiply()).
*
* Число слотов потоков — параметр шаблона (без макросов), например IrDmaTxStm32<2>.
* По умолчанию: IrDmaTxStm32<> ≡ irproto::kDefaultDmaTxMaxStreams (см. IR_config.h).
@ -37,7 +38,7 @@ public:
uint32_t* dmaWords = nullptr;
uint16_t dmaWordCount = 0;
IR_Encoder::IR_TxGateRun* gateRuns = nullptr;
IrTxGateRun* gateRuns = nullptr;
size_t maxGateRuns = 0;
};
@ -134,13 +135,11 @@ private:
uint16_t bufLen = 0;
uint16_t halfLen = 0;
IR_Encoder::IR_TxGateRun* runs = nullptr;
IrTxGateRun* runs = nullptr;
size_t maxRuns = 0;
size_t runCount = 0;
size_t runIndex = 0;
uint16_t ticksLeftInRun = 0;
bool carrierPhase = false;
IrTxBsrrWave wave{};
uint32_t totalTicks = 0;
volatile uint32_t ticksOutput = 0;
@ -148,45 +147,14 @@ private:
bool active = false;
void resetWave() {
runIndex = 0;
carrierPhase = false;
wave.configure(setWord, resetWord, nullptr, 0, 2, 1);
ticksOutput = 0;
totalTicks = 0;
runCount = 0;
ticksLeftInRun = 0;
}
IR_DMA_TX_HOT uint32_t nextWord() {
if (runIndex >= runCount) {
return resetWord;
}
const bool gate = runs[runIndex].gate;
if (!gate) {
carrierPhase = false;
} else {
carrierPhase = !carrierPhase;
}
const uint32_t out = (gate && carrierPhase) ? setWord : resetWord;
if (ticksLeftInRun > 0) {
ticksLeftInRun--;
}
if (ticksLeftInRun == 0) {
runIndex++;
if (runIndex < runCount) {
ticksLeftInRun = runs[runIndex].lenTicks;
}
}
return out;
}
IR_DMA_TX_HOT void fill(uint32_t* dst, uint16_t count) {
if (dst == nullptr || count == 0) {
return;
}
do {
*dst++ = nextWord();
} while (--count != 0);
wave.fill(dst, count);
}
void onHalf() {
@ -325,13 +293,25 @@ private:
s.runCount = IR_Encoder::buildGateRuns(packet, len, s.runs, s.maxRuns);
if (s.runCount == 0) return false;
size_t rc = s.runCount;
if (!IR_Encoder::scaleGateRunsToPhysical(s.runs, &rc, s.maxRuns, IR_Encoder::carrierMultiply())) {
return false;
}
s.runCount = rc;
uint32_t total = 0;
for (size_t i = 0; i < s.runCount; i++) total += s.runs[i].lenTicks;
s.totalTicks = total;
s.runIndex = 0;
s.ticksLeftInRun = s.runs[0].lenTicks;
s.carrierPhase = false;
const uint16_t mult = IR_Encoder::carrierMultiply();
uint16_t pwr = mult / 2U;
if (s.enc != nullptr) {
const uint16_t want = s.enc->powerNumerator();
const uint16_t cap = IR_Encoder::maxPowerNumerator();
pwr = (want > cap) ? cap : want;
}
s.wave.configure(s.setWord, s.resetWord, s.runs, s.runCount, mult, pwr);
s.fill(&s.dmaBuf[0], s.bufLen);