Подключение символьного ЖКИ к плате от WD MyBook Live на AppliedMicro APM82181

от автора

Добрый день!
Целью данной работы было расширение возможностей имеющейся платы от NAS WesternDigital MyBook Live.

Внешний вид:

image

По своим характеристикам данная плата очень не плоха:
Процессор: APM82181
Частота: 800 МГц
Платформа: PowerPC 44x
ОЗУ: 256 MB
ПЗУ: 512 КВ
Из интерфейсов в наличии SATA, сеть 100 Мбит/с, последовательный порт (UART, не распаян), место под отладочный разъем JTAG.
На плате была этикетка с номером 4061-705086-003 REV. AH. На другой стороне вытравлен номер 4060-705086.

Содержание статьи:
1. Подключение консоли
2. Загрузка без диска
3. Компиляция в LEDE
4. Управление портами (через LuCI и консоль)
5. Подключение к шине I2C
6. Подключение расширителя портов PCF8574
Остальное в следующей части…

Дополнения и замечания приветствуются. Поехали!

1. Подключение консоли

Для работы с платой требуется локальное подключение консоли (хотя большинство операций после загрузки можно выполнять и через SSH). Делается это просто, в интернете достаточно информации, например вот WD MyBook Live UART Port.

Распайка контактов:

image

Подключение делается к порту RS232 компьютера через переходник RS232-UART, т.к. на плате логические уровни в пределах 3.3В. Скорость по умолчанию 115200 бод.

После подключения и подачи питания в консоли видно сообщения загрузчика u-boot:

U-Boot 2009.08-svn65645 (Oct 08 2012 - 14:36:50), Build: 0.2.5  CPU:   AMCC PowerPC  UNKNOWN (PVR=12c41c83) at 800 MHz (PLB=200, OPB=100, EBC=100 MHz)        Bootstrap Option E - Boot ROM Location NOR/SRAM (8 bits)        32 kB I-Cache 32 kB D-Cache Board: Apollo-3G - APM82181 Board, 2*SATA, 1*USB I2C:   ready DRAM:  Auto calibration 256 MB FLASH: 512 kB DTT:   1 FAILED INIT Net:   PHY EC1 Register: 0x2c8c ppc_4xx_eth0  Type run flash_nfs to mount root filesystem over NFS  Hit any key to stop autoboot:  0 

Сообщение «Apollo-3G — APM82181 Board, 2*SATA, 1*USB» немного неверное, так как USB тут нет, а SATA всего один. Это связано видимо что загрузчик общий для MyBook Live и модели DUO с двумя дисками.
Если ничего не нажимать в консоли, то будет произведена попытка загрузки с жесткого диска. В нашем случае его нет, поэтому нажатием любой кнопки загрузка остановлена.

2. Загрузка без диска

В загрузчике u-boot много возможностей для работы с оборудованием.

Например можно посмотреть все цвета трехцветного светодиода.

Выключение светодиода (в загрузчике горит синим цветом):

ledtestoff 

Тест трех цветов светодиода поочередно:

ledtest

Список команд можно увидеть набрав help. Подробнее о загрузчике можно узнать здесь.
В консоли при загрузке видно, что u-boot предлагает вариант монтирования файловой системы nfs «Type run flash_nfs to mount root filesystem over NFS». В данном же случае мы будем пользоваться другим вариантом — загрузкой RAM-образа c TFTP сервера.
На компьютере поднимается сервер, например TFTPD32 (Official site), затем настраиваем плату. Устанавливаем локальный IP адрес и адрес TFTP сервера (вашего компьютера). Они должны быть из одной подсети:

setenv ipaddr '192.168.1.1' setenv serverip '192.168.1.10'

Посмотреть имена файлов, которые будут запрашиваться с TFTP сервера:

=> printenv fdt_file bootfile fdt_file=apollo3g.dtb bootfile=uImage

Заметим, что в переменной fdt_file записано имя файла дерева устройств, а в bootfile — имя файла образа RAM-диска с операционной системой.
Имена можно поменять на более удобные аналогично адресам командой setenv.
После настройки желательно сохранить новые значения переменных в ПЗУ:

=> saveenv Saving Environment to Flash... Un-Protected 1 sectors Un-Protected 1 sectors Erasing Flash... . done Erased 1 sectors Writing to Flash... done Protected 1 sectors Protected 1 sectors

