00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <stdarg.h>
00004 #include <unistd.h>
00005
00006 #include <pigpio.h>
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #define MAX_GPIOS 32
00040
00041 #define OPT_P_MIN 1
00042 #define OPT_P_MAX 1000
00043 #define OPT_P_DEF 20
00044
00045 #define OPT_R_MIN 1
00046 #define OPT_R_MAX 10
00047 #define OPT_R_DEF 5
00048
00049 #define OPT_S_MIN 1
00050 #define OPT_S_MAX 10
00051 #define OPT_S_DEF 5
00052
00053 static volatile int g_pulse_count[MAX_GPIOS];
00054 static volatile int g_reset_counts;
00055 static uint32_t g_mask;
00056
00057 static int g_num_gpios;
00058 static int g_gpio[MAX_GPIOS];
00059
00060 static int g_opt_p = OPT_P_DEF;
00061 static int g_opt_r = OPT_R_DEF;
00062 static int g_opt_s = OPT_S_DEF;
00063 static int g_opt_t = 0;
00064
00065 void usage()
00066 {
00067 fprintf
00068 (stderr,
00069 "\n" \
00070 "Usage: sudo ./freq_count_1 gpio ... [OPTION] ...\n" \
00071 " -p value, sets pulses every p micros, %d-%d, TESTING only\n" \
00072 " -r value, sets refresh period in deciseconds, %d-%d, default %d\n" \
00073 " -s value, sets sampling rate in micros, %d-%d, default %d\n" \
00074 "\nEXAMPLE\n" \
00075 "sudo ./freq_count_1 4 7 -r2 -s2\n" \
00076 "Monitor gpios 4 and 7. Refresh every 0.2 seconds. Sample rate 2 micros.\n" \
00077 "\n",
00078 OPT_P_MIN, OPT_P_MAX,
00079 OPT_R_MIN, OPT_R_MAX, OPT_R_DEF,
00080 OPT_S_MIN, OPT_S_MAX, OPT_S_DEF
00081 );
00082 }
00083
00084 void fatal(int show_usage, char *fmt, ...)
00085 {
00086 char buf[128];
00087 va_list ap;
00088
00089 va_start(ap, fmt);
00090 vsnprintf(buf, sizeof(buf), fmt, ap);
00091 va_end(ap);
00092
00093 fprintf(stderr, "%s\n", buf);
00094
00095 if (show_usage) usage();
00096
00097 fflush(stderr);
00098
00099 exit(EXIT_FAILURE);
00100 }
00101
00102 static int initOpts(int argc, char *argv[])
00103 {
00104 int i, opt;
00105
00106 while ((opt = getopt(argc, argv, "p:r:s:")) != -1)
00107 {
00108 i = -1;
00109
00110 switch (opt)
00111 {
00112 case 'p':
00113 i = atoi(optarg);
00114 if ((i >= OPT_P_MIN) && (i <= OPT_P_MAX))
00115 g_opt_p = i;
00116 else fatal(1, "invalid -p option (%d)", i);
00117 g_opt_t = 1;
00118 break;
00119
00120 case 'r':
00121 i = atoi(optarg);
00122 if ((i >= OPT_R_MIN) && (i <= OPT_R_MAX))
00123 g_opt_r = i;
00124 else fatal(1, "invalid -r option (%d)", i);
00125 break;
00126
00127 case 's':
00128 i = atoi(optarg);
00129 if ((i >= OPT_S_MIN) && (i <= OPT_S_MAX))
00130 g_opt_s = i;
00131 else fatal(1, "invalid -s option (%d)", i);
00132 break;
00133
00134 default:
00135 usage();
00136 exit(-1);
00137 }
00138 }
00139 return optind;
00140 }
00141
00142 void edges(int gpio, int level, uint32_t tick)
00143 {
00144 int g;
00145
00146 if (g_reset_counts)
00147 {
00148 g_reset_counts = 0;
00149 for (g=0; g<MAX_GPIOS; g++) g_pulse_count[g] = 0;
00150 }
00151
00152
00153 if (level == 1) g_pulse_count[gpio]++;
00154 }
00155
00156 int main(int argc, char *argv[])
00157 {
00158 int i, rest, g, wave_id, mode;
00159 gpioPulse_t pulse[2];
00160 int count[MAX_GPIOS];
00161
00162
00163
00164 rest = initOpts(argc, argv);
00165
00166
00167
00168 g_num_gpios = 0;
00169
00170 for (i=rest; i<argc; i++)
00171 {
00172 g = atoi(argv[i]);
00173 if ((g>=0) && (g<32))
00174 {
00175 g_gpio[g_num_gpios++] = g;
00176 g_mask |= (1<<g);
00177 }
00178 else fatal(1, "%d is not a valid g_gpio number\n", g);
00179 }
00180
00181 if (!g_num_gpios) fatal(1, "At least one gpio must be specified");
00182
00183 printf("Monitoring gpios");
00184 for (i=0; i<g_num_gpios; i++) printf(" %d", g_gpio[i]);
00185 printf("\nSample rate %d micros, refresh rate %d deciseconds\n",
00186 g_opt_s, g_opt_r);
00187
00188 gpioCfgClock(g_opt_s, 1, 1);
00189
00190 if (gpioInitialise()<0) return 1;
00191
00192 gpioWaveClear();
00193
00194 pulse[0].gpioOn = g_mask;
00195 pulse[0].gpioOff = 0;
00196 pulse[0].usDelay = g_opt_p;
00197
00198 pulse[1].gpioOn = 0;
00199 pulse[1].gpioOff = g_mask;
00200 pulse[1].usDelay = g_opt_p;
00201
00202 gpioWaveAddGeneric(2, pulse);
00203
00204 wave_id = gpioWaveCreate();
00205
00206
00207
00208 for (i=0; i<g_num_gpios; i++) gpioSetAlertFunc(g_gpio[i], edges);
00209
00210 mode = PI_INPUT;
00211
00212 if (g_opt_t)
00213 {
00214 gpioWaveTxSend(wave_id, PI_WAVE_MODE_REPEAT);
00215 mode = PI_OUTPUT;
00216 }
00217
00218 for (i=0; i<g_num_gpios; i++) gpioSetMode(g_gpio[i], mode);
00219
00220 while (1)
00221 {
00222 for (i=0; i<g_num_gpios; i++) count[i] = g_pulse_count[g_gpio[i]];
00223
00224 g_reset_counts = 1;
00225
00226 for (i=0; i<g_num_gpios; i++)
00227 {
00228 printf(" %d=%d", g_gpio[i], count[i]);
00229 }
00230
00231 printf("\n");
00232
00233 gpioDelay(g_opt_r * 100000);
00234 }
00235
00236 gpioTerminate();
00237 }
00238