Chip select asserts at same interval even when increasing SPI bus frequency

614 views
Skip to first unread message

Ken S

unread,
Feb 4, 2013, 2:38:52 AM2/4/13
to bcm...@googlegroups.com

Hi Mike,

I have been using your bcm2835 C library on my Raspberry Pi to control the SPI bus.  It’s awesome!  Very easy to use!  But I’m monitoring the bus with an oscilloscope, and finding a limitation that I’d like to ask you about.

I’m using it to read data from the MCP3008 A/D converter that Adafruit.com sells.  I’m sending and reading 3 bytes at a time using bcm2835_spi_transfernb(), for each sample, the way the spec sheet for MCP3008 describes.  I’m reading the data just fine, but there seems to be a limitation as to how often I can read a sample, no matter how fast I set the SPI bus to.  (It takes 3 bytes to read one sample.)

If I monitor the chip select and the clock using a ‘scope, I see chip select go low, 8 clocks, a gap, 8 more clocks, another gap, 8 more clocks, a gap, and then chip select goes high briefly until the next sample, at which point the pattern repeats.  So far that sounds normal, right?  But if I increase the SPI bus speed, I see each group of 8 clocks gets narrower as expected, but the gap gets larger before the next 8 clocks come out, causing each chip select to happen at the exact same interval as before!  This prevents me from sampling faster than about 28KHz.  Whether I use a clock divider of 24 or 300… I get the exact same interval between chip selects.  Once I go above a divider of ~300, there isn’t enough room for the 3 sets of 8 clocks between each chip select, so then the chip selects start getting farther apart, allowing a slower sample rate.  But I want to go faster than 28KHz, and there appears to be plenty of time to do so, but it seems that your library is waiting a constant amount of time after sending the first clock of the first byte before it sends the first clock of the 2nd byte, (and again with the 3rd byte) preventing me from increasing the sample rate above 28KHz.

Is there any way around this?

I’m not doing much in my code between samples, chip select is only going high for about 640ns, so it’s not that I have a ton of code between each sample slowing things down.

Any advice would be appreciated.

Regards,

Ken

 

Mike McCauley

unread,
Feb 4, 2013, 2:42:56 AM2/4/13
to bcm...@googlegroups.com
Hi,

As I think you may have found out since, I suspect this problem is due to the
10 microsecond busy-wait loop when waiting for the SPI bytes to transfer.

Perhaps a smaller wait delay would be better?

Cheers.
--
Mike McCauley mi...@open.com.au
Open System Consultants Pty. Ltd
9 Bulbul Place Currumbin Waters QLD 4223 Australia http://www.open.com.au
Phone +61 7 5598-7474 Fax +61 7 5598-7070

Radiator: the most portable, flexible and configurable RADIUS server
anywhere. SQL, proxy, DBM, files, LDAP, NIS+, password, NT, Emerald,
Platypus, Freeside, TACACS+, PAM, external, Active Directory, EAP, TLS,
TTLS, PEAP, TNC, WiMAX, RSA, Vasco, Yubikey, MOTP, HOTP, TOTP,
DIAMETER etc. Full source on Unix, Windows, MacOSX, Solaris, VMS, NetWare etc.

Ken S

unread,
Feb 4, 2013, 3:30:21 AM2/4/13
to bcm...@googlegroups.com
Yes, that did help.  Although the timing is a bit inconsistent when reducing that too low.  I am trying to sample audio with the MCP3008.  I realize the RPi isn't the best platform to do that on, but I think I will try the optimization posted by maddin, and maybe combine it with the real-time optimzation suggested by Arjan in a couple posts below!

Thanks,

Ken


Arjan

unread,
Feb 4, 2013, 4:45:21 AM2/4/13
to bcm...@googlegroups.com
Hi Ken,

I have even removed all delayMicroseconds(10); entries from the bcm2835_spi_transfernb function. This gives me the highest possible throughput on the RPi (--> Linux).

Another optimization is to look at netstat -tap | grep LISTEN. Maybe there are some services which are really not needed for your application to run.

Arjan


Op maandag 4 februari 2013 09:30:21 UTC+1 schreef Ken S het volgende:

Stefano Andreoni

unread,
May 1, 2015, 5:23:08 AM5/1/15
to bcm...@googlegroups.com
Hi Ken S!

I'm  trying to interface the mcp3008 A/D converter with Rpi using bcm2835 library. I don't understand how to use bcm2835_spi_transfernb() function and I need to sample at 200k samples/second. Can you give me your code and tell me how the spi functions work?
Regards, Steve


Tom Olenik

unread,
May 1, 2015, 7:22:22 AM5/1/15
to bcm...@googlegroups.com
Steve,

The bcm2835_spi_transfernb() function takes in three arguments.  The first is the output buffer containing data you want to send to the SPI device. The second is the input buffer where you want to store data coming back from the SPI device. SPI is a full duplex communication type meaning data is flowing both directions at the same time. The third argument is the length of the longest buffer in number of bytes. 

I demonstrate how to use this function with an AD5592 DAC / ADC in a recent video:

I was able to get an DAC output sample rate of around 500kHz on the Raspberry Pi 2 (14.1kHz sine wave * 36 samples per period), but this will depend on the device you are using a well. I have not used the MCP3008, but the only thing that would differ would be the data you are sending to the device and the SPI configuration for the device.  The video linked to above also explains SPI in general and the steps to use to set up a SPI device with the BCM2835 library. The actual bits you send will depend on your device though.

I hope that helps.

Tom
Reply all
Reply to author
Forward
0 new messages