Добавить очереди операций PBUS/SBUS, общую консоль, настройки Candle и SLCAN, декодеры DSView и обработку плотных графиков. Обновить протокол Бальзам и проверки общих компонентов.
205 lines
17 KiB
Markdown
205 lines
17 KiB
Markdown
# PySetTerminal
|
||
|
||
Shared PySide6 terminal migrated from PySetTerminal-master/pysetterminal.
|
||
|
||
- Standalone entry point: `python -m pysetterminal` with templates/python on PYTHONPATH.
|
||
- SETGUI embeds `pysetterminal.panel.ByteWorkPanel` in TMS2812 / Работа с байтом.
|
||
- Serial bus, macro editor, asynchronous macro execution with cancellation, PEEK/POKE and RAW console are included.
|
||
- COM transport uses QtSerialPort. Embedded operations reuse the TMS2812 connection and configured controller address.
|
||
- PEEK/POKE packet construction and response validation use the existing protocan native C ABI, with 16-bit TMS2812 values.
|
||
- Macro files are stored under the application data directory, outside the source checkout.
|
||
- The standalone launcher uses PySide6; SETGUI Windows 7 uses its existing PySide2/Qt5 compatibility layer. Frozen SETGUI builds bundle Python and Qt. Pyserial is not required. A native set-protocol runtime remains required.
|
||
|
||
`build_and_clean.py` is the migrated original standalone packaging helper.
|
||
|
||
## Подключение «Работы с байтом» в другую вкладку
|
||
|
||
Вся панель — самостоятельный `ByteWorkPanel`: чтение и запись слова, HEX/BIN,
|
||
операции с шиной, макросы, PEEK/POKE и RAW. Она не требует `Tms2812Tab`.
|
||
Данные — 16 бит, адрес слова — 32 бита; протокол по умолчанию — TMS2812.
|
||
|
||
```python
|
||
from pysetterminal.panel import ByteWorkPanel
|
||
from pysetterminal.rawprotocol import RawProtocol
|
||
|
||
# Сохраните протокол в объекте, который владеет соединением.
|
||
self.byte_protocol = RawProtocol()
|
||
self.byte_page = ByteWorkPanel(
|
||
self.byte_protocol,
|
||
device_address=lambda: self.controller_address.value(),
|
||
)
|
||
self.tabs.addTab(self.byte_page, "Работа с байтом")
|
||
|
||
# Подключение выполняется явным действием пользователя.
|
||
# self.byte_protocol.connect("COM3", 57600)
|
||
|
||
# Перед закрытием соединения:
|
||
# self.byte_page.stop()
|
||
# self.byte_protocol.disconnect()
|
||
```
|
||
|
||
В существующую компоновку панель добавляется через
|
||
`layout.addWidget(self.byte_page)`. Фабрика
|
||
`build_byte_page(protocol, **options)` возвращает такой же виджет.
|
||
|
||
Параметры:
|
||
|
||
- `protocol` — существующий протокол с методами `request_async`,
|
||
`cancel_async`, `peek`, `poke`, `send_raw`, `receive_raw`.
|
||
Асинхронный ответ передаётся в `callback(success, result)`: для чтения
|
||
`result["value"]`, для записи `result["raw"]`; ошибки — строкой.
|
||
Синхронные `peek/poke` возвращают `(success, result)`; чтение дополнительно
|
||
содержит `result["raw_response"]["raw"]` для журнала.
|
||
- `device_address` — адрес контроллера или функция, возвращающая текущий адрес;
|
||
используется всеми блоками панели. Адрес фиксируется на время записи с
|
||
проверкой и выполнения макроса.
|
||
- `macros_file` — отдельный JSON-файл макросов для конкретной вкладки.
|
||
По умолчанию сохраняется существующее хранилище приложения.
|
||
- `default_address`, `hint`, `initial_status` — начальный адрес и тексты.
|
||
- `start_word(write, address, value)` — необязательный обработчик для вкладок,
|
||
у которых уже есть очередь памяти. При чтении `value=None`.
|
||
Обработчик отвечает за чтение, проверку записи и остановку своей очереди.
|
||
|
||
Без `start_word` панель выполняет асинхронный запрос, а запись подтверждает
|
||
последующим чтением. Пример подключения к существующей очереди:
|
||
|
||
```python
|
||
self.byte_page = ByteWorkPanel(
|
||
self.protocol,
|
||
device_address=lambda: self.address.value(),
|
||
start_word=lambda write, address, value: self.start_memory(
|
||
write=write, address=address, value=value),
|
||
macros_file=self.storage_dir / "byte_macros.json",
|
||
)
|
||
self.tabs.addTab(self.byte_page, "Работа с байтом")
|
||
|
||
# В обработчике ответа очереди:
|
||
self.byte_page.set_read_value(address, value)
|
||
self.byte_page.set_status("Чтение завершено")
|
||
```
|
||
|
||
`set_status(text)` показывает внешний статус. Сигнал `status_changed(str)`
|
||
передаёт ошибки ввода и результаты операций панели владельцу.
|
||
`stop()` отменяет её асинхронный обмен и макрос; внешнюю очередь памяти
|
||
останавливает владелец вкладки.
|
||
|
||
Каждому независимому соединению нужен собственный протокол. Если вкладки
|
||
используют одно соединение, владелец транспорта должен запрещать одновременные
|
||
запросы и маршрутизировать ответы. В SETGUI это делает существующая очередь TMS2812.
|
||
|
||
## PBUS, SBUS и общие макросы
|
||
|
||
В SETGUI, на странице «Работа с байтом → Команды / макросы», слева находится
|
||
«SBUS (Сериальная шина)», справа — «PBUS (Параллельная шина)». Под обоими
|
||
блоками расположен единственный общий список макросов на всю ширину.
|
||
Один макрос может содержать команды обеих шин в произвольном порядке.
|
||
Создание, редактирование, удаление, запуск и остановка макросов сохранены.
|
||
Отдельных нижних полей «Ответ контроллера» и «Считанное слово» нет.
|
||
|
||
SBUS сохраняет прежние чтение и запись через `0x200A`, `0x200B`, `0x200F`.
|
||
Старый JSON без поля `bus` исполняется как SBUS, новые команды явно
|
||
сохраняют `bus: "sbus"` или `bus: "pbus"`. Публичные элементы `bus_*`
|
||
по-прежнему относятся к SBUS. Таблица результатов доступна как `pbus_table`.
|
||
|
||
В PBUS достаточно ввести адрес платы и регистр, затем нажать «Добавить в
|
||
таблицу» или Enter. Таблица показывает плату, регистр, HEX, DEC и состояние
|
||
считывания. Повторное добавление того же источника не создаёт дубликат.
|
||
«Убрать из таблицы» и Delete удаляют выделенные строки; Ctrl и Shift
|
||
позволяют удалить несколько источников сразу. После удаления оставшиеся
|
||
регистры уплотняются и заново записываются в аппаратную таблицу с правильными
|
||
адресами буфера. «Изменить строку» заменяет выбранную строку адресом и
|
||
регистром из полей выше. После удаления последнего регистра список
|
||
становится пустым, аппаратный и фоновый опрос остаются остановленными;
|
||
прежнее содержимое аппаратного буфера не используется как результат.
|
||
|
||
В блоке PBUS поле «Порог ошибок (1–15)» задаёт число допустимых ошибок.
|
||
Начальное значение — 10 (`0xA`), поэтому две записи запускаются словом
|
||
`0x8A01`. Выбранный порог применяется при добавлении, изменении таблицы
|
||
или нажатии «Обновить». Обычный фоновый цикл использует уже применённые
|
||
параметры и передаёт только запросы чтения памяти. Команда макроса может
|
||
явно задать свой порог; новое редактирование поля во время обмена не
|
||
меняет снимок уже поставленной команды.
|
||
|
||
Перенастройка выполняется одной операцией общей очереди: остановка через
|
||
`0x200C`, полная запись всех пар индекса `0x200D` и дескриптора `0x200E`,
|
||
затем запуск через `0x200C`. Остановка сохраняет порог и последний индекс
|
||
ранее подтверждённой активной таблицы, сбрасывая только бит 15. Запуск
|
||
содержит новый последний индекс `N-1` в младшем байте и порог в битах 11:8.
|
||
Для пустого списка выполняется только остановка, без переполнения `N-1`
|
||
и без команд запуска, включая `0x80FE`.
|
||
|
||
Дескриптор равен `(плата << 12) | (регистр << 8) | CD`. Индекс таблицы
|
||
независим от CD, а результат читается по словному адресу `0x2000 | CD`,
|
||
без умножения на размер слова. При обычном добавлении CD начинается с
|
||
`0x40`, поэтому строки читаются из `0x2040`, `0x2041` и далее. Полный
|
||
снимок настройки может содержать явный `cd` у каждой записи: это назначение
|
||
сохраняется при редактировании и перестройке таблицы. Максимум — 64 записи.
|
||
Регистр `0x2012` не читается для проверки состояния или блокировки данных.
|
||
|
||
После подтверждения запуска выдерживается поле «После запуска» в
|
||
миллисекундах; начальное значение — 100 мс. Оно настраивается по времени
|
||
обновления аппаратного буфера отдельно от периода чтения. До окончания
|
||
паузы и успешного первого чтения таблица не считается применённой и
|
||
прежние значения не показываются. Ошибка записи останавливает дальнейшие
|
||
шаги и запрещает автоматическое применение или повторный запуск.
|
||
|
||
Пример двух регистров платы `0xE` с порогом `0xA`:
|
||
|
||
```text
|
||
write(0x200C, 0x0A01)
|
||
write(0x200D, 0x0000)
|
||
write(0x200E, 0xE040)
|
||
write(0x200D, 0x0001)
|
||
write(0x200E, 0xE141)
|
||
write(0x200C, 0x8A01)
|
||
ожидание аппаратного обновления
|
||
read(0x2040)
|
||
read(0x2041)
|
||
```
|
||
|
||
«Обновить» получает значения списка. «Циклическое чтение» повторяет чтение
|
||
PBUS с выбранным периодом в миллисекундах и сохраняет выделение строк.
|
||
Циклическое чтение передаёт только ReadMemory назначений 20CD, не меняет
|
||
таблицу и не перезапускает шину. При выключении галочки отменяются будущие
|
||
повторы и неотправленные чтения; после завершения текущего пакета или
|
||
логической операции в очередь передаётся остановка `0x200C` с очищенным
|
||
битом 15 и сохранёнными параметрами активной таблицы. Повторное включение
|
||
галочки запускает аппаратно остановленную таблицу перед чтением её буфера. При изменённой или неподтверждённой
|
||
таблице необходимо явное нажатие «Обновить» для полного применения.
|
||
Изменение адреса контроллера останавливает опрос до явного применения
|
||
списка к новому устройству. В SBUS собственные галочка и период повторяют
|
||
чтение устройства и регистра из текущих полей; изменения применяются к
|
||
следующему запросу, уже отправленные параметры сохраняются.
|
||
|
||
Кнопки и поля остаются доступными во время обмена. Нажатия фиксируют
|
||
параметры и становятся в общую очередь соединения. В одной логической
|
||
операции подготовка регистра и получение результата выполняются целиком,
|
||
без перемешивания с другой операцией. Проверка записанного слова чтением
|
||
также удерживает соединение до завершения. Ручные действия обслуживаются
|
||
раньше следующего фонового задания. Периодический источник имеет не более
|
||
одного ожидающего или выполняющегося запуска; пропущенные циклы не копятся.
|
||
|
||
Макросы размещаются слева направо с переносом по ширине панели и
|
||
вертикальной прокруткой, сохраняя прежнюю высоту и естественную ширину.
|
||
Длинное имя увеличивает ширину кнопки. У каждого макроса есть галочка
|
||
«Циклически»; поле «Период повторения» в редакторе сохраняется как
|
||
`period_ms` в его JSON. Старые макросы получают период 1000 мс.
|
||
Включение сразу запускает макрос, период отсчитывается между реальными
|
||
началами повторов. Незавершённый запуск того же макроса исключает повтор,
|
||
а однократная кнопка выполнения остаётся доступной отдельно.
|
||
|
||
Общий редактор команд PBUS поддерживает `add`, `remove`, `poll`, `start`
|
||
и `stop`. Команды и будущий размер списка проверяются до первого запроса.
|
||
Ошибки порта, CRC, неверный ответ и таймаут прекращают оставшиеся команды
|
||
соответствующего запуска. Остановка снимает будущие повторения и ещё
|
||
не отправленные команды выбранного задания; текущий пакет завершается
|
||
ответом или штатным таймаутом. Отключение порта очищает всю очередь.
|
||
Уже переданные аппаратные записи не откатываются.
|
||
|
||
Рабочие панели SETGUI используют существующие `QDockWidget` и
|
||
`QMainWindow`: перемещаются влево, вправо, вверх, вниз и в общую группу
|
||
вкладок со штатной подсветкой области вставки. Разделители меняют размеры.
|
||
Перенос сохраняет экземпляры панелей, соединение и выполняемые задания.
|
||
Раскладка сохраняется между запусками; «Сбросить раскладку» возвращает
|
||
стандартное расположение без пересоздания содержимого.
|