| /* |
| * spiSpeed.c: |
| * Code to measure the SPI speed/latency. |
| * Copyright (c) 2014 Gordon Henderson |
| *********************************************************************** |
| * This file is part of wiringPi: |
| * https://projects.drogon.net/raspberry-pi/wiringpi/ |
| * |
| * wiringPi is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU Lesser General Public License as |
| * published by the Free Software Foundation, either version 3 of the |
| * License, or (at your option) any later version. |
| * |
| * wiringPi is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with wiringPi. |
| * If not, see <http://www.gnu.org/licenses/>. |
| *********************************************************************** |
| */ |
| |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <stdint.h> |
| #include <string.h> |
| #include <errno.h> |
| //#include <fcntl.h> |
| //#include <sys/ioctl.h> |
| //#include <linux/spi/spidev.h> |
| |
| #include <wiringPi.h> |
| #include <wiringPiSPI.h> |
| |
| #define TRUE (1==1) |
| #define FALSE (!TRUE) |
| |
| #define SPI_CHAN 0 |
| #define NUM_TIMES 100 |
| #define MAX_SIZE (1024*1024) |
| |
| static int myFd ; |
| |
| |
| void spiSetup (int speed) |
| { |
| if ((myFd = wiringPiSPISetup (SPI_CHAN, speed)) < 0) |
| { |
| fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ; |
| exit (EXIT_FAILURE) ; |
| } |
| } |
| |
| |
| int main (void) |
| { |
| int speed, times, size ; |
| unsigned int start, end ; |
| int spiFail ; |
| unsigned char *myData ; |
| double timePerTransaction, perfectTimePerTransaction, dataSpeed ; |
| |
| if ((myData = malloc (MAX_SIZE)) == NULL) |
| { |
| fprintf (stderr, "Unable to allocate buffer: %s\n", strerror (errno)) ; |
| exit (EXIT_FAILURE) ; |
| } |
| |
| wiringPiSetup () ; |
| |
| for (speed = 1 ; speed <= 32 ; speed *= 2) |
| { |
| printf ("+-------+--------+----------+----------+-----------+------------+\n") ; |
| printf ("| MHz | Size | mS/Trans | TpS | Mb/Sec | Latency mS |\n") ; |
| printf ("+-------+--------+----------+----------+-----------+------------+\n") ; |
| |
| spiFail = FALSE ; |
| spiSetup (speed * 1000000) ; |
| for (size = 1 ; size <= MAX_SIZE ; size *= 2) |
| { |
| printf ("| %5d | %6d ", speed, size) ; |
| |
| start = millis () ; |
| for (times = 0 ; times < NUM_TIMES ; ++times) |
| if (wiringPiSPIDataRW (SPI_CHAN, myData, size) == -1) |
| { |
| printf ("SPI failure: %s\n", strerror (errno)) ; |
| spiFail = TRUE ; |
| break ; |
| } |
| end = millis () ; |
| |
| if (spiFail) |
| break ; |
| |
| timePerTransaction = ((double)(end - start) / (double)NUM_TIMES) / 1000.0 ; |
| dataSpeed = (double)(size * 8) / (1024.0 * 1024.0) / timePerTransaction ; |
| perfectTimePerTransaction = ((double)(size * 8)) / ((double)(speed * 1000000)) ; |
| |
| printf ("| %8.3f ", timePerTransaction * 1000.0) ; |
| printf ("| %8.1f ", 1.0 / timePerTransaction) ; |
| printf ("| %9.5f ", dataSpeed) ; |
| printf ("| %8.5f ", (timePerTransaction - perfectTimePerTransaction) * 1000.0) ; |
| printf ("|\n") ; |
| |
| } |
| |
| close (myFd) ; |
| printf ("+-------+--------+----------+----------+-----------+------------+\n") ; |
| printf ("\n") ; |
| } |
| |
| return 0 ; |
| } |