Эмуляция классического телефона Siemens на современном одноплатном компьютере: от дисплея до видеопотока

Вспомним культовые телефоны Siemens серии 65-75, которые были популярны около двух десятилетий назад. На их примере мы проведем увлекательный технический эксперимент. Его суть — создать управляющую библиотеку на языке C и модифицировать системную утилиту Linux, чтобы заставить старый дисплей работать в связке с современным одноплатным компьютером. В статье подробно разбираются все этапы этого процесса.

❯ 1. Аппаратная часть: воскрешение дисплея


В серию Siemens 75 входили модели C75, ME75 и CX75, различавшиеся дизайном, но имевшие общую аппаратную основу, включая дисплей с разрешением 132×176 пикселей. Для проекта был найден сильно потрепанный временем корпус телефона, предположительно, поздней реплики BenQ C75. Поскольку родной процессор устройства вышел из строя безвозвратно, было решено не пытаться его реанимировать, а перехватывать изображение на уровне управления дисплеем.

Первым делом необходимо было разобраться с самим дисплеем. Его устройство и принципы работы были подробно описаны ранее, поэтому автор не стал повторять теорию, а опирался на уже существующие наработки.

Основываясь на опыте и схеме подключения от Игоря Кизима, автор адаптировал питание дисплея. Вместо оригинальной схемы со стабилитроном и инвертором для подсветки была применена упрощенная версия: напряжение питания понижено до 5В, а светодиоды подсветки заменены на работающие от этого напряжения, что позволило избавиться от лишнего провода, хотя и слегка ухудшило равномерность подсветки.

В итоге для управления дисплеем остались две линии питания (+5В и GND) и пять сигнальных линий с логическим уровнем 3,3В.

Первоначально для тестирования дисплея была использована плата Arduino Uno на базе ATmega328. Найденная библиотека, написанная для ESP8266, использовала программную эмуляцию SPI. Её удалось портировать, заменив низкоуровневые операции управления пинами на функции Arduino `digitalWrite`. Библиотека успешно заработала, что подтвердило работоспособность дисплея.


Поскольку библиотека использовала программный SPI, пины можно было назначать гибко. Исходный код был выложен в репозиторий на GitHub. Скорость отрисовки при таком подходе была невысокой, что хорошо видно на демонстрационном видео.

Для удобства дальнейшей работы динамик был извлечен, а провода выведены через его отверстие в корпусе.

Успешный запуск дисплея на Arduino подтвердил жизнеспособность основной идеи проекта.

❯ 2. Подключаем Orange Pi GPIO: больше мощности


Медленная скорость отрисовки на Arduino была ожидаема из-за невысокой тактовой частоты и программного SPI. Для решения этой проблемы требовался более производительный контроллер. Вдохновением послужила статья, где аналогичный дисплей был подключен к Raspberry Pi. Однако в наличии был одноплатный компьютер Orange Pi, что потребовало адаптации.

Оригинальный код для Raspberry Pi использовал библиотеку для чипсета `bcm2835`, которая не подходила для Orange Pi с чипсетом `h3`. В качестве альтернативы была найдена и успешно собрана форкнутая версия библиотеки `WiringPi`, адаптированная для данной платы.

Назначение пинов GPIO на Orange Pi производится так же, как и в Arduino, через их номера.

Важным отличием стало то, что Orange Pi работает с логическими уровнями 3,3В, поэтому резисторный делитель, необходимый для Arduino (5В -> 3,3В), был убран. Схема подключения упростилась.

Библиотека для AVR была портирована на `WiringPi` с минимальными изменениями (замена `LOW`/`HIGH` на `0`/`1`). На этом этапе из неё были удалены почти все графические примитивы, осталась только функция прямой отрисовки кадра из буфера. Программа была скомпилирована через `gcc` и запущена.

Как видно на видео, прирост скорости по сравнению с Arduino был минимальным. Проблема оставалась прежней — часто вызываемая функция передачи данных по-прежнему использовала медленный программный SPI. Для реального ускорения нужно было задействовать аппаратный SPI.

