The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.


<HTML>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <title>HiPi::Device::SPI</title></head>

<BODY TOPMARGIN=4 BGCOLOR=#FFFFFF TEXT=#000000 VLINK=#0000CC LINK=#0000CC ALINK=#0000CC>
<FONT FACE="Arial, Lucida, Helvetica" >

<TABLE WIDTH="100%" ALIGN=CENTER CELLPADDING=1 CELLSPACING=0>
<TR>
<TD WIDTH="100%" ALIGN=CENTER>


<A HREF="contents.htm"><img align=center src="home.png" BORDER=0 ALT="Contents"></A>


<A HREF="mod_device.htm"><img align=center src="up.png" BORDER=0 ALT="Up"></A>

<A HREF="mod_device_i2c.htm"><img align=center src="back.png" BORDER=0 ALT="Previous"></A>

<A HREF="mod_device_onewire.htm"><img align=center src="forward.png" BORDER=0 ALT="Next"></A>
</TD>
</TR>
<TR>
<TD COLSPAN=2 HEIGHT=2 BGCOLOR="#C0C0C0">
</TD>
</TR>
</TABLE>

<H2>HiPi::Device::SPI</H2><p>The HiPi::Device::SPI module provides access to the kernel driver for the SPI bus.</p>
<p>See : <A HREF="topic_spidev.htm">SPI Device Driver</A></p>
<p>Loading and configuring the kernel SPI driver is controlled by configuring the device tree in your /boot/config.txt file.</p>
<p>See : <A HREF="topic_device_tree.htm">Using the Device Tree</A></p>
<!--
<p>The settings for the SPI device can be controlled in the <A HREF="control_app_spi.htm">HiPi Control GUI</A>.</p>
-->
<p>The following interface modules use HiPi::Device::SPI as a backend and may contain code that helps with your own usage.</p>
<p><A HREF="mod_interface_mcp3004.htm">HiPi::Interface::MCP3004</A><br />
<A HREF="mod_interface_mcp3008.htm">HiPi::Interface::MCP3008</A><br />
<A HREF="mod_interface_mcp49xx.htm">HiPi::Interface::MCP49XX</A><br /></p>
<A HREF="mod_interface_mcp23S17.htm">HiPi::Interface::MCP23S17</A><br /></p>
<h2>Class Methods</h2>
<!--
<h5>HiPi::Device::SPI->load_modules( $forceunload );</h5>
<pre>    Loads the kernel device driver modules for SPI
    spi_bcm2708
    spidev

    When $forceunload is true, unloads the kernel modules
    first if they are loaded (effectively forces a reload)

    spidev is loaded with the current bufsiz

    Of course, the user the script is running as must have
    root permissions to load and unload kernel modules.</pre>
<h5>HiPi::Device::SPI->unload_modules();</h5>
<pre>    Unloads the kernel device driver modules for SPI
    spi_bcm2708
    spidev

    Of course, the user the script is running as must have
    root permissions to load and unload kernel modules.</pre>
<h5>HiPi::Device::SPI->get_bufsiz();</h5>
<pre>    Returns the current bufsiz of a loaded spidev
    module. If the module is not loaded or the process 
    does not have root permissions, returns the current
    default module setting for bufsiz.</pre>
<h5>HiPi::Device::SPI->set_bufsiz( $newsiz );</h5>
<pre>    Sets the bufsiz option of the spidev module. Must
    unload and load the kernel module to do this.

    Of course, the user the script is running as must have
    root permissions to load and unload kernel modules.</pre>
-->
<h5>HiPi::Device::SPI->get_device_list();</h5>
<pre>    Returns an array containing the names of available
    devices. 
    Will normally return ('/dev/spidev0.0', '/dev/spidev0.1')
</pre>
<h2>Object Constructor and Methods</h2>

<h5>my $dev = HiPi::Device::SPI->new();</h5>
<pre>    Returns a new instance of the HiPi::Device::SPI class.

    You can optionally specify several parameters as key 
    value pairs in the constructor. Their default values
    are:

    my $dev = HiPi::Device::SPI->new(
        devicename   => '/dev/spidev0.0',
        speed        => SPI_SPEED_MHZ_1,
        bitsperword  => 8,
        delay        => 0,
    );

    In default setup mode the SPI driver for Raspberry Pi has two
    cable select pins assigned.

    For controlling a device connected to SPI0_CS0 you need
    devicename => '/dev/spidev0.0'

    For controlling a device connected to SPI0_CS1 you need
    devicename => '/dev/spidev0.1'

    You can control data transfer speed by specifying one of the
    following constants for the key value 'speed'

        SPI_SPEED_KHZ_500
        SPI_SPEED_MHZ_1
        SPI_SPEED_MHZ_2
        SPI_SPEED_MHZ_4
        SPI_SPEED_MHZ_8        
        SPI_SPEED_MHZ_16
        SPI_SPEED_MHZ_32

    You can import these constants into your namespace with:

    use HiPi::Device::SPI qw( :spi );

    Consult SPI bus documentation if you find your devices need
    or would benefit from specifying none default values for 
    'bitsperword' and 'delay'. (I haven't discovered a use for
    these)
