SPI Library

WiringPi includes a library which can make it easier to use the Raspberry Pi’s on-board SPI interface.

Firstly, you need to use the gpio utility to load the SPI drivers into the kernel:

gpio load spi

If you need a buffer size of greater than 4KB, then you can specify the size (in KB) on the command line:

gpio load spi 100

will allocate a 100KB buffer. (You should not need this though, the default is more than enough for most applications).

To use the SPI library, you need to:

#include <wiringPiSPI.h>

in your program.

Functions available:

  • int wiringPiSPISetup (int channel, int speed) ;

This is the way to initialise a channel (The Pi has 2 channels; 0 and 1). The speed parameter is an integer in the range 500,000 through 32,000,000 and represents the SPI clock speed in Hz.

The returned value is the Linux file-descriptor for the device, or -1 on error. If an error has happened, you may use the standard errno global variable to see why.

  • int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;

This performs a simultaneous write/read transaction over the selected SPI bus. Data that was in your buffer is overwritten by data returned from the SPI bus.

Programs need to be linked with -lwiringPi as usual.

That’s all there is in the helper library. It is possible to do simple read and writes over the SPI bus using the standard read() and write() system calls though – write() may be better to use for sending data to chains of shift registers, or those LED strings where you send RGB triplets of data. Devices such as A/D and D/A converters usually need to perform a concurrent write/read transaction though.

Comments

