pikeyd165 – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /******************************************************************************* |
2 | * |
||
3 | * gpio.c |
||
4 | * |
||
5 | * Copyright (c) 2013 Shahrooz Shahparnia |
||
6 | * |
||
7 | * Description: |
||
8 | * gpio is a command-line utility for executing gpio commands with the |
||
9 | * Broadcom bcm2835. It was developed and tested on a Raspberry Pi single-board |
||
10 | * computer model B. The utility is based on the bcm2835 C library developed |
||
11 | * by Mike McCauley of Open System Consultants, http://www.open.com.au/mikem/bcm2835/. |
||
12 | * |
||
13 | * Invoking "gpio" results in a read, set of clear of a GPIO. |
||
14 | * Options include GPIO read/set/clear |
||
15 | * of a single GPIO pin, enabling or disabling pull up and pull downs as well as |
||
16 | * resetting all GPIOs to a default input state. |
||
17 | * The command usage and command-line parameters are described below |
||
18 | * in the showusage function, which prints the usage if no command-line parameters |
||
19 | * are included or if there are any command-line parameter errors. Invoking gpio |
||
20 | * requires root privilege. |
||
21 | * |
||
22 | * This file contains the main function as well as functions for displaying |
||
23 | * usage and for parsing the command line. |
||
24 | * |
||
25 | * Open Source Licensing GNU GPLv3 |
||
26 | * |
||
27 | * Building: |
||
28 | * After installing bcm2835, you can build this |
||
29 | * with something like: |
||
30 | * gcc -o gpio gpio.c -l bcm2835 |
||
31 | * sudo ./gpio |
||
32 | * |
||
33 | * Or you can test it before installing with: |
||
34 | * gcc -o gpio -I ../../src ../../src/bcm2835.c gpio.c |
||
35 | * sudo ./gpio |
||
36 | * |
||
37 | * |
||
38 | * History: |
||
39 | * 11/10 VERSION 1.0.0: Original |
||
40 | * |
||
41 | * User input parsing (comparse) and showusage\ |
||
42 | * have been adapted from: http://ipsolutionscorp.com/raspberry-pi-spi-utility/ |
||
43 | * mostly to keep consistence with the spincl tool usage. |
||
44 | * |
||
45 | * Compile with: gcc -o gpio gpio.c bcm2835.c |
||
46 | * |
||
47 | * Examples: |
||
48 | * Clear pin 5: sudo ./gpio -ib -dc -pn -n5 |
||
49 | * Reset all GPIOs to inputs and disable all pull up/downs: sudo ./gpio -ie |
||
50 | * Read pin 10: sudo ./gpio -ib -dr -pn -n10 |
||
51 | * Read pin 10 in debug mode with verbose output: sudo ./gpio -ib -dr -pn -n10 -b |
||
52 | * Read pin 10 and set pin as input with pull down: sudo ./gpio -ib -di -pd -n10 |
||
53 | * |
||
54 | * Note: Pin numbers match the Raspberry Pie connector pin numbers |
||
55 | ********************************************************************************/ |
||
56 | |||
57 | #include <bcm2835.h> |
||
58 | #include <stdio.h> |
||
59 | #include <stdlib.h> |
||
60 | #include <string.h> |
||
61 | #include <stdint.h> |
||
62 | |||
63 | #define MODE_READ 0 |
||
64 | #define MODE_SET 1 |
||
65 | #define MODE_CLR 2 |
||
66 | #define MODE_INPUT_READ 3 |
||
67 | |||
68 | #define PULL_UP 0 |
||
69 | #define PULL_DOWN 1 |
||
70 | #define NO_PULL 2 |
||
71 | |||
72 | #define GPIO_BEGIN 0 |
||
73 | #define GPIO_END 1 |
||
74 | #define NO_ACTION 2 |
||
75 | |||
76 | #define NO_PIN 40 // Some big number that's beyond the connector's pin count |
||
77 | #define DEBUG_OFF 0 |
||
78 | #define DEBUG_ON 1 |
||
79 | |||
80 | uint8_t init = NO_ACTION; |
||
81 | uint8_t pull = NO_PULL; |
||
82 | uint8_t mode = MODE_READ; |
||
83 | uint8_t pin_number = NO_PIN; |
||
84 | |||
85 | uint8_t i, len; |
||
86 | uint8_t data, pin, debug_mode = DEBUG_OFF; |
||
87 | |||
88 | //******************************************************************************* |
||
89 | // comparse: Parse the command line and return EXIT_SUCCESS or EXIT_FAILURE |
||
90 | // argc: number of command-line arguments |
||
91 | // argv: array of command-line argument strings |
||
92 | //******************************************************************************* |
||
93 | |||
94 | void gpio_reset(void); |
||
95 | |||
96 | int comparse(int argc, char **argv) { |
||
97 | int argnum, i, xmitnum; |
||
98 | |||
99 | if (argc < 2) { // must have at least program name and len arguments |
||
100 | // or -ie (GPIO_END) or -ib (GPIO_BEGIN) |
||
101 | fprintf(stderr, "Insufficient command line arguments\n"); |
||
102 | return EXIT_FAILURE; |
||
103 | } |
||
104 | |||
105 | argnum = 1; |
||
106 | while (argnum < argc && argv[argnum][0] == '-') { |
||
107 | |||
108 | switch (argv[argnum][1]) { |
||
109 | |||
110 | case 'i': // GPIO init |
||
111 | switch (argv[argnum][2]) { |
||
112 | case 'b': init = GPIO_BEGIN; break; |
||
113 | case 'e': init = GPIO_END; break; |
||
114 | default: |
||
115 | fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]); |
||
116 | return EXIT_FAILURE; |
||
117 | } |
||
118 | break; |
||
119 | |||
120 | case 'd': // Set/Clear/Read Mode |
||
121 | switch (argv[argnum][2]) { |
||
122 | case 'r': mode = MODE_READ; break; |
||
123 | case 's': mode = MODE_SET; break; |
||
124 | case 'c': mode = MODE_CLR; break; |
||
125 | case 'i': mode = MODE_INPUT_READ; break; |
||
126 | default: |
||
127 | fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]); |
||
128 | return EXIT_FAILURE; |
||
129 | } |
||
130 | break; |
||
131 | |||
132 | case 'p': // Pull up, down and no pull Mode |
||
133 | switch (argv[argnum][2]) { |
||
134 | case 'u': pull = PULL_UP; break; |
||
135 | case 'd': pull = PULL_DOWN; break; |
||
136 | case 'n': pull = NO_PULL; break; |
||
137 | default: |
||
138 | fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]); |
||
139 | return EXIT_FAILURE; |
||
140 | } |
||
141 | break; |
||
142 | |||
143 | case 'n': // pin number |
||
144 | pin_number = atoi(argv[argnum]+2); |
||
145 | break; |
||
146 | |||
147 | case 'b': // debug mode |
||
148 | debug_mode = DEBUG_ON; |
||
149 | break; |
||
150 | |||
151 | default: |
||
152 | fprintf(stderr, "%c is not a valid option\n", argv[argnum][1]); |
||
153 | return EXIT_FAILURE; |
||
154 | } |
||
155 | |||
156 | argnum++; // advance the argument number |
||
157 | |||
158 | } |
||
159 | |||
160 | if (argnum == argc && init != NO_ACTION) // no further arguments are needed |
||
161 | return EXIT_SUCCESS; |
||
162 | |||
163 | return EXIT_SUCCESS; |
||
164 | } |
||
165 | |||
166 | //******************************************************************************* |
||
167 | // showusage: Print the usage statement and return errcode. |
||
168 | //******************************************************************************* |
||
169 | |||
170 | int showusage(int errcode) { |
||
171 | printf("gpio \n"); |
||
172 | printf("Usage: \n"); |
||
173 | printf(" gpio [options]\n"); |
||
174 | printf("\n"); |
||
175 | printf(" Invoking gpio to set or reset a GPIO, enable disable pull up or pull down. Initialize or release a GPIO.\n"); |
||
176 | printf("\n"); |
||
177 | printf(" The following are the options, which must be a single letter\n"); |
||
178 | printf(" preceded by a '-' and followed by another character.\n"); |
||
179 | printf(" -ix where x is the GPIO init option, b[egin] or e[nd]\n"); |
||
180 | printf(" The begin option must be executed before any transfer can happen.\n"); |
||
181 | printf(" The end option will return the GPIO to inputs and turn off all pull up and pull downs.\n"); |
||
182 | printf(" It may be included with a transfer.\n"); |
||
183 | printf(" -dx where x is 'c' for clear, 's' is for set, 'r' for read and 'i' for read and set as input.\n"); |
||
184 | printf(" -px where x is the GPIO pull up or down option. 'u' for pull up, 'd' for pull down and 'n' for none.\n"); |
||
185 | printf(" -nx where x is the pin number.\n"); |
||
186 | printf("\n"); |
||
187 | return errcode; |
||
188 | } |
||
189 | |||
190 | int main(int argc, char **argv) { |
||
191 | |||
192 | printf("Running ... \n"); |
||
193 | |||
194 | // parse the command line |
||
195 | if (comparse(argc, argv) == EXIT_FAILURE) return showusage (EXIT_FAILURE); |
||
196 | |||
197 | if (!bcm2835_init()) return 1; |
||
198 | |||
199 | // GPIO begin if specified |
||
200 | if (init == GPIO_BEGIN) ; |
||
201 | |||
202 | |||
203 | // If len is 0, no need to continue, but do GPIO end if specified |
||
204 | // if (len == 0) { |
||
205 | // if (init == GPIO_END) ; |
||
206 | // printf("Zero length ... error!\n"); |
||
207 | // return EXIT_SUCCESS; |
||
208 | // } |
||
209 | switch (pin_number) { |
||
210 | case 3: |
||
211 | pin = RPI_V2_GPIO_P1_03; |
||
212 | break; |
||
213 | case 5: |
||
214 | pin = RPI_V2_GPIO_P1_05; |
||
215 | break; |
||
216 | case 7: |
||
217 | pin = RPI_V2_GPIO_P1_07; |
||
218 | break; |
||
219 | case 26: |
||
220 | pin = RPI_V2_GPIO_P1_26; |
||
221 | break; |
||
222 | case 24: |
||
223 | pin = RPI_V2_GPIO_P1_24; |
||
224 | break; |
||
225 | case 21: |
||
226 | pin = RPI_V2_GPIO_P1_21; |
||
227 | break; |
||
228 | case 19: |
||
229 | pin = RPI_V2_GPIO_P1_19; |
||
230 | break; |
||
231 | case 23: |
||
232 | pin = RPI_V2_GPIO_P1_23; |
||
233 | break; |
||
234 | case 10: |
||
235 | pin = RPI_V2_GPIO_P1_10; |
||
236 | break; |
||
237 | case 11: |
||
238 | pin = RPI_V2_GPIO_P1_11; |
||
239 | break; |
||
240 | case 12: |
||
241 | pin = RPI_V2_GPIO_P1_12; |
||
242 | break; |
||
243 | case 13: |
||
244 | pin = RPI_V2_GPIO_P1_13; |
||
245 | break; |
||
246 | case 15: |
||
247 | pin = RPI_V2_GPIO_P1_15; |
||
248 | break; |
||
249 | case 16: |
||
250 | pin = RPI_V2_GPIO_P1_16; |
||
251 | break; |
||
252 | case 18: |
||
253 | pin = RPI_V2_GPIO_P1_18; |
||
254 | break; |
||
255 | case 22: |
||
256 | pin = RPI_V2_GPIO_P1_22; |
||
257 | break; |
||
258 | default: |
||
259 | pin = NO_PIN; |
||
260 | } |
||
261 | |||
262 | switch (pull) { |
||
263 | case PULL_UP: |
||
264 | bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_UP); |
||
265 | break; |
||
266 | case PULL_DOWN: |
||
267 | bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_DOWN); |
||
268 | break; |
||
269 | case NO_PULL: |
||
270 | bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_OFF); |
||
271 | break; |
||
272 | default: |
||
273 | bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_OFF); |
||
274 | } |
||
275 | |||
276 | switch (mode) { |
||
277 | case MODE_READ: |
||
278 | data = bcm2835_gpio_lev(pin); |
||
279 | printf("Reading pin: %d\n", data); |
||
280 | break; |
||
281 | case MODE_INPUT_READ: |
||
282 | bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT); |
||
283 | data = bcm2835_gpio_lev(pin); |
||
284 | printf("Reading pin: %d\n", data); |
||
285 | break; |
||
286 | case MODE_SET: |
||
287 | bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP); |
||
288 | bcm2835_gpio_set(pin); |
||
289 | break; |
||
290 | case MODE_CLR: |
||
291 | bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP); |
||
292 | bcm2835_gpio_clr(pin); |
||
293 | break; |
||
294 | default: |
||
295 | printf("Wrong mode ...!\n"); |
||
296 | } |
||
297 | |||
298 | if (debug_mode == DEBUG_ON) { |
||
299 | printf("Init %d\n", init); |
||
300 | printf("Mode %d\n", mode); |
||
301 | printf("Pull %d\n", pull); |
||
302 | printf("Pin Number %d\n", pin_number); |
||
303 | printf("Pin %d\n", pin); |
||
304 | } |
||
305 | |||
306 | if (init == GPIO_END) gpio_reset(); |
||
307 | bcm2835_close(); |
||
308 | printf("... done!\n"); |
||
309 | return 0; |
||
310 | } |
||
311 | |||
312 | void gpio_reset(void) { |
||
313 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_03, BCM2835_GPIO_PUD_OFF); |
||
314 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_05, BCM2835_GPIO_PUD_OFF); |
||
315 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_07, BCM2835_GPIO_PUD_OFF); |
||
316 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_26, BCM2835_GPIO_PUD_OFF); |
||
317 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_24, BCM2835_GPIO_PUD_OFF); |
||
318 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_21, BCM2835_GPIO_PUD_OFF); |
||
319 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_19, BCM2835_GPIO_PUD_OFF); |
||
320 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_23, BCM2835_GPIO_PUD_OFF); |
||
321 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_10, BCM2835_GPIO_PUD_OFF); |
||
322 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_11, BCM2835_GPIO_PUD_OFF); |
||
323 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_12, BCM2835_GPIO_PUD_OFF); |
||
324 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_13, BCM2835_GPIO_PUD_OFF); |
||
325 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_15, BCM2835_GPIO_PUD_OFF); |
||
326 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_16, BCM2835_GPIO_PUD_OFF); |
||
327 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_18, BCM2835_GPIO_PUD_OFF); |
||
328 | bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_22, BCM2835_GPIO_PUD_OFF); |
||
329 | |||
330 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT); |
||
331 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT); |
||
332 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_07, BCM2835_GPIO_FSEL_INPT); |
||
333 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_26, BCM2835_GPIO_FSEL_INPT); |
||
334 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_24, BCM2835_GPIO_FSEL_INPT); |
||
335 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_21, BCM2835_GPIO_FSEL_INPT); |
||
336 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_19, BCM2835_GPIO_FSEL_INPT); |
||
337 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_23, BCM2835_GPIO_FSEL_INPT); |
||
338 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_10, BCM2835_GPIO_FSEL_INPT); |
||
339 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_11, BCM2835_GPIO_FSEL_INPT); |
||
340 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_12, BCM2835_GPIO_FSEL_INPT); |
||
341 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_13, BCM2835_GPIO_FSEL_INPT); |
||
342 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_15, BCM2835_GPIO_FSEL_INPT); |
||
343 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_16, BCM2835_GPIO_FSEL_INPT); |
||
344 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_18, BCM2835_GPIO_FSEL_INPT); |
||
345 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_22, BCM2835_GPIO_FSEL_INPT); |
||
346 | } |