</pre>
<h3>SPI Methods</h3>
<h5>my $result = $dev->transfer( $buffer );</h5>
<pre>    Writes $buffer to the connected SPI device and returns
    the length($buffer) bytes read. In SPI transfers the length
    of data returned is always the same as the length of data
    sent.

    Uses the speed, bitsperword and delay settings specified in
    the constructor.

    Depending on your device you will probably have to pack / 
    unpack the $buffer and return value and engage in some
    bit shifting to retrieve the returned value.

    For example, your SPI device expects a transfer message of 4 
    bytes in length.
    Arrange these 4 bytes on an array : @buffer.

    my @vals = unpack('C4',$spi->transfer(pack('C4',($addr,$reg,@buffer))));

    You will have to check the data sheets for your individual
    SPI device.
    
    For example, the MCP23S17 requires the first 2 bytes of a nessage
    to be a device address and a register address. It allows requests 
    to retrieve any number of bytes.

    If I want to retrieve 10 bytes of information, I have to send 12 
    bytes - 2 bytes of device and register address plus a 10 byte buffer.
    
    my @buffer = (0) x 10;
    my @vals = unpack('C12',$spi->transfer(pack('C12',($addr,$reg,@buffer))));
    
    The device doesn't populate $vals[0] or $vals[1] so the 10 bytes I 
    read start at $vals[2];

    The MCP3008 analogue to digital converter uses 3 byte SPI transfers. 
    In the request bytes the first byte and 4 high bits of the second byte 
    define the request. The ADC returns its 10 bit result as the low 2 bits 
    of the second byte + the third byte. In the request, we just send 0 as
    the third byte. Then we bitshift the value in the second byte.
  
    my @vals = unpack('C3',$spi->transfer(pack('C3',($byt1,$byt2,0))));
    my $result = (($vals[1] & 3) &lt;&lt; 8) + $vals[2];
    
    Use the code for HiPi::Interface::MCP3008 and HiPi::Interface::MCP23S17 
    as guides.</pre>
<h5>$dev->set_bus_mode( $mode );</h5>
<pre>    $mode   one of 

        SPI_MODE_0 
        SPI_MODE_1
        SPI_MODE_2
        SPI_MODE_3 

    You can import these constants into your namespace with:

    use HiPi::Device::SPI qw( :spi );

    The documentation for your SPI device should tell you which
    modes it supports. Default mode is SPI_MODE_0.</pre>
<h5>$dev->set_bus_maxspeed( $speed );</h5>
<pre>    $speed   one of 

        SPI_SPEED_KHZ_500
        SPI_SPEED_MHZ_1
        SPI_SPEED_MHZ_2
        SPI_SPEED_MHZ_4
        SPI_SPEED_MHZ_8        
        SPI_SPEED_MHZ_16
        SPI_SPEED_MHZ_32

    You can import these constants into your namespace with:

    use HiPi::Device::SPI qw( :spi );

    I have not yet investigated how this setting combines with
    the speed setting specified in the constructor. The commands
    are simply wrappers for the exposed kernel device driver
    calls. 
</pre></FONT>
<br>
<p>
<br>
<hr>
<br>
<center>
<A HREF="contents.htm"><img align=center src="home.png" BORDER=0 ALT="Contents"></A>


<A HREF="mod_device.htm"><img align=center src="up.png" BORDER=0 ALT="Up"></A>

<A HREF="mod_device_i2c.htm"><img align=center src="back.png" BORDER=0 ALT="Previous"></A>

<A HREF="mod_device_onewire.htm"><img align=center src="forward.png" BORDER=0 ALT="Next"></A>
</center>

<HR>
<br>
<center><FONT FACE="Arial, Lucida, Helvetica" size="2" color="#000080">HiPi Modules Copyright &#169; 2013 - 2016 Mark Dootson</font></center>
</BODY></HTML>