SPI Library — 110 Comments

  1. I cannot get the thing to initialise.
    What could I be doing wrong?

    #include

    void main(void)
    {
    int chan=1;
    int speed=1000000;

    if( wiringPiSPISetup (chan, speed)==-1)
    {
    printf(“Could not initialise SPI\n”);
    return;
    }
    printf(“When ready hit enter.\n”);
    (void) getchar();// remove the CR
    unsigned char buff[100];

    while (1)
    {
    printf(“Input a string, Input 0 to finish “);
    gets (buff);
    if(buff[0]==’0′)
    {
    break;
    }
    else
    {
    int ret=wiringPiSPIDataRW (chan,buff,100) ;
    printf (“%s \n”, buff);

    }

    }
    } // main

    • Hey Alan! I got SPI working with the library, I actually used your code to base mine on, but there are some fundamental mistakes in your c code-

      void main()

      The above line for example, try using int main()
      {
      //Your code
      return(0)
      }

      • you also do not list your #includes

        printf

        The above function will require the std library to be included.

        Also! I used gcc to compile my c code, and got it working with the line gcc TestCode.c -l wiringPi

        The -l BASH there indicates you are linking wiringPi.

        Also! (Alot of ‘also’s’ I know!) You should add the switches “-Wall and -Wextra (If u are using gcc) and it will troubleshoot whats wrong right there in BASH.

        Cheers! Adam!

  2. Hi,

    I have used the ‘gpio load spi’ but the ‘module spidev’ is not found. Any suggestions on how to fix this issue?

    Regards

      • Yeah I am using the Raspbian system but am pretty new to this. I have followed advice on installation but then encountered a problem with the PiFace board not initialising. Following advice on other threads has now brought me to this issue. I have thus tried the ‘gpio load spi’ but encounter that problem.

        • OK. I’m surprised it’s not finding the module then. Just one thing – what version of wiringPi do you have? Run gpio -v and let me know…

          -Gordon

          • Maybe the module is blacklisted. In my standard raspbian distribution there was an entry in /etc/modprobe.d/raspi-blacklist.conf – remove it.

  3. Working with your library…having trouble with a MCP2515 CAN bus module I am trying to command via SPI to send data on a CAN bus.

    (This is a CAN BUS shield I got from sparkfun (https://www.sparkfun.com/products/10039). Works fine on arduino, and am using it on a arduino to raspberry shield from cooking hacks (http://www.cooking-hacks.com/index.php/documentation/tutorials/raspberry-pi-to-arduino-shields-connection-bridge))

    Works fine on arduino with SPI code I wrote on that. On the raspberry, I am sending identical data raspberry using your SPI library, but the CAN bus will not respond.

    have spend days and days on this. Checked timings, pins, tested backwards and forwards and have been watching the SPI bus via Salae Logic, so I can see exactly what is going on.

    I have looked at the bus with a protocol analyzer. THe only major difference I see on the SPI bus between arduino (which works) and raspberry (which doesn’t) is the the MOSI on the arduino FALLS (neutral state is HIGH) when there is data, whereas on the raspberry it rises (neutral state is LOW).

    Beyond that, I can see any difference. But the shield responds to the arduino and its SPI library, but not to the raspberry using this library.

    Could it be that rising vs falling MOSI? And if so, how can I set that?

    Really appreciate the help if you might have any thoughts or advice…

  4. Hmmm…I missed this thread, which is surprising given the days of google and forum searching I’ve been doing!

    Well, this may be applicable. However, in my case, on the logic analyzer I am not seeing any losses. And I am not reading anything from the slave, simply sending small data packets to it, and I see these show up just fine on the analyzer. This is a very slow situation with a device that is a 10mhz bus and even when I drop down speeds well below that.

    The only thing I have been noticing is that is different from a capture that works from the arduino, is that inverted MISO line, starting HIGH nad dropping LOW for signals…and I am not sure if that is meaningful or not.

    Thanks for the pointer, I do appreciate it. And it is great to have your library to work with…extremely useful.

    • There are 4 modes for SPI – to do with the clock and data polatirys. I’m initialising the Pi’s hardware in mode 0 – which is what I was under the impression that 99% of all devices seem to use – e.g. the A/D and D/A chips on the Gertboard (which is what I originally devleoped it for).

      So it might be worth while seeing what polarity/mode the CAN ship itself actually wants – my suspicion is that the initial polarity isn’t important though as the CAN chip will sample the data line on the rising clock edge, as does the Pi. (MISO being the input into the Pi).

      Are you also remembering to write enough bytes down the SPI bus to keep the other end clocking data back?

      -Gordon

      • Not sure I follow: write enough for the other end to clock data back? Could you clarify?

        (At any rate, in my use, the device doesn’t send anything back. It is being commanded and is not communicating back to the raspberry. )

        Thanks for your help, and yes, it is mode 0. The signal really looks ok on the analyzer, really not sure why the CAN Bus shield isn’t responding to it.

        • I’d need to study the datasheet in detail to see what it needs – but e.g. if you expect the chip to send back (say) 16 bytes after you send it a 4-byte command, then you need to send it 4+16 bytes, so the clock can keep going for the full duration. Some of the A/D chips I’ve used work like that.

          Although you can just use the standard write() and read() system calls too.

          -Gordon

        • I’ve no idea. My code is written in C, however if you’re using that from Java then be aware that it uses mode 0 by default.

          -Gordon

  5. Great job.
    I got quick results with Discovery board (STM32F4).
    However, when I tried to put the gpio load spi command in a crontab (@reboot), I got this errorlog:
    sh: 1: modprobe: not found
    sh: 1: modprobe: not found
    /usr/local/bin/gpio: Unable to load spi_bcm2708

    any ideas

    • In crontab, or any on the /etc/inti.d/ scripts there is no path setup..

      So: /usr/local/bin/gpio will get you the gpio command, but modprobe (which is what the gpio command calls) is /sbin/modprobe – probably my fault for not coding the full path in….

      So you might find that:

      PATH=”/bin:/usr/bin:/sbin” /usr/local/bin/gpio modprobe spi

      will do the trick.

      However, if you need the SPI drivers loaded every time, then it might be easier to simply edit /etc/modules and put them in there.

      -Gordon

    • Hi,
      I am looking for some sample code to interconnect discovery stm32f4 with pi using spi. code you help me with the same?

  6. Hi Gordon
    Many thanks for the links.
    But why to use digital pins of the raspberry but not the SPI0 or 1 output?
    I understand that it’s more easy to import the Arduino pin definition to the RPI.
    I will try to translate it to SPI “language”
    Thanks for help.
    Mike

    • Er, don’t know. I didn’t find a datasheet for that device, however to do it with GPIO pins needs too many – one for each digit and 7 for the segments. You run out of GPIO rather quickly, so using SPI to talk to an on-board controller which has the pins is an optimisation.

      If you find me the datasheet I might be able to suggest someting…

      -Gordon

    • Well it doesn’t look too bad, but I don’t know why you can’t use the software that I pointed you to that’s already been written for it using wiringPi. Just click on the download link and it’s all there.

      You don’t need the Arduino code – the Raspberry Pi code is already there. Just read it and implement it.

      -Gordon

    • Yes – if you’re using the same chip. It has 8 channels, so to read a different channel just call the readadc() function with the channel number you want.

      -Gordon

  7. Hello,

    I’m a student from Belgium and I try to communicate with the radio module CC110L by SPI GPIO connector.

    In the program below, I want to read a register from the radio module.

    “0x84” means that I want to read register 0x04.

    I received two bytes of radio module: status bytes
      register value
    But these two values ​​are null when normally not.

    My programme is correct ? I want to send one byte and receive two byte.
    (In my code i use manually the chip select)

    //—- Librairies —-

    #include
    #include
    #include
    #include
    #include
    #include
    #include
    //—- Pin Configuration —-//
    #define GPIO0 0
    #define RESET 1
    #define GPIO2 2
    #define GPIO3 3
    #define CS 4

    //—- Variables Configuration —-//
    int channel =0 ; // channels : 0 ou 1
    int speed = 500000; //speed : 500 000 to 32 000 000 => Clock speed Hz
    // 0,5 MHz 1 MHz 2 MHz 4 MHz 8 MHz 16 MHz et 32 MHz.

    uint8_t send_address[2];

    //—- Programme —-//
    int main()
    {
    printf (“Read register :\n”);
    if(wiringPiSetup() == -1)
    {
    exit(1);
    }
    if (wiringPiSPISetup (channel, speed) error
    {
    fprintf (stderr, “SPI Setup failed: %s\n”, strerror (errno));
    return 0;
    }
    pinMode (CS, OUTPUT);
    digitalWrite (CS, 0);

    delay (10);// On attend que la puce CC110L soit stable (SO == 0)
    send_address[0]= 0x84;

    printf(“Commande :%02X\n”, send_address[0]);

    wiringPiSPIDataRW(channel,send_address,1);

    printf(“Donnee recue : %02X \n”,send_address[0]);
    printf(“Donnee recue : %02X \n”,send_address[1]);

    digitalWrite (CS, 1);

    return 0;
    }

    Thanking you in advance,

    Jordan

    • Normally you’d use the CE0 or CE1 pins from the Pi as the Chip Select, but you may be doing other things here.

      You write one byte, but check 2 bytes. you need to write 2 bytes to get 2 bytes back.

      so wiringPiSPIDataRW(channel,send_address,1); should be: wiringPiSPIDataRW(channel,send_address,2);

      -Gordon

      • Thank you for your answer

        I do not use CE0 or CE1 because I use an adapter to connect the radio module. This adapter uses pin 4 (wiringPi) and not CE0, CE1. Do you think the problem could come from there?

        I’ll try: wiringPiSPIDataRW (channel, send_address, 2). If i write 2 bytes, the second byte don’t perturb the module radio?

        I will have the opportunity to work on Thursday, March 28 on the project. I’ll let you know, Thursday.

        Jordan

  8. Hi Gordon,
    The MCP23S17 I/O expander has addressing provisions for 8 devices to share an SPI bus channel. PiFace has jumpering (J1 & J2) to support up to 4 devices on a channel. I’m not aware of any library support for such channel sharing. Am I missing something?
    Thanks for your great work.

    • wiringPi v2 (will be released tomorrow or monday) will support 8 mcp23S17’s per Pi’s SPI bus, so 16 in total. Add on 8 mcp23017’s on the I2C bus and that gives you the potential for 384 more gpio pins…

      -Gordon

      • Excellent and very timely 🙂
        I presume that’s 8 MCP23017’s per I2C bus address which is a possible total of squillions of GPIOs.
        Thanks again.

        • Well – there is only one easilly accessible I2C but on the Pi, so just 8 of them. However for each group of 3 pins (and these pins can be the Pi’s own or those off a GPIO expander), you can put 4 ‘595 shift registers to give an additional 32-bits of output, so the current theoretical limit is over 10K output pins.

          They’re not fast though!

          -Gordon

      • Does this news imply an update to the Arduino IDE’s Raspberry Pi GPIO programmer to allow sharing of SPI channel with PiFace etc?

        • The issue here is getting access to anything under the PiFace – although rumour has it that they’re looking at a breakout board to go in-between the PiFace and the Pi…

          Personally, I won’t use SPI or I2C between the Pi and Arduino – serials more than good enough, although maybe if I did have a lot of data to transfer then I might look at SPI.

          However there are 2 CE pins off the Pi, so one could go to Arduino and one to the PiFace, so it should not be an issue anyway.

          -Gordon

      • Does this news imply an update to the Arduino IDE’s Raspberry Pi GPIO programmer to allow sharing of SPI channel with PiFace etc?
        Later … On reflection I’ve realised that address conflict is a small issue compared with the fundamentally different understandings of the /CE signal. As (if) I understand it, the MCU23S17 takes the Low on /CE to mean “if your address matches, let’s talk” whereas an AVR MCU takes it to mean “drop whatever you are doing and let’s talk”, two entirely different and incompatible protocols.

        • with SPI, when a device sees it’s CE going low, it’s supposed to activate an internal “reset” operation – and at that point the MISO pin on the slave can be driven – that’s the only time a slave SPI device can drive that pin. This should allow for as many SPI devices as you have CE lines – 2 on the Pi.

          One issue with programming an ATmega is that although it uses the SPI port, it doesnt use SPI prtocoll – as far as I’m aware, but I’ll need to do a bit more reading.

          Have to say though – I’ve stopped using the Pi to program via GPIO and use serial or a programmer myself… I’ll be re-doing the Gertboards stuff soon and offering a means to program it via the serial line…

          The 23S17’s are somewhat intersting in that the 3-bit address function is purely a convention used by the 23S17 – you also have to tell the 23S17 to look at those address bits too – if you don’t then all 23S17’s will accept the commands!

          -Gordon

  9. Hi Gordon, and Thank you for your work!
    I’ve trouble to interface the Raspberry with a ADC AD7715 through SPI.
    When you say:
    “It is possible to do simple read and writes over the SPI bus using the standard read() and write() system calls though – write() may be better to use for sending data to chains of shift registers, or those LED strings where you send RGB triplets of data. Devices such as A/D and D/A converters usually need to perform a concurrent write/read transaction though.”
    I don’t understand how to do it… Do I have to use MOSI and MISO as simple
    in out port, and call digitalWrite or digitalRead 8 time to send or receive a byte?

    • You don’t need to fiddle with pins inidividually, just load the kernel SPI driver then off you go…

      Start by looking at the Gertboard code I wrote for its ADC. You will need to use wiringPiSPIDataRW() for this chip though. So open the spi/chip, then you need to read the manual – stating on page 13. It looks like you need to write to the communiucations register once to setup the chip, then you write to it a 2nd time with bit 7 set high, and the RS bits high, then write/read another 2 bytes to get the data back. So 2 separate calls to wiringPiSPIDataRW() the first to send 1 byte – that happens once for initialisation, then to read the data, you do a wiringPiSPIDataRW() with 3 bytes – the first one is the communucations register bits, then next 2 are 0, but you read back the 3 bytes and extract the 16-bit value from the last 2 bytes.

      I think!

      -Gordon

      • Yes, you read quite rightly and quickly the datasheet 😉
        I’ts already working with an Arduino, without any problem.
        I am just trying to trace signals with a oscilloscope, and it seems
        that my SCLK isn’t working… and I don’t know why…

        • You should see the relevant CE line go low, then the clock will wiggle for 8 bits of every byte that goes out. If you’re not seeing anything on SCLK then I’d unplug everything and try again – make sure the SPI driver is loaded (gpio load spi)

          -Gordon

          • I’ve doubled, tripled check the wiring of my AD7715…
            … and it works finaly 🙂
            I’ve forgotten to say that I am using pi4J, sorry!
            I code as you said before, with packet of only one
            byte, but it didn’t work neither…
            But I found the solution! It works perfectly when
            the CS Pin of my AD7715 is wired to ground (no CS,
            or in other words, AD7715 is the only slave). If I
            wired it back on the CS of the Raspberry, the
            communication doesn’t work anymore…
            The “bug”* is absolutely reversible.
            *I call it a bug, but I really can’t affirm if it is
            a real one or not…
            An idea?
            PS: I will offer you some beer next time 😉

          • if it works, then leave it 🙂
            However it’s odd – a lot of SPI interfaces will use the CE line as a ‘reset’ or trigger for some internal functions, but if this works with CE low all the time, then you’ll probably be ok…

            -Gordon

  10. Hi Gordon, your library is awesome. But I have one question which I could not figure out on my own:

    How do you put the SPI-pins back into alt0 mode after you set them to input or output manually?

    I did “gpio load spi” and then was able to send/receive data over SPI. Then i did “gpio mode 12 out” and now I’m not able to put that pin back into alt0 mode, other than rebooting the Pi.

    Thanks for your help

    • To be honest – I don’t know! I suspect if you rmmod the kernel modules, then reload them (gpio load spi) it will do it though.

      -Gordon

      • Okay, “sudo rmmod spi_bcm2708” and “gpio load spi” seems to do the trick.

  11. Seems like my SPI is not working properly. When reading the values back from the wiringPiSPIDataRW function, I am getting -1. This means the ioctl functions used is returning -1.

    When reading the errno, I get: “Invalid argument”

    I am using your gertboard.c example and modify it for my purpose

    THe only difference is I set chanBits to be fixed and only send one message to my device which is: AD7753 energy metering device.

    Any help would be great!

  12. Hi!
    I have the following code:
    int main() {
    int chan=0;
    int speed=1000000;
    int pepe=wiringPiSPISetup(chan, speed);
    cout << pepe << endl;
    return 0;
    }

    But i get pepe = 3
    What does this mean?
    Thanks

    • It’s the Linux file-handle returned when you open a device. You use it with the standard read(2), write(2) system calls. The wiringPiSPIDataRW() function takes the channel number (0 or 1) and works out the file handle allocated at setup time.

      -Gordon

  13. I was testing the functionality of your wiringPi’s SPI interface. I works well. One problem I am having. When I set length of write to a value over 4096 the SPI interface stops working. I am using the below code. Any help would be appreciated.

    #include “wiringPi.h”
    #include “wiringPiSPI.h”

    #include
    #include
    #include
    #include
    #include

    #define BUF_SIZE 4096
    int main (void)
    {
    int channel=0 ;
    int i=0 ;
    int j=0 ;
    int k=0 ;
    int delaytime = 550 ;
    char outbuffer[BUF_SIZE] ;
    int cnt ;

    printf(“Raspberry Pi wiringPi SPI LED test programn”);

    // set output SPI channel to 0 and speed to 8MHz

    if (wiringPiSPISetup (0,16000000) < 0)
    {
    fprintf (stderr, "Unable to open SPI device 0: %sn", strerror (errno)) ;
    exit (1) ;
    }
    printf("Startingn") ;
    wiringPiSetupSys() ;

    while(1)
    {
    memset(outbuffer,0x33,BUF_SIZE);
    wiringPiSPIDataRW (channel, outbuffer, BUF_SIZE) ;
    delayMicroseconds (delaytime) ;
    }
    printf("Done\n") ;
    return 0 ;
    }

    • My bad. I issued command “gpio load spi” first. Then I issued “gpio load spi 100” thinking it would reload with larger buffer. When I rebooted and issued “gpoi load spi 100” it worked.

      How do you unload the spi from command?

      • There isn’t a gpio command, but a standard linux one:
        sudo rmmod [modulename]
        type lsmod to list the currently loaded modules. (I’m not near a Pi and don’t recall the names of the spi ones, but they’re obvious)

        -Gordon

        • Thanks Gordon. I am successfully transferring data to a PIC32 device at 16 Mhz.

  14. Hi
    I keep getting a “-1” for wiringPiSPISetup(0,2000);
    I did gpio load spi and lsmod shows that bcm2807 is supposed to work.
    wiringPiSetup works fine if that matters.
    Are there any other reasons for spi not setting up properly?

  15. Great job Gordon! I now have two PICs talking to my RasPi over SPI from userspace via Qt. All other methods required SU access in some way, which was not what I wanted.
    Is there no way to clock SPI less than 500kHz? I have to run the PICs at top speed to keep up!

    • I’ve not tried any lower clock rates – it won’t hurt to try – in the wiringPiSPISetup() routine… I know the current driver is powers of 2, so it’s likely to be 1Mb, 512Kb, 256Kb, 128Kb, etc.

      -Gordon

  16. Hi,
    I want to connect two SPI devices on the same MOSI/MISO/SCLK Pins: the MCP23S17 (SCK->CE0) and a MCP3008 ADC (SCK->CE1). Will that work?
    What happens when one program use the expansion chip and a separate program try to read the ADC at the same time?

    Thanks for reading and for your great library,
    Norman

    • It should work OK – that’s why there are 2 select lines – however you should use some locking to make sure that only one program is accessing the device at the same time.

      -Gordon

  17. Hi everybody !

    Does someone have examples of code for MCP2515 ?

    I have code for Arduino (SK-Pang Shield) working fine but on Raspberry (with Raspbian) I”m really a beginner !

    Best regards.

  18. Do you know of any sane way of doing synchronous operation between the 2 chip select lines? For example, I want to send/receive a ~4kB packet that alternates between CS0 and CS1 every couple of bytes.

    linux/spi/spi.h says that the message priority function between multiple spi device children is undefined, which seems pretty unhelpful.

    Is there any high-level way of doing this or am I going to have to hack apart the driver core?

      • Unfortunately not. One device is a DAC and the other an ADC, but they both have programmable state and would be affected by the signals sent to the other device if open simultaneously. I think they also inconveniently require operation in different modes.

  19. Gordon,

    Great work. I am pulling up a system and while waiting for some parts I wanted to get the SPI debugged and running while UPS meanders my package across the country. In the interim, I was looking at cross connecting 2 Pi’s to talk to each other. Is the SPI interface invertible? I don’t see any place to configure as master or slave.

    Adam

    • The Pi’s SPI is master only. Use serial. (rs232) Much easier to program and almost always fast enough for most needs.

      -Gordon

    • I’ve done it.
      Change const static uint8_t spiMode = yourchoice ;
      in wiringPiSPI.c
      then REBUILD!

  20. Hi, Gordon.
    I have one problem. When I use your SPI function, it works well the buffer size is under 4099, but over 4099 it doesn’t work.
    for example~
    wiringPiSPIDataRW(ch, arr, 4099); // everything is ok
    wiringPiSPIDataRW(ch, arr, 4100); // OMG! it doesn’t work ;-(

    and when I boot raspberry pi typed this “spi gpio load 1024”
    Is it mean “i will allocate 1Megabyte for spi buf”?

    I want to send data “unsigend char arr[320*240*2]” at a time…. help me please

    • I think you’ll find that the limit is exactly 4096 bytes…

      You can increase the kernels SPI buffer by using the gpio command to load the SPI module:

      gpio load spi 256

      will allocate 256KB for the kernels SPI DMA buffer which ought to be enough for your purpose… Not sure why your 1024 isn’t working – it’s possible there is an upper limit, but I never went that far myself!

      Sounds like you’re driving a display – I did this myself recently too and had to increase the buffer size…

      -Gordon

      • Opps! It was all my mistake.
        Before using your library, i changed file where /etc/modprobe.d/raspi-blacklist.conf

        i remembered that added ‘#’ in front of ‘blacklist spi-bcm2708’. So i remove ‘#’ then, it works. Sorry Gordon~!

        • No wories. I tend to keep the SPI & I2C modules blacklisted and use the gpio command to load them when I need them.

          e.g.

          gpio load spi

          -Gordon

  21. Hey Gordon, thanks for this awesome library.

    Do you have an example on how to use “write” to send the data to the SPI bus? How is the CE0 or CE1 Signal triggered?
    I have an issue with wiringPiSPIDataRW and want to see it this can be solved by using direct write.

    Thanks
    Marc

    • Use wiringPiSPIGetFd() to return the Linux file descriptor of the channel you opened (0 or 1), then use the standard Linux system call write()

      e.g.

      fd = wiringPiSPIGetFd (0) ;
      write (fd, buffer, len) ;

      -Gordon

  22. Hello,
    i try to communicate with a TI LMP90100 device. Read and write actions are working fine.
    I using the CE0 Pin for chip selection. It is normal that the chip select wire is always low for a selected device ? How can i change this ? CE0 should only be zero, if data will be transmitted on MOSI.

    Best regards

  23. Hi Gordon.
    I am trying to do some work with this library. But when I run my progam it gives me this error(Unable to opne SPI devide:Too many SPI descriptors).
    Have y any idea how can I delete the file descriptor when I open a SPI comunication?.
    Best Regards.

      • thank you so much Gordon.
        I have another question
        I am making a program and I use the pin 7 of my rasp as INPUT for an interrupt.
        I use the function wiringPiISR(7, INT_EDGE_RISE,&myInterrupt), but in some parts of the program I would like to disable the interrupts and enables them later.
        Can I do this? Wich way?.
        Best Regards

        • it’s not easy at present. You could write your own version and simply stop the thread running, or just set a global flag to tell the interrupt handler to ignore the interrupts.

          -Gordon

          • Ok Gordon I was trying to use this command to desactivate “system(“usr/local/gpio 22 edge none”)” and this to activate “system(“usr/local/gpio 22 edge falling”)” the interrupt in one pin. Can I do this?.
            I will try the other way.

            -Iñigo

          • I’ve no idea. Just ignore the interrupt is probably the easiest way. Or redesign your hardware so you never have to ignore/disable interrupts.

            -Gordon

  24. Hi Gordon,

    I’m having trouble getting your SPI library going, specifically wiringPiSPIDataRW. I’ve written a post about it (link in the website section of this reply). Any comments appreciated!

  25. Hi Gordon:

    I really love your job with the community. Great job and I admire all you’ve done so far. I’ve got a question for you.

    I’ve got a device that works under SPI but this device requires to load words of 16 bits straight without clock interruptions.

    I know that with spidev is possible to change the “bits_per_word” to 16 (not success with this, it seems there is a bug) but I don’t know if that is possible with wiringpi. Do you know if it’s possible to load 16 bits words in the RasPi registers? Have you tried before?

    Thanks for your help and lead!

    Mario B.

    • Just write 2 bytes in a single operation – either use the write() system call, or wiringPiSPIDataRW() with a 2-byte buffer.

      The 16-bit write will be accomplished by virtue of the CE line staying low for each byte transfered.

      Make sure you get them the right way round!

      -Gordon

  26. Hi Gordon
    Trying to use the MCP23S17 libs, but the CE0 pin is not changing. I can see the clk and MOSI line transfering data but CE0 never goes hi. As a result the port expander is not behaving as it should. I’ve looked deep into the code and don’t see where the CE0 (or CE1) pins are toggled, I presume that is part of IOctl function. Would appreciate your thoughts. W

    • The CE0/1 lines are controlled by the kernel driver that I use. At the start of the write (or ioctl), then CE line ought to go low, then it’s returned high at the end of the write/ioctl.

      -Gordon

  27. Hi Gordon,
    It’s possible configure the SPI communication to falling edge using WiringPi?
    Thanks for your help.
    Marc Q.

  28. Hi Gordon,
    I am trying reading AS3935 Lightning sensor using SPI,
    The sensor has 0x32 registers, to read any register, I am supposed to send 16 bits.From LSB, the first 2 bits are 01 indicating it is a read operation, the next 6 bits are for register to be read, the other 8 bits are 0 for read operation. For example, I needed to read register 0x00. So I had to send the command 01000000 00000000 to the sensor using SPI using the code below. The value returned is 2. I tried changing the testing with other registers, but it will always return 2. What I am I doing wrong?

    #include
    #include
    #include
    //#include
    int channel = 0;
    int speed = 1000000;
    int i;
    int main ()
    {

    if(wiringPiSetup() == -1)
    printf(“Wiring Pi Failed to open”);
    else
    printf(“WiringPi library ok! NO: %d\n\n”,wiringPiSetup());

    return(0);

    char buff[0]=0b010000;
    char buff[1]=0b0

    int returned = wiringPiSPIDataRW(channel, buffer,2)
    printf(“Value returned is %d”, returned);
    }

    • You’re not doing anything wrong, however you might be failing to understand what’s going on….

      wiringPiSPIDataRW() does not return data read as the functions return code. It returns the data read inside the buffer it reads from. Try printing out your buffer after the call to wiringPiSPIDataRW():

      printf (“%02X %02X\n”, buffer [0], buffer [1]) ;

      -Gordon

  29. You are good!
    In this function,

    int wiringPiSPIDataRW (int channel, unsigned char *data, int len)

    what does the function return as int?
    I am dealing with integers, how do I handle them using unsigned char *data?

    • The number is returns is the return code from the underlying ioctl() function call. In this case anything >= 0 is good.

      You need to take the 2 bytes that are overwritten in your data array and convert them back into a single 32-bit int. See some of my other code for examples – e.g. the A/D converters, but you’ll need to read the datasheet for your device – some devices put the bits in a funny order, or you need to pick out 12 bits from the 16, etc.

      -Gordon

  30. Hi Gordon,
    I want to use your library with L3GD20 3-axis gyroscope. How can I change the data bits from 8 bit to 16 bit? It would be also better if We have the ability to change the SPI mode and bits per word parameters directly in the wiringPiSPISetup function.

    thanks.

    • If you want to read/write more than 8 bits at a time, then just do it. See my examples. You just need to do it and as long as you ask it to write/read in a single operation, you can send MB over the SPI bus if required.

      -Gordon

  31. Is it possible to write data to SPI in chunks other then 8, 16, 24, … bits? For example, the Texas Instruments TLC5952 LED driver requires exactly 25 bits to be written each time (the most significant bit directs the data either to the command register or the output drivers latch. How can this be achieved?

    • You can write in chunks of 8 bits at a time, so to write 25 bits, you could write 32 bits in a single operation. See my examples – e.g. the Gertboard A/D converters – they exchange 16 bits in a single operation.

      -Gordon

  32. Isnt’t it possible to use both channels CE0 and CE1 in a program? Only the first initialized channel works. Initializing the second one seems to have no effect.

    if (wiringPiSPISetup(0, 1000000) < 0 && wiringPiSPISetup(1, 1000000) < 0) {
    fprintf (stderr, "SPI Setup failed: %s\n", strerror(errno));
    exit(errno);
    }

    • There should not be any issues with both channels – but the only time I’ve used both has been with the Gertboard – one channel is the A/D and the other is the A/D chips. It seemed to work well and I had no issues with it.

      However I’m wondering about the logic in your code fragment here… C processes conditionals left to right and will stop evaluating when it deems the entire expression to be true or false. You also possible want to use a logical OR here (||) as you want to fail if channel 0 OR channel 1 fails to initialise, but personally I’d use two separate if statements here, so you can print an appropriate error message and then know which one failed to initialise.

      -Gordon

  33. Hi gordon, (or perhaps anyone else?)
    Are there examples of code to read from an MCP3008 chip? Not sure where to start…
    Thanks!
    J