Difference between revisions of "RPi SPI"

From eLinux.org
Jump to: navigation, search
(Contents is moved to the Raspberry Pi Documentation pages)
(Undo revision 339638 by Notro (talk) I've added the pointer to the RPi Documentation project at the top of the page and restored the content. There's no need to delete it all.)
Line 1: Line 1:
 
[[Category: RaspberryPi]]
 
[[Category: RaspberryPi]]
  
The page has been moved: http://www.raspberrypi.org/documentation/hardware/raspberrypi/spi.md
+
NOTE:  Similar documentation can be found on the official [http://www.raspberrypi.org/documentation/hardware/raspberrypi/spi.md  Raspberry Pi Documentation Project] page.
 +
 
 +
The BCM2835 on the Raspberry Pi has 3 [http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus SPI] Controllers. Only one of the controllers is available on the header.
 +
 
 +
Chapter 10 in the [http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf BCM2835 ARM Peripherals] datasheet describes this controller.
 +
 
 +
 
 +
== Hardware ==
 +
This interface is referred to as SPI0 in the documentation.
 +
 
 +
=== Master modes ===
 +
* '''Standard mode'''
 +
: In Standard SPI master mode the peripheral implements the standard 3 wire serial protocol.
 +
: Signal names: Clock=CLK, ChipSelect=CE, SerialOut=MOSI (Master Out Slave In), SerialIn=MISO (Master In Slave Out)
 +
 
 +
* '''Bidirectional mode'''
 +
: In bidirectional SPI master mode the same SPI standard is implemented except that a single wire is used for the data (MIMO) instead of the two as in standard mode (MISO and MOSI).
 +
: Signal names: Clock=CLK, ChipSelect=CE, SerialINOut=MOMI (Master Out Master In) or MIMO (Master In Master Out)
 +
 
 +
* '''LoSSI mode''' (Low Speed Serial Interface)
 +
: The LoSSI standard allows us to issue commands to peripherals and to transfer data to and from them.
 +
: LoSSI commands and parameters are 8 bits long, but an extra bit is used to indicate whether the byte is a command or data.
 +
: This extra bit is set high for a parameter and low for a command. The resulting 9-bit value is serialized to the output.
 +
: When reading from a LoSSI peripheral the standard allows us to read bytes of data, as well as 24 and 32 bit words.
 +
: Signal names: Clock=SCL, ChipSelect=CS, SerialOut=SDA (Serial DAta)
 +
 
 +
: The signal name SDA indicates that this could be a bidirectional bus.
 +
: The Nokia 5800 [http://www.shrak-mobile.com/eng/schem_nokia.html schematics] shows LoSSI Data In and LoSSI Data Out as connected.
 +
: This [http://www.raspberrypi.org/phpBB3/viewtopic.php?p=262818#p262818 post] also supports this.
 +
 
 +
=== Transfer modes ===
 +
* Polled
 +
* Interrupt
 +
* DMA
 +
 
 +
=== Speed ===
 +
The CDIV (Clock Divider) field of the CLK register sets the SPI clock speed
 +
<pre>SCLK = Core Clock / CDIV
 +
If CDIV is set to 0, the divisor is 65536. The divisor must be a power of 2. Odd numbers rounded down. The maximum SPI clock rate is of the APB clock.</pre>
 +
Errata (http://elinux.org/BCM2835_datasheet_errata):  "must be a power of 2" probably should be "must be a multiple of 2"
 +
 
 +
=== Chip Select ===
 +
The controller supports 3 Chip selects, but only 2 is available on the header.
 +
 
 +
Setup and Hold times related to the automatic assertion and de-assertion of the CS lines when operating in '''DMA''' mode (DMAEN and ADCS set) are as follows:
 +
* The CS line will be asserted at least 3 core clock cycles before the msb of the first byte of the transfer.
 +
* The CS line will be de-asserted no earlier than 1 core clock cycle after the trailing edge of the final clock pulse.
 +
 
 +
 
 +
== Linux driver ==
 +
The default Linux driver is [https://github.com/raspberrypi/linux/blob/rpi-3.6.y/drivers/spi/spi-bcm2708.c spi_bcm2708].
 +
The following information was valid 2013-05-15.
 +
 
 +
=== Speed ===
 +
The driver supports the following speeds
 +
  cdiv    speed
 +
    2    125.0 MHz
 +
    4    62.5 MHz
 +
    8    31.2 MHz
 +
    16    15.6 MHz
 +
    32      7.8 MHz
 +
    64      3.9 MHz
 +
  128    1953 kHz
 +
  256      976 kHz
 +
  512      488 kHz
 +
  1024      244 kHz
 +
  2048      122 kHz
 +
  4096      61 kHz
 +
  8192    30.5 kHz
 +
16384    15.2 kHz
 +
32768    7629 Hz
 +
 
 +
When asking for say 24 MHz, the actual speed will be 15.6 MHz.
 +
The fastest reported working speed is 32 MHz.
 +
 
 +
[http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=43442&p=347073 SPI has more speeds]
 +
 
 +
=== Supported Mode bits ===
 +
* SPI_CPOL - Clock polarity
 +
* SPI_CPHA - Clock phase
 +
* SPI_CS_HIGH - Chip Select active high
 +
* SPI_NO_CS - 1 dev/bus, no chipselect
 +
 
 +
=== Supported bits per word ===
 +
* 8 - Normal
 +
* 9 - This is supported using LoSSI mode.
 +
 
 +
=== Transfer modes ===
 +
Only interrupt mode is supported.
 +
 
 +
=== Deprecated ===
 +
The following appears in the kernel log on Linux version 3.6.11+
 +
bcm2708_spi bcm2708_spi.0: master is unqueued, this is deprecated
 +
 
 +
=== SPI driver latency ===
 +
This [http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=19489 thread] discusses latency problems.
 +
 
 +
This [https://github.com/msperl/linux/blob/rpi-3.6.y/drivers/spi/spi-bcm2708.c driver] proposes a solution to those problems ([https://github.com/raspberrypi/linux/pull/147 Pull Request]). It also solves the deprecation problem.
 +
 
 +
=== DMA capable driver ===
 +
https://github.com/notro/spi-bcm2708 ([https://github.com/notro/spi-bcm2708/wiki wiki])
 +
 
 +
== Loopback test ==
 +
This can be used to test SPI send and receive. Put a wire between MOSI and MISO. It does not test CE0 and CE1.
 +
wget https://raw.github.com/torvalds/linux/master/Documentation/spi/spidev_test.c
 +
gcc -o spidev_test spidev_test.c
 +
./spidev_test -D /dev/spidev0.0
 +
 
 +
If you get SPI_TX_QUAD undeclared, use this instead
 +
wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c
 +
 
 +
== Software ==
 +
* http://wiringpi.com/
 +
* Shell
 +
# Write binary 1, 2 and 3
 +
echo -ne "\x01\x02\x03" > /dev/spidev0.0
  
 
{{Template:Raspberry Pi}}
 
{{Template:Raspberry Pi}}

Revision as of 10:43, 7 July 2014


NOTE: Similar documentation can be found on the official Raspberry Pi Documentation Project page.

The BCM2835 on the Raspberry Pi has 3 SPI Controllers. Only one of the controllers is available on the header.

Chapter 10 in the BCM2835 ARM Peripherals datasheet describes this controller.


Hardware

This interface is referred to as SPI0 in the documentation.

Master modes

  • Standard mode
In Standard SPI master mode the peripheral implements the standard 3 wire serial protocol.
Signal names: Clock=CLK, ChipSelect=CE, SerialOut=MOSI (Master Out Slave In), SerialIn=MISO (Master In Slave Out)
  • Bidirectional mode
In bidirectional SPI master mode the same SPI standard is implemented except that a single wire is used for the data (MIMO) instead of the two as in standard mode (MISO and MOSI).
Signal names: Clock=CLK, ChipSelect=CE, SerialINOut=MOMI (Master Out Master In) or MIMO (Master In Master Out)
  • LoSSI mode (Low Speed Serial Interface)
The LoSSI standard allows us to issue commands to peripherals and to transfer data to and from them.
LoSSI commands and parameters are 8 bits long, but an extra bit is used to indicate whether the byte is a command or data.
This extra bit is set high for a parameter and low for a command. The resulting 9-bit value is serialized to the output.
When reading from a LoSSI peripheral the standard allows us to read bytes of data, as well as 24 and 32 bit words.
Signal names: Clock=SCL, ChipSelect=CS, SerialOut=SDA (Serial DAta)
The signal name SDA indicates that this could be a bidirectional bus.
The Nokia 5800 schematics shows LoSSI Data In and LoSSI Data Out as connected.
This post also supports this.

Transfer modes

  • Polled
  • Interrupt
  • DMA

Speed

The CDIV (Clock Divider) field of the CLK register sets the SPI clock speed

SCLK = Core Clock / CDIV 
If CDIV is set to 0, the divisor is 65536. The divisor must be a power of 2. Odd numbers rounded down. The maximum SPI clock rate is of the APB clock.

Errata (http://elinux.org/BCM2835_datasheet_errata): "must be a power of 2" probably should be "must be a multiple of 2"

Chip Select

The controller supports 3 Chip selects, but only 2 is available on the header.

Setup and Hold times related to the automatic assertion and de-assertion of the CS lines when operating in DMA mode (DMAEN and ADCS set) are as follows:

  • The CS line will be asserted at least 3 core clock cycles before the msb of the first byte of the transfer.
  • The CS line will be de-asserted no earlier than 1 core clock cycle after the trailing edge of the final clock pulse.


Linux driver

The default Linux driver is spi_bcm2708. The following information was valid 2013-05-15.

Speed

The driver supports the following speeds

 cdiv    speed
    2    125.0 MHz
    4     62.5 MHz
    8     31.2 MHz
   16     15.6 MHz
   32      7.8 MHz
   64      3.9 MHz
  128     1953 kHz
  256      976 kHz
  512      488 kHz
 1024      244 kHz
 2048      122 kHz
 4096       61 kHz
 8192     30.5 kHz
16384     15.2 kHz
32768     7629 Hz

When asking for say 24 MHz, the actual speed will be 15.6 MHz. The fastest reported working speed is 32 MHz.

SPI has more speeds

Supported Mode bits

  • SPI_CPOL - Clock polarity
  • SPI_CPHA - Clock phase
  • SPI_CS_HIGH - Chip Select active high
  • SPI_NO_CS - 1 dev/bus, no chipselect

Supported bits per word

  • 8 - Normal
  • 9 - This is supported using LoSSI mode.

Transfer modes

Only interrupt mode is supported.

Deprecated

The following appears in the kernel log on Linux version 3.6.11+

bcm2708_spi bcm2708_spi.0: master is unqueued, this is deprecated

SPI driver latency

This thread discusses latency problems.

This driver proposes a solution to those problems (Pull Request). It also solves the deprecation problem.

DMA capable driver

https://github.com/notro/spi-bcm2708 (wiki)

Loopback test

This can be used to test SPI send and receive. Put a wire between MOSI and MISO. It does not test CE0 and CE1.

wget https://raw.github.com/torvalds/linux/master/Documentation/spi/spidev_test.c
gcc -o spidev_test spidev_test.c
./spidev_test -D /dev/spidev0.0

If you get SPI_TX_QUAD undeclared, use this instead

wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c

Software

# Write binary 1, 2 and 3
echo -ne "\x01\x02\x03" > /dev/spidev0.0