Таким образом после перезагрузки или отключения питания настройки сохранятся.
После этого размещаем два необходимых файла (если у вас их нет, то об их создании смотрите в следующем разделе) на TFTP сервере и набираем команду run net_nfs.

=> run net_nfs

Waiting for PHY auto negotiation to complete.. done ENET Speed is 100 Mbps - FULL duplex connection (EMAC0) Using ppc_4xx_eth0 device TFTP from server 192.168.1.10; our IP address is 192.168.1.1 Filename 'uImage'. Load address: 0x1000000 Loading: #################################################################          #################################################################          #################################################################          #################################################################          #################################################################          #################################################################          #################################################################          # done Bytes transferred = 6680079 (65ee0f hex) Using ppc_4xx_eth0 device TFTP from server 192.168.1.10; our IP address is 192.168.1.1 Filename 'apollo3g.dtb'. Load address: 0x1800000 Loading: ## done Bytes transferred = 16384 (4000 hex) ## Booting kernel from Legacy Image at 01000000 ...    Image Name:   POWERPC LEDE Linux-4.4.21    Image Type:   PowerPC Linux Kernel Image (gzip compressed)    Data Size:    6680015 Bytes =  6.4 MB    Load Address: 00000000    Entry Point:  00000000    Verifying Checksum ... OK ## Flattened Device Tree blob at 01800000    Booting using the fdt blob at 0x1800000    Uncompressing Kernel Image ... OK    Loading Device Tree to 00ff9000, end 00ffffff ... OK

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

root@lede: uname -a Linux lede 4.4.21 #0 Fri Nov 18 03:27:44 UTC 2016 ppc GNU/Linux

3. Компиляция в LEDE

В качестве источника операционной системы для нашей платы будем использовать LEDE. Это форк OpenWRT и он поддерживает плату MyBook Live. Скачать можно здесь: apm82181-lede. Докачиваем пакеты, как написано в инструкции:

./scripts/feeds update -a  ./scripts/feeds install -a 

Запускаем конфигуратор

make menuconfig

Выбираем в качестве системы («Target System») «AppliedMicro APM821xx», в качестве подсистемы («Subtarget») — «Devices which boot from SATA (NAS)», профиль («Target Profile») — «Western Digital My Book Live». Конечным образом («Target Images») должен обязательно быть отмечен ramdisk.
Пакеты выбираем по своему усмотрению. Сохранив настройки в конфигураторе и выйдя из него, можно запустить компиляцию командой make.
После окончания процесса, если он прошел без ошибок, необходимые файлы можно забрать и положить на TFTP сервер:

  • файл bin/targets/apm821xx/sata/lede-apm821xx-sata-MyBookLiveSingle-initramfs-kernel.bin переименовываем в uImage
  • файл build_dir/target-powerpc_464fp_musl-1.1.15/linux-apm821xx_sata/tmp/lede-apm821xx-sata-MyBookLiveSingle-initramfs-kernel.bin.dtb переименовываем в apollo3g.dtb

Таким образом мы прошли этапы загрузки системы без диска.

4. Управление портами (через LuCI и консоль)

Найти в интернете схему данной платы и вообще схему любого устройства на базе процессора APM82181 мне не удалось. Поэтому будем выполнять частично реверс-инжиниринг (обратную разработку), то есть догадываться о соединениях на плате и проверять это. Разработчики LEDE видимо частично это сделали, потому что подключенные порты можно увидеть в дереве устройств или посмотреть информацию из ядра:

Порты ввода-вывода

root@lede: cat /sys/kernel/debug/gpio GPIOs 496-503, platform/4e0100000.gpio1, 4e0100000.gpio1:  gpio-498 (                    |Reset button        ) in  hi  GPIOs 504-511, platform/4e0000000.gpio0, 4e0000000.gpio0:  gpio-504 (                    |enable EMAC PHY     ) out hi  gpio-505 (                    |Enable Reset Button,) out lo  gpio-506 (                    |Power USB Core      ) out hi  gpio-507 (                    |Power Drive Port 1  ) out hi  gpio-508 (                    |?                   ) out lo  gpio-509 (                    |?                   ) out hi  gpio-510 (                    |?                   ) out lo  gpio-511 (                    |Power Drive Port 0  ) out hi

Как видно, один порт используется для ввода нажатия кнопки, остальные на вывод для управления. Понятно, что редактируя файл дерева устройств (файл с расширением .dts) можно освободить от функций любой порт в операционной системе, но это может сказаться на работоспособности функциональных блоков платы. Разве что кроме светодиода. Порты, подключенные к этому индикатору, можно использовать в своих целях. Порты обозначенные знаком вопроса, как раз к нему и подключены. А управление светодиодом доступно, например, из консоли.
По умолчанию после загрузки LEDE индикатор горит зеленым цветом.
Вот так его можно выключить:

