SPI Command-line Utility for Raspberry Pi

Raspberry PiiP Solu­tions has cre­ated a Ser­ial Periph­eral Inter­face (SPI) command-line util­ity for the Rasp­berry Pi (www.raspberrypi.org) plat­form.  The util­ity, spincl, is licensed under Open Source GNU GPLv3 and is being offered by iP Solu­tions as a free down­load with source included.

Although a C library exists for the Broad­com bcm2835 with an SPI Appli­ca­tion Pro­gram­ming Inter­face (API) among other things, there are rea­sons to have a command-line util­ity, which can be invoked from a shell com­mand line or from within a script.  A command-line util­ity allows easy test­ing and debug­ging of SPI slave devices with­out hav­ing to develop a C exe­cutable.  Addi­tion­ally, it pro­vides a sim­ple way for bash and python scripts to access the SPI mas­ter of the BCM2835 on Rasp­berry Pi. Although the raspian dis­tri­b­u­tion pro­vides GPIO libraries with the included python instal­la­tion it doesn’t include an SPI library. spincl, on the other hand, can be invoked from a python (or bash) script.  


spincl is a command-line util­ity for exe­cut­ing SPI com­mands with the Broad­com bcm2835 from a shell com­mand line (or script).  The util­ity is based on the bcm2835 C library devel­oped by Mike McCauley of Open Sys­tem Con­sul­tants, http://www.open.com.au/mikem/bcm2835.  It was built with ver­sion 1.17 of the bcm2835 library and tested on a Rasp­berry Pi single-board com­puter model B with an iP Solu­tions designed I/O board, which con­tains SPI acces­si­ble ADC and dig­i­tal I/O expansion.

Invok­ing spincl results in a full-duplex SPI trans­fer.  Options include the the SPI clock fre­quency, SPI Mode, chip select des­ig­na­tion, and chip select polar­ity.  Invok­ing spincl requires root priv­i­lege.  If no command-line argu­ments are included or if there are any command-line argu­ment errors, a “usage state­ment” will be printed on std­out sim­i­lar to the Usage doc­u­men­ta­tion below.


spincl [options] len [xmit bytes]

Invok­ing spincl results in a full-duplex SPI trans­fer of a spec­i­fied num­ber of bytes.  Addi­tion­ally, it can be used to set the appro­pri­ate  GPIO pins to their respec­tive SPI con­fig­u­ra­tions or return them  to GPIO input con­fig­u­ra­tion.  Options include the SPI clock fre­quency,  SPI Mode, chip select des­ig­na­tion, chip select polar­ity and an  ini­tial­iza­tion option (spi_begin and spi_end).

spincl must be invoked  with root priv­i­leges.  How­ever, as of ver­sion 1.3.0, although the make install tar­get included in the Make­file installs spincl with a root owner, it also sets the suid bit so that users other than root may invoke spincl with­out a sudo pre­fix.

The fol­low­ing are the options, which must be a sin­gle let­ter  pre­ceded by a ‘-’ and fol­lowed by another character:

  • –ix where x is the SPI init option, b[egin] or e[nd].  The begin option must be exe­cuted before any trans­fer can hap­pen.   It may option­ally be included with a trans­fer.   The end option will return the SPI pins to GPIO inputs.   It may also option­ally be included with a transfer.
  • –mx where x is the SPI mode, 0, 1, 2, or 3
  • –cx where x is the expo­nent of 2 of the clock divider.   Allowed val­ues  are 0 through 15.  Valid clock divider val­ues are pow­ers of 2.  Cor­re­spond­ing fre­quen­cies are spec­i­fied in bcm2835.h.
  • –sx where x is 0 (CS0), 1 (CS1), 2 (CS1&CS2), or 3 (None)
  • –px where x is chip select polar­ity, 0(LOW) or 1(HIGH)

len: The num­ber of bytes to be trans­mit­ted and received (full duplex).

xmit bytes:  The bytes to be trans­mit­ted if spec­i­fied.  If none are spec­i­fied, 0s will be trans­mit­ted, which may be the case when only the received data is relevant.


Use spincl to just intial­ize the SPI pins: spincl –ib

Use spincl to intial­ize the SPI pins and read three bytes (note xmit bytes are not spec­i­fied).  Mode is 2, clock fre­quency is 15.625Mhz (see bcm2835.h), chip select is 0, and polar­ity is active low:  spincl –ib –m2 –c4 –s0 –p0 3

Use spincl to trans­mit 2 bytes (spec­i­fied) and read back 2 bytes, which may or may not be rel­e­vant.  Mode is 1, clock fre­quency is 7.8125MHz, chip select is 1, and polar­ity is active high.  Note that no ini­tial­iza­tion has been spec­i­fied so SPI pins must have been pre­vi­ously ini­tial­ized:  spincl –m1 –c5 –s1 –p1 2 0x5c 0x13

Use spincl to read two byte with mode 3, clock fre­quency of 15.625Mhz, and no chip select (done by user some other way).  When the SPI tran­fer has been com­pleted, the SPI pins will be returned to GPIO inputs:  spincl –ie –m3 –c4 –s3 2

