Gordons Projects

--> Projects Top-Level GIT

Build system: Add a .gitignore
[wiringPi] / examples / spiSpeed.c
1 /*
2  * spiSpeed.c:
3  *      Code to measure the SPI speed/latency.
4  *      Copyright (c) 2014 Gordon Henderson
5  ***********************************************************************
6  * This file is part of wiringPi:
7  *      https://projects.drogon.net/raspberry-pi/wiringpi/
8  *
9  *    wiringPi is free software: you can redistribute it and/or modify
10  *    it under the terms of the GNU Lesser General Public License as
11  *    published by the Free Software Foundation, either version 3 of the
12  *    License, or (at your option) any later version.
13  *
14  *    wiringPi is distributed in the hope that it will be useful,
15  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *    GNU Lesser General Public License for more details.
18  *
19  *    You should have received a copy of the GNU Lesser General Public
20  *    License along with wiringPi.
21  *    If not, see <http://www.gnu.org/licenses/>.
22  ***********************************************************************
23  */
24
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <stdint.h>
30 #include <string.h>
31 #include <errno.h>
32 //#include <fcntl.h>
33 //#include <sys/ioctl.h>
34 //#include <linux/spi/spidev.h>
35
36 #include <wiringPi.h>
37 #include <wiringPiSPI.h>
38
39 #define TRUE    (1==1)
40 #define FALSE   (!TRUE)
41
42 #define SPI_CHAN                0
43 #define NUM_TIMES               100
44 #define MAX_SIZE                (1024*1024)
45
46 static int myFd ;
47
48
49 void spiSetup (int speed)
50 {
51   if ((myFd = wiringPiSPISetup (SPI_CHAN, speed)) < 0)
52   {
53     fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ;
54     exit (EXIT_FAILURE) ;
55   }
56 }
57
58
59 int main (void)
60 {
61   int speed, times, size ;
62   unsigned int start, end ;
63   int spiFail ;
64   unsigned char *myData ;
65   double timePerTransaction, perfectTimePerTransaction, dataSpeed ;
66
67   if ((myData = malloc (MAX_SIZE)) == NULL)
68   {
69     fprintf (stderr, "Unable to allocate buffer: %s\n", strerror (errno)) ;
70     exit (EXIT_FAILURE) ;
71   }
72
73   wiringPiSetup () ;
74
75   for (speed = 1 ; speed <= 32 ; speed *= 2)
76   {
77     printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
78     printf ("|   MHz |   Size | mS/Trans |      TpS |    Mb/Sec | Latency mS |\n") ;
79     printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
80
81     spiFail = FALSE ;
82     spiSetup (speed * 1000000) ;
83     for (size = 1 ; size <= MAX_SIZE ; size *= 2)
84     {
85       printf ("| %5d | %6d ", speed, size) ;
86
87       start = millis () ;
88       for (times = 0 ; times < NUM_TIMES ; ++times)
89         if (wiringPiSPIDataRW (SPI_CHAN, myData, size) == -1)
90         {
91           printf ("SPI failure: %s\n", strerror (errno)) ;
92           spiFail = TRUE ;
93           break ;
94         }
95       end = millis () ;
96
97       if (spiFail)
98         break ;
99
100       timePerTransaction        = ((double)(end - start) / (double)NUM_TIMES) / 1000.0 ;
101       dataSpeed                 =  (double)(size * 8)    / (1024.0 * 1024.0) / timePerTransaction  ;
102       perfectTimePerTransaction = ((double)(size * 8))   / ((double)(speed * 1000000)) ;
103
104       printf ("| %8.3f ", timePerTransaction * 1000.0) ;
105       printf ("| %8.1f ", 1.0 / timePerTransaction) ;
106       printf ("| %9.5f ", dataSpeed) ;
107       printf ("|   %8.5f ", (timePerTransaction - perfectTimePerTransaction) * 1000.0) ;
108       printf ("|\n") ;
109
110     }
111
112     close (myFd) ;
113     printf ("+-------+--------+----------+----------+-----------+------------+\n") ;
114     printf ("\n") ;
115   }
116
117   return 0 ;
118 }