echo 0 > /sys/class/leds/mbl\:green\:power/brightness

И включить синий:

echo 1 > /sys/class/leds/mbl\:blue\:power/brightness

Если LEDE собиралась с веб-оболочкой LuCI, то светодиодами можно управлять из браузера.

Заходим по IP адресу сетевой платы

image

В меню System заходим в LED Configuration, и настраиваем на какие события срабатывает каждый конкретный цвет светодиода. Например вот так зеленый светодиод будет мигать на приходящие и уходящие сетевые пакеты:

Сетевая активность

image

Понятно, что если использовать порты светодиода для своих нужд, то сервис, управляющий светодиодом (/etc/init.d/led) будет не нужен и драйвер тоже. А управление можно сделать из скрипта например так:

echo 1 > /sys/class/gpio/gpio508/value

5. Подключение к шине I2C

Итак, имеется возможность использовать как минимум три порта. Хотелось бы конечно иметь больше ресурсов. Можно поставить на эти порты расширитель портов, подключить его к программному порту I2C. Тогда можно набрать практически неограниченное количество портов, правда с невысоким быстродействием.
На плате имелось некоторое количество пустых посадочных мест, появилось желание проверить может на них что-то разведено, что может нам пригодиться.
Например вблизи процессора посадочное место, маркированное U12 для чипа с 8-ю ногами:

Припаян шлейф

image

Убедившись что на всех контактах не более 3.3В, был подключен цифровой анализатор.
В процессе загрузки ОС никаких сигналов обнаружено не было.
Тогда в дерево устройств было добавлено описание шины I2C, так как изначально она отсутствовала:

