# LoRa генератор сигналів (TX/RX)

Цей workspace містить дві окремі прошивки ESP-IDF для ESP32 з LR1121 по SPI, I2C OLED та 5-позиційним джойстиком:
- `apps/tx` — передавач.
- `apps/rx` — приймач.

Спільні драйвери та утиліти лежать у `components/`.

## Структура
```
components/
  common/        # базова інформація про чип, роль
  input/         # джойстик через ADC (резистивний дільник)
  lora_radio/    # LR1121 (SPI, busy/dio1), налаштування пінів через Kconfig
  ui/            # I2C OLED (за замовчуванням SSD1306 128x64)
apps/
  tx/            # прошивка передавача + sdkconfig.defaults
  rx/            # прошивка приймача + sdkconfig.defaults
```

## Збірка
Вкажіть потрібний застосунок через `-C`, окремі build-директорії краще розділяти:
- Передавач: `idf.py -C apps/tx -B build-tx -DSDKCONFIG_DEFAULTS=sdkconfig.defaults build`
- Приймач: `idf.py -C apps/rx -B build-rx -DSDKCONFIG_DEFAULTS=sdkconfig.defaults build`

## Налаштування
- Піни LR1121 (SPI CS/MOSI/MISO/SCK, BUSY, DIO1, RST) та радіо-параметри налаштовуються в `apps/*/sdkconfig.defaults` (Kconfig у `components/lora_radio`). BUSY має бути підключений; дозволяється ставити `-1` на RST/DIO1 (немає лінії), але без RST складніше відновлюватись після зависань, без DIO1 — робота тільки через опитування статусу.
- Роль пристрою визначається `CONFIG_LORA_ROLE_TX` / `CONFIG_LORA_ROLE_RX` (див. `components/common/Kconfig`).
- OLED: виберіть I2C порт/адресу/пін `SDA/SCL/RST` та розмір дисплея через `components/ui/Kconfig` (дефолт — SSD1306 128x64, addr `0x3C`).
- Джойстик: один ADC канал з резистивним дільником на кожну кнопку. Вкажіть канал та очікувані рівні АЦП (`CONFIG_JOYSTICK_ADC_LEVEL_*`) і допуск (`CONFIG_JOYSTICK_ADC_TOLERANCE`).

## Екрани та керування (OLED + джойстик)
Джойстик: LEFT/RIGHT — перемикання екранів, UP/DOWN — змінити поточне значення, CENTER — підтвердити/оновити (або toggle на деяких екранах).

### RX
- `FREQ`: робоча частота (крок 1 МГц) у межах вибраного band. CENTER просто повторно застосовує параметри.
- `BAND`: вибір діапазону (430, 868, 915 МГц; L‑band 1.525–1.660 ГГц; S‑band 1.9–2.1 ГГц; 2.4 ГГц ISM 2400–2483.5 МГц). FREQ клампиться всередині band.
- `BANDW`: смуга (BW) 125/250/500 кГц.
- `SPREAD`: LoRa SF 5…12.
- `CODERATE`: LoRa CR 4/5…4/8.
- `PAYLOAD`: відображає останній прийнятий пакет (ASCII до 31 символа), нижче завжди показані метрики SNR/RSSI/статус.
- `BOOT`: перезавантаження в ROM bootloader (USB CDC/JTAG) для прошивки. CENTER запускає перезавантаження; підключіть USB і запускайте флешер.

### TX
- `FREQ`: робоча частота (крок 1 МГц) у межах вибраного band.
- `BAND`: діапазони як у RX (430/868/915/L/S/2.4G), FREQ клампиться всередині band.
- `BANDW`: смуга (BW) 125/250/500 кГц.
- `SPREAD`: LoRa SF 5…12.
- `CODERATE`: LoRa CR 4/5…4/8.
- `POWER`: вихідна потужність у dBm. Ліміт суб‑ГГц до +22 dBm, для HF (L/S/2.4 ГГц) до ~+13 dBm, мінімум −17 dBm.
- `PAYLOAD`: вибір фрази для передачі з готового списку `PING 1`…`PING 10` (UP/DOWN гортає).
- `PERIOD`: період автопередачі в мс (100…60000, крок 100).
- `TX`: enable/disable автопередачу (UP=ON, DOWN=OFF, CENTER=tgl).
- `BOOT`: перезавантаження в ROM bootloader (USB CDC/JTAG) для прошивки. CENTER запускає перезавантаження; підключіть USB і запускайте флешер.

У кожному екрані нижні рядки відображають SNR/RSSI/стан IRQ з радіо. Застосування параметрів відбувається одразу після зміни (через `lora_radio_apply_params`).

## USB JSON API
- Працює через USB Serial/JTAG (CDC ACM). Читайте/пишіть рядки UTF-8 із завершенням `\n`.
- Команди:  
  - `{"cmd":"get_status"}` — повертає JSON зі статусом/параметрами.  
  - `{"cmd":"set_params","params":{"band":"430","freq_mhz":433,"bw_khz":125,"sf":7,"cr":5,"tx_power_dbm":14,"period_ms":1000,"tx_enabled":true,"payload":"PING 1"}}` — застосувати параметри (RX ігнорує TX-поля).  
  - `{"cmd":"reboot_bootloader"}` — перезавантаження в ROM bootloader.
- Відповідь `status` для TX: `role`, `freq_mhz`, `bw_khz`, `sf`, `cr`, `band`, `tx_power_dbm`, `period_ms`, `tx_enabled`, `snr_db`, `rssi_dbm`, `last_status`. Для RX додається `payload` (останній прийнятий пакет).
- Готовий GUI-клієнт: `py_app/` (PyQt6), відправляє `set_params` одразу після зміни полів.

збірка
IDF_TARGET=esp32s3 idf.py -C apps/tx -B build-tx -DSDKCONFIG_DEFAULTS=sdkconfig.defaults build
