Help? SPI communication slow

cmicrocontrollerspi

I am using an Intel Edison with Arduino Breakout Board to communicate via SPI to a LS7366R Quadrature Encoder Buffer. I am using the QEB as a timer: a pulse that enters the index will shift the counter register to an OTR register for reading.

My problem is with the speed of SPI communication from IE to QEB. I am programming IE with a mraa library to communicate via SPI in C. According to a clock speed of 6.25 MHz, it should take 1.28 microseconds to transfer 1 byte. Instead, it takes 60 microseconds. I do not know why my SPI communication is slow. I have already ensured that communication is working properly, albeit slow.

Proof: The following code takes on average .61 seconds to execute. If I remove line 3, it takes on average .005 seconds to execute.

1. for(i = 0; i < 10000; i++) {
2.     mraa_gpio_write(ss_o, 0);  // ss_o is slave select one
3.     mraa_spi_write(spi, 0x60); // transfer 1 byte via spi
4.     mraa_gpio_write(ss_o, 1);  // end transmission
5. }

My question: How can I speed up my spi communications?

I am using mraa version: v0.6.1

EDIT: After transmitting 5 bytes of data at a time, I found that the initialization may be taking a long time. Replacing line 3 above with…

3.    mraa_spi_write_buf(spi, write_buf, 5);

… results in .65 seconds, a minute increase of time for 5 times the data sent. I am not an expert on parsing libraries, so can anyone help me find the bottleneck in the mraa spi library? I want to see if I can edit it to speed up the SPI calls.

EDIT: CLARIFICATION: I am intending to use the counter as a timer; every time a pulse comes in I want to know when it came in. Therefore, I need fast repeated reads of the OTR register.

EDIT: added full code:

#include <stdio.h>
#include <time.h>
#include "mraa.h"

int i = 0;
mraa spi_context spi;
mraa_gpio_context ss_o;  // ss_o is slave select one
clock_t start, end;

int main(void) {
    spi = mraa_spi_init(0);
    mraa_spi_frequency(spi, 6250000); // Set frequency to 6.25 MHz
    mraa_spi_mode(spi, 0);
    ss_o = mraa_gpio_init(10);  // ss_o is pin 10)
    mraa_gpio_dir(ss_o, MRAA_GPIO_OUT);
    mraa_gpio_use_mmaped(ss_o, 1);
    mraa_gpio_write(ss_o, 1);

    // Initialize counters
    mraa_gpio_write(ss_o, 0); // Begin SPI conversation
    mraa_spi_write(spi, 0x90);
    mraa_spi_write(spi, 0x1);
    mraa_gpio_write(ss_o, 1); // Terminate SPI conversation

    mraa_gpio_write(ss_o, 0); // Begin SPI conversation
    mraa_spi_write(spi, 0x88);
    mraa_spi_write(spi, 0x30);
    mraa_gpio_write(ss_o, 1); // Terminate SPI conversation

    start = clock();  // For measuring time
    for(i = 0; i < 10000; i++) {
        mraa_gpio_write(ss_o, 0);  // ss_o is slave select one
        mraa_spi_write(spi, 0x60); // transfer 1 byte via spi
        mraa_gpio_write(ss_o, 1);  // end transmission
    }
    end = clock();
    double diff = (double)(end - start) / (CLOCKS_PER_SEC);
    printf("Time elapsed: %f\n", diff);

}

Best Answer

Try this,,,,there is no need to select same slave and end transmission for every count,,,,you can end it after all 10000 counts are finished

  mraa_gpio_write(ss_o, 0);  // ss_o is slave select one  
  for(i = 0; i < 10000; i++) 
    {
        mraa_spi_write(spi, 0x60); // transfer 1 byte via spi    
    }
mraa_gpio_write(ss_o, 1);  // end transmission

hope this helps