8 Replies Latest reply on Aug 12, 2015 3:38 AM by Mackeyorama

    SPI.setClockDivider and mraa_spi_frequency does not have an effect?

    KurtE

      As I have mentioned in a few different threads.  I have been playing around with the Adafruit_ILI9341 drivers.  I have a version that runs using the Arduino IDE uses the SPI library and another version that runs under linux using the MRAA library.  In both places I am trying to speed the code up

       

      As far as I can tell trying to set the SPI speed has no effect on what I am seeing on the SPI output.  In all cases the CLK line appears to have the same pulse where each cycle is about 80ns.

       

      I think I found some of the srouces for the SPIDEV device, but I believe it calls off to some other driver when you try to set the max clock.  But not sure yet which one.  Not sure if the underlying device is failing the requested speed and as such always uses the default. 

       

      I have tried modifying the MRAA code to set both Read and write max speed.  Before it also sent the speed as part of each transfer request.  In all cases my timing appears to be the same.

       

      Suggestions?  Which driver is the underlying driver for the Edison hardware SPI?

       

      Thanks

        • 1. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
          mikemoy

          I know this is not much help, but mraa_spi_frequency works for me.

          • 2. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
            KurtE

            Yes, I am seeing a little differences with the speed, but not much.  It would still be good to know how this is handled at the device driver level.  For example suppose I give it a 256 byte buffer to output, does it use DMA to output it? Does it spin on waiting for each SPI output (I assume not), or is it fielding an interrupt after each output.  Is there any hardware FIFO queue or is it each transfer at a time?

             

            Kurt

            • 3. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
              mikemoy

              I am on the hunt for the same thing. There has to be a way to kick this up. I ran into this the other day it may be of help.

              http://hertaville.com/2013/07/24/interfacing-an-spi-adc-mcp3008-chip-to-the-raspberry-pi-using-c/

              lower on the page he says this:

               

              • Write your own custom/optimized ADC device driver. Have a look at the 24th (June 2014) edition of the MagPi Magazine. The first article explains how to write a Linux driver for a 6-bit 10MSPS ADC and use it in conjunction with GNUplot to plot the waveforms.

               

              In the magazine article shows things in more detail. He even turns off IRQ's before and then back on after the read.

              I have not gotten that far yet. I tried the code in the first link and the Edison does not output the 3 bytes but only one. Yet the same code i tried on 3 other linux boards and they did output 3 bytes. Strange.... So until i figure that out i am stuck.

              • 4. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
                KurtE

                Since there was some updates today and it looked like SPI was involved I hoped things magically sped up.  So far I don't see any speedups.  Looking at the Logic Analyzer timings still showed that the Frequency was about 6.25mhz and still have large gap in between bytes.

                 

                So I did some hacking on MRAA to see if I find anything.  I tried to see if changing using a write instead of the IOCTL to output the buffers, no change.  I thought maybe the fact that MRAA did not set the max speed but instead passed it in each packet, might be something so I tried setting the max as well.

                 

                Out of curiosity at device start I did a IOCTL to do a query of the max speed, which I output in a printf.  It printed:  Max Speed 6250000

                 

                Again I tried actually setting this speed, and printed out what the result:

                mraa_result_t

                mraa_spi_frequency(mraa_spi_context dev, int hz)

                {

                    dev->clock = hz;

                  

                #if 1

                    uint32_t ulMaxSpeed = hz;

                    ioctl(dev->devfd,  SPI_IOC_WR_MAX_SPEED_HZ, &ulMaxSpeed);

                    ioctl(dev->devfd,  SPI_IOC_RD_MAX_SPEED_HZ, &ulMaxSpeed);

                printf("Try %u Max Speed %u\n", hz, ulMaxSpeed);

                #endif

                 

                    return MRAA_SUCCESS;

                }

                What I saw was: Try 8000000 Max Speed 6250000

                 

                So so far it looks like I can not update to any faster speed.  Is there some other external setting to allow it to go faster?  Also wonder if there is a setting for inter byte gap?

                • 5. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
                  hk101

                  Hi KurtE,

                   

                  I posted earlier on a different thread on the same issue.

                   

                  Can Intel please confirm the max speed we can ever get is 6.25MHz on the SPI ?

                   

                  The Intel® Edison Compute Module Hardware Guide says:

                  4.4 SPI interface

                  An SPI interface is available on pins 51, 53, 55, 57, and 59. The interface has two available chip selects.

                  • In a single-frame transfer, the SoC supports all four possible combinations for the serial clock phase and polarity.

                  • In multiple frame transfer, the SoC supports SPH=1 and SPO= 0 or 1.

                  • The SoC may toggle the slave select signal between each data frame for SPH=0.

                  • 25 MHz Master mode, 16.67 MHz slave mode.

                  • 6. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
                    KurtE

                    Yes it would be great to know the answer.

                     

                    Again not sure what the limiter is.  It appears like there is a fifo queue on both TX and RX to the SPI, so I would think we should be able keep the SPI running at full speed.  From some of the comments I have seen up on the forum and in the code, I get the impression that there is some form of software limiter going on.

                     

                    Currently not sure that the speed of each byte is the main inhibitor for getting reasonable performance out of things like the Adafruit TFT display.   The real bottleneck is the delay between each byte output.

                     

                    Also in addition to this wonder if/when DMA access to the SPI will be supported.  I know for example the higher performance implementation of the TFT software for the Arduino Due depends on this.

                     

                    I hope to take some more time soon and again try to figure out where in the code base the hardware SPI is actually handled.

                     

                    Again hints would be greatly appreciated.

                    • 7. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
                      Nag

                      I am also tired.... and getting max spi speed as 6.25Mhz.

                      Please someone form Intel can confirm the max speed we can ever get is 6.25MHz on the SPI ?

                      • 8. Re: SPI.setClockDivider and mraa_spi_frequency does not have an effect?
                        Mackeyorama

                        I was looking for an answer to this question also, here is what I have found so far. The limitation is defined by the libmraa and depends on the board the Edison is connected to. The 25Mhz/4 = 6.25Mhz limit is mentioned in the Edison Arduino mraa documentation mraa: Intel Edison.

                         

                        The Edison is capable of 25Mhz SPI if you don't use an arduino based breakout board and the Arduino IDE. So your only options if you want to use the mraa library @ 25Mhz is the mini breakout board or a custom board.  After a bit of work on a custom board seems to be working alright so far me.