NAME

RPi::SPI - Communicate with devices over the Serial Peripheral Interface (SPI) bus on Raspberry Pi

SYNOPSIS

# channel 0 and 1 are the hardware SPI pins
# CE0 and CE1

my $spi = RPi::SPI->new(0);

my $buf = [0x01, 0x02];
my $len = 2;

my @data = $spi->rw($buf, $len);

# use a GPIO pin to expand the number of SPI
# channels. The transfer still runs on the
# hardware SPI engine, but the hardware CE line
# is held off (SPI_NO_CS) and we drive this GPIO
# as the CS. It must connect to the CS/SS pin on
# the IC you're using

$spi = RPi::SPI->new(26); # GPIO 26 is the CS

# or run the whole bus in software on any GPIO
# pins by passing a hashref of bit-bang params

$spi = RPi::SPI->new({ clk => 21, mosi => 20, miso => 19, cs => 26 });

DESCRIPTION

This distribution provides you the ability to communicate with devices attached to the channels on the Serial Peripheral Interface (SPI) bus. Although it was designed for the Raspberry Pi, that's not a hard requirement, and it should work on any Unix-type system that has support for SPI.

You can use the hardware SPI pins CE0 and CE1 on the Raspberry Pi, but if you need more SPI slaves, you can hand us any GPIO pin as the chip select instead: the transfer still runs on the hardware SPI engine, but we hold the hardware CE line off with SPI_NO_CS and frame the transaction with your GPIO, so the onboard CE0/CE1 pins are left untouched. You can also run the entire bus in software (bit-bang) on arbitrary GPIO pins.

METHODS

new

Instantiates a new RPi::SPI instance, prepares a specific SPI bus channel for use, then returns the object.

Parameters:

$channel

The SPI bus channel to initialize.

Mandatory: Integer or hashref.

Integer 0 for /dev/spidev0.0 or 1 for /dev/spidev0.1, using the hardware chip select pins (CE0/CE1). Send in any number above 1 and we'll treat it as a GPIO pin connected to the CS/SS pin of the IC: the transfer still runs on the hardware SPI engine, but we set the kernel's SPI_NO_CS flag and drive that GPIO ourselves around each transaction, freeing up the onboard hardware chip selects and leaving CE0/CE1 untouched.

Send in a hashref instead to run the whole bus in software (bit-bang) on arbitrary GPIO pins (BCM numbering):

my $spi = RPi::SPI->new({
    clk   => 21, # Clock
    mosi  => 20, # Data out (to the device), or -1 if unused
    miso  => 19, # Data in  (from the device), or -1 if unused
    cs    => 26, # Chip select, or -1 to manage it yourself
    mode  => 0,  # Optional SPI mode 0-3 (default 0)
    delay => 1,  # Optional microseconds per clock phase (default 0)
});

$speed

Optional, Integer. The data rate to communicate on the bus using. Defaults to 1000000 (1MHz). Ignored in bit-bang mode (use delay to pace the clock).

Dies if we can't open the SPI bus.

rw

Writes specified data to the bus on the channel specified in new(), then after completion, does a read of the bus and re-populates the write buffer with the freshly read data, and returns it as an array.

Parameters:

$buf

Mandatory: Array reference where each element is an unsigned char (0-255). This array is the write buffer; the data we'll be sending to the SPI bus.

$len

Mandatory: Integer, the number of array elements in the $buf parameter sent in above.

Return: The write buffer, after being re-populated with the read data, as a Perl array.

Dies if we can't open the SPI bus.

AUTHOR

Steve Bertrand, <steveb at cpan.org>

LICENSE AND COPYRIGHT

Copyright 2017-2026 Steve Bertrand.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.