Журнал Эмбеддед-Инженера

[WiP] Использование моста USB-to-SPI MCP2210 в Линукс

USB-to-SPI bridge

Введение

   Задача состояла в том, чтобы из под десктопного линукса иметь возможность работать с SPI-интерфейсом внешних чипов, притом желательно это делать стандартным механизмом через устройство /dev/spiХ, причем решить эту задачу максимально беспроблемно без свистопляски с пересбором ядра и дров, а поскольку, если это не SBC (Single Board Computer), а десктопное детище архитектуры x86 без набортного контроллера SPI Master, то от соблазна подобрать что-то из конвертеров SPI-to-USB никуда не деться, а их существует некоторое количество.

Кандидаты USB-to-SPI 

•  CP2130 от Silicon Labs

•  MCP2210 от Микрочипа

•  FT232H от FTDI (или что-то иное подходящее от FTDI) 

   В итоге гонку выиграл MCP2210, хотя под CP2130 тоже имелись какие-то варианты решения:  https://www.silabs.com/documents/public/software/CP2130_SDK_Linux.zip и  https://github.com/Henneberg-Systemdesign/cp2130 .

MCP2210

   Некто Daniel Santos разработал линукс-драйвер для этого моста, базирующийся в то же время на более раннем драйвере https://github.com/MathewKing/mcp2210-linux от Mathew King. На данный момент драйвер умеет отправлять и получать ответы для большинства настроечных команд (настройка параметров шины SPI, управление чипом, и т.д.), чтения/записи пользовательского EEPROM и отправки/приема непосредственно сообщений SPI. Однако надо учитывать, что при работе через спецификацию устройства spidev многие вызовы через ioctl не поддерживаются и захардкожены с помощью функции fake_config().

   Без знания заранее конфигурации платы (схемотехники) с чипом MCP2210 автонастройка SPI невозможна. MCP2210 может быть сконфигурирована при начальном запуске скрипта настройки (индивидуальная настройка каждой линии ввода-вывода), для хранения этих настроек на стороне устройства идеально подходит пользовательский EEPROM размером 256 байт. Система авто-конфига получила название Creek, все настройки за исключением имени драйвера протокола и прочих строковых переменных занимают для хранения 5 байт EEPROM. Минорный функционал настроек реализован через вызовы ioctl из пользовательского окружения.

Установка

Шаг 1

Установка ядра 4.15 (ядро называется kernel-ml, доступно в репозитарии elrepo-kernel) на CentOS 7.

Шаг 2

Сборка и установка драйвера mcp2210 под linux:

git clone https://github.com/iDoka/mcp2210-linux.git
cd mcp2210-linux

make all
sudo make modules_install


 Установка правил UDEV и скрипта, который перепривязывает к конкретному устройству новый драйвер:

sudo cp udev/99_mcp2210.rules /etc/udev/rules.d
sudo udevadm control --reload-rules

sudo cp udev/rebind_sysfs_driver.sh /usr/local/sbin/
sudo chmod 0755 /usr/local/sbin/rebind_sysfs_driver.sh

 Шаг 3

Тест драйвера:

sudo modprobe mcp2210
lsmod | grep mcp2210
cd user/
LD_LIBRARY_PATH=`pwd` ./mcp2210-util --help

 Считывание конфига:

 LD_LIBRARY_PATH=`pwd` ./mcp2210-util -d /dev/usb2spi_bridge0 get config > creek.dat

 Материалы

Все изменения в udev-rules, создающие девайс, доступный из-под пользователя, доступны в моём форке: https://github.com/iDoka/mcp2210-linux

PS: если заметка помогла Вам, поделитесь ей с друзьями или коллегами: