Подключение символьного ЖКИ к плате от 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 16x2 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, потому что существующие драйверы не подошли.
    Поделиться публикацией

    Комментарии 19

      +1
      У этих дисплеев при разных напряжениях питания требуются разные сопротивления в цепи контраста. Достаточно было подобрать резистор :)
        0
        для нашей платы будем использовать LEDE. Это форк OpenWRT
        Они сейчас сильно разошлись с OpenWRT?
          0
          Детально не изучал, но поддержки этой платы в OpenWRT нет.
          0
          Там даже переменный резистор стоит, однако не хватило. Насколько я мог найти информацию в интернете, бывают платы с распаянным регулятором напряжения, который повышает напряжение с 3.3 до 6В, а оно уже идет на регулятор контраста. В моем случае его не было (место под U3 и пассивные компоненты рядом):
          image
            0
            Сорри, не попал в ветку, это ответ для hexus7
              0
              На самом деле достаточно припать U3, пару конденсаторов и перекинуть перемычку-соплю. Либо покупать сразу под 3.3В. На Али встречал готовые.
                0
                Согласен, тоже вариант
                0
                На самом деле преобразователь не 6 В а -3,3в
                Логика питается от 3.3в а для LCD стекляхи используется двуполярное +3.3 -3.3
                Подробнее тут
                  0
                  Спасибо за информацию, в хозяйстве пригодится)
                  Я такой вариант не рассматривал, так как был уверен что микросхемы у меня все равно нет, а транзисторы купить точно дешевле.
                  0
                  Самый прикол, что у меня ни на одном дисплее нет этого U3. Давным-давно (поэтому подробностей уже не помню) экспериментировал с PSoC3, и кучкой разнообразных дисплеев — прикрутил без особых проблем, в т.ч. и некомплектные с подсветкой.
                  0
                  -
                    0
                    У них U-Boot без пароля на консоль?
                      0
                      Да, все открыто
                      0
                      на всякий случай, откамменчу, в очередной раз, для любителей самоделок есть отличные символьные дисплеи digole, работающие через… uart! очень удобно и легко их завести даже на устройствах, на которых нет openwrt.
                        0
                        Спасибо за информацию.
                        У меня UART был занят консолью, второго не нашел, возможно не разведен, а I2C в наличии и свободна.
                          +1
                          11.49$ за 0.96 OLED? Нет, спасибо.
                            0
                            а 11.49$ за 1.8" цветной с поддержкой шрифтов и графики? ну и вообще, аналоги может назовёте более дешевые?
                          0
                          У меня есть WD mybooklive. С ним что-то случилось и он не грузится (светит светодиодом, информируя о проблеме загрузки оси). Замена диска и перепрошивка не помогли. Может с ним и все ок, просто я где-то накосячил. Но в итоге было куплено устройство другого уровня (мне только дай повод :) ). А трупик WD планирую выкинуть. Но если автор статьи обитает в Москве и ему эта тушка была бы полезна, могу отдать безвозмездно.
                            0
                            Спасибо за предложение. Обитаю не в Москве, но готов оплатить почтовые расходы по отправке тушки ко мне)

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.