Compare commits
| Author | SHA256 | Date | |
|---|---|---|---|
|
|
553a1f1e27 | ||
|
|
940dc855cf | ||
|
|
9e6ff07136 | ||
|
|
f095182673 |
@@ -3,14 +3,31 @@
|
|||||||
- Краткое описание: минимальный UI-прототип для сабсервера на базе `LVGL + subserver touch`, с Wi-Fi flow, серверными адресами и общим экраном редактирования текста.
|
- Краткое описание: минимальный UI-прототип для сабсервера на базе `LVGL + subserver touch`, с Wi-Fi flow, серверными адресами и общим экраном редактирования текста.
|
||||||
- Что проверять:
|
- Что проверять:
|
||||||
- стартует экран `HOME`;
|
- стартует экран `HOME`;
|
||||||
- на `HOME` видны реальное значение сабсервера или `subserver not set`, реальное значение логина или `login not set`, при отсутствии секрета строка `secret not set`, а также `STATUS`, верхний правый блок с процентом батареи, иконкой батареи и индикатором Wi-Fi, кнопка `SETTINGS` и нижняя подпись `SHiNE subserver (v.0.18)`;
|
- на `HOME` видны реальное значение сабсервера или `subserver not set`, реальное значение логина или `login not set`, при отсутствии секрета строка `secret not set`, а также `STATUS`, верхний правый блок с процентом батареи, иконкой батареи и индикатором Wi-Fi, кнопка баланса, строка `SHiNE: ...`, кнопка `SETTINGS` уменьшенной ширины у правого края и нижняя подпись `SHiNE subserver (v.0.18)`;
|
||||||
|
- справа от строки логина виден индикатор статуса Solana-аккаунта:
|
||||||
|
- зелёный, если ключи совпали;
|
||||||
|
- красный, если mismatch;
|
||||||
|
- белый контур, если пользователь не найден;
|
||||||
|
- если статус не зелёный, рядом выводится краткое текстовое пояснение;
|
||||||
- строка Wi-Fi на `HOME` корректно показывает одно из состояний:
|
- строка Wi-Fi на `HOME` корректно показывает одно из состояний:
|
||||||
- `Wi-Fi (not configured) not configured`
|
- `Wi-Fi (not configured) not configured`
|
||||||
- `Wi-Fi (<saved_ssid>) disconnected`
|
- `Wi-Fi (<saved_ssid>) disconnected`
|
||||||
- `Wi-Fi (<current_ssid>) connected`
|
- `Wi-Fi (<current_ssid>) connected`
|
||||||
|
- строка `SHiNE:` корректно показывает одно из состояний:
|
||||||
|
- `connected`
|
||||||
|
- `account not configured`
|
||||||
|
- `unavailable`
|
||||||
- пока открыт `HOME`, статус сам обновляется без перехода на другие экраны;
|
- пока открыт `HOME`, статус сам обновляется без перехода на другие экраны;
|
||||||
|
- баланс обновляется кнопкой по нажатию;
|
||||||
|
- если логин зарегистрирован и секрет/сабсервер заданы, устройство:
|
||||||
|
- читает `user_pda` через Solana RPC;
|
||||||
|
- сверяет `root`, `blockchain`, `device` и `subserver` session type `100`;
|
||||||
|
- поднимает WebSocket-сессию с сервером SHiNE;
|
||||||
|
- шлёт `Ping` раз в минуту;
|
||||||
- кнопка `SETTINGS` открывает `SETTINGS_MENU`;
|
- кнопка `SETTINGS` открывает `SETTINGS_MENU`;
|
||||||
- свайп влево на `HOME` открывает `SETTINGS_MENU`;
|
- свайп влево на `HOME` открывает `SETTINGS_MENU`;
|
||||||
|
- если пользователь не найден в Solana PDA, слева снизу появляется `REGISTER ACCOUNT`;
|
||||||
|
- `REGISTER ACCOUNT` открывает экран-заглушку;
|
||||||
- в `SETTINGS_MENU` сначала видны только `Wi-Fi` и `Server`;
|
- в `SETTINGS_MENU` сначала видны только `Wi-Fi` и `Server`;
|
||||||
- обе видимые карточки меню одного цвета;
|
- обе видимые карточки меню одного цвета;
|
||||||
- свайп вверх показывает `Server` и `Account`;
|
- свайп вверх показывает `Server` и `Account`;
|
||||||
@@ -20,6 +37,9 @@
|
|||||||
- `SELECT NETWORK` запускает скан;
|
- `SELECT NETWORK` запускает скан;
|
||||||
- после скана показывается список доступных SSID;
|
- после скана показывается список доступных SSID;
|
||||||
- выбор SSID открывает общий экран редактирования текста для пароля;
|
- выбор SSID открывает общий экран редактирования текста для пароля;
|
||||||
|
- если для этого SSID пароль уже сохранялся раньше, он автоматически подставляется в редактор;
|
||||||
|
- если затем ввести пароль для другого SSID, пароль первой сети не теряется;
|
||||||
|
- одновременно хранится до `8` паролей для разных SSID;
|
||||||
- на этом экране видно старое значение, курсор стоит в конце;
|
- на этом экране видно старое значение, курсор стоит в конце;
|
||||||
- две верхние служебные строки над полем ввода отсутствуют;
|
- две верхние служебные строки над полем ввода отсутствуют;
|
||||||
- при вводе пароля Wi-Fi текст показывается открыто, без точек;
|
- при вводе пароля Wi-Fi текст показывается открыто, без точек;
|
||||||
@@ -40,6 +60,7 @@
|
|||||||
- медленный свайп по экрану не должен превращаться в случайное нажатие кнопки;
|
- медленный свайп по экрану не должен превращаться в случайное нажатие кнопки;
|
||||||
- `ABC/123`, `SHIFT`, `DEL`, `SAVE`, `CANCEL` работают;
|
- `ABC/123`, `SHIFT`, `DEL`, `SAVE`, `CANCEL` работают;
|
||||||
- при успехе SSID и пароль сохраняются, а `HOME` показывает `Wi-Fi connected`;
|
- при успехе SSID и пароль сохраняются, а `HOME` показывает `Wi-Fi connected`;
|
||||||
|
- если после подключения ко второй сети снова выбрать первую, её старый пароль уже подставлен и достаточно нажать `SAVE`;
|
||||||
- при ошибке показывается `Connection failed`;
|
- при ошибке показывается `Connection failed`;
|
||||||
- `CLEAR SAVED WI-FI` очищает сохранённые настройки;
|
- `CLEAR SAVED WI-FI` очищает сохранённые настройки;
|
||||||
- если сеть была ранее успешно сохранена, после потери связи устройство автоматически пытается переподключиться;
|
- если сеть была ранее успешно сохранена, после потери связи устройство автоматически пытается переподключиться;
|
||||||
@@ -60,8 +81,18 @@
|
|||||||
- `Subserver` открывает промежуточный экран с `USE SUBSERVER1` и `EDIT MANUALLY`;
|
- `Subserver` открывает промежуточный экран с `USE SUBSERVER1` и `EDIT MANUALLY`;
|
||||||
- `USE SUBSERVER1` возвращает стандартное значение `subserver1`;
|
- `USE SUBSERVER1` возвращает стандартное значение `subserver1`;
|
||||||
- `EDIT MANUALLY` открывает общий экран редактирования и сохраняет значение в NVS;
|
- `EDIT MANUALLY` открывает общий экран редактирования и сохраняет значение в NVS;
|
||||||
- `Secret` открывает экран-заглушку, где сказано, что настройка ещё не реализована;
|
|
||||||
- `Secret` теперь открывает меню секрета с показом секрета, ручным вводом и генерацией;
|
- `Secret` теперь открывает меню секрета с показом секрета, ручным вводом и генерацией;
|
||||||
|
- в `SHOW SECRET` показывается прокручиваемый список всех ключей:
|
||||||
|
- `Secret (base58)`
|
||||||
|
- `Root key (base58)`
|
||||||
|
- `Root key priv (base58)`
|
||||||
|
- `Blockchain key (base58)`
|
||||||
|
- `Blockchain key priv (base58)`
|
||||||
|
- `Device key (base58)`
|
||||||
|
- `Device key priv (base58)`
|
||||||
|
- `Subserver key (base58)`
|
||||||
|
- `Subserver key priv (base58)`
|
||||||
|
- значения ключей показываются полными строками увеличенным шрифтом;
|
||||||
- при смене `login` сохранённый секрет сбрасывается в `not set`;
|
- при смене `login` сохранённый секрет сбрасывается в `not set`;
|
||||||
- во время генерации секрета есть `CANCEL` и подтверждение остановки;
|
- во время генерации секрета есть `CANCEL` и подтверждение остановки;
|
||||||
- при отмене генерации старый секрет, если он был, не должен теряться;
|
- при отмене генерации старый секрет, если он был, не должен теряться;
|
||||||
@@ -69,4 +100,5 @@
|
|||||||
- свайп вправо из `ACCOUNT_SUBSERVER_SCREEN` и `ACCOUNT_SECRET_SCREEN` возвращает в `ACCOUNT_SCREEN`;
|
- свайп вправо из `ACCOUNT_SUBSERVER_SCREEN` и `ACCOUNT_SECRET_SCREEN` возвращает в `ACCOUNT_SCREEN`;
|
||||||
- если во время реального свайпа палец проходит по кнопке, это не должно открывать кнопку как обычный `click`.
|
- если во время реального свайпа палец проходит по кнопке, это не должно открывать кнопку как обычный `click`.
|
||||||
- Ожидаемый результат: новый скетч даёт чистый навигационный каркас и уже умеет настраивать Wi-Fi и серверные адреса на самой ESP32.
|
- Ожидаемый результат: новый скетч даёт чистый навигационный каркас и уже умеет настраивать Wi-Fi и серверные адреса на самой ESP32.
|
||||||
|
- Дополнительно ожидается: `HOME` уже показывает реальный Solana/WS-статус сабсервера, а отсутствие пользователя в Solana заметно сразу без перехода в настройки.
|
||||||
- Статус: pending
|
- Статус: pending
|
||||||
|
|||||||
@@ -7,19 +7,17 @@
|
|||||||
Этот прототип проверяет базовую механику экранов, крупных кнопок, свайпов, первичную настройку Wi-Fi и настройку серверных адресов через общий экран редактирования текста.
|
Этот прототип проверяет базовую механику экранов, крупных кнопок, свайпов, первичную настройку Wi-Fi и настройку серверных адресов через общий экран редактирования текста.
|
||||||
|
|
||||||
На этом этапе отсутствуют:
|
На этом этапе отсутствуют:
|
||||||
- логика серверной проверки доступности;
|
|
||||||
- логин/пароль учётной записи SHiNE;
|
- логин/пароль учётной записи SHiNE;
|
||||||
- PIN;
|
- PIN;
|
||||||
- кошелёк;
|
- кошелёк;
|
||||||
- QR;
|
- QR;
|
||||||
- баланс;
|
|
||||||
- регистрация;
|
- регистрация;
|
||||||
- PDA и транзакции;
|
- PDA update/create транзакции;
|
||||||
- входящие запросы.
|
- входящие запросы.
|
||||||
|
|
||||||
## Экраны
|
## Экраны
|
||||||
|
|
||||||
Прототип содержит 8 экранов:
|
Прототип содержит 10 экранов:
|
||||||
- `HOME`
|
- `HOME`
|
||||||
- `SETTINGS_MENU`
|
- `SETTINGS_MENU`
|
||||||
- `WIFI_SCREEN`
|
- `WIFI_SCREEN`
|
||||||
@@ -27,13 +25,21 @@
|
|||||||
- `ACCOUNT_SCREEN`
|
- `ACCOUNT_SCREEN`
|
||||||
- `ACCOUNT_SUBSERVER_SCREEN`
|
- `ACCOUNT_SUBSERVER_SCREEN`
|
||||||
- `ACCOUNT_SECRET_SCREEN`
|
- `ACCOUNT_SECRET_SCREEN`
|
||||||
|
- `SECRET_SHOW_SCREEN`
|
||||||
|
- `SECRET_GENERATE_*`
|
||||||
- `TEXT_EDIT_SCREEN`
|
- `TEXT_EDIT_SCREEN`
|
||||||
|
- `REGISTER_ACCOUNT_PLACEHOLDER`
|
||||||
|
|
||||||
## HOME
|
## HOME
|
||||||
|
|
||||||
Показывает:
|
Показывает:
|
||||||
- сверху слева значение сабсервера или `subserver not set`;
|
- сверху слева значение сабсервера или `subserver not set`;
|
||||||
- ниже значение логина или `login not set`;
|
- ниже значение логина или `login not set`;
|
||||||
|
- справа от строки логина индикатор статуса Solana-аккаунта:
|
||||||
|
- зелёный — все ключи совпадают;
|
||||||
|
- красный — есть mismatch;
|
||||||
|
- белый контур — пользователь не найден в Solana PDA;
|
||||||
|
- рядом с индикатором краткий текст ошибки, если статус не зелёный;
|
||||||
- третьей строкой `secret not set`, если секрет ещё не помечен как установленный;
|
- третьей строкой `secret not set`, если секрет ещё не помечен как установленный;
|
||||||
- сверху справа один ряд индикаторов:
|
- сверху справа один ряд индикаторов:
|
||||||
- процент батареи;
|
- процент батареи;
|
||||||
@@ -41,7 +47,10 @@
|
|||||||
- индикатор Wi-Fi уровня сигнала;
|
- индикатор Wi-Fi уровня сигнала;
|
||||||
- по центру крупный текст `STATUS`;
|
- по центру крупный текст `STATUS`;
|
||||||
- одна строка Wi-Fi вида `Wi-Fi (<ssid>) connected/disconnected`;
|
- одна строка Wi-Fi вида `Wi-Fi (<ssid>) connected/disconnected`;
|
||||||
- снизу большую кнопку `SETTINGS`.
|
- кнопка баланса вида `Balance: <value SOL>` или `Balance: failed to load`, по нажатию выполняет повторный запрос;
|
||||||
|
- строка `SHiNE: <server> connected/account not configured/unavailable`;
|
||||||
|
- при отсутствии пользователя в Solana PDA слева снизу появляется кнопка `REGISTER ACCOUNT`;
|
||||||
|
- снизу кнопку `SETTINGS`, уменьшенную примерно до половины ширины экрана и сдвинутую к правому краю.
|
||||||
- внизу на тёмной полосе подпись `SHiNE subserver (v.0.18)`.
|
- внизу на тёмной полосе подпись `SHiNE subserver (v.0.18)`.
|
||||||
|
|
||||||
Строка Wi-Fi на `HOME`:
|
Строка Wi-Fi на `HOME`:
|
||||||
@@ -50,9 +59,20 @@
|
|||||||
- `Wi-Fi (<current_ssid>) connected`
|
- `Wi-Fi (<current_ssid>) connected`
|
||||||
|
|
||||||
Переходы:
|
Переходы:
|
||||||
|
- кнопка `REGISTER ACCOUNT` -> `REGISTER_ACCOUNT_PLACEHOLDER`, только если пользователь не найден;
|
||||||
- кнопка `SETTINGS` -> `SETTINGS_MENU`;
|
- кнопка `SETTINGS` -> `SETTINGS_MENU`;
|
||||||
- свайп влево -> `SETTINGS_MENU`.
|
- свайп влево -> `SETTINGS_MENU`.
|
||||||
|
|
||||||
|
Фоновая логика:
|
||||||
|
- пока открыт `HOME`, экран сам обновляется примерно раз в секунду;
|
||||||
|
- при наличии `login + secret + subserver` и Wi-Fi устройство читает Solana `user_pda` напрямую через RPC;
|
||||||
|
- сравниваются `root key`, `blockchain key`, `device key` и `subserver` session-запись типа `100`;
|
||||||
|
- для строки `SHiNE:` устройство держит отдельную WebSocket-сессию с сервером SHiNE:
|
||||||
|
- авторизация через `AuthChallenge/CreateAuthSession` или `SessionChallenge/SessionLogin`;
|
||||||
|
- session key = публичный `subserver key`;
|
||||||
|
- подтверждение создания сессии подписывается `device key`;
|
||||||
|
- heartbeat выполняется `Ping` раз в минуту.
|
||||||
|
|
||||||
## SETTINGS_MENU
|
## SETTINGS_MENU
|
||||||
|
|
||||||
Показывает вертикальное меню из 3 пунктов:
|
Показывает вертикальное меню из 3 пунктов:
|
||||||
@@ -90,7 +110,7 @@
|
|||||||
|
|
||||||
Показывает:
|
Показывает:
|
||||||
- текущий Wi-Fi статус;
|
- текущий Wi-Fi статус;
|
||||||
- сохранённый SSID;
|
- сохранённый SSID и число известных сетей;
|
||||||
- статусное сообщение;
|
- статусное сообщение;
|
||||||
- кнопку `SELECT NETWORK`;
|
- кнопку `SELECT NETWORK`;
|
||||||
- кнопку `CLEAR SAVED WI-FI`;
|
- кнопку `CLEAR SAVED WI-FI`;
|
||||||
@@ -109,6 +129,13 @@
|
|||||||
|
|
||||||
Нажатие на SSID открывает `TEXT_EDIT_SCREEN` для ввода пароля.
|
Нажатие на SSID открывает `TEXT_EDIT_SCREEN` для ввода пароля.
|
||||||
|
|
||||||
|
Поведение:
|
||||||
|
- если для выбранного SSID пароль уже был сохранён раньше, он сразу подставляется в поле ввода;
|
||||||
|
- если пароль меняют для другого SSID, старые сохранённые пароли других сетей не теряются;
|
||||||
|
- после успешного подключения выбранная сеть становится текущей `wifi_ssid/wifi_pass`;
|
||||||
|
- одновременно хранится до `8` известных сетей `SSID -> password`;
|
||||||
|
- `CLEAR SAVED WI-FI` очищает все сохранённые сети и текущую сеть.
|
||||||
|
|
||||||
Переходы:
|
Переходы:
|
||||||
- свайп вправо из любого режима `WIFI_SCREEN` -> `SETTINGS_MENU`
|
- свайп вправо из любого режима `WIFI_SCREEN` -> `SETTINGS_MENU`
|
||||||
- кнопка `BACK` -> `SETTINGS_MENU`
|
- кнопка `BACK` -> `SETTINGS_MENU`
|
||||||
@@ -162,16 +189,34 @@
|
|||||||
|
|
||||||
## ACCOUNT_SECRET_SCREEN
|
## ACCOUNT_SECRET_SCREEN
|
||||||
|
|
||||||
Пока это заглушка.
|
|
||||||
|
|
||||||
Показывает:
|
Показывает:
|
||||||
- текущий статус секрета `set/not set`;
|
- кнопку `SHOW SECRET` или серую `SECRET NOT SET`, если секрета ещё нет;
|
||||||
- сообщение, что настройка секрета пока не реализована;
|
- кнопку `ENTER SECRET MANUALLY (NOT RECOMMENDED)`;
|
||||||
- кнопку `BACK`.
|
- кнопку `GENERATE SECRET`.
|
||||||
|
|
||||||
Переходы:
|
Переходы:
|
||||||
- свайп вправо -> `ACCOUNT_SCREEN`
|
- свайп вправо -> `ACCOUNT_SCREEN`
|
||||||
- `BACK` -> `ACCOUNT_SCREEN`
|
- `SHOW SECRET` -> экран просмотра секрета
|
||||||
|
- `ENTER SECRET MANUALLY (NOT RECOMMENDED)` -> `TEXT_EDIT_SCREEN`
|
||||||
|
- `GENERATE SECRET` -> экран подтверждения генерации
|
||||||
|
|
||||||
|
## SECRET_SHOW_SCREEN
|
||||||
|
|
||||||
|
Показывает:
|
||||||
|
- заголовок `SECRET`;
|
||||||
|
- вертикально прокручиваемый список ключей;
|
||||||
|
- `Secret (base58)`;
|
||||||
|
- `Root key (base58)`;
|
||||||
|
- `Root key priv (base58)`;
|
||||||
|
- `Blockchain key (base58)`;
|
||||||
|
- `Blockchain key priv (base58)`;
|
||||||
|
- `Device key (base58)`;
|
||||||
|
- `Device key priv (base58)`;
|
||||||
|
- `Subserver key (base58)`;
|
||||||
|
- `Subserver key priv (base58)`;
|
||||||
|
- для каждого поля показывается формула derivation;
|
||||||
|
- значения ключей показываются полными строками увеличенным шрифтом;
|
||||||
|
- кнопку `BACK`.
|
||||||
|
|
||||||
## TEXT_EDIT_SCREEN
|
## TEXT_EDIT_SCREEN
|
||||||
|
|
||||||
@@ -191,6 +236,15 @@
|
|||||||
- кнопки `SAVE`, `CANCEL`, `DEL`, `CLR`;
|
- кнопки `SAVE`, `CANCEL`, `DEL`, `CLR`;
|
||||||
- большую экранную клавиатуру.
|
- большую экранную клавиатуру.
|
||||||
|
|
||||||
|
## REGISTER_ACCOUNT_PLACEHOLDER
|
||||||
|
|
||||||
|
Временный экран-заглушка регистрации.
|
||||||
|
|
||||||
|
Показывает:
|
||||||
|
- заголовок `REGISTER ACCOUNT`;
|
||||||
|
- сообщение, что регистрационный flow пока не реализован;
|
||||||
|
- кнопку `BACK`.
|
||||||
|
|
||||||
## Клавиатура
|
## Клавиатура
|
||||||
|
|
||||||
Клавиатура единая для всех текстовых вводов.
|
Клавиатура единая для всех текстовых вводов.
|
||||||
@@ -211,8 +265,13 @@
|
|||||||
- `wifi_ssid`
|
- `wifi_ssid`
|
||||||
- `wifi_pass`
|
- `wifi_pass`
|
||||||
- `wifi_known_good`
|
- `wifi_known_good`
|
||||||
|
- до `8` сохранённых пар `SSID -> password`
|
||||||
|
|
||||||
При старте устройства, если сохранён SSID, выполняется попытка подключения к сохранённой сети.
|
При старте устройства, если сохранён SSID, выполняется попытка подключения к текущей сохранённой сети.
|
||||||
|
|
||||||
|
Если пользователь уже вводил пароль для сети раньше:
|
||||||
|
- при повторном выборе этого SSID старый пароль сразу подставляется в editor screen;
|
||||||
|
- сохранение пароля для другой сети не удаляет уже сохранённые пароли остальных сетей.
|
||||||
|
|
||||||
Если сеть раньше уже была успешно подключена и помечена как валидная:
|
Если сеть раньше уже была успешно подключена и помечена как валидная:
|
||||||
- после потери связи устройство автоматически пытается переподключиться;
|
- после потери связи устройство автоматически пытается переподключиться;
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
# Test Device
|
# Test Device
|
||||||
|
|
||||||
Скрипт заливает официальные Arduino-примеры для быстрой проверки платы.
|
Скрипт заливает официальные Arduino-примеры для быстрой проверки платы.
|
||||||
|
`burn.sh` теперь:
|
||||||
|
- сам пытается найти USB-порт ESP32;
|
||||||
|
- сначала делает быструю инкрементальную сборку;
|
||||||
|
- если быстрая сборка не удалась, автоматически повторяет полную `clean`-сборку.
|
||||||
|
|
||||||
Для режимов `widgets`, `audio` и `hello` рядом должен лежать локальный checkout `official-demo/` из официального репозитория Waveshare. В основной git он не добавляется, потому что это большой внешний набор примеров, библиотек, прошивок и артефактов.
|
Для режимов `widgets`, `audio` и `hello` рядом должен лежать локальный checkout `official-demo/` из официального репозитория Waveshare. В основной git он не добавляется, потому что это большой внешний набор примеров, библиотек, прошивок и артефактов.
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,29 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
BOARD_DIR="$(cd "${ROOT_DIR}/.." && pwd)"
|
BOARD_DIR="$(cd "${ROOT_DIR}/.." && pwd)"
|
||||||
DEMO_BASE="${BOARD_DIR}/official-demo/examples/Arduino-v3.3.5"
|
DEMO_BASE="${BOARD_DIR}/official-demo/examples/Arduino-v3.3.5"
|
||||||
MODE="${1:-widgets}"
|
MODE="${1:-widgets}"
|
||||||
PORT="${PORT:-/dev/ttyACM0}"
|
PORT="${PORT:-}"
|
||||||
FQBN="${FQBN:-esp32:esp32:esp32s3:USBMode=hwcdc,CDCOnBoot=cdc,UploadSpeed=921600,CPUFreq=240,FlashMode=dio,FlashSize=16M,PartitionScheme=app3M_fat9M_16MB,PSRAM=opi}"
|
FQBN="${FQBN:-esp32:esp32:esp32s3:USBMode=hwcdc,CDCOnBoot=cdc,UploadSpeed=921600,CPUFreq=240,FlashMode=dio,FlashSize=16M,PartitionScheme=app3M_fat9M_16MB,PSRAM=opi}"
|
||||||
BUILD_DIR="${BUILD_DIR:-${ROOT_DIR}/.arduino-build/build-${MODE}}"
|
BUILD_DIR="${BUILD_DIR:-${ROOT_DIR}/.arduino-build/build-${MODE}}"
|
||||||
OUT_DIR="${OUT_DIR:-${ROOT_DIR}/.arduino-build/out-${MODE}}"
|
OUT_DIR="${OUT_DIR:-${ROOT_DIR}/.arduino-build/out-${MODE}}"
|
||||||
|
|
||||||
|
detect_port() {
|
||||||
|
local detected
|
||||||
|
detected="$(arduino-cli board list 2>/dev/null | awk '/\/dev\/tty(ACM|USB)/ {print $1; exit}')"
|
||||||
|
if [[ -n "${detected}" ]]; then
|
||||||
|
echo "${detected}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for candidate in /dev/ttyACM* /dev/ttyUSB*; do
|
||||||
|
if [[ -e "${candidate}" ]]; then
|
||||||
|
echo "${candidate}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
case "${MODE}" in
|
case "${MODE}" in
|
||||||
hello) SKETCH_DIR="${DEMO_BASE}/examples/01_HelloWorld" ;;
|
hello) SKETCH_DIR="${DEMO_BASE}/examples/01_HelloWorld" ;;
|
||||||
widgets) SKETCH_DIR="${DEMO_BASE}/examples/05_LVGL_Widgets" ;;
|
widgets) SKETCH_DIR="${DEMO_BASE}/examples/05_LVGL_Widgets" ;;
|
||||||
@@ -34,6 +52,13 @@ case "${MODE}" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
if [[ -z "${PORT}" ]]; then
|
||||||
|
if ! PORT="$(detect_port)"; then
|
||||||
|
echo "Failed to auto-detect ESP32 port. Set PORT=/dev/ttyACM0 ./burn.sh ${MODE}" >&2
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
echo "== Mode: ${MODE}"
|
echo "== Mode: ${MODE}"
|
||||||
echo "== Sketch: ${SKETCH_DIR}"
|
echo "== Sketch: ${SKETCH_DIR}"
|
||||||
echo "== Port: ${PORT}"
|
echo "== Port: ${PORT}"
|
||||||
@@ -41,17 +66,23 @@ echo "== FQBN: ${FQBN}"
|
|||||||
|
|
||||||
mkdir -p "${BUILD_DIR}" "${OUT_DIR}"
|
mkdir -p "${BUILD_DIR}" "${OUT_DIR}"
|
||||||
|
|
||||||
arduino-cli compile \
|
compile_args=(
|
||||||
--clean \
|
--fqbn "${FQBN}"
|
||||||
--fqbn "${FQBN}" \
|
--build-path "${BUILD_DIR}"
|
||||||
--build-path "${BUILD_DIR}" \
|
--output-dir "${OUT_DIR}"
|
||||||
--output-dir "${OUT_DIR}" \
|
--library "${DEMO_BASE}/libraries/GFX_Library_for_Arduino"
|
||||||
--library "${DEMO_BASE}/libraries/GFX_Library_for_Arduino" \
|
--library "${DEMO_BASE}/libraries/SensorLib"
|
||||||
--library "${DEMO_BASE}/libraries/SensorLib" \
|
--library "${DEMO_BASE}/libraries/XPowersLib"
|
||||||
--library "${DEMO_BASE}/libraries/XPowersLib" \
|
--library "${DEMO_BASE}/libraries/lvgl"
|
||||||
--library "${DEMO_BASE}/libraries/lvgl" \
|
--library "${DEMO_BASE}/libraries/Mylibrary"
|
||||||
--library "${DEMO_BASE}/libraries/Mylibrary" \
|
|
||||||
"${SKETCH_DIR}"
|
"${SKETCH_DIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "== Compile: fast incremental build"
|
||||||
|
if ! arduino-cli compile "${compile_args[@]}"; then
|
||||||
|
echo "== Compile: fast build failed, retrying clean build"
|
||||||
|
arduino-cli compile --clean "${compile_args[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
arduino-cli upload \
|
arduino-cli upload \
|
||||||
-p "${PORT}" \
|
-p "${PORT}" \
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
client.version=1.2.150
|
client.version=1.2.154
|
||||||
server.version=1.2.142
|
server.version=1.2.146
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Источники тестовых аватаров
|
||||||
|
|
||||||
|
- `avatar_001.png` ... `avatar_050.png`: портреты с `randomuser.me`
|
||||||
|
- `avatar_051.png` ... `avatar_100.png`: мультяшные аватары с `dicebear.com`
|
||||||
|
- Все файлы приведены к размеру `512x512`.
|
||||||
|
After Width: | Height: | Size: 174 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 245 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 239 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 265 KiB |
|
After Width: | Height: | Size: 231 KiB |
|
After Width: | Height: | Size: 252 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 261 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 286 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 231 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 251 KiB |
|
After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 286 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 272 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 267 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 268 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 303 KiB |