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