Pages: [1] 2   Go Down
Author Topic: SPI - Bitbang VS. SPI library  (Read 4236 times)
0 Members and 1 Guest are viewing this topic.
Worst state in America
Offline Offline
God Member
*****
Karma: 32
Posts: 808
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I've been playing with a new 128 x 64 pixel vacuum fluorescent display (a Noritake GU128X64E-U100) module which has several different interface modes (i.e. parallel and 3 different types of serial).



I have it working using the library code supplied by Noritake, but this code bit-bangs the ports with digitalWrite() and digitalRead() statements.

When trying to send data fast (like a live, runtime bar graph), the transfer rate is slow enough that the display doesn't move smoothly (hard to explain). I can see the updated image "sweep" across the display... imagine an old CRT TV set with a slow scan rate.

Anyway, I wonder if I use the Arduino hardware SPI pins and the SPI.h library (and modify the Noritake library to use it), could I expect to see better results (i.e. faster data transfers)?

Thanks!

-- Roger
Logged

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 27372
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes. Hardware SPI is much quicker than software SPI, if the receiving device can accept the data at the faster rate.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1729
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A digitalWrite() call takes about 15us to execute. There are two pins that need to be controlled meaning that the absolute max speed you can achieve using the wiring library is 2*15us = 30us per clock cycle, or 33kHz.

The Hardware SPI can run at a maximum of half FCPU. For an Arduino, that is 8MHz.

Based on that, using the SPI library should be around 240 times faster.
Logged

~Tom~

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17303
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A digitalWrite() call takes about 15us to execute. There are two pins that need to be controlled meaning that the absolute max speed you can achieve using the wiring library is 2*15us = 30us per clock cycle, or 33kHz.

The Hardware SPI can run at a maximum of half FCPU. For an Arduino, that is 8MHz.

Based on that, using the SPI library should be around 240 times faster.

There could also be a alternate method using direct port access in the software SPI that would be somewhere between hardware SPI and software SPI using arduino digital pin commands.

Lefty
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 137
Posts: 6792
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(whether the faster communications rate will actually improve the way things LOOK is a separate question.)

You could speed up the comm a great deal, without running into the limitations of hardware SPI, but replacing the digitalWrite/digitalRead calls with "port IO" statements.
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 80
Posts: 1729
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yup, you can get about 250kHz from a bitbanged software SPI using direct port writes from what I have seen. I can get 125k on an 8MHz ATTiny with the software SPI library I wrote.

I've attached the library. It is not quite finished, but it works, and has all the features of the Hardware SPI library except that you call begin() with the four arduino pin numbers for your SPI interface:
begin(SCK, MOSI, MISO, SS);

* TinySoftwareSPI.h (1.97 KB - downloaded 143 times.)
* TinySoftwareSPI.cpp (4.55 KB - downloaded 170 times.)
Logged

~Tom~

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for sharing the software SPI implementation, Tom, it looks damned useful.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Offline Offline
Shannon Member
****
Karma: 216
Posts: 12554
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A digitalWrite() call takes about 15us to execute.

No, its about 4us with constant parameters on a 16MHz Uno, meaning about 15kB/s rate for bit-banged
SPI using digitalWrite (about 18 calls)

With full speed Hardware SPI on that board you get bytes sent at 8MHz, but some overhead between bytes,
so the practical rate is about 500kB/s so long as you toggle the CS pin with direct port manipulation (using digitalWrite
for that will dominate the time in SPI handling)

Bit-banging with direct port manipulation can get you close to the hardware SPI speeds.

The UART can be programmed to do SPI master mode too I believe.
Logged

[ I won't respond to messages, use the forum please ]

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2741
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A digitalWrite() call takes about 15us to execute.
It isn't that long on a 16mhz AVR.  I've measured this many times and just
measured it again earlier today on a 16mhz atmega328 using a logic analyzer
and it is right at about 4.8us.

Still pretty abysmal compared to what an AVR can do with direct port i/o which is 62.5ns

--- bill
Logged

Offline Offline
God Member
*****
Karma: 19
Posts: 787
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've used a lot of SPI and I've never really used the SPI library yet.  I ususally use direct port access to set my slave select pins and then I just write bytes to SPDR and watch SPIF to see when it's time to load on another.  It can go really really fast like that.

I would probably use the SPI library if I hadn't already found that method from reading the datasheet and a bit of code.  But that's how I do it. 


A blocking example:
Code:
SPDR = byteToSend;
while(!(SPSR & (1<<SPIF)));



For a non-blocking code, you could check SPIF every time to let you know you can send another byte or I suppose you could even set up an interrupt to handle it. 
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I haven't tried anything like that but I'm curious to know whether there's a reason for doing the send/wait in that order. Intuitively I've have guessed it would be more efficient to do it the other way round (prepare the byte to send, wait for the hardware to become idle, send the byte, move on and do something else).
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
A blocking example:

I would flip the sequence:

Code:
while(!(SPSR & (1<<SPIF))) continue; //wait if the prior transmission hasn't ended

SPDR = byteToSend;

This can be considerably faster than your sequency.
Logged

Offline Offline
God Member
*****
Karma: 19
Posts: 787
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see.  I guess you're right.  The code I grabbed was actually waiting for a reply.  So it had a line after that.

Code:
byteRecieved = SPDR;

And in that code I was waiting for the flag so I would know there would be good data in SPDR to read. 
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 227
Posts: 6637
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you want to get the maximum speed out of the hardware SPI, It's even faster if you don't wait for the SPIF bit but instead include just the right number of NOPs between writing one byte and the next to SPDR.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

And the right number is ? And is it constant  for a given SPI Clock setting ?

Duane B
Logged


Pages: [1] 2   Go Up
Jump to: