[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [microblaze-uclinux] GPIO in /dev/gpio



Thank you very much for your help. This was exactly what I should have 
put in the vendors/Xilinx/uclinux-auto/Makefile

I have succesfully applied the cyclone and KIT pattern to the LED's.

PS: I'm using microblaze

Paul Hartke a écrit :
> I'm working on GPIO as well.  I have been using the following in
> vendors/Xilinx/uclinux-auto/Makefile
> 
> ifdef CONFIG_XILINX_GPIO
> DEVICES +=      \
>         gpio,c,10,185
> endif
> 
> Note that you do not need multiple entries in /dev/ for multiple gpios
> instances since the GPIO adapter multiplexes accesses to more than 1 GPIO. 
> I have used the attached program to successfully read GPIO but don't have
> writes working yet.  I can use xmd to successfully write the gpios so I
> think its a software issue somewhere.
> 
> The adapter in the current version of uclinux is much different than the one
> in the latest PPC tree.  Nothing jumps out at me as an issue though:
> http://ppc.bkbits.net:8080/linuxppc-2.4/src/drivers/char//xilinx_gpio?nav=src/drivers/char/
> 
> Let me know if you are successful so we can feed these changes back into the
> distro.
> 
> Paul
> 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <string.h>
> #include <sys/ioctl.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <linux/ibm_ocp_gpio.h>
> 
> static void
> usage(char *argv0)
> {
> 	char *basename = strrchr(argv0, '/');
> 	if (!basename)
> 		basename = argv0;
> 
> 	fprintf(stderr,
> 		"Usage: %s [-d DEVICE] [-n DEV_INSTANCE] [-m MASK] COMMAND\n"
> 		"  where COMMAND is one of:\n"
> 		"    -i           Input value from GPIO and print it\n"
> 		"    -o VALUE     Output value to GPIO\n"
> 		"    -t VALUE     Set tristate to value\n"
> 		"    -c           Cylon test pattern\n"
> 		"    -k           KIT test pattern\n"
> 		"  DEVICE indicates which GPIO driver to talk to (default is /dev/gpio)\n"
> 		"  DEV_INSTANCE indicates which GPIO interface to talk to (default is
> zero)\n"
> 		"  MASK is ANDed with the value (default is all ones)\n"
> 		, basename);
> 
> 	exit(2);
> }
> 
> static const unsigned long cylon[] = {
> 	0x80000000, 0x40000000, 0x20000000, 0x10000000,
> 	0x08000000, 0x04000000, 0x02000000, 0x01000000,
> 	0x00800000, 0x00400000, 0x00200000, 0x00100000,
> 	0x00080000, 0x00040000, 0x00020000, 0x00010000,
> 	0x00008000, 0x00004000, 0x00002000, 0x00001000,
> 	0x00000800, 0x00000400, 0x00000200, 0x00000100,
> 	0x00000080, 0x00000040, 0x00000020, 0x00000010,
> 	0x00000008, 0x00000004, 0x00000002, 0x00000001,
> 		    0x00000002, 0x00000004, 0x00000008,
> 	0x00000010, 0x00000020, 0x00000040, 0x00000080,
> 	0x00000100, 0x00000200, 0x00000400, 0x00000800,
> 	0x00001000, 0x00002000, 0x00004000, 0x00008000,
> 	0x00010000, 0x00020000, 0x00040000, 0x00080000,
> 	0x00100000, 0x00200000, 0x00400000, 0x00800000,
> 	0x01000000, 0x02000000, 0x04000000, 0x08000000,
> 	0x10000000, 0x20000000, 0x40000000
> };
> static const unsigned long kit[] = {
> 	0x80000000, 0xc0000000,
> 	0xe0000000, 0x70000000, 0x38000000, 0x1c000000,
> 	0x0e000000, 0x07000000, 0x03800000, 0x01c00000,
> 	0x00e00000, 0x00700000, 0x00380000, 0x001c0000,
> 	0x000e0000, 0x00070000, 0x00038000, 0x0001c000,
> 	0x0000e000, 0x00007000, 0x00003800, 0x00001c00,
> 	0x00000e00, 0x00000700, 0x00000380, 0x000001c0,
> 	0x000000e0, 0x00000070, 0x00000038, 0x0000001c,
> 	0x0000000e, 0x00000007, 0x00000003, 0x00000001,
> 		    0x00000003, 0x00000007, 0x0000000e,
> 	0x0000001c, 0x00000038, 0x00000070, 0x000000e0,
> 	0x000001c0, 0x00000380, 0x00000700, 0x00000e00,
> 	0x00001c00, 0x00003800, 0x00007000, 0x0000e000,
> 	0x0001c000, 0x00038000, 0x00070000, 0x000e0000,
> 	0x001c0000, 0x00380000, 0x00700000, 0x00e00000,
> 	0x01c00000, 0x03800000, 0x07000000, 0x0e000000,
> 	0x1c000000, 0x38000000, 0x70000000, 0xe0000000,
> 	0xc0000000
> };
> #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
> 
> int
> main(int argc, char **argv)
> {
> 	extern char *optarg;
> 	char *cptr;
> 	enum { NONE, IN, OUT, TRISTATE, CYLON, KIT } operation = NONE;
> 	char *devfile = "/dev/gpio";
> 	struct ibm_gpio_ioctl_data ioctl_data;
> 	int i, fd;
> 
> 	ioctl_data.device = 0;
> 	ioctl_data.data = 0;
> 	ioctl_data.mask = ~0;
> 
> 	while ((i = getopt(argc, argv, "d:n:m:io:t:ck")) != EOF) {
> 		switch (i) {
> 		case 'd':
> 			devfile = optarg;
> 			break;
> 		case 'n':
> 			ioctl_data.device = strtoul(optarg, &cptr, 0);
> 			if (cptr == optarg)
> 				usage(argv[0]);
> 			break;
> 		case 'm':
> 			ioctl_data.mask = strtoul(optarg, &cptr, 0);
> 			if (cptr == optarg)
> 				usage(argv[0]);
> 			break;
> 		case 'i':
> 			operation = IN;
> 			break;
> 		case 'o':
> 			operation = OUT;
> 			ioctl_data.data = strtoul(optarg, &cptr, 0);
> 			if (cptr == optarg)
> 				usage(argv[0]);
> 			break;
> 		case 't':
> 			operation = TRISTATE;
> 			ioctl_data.data = strtoul(optarg, &cptr, 0);
> 			if (cptr == optarg)
> 				usage(argv[0]);
> 			break;
> 		case 'c':
> 			operation = CYLON;
> 			break;
> 		case 'k':
> 			operation = KIT;
> 			break;
> 		case '?':
> 			usage(argv[0]);
> 		}
> 	}
> 
> 	if (optind < argc || operation == NONE) {
> 		usage(argv[0]);
> 	}
> 
> 	if ((fd = open(devfile, O_RDWR)) == -1) {
> 		perror(devfile);
> 		exit(1);
> 	}
> 
> 	switch (operation) {
> 	case IN:
> 		if (ioctl(fd, IBMGPIO_IN, &ioctl_data) == -1) {
> 			perror(devfile);
> 			exit(1);
> 		}
> 		printf("0x%08X\n", ioctl_data.data);
> 		break;
> 	case OUT:
> 		if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
> 			perror(devfile);
> 			exit(1);
> 		}
> 		break;
> 	case TRISTATE:
> 		if (ioctl(fd, IBMGPIO_TRISTATE, &ioctl_data) == -1) {
> 			perror(devfile);
> 			exit(1);
> 		}
> 		break;
> 	case CYLON:
> #define CYLON_DELAY_USECS (10000)
> 		for (;;) {
> 			for (i=0; i<ARRAY_SIZE(cylon); i++) {
> 				ioctl_data.data = cylon[i];
> 				if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
> 					perror(devfile);
> 					exit(1);
> 				}
> 				usleep(CYLON_DELAY_USECS);
> 			}
> 		}
> 		break;
> 	case KIT:
> #define KIT_DELAY_USECS (10000)
> 		ioctl_data.data = ~0UL;
> 		if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
> 			perror(devfile);
> 			exit(1);
> 		}
> 		usleep(KIT_DELAY_USECS);
> 		for (;;) {
> 			for (i=0; i<ARRAY_SIZE(kit); i++) {
> 				ioctl_data.data = kit[i];
> 				if (ioctl(fd, IBMGPIO_OUT, &ioctl_data) == -1) {
> 					perror(devfile);
> 					exit(1);
> 				}
> 				usleep(KIT_DELAY_USECS);
> 			}
> 		}
> 		break;
> 	}
> 	close(fd);
> 	return 0;
> }
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Quoting Arnaud Lagger <arnaud.lagger@epfl.ch>:
> 
>>Dear all,
>>
>>I'm trying to use the GPIO, as in gpio_test but /dev/gpio doesn't appear
>>in uClinux.
>>
>>So I added:
>>
>>----
>>
>>ifdef CONFIG_XILINX_GPIO
>>DEVICES +=   \
>>	gpio,c,185,0	gpio1,c,185,1	gpio2,c,185,2	\
>>	gpio3,c,185,3	gpio4,c,185,4	gpio5,c,185,5	\
>>	gpio6,c,185,6	gpio7,c,185,7	gpio8,c,185,8	\
>>	gpio9,c,185,9	gpio10,c,185,10	gpio11,c,185,11	\
>>	gpio12,c,185,12	gpio13,c,185,13	gpio14,c,185,14	\
>>	gpio15,c,185,15	gpio16,c,185,16	gpio17,c,185,17	\
>>	gpio18,c,185,18	gpio19,c,185,19	gpio20,c,185,20	\
>>	gpio21,c,185,21	gpio22,c,185,22	gpio23,c,185,23
>>endif
>>
>>----
>>
>>in vendors/Xilinx/uclinux-auto/Makefile
>>
>>and /dev/gpio appears but it cannot be opened (with for instance
>>open("/dev/gpio", O_RDWR))!
>>
>>Any idea?
>>
>>Thanks,
>>
>>Arnaud Lagger
>>___________________________
>>microblaze-uclinux mailing list
>>microblaze-uclinux@itee.uq.edu.au
>>Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
>>Mailing List Archive :
>>http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/
>>
> 
> ___________________________
> microblaze-uclinux mailing list
> microblaze-uclinux@itee.uq.edu.au
> Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
> Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/
> 

___________________________
microblaze-uclinux mailing list
microblaze-uclinux@itee.uq.edu.au
Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/