Два SPI-джойстика, соединённых последовательно на одном чипе и одних часах. В документации на джойстики значится, что после активации ножки CS надо дать им 35 мс времени на подготовку данных.
SK-iMX6S-OEM-Ind
SK-iMX6S/53/50-MB
buildroot-2017.08 на базе ядра 4.1.15-2.1.0 для i.mx6 от sasamy (тык).
Что не так:
На первый взгляд всё хорошо: циферки приходят правильные, успешно парсятся, вроде бы профит. Код этот исполняется регулярно в цикле, между повторами sleep потока 5 мс. Долго работала программа с этим кодом, да вот заглянул я в утилиту top и глаза на лоб полезли: выше моей программы торчит процесс spi0 и жрёт 55-60% (!!!) процессорного времени. Такое ощущение, что во время пресловутого таймаута в 35000 мкс драйвер заставляет процессор делать while(1).
Почему код написан именно так:
Если разбить на два трансфера и вставить между ними православный sleep, то между трансферами CS возвращается в пассивное состояние, и никакие данные джойстиками не готовятся. Есть идея отвязать CS от стандартной ноги SPI и завладеть ею самому через банальный GPIO, но, хоспаде, это же такой костыль! Очень не хочется этого делать.
Вопросы:
1. Может, я всё-таки что-то упускаю из виду с драйвером spidev?
2. Может, кто-то знает иной драйвер?
Заранее благодарю за помощь!
Upd. Гипотеза про while(1) подтверждается: заменил 35000 на 35. Джойстики не работают, но и загруженность проца от spi0 упала с ~60% до ~3%...
У вас все работает именно так как и должно работать. В исходниках драйвера spi написано:
udelay - программная задержка типа while(1)...
И подобное в полный рост используют в патчах реализации RS485 на uart без его аппаратной поддержки.
"финские студенты" совершенно не умеют писать драйвера и работать с оборудованием да и те кто умеют пишут лишь бы собралось без варнингов.
При такой задержке вам лучше использовать gpio и рулить им вместо cs spi интерфейса.
это вообще не драйвер - это прослойка в юзерспейс для доступа к spi-мастеу, больше для тестов а не реальной работы с оборудованием
так вам и нужно написать драйвер ядра для устройства ввода а не в юзерспейс прослойки дергать.
Чтобы исправить то что уже сделано - можно в качестве CS драйаеру SPI указать "левый" gpio а реальным управлять из юзерспейс и использовать таймер для задержки.
Даже если писать нормальный драйвер ядра для такой огромой задержки 35 ms чипселектом придется управлять вручную.
ф-ции передачи данных по SPI вызываются в контексте прерывания - там возможны только такие задержки, перепланирование в таком контексте недопустимо - засыпать такой контекст не может, в таком контексте вообще лучше не делать никакие задержки.
Я не совсем прав, называя его джойстиком. Это министик.
Он работает как сдвиговый регистр и возвращает четыре 16-битных слова (значения АЦП по четырём полуосям). Данные готовы через 35 мс после активации CS.
В любом случае, всем огромное спасибо за отклики! Я уже переписал всё, управляя ножкой CS самостоятельно. Работает, процессорное время не жрётся.