I was playing around with the SPI Slave and, well, it didn't look that promising in the first place (see viewtopic.php?t=162790).
Still, I'm quite disappointed of the BCM2835 data sheet's quality (pp.160). Here some findings (you have to read the data sheet before):
Code: Select all
// Short Description (including extensive errata)
//
// The device handles special-purpose dialogues. The dialogues are
// Octet based (8-bit groups). Octets are transmitted MSB-first. The
// first MOSI octet defines the type of the dialogue:
//
// If the LSB is 0, then all subsequent MOSI octets are read and
// deserialized into the rx-fifo. No data is put on MISO. It will
// be high for the complete dialogue. The tx-fifo is not touched.
//
// If the LSB is 1, then all subsequent MOSI octets are ignored. The
// rx-fifo is not touched. However, the data in the tx-fifo is
// serialized and put on MOSI.
//
// The 7 most significant bits of the first MOSI octet appear to be
// ignored completely. The first MISO octet is always 0xff.
//
// Note that MISO and MOSI are the other way around than described in
// the datasheet. The BCM pins are MISO=18, SCLK=19, MOSI=20, CE=21.
//
// Both, the rx- and tx-fifo, may each hold a maximum of 16 octets.
//
// Control register fields:
//
// * The BRK field does neither clear the tx- nor the rx-fifo.
//
// * If the TESTFIFO field is set, then access to TDR (FIFO test data
// register at address 0x2c) takes effect:
// * Read: returns the head of the tx-fifo; it will not be dequeued;
// note that if the device is enabled, the next octet to be sent
// has already left the tx-fifo and was placed into the serializer
// * Write: enqueues a new octet at the rx-fifo's tail; incoming
// data from MOSI appears to be ignored (0x00 is enqueued instead).
//
// Other than specified, the tx-fifo can neither be cleared by BRK nor
// by reading TDR. However, it is possible to dequeue a tx-fifo octet
// by enabling the device (which places an octet into the serializer).
// Thus a sequence of disabling (0) and enabling (EN+TXE) the device
// for (TXFLEVEL+1) times clears the tx-fifo including the byte in the
// serializer.
Below a test run which might help understand the device's operation.
Code: Select all
In the illustrations below, SPI-Slave pins are as follows:
Channel 0 = MISO (BCM 18)
Channel 1 = SCLK (BCM 19)
Channel 2 = MOSI (BCM 20)
Channel 3 = CE (BCM 21)
(1) Slave registers are set up as follows:
Status Register (0x0)
rx-over .... 0
tx-under ... 0
Control Register (0x303)
enable ........ 1
spi ........... 1
i2c ........... 0
cpha .......... 0
cpol .......... 0
en-stat ....... 0
en-ctrl ....... 0
brk ........... 0
en-tx ......... 1
en-rx ......... 1
inv-rx-full ... 0
en-test ....... 0
en-host ....... 0
inv-tx-full ... 0
Flag Register (0x12)
tx-busy .... 0
rx-empty ... 1
tx-full .... 0
rx-full .... 0
tx-empty ... 1
rx-busy .... 0
tx-level ... 0
rx-level ... 0
(2) The octets (0xcc,0x0f) are placed for transmission; which affects the Flag register:
Flag Register (0x42)
tx-busy .... 0
rx-empty ... 1
tx-full .... 0
rx-full .... 0
tx-empty ... 0
rx-busy .... 0
tx-level ... 1
rx-level ... 0
(3) SPI0 is used as Master with a divider of 10 (~800 kHz on Pi-0; ~500 kHz on Pi-2). The octets (0x00,0x03,0x15) are sent.
See figure 1.
The Master receives the octets (0xff,0xff,0xff)
The Slave's resulting Flag register is as follows:
Flag Register (0x1040)
tx-busy .... 0
rx-empty ... 0
tx-full .... 0
rx-full .... 0
tx-empty ... 0
rx-busy .... 0
tx-level ... 1
rx-level ... 2
(two new octets arrived in rx-fifo; tx-fifo is unchanged)
Reading the octets matches with (0x03,0x15). Thereafter, the rx-fifo is empty again:
Flag Register (0x42)
tx-busy .... 0
rx-empty ... 1
tx-full .... 0
rx-full .... 0
tx-empty ... 0
rx-busy .... 0
tx-level ... 1
rx-level ... 0
(4) The Master sends the octets (0x01,0x03,0x15).
See figure 2.
The Master receives the octets (0xff,0xcc,0x0f)
The Slave's resulting Flag register is as follows:
Flag Register (0x12)
tx-busy .... 0
rx-empty ... 1
tx-full .... 0
rx-full .... 0
tx-empty ... 1
rx-busy .... 0
tx-level ... 0
rx-level ... 0
(no new octets arrived in rx-fifo; tx-fifo has been cleared)