Перейти к основному содержимому

GPIO разъем GP40

Использование выводов в режиме GPIO

Все выводы разъема по умолчанию настроены на работу в режиме GPIO.
Для ручной установки или чтения состояния выводов можно использовать команды:

set -- $(gpiofind I2C2_SDA)
gpioset -m wait "$1" "$2=1"

и

set -- $(gpiofind I2C2_SDA)
gpioget "$1" "$2"

Здесь I2C2_SDA - название вывода разъема, указанное в описании дерева устройства. Соответствие номеров выводов разъема и их названий представлено в таблице ниже.

НомерНазваниеНомерНазвание
13V325V
3I2C2_SDA45V
5I2C2_SCL6GND
7PWM_OENA08UART1_TXD
9GND10UART1_RXD
11CAN_RX12PCM_CLK
13GPIO1_D114GND
15GPIO1_D616GPIO1_D0
173V318SPI1_CS2
19SPI1_MOSI20GND
21SPI1_MISO22GPIO0_B0
23SPI1_SCLK24SPI1_CS0
25GND26SPI1_CS1
27I2C3_SDA28I2C3_SCL
29GPIO1_D730GND
31PWM_OENB032PWM_OENA1
33PWM_OENB134GND
35PCM_FS36CAN_TX
37SPI1_CS338PCM_DIN
39GND40PCM_DOUT

Включение UART на разъеме GPIO

На разъем GPIO выведен интерфейс UART1:

UART1_TXD -> GPIO0_B6 -> вывод 8
UART1_RXD -> GPIO0_B5 -> вывод 10

Для включения UART1 нужно добавить слой eltay-sc-uart1.dtbo в конфигурационный файл /boot/extlinux/extlinux.conf:

fdtoverlays /boot/overlays/eltay-sc-uart1.dtbo

После сохранения изменений в файле и перезагрузки устройства проверить, что UART1 появился:

dmesg | grep -Ei 'serial|ttyS|uart|1640000'

Ожидаемая строка:

1640000.serial: ttyS1 ... is a 16550A

В этом случае UART1 доступен как /dev/ttyS1.


Включение I2C на разъеме GPIO

На разъем GPIO выведены две I2C-шины - I2C2 и I2C3:

I2C2_SDA -> GPIO1_A3 -> вывод 3
I2C2_SCL -> GPIO1_A2 -> вывод 5

I2C3_SDA -> GPIO1_A5 -> вывод 27
I2C3_SCL -> GPIO1_A4 -> вывод 28

Для включения I2C2 нужно добавить слой eltay-sc-i2c2.dtbo в конфигурационный файл /boot/extlinux/extlinux.conf:

fdtoverlays /boot/overlays/eltay-sc-i2c2.dtbo

Для включения I2C3 добавить:

fdtoverlays /boot/overlays/eltay-sc-i2c3.dtbo

I2C2 и I2C3 можно включить одновременно:

fdtoverlays /boot/overlays/eltay-sc-i2c2.dtbo /boot/overlays/eltay-sc-i2c3.dtbo

После сохранения изменений в файле и перезагрузки устройства проверить, что шина появилась:

ls -l /dev/i2c-*

for d in /sys/class/i2c-dev/i2c-*; do
echo "$d -> $(readlink -f "$d/device")"
done

Ожидаемые соответствия:

1720000.i2c -> I2C2
1730000.i2c -> I2C3

В этом случае для I2C2 используется номер шины 2, а для I2C3 — номер шины 3.

Для работы с шиной можно использовать инструмент i2c-tools:

# поиск устройств на шине I2C2
i2cdetect -y -r 2
# запись одного байта 0x10 в устройство с адресом 0x42, подключенное к шине I2C2
i2ctransfer -y 2 w1@0x42 0x10
# чтение 4х байтов из устройства с адресом 0x42, подключенного к шине I2C2
i2ctransfer -y 2 r4@0x42

Включение SPI на разъеме GPIO

На разъем GPIO выведена шина SPI1:

SPI1_MOSI -> GPIO1_C1 -> вывод 19
SPI1_MISO -> GPIO1_C2 -> вывод 21
SPI1_SCLK -> GPIO1_C0 -> вывод 23
SPI1_CS0 -> GPIO1_C3 -> вывод 24
SPI1_CS1 -> GPIO1_C4 -> вывод 26
SPI1_CS2 -> GPIO1_C5 -> вывод 18
SPI1_CS3 -> GPIO1_C6 -> вывод 37

Для включения SPI1 в тестовом режиме нужно добавить слой eltay-sc-spi1-spidev-cs0.dtbo в конфигурационный файл /boot/extlinux/extlinux.conf:

fdtoverlays /boot/overlays/eltay-sc-spi1-spidev-cs0.dtbo

После сохранения изменений и перезагрузки устройства проверить, что появился интерфейс spidev:

dmesg | grep -Ei 'spi|spidev|1760000'
ls -l /dev/spidev*

Ожидаемый результат: /dev/spidev2.0, номер может отличаться.

Тестовый слой eltay-sc-spi1-spidev-cs0.dtbo включает SPI1 в режиме master и создает userspace-устройство spidev с CS0. В overlay это задается строками:

pinctrl-0 = <&spi1_mux_data
&spi1_mux_ss0
&spi1_mux_ss_in
&spi1_default_cfg>;

spidev@0 {
compatible = "rohm,dh2228fv";
reg = <0>;
spi-max-frequency = <1000000>;
};

&spi1_mux_ss0 включает аппаратный вывод SS0, а reg = <0> привязывает устройство к CS0.

Для использования другого CS нужно заменить обе части overlay. Например, для использования CS2 необходимо ввести:

pinctrl-0 = <&spi1_mux_data
&spi1_mux_ss2
&spi1_mux_ss_in
&spi1_default_cfg>;

spidev@2 {
compatible = "rohm,dh2228fv";
reg = <2>;
spi-max-frequency = <1000000>;
};

При этом &spi1_mux_ss_in необходимо оставлять в списке pinctrl-0.

При подключении на SPI реального устройства с kernel-драйвером, вместо тестового spidev@0 нужно описать это устройство. Например:

&spi1 {
status = "okay";

pinctrl-names = "default";
pinctrl-0 = <&spi1_mux_data
&spi1_mux_ss0
&spi1_mux_ss_in
&spi1_default_cfg>;

#address-cells = <1>;
#size-cells = <0>;

device@0 {
compatible = "vendor,device-name";
reg = <0>;
spi-max-frequency = <1000000>;
};
};

В этом случае compatible должен соответствовать драйверу подключенного SPI-устройства.

При изменении только overlay-файла полная пересборка SDK не требуется. Достаточно пересобрать только rootfs.


Включение PWM на разъеме GPIO

На разъем GPIO выведены два PWM-канала, каждый из которых может быть направлен на выход OUTA или OUTB. То есть на разъеме доступно 4 вывода, с которых можно снять PWM сигнал, но в одной сессии одновременно могут работать только два вывода.
Соответствие каналов:

pwm0 = PWM_CH0
pwm1 = PWM_CH1

PWM_CH0 OUTA -> GPIO1_D2 -> PWM_OENA0 -> вывод 7
PWM_CH0 OUTB -> GPIO1_D3 -> PWM_OENB0 -> вывод 31

PWM_CH1 OUTA -> GPIO1_D4 -> PWM_OENA1 -> вывод 32
PWM_CH1 OUTB -> GPIO1_D5 -> PWM_OENB1 -> вывод 33

Для работы с PWM доступно несколько overlay-файлов, в конфигурационный файл /boot/extlinux/extlinux.conf необходимо добавить только один из них:

  • для включения только канала PWM_CH0:
    fdtoverlays /boot/overlays/eltay-sc-pwm-ch0.dtbo
  • для включения только канала PWM_CH1:
    fdtoverlays /boot/overlays/eltay-sc-pwm-ch1.dtbo
  • для включения обоих каналов:
    fdtoverlays /boot/overlays/eltay-sc-pwm-ch0-ch1.dtbo

После внесения изменений в файл необходимо перезагрузить устройство.

Выбор физического выхода (OUTA или OUTB) выполняется в файлах overlay через свойство elvees,output-channel и соответствующий pinctrl-0.

Для PWM_CH0:

Выбрать OUTA: elvees,output-channel = <0 0 0 0>; pinctrl-0 = <&pwm_oena0_mux>;
Выбрать OUTB: elvees,output-channel = <1 0 0 0>; pinctrl-0 = <&pwm_oenb0_mux>;

Для PWM_CH1:

Выбрать OUTA: elvees,output-channel = <0 0 0 0>; pinctrl-0 = <&pwm_oena1_mux>;
Выбрать OUTB: elvees,output-channel = <0 1 0 0>; pinctrl-0 = <&pwm_oenb1_mux>;

Для одновременной работы двух каналов:

PWM_CH0 OUTA + PWM_CH1 OUTA:
elvees,output-channel = <0 0 0 0>;
pinctrl-0 = <&pwm_oena0_mux &pwm_oena1_mux>;

PWM_CH0 OUTB + PWM_CH1 OUTB:
elvees,output-channel = <1 1 0 0>;
pinctrl-0 = <&pwm_oenb0_mux &pwm_oenb1_mux>;

PWM_CH0 OUTB + PWM_CH1 OUTA:
elvees,output-channel = <1 0 0 0>;
pinctrl-0 = <&pwm_oenb0_mux &pwm_oena1_mux>;

PWM_CH0 OUTA + PWM_CH1 OUTB:
elvees,output-channel = <0 1 0 0>;
pinctrl-0 = <&pwm_oena0_mux &pwm_oenb1_mux>;

Все выводы, перечисленные в pinctrl-0, переключаются из режима GPIO в аппаратную функцию PWM. Если какой-либо вывод должен использоваться как GPIO, его mux не должен быть указан в PWM overlay.

После изменения overlay-файла необходимо пересобрать rootfs.

Запуск PWM-сигнала через sysfs

После загрузки устройства с выбранным overlay нужный канал необходимо экспортировать через sysfs.
Пример для pwm0:

PWMCHIP=/sys/class/pwm/pwmchip0
echo 0 > "$PWMCHIP/export"

После этого появится каталог /sys/class/pwm/pwmchip0/pwm0.

Запуск генерации сигнала с частотой 1 кГц и 50% заполнением:

echo 0 > "$PWMCHIP/pwm0/enable" 2>/dev/null
echo 1000000 > "$PWMCHIP/pwm0/period"
echo 500000 > "$PWMCHIP/pwm0/duty_cycle"
echo normal > "$PWMCHIP/pwm0/polarity" 2>/dev/null
echo 1 > "$PWMCHIP/pwm0/enable"

Параметры задаются в наносекундах:

period = 1000000 ns = 1 мс = 1 кГц
duty_cycle = 500000 ns = 50 %

Отключение генерации сигнала:

PWMCHIP=/sys/class/pwm/pwmchip0
echo 0 > "$PWMCHIP/pwm0/duty_cycle"
echo 0 > "$PWMCHIP/pwm0/enable"

Освобождение канала:

echo 0 > "$PWMCHIP/unexport"

Для экспорта канала pwm1 используется команда echo 1 > /sys/class/pwm/pwmchip0/export, для освобождения канала - echo 1 > "$PWMCHIP/unexport", а в остальных командах путь pwm0 заменяется на pwm1.


Включение I2S на разъеме GPIO

На разъемe GPIO доступен интерфейс I2S:

PCM_CLK -> MFBSP0_LCLK -> вывод 12
PCM_FS -> MFBSP0_LDAT1 -> вывод 35
PCM_DIN -> MFBSP0_LDAT2 -> вывод 38
PCM_DOUT -> MFBSP0_LDAT3 -> вывод 40

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

Ограничение по работе GPIO при использовании I2S

При включении I2S часть ресурсов разъема занимает аудиодрайвер. Поэтому выводы, которые в обычном режиме могли бы использоваться как GPIO, при работе I2S через штатные средства Linux недоступны. В частности, недоступны следующие выводы:

вывод 11 -> MFBSP0_LDAT6 -> CAN_RX
вывод 36 -> MFBSP0_LDAT7 -> CAN_TX

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

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

DIR_REG = 0x1f0a1308
DAT_REG = 0x1f0a130c

бит 8 -> вывод 11 / CAN_RX
бит 9 -> вывод 36 / CAN_TX

Например, для управления выводами в режиме выходов необходимо сохранить исходные значения:

DIR_REG=0x1f0a1308
DAT_REG=0x1f0a130c

DIR_ORIG=$(devmem $DIR_REG 32)
DAT_ORIG=$(devmem $DAT_REG 32)

Назначить CAN_RX и CAN_TX выходами:

DIR_NOW=$(devmem $DIR_REG 32)
devmem $DIR_REG 32 $(printf "0x%08x" $((DIR_NOW | 0x300)))

И с помощью масок изменять состояние указанных выводов. Ниже представлено несколько примеров.
Установить CAN_RX = 1, CAN_TX = 0:

DAT_NOW=$(devmem $DAT_REG 32)
devmem $DAT_REG 32 $(printf "0x%08x" $(((DAT_NOW | 0x100) & ~0x200)))

Установить CAN_RX = 0, CAN_TX = 1:

DAT_NOW=$(devmem $DAT_REG 32)
devmem $DAT_REG 32 $(printf "0x%08x" $(((DAT_NOW | 0x200) & ~0x100)))

Установить оба вывода в 0:

DAT_NOW=$(devmem $DAT_REG 32)
devmem $DAT_REG 32 $(printf "0x%08x" $((DAT_NOW & ~0x300)))

Установить оба вывода в 1:

DAT_NOW=$(devmem $DAT_REG 32)
devmem $DAT_REG 32 $(printf "0x%08x" $((DAT_NOW | 0x300)))

Вернуть исходное состояние:

devmem $DAT_REG 32 $DAT_ORIG
devmem $DIR_REG 32 $DIR_ORIG

Работа I2S в режиме playback (вывод звука наружу)

Для примера организации работы I2S в режиме playback доступен слой eltay-sc-mfbsp0-i2s-pcm5102a.dtbo, позволяющий выводить звук наружу с помощью внешней микросхемы ЦАП PCM5102A. Для использования слоя необходимо добавить следующую строку в конфигурационный файл /boot/extlinux/extlinux.conf:

fdtoverlays /boot/overlays/eltay-sc-mfbsp0-i2s-pcm5102a.dtbo

После внесения изменений в файл необходимо перезагрузить устройство.

Также необходимо, чтобы в состав ядра входили драйверы, в конфигурации ядра обозначенные как:

CONFIG_MODULES=y
CONFIG_SND=m
CONFIG_SND_SOC=m
CONFIG_SND_SIMPLE_CARD=m

CONFIG_SND_SOC_PCM5102A=m

Для включения нужных драйверов можно подключить фрагмент linux_audio.fragment в используемый конфигурационный файл Buildroot строкой BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_ELTAY_SC_PATH}/board/eltay/eltay-sc-r1.0.0/fragments/linux_audio.fragment" и пересобрать ядро.

Подключение:

вывод 12 / PCM_CLK -> PCM5102A BCK / BCLK
вывод 35 / PCM_FS -> PCM5102A LRCK / WS / LCK
вывод 40 / PCM_DOUT -> PCM5102A DIN
GND -> PCM5102A GND
3.3V -> PCM5102A VCC / VIN

PCM_DIN (вывод 38) в этом режиме не используется.

После сохранения изменений и перезагрузки устройства в системе должно появиться ALSA playback-устройство. Проверка:

cat /proc/asound/cards
cat /proc/asound/pcm
aplay -l

Ожидаемый вывод:

0 [eltayscpcm5102a]: simple-card - eltay-sc-pcm5102a
eltay-sc-pcm5102a
00-00: 1f0a1300.i2s-pcm5102a-hifi pcm5102a-hifi-0 : : playback 1
card 0: eltayscpcm5102a [eltay-sc-pcm5102a], device 0

Для запуска воспроизведения сигнала можно использовать команду:

aplay -D hw:0,0 /tmp/test.wav

где /tmp/test.wav - название файла, содержащего необходимый сигнал.

Для работы с другой микросхемой необходимо аналогичным образом описать её и добавить новый overlay слой в папку с исходниками - /external-eltaySC/board/eltay/eltay-sc-r1.0.0/overlays/. Также при необходимости подключить дополнительные драйверы для используемой микросхемы.
При добавлении только overlay-файла полная пересборка SDK не требуется, достаточно пересобрать только rootfs. При подключении новых драйверов необходимо заново собрать и ядро.

Работа I2S в режиме capture (ввод звука в устройство)

Для примера организации работы I2S в режиме capture доступен слой eltay-sc-mfbsp0-i2s-wm8782.dtbo, позволяющий заводить звук в микрокомпьютер с помощью внешней микросхемы АЦП WM8782. Предполагается, что WM8782 работает как I2S master, а устройство принимает сигналы BICK/LRCK/DATA.

Для использования слоя необходимо добавить следующую строку в конфигурационный файл /boot/extlinux/extlinux.conf:

fdtoverlays /boot/overlays/eltay-sc-mfbsp0-i2s-wm8782.dtbo

После внесения изменений в файл необходимо перезагрузить устройство.

