9 Replies Latest reply on Jul 2, 2014 9:52 AM by kirkwood

    SPI speed of the Galileo

    kirkwood

      Hello everybody,

       

      I have been searching around this forum looking for info on the SPI speed of the Galileo. I have found some information at the links below:

       

      1. Re: what's the max speed of galileo SPI ?
      2. I/O speeds?

       

      So it seems that the SPI speed is slow for using Arduino shields with SPI interfaces. I gather the reason is because the Quark chip doesn’t provide the same GPIO ports as the Arduino’s microcontroller, it has to deliver them indirectly by way of an on-board I²C Port Expander, the Cypress chip, which operates at the I²C standard clock rate of 100kHz but adds inevitable lag, so GPIO access takes 2ms and the read/write frequency is limited to 230 kHz.

       

      In short, is there anything that I can do improve the SPI speed using the Arduino SPI library?


      Also, I found this in the FAQ. any indication as to when this will be implemented? Will this make it comparable to the Arduino in terms of speed?

      Q: What is the maximum SPI clock speed supported?

      The default setting for the SPI clock on Intel® Galileo is 4 MHz, the same as Arduino Uno. Similarly, the SPI clock can be varied from 125 kHz to 8 MHz using SPI.setClockDivider(). The Intel® Quark SoC X1000 supports SPI clock frequencies up to 25 MHz, but this support is not yet added in the Arduino IDE.

       

      Steven

        • 1. Re: SPI speed of the Galileo
          JPMontero_Intel

          Hi

          Yes you can improve the performance by doing some changes to the SPI library. We ran some tests and by using the SPI.setClockDivider(dividers) we got with the divider SPI_CLOCK_DIV4 4Mhz which is the standard, with the SPI_CLOCK_DIV2 we received 8.33MHz. In case you haven’t used this function it is normally used in the void setup(), and it looks like this:

          SPI.setClockDivider(SPI_CLOCK_DIV2)

          The dividers available for this are SPI_CLOCK_DIV2, SPI_CLOCK_DIV4, SPI_CLOCK_DIV8, SPI_CLOCK_DIV16, SPI_CLOCK_DIV32, SPI_CLOCK_DIV64 and SPI_CLOCK_DIV128. The SPI_CLOCK_DIV2 is the fastest and SPI_CLOCK_DIV8 the slowest.


          The library for the SPI is located in C:\Arduino-1.5.3\hardware\arduino\x86\libraries\SPI. We modified the SPI.cpp file, in the section that says “void SPIClass::setClockDivider(uint8_t clkDiv)”, in there are some cases, which dictates the behavior of the dividers used in the setClockDivider function. To improve the speed we changed the value of the SPI_CLOCK_DIV2 by modifying the line

          maxSpeedHz = SPI_CLK_DEFAULT_HZ << 1;

          And we change the value to 2, and the line looked like this:

          maxSpeedHz = SPI_CLK_DEFAULT_HZ << 2;

          With this modification we got 12.5MHz, and if you change the value to 3 it will give 25MHz. You can try with this, but I really don’t know if this change will affect anything else, and the signal might not be as accurate as with lower speeds, but If you decide to try it let us know your results.

           

          Regards
          JPMontero_Intel

          • 2. Re: Re: SPI speed of the Galileo
            kirkwood

            Hi JP,

             

            Thanks for your detailed reply.

             

            I see that the GPIO including the SPI (from ICSP header) is handled via the Cypress chip, from the pdf schematics. However, it was inconsistent with what I observed during the tests. I measured the SPI clock to be 4MHz and above. How is this achieved through the cypress chip if itself is on 100kHz I2C bus? And why is the point to do so?

             

            Thanks

            Stev

            • 3. Re: Re: SPI speed of the Galileo
              SpiderKenny

              I don't think SPI comes via the Cypress chip at all.

              Lets trace the pins on the schematic. I'll start with the pin headers and work back to the processor.

               

              Lets trace the MOSI signal which appears on Pin 11 of the Arduino header.

              Page "23 of 27" shows the pin headers.

              **NOTE The page numbers in the schematic are all out by one. I have reported this before. **

               

              Pin 11 from the header goes through Resistor "R3M18" and becomes a signal called "IO11" Which leaves this page and goes to <22B1>. Due to the page references all being wrong (out by 1) this is actually page 21 Section B1.

              Screen Shot 2014-06-20 at 12.10.06.png

               

              On Page 21, Section B1, the signal IO11 goes through the Mulitplexor (MUX) and can be selected as either of the signals LVL_SPI1_MOSI or IO11_GPIO_PWM, so lets follow LVL_SPI1_MOSI.

              Screen Shot 2014-06-20 at 12.19.51.png

              It goes off to <22C1> (which is actually 21C1) so on page 21 at section C1 we see that it goes through the 3.3V to 5V level shifter and comes out, now called SPI1_MOSI:

              Screen Shot 2014-06-20 at 12.21.57.png

               

              So now, called SPI1_MOSI it goes off to 7D7, (which is actually 6D7 grrr... that stupid page bug!!!)

              On page 7D7 6D7 we see it going straight into the Quark X1000 SoC, i.e. the main processor.

              Screen Shot 2014-06-20 at 12.25.32.png

               

              So, you should be able to get full native speed on the SPI bus, one way or another.

              If doing it through the file system with System() commands from Arduino, you must remember to switch on the Level translator and the MUX too.

              Then you need to look at the data sheet for the MUX chip and Level translator chip and make sure they can also support your desired frequency. You then also need to take into account that Resistor R3M18 which is there for protection from ESD and for impedance matching, and worry about whether that is going to affect any pull-up resistors on your shield, and the slew rate of the signal edges. Rather than try to do a bunch of complicated engineers maths, the best approach would be to try it, test it and see if it works.

               

              The MUX chip has a stated bandwidth of 100 MHz.

              The level translator has a maximum signal frequency of 60 Mbps in push-pull mode, or just 2 Mbps in open-drain mode. It is not immediately clear which mode is being used here.

              I hope this helps!

              • 4. Re: Re: SPI speed of the Galileo
                SpiderKenny

                >>The level translator has a maximum signal frequency of 60 Mbps in push-pull mode, or just 2 Mbps in open-drain mode.


                I suspect most SPI signals are open drain (driven low) with a passive pull up to VCC, meaning you might find that the maximum data rate of just 2 Mbps applies here. I might be wrong about that. It would certainly tie in which my experience with my LED Matrix shield, because it started to misbehave above 1 Mbps, and I am sure it was the signal slew rate that was the issue. You can probably work around this though.

                • 5. Re: SPI speed of the Galileo
                  kirkwood

                  Hi SpiderKenny,

                   

                  Firstly, thanks for providing such a detailed response, I appreciate all the effort. 

                   

                  I'm confused now though. JPMontero_Intel is this consistent with what the results of your experiments show? I'm relatively new to Arduino programming and learning fast!

                   

                  Thanks

                  Stev

                  • 6. Re: Re: SPI speed of the Galileo
                    SpiderKenny

                    >>I'm confused now though

                    When accessing SPI through Arduino sketches it may not be possible to achieve the theoretical maximum throughput, as (and this is not verified) I suspect there is some setup and teardown overhead with each SPI transaction through Arduino functions. I opted to use C programs compiled right on the Galileo itself and using Linux user mode libraries rather than arduino libraries because it works for me, and fits into my comfort zone. You could probably go even further and modify or even write your own linux kernel mode code to create an optimised SPI driver for a specific function, but that is probably not a great approach.

                    • 7. Re: Re: Re: SPI speed of the Galileo
                      kirkwood

                      Hi SpiderKenny,

                       

                      I've figured out the SPI configuration:

                       

                      1. SPI is provided at SoC level, SCK, MISO, MOSI, come out of the Quark chip

                      2. Muxing to bring out SPI lines is performed by the cypress gpio expander

                      3. SPI chip select line is gpio controlled. 

                       

                      Quick question, in the SPI libary can you choose which lines to use for SS, MOSI, MISO and SCK? Could I use the two fast GPIOs IO2 and IO3 to speed up the performance? Data only flows in one direction so I don't need MISO. Of the remaining 3 which 2 should I (could I) assign to SS, MOSI and SCK for optimal performance?

                       

                      Thanks

                      Stev

                      • 8. Re: Re: Re: SPI speed of the Galileo
                        SpiderKenny

                        I'm surprised that the library allows you to choose GPIO lines for the signals, as their is no routing available on the board.

                        If it indeed does work that you can select alternate lines, I think they must be 'bit banged' by the library, which would be slow.

                         

                        Like I always say, test it and see if it works!

                        • 9. Re: Re: Re: SPI speed of the Galileo
                          kirkwood

                          I don't think the library allows you to choose GPIO lines, I'm looking at it now and can't see anything, but I really don't know...