IIC0: i2c@ef600700 {   compatible = "ibm,iic";   reg = <0xef600700 0x00000014>;   interrupt-parent = <&UIC0>;   interrupts = <0x2 0x4>;   fast-mode;   #address-cells = <1>;   #size-cells = <0>; }; 

Понятно, что в конфигурации LEDE тоже необходимо включить поддержку I2C в ядре (kmod-i2c-core).
После компиляции, обновления файла на сервере TFTP и перезагрузки появилось устройство /dev/i2c-0.

root@lede: dmesg | grep i2c [    4.816060] i2c /dev entries driver [    4.819878] ibm-iic 4ef600700.i2c: using standard (100 kHz) mode 

Отправляя символы командой echo

root@lede: echo 11 > /dev/i2c-0 ash: write error: Remote I/O error 

был обнаружен сигнал цифровым анализатором:

image

Таким образом обнаружена аппаратная шина I2C, что сильно расширило возможности ввода-вывода данной платы.
Судя по расположению сигналов на U12 (5 — GND, 7 — SDA, 8 — SCL), это возможно предполагался ADM1032ARMZ — датчик температуры.

6. Подключение расширителя портов PCF8574

Пришло время подключить что-либо на шину I2C.
В запасах нашелся жидкокристаллический индикатор размерностью 2х16 знакомест, каждое 8х5 пикселов. Сделан в Китае на основе клона контроллера HD44780 и расширителя портов PCF8574.

ЖКИ HD44780 16×2 I2C

image

По описанию допускает питание и уровни сигналов как 5 так и 3.3В, но при проверке была обнаружена очень низкая контрастность изображения при питании 3.3В. Так как питание 5В привело бы и к уровням сигналов от 0 до 5 В, а плата рассчитана на 3.3, то пришлось сделать примитивный преобразователь уровней сигналов. Шина I2C двунаправленная, от устройства должен приходить сигнал подтверждения, поэтому как минимум на линии SDA должен быть двунаправленный преобразователь. Очень хорошо варианты схем описаны здесь: Согласование логических уровней 5В и 3.3В устройств. В нашем случае была использована

схема с полевым транзистором с изолированным затвором,

image

правда транзистор другой, подобран из аналогичных — BSS123.

Собрано на макетной плате:

image

Таким образом, на ЖКИ индикатор подано питание 5В (взято на плате с разъема питания SATA), на преобразователь уровня приходят оба питания — 3.3 и 5В.
Теперь добавим в LEDE расширитель портов.
Включаем поддержку в ядре (Kernel modules — Other modules — kmod-gpio-pcf857x… PCX857x, PCA967x and MAX732X I2C GPIO expanders), перекомпилируем, заливаем на сервер, перезагружаемся.
Смотрим наличие драйвера

root@lede: lsmod |grep pcf gpio_pcf857x            6128  0 

Подключаем (0x27 — адрес нашего расширителя на шине I2C)

root@lede: echo pcf8574 0x27 > /sys/bus/i2c/devices/i2c-0/new_device [  218.957888] pcf857x 0-0027: probed [  218.961321] i2c i2c-0: new_device: Instantiated device pcf8574 at 0x27 

Проверяем появление портов

root@lede: ls -l /sys/class/gpio/ --w-------    1 root     root          4096 Jan  1  1970 export lrwxrwxrwx    1 root     root             0 Nov 25 04:04 gpiochip488 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpiochip488 lrwxrwxrwx    1 root     root             0 Jan  1  1970 gpiochip496 -> ../../devices_platform/plb/plb:opb/4e0100000.gpio1/gpio/gpiochip496 lrwxrwxrwx    1 root     root             0 Jan  1  1970 gpiochip504 -> ../../devices/platform/plb/plb:opb/4e0000000.gpio0/gpio/gpiochip504 --w-------    1 root     root          4096 Jan  1  1970 unexport

Как видно, появилась группа портов gpiochip488 на шине I2C с адресом 0x27.
Сейчас можно добавить порты, которые будут также представлены системой, как и расположенные на процессоре, несмотря на то, что они работают через расширитель портов:

root@lede: echo 488 > /sys/class/gpio/export root@lede: echo 489 > /sys/class/gpio/export root@lede: echo 490 > /sys/class/gpio/export root@lede: echo 491 > /sys/class/gpio/export

и так до 495, так как у нас 8-и портовый расширитель в наличии.
Проверим их наличие

root@lede: ls -l /sys/class/gpio/gpio??? lrwxrwxrwx    1 root     root             0 Nov 25 04:17 /sys/class/gpio/gpio488 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio488 lrwxrwxrwx    1 root     root             0 Nov 25 04:17 /sys/class/gpio/gpio489 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio489 lrwxrwxrwx    1 root     root             0 Nov 25 04:17 /sys/class/gpio/gpio490 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio490 lrwxrwxrwx    1 root     root             0 Nov 25 04:17 /sys/class/gpio/gpio491 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio491 

Зададим направление работы на вывод

root@lede: echo out > /sys/class/gpio/gpio488/direction root@lede: echo out > /sys/class/gpio/gpio489/direction root@lede: echo out > /sys/class/gpio/gpio490/direction root@lede: echo out > /sys/class/gpio/gpio491/direction 

Если надо на ввод, то надо дать команду «in».
Ну и проверить как работает вывод, например измеряя состояние выхода тестером или цифровым анализатором. В случае подключенного к расширителю ЖКИ HD447880 можно воспользоваться тем что третий бит расширителя управляет подсветкой индикатора:

root@lede: echo 1 > /sys/class/gpio/gpio491/value root@lede: echo 0 > /sys/class/gpio/gpio491/value 

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

			IIC0: i2c@ef600700 { 				compatible = "ibm,iic"; 				reg = <0xef600700 0x00000014>; 				interrupt-parent = <&UIC0>; 				interrupts = <0x2 0x4>; 				fast-mode; 				#address-cells = <1>; 				#size-cells = <0>; 				/* Boot ROM is at 0x52-0x53, do not touch */ 				/* Unknown chip at 0x6e, not sure what it is */ 				i2cled: led@27{ 					#gpio-cells = <2>; 					compatible = "nxp,pcf8574"; 					reg = <0x27>; 					gpio-controller; 				}; 			}; 

Строки после метки i2cled заменяют команду «echo pcf8574 0x27 > /sys/bus/i2c/devices/i2c-0/new_device»
Итак, появилась и реализована на практике возможность прозрачно использовать порты ввода-вывода, подключенные через расширитель к шине I2C.

Для первой части, наверное, достаточно. Во второй части, если конечно не будет явного антагонизма в комментариях, дойдем до использования индикатора для отображения состояния системы:
image
Для этого был использован и доработан драйвер HD44780. Подключен пакет LCD4Linux, в котором также был написан новый драйвер дисплея, управляющий дисплеем командами терминала VT100, потому что существующие драйверы не подошли.
ссылка на оригинал статьи https://habrahabr.ru/post/315912/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *