[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/