Use spincl to just return the SPI pins to GPIO inputs:  spincl –ie


Of course the spincl exe­cutable will work as is.  How­ever, if you want to make edits to the source, a Make­file is included to rebuild the exe­cutable.  The Make­file assumes that the bcm2835 library has been installed.  In other words, bcm2835.h is in /usr/local/include and libbcm2835.a is in /usr/local/lib.  To “make” the exe­cutable, type make at the command-line prompt from the spincl direc­tory.  Again, the ver­sion of the  bcm2835 library that was used to build the exe­cutable included in the down­load is 1.17.  You may wish to try build­ing spincl with the most cur­rent ver­sion.  An exam­ple “install” tar­get is included in the Make­file, which installs spincl in /opt/bin with root own­er­ship and group with appro­pri­ate priv­i­leges, includ­ing set­ting the suid bit.  Edit them as required for your application.

Get Free Download

Click here to down­load lat­est update of spincl.tar.gz     Down­load

Place the tar­ball file in the desired direc­tory and then execute:

  • tar –xzvf spincl.tar.gz (spincl_1_3_1.tar.gz as of 7/31/13)

to get the expanded source directory.


  • Ver­sion 1.3.0, 5/19/24:
    • Bug Fix:  A bug in the way the num­ber of trasmit bytes was cal­cu­lated was fixed.  Pre­vi­ously, if the total byte length of the trans­fer was greater than the num­ber of spec­i­fied xmit bytes then an attempt to access command-line argu­ments beyond the num­ber avail­able would occur, which causes a seg­men­ta­tion fault.
    • suid bit is now set in the install tar­get of Makefile.
  • Ver­sion 1.3.1, 6/25/13:
    • This ver­sion was built with the bcm2835-1.25 library.  All pre­vi­ous ver­sions were built with bcm2835-17.
    • This ver­sion was tested on 2013-02-09 raspian wheezy. The 2012-10-28 raspian wheezy was used for all pre­vi­ous versions.

iP Solu­tions in no way war­rants or guar­an­tees cor­rect­ness of the down­loaded code or that it’s bug-free.



4 thoughts on “SPI Command-line Utility for Raspberry Pi

  1. Thank you for this use­ful util­ity! Do you have plan to improve this util­ity to run it with­out root privilege?

    • Thank you Bill for your ques­tion. I had not con­sid­ered the option of run­ning the util­ity with­out root priv­i­lege because gen­er­ally an embed­ded appli­ca­tion that needs to access ker­nel resources needs to have root priv­i­lege. In this case, the SPI core on the bcm2835 chip is pro­grammed by it’s reg­is­ters that are mem­ory mapped with very spe­cific hard­ware addresses, which can only be accessed by ker­nel (device dri­ver) code. The dri­ver in this case is /dev/mem.

      You might be able to cre­ate a “work-around” for this, but it would go against the “Linux priv­i­lege model”. I should also say that most embed­ded appli­ca­tions run as root. That’s not to say that there isn’t a role for user’s with non-root priv­i­lege on embed­ded sys­tems. For exam­ple, I have a user (devel­oper) on my pri­mary Rasp­berry Pi devel­op­ment sys­tem that owns all the source code, etc. Also, you might want users with dif­fer­ent lev­els of access to var­i­ous types of data/information, etc.

      I hope this was useful.

      • Thank you Gary for explain to me in detail. I’m a new­bie to embed­ded Linux, and doesn’t have much expe­ri­ence to device dri­ver or periph­eral con­trol pro­gram­ming. I could fully under­stand your expla­na­tion. I just feel curi­ous that the util­ity “gpio” com­ing with “wiringPi” doesn’t require me to “sudo” first, and I think maybe this use­ful util­ity could have such fea­ture. Any­way, thank you for your great job! :)

        • Bill, I have not used “wiringPi”, but I checked it out. There are a cou­ple of points made by the cre­ator, which speak to the issue:
          1. “The gpio com­mand is designed to be installed as a setuid pro­gram and called by a nor­mal user with­out using the sudo com­mand (or log­ging in as root).“
          2. The gpio util­ity sup­ports GPIO exports to /sys/class/gpio.

          The first tech­nique (setuid) can just as eas­ily be done with spincl. Sim­ply use chmod to set the bit:
          chmod +s /path/spincl.
          Or edit the “install” tar­get in the Make­file to set the per­mis­sions as 4755 instead of 755:
          sudo chmod 4755 /opt/bin/spincl.
          I should point out that using setuid is con­sis­tent with my point about root priv­i­leges. In other words, because spincl is owned by root and the setuid bit trans­fers the owner’s priv­i­leges to the process that is exe­cut­ing spincl, then that user has root priv­i­leges for that process.

          The sec­ond tech­nique (/sys/class/gpio) is an embed­ded Linux method of trans­fer­ring GPIO resources from ker­nel space to user space. I don’t know if there is any equiv­a­lent for SPI.

          If you need users other than root to use spincl (I would be cau­tious about this), then your best bet is to set the ‘s’ bit (tech­nique 1 above).