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

SPI/BSC SLAVE peripheral problems

Fri Oct 14, 2016 3:09 pm

I have been playing with the SPI/BSC SLAVE peripheral with limited success.

The peripheral is meant to allow the Raspberry Pi to act as a slave device on an I2C or SPI bus.

See BCM2835 ARM Peripherals page 160.

It sort of works, I2C somewhat better than SPI.

Does anyone know of an effective way of clearing the transmit FIFO? It would be nice to clear the transmit FIFO of invalid data during initialisation. Setting control register bit BRK (clear FIFOs) has no effect, perhaps other bits need to be set at the same time. I have also tried reading from the TDR register (with control register bit TESTFIFO set). That only returned the top most TX FIFO entry without purging the value.

SPI seems to discard the first byte transmitted. Has anyone had any success with SPI?

baantonia
Posts: 63
Joined: Fri Feb 06, 2015 2:19 pm

Re: SPI/BSC SLAVE peripheral problems

Fri Oct 14, 2016 11:57 pm

I've been trying on and off for a few months now without any luck using some bare metal code to transfer data to another Pi via SPI as a slave. The FIFO appears to fill but nothing gets written onto the wire, very frustrating! Had an oscilloscope on the MISO wire, nothing. I think I did test a count writing to the FIFO until it became full, I'll check again at some point but busy this weekend. Even if the SPI masters code was not correct in processing any received data, with the masters clock line functioning and the slaves FIFO filling, I would expect to get some activity on the MISO wire. If anyone has discovered the magic ingredient to this function I would like to know.

The new CM3 documentation shows GPIO18-21 mode 3 as blank, so not very hopeful there,

Haven't tested setting bit 7 of the CR register, BRK. The documentation says it clears the FIFO's, have you tested that yet?

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

Re: SPI/BSC SLAVE peripheral problems

Sat Oct 15, 2016 4:08 am

I have tried BRK, without success.

With SPI I can send or receive. What has been eluding me is doing both at the same time. I am modifying my test program. When I have done that it will be easier to judge the state of play. I have allowed myself to get bogged down in trying to find a way to flush the TX buffer. In practice that might only exist as a problem in my head.

On the I2C side I think a practical solution is possible (by which I mean a usable I2C slave device).

On SPI I'll know better within a day or so.

Mine is a Linux userland solution not using interrupts.

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

Re: SPI/BSC SLAVE peripheral problems

Mon Oct 17, 2016 12:16 pm

I don't think the SPI/BSC SLAVE peripheral works properly in SPI mode.

I can transfer data from the SPI/BSC slave to a SPI master correctly, but no data comes from the master to the slave.

I can transfer data from a SPI master to the SPI/BSC slave incorrectly, but no data comes from the slave to the master. I say incorrectly as if value x is sent then value 2*x is received.

I will probably add an I2C slave mode to pigpio but leave SPI on the back burner.

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

Re: SPI/BSC SLAVE peripheral problems

Sun Oct 30, 2016 4:32 pm

pigpio V57 has added support for I2C as a slave.

The Python bsc_i2c should have a testable example.

The generic Python code is bsc_xfer for I2C/SPI. I can't get SPI working. If you can please let me know.

As usual I have done little testing so won't be too surprised by error reports.

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

Re: SPI/BSC SLAVE peripheral problems

Mon Oct 31, 2016 8:20 pm

pigpio (from V57) now supports the Raspberry Pi acting as a I2C slave device.

The core function is the C bscXfer.

The Python wrapper bsc_i2c provides an I2C slave interface.

As a test between a Pi3 and an Arduino Pro Mini I used the following code.

On the Pi3.

Code: Select all

#!/usr/bin/env python

import time
import pigpio

I2C_ADDR=9

def i2c(id, tick):
   global pi

   s, b, d = pi.bsc_i2c(I2C_ADDR)

   if b:

     print(d[:-1])

pi = pigpio.pi()

if not pi.connected:
    exit()

# Respond to BSC slave activity

e = pi.event_callback(pigpio.EVENT_BSC, i2c)

pi.bsc_i2c(I2C_ADDR) # Configure BSC as I2C slave

time.sleep(600)

e.cancel()

pi.bsc_i2c(0) # Disable BSC peripheral

pi.stop()
On the Arduino Pro Mini.

Code: Select all

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
   Wire.begin(); // join i2c bus as master
}

char str[17];

int x = 0;

void loop()
{
   sprintf(str, "Message %7d\n", x);
   if (++x > 9999999) x=0;

   Wire.beginTransmission(9); // transmit to device #9
   Wire.write(str);           // sends 16 bytes
   Wire.endTransmission();    // stop transmitting

   delay(50);
}
So the Arduino is sending 20 16-byte messages per second (16 is the slave receive FIFO size so it is a sensible maximum message size).

The Python was executing on a Linux laptop networked with the Pi.

Over a 600 second period the Arduino sent 11526 messages. The Python saw 11018 (95.6%).

The missing messages could be detected by the gap between successive message numbers which should always be 1. The actual gap counts were

Code: Select all

count gap
10855 1
    9 2
   20 3
   95 4
   32 5
    1 6
    3 7
    1 8
    2 9
The performance seems perfectly reasonable to me for a userland solution. Occasionally there will be inconvenient reschedules. I'd expect better figures if the Python was running on the local Pi.

I repeated the test on a local Pi and all the sent messages were received error free (100%).

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

Re: SPI/BSC SLAVE peripheral problems

Fri Apr 28, 2017 9:24 am

Hi Joan,

You wrote above
joan wrote:I can transfer data from the SPI/BSC slave to a SPI master correctly, but no data comes from the master to the slave.

I can transfer data from a SPI master to the SPI/BSC slave incorrectly, but no data comes from the slave to the master. I say incorrectly as if value x is sent then value 2*x is received.
That doesn't sound like the result in my experiments. (viewtopic.php?f=44&t=181784)

If I understand you correctly,

(1) You managed to transfer data from slave to master "correctly". -- I always get a leading 0xff start byte.
(2) You managed to transfer data from master to slave which arrives twice at the slave. -- I get all the data once (the data after the start byte).

Can you describe your setup with some more details? Thank you!

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

Re: SPI/BSC SLAVE peripheral problems

Fri Apr 28, 2017 9:47 am

These were ad hoc unsuccessful experiments which I didn't feel the need to record in detail.

I don't remember a leading 0xFF, I suppose I could have missed it as there would be no level change.

When I say 2*x I mean if three bytes with values 1, 5, and 33 are sent then three bytes with values 2, 10, and 66 are received. Presumably some sort of mode mismatch.

akshu
Posts: 1
Joined: Tue Jul 31, 2018 7:57 am

Re: SPI/BSC SLAVE peripheral problems

Tue Jul 31, 2018 8:04 am

Hello,
I am also trying to interface Raspberry pi3 as Slave. I tried the example given above in the forum but no luck.
Could anyone tell me regarding the I2C pins to be used? Precisely how was the pin connection in the above working example(Arduino as master and Rasp3 as the slave)
This information would be really helpful.

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