piras77
Posts: 147
Joined: Mon Jun 13, 2016 11:39 am

SPI Slave (BSC Slave) Errata

Fri Apr 28, 2017 9:14 am

Hi there,

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.
The description above is the result of some experiments. It would be helpful if somebody could confirm the behaviour.

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)
figure_1_pi0.png
Figure 1 (PI-0)
figure_1_pi0.png (47.46 KiB) Viewed 1893 times
figure_2_pi0.png
Figure 2 (Pi-0)
figure_2_pi0.png (47.28 KiB) Viewed 1893 times
If you have any comments (e.g. bugs in my descriptions, explanations for the Slave's operation, experiences with the device, etc.), please feel free to respond.

piras77
Posts: 147
Joined: Mon Jun 13, 2016 11:39 am

Re: SPI Slave (BSC Slave) Errata

Fri Apr 28, 2017 9:37 am

addendum with scope for Pi-2 ('cause limited number of attachments by forum software)
figure_1_pi2.png
Figure 1 (Pi-2)
figure_1_pi2.png (47.24 KiB) Viewed 1883 times
figure_2_pi2.png
Figure 2 (Pi-2)
figure_2_pi2.png (47.29 KiB) Viewed 1883 times

User avatar
joan
Posts: 15084
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: SPI Slave (BSC Slave) Errata

Fri Apr 28, 2017 10:55 am

The pigpio pigs BSCX command may be useful for those wanting to experiment with the BSC slave.

cedricszc
Posts: 1
Joined: Thu Nov 02, 2017 12:27 pm

Re: SPI Slave (BSC Slave) Errata

Thu Nov 02, 2017 12:38 pm

Hello,
I have been struggling for one week and I got the same results as yours.
Inversion of BSC MISO and BSC MOSI in the BCM2835 datasheet.
When the LSB of the first byte transmitted (from master to slave) is :
  • '1' the following bytes are correctly stored to the rx buffer of the slave device, but no MISO data are transmitted to the master
  • '0' the following bytes are not correctly stored to the rx buffer of the slave device, but MISO data are transmitted to the master
Platform: RPi 3

Cédric

piras77
Posts: 147
Joined: Mon Jun 13, 2016 11:39 am

Re: SPI Slave (BSC Slave) Errata

Thu Nov 02, 2017 2:59 pm

Thanks for your feedback! :-)

Return to “Interfacing (DSI, CSI, I2C, etc.)”