mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-04-28 03:08:08 +00:00
147 lines
5.6 KiB
Markdown
147 lines
5.6 KiB
Markdown
# Режимы IR TX в библиотеке
|
||
|
||
Этот документ описывает, как в библиотеке выбирается путь передачи IR и как его правильно использовать в проектах Arduino STM32.
|
||
|
||
## Кратко
|
||
|
||
У библиотеки есть три варианта TX:
|
||
|
||
- `legacy ISR` — внутренний ISR-путь без внешнего backend. Это путь по умолчанию для обратной совместимости.
|
||
- `buffered ISR` — внутренний ISR-путь с предварительной подготовкой BSRR-слов и кольцевым буфером.
|
||
- `external backend` — передача делегируется проекту через `IR_Encoder::setExternalTxBackend(...)`, например в DMA backend.
|
||
|
||
Порядок выбора такой:
|
||
|
||
1. Если зарегистрирован `external backend`, используется он.
|
||
2. Иначе используется внутренний ISR библиотеки.
|
||
3. Для внутреннего ISR:
|
||
- по умолчанию включён `legacy ISR`
|
||
- `buffered ISR` включается явно: нужно привязать storage к encoder и переключить режим
|
||
|
||
## 1. Legacy ISR
|
||
|
||
Это режим по умолчанию. Старые проекты могут ничего не менять:
|
||
|
||
```cpp
|
||
static HardwareTimer timer(TIM11);
|
||
static IR_Encoder enc(PA9, 42, &dec);
|
||
|
||
void setup() {
|
||
IR_Encoder::begin(&timer, 1, TIM11_IRQn, 0);
|
||
enc.enable();
|
||
}
|
||
```
|
||
|
||
Если проект не регистрирует внешний backend и не переключает режим явно, библиотека работает в `legacy ISR`.
|
||
|
||
Для явного выбора можно написать:
|
||
|
||
```cpp
|
||
IR_Encoder::setTxIsrLegacyMode(true);
|
||
IR_Encoder::begin(&timer, 1, TIM11_IRQn, 0);
|
||
```
|
||
|
||
## 2. Buffered ISR
|
||
|
||
Этот режим использует внутренний буферный ISR-путь библиотеки. Он включается только явно:
|
||
|
||
```cpp
|
||
#include <IrTxIsrBufferedStorage.h>
|
||
|
||
static IrTxIsrBufferedStorage<> txStorage;
|
||
|
||
enc.enableBufferedIsr(txStorage);
|
||
IR_Encoder::begin(&timer, 1, TIM11_IRQn, 0);
|
||
```
|
||
|
||
Нижнеуровневый вариант API — отдельно привязать storage через `attachBufferedIsrStorage(...)`, но в обычном проекте удобнее использовать `enableBufferedIsr(...)`.
|
||
|
||
Смысл режима:
|
||
|
||
- пакет сначала превращается в `gate runs`
|
||
- затем в поток слов `GPIO->BSRR`
|
||
- ISR выдаёт готовые слова из кольцевого буфера
|
||
|
||
### Важно про RAM
|
||
|
||
В текущей реализации память под буферный ISR вынесена из `IR_Encoder` в отдельный storage-объект.
|
||
|
||
То есть:
|
||
|
||
- `legacy ISR` не тянет buffered-буферы в RAM самого `IR_Encoder`
|
||
- память под `gate runs` и `BSRR words` появляется только там, где проект сам создал `IrTxIsrBufferedStorage<>`
|
||
|
||
Это важно для STM32 с небольшим объёмом RAM, например для `STM32F401`.
|
||
|
||
## 3. External backend
|
||
|
||
Если проект хочет полностью взять TX на себя, библиотека позволяет зарегистрировать внешний backend:
|
||
|
||
```cpp
|
||
static bool txBusy(void* ctx);
|
||
static bool txStart(void* ctx, IR_Encoder* enc, const uint8_t* packet, uint8_t len);
|
||
|
||
void setup() {
|
||
IR_Encoder::beginClockOnly(&timer);
|
||
IR_Encoder::setExternalTxBackend(txStart, txBusy, nullptr);
|
||
enc.enable();
|
||
}
|
||
```
|
||
|
||
После вызова `setExternalTxBackend(...)` библиотека больше не использует свои внутренние ISR-пути для фактической передачи.
|
||
|
||
В этом режиме:
|
||
|
||
- `setTxIsrLegacyMode(true/false)` игнорируется
|
||
- завершение передачи должен сигнализировать сам backend через `enc->externalFinishSend()`
|
||
|
||
Подробности по встроенному DMA backend для `STM32G4xx`: см. [IR_DMA_TX_backend.md](IR_DMA_TX_backend.md).
|
||
|
||
## Когда какой режим использовать
|
||
|
||
### Старый проект, который ничего не настраивает
|
||
|
||
Использовать как есть:
|
||
|
||
```cpp
|
||
IR_Encoder::begin(...);
|
||
```
|
||
|
||
Итог: `legacy ISR`
|
||
|
||
### Нужен новый внутренний буферный ISR
|
||
|
||
Включить явно:
|
||
|
||
```cpp
|
||
#include <IrTxIsrBufferedStorage.h>
|
||
|
||
static IrTxIsrBufferedStorage<> txStorage;
|
||
|
||
enc.enableBufferedIsr(txStorage);
|
||
IR_Encoder::begin(...);
|
||
```
|
||
|
||
Итог: `buffered ISR`
|
||
|
||
### Нужен проектный DMA или другой свой транспорт
|
||
|
||
Подключить внешний backend:
|
||
|
||
```cpp
|
||
IR_Encoder::beginClockOnly(...);
|
||
IR_Encoder::setExternalTxBackend(...);
|
||
```
|
||
|
||
Итог: `external backend`
|
||
|
||
## Рекомендация для совместимости
|
||
|
||
Для старых проектов безопаснее не вызывать `setTxIsrLegacyMode(false)`, если нет явной причины переходить на buffered ISR.
|
||
|
||
Если задача — сохранить старое поведение без неожиданного роста нагрузки на TX-логику, оставляйте default `legacy ISR` или задавайте его явно:
|
||
|
||
```cpp
|
||
IR_Encoder::setTxIsrLegacyMode(true);
|
||
```
|