pikeyd165 – Blame information for rev 1

Subversion Repositories:
Rev:
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 }