Использование SPI из Python на Raspberry Pi

    Приведенная в этой статье информация получена в процессе подключения трансивера nRF24L01+ к RPi. Естественно, все это можно использовать и для работы с другими SPI устройствами.

    Для включение аппаратного интерфейса SPI нужно в файле /etc/modprobe.d/raspi-blacklist.conf закомментировать строку "blacklist spi-bcm2708" и перезагрузить Pi. Для того, что бы убедиться, что SPI включен можно запустить листинг директории /dev:

    image

    Расположение сигналов SPI на разъеме GPIO:

    image

    Для проверки корректности работы SPI нужно замкнуть между собой MOSI и MISO и выполнить следующие команды:

    $ wget https://raw2.github.com/torvalds/linux/master/Documentation/spi/spidev_test.c
    
    $ gcc spidev_test.c
    
    $ sudo ./a.out -D /dev/spidev0.0
    


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

    image

    Python модуль для работы с SPI можно взять здесь. Установка модуля выполняется следующим образом:

    $ git clone https://github.com/doceme/py-spidev
    
    $ cd py-spidev/
    
    $ sudo python setup.py install
    


    Основные функции модуля py-spidev.

    • SpiDev([bus],[client]). Return a new SPI object that is (optionally) connected to the specified SPI device interface.
    • open(bus, device). Connects the object to the specified SPI device. open(X,Y) will open /dev/spidev-X.Y
    • xfer2([values]). Perform SPI transaction. CS will be held active between blocks.
    • close(). Disconnects the object from the interface.


    Пример работы с SPI из Python:

    nrf = spidev.SpiDev(0, 0)
    nrf.xfer2([0x1, 0x8])
    nrf.close()
    
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 4

      +1
      Несколько комментариев:

      1) К raspberry pi это всё конечно же не имеет отношения, это стандартные ядерные интерфейсы. Работать будет и на любой* другой платформе.

      2) На самом деле, можно просто писать-читать в порт /dev/spidevX.X. Принципиальное отличие xfer2 и прочего, для чего все эти модули пишут — в том, что они позволяют выполнять «пачки» операций чтения/записи в одной «транзакции», без отпускания слейв-селекта в промежутке между ними.
      Для многих устройств, но не для всех, это критично.

      3) В природе существуют реализации на голом Python с помощью ctypes: вот например в quick2wire, если не страшен Python 3. Интерфейс quick2wire гораздо более человеческий.

      4) Абсолютно все периферийные устройства для SPI, которые я видел — полудуплексные, т.е. одновременно идёт либо передача, либо приём. В некоторых SoC по этому поводу используются полудуплексные SPI-мастера. На таких платформах упомянутый в статье модуль, да и большинство других, работать не будут. Фикс довольно тривиальный

      5) Я так понимаю, что конкретно в модуле, который вы упоминаете, течёт память. По крайней мере в форке что-то такое недавно фиксили, а модуль из статьи не обновлялся много лет.
        0
        Статья задумывалась как пошаговое руководство, с помощью которого можно получить python-код для работы с SPI на RPi. Специфичная именно для RPi информация все-таки присутствует, как минимум название модуля «spi-bcm2708».

        На quick2wire я смотрел в свое время внимательно, решающим не в его пользу для меня оказался именно Python 3.

        4) Абсолютно все периферийные устройства для SPI, которые я видел — полудуплексные, т.е. одновременно идёт либо передача, либо приём. В некоторых SoC по этому поводу используются полудуплексные SPI-мастера. На таких платформах упомянутый в статье модуль, да и большинство других, работать не будут. Фикс довольно тривиальный

        Эту мысль я не совсем понял. Указанный в статье модуль успешно используется для работы с nRF24L01+ и обмен там именно полудуплексный.

        5) Я так понимаю, что конкретно в модуле, который вы упоминаете, течёт память. По крайней мере в форке что-то такое недавно фиксили, а модуль из статьи не обновлялся много лет.

        Я посмотрел на коммиты, сравнил с оригинальным модулем и, если я правильно понял, фиксили они свои же изменения.
          0
          Эту мысль я не совсем понял. Указанный в статье модуль успешно используется для работы с nRF24L01+ и обмен там именно полудуплексный.

          Я неудачно выразился наверное. В общем, несмотря на то, что обмен фактически полудуплексный, вы при работе с этим модулем всегда указываете драйверу два буфера — для приёма и передачи. Просто например при «чтении» вы передаёте буфер, заполненый нулями, или вроде того. Это всё прекрасно работает, пока мастер поддерживает полнодуплексный обмен. На Raspberry Pi всё хорошо, потому что там полнодуплексный мастер. На некоторых других процессорах, например i.mx2x, такой код работать не будет, потому что мастер там может физически либо принимать, либо передавать одновременно, а сам решить какой из двух буферов вы не используете, мастер не может.

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

          BTW, а какой модуль вы для nrf24 используете в линуксе?
            0
            Тогда понятно. Я просто с такой реализацией SPI мастера не сталкивался.

            BTW, а какой модуль вы для nrf24 используете в линуксе?

            Собственной разработки. У меня организация обмена между устройствами очень простая.

      Only users with full accounts can post comments. Log in, please.