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