Staggering SPI
         Performance
Or how I learned to stop bit-banging and love SPDR
                       --Dg
Project background

                               • Multi-led project
                               • Shift register based controllers
                               • Software PWM
                               • 40-60% cpu use target

Wi nøt tei a høliday in Sweden this yer?
Software PWM
                       • 32 rgb leds, 96 individual leds
                       • 12 8-bit shift registers to turn leds on/off
                       • 12 bytes output per round
                       • 128 levels of color desired
                       • ~100Hz refresh rate wanted
                       • 12,800 rounds of sending 12 bytes/second
See the løveli lakes
NO BITBANGING


                            • Bit twiddling may be fun, but it is slow
                            • Order of magnitude slower than hardware
                                 spi - numbers later




The wonderful telephøne system
Arduino Hardware SPI
                              • Suggestions for use found online suggest:
                                     while(morestuff) {
                                       data = morestuff;
                                       SPDR = data;
                                       while(!(SPSR & (1<<SPIF)));
                                     }



And mani interesting furry animals
Waiting for ?

                               • 63.2µs / 12 byte round of output
                               • 12,500 rounds/second - 80% cpu used
                               • 28% of time spent waiting for SPI to be
                                 ready
                               • waiting sucks

Including the majestic møøse
Staggered SPI output
                                 • Do work while waiting:
                           data = stuff;
                           SPDR=data;
                           while(morestuff) {
                             data = morestuff;
                             while(!(SPSR & (1<<SPIF)));
                             SPDR=data;
                           }

A Møøse once bit my sister ...
Staggered numbers

                              • 49.1µs/round - 61% cpu spent doing PWM
                              • 7% of that still spent spinning for SPSR
                              • More to peel out?

No realli! She was Karving her initials on the møøse with the sharpened end of an interspace tøøthbrush given her by Svenge - her brother-in-law - an Oslo dentist and the star of many Norwegian møvies: “The Høt Hands of an Oslo Dentist”, “Fillings
of Passion”, “The Huge Mølars of Horst Nordfink”
Squeezing more
                              • Loop unrolling buys more time
                              • 42.4µs/round - 53% cpu usage
                                SPDR = data; data=morestuff; SPSRWait;
                                SPDR = data; data=morestuff; SPSRWait;
                                SPDR = data; data=morestuff; SPSRWait;
                                SPDR = data; data=morestuff; SPSRWait;
                                ....

Mynd you, møøse bites Kan be pretty nasti...
Bitbanging?

                              • 586.6µs/round
                              • 73% cpu usage
                              • only 1000 rounds - 10 levels of color at
                                           100Hz or 20 at 50Hz
                              • any higher flickers

Did you kno that Møøse like bit banging?
More techniques
                            • Smoother PWM by spreading out work
                            • Hiding SPSR waiting in interrupts
                            • Clock counting, hand assembler
                            • Take advantage of avr opcodes *(--pData)
                                      becomes a single opcode (dec and
                                      derefence)


They dø! Dirty, dirty bit banging møøses...
Fin

                                                    Daniel Garcia
                                                 dgarcia@dgarcia.net
                                                        --Dg




Møøse trained by TUTTE HERMSGERVORDENBROTBORDA

Staggering spi performance for arduino

  • 1.
    Staggering SPI Performance Or how I learned to stop bit-banging and love SPDR --Dg
  • 2.
    Project background • Multi-led project • Shift register based controllers • Software PWM • 40-60% cpu use target Wi nøt tei a høliday in Sweden this yer?
  • 3.
    Software PWM • 32 rgb leds, 96 individual leds • 12 8-bit shift registers to turn leds on/off • 12 bytes output per round • 128 levels of color desired • ~100Hz refresh rate wanted • 12,800 rounds of sending 12 bytes/second See the løveli lakes
  • 4.
    NO BITBANGING • Bit twiddling may be fun, but it is slow • Order of magnitude slower than hardware spi - numbers later The wonderful telephøne system
  • 5.
    Arduino Hardware SPI • Suggestions for use found online suggest: while(morestuff) { data = morestuff; SPDR = data; while(!(SPSR & (1<<SPIF))); } And mani interesting furry animals
  • 6.
    Waiting for ? • 63.2µs / 12 byte round of output • 12,500 rounds/second - 80% cpu used • 28% of time spent waiting for SPI to be ready • waiting sucks Including the majestic møøse
  • 7.
    Staggered SPI output • Do work while waiting: data = stuff; SPDR=data; while(morestuff) { data = morestuff; while(!(SPSR & (1<<SPIF))); SPDR=data; } A Møøse once bit my sister ...
  • 8.
    Staggered numbers • 49.1µs/round - 61% cpu spent doing PWM • 7% of that still spent spinning for SPSR • More to peel out? No realli! She was Karving her initials on the møøse with the sharpened end of an interspace tøøthbrush given her by Svenge - her brother-in-law - an Oslo dentist and the star of many Norwegian møvies: “The Høt Hands of an Oslo Dentist”, “Fillings of Passion”, “The Huge Mølars of Horst Nordfink”
  • 9.
    Squeezing more • Loop unrolling buys more time • 42.4µs/round - 53% cpu usage SPDR = data; data=morestuff; SPSRWait; SPDR = data; data=morestuff; SPSRWait; SPDR = data; data=morestuff; SPSRWait; SPDR = data; data=morestuff; SPSRWait; .... Mynd you, møøse bites Kan be pretty nasti...
  • 10.
    Bitbanging? • 586.6µs/round • 73% cpu usage • only 1000 rounds - 10 levels of color at 100Hz or 20 at 50Hz • any higher flickers Did you kno that Møøse like bit banging?
  • 11.
    More techniques • Smoother PWM by spreading out work • Hiding SPSR waiting in interrupts • Clock counting, hand assembler • Take advantage of avr opcodes *(--pData) becomes a single opcode (dec and derefence) They dø! Dirty, dirty bit banging møøses...
  • 12.
    Fin Daniel Garcia dgarcia@dgarcia.net --Dg Møøse trained by TUTTE HERMSGERVORDENBROTBORDA