❯ 3. Подключаем аппаратный SPI: достижение 60 FPS


Библиотека `WiringPi` предоставляет функции для работы с аппаратным SPI (`WiringPiSPISetup`, `WiringPiSPIDataRW`). Однако на Orange Pi его сначала нужно было включить на уровне системы. Это было сделано путём редактирования файла `/boot/armbianEnv.txt` и добавления строки `param_spidev_spi_bus=0`.

После перезагрузки в системе появилось устройство `/dev/spidev0.0`. Контакты дисплея CS, CLK и DATA были подключены к выводам аппаратного SPI0, а пины RS и RESET остались на обычном GPIO.

Первоначальная замена на аппаратный SPI не дала прироста, потому что данные отправлялись по одному байту, что влекло за собой огромные накладные расходы. Решением стала отправка данных пакетами. Ограничение буфера SPI в 4 КБ привело к разбиению всего кадра (около 44 КБ) на 11 пакетов.

Перед отправкой каждый пакет копировался в отдельный буфер с помощью `memcpy`. Также была увеличена скорость шины SPI до максимальных 32 МГц.

Эти оптимизации позволили достичь частоты кадров около 60 FPS, что, вероятно, является пределом для данной конфигурации. На видео наглядно показана разница в скорости передачи при 500 кГц и 32 МГц.

Обратите внимание: Спасение утонувшего сотового телефона. Силикагель или овсянка помогут.


В первой половине видео показана часть области отображения, отправленная за одну передачу (4096 байт). Это примерно 1/10 от общей площади экрана. Скорость шины установлена ​​на 500 кГц. Во второй половине передаются все 11 областей и скорость шины составляет 32 МГц. Другими словами, скорость передачи составляет примерно 20 Мбит/сек. В данном случае, я думаю, вы достигли верхнего предела общей производительности сборки.

❯ 4. Выводим статичный BMP-кадр: борьба с цветом


Следующим шагом стала отрисовка статичного изображения. Использовался код из статьи-ориентира, но с корректировкой смещения в заголовке BMP-файла. Первые попытки привели к искажённому изображению.

Было выявлено две основные проблемы:

  1. Необходимость сдвига массива пикселей на байт для корректного выравнивания.

  2. Несоответствие цветового формата. Adobe Photoshop по умолчанию сохраняла 16-битные BMP в формате X1R5G5B5 (с альфа-каналом), в то время как дисплей ожидал формат R5G6B5 (где на зелёный канал отводится на 1 бит больше).

В результате белый цвет (FF FF) сохранялся как FF 7F, что приводило к бирюзовому оттенку. После сохранения изображения в правильном формате цвета стали отображаться корректно. На этом этап работы с библиотекой для дисплея был завершён, и началась самая интересная часть — вывод живого видеопотока.

❯ 5. Пишем ПО для захвата экрана: поиск оптимального метода


Попытка использовать прямой рендеринг из фреймбуфера Linux (`/dev/fb0`), как в исходной статье, не увенчалась успехом из-за несовпадения данных. Изображение выводилось в виде чёрной сетки. Требовалось захватывать не весь экран, а определённую его область.

Слева: рендеринг из `/dev/fb0`. Справа: рендеринг со скриншота.

Поскольку графическая среда Armbian (XFCE) работает поверх X Window System, было решено делать скриншоты через неё. Чтобы не усложнять программу подключением библиотек `gdk` и `x11`, автор пошёл другим путём — модифицировал встроенную утилиту `xfce4-screenshooter`. В её код был добавлен новый параметр командной строки `FIXED`, позволяющий сохранять в файл заранее заданную область экрана, а не выбирать её мышью.

Утилита была пересобрана и установлена в систему. Теперь одним вызовом из терминала можно было получить скриншот нужного размера.

Однако у этого метода обнаружились существенные недостатки в производительности. Процесс захвата всего рабочего стола с последующей обрезкой и сохранением занимал от 100 до 400 мс на Orange Pi, что ограничивало частоту кадров примерно 5 FPS. Это было приемлемо для статичного контента, но не для видео.

Примечание: Позже проблема производительности была решена с помощью программного обеспечения `jsmpeg-vnc`, которое транслирует видеопоток в формате MPEG через WebSocket, позволяя кодировать и передавать только нужную область экрана с частотой более 50 FPS. Эта тема может быть раскрыта в отдельной статье.

Дополнительной сложностью стало то, что утилита сохраняла скриншоты в 24-битном формате, а дисплей требовал 16-битного (R5G6B5). Пришлось писать код для преобразования цветового пространства с использованием битовых сдвигов.

Алгоритм преобразования переводил цвет из формата `KKKKKKKK ZZZZZZZZ SSSSSSSS` (24-битный BGR) в `ZZZSSSSS KKKKKZZZ` (16-битный RGB). Для отладки использовалось цветное изображение-тест.

В итоге был создан цикл, который вызывал утилиту для создания скриншота, читала полученный BMP-файл, преобразовывала цвета и выводила кадр на дисплей. Основным узким местом оставался именно процесс захвата экрана.

❯ 6. Эмуляция сотового телефона: кульминация проекта


Для финального эксперимента был использован официальный эмулятор телефона Siemens CX75, входивший в состав пакета для разработки Java-приложений (WTK/JDK 2.0). Эмулятор, созданный около 20 лет назад, требовал для работы JDK 6u45 и Windows XP, поэтому был запущен внутри виртуальной машины.

Эмулятор полностью имитировал функционал прошивки, включая установку Java-игр. Он создавал окно с точным разрешением 132×176 пикселей, что идеально подходило под дисплей.

Для передачи изображения с виртуальной машины Windows XP на Orange Pi использовался TightVNC: сервер на Windows и клиент на Armbian. Окно эмулятора было размещено в определённой области экрана VNC-клиента, которую затем захватывал модифицированный `xfce4-screenshooter`.

Наступил ключевой момент: окно эмулятора телефона было выведено на физический дисплей того же телефона. Получилась своеобразная «матрешка».


Таким образом, видеопоток проходил через следующие слои:

  • Эмулятор CX75 (программа на языке C x86, но порт прошивки, совместимой с ARM);

  • Windows XP (виртуальная машина);

  • Windows 10 (через виртуализацию, но виртуализацию можно пропустить, выведя напрямую в VNC из XP);

  • Графический интерфейс Armbian xfce4 (через VNC);

  • кэш изображения.bmp (через xfce4-screenshooter);

  • Показать C75 (через Wired Pi + Wired PiSPI).


Для завершения эмуляции можно было бы подключить физические кнопки корпуса телефона, припаяв их контактные площадки к USB-контроллеру клавиатуры. Это позволило бы сделать управление полностью аутентичным, но в рамках данной задачи этот шаг был опущен.

❯ 7. Заключение и итоги


Итоговый результат проекта:

В ходе работы были исследованы и применены на практике технологии работы с GPIO, аппаратным SPI, библиотеками для графического интерфейса (GTK3), удалённым доступом (VNC) и преобразованием данных. Была написана и доработана библиотека для управления дисплеем с помощью `WiringPi` и создан форк утилиты для создания скриншотов.

Проект наглядно демонстрирует, как можно объединить старое аппаратное обеспечение с современными вычислительными платформами для создания нестандартных и интересных решений.

  • Написано специально для читателей Timeweb Cloud и Pikabu. Подпишитесь на наш блог, чтобы не пропустить новый и интересный материал.

  • Также подпишитесь на наш эксклюзивный канал в Telegram, посвященный техническим, информативным и юмористическим вопросам об IT, технологиях и электронике. Это будет интересно.

  • Облачный сервис Timeweb Cloud — это реферальная ссылка, которая помогает поддерживать проект.

[мое]PythonTimeweb Эмулятор ИТ-электроники для мобильных телефонов Видео на YouTube Длинная запись 8

Больше интересных статей здесь: Гаджеты.

Источник статьи: Эмуляция сотового телефона… на сотовом телефоне.