0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <unistd.h>
0012 #include <stdlib.h>
0013 #include <stdbool.h>
0014 #include <stdio.h>
0015 #include <dirent.h>
0016 #include <errno.h>
0017 #include <string.h>
0018 #include <poll.h>
0019 #include <fcntl.h>
0020 #include <getopt.h>
0021 #include <sys/ioctl.h>
0022 #include <linux/gpio.h>
0023 #include "gpio-utils.h"
0024
0025 int hammer_device(const char *device_name, unsigned int *lines, int num_lines,
0026 unsigned int loops)
0027 {
0028 struct gpio_v2_line_values values;
0029 struct gpio_v2_line_config config;
0030 char swirr[] = "-\\|/";
0031 int fd;
0032 int ret;
0033 int i, j;
0034 unsigned int iteration = 0;
0035
0036 memset(&config, 0, sizeof(config));
0037 config.flags = GPIO_V2_LINE_FLAG_OUTPUT;
0038
0039 ret = gpiotools_request_line(device_name, lines, num_lines,
0040 &config, "gpio-hammer");
0041 if (ret < 0)
0042 goto exit_error;
0043 else
0044 fd = ret;
0045
0046 values.mask = 0;
0047 values.bits = 0;
0048 for (i = 0; i < num_lines; i++)
0049 gpiotools_set_bit(&values.mask, i);
0050
0051 ret = gpiotools_get_values(fd, &values);
0052 if (ret < 0)
0053 goto exit_close_error;
0054
0055 fprintf(stdout, "Hammer lines [");
0056 for (i = 0; i < num_lines; i++) {
0057 fprintf(stdout, "%d", lines[i]);
0058 if (i != (num_lines - 1))
0059 fprintf(stdout, ", ");
0060 }
0061 fprintf(stdout, "] on %s, initial states: [", device_name);
0062 for (i = 0; i < num_lines; i++) {
0063 fprintf(stdout, "%d", gpiotools_test_bit(values.bits, i));
0064 if (i != (num_lines - 1))
0065 fprintf(stdout, ", ");
0066 }
0067 fprintf(stdout, "]\n");
0068
0069
0070 j = 0;
0071 while (1) {
0072
0073 for (i = 0; i < num_lines; i++)
0074 gpiotools_change_bit(&values.bits, i);
0075
0076 ret = gpiotools_set_values(fd, &values);
0077 if (ret < 0)
0078 goto exit_close_error;
0079
0080
0081 ret = gpiotools_get_values(fd, &values);
0082 if (ret < 0)
0083 goto exit_close_error;
0084
0085 fprintf(stdout, "[%c] ", swirr[j]);
0086 j++;
0087 if (j == sizeof(swirr) - 1)
0088 j = 0;
0089
0090 fprintf(stdout, "[");
0091 for (i = 0; i < num_lines; i++) {
0092 fprintf(stdout, "%d: %d", lines[i],
0093 gpiotools_test_bit(values.bits, i));
0094 if (i != (num_lines - 1))
0095 fprintf(stdout, ", ");
0096 }
0097 fprintf(stdout, "]\r");
0098 fflush(stdout);
0099 sleep(1);
0100 iteration++;
0101 if (loops && iteration == loops)
0102 break;
0103 }
0104 fprintf(stdout, "\n");
0105 ret = 0;
0106
0107 exit_close_error:
0108 gpiotools_release_line(fd);
0109 exit_error:
0110 return ret;
0111 }
0112
0113 void print_usage(void)
0114 {
0115 fprintf(stderr, "Usage: gpio-hammer [options]...\n"
0116 "Hammer GPIO lines, 0->1->0->1...\n"
0117 " -n <name> Hammer GPIOs on a named device (must be stated)\n"
0118 " -o <n> Offset[s] to hammer, at least one, several can be stated\n"
0119 " [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n"
0120 " -? This helptext\n"
0121 "\n"
0122 "Example:\n"
0123 "gpio-hammer -n gpiochip0 -o 4\n"
0124 );
0125 }
0126
0127 int main(int argc, char **argv)
0128 {
0129 const char *device_name = NULL;
0130 unsigned int lines[GPIOHANDLES_MAX];
0131 unsigned int loops = 0;
0132 int num_lines;
0133 int c;
0134 int i;
0135
0136 i = 0;
0137 while ((c = getopt(argc, argv, "c:n:o:?")) != -1) {
0138 switch (c) {
0139 case 'c':
0140 loops = strtoul(optarg, NULL, 10);
0141 break;
0142 case 'n':
0143 device_name = optarg;
0144 break;
0145 case 'o':
0146
0147
0148
0149
0150
0151 if (i < GPIOHANDLES_MAX)
0152 lines[i] = strtoul(optarg, NULL, 10);
0153
0154 i++;
0155 break;
0156 case '?':
0157 print_usage();
0158 return -1;
0159 }
0160 }
0161
0162 if (i >= GPIOHANDLES_MAX) {
0163 fprintf(stderr,
0164 "Only %d occurrences of '-o' are allowed, %d were found\n",
0165 GPIOHANDLES_MAX, i + 1);
0166 return -1;
0167 }
0168
0169 num_lines = i;
0170
0171 if (!device_name || !num_lines) {
0172 print_usage();
0173 return -1;
0174 }
0175 return hammer_device(device_name, lines, num_lines, loops);
0176 }