mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-04-28 03:08:08 +00:00
Add documentation for IR TX modes in the library
This commit is contained in:
146
ref/IR_TX_MODES.md
Normal file
146
ref/IR_TX_MODES.md
Normal file
@ -0,0 +1,146 @@
|
||||
# Режимы 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);
|
||||
```
|
||||
Reference in New Issue
Block a user