ESP32: добавить UI сабсервера, PIN-ввод пока не работает
This commit is contained in:
parent
885cf463a7
commit
b9185e761b
@ -0,0 +1,26 @@
|
||||
# ESP32 UI-прототип сабсервера SHiNE
|
||||
|
||||
- краткое описание фичи:
|
||||
для `Waveshare ESP32-S3-Touch-AMOLED-2.16` добавлен новый интерактивный UI-скетч сабсервера `SHiNE` с хранением данных в `NVS`, PIN-блокировкой, настройками `Wi-Fi`, настройками серверов, кошельком, экраном `QR/URI`, живой Solana-регистрацией и экраном входящих запросов. В текущей версии `Wi-Fi` подключается реально, адреса `API/RPC/WS` проверяются реально, баланс кошелька читается из `Solana RPC`, а регистрация отправляет `create_user_pda` в `shine_users`.
|
||||
|
||||
- что именно проверять:
|
||||
1. Прошить режим `subserver-ui` и дождаться старта экрана блокировки.
|
||||
2. Проверить, что русский текст в заголовках, кнопках и статусах отображается корректно, без кракозябр и замены на английский.
|
||||
3. Ввести PIN `1234` и убедиться, что открывается главный экран.
|
||||
4. Открыть `Подключение -> Wi-Fi`, ввести `SSID` и пароль, нажать `Проверить`, дождаться реального подключения, затем перезагрузить устройство и проверить, что значения сохранились.
|
||||
5. Открыть `Подключение -> Серверы`, проверить или изменить `API/RPC/WS`, нажать `Проверить` и убедиться, что показываются реальные статусы доступности, затем перезагрузить устройство и проверить сохранение значений.
|
||||
6. Открыть `Аккаунт`, ввести логин, имя сабсервера и нажать `Сгенерировать`; проверить, что появились секрет и адрес кошелька, а после перезагрузки они не исчезают.
|
||||
7. Открыть `Кошелёк`, нажать `Проверить` и убедиться, что баланс реально читается из `Solana RPC`; затем открыть `QR и URI` и проверить, что QR-код отрисовывается и сканируется как `solana:`-ссылка.
|
||||
8. При необходимости отдельно проверить тестовые кнопки `+/- SOL`: они меняют локальный баланс для UX-сценариев, но после следующей реальной RPC-проверки баланс должен вернуться к сетевому значению.
|
||||
9. Вернуться на главный экран и проверить, что до выполнения всех условий кнопка регистрации недоступна, а после выполнения становится доступной.
|
||||
10. Выполнить регистрацию и убедиться, что статус меняется на `Сабсервер активен`, онлайн-статус становится активным, а на экране появляются краткие отпечатки `PDA/TX`.
|
||||
11. После регистрации проверить через `Solana`/UI проекта, что `user_pda` для этого логина реально создана и соответствует `device`-адресу устройства.
|
||||
12. Открыть `Запросы`, поочерёдно открыть оба демонстрационных запроса и проверить, что кнопки `Разрешить` и `Отклонить` меняют их статус.
|
||||
13. Открыть `Настройки`, сменить PIN, затем заблокировать/перезагрузить устройство и проверить вход с новым PIN.
|
||||
14. Выполнить `Полный сброс` и убедиться, что все поля, секрет, баланс, онлайн и регистрация очищаются.
|
||||
|
||||
- ожидаемый результат:
|
||||
новый `ESP32`-скетч стабильно запускается, показывает нормальный русский интерфейс, сохраняет данные во внутренней памяти устройства, реально подключается к `Wi-Fi`, реально проверяет `API/RPC/WS`, реально читает баланс из `Solana RPC`, рисует рабочий `QR` для `solana:`-URI и позволяет вручную пройти полный сценарий on-chain регистрации сабсервера.
|
||||
|
||||
- статус:
|
||||
pending
|
||||
@ -0,0 +1,13 @@
|
||||
# ESP32 авто-прошивка shine_subserver_ui
|
||||
|
||||
- краткое описание фичи:
|
||||
добавлен исполняемый скрипт `flash_shine_subserver_ui.sh`, который автоматически ищет USB-порт `ESP32` и запускает заливку прошивки `shine_subserver_ui` без ручного указания `PORT`.
|
||||
- что именно проверять:
|
||||
1. Подключить плату `ESP32` по USB.
|
||||
2. Перейти в папку `ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/test-device/`.
|
||||
3. Запустить `./flash_shine_subserver_ui.sh`.
|
||||
4. Убедиться, что скрипт сам показывает найденный порт и успешно запускает compile/upload.
|
||||
- ожидаемый результат:
|
||||
скрипт без ручного ввода порта находит `ESP32`, печатает найденный `/dev/ttyACM*` или `/dev/ttyUSB*` и заливает `shine_subserver_ui`.
|
||||
- статус:
|
||||
pending
|
||||
@ -0,0 +1,12 @@
|
||||
# ESP32 PIN-клавиатура: подписи кнопок
|
||||
|
||||
- краткое описание фичи:
|
||||
в UI-скетче `shine_subserver_ui` изменена отрисовка подписей кнопок. Вместо малого шрифта теперь используется более стабильный шрифт с явным центрированием текста внутри кнопок, чтобы на экране ввода PIN и других экранах не пропадали цифры и надписи.
|
||||
- что именно проверять:
|
||||
1. Включить устройство и дождаться экрана ввода PIN.
|
||||
2. Убедиться, что на всех серых кнопках видны цифры `0-9`, `Отмена` и `OK`.
|
||||
3. Открыть другие экраны с кнопками (`Главный экран`, `Wi-Fi`, `Серверы`, `Настройки`) и убедиться, что подписи отображаются и не уезжают за границы кнопок.
|
||||
- ожидаемый результат:
|
||||
подписи кнопок стабильно видны сразу после старта, текст визуально центрирован, пустых серых кнопок без цифр и названий нет.
|
||||
- статус:
|
||||
pending
|
||||
@ -0,0 +1,478 @@
|
||||
# SHiNE ESP32 Subserver UI Spec
|
||||
|
||||
## Назначение
|
||||
|
||||
Этот документ описывает актуальный UI-прототип сабсервера `SHiNE` для платы `Waveshare ESP32-S3-Touch-AMOLED-2.16`.
|
||||
|
||||
Документ является источником истины для Arduino-скетча:
|
||||
|
||||
- если меняется этот документ, должен меняться и скетч;
|
||||
- если меняется скетч, должен обновляться и этот документ;
|
||||
- экраны, кнопки, поля, статусы, переходы и тексты не должны расходиться.
|
||||
|
||||
## Текущий объём реализации
|
||||
|
||||
Текущая реализация является интерактивным прототипом экрана устройства, пригодным для ручной проверки на железе.
|
||||
|
||||
Что уже входит в прототип:
|
||||
|
||||
- локальный UI на тач-экране;
|
||||
- хранение настроек и секретов во внутренней памяти `ESP32` через `NVS`;
|
||||
- русский текст на экране через `UTF-8` + кириллический шрифт `U8g2`;
|
||||
- экран пополнения с реальным `solana:` URI и рисованием QR-кода;
|
||||
- реальное подключение к `Wi-Fi` по сохранённым `SSID/паролю`;
|
||||
- реальная проверка доступности `API`, `RPC` и `WS`-адресов;
|
||||
- реальное чтение баланса кошелька из `Solana RPC`;
|
||||
- проверка обязательных условий перед регистрацией;
|
||||
- живая on-chain регистрация серверного `user_pda` в `shine_users` через `device key` устройства;
|
||||
- прототип входящих запросов с подтверждением и отклонением;
|
||||
- PIN-блокировка;
|
||||
- базовые настройки, статус и главный экран;
|
||||
- сохранение `PDA` и `tx signature` после успешной регистрации.
|
||||
|
||||
Что пока считается именно прототипом, а не финальной интеграцией:
|
||||
|
||||
- приём реальных входящих запросов на вход/подпись пока не подключён к живой сети;
|
||||
- входящие запросы пока демонстрационные, чтобы можно было проверить UX и логику подтверждения.
|
||||
|
||||
## Основная идея устройства
|
||||
|
||||
Устройство работает как отдельный сабсервер:
|
||||
|
||||
- хранит секрет на самом устройстве;
|
||||
- позволяет ввести логин, секрет и имя сабсервера;
|
||||
- показывает адрес кошелька устройства;
|
||||
- позволяет пополнить баланс перед регистрацией;
|
||||
- после выполнения условий даёт зарегистрировать устройство как сабсервер;
|
||||
- после регистрации может принимать входящие запросы на вход и на подпись.
|
||||
|
||||
`SD`-карта не нужна для постоянного хранения секрета в этом прототипе.
|
||||
Основное сохранение идёт во внутреннюю flash-память через `NVS`.
|
||||
|
||||
## Данные, которые хранятся на устройстве
|
||||
|
||||
Прототип хранит:
|
||||
|
||||
- `PIN`;
|
||||
- `Wi-Fi SSID`;
|
||||
- `Wi-Fi password`;
|
||||
- `login`;
|
||||
- `session/subserver name`;
|
||||
- `master secret`;
|
||||
- `wallet address`;
|
||||
- `user pda address`;
|
||||
- `registration signature`;
|
||||
- `balance`;
|
||||
- `server api url`;
|
||||
- `server rpc url`;
|
||||
- `server ws url`;
|
||||
- флаги:
|
||||
`wifiReady`, `serversReady`, `secretReady`, `registered`, `online`.
|
||||
|
||||
## Правила готовности к регистрации
|
||||
|
||||
Кнопка регистрации доступна только если одновременно выполнены условия:
|
||||
|
||||
1. настроен и подтверждён `Wi-Fi`;
|
||||
2. заполнены и подтверждены серверные адреса;
|
||||
3. задан логин;
|
||||
4. сгенерирован или введён секрет;
|
||||
5. баланс кошелька не меньше `0.20 SOL`;
|
||||
6. устройство ещё не зарегистрировано.
|
||||
|
||||
Если хотя бы одно условие не выполнено, главный экран показывает, чего именно не хватает.
|
||||
|
||||
## Экранная модель
|
||||
|
||||
В прототипе используются следующие экраны:
|
||||
|
||||
1. `LOCK`
|
||||
2. `HOME`
|
||||
3. `STATUS`
|
||||
4. `CONNECTION`
|
||||
5. `WIFI_EDIT`
|
||||
6. `SERVERS`
|
||||
7. `ACCOUNT`
|
||||
8. `WALLET`
|
||||
9. `WALLET_QR`
|
||||
10. `REQUESTS`
|
||||
11. `REQUEST_DETAIL`
|
||||
12. `SETTINGS`
|
||||
13. `PIN_EDIT`
|
||||
14. `TEXT_INPUT`
|
||||
15. `CONFIRM`
|
||||
|
||||
## Общие правила интерфейса
|
||||
|
||||
- Верхняя строка всегда показывает краткий статус устройства:
|
||||
`PIN`, `Wi-Fi`, `сервер`, `регистрация`.
|
||||
- Основной язык прототипа: русский.
|
||||
- Для вывода текста используется `UTF-8`.
|
||||
- Для кириллицы используется `U8g2`-шрифт с поддержкой `Cyrillic`.
|
||||
- Кнопки крупные, с тач-ориентированным размером.
|
||||
- Опасные действия подтверждаются отдельным диалогом.
|
||||
- После изменения данных конфигурация сразу сохраняется в `NVS`.
|
||||
|
||||
## Экран LOCK
|
||||
|
||||
Назначение:
|
||||
|
||||
- блокировка устройства после запуска;
|
||||
- вход по PIN.
|
||||
|
||||
Отображается:
|
||||
|
||||
- заголовок `SHiNE Device`;
|
||||
- статус `Устройство заблокировано`;
|
||||
- поле ввода PIN в виде маски;
|
||||
- кнопки цифровой клавиатуры;
|
||||
- кнопки `Стереть` и `Открыть`.
|
||||
|
||||
Поведение:
|
||||
|
||||
- если PIN введён верно, открывается `HOME`;
|
||||
- если PIN неверный, показывается ошибка `Неверный PIN`.
|
||||
|
||||
## Экран HOME
|
||||
|
||||
Это основной экран устройства.
|
||||
|
||||
Показывает:
|
||||
|
||||
- крупный статус регистрации;
|
||||
- имя логина;
|
||||
- имя сабсервера;
|
||||
- короткий статус Wi-Fi;
|
||||
- короткий статус сервера;
|
||||
- короткий статус баланса.
|
||||
|
||||
Нижние кнопки:
|
||||
|
||||
- `Статус`
|
||||
- `Подключение`
|
||||
- `Аккаунт`
|
||||
- `Кошелёк`
|
||||
- `Запросы`
|
||||
- `Настройки`
|
||||
|
||||
Дополнительная большая кнопка:
|
||||
|
||||
- `Зарегистрировать`
|
||||
|
||||
Если регистрация уже сделана:
|
||||
|
||||
- вместо призыва к регистрации показывается статус `Сабсервер активен`.
|
||||
|
||||
## Экран STATUS
|
||||
|
||||
Показывает сводку:
|
||||
|
||||
- логин;
|
||||
- сабсервер;
|
||||
- есть ли секрет;
|
||||
- зарегистрировано ли устройство;
|
||||
- подключён ли Wi-Fi;
|
||||
- доступны ли серверы;
|
||||
- хватает ли баланса;
|
||||
- находится ли устройство онлайн;
|
||||
- краткий отпечаток `PDA` или `tx`.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Назад`
|
||||
- `Обновить статус`
|
||||
|
||||
`Обновить статус` в прототипе не делает сеть, а просто перерисовывает текущие вычисленные состояния.
|
||||
|
||||
## Экран CONNECTION
|
||||
|
||||
Показывает:
|
||||
|
||||
- `Wi-Fi`: готов / не готов;
|
||||
- `Серверы`: готовы / не готовы;
|
||||
- `Онлайн`: да / нет.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Wi-Fi`
|
||||
- `Серверы`
|
||||
- `Подключить`
|
||||
- `Отключить`
|
||||
- `Назад`
|
||||
|
||||
Поведение:
|
||||
|
||||
- `Подключить` переводит устройство в `online=true`, если `Wi-Fi` реально подключён и серверы реально проверены;
|
||||
- `Отключить` переводит устройство в `online=false`.
|
||||
|
||||
## Экран WIFI_EDIT
|
||||
|
||||
Поля:
|
||||
|
||||
- `SSID`
|
||||
- `Пароль`
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Изменить SSID`
|
||||
- `Изменить пароль`
|
||||
- `Проверить`
|
||||
- `Сбросить`
|
||||
- `Назад`
|
||||
|
||||
Поведение:
|
||||
|
||||
- `Проверить` делает реальную попытку подключения к `Wi-Fi`;
|
||||
- `Сбросить` очищает обе строки и ставит `wifiReady=false`.
|
||||
|
||||
## Экран SERVERS
|
||||
|
||||
Поля:
|
||||
|
||||
- `API URL`
|
||||
- `RPC URL`
|
||||
- `WS URL`
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Изменить API`
|
||||
- `Изменить RPC`
|
||||
- `Изменить WS`
|
||||
- `Проверить`
|
||||
- `Тестовые`
|
||||
- `Назад`
|
||||
|
||||
Поведение:
|
||||
|
||||
- `Тестовые` подставляет дефолтные тестовые значения;
|
||||
- `Проверить` делает реальные сетевые проверки:
|
||||
- `API URL` должен отвечать по `HTTP/HTTPS`;
|
||||
- `RPC URL` должен отвечать на `Solana JSON-RPC`;
|
||||
- `WS URL` должен принимать `TCP/TLS`-соединение.
|
||||
|
||||
## Экран ACCOUNT
|
||||
|
||||
Показывает:
|
||||
|
||||
- логин;
|
||||
- имя сабсервера;
|
||||
- статус секрета;
|
||||
- короткий отпечаток секрета;
|
||||
- статус регистрации;
|
||||
- короткий отпечаток `PDA` или `tx`.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Изменить логин`
|
||||
- `Секрет`
|
||||
- `Имя сабсервера`
|
||||
- `Сгенерировать`
|
||||
- `Очистить`
|
||||
- `Назад`
|
||||
|
||||
Поведение:
|
||||
|
||||
- `Сгенерировать` создаёт новый `master secret` и пересчитывает из него `device`-кошелёк;
|
||||
- `Очистить` удаляет секрет, адрес кошелька, `PDA`, `tx`, регистрацию и онлайн-статус;
|
||||
- логин приводится к нижнему регистру и trim.
|
||||
|
||||
## Экран WALLET
|
||||
|
||||
Показывает:
|
||||
|
||||
- адрес кошелька устройства;
|
||||
- баланс в `SOL`;
|
||||
- минимально рекомендуемую сумму для регистрации;
|
||||
- статус `Хватает / Не хватает`.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `QR и URI`
|
||||
- `+0.10 SOL`
|
||||
- `+0.25 SOL`
|
||||
- `-0.10 SOL`
|
||||
- `Проверить`
|
||||
- `Назад`
|
||||
|
||||
Поведение:
|
||||
|
||||
- кнопки пополнения/уменьшения нужны для теста сценариев;
|
||||
- `Проверить` читает реальный баланс из `Solana RPC`;
|
||||
- адрес кошелька должен совпадать с `device key`, вычисленным из сохранённого `master secret`;
|
||||
- отрицательный баланс не допускается.
|
||||
|
||||
## Экран WALLET_QR
|
||||
|
||||
Показывает:
|
||||
|
||||
- QR-код для строки вида:
|
||||
`solana:<wallet>?amount=0.20&label=SHiNE%20Register`;
|
||||
- адрес кошелька;
|
||||
- сумму;
|
||||
- текст URI.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Назад`
|
||||
|
||||
QR должен быть сканируемым, а не декоративным.
|
||||
|
||||
## Экран REQUESTS
|
||||
|
||||
Показывает список демонстрационных запросов:
|
||||
|
||||
- `Вход в сессию`
|
||||
- `Подпись сообщения`
|
||||
|
||||
Для каждого запроса:
|
||||
|
||||
- тип;
|
||||
- источник;
|
||||
- короткий статус.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Открыть запрос 1`
|
||||
- `Открыть запрос 2`
|
||||
- `Назад`
|
||||
|
||||
## Экран REQUEST_DETAIL
|
||||
|
||||
Показывает детали выбранного запроса:
|
||||
|
||||
- тип запроса;
|
||||
- кто запросил;
|
||||
- время;
|
||||
- описание;
|
||||
- отпечаток/идентификатор.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Разрешить`
|
||||
- `Отклонить`
|
||||
- `Назад`
|
||||
|
||||
Поведение:
|
||||
|
||||
- после разрешения или отклонения запрос помечается обработанным;
|
||||
- экран списка отражает новый статус.
|
||||
|
||||
## Экран SETTINGS
|
||||
|
||||
Показывает:
|
||||
|
||||
- текущий PIN;
|
||||
- базовые флаги безопасности;
|
||||
- технические действия прототипа.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Сменить PIN`
|
||||
- `Сбросить онлайн`
|
||||
- `Полный сброс`
|
||||
- `Назад`
|
||||
|
||||
`Полный сброс` очищает весь локальный конфиг и возвращает устройство к стартовому состоянию.
|
||||
|
||||
## Экран PIN_EDIT
|
||||
|
||||
Используется для ввода нового PIN.
|
||||
|
||||
Правила:
|
||||
|
||||
- допустимы только цифры;
|
||||
- длина PIN: 4..8 символов;
|
||||
- после сохранения новый PIN немедленно пишется в `NVS`.
|
||||
|
||||
## Экран TEXT_INPUT
|
||||
|
||||
Это общий экран редактирования текстовых полей.
|
||||
|
||||
Используется для:
|
||||
|
||||
- `SSID`
|
||||
- `Пароль Wi-Fi`
|
||||
- `Логин`
|
||||
- `Имя сабсервера`
|
||||
- `API URL`
|
||||
- `RPC URL`
|
||||
- `WS URL`
|
||||
|
||||
Состав экрана:
|
||||
|
||||
- заголовок поля;
|
||||
- текущее значение;
|
||||
- программная клавиатура;
|
||||
- кнопки `Стереть`, `OK`, `Отмена`.
|
||||
|
||||
## Экран CONFIRM
|
||||
|
||||
Это модальный экран подтверждения.
|
||||
|
||||
Используется для:
|
||||
|
||||
- регистрации;
|
||||
- очистки секрета;
|
||||
- полного сброса.
|
||||
|
||||
Кнопки:
|
||||
|
||||
- `Подтвердить`
|
||||
- `Отмена`
|
||||
|
||||
## Сценарий первой настройки
|
||||
|
||||
Ожидаемый путь пользователя:
|
||||
|
||||
1. разблокировать устройство PIN-кодом;
|
||||
2. открыть `Подключение -> Wi-Fi`;
|
||||
3. ввести `SSID` и пароль, нажать `Проверить`;
|
||||
4. открыть `Подключение -> Серверы`;
|
||||
5. проверить или задать серверные адреса;
|
||||
6. открыть `Аккаунт`;
|
||||
7. ввести логин;
|
||||
8. задать имя сабсервера;
|
||||
9. сгенерировать секрет;
|
||||
10. открыть `Кошелёк`;
|
||||
11. при необходимости пополнить баланс;
|
||||
12. вернуться на `HOME`;
|
||||
13. нажать `Зарегистрировать`;
|
||||
14. после подтверждения увидеть статус `Сабсервер активен`.
|
||||
|
||||
Примечание:
|
||||
|
||||
- устройство реально отправляет `create_user_pda` в `shine_users`, а после подтверждения сохраняет `PDA` и `tx signature`.
|
||||
|
||||
## Сценарий входящего запроса
|
||||
|
||||
1. открыть `Запросы`;
|
||||
2. выбрать один из запросов;
|
||||
3. прочитать детали;
|
||||
4. нажать `Разрешить` или `Отклонить`;
|
||||
5. убедиться, что статус запроса изменился.
|
||||
|
||||
## Технические требования к кириллице
|
||||
|
||||
Для корректного русского текста скетч обязан:
|
||||
|
||||
- хранить строковые литералы в `UTF-8`;
|
||||
- вызывать `gfx->setUTF8Print(true)`;
|
||||
- использовать шрифт `U8g2` с поддержкой `Cyrillic`;
|
||||
- не полагаться на стандартный `ASCII`-шрифт `Arduino_GFX` для русского текста.
|
||||
|
||||
Если эти условия нарушены, UI считается сломанным даже при правильной логике экранов.
|
||||
|
||||
## Критерии ручной проверки
|
||||
|
||||
Минимально нужно проверить:
|
||||
|
||||
1. устройство загружается и показывает экран блокировки;
|
||||
2. русский текст отображается без кракозябр;
|
||||
3. ввод по экранной клавиатуре работает;
|
||||
4. после перезагрузки сохранённые поля остаются в памяти;
|
||||
5. секрет и адрес кошелька сохраняются на устройстве;
|
||||
6. экран `QR и URI` рисует читаемый QR-код;
|
||||
7. регистрация блокируется, пока условия не выполнены;
|
||||
8. после выполнения условий регистрация становится доступной;
|
||||
9. список запросов и экран подтверждения работают;
|
||||
10. полный сброс действительно очищает сохранённое состояние.
|
||||
@ -10,6 +10,7 @@
|
||||
- `hello` — базовый тест экрана (пример `01_HelloWorld`)
|
||||
- `simple` — простой кастомный тест: экран + touch + запись/проигрывание + наклон (IMU)
|
||||
- `argon2` — генерация masterSecret через Argon2id с SD-картой как памятью (тест скорости)
|
||||
- `subserver-ui` — основной UI-прототип сабсервера SHiNE: NVS, PIN, Wi-Fi, серверы, кошелёк, QR, запросы
|
||||
|
||||
Запуск:
|
||||
|
||||
@ -17,3 +18,5 @@
|
||||
- `./burn.sh audio`
|
||||
- `./burn.sh hello`
|
||||
- `./burn.sh simple`
|
||||
- `./burn.sh subserver-ui`
|
||||
- `./flash_shine_subserver_ui.sh` - автоматически находит USB-порт и заливает `shine_subserver_ui`
|
||||
|
||||
@ -16,9 +16,10 @@ case "${MODE}" in
|
||||
audio) SKETCH_DIR="${DEMO_BASE}/examples/07_ES8311" ;;
|
||||
simple) SKETCH_DIR="${ROOT_DIR}/simple_av_test" ;;
|
||||
argon2) SKETCH_DIR="${ROOT_DIR}/argon2_sd_test" ;;
|
||||
subserver-ui) SKETCH_DIR="${ROOT_DIR}/shine_subserver_ui" ;;
|
||||
*)
|
||||
echo "Unknown mode: ${MODE}" >&2
|
||||
echo "Use one of: hello, widgets, audio, simple, argon2" >&2
|
||||
echo "Use one of: hello, widgets, audio, simple, argon2, subserver-ui" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
detect_port_from_arduino_cli() {
|
||||
local line
|
||||
while IFS= read -r line; do
|
||||
[[ -z "${line}" ]] && continue
|
||||
[[ "${line}" == Port* ]] && continue
|
||||
if [[ "${line}" == /dev/* ]]; then
|
||||
awk '{print $1}' <<<"${line}"
|
||||
return 0
|
||||
fi
|
||||
done < <(arduino-cli board list 2>/dev/null || true)
|
||||
return 1
|
||||
}
|
||||
|
||||
detect_port_from_dev() {
|
||||
local candidates=()
|
||||
local path
|
||||
for path in /dev/ttyACM* /dev/ttyUSB*; do
|
||||
[[ -e "${path}" ]] || continue
|
||||
candidates+=("${path}")
|
||||
done
|
||||
|
||||
if [[ "${#candidates[@]}" -eq 1 ]]; then
|
||||
printf '%s\n' "${candidates[0]}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
PORT="${PORT:-}"
|
||||
if [[ -z "${PORT}" ]]; then
|
||||
PORT="$(detect_port_from_arduino_cli || true)"
|
||||
fi
|
||||
if [[ -z "${PORT}" ]]; then
|
||||
PORT="$(detect_port_from_dev || true)"
|
||||
fi
|
||||
|
||||
if [[ -z "${PORT}" ]]; then
|
||||
echo "Не удалось автоматически найти USB-порт ESP32." >&2
|
||||
echo "Подключите плату и проверьте 'arduino-cli board list'." >&2
|
||||
echo "Либо укажите порт вручную: PORT=/dev/ttyACM0 ./flash_shine_subserver_ui.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "== Найден порт: ${PORT}"
|
||||
PORT="${PORT}" "${ROOT_DIR}/burn.sh" subserver-ui
|
||||
@ -0,0 +1 @@
|
||||
#include "../../official-demo/examples/Arduino-v3.3.5/libraries/lvgl/src/extra/libs/qrcode/qrcodegen.c"
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,2 +1,2 @@
|
||||
client.version=1.2.135
|
||||
server.version=1.2.127
|
||||
client.version=1.2.138
|
||||
server.version=1.2.130
|
||||
|
||||
Loading…
Reference in New Issue
Block a user