Также необходимо, чтобы в состав ядра входили драйверы, в конфигурации ядра обозначенные как:

CONFIG_MODULES=y
CONFIG_SND=m
CONFIG_SND_SOC=m
CONFIG_SND_SIMPLE_CARD=m

CONFIG_SND_SOC_WM8782=m

Для включения нужных драйверов можно подключить фрагмент linux_audio.fragment в используемый конфигурационный файл Buildroot строкой BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_ELTAY_SC_PATH}/board/eltay/eltay-sc-r1.0.0/fragments/linux_audio.fragment" и пересобрать ядро.

Подключение:

вывод 12 / PCM_CLK -> WM8782 BICK
вывод 35 / PCM_FS -> WM8782 LRCK
вывод 38 / PCM_DIN -> WM8782 DATA
GND -> WM8782 GND
5V -> WM8782 VCC

PCM_DOUT (вывод 40) в этом режиме не используется.

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

После сохранения изменений и перезагрузки устройства в системе должно появиться ALSA capture-устройство. Проверка:

cat /proc/asound/cards
cat /proc/asound/pcm
arecord -l

Ожидаемый вывод:

0 [eltayscwm8782 ]: simple-card - eltay-sc-wm8782
eltay-sc-wm8782
00-00: 1f0a1300.i2s-wm8782 wm8782-0 : : capture 1
**** List of CAPTURE Hardware Devices ****
card 0: eltayscwm8782 [eltay-sc-wm8782], device 0: 1f0a1300.i2s-wm8782 wm8782-0 []

Команда для записи сигнала в режиме 24 bit / 192 kHz:

arecord -D hw:0,0 -f S24_LE -r 192000 -c 2 -d 5 /tmp/wm8782_test.wav

где /tmp/wm8782_test.wav - название файла, содержащего результаты записи.

Для работы с другой микросхемой необходимо аналогичным образом описать её и добавить новый overlay слой в папку с исходниками - /external-eltaySC/board/eltay/eltay-sc/overlays/. Также при необходимости подключить дополнительные драйверы для используемой микросхемы.
При добавлении только overlay-файла полная пересборка SDK не требуется, достаточно пересобрать только rootfs. При подключении новых драйверов необходимо заново собрать и ядро.

Включение CAN на разъеме GPIO

На разъемe GPIO доступен интерфейс CAN:

CAN_RX -> MFBSP0_LDAT6 -> вывод 11
CAN_TX -> MFBSP0_LDAT7 -> вывод 36

Это логические сигналы контроллера CAN, а не линии CAN-шины. Для подключения к CAN-шине нужен внешний CAN-трансивер. Пример подключения:

CAN_TX -> TXD CAN-трансивера
CAN_RX <- RXD CAN-трансивера
GND -> GND CAN-трансивера
CANH/CANL CAN-трансивера -> CAN-шина

При использовании 5-вольтового CAN-трансивера сигнал RXD необходимо привести к уровню 3,3В, прежде чем подключать его к выводу CAN_RX микрокомпьютера.

Для включения CAN нужно добавить слой eltay-sc-mfbsp0-can.dtbo при работе с ревизией платы Eltay SC rev.1.0.0 или слой eltay-sc-mfbsp1-can.dtbo при работе с ревизией платы Eltay SC rev.1.0.1 в конфигурационный файл /boot/extlinux/extlinux.conf, например:

fdtoverlays /boot/overlays/eltay-sc-mfbsp1-can.dtbo

После сохранения изменений и перезагрузки устройства проверить, что появился интерфейс can0:

ip link show can0

Ожидаемый результат:

can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN

Для запуска CAN, например на скорости 500 кбит/с:

ip link set can0 down 2>/dev/null
ip link set can0 type can bitrate 500000 loopback off
ip link set can0 up

ip -details link show can0

Ожидаемый вывод в случае успешного запуска:

can state ERROR-ACTIVE
bitrate 500000

Для проверки CAN-контроллера без внешнего трансивера можно использовать внутренний loopback:

ip link set can0 down 2>/dev/null
ip link set can0 type can bitrate 500000 loopback on
ip link set can0 up

После включения интерфейса проверить передачу и убедиться, что отправленные данные соответствуют принятым.

Для работы с реальной CAN-шиной loopback должен быть отключён:

ip link set can0 down 2>/dev/null
ip link set can0 type can bitrate 500000 loopback off
ip link set can0 up