У меня есть проект, в котором есть основная плата с процессором и дочерняя плата с двумя микросхемами электронного измерения, подключенными к основной плате через шину SPI. Контроллером этой шины выступает ЦП, он работает на Linux, архитектуре ARM.
Мне было поручено написать драйвер (встроенный модуль ядра) для этой дочерней платы, но у меня очень ограниченный практический опыт работы с драйверами SPI для Linux. На этой картинке показано, как выглядит моя архитектура. Проблема в том, что разные графические процессоры процессора действуют как Chipselect для каждого чипа электронного метра, остальные «провода» являются общими. GPIOS изменить нельзя, они изображены такими, какие присутствуют на схемах.
В API Linux spi struct spi_device
есть поле cs_gpio, но нет других полей, описывающих мисо/mosi/rst и другие gpios, поэтому я думаю, мне нужно добавить правильное описание шины spi в DTS.
Вопрос в том, как это сделать правильно? К сожалению, я не могу найти подходящего описания dts или полного описания его полей, которые могут мне понадобиться. Тот факт, что чипов два, еще больше усложняет задачу :(
Обратите внимание, что измерения каждого чипа должны быть записаны в разных атрибутах sysfs, поскольку они измеряют электроэнергию от разных линий электропередачи. Это должно быть реализовано в одном драйвере, чтобы его нельзя было создать дважды для каждого чипа, оно должно работать для них обоих, а не так, как в этом посте ответы.
Я начал с реализации простого драйвера spi, но понятия не имею, какие значения должны быть в полях struct spi_board_info
chip_select и bus_num, а в struct spi_device
есть только поле cs_gpio и нет полей для описания строк mosi/miso/rst/sck (gpios) .
Подводя итог, не могли бы вы подсказать мне, как написать dts для моей дочерней платы и шины spi, или рассказать, как создать в драйвере / dts экземпляр, чтобы провода шины spi управлялись точными gpios?
Основная плата @Lundin является ведущей, чипы электронного метра являются подчиненными.
Пожалуйста, отредактируйте свой вопрос и добавьте больше деталей. Какое у вас оборудование? Хотите ли вы реализовать (1) драйвер ядра для своих чипов или (2) программное обеспечение пользовательского режима? Вы имеете в виду «реализацию драйвера». Добавьте ссылку на этот драйвер или хотя бы уточните какой драйвер вы имеете в виду. Возможно, оборудование SPI определяет контакты для MISO, MOSI и SCK, в то время как вы можете свободно выбирать любые GPIO в качестве сигналов CSx, если вам вообще нужен CS. Для (2) см., например. wiki.st.com/stm32mpu/wiki/… для (1) найдите существующие драйверы ядра, такие как датчики температуры SPI, например.
@Bodo Под реализацией драйвера я имею в виду Linux spi api, моя вина. Моя задача написать драйвер. Я отредактировал сообщение, чтобы объяснить это лучше.
Есть ли на плате ЦП аппаратный SPI-контроллер, или нужно все побитовать? Битбэнг можно выполнить, но производительность системы во время передачи SPI будет низкой, поскольку процессор будет привязан к времени всех битовых переходов.
@IanAbbott На схемах это очень похоже на то, что это должно быть тряской. SPI-контроллер есть, но он никак не подключается к описанной spi-шине. Я отредактировал пост, добавив еще две картинки, скриншоты со схем.
Вы можете создать побитовый SPI-контроллер из линий GPIO в дереве устройств, который будет использовать драйвер «spi-gpio» в Linux. Подробности привязки узлов дерева устройств для контроллера документированы (в формате YAML) по адресу spi-gpio.yaml. Вы можете добавить дочерние узлы для двух устройств emeter. У одного будет reg = <0>;
, а у другого reg = <1>;
, что соответствует двум линиям CS.
Кажется, вы напутали с контактами CS. INT (скорее всего) используется в качестве прерывания ЖК-дисплеем, вы не можете сделать один и тот же вывод двунаправленным для двух разных аппаратных блоков (это может быть один, например, i2c). Или ЖК не подключен? Я не понял этого...
Если это процессор V3X, то у него есть spi-контроллер. Существует также пользовательское пространство SPI и GPIO, которые вы можете вручную выбрать, выбирает чип. Все требует вменяемого железа.
@0andriy к этой плате не подключен ЖК-дисплей. Многие gpios используются не так, как было задумано allwinner :) Итак, в этой конфигурации эти контакты используются как автономный spi-контроллер.
Итак, благодаря @IanAbbott я узнал о драйвере spi-gpio в Linux ( src ) и описании привязки дерева устройств здесь.
Итак, это правильное дерево устройств:
spi-gpio {
compatible = "spi-gpio";
#address-cells = <0x1>;
ranges;
status = "okay";
sck-gpios = <&pio 4 9 GPIO_ACTIVE_HIGH>; // PE9
mosi-gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>; // PE6
miso-gpios = <&pio 4 8 GPIO_ACTIVE_HIGH>; // PE8
cs-gpios = <&pio 4 4 GPIO_ACTIVE_HIGH>, // PE4
<&pio 4 17 GPIO_ACTIVE_HIGH>; // PE17
num-chipselects = <2>;
/* Clients */
m90e32@0 {
reg = <0>;
compatible = "atmel,m90e32";
spi-max-frequency = <950000>;
};
m90e32@1 {
reg = <1>;
compatible = "atmel,m90e32";
spi-max-frequency = <950000>;
};
};
Идея состоит в том, чтобы использовать драйвер spi-gpio для связи с чипами e-meter. Это можно сделать через spidev в пользовательском пространстве или в другом модуле ядра. Более подробная информация в моем другом вопросе.
Неясно, какая плата является ведущей, а какая — подчиненной. Поскольку все шины SPI в вашей системе кажутся двухточечными, это не очевидно.