Still struggling with Xilinx GPIO...

John Bonesio john.bonesio at xilinx.com
Wed May 28 02:42:20 EST 2008


Hi Guillaume,

Try using channel 1. It may be set up where the first channel is 1 and
not 0.

- John

On Mon, 2008-05-26 at 17:43 +0200, Guillaume Dargaud wrote:

> I still haven't managed to figure out how to use the Xilinx GPIO from 
> usermode.
> 
> The program gpio_test found at 
> http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/archive/2004/05/msg00004.html 
> and slightly modified as this:
> 
> #include <stdio.h>
> #include <fcntl.h>
> #include <errno.h>
> #include <string.h>
> 
> #include <linux/types.h>
> #include <sys/ioctl.h>
> 
> #include <xgpio_ioctl.h>
> 
> #define GPIO_DEV "/dev/xgpio"
> 
> void usage(int argc, char *argv[])
> {
>         fprintf(stderr,"usage: %s hexval\n\n", argv[0]);
>         fprintf(stderr,"\n");
>         fprintf(stderr,"Puts the input hexval onto the LEDs, and\n");
>         fprintf(stderr,"displays the current value on the DIP switches\n");
>         fprintf(stderr,"\n");
>         fprintf(stderr,"try  gpio_test FC\n\n");
> 
> }
> 
> void dump_dipsw(int val)
> {
>         int i;
>         val = (val & 0x000000FF);
> 
>         printf("DIP SW: ");
>         for(i=0;i<8;i++)
>         {
>                 printf("%i",val & 0x01);
>                 val >>= 1;
>         }
>         printf("\n");
> }
> 
> /* Turn 4 LSB of X into 8 bit LED segment code */
> unsigned char nyb_hex2led(int x)
> {
>         unsigned char led_tab[] = {
>                 0xFC, 0x60, 0xDA, 0xF2,
>                 0x66, 0xB6, 0xBE, 0xE0,
>                 0xFE, 0xF6, 0xEE, 0x3E,
>                 0x9C, 0x7A, 0x9E, 0x8E};
> 
>         return led_tab[x & 0xF];
> }
> 
> /* Turn 8 LSB of x into 2 times 8 bit LED segment codes */
> unsigned short hex2led(int x)
> {
>         return (nyb_hex2led(x & 0xF) << 8) | (nyb_hex2led((x >> 4) & 0xF));
> }
> 
> int main(int argc, char *argv[])
> {
>         /* Open the device */
>         int fd = open(GPIO_DEV, O_RDWR);
> 
>         struct xgpio_ioctl_data gpio_ioctl;
>         // struct ibm_gpio_ioctl_data gpio_ioctl;
> //      int     result;
> //      int command;
> 
>         if(fd==-1) {
>                 fprintf(stderr,"Unable to open %s\n", GPIO_DEV);
>                 return -1;
>         }
> 
> /*
>         if(argc!=2)
>         {
>                 usage();
>                 exit(1);
>         }
> */
>         gpio_ioctl.chan=0;
> 
>         /* Set the tristates */
>         gpio_ioctl.mask=0x000000FF;
>         ioctl(fd, XGPIO_TRISTATE,(void *)&gpio_ioctl);
> 
>         /* Get output data from command line if provided */
> 
>         if(argc==2)
>                 sscanf(argv[1],"%x",&(gpio_ioctl.data));
>         else
>                 gpio_ioctl.data=time(NULL);
> 
>         /* Convert binary (16 LSB) into LED segment codes and shift into
>            position on gpio */
>         gpio_ioctl.data=hex2led(gpio_ioctl.data & 0xFF)<<8;
> 
>         ioctl(fd, XGPIO_OUT,(void *)&gpio_ioctl);
> 
>         /* Read some data */
>         ioctl(fd, XGPIO_IN,(void *)&gpio_ioctl);
> 
>         dump_dipsw(gpio_ioctl.data);
> 
>         return 0;
> }
> 
> 
> ...crashes in flames when run:
> 
> # gpio_test FC
> [ 1366.864955] Oops: kernel access of bad area, sig: 11 [#5]
> [ 1366.867560] NIP: c0108d50 LR: c00e68c4 CTR: 00000000
> [ 1366.867560] REGS: c752fde0 TRAP: 0300   Tainted: G      D   (2.6.25-rc9)
> [ 1366.867560] MSR: 00029030 <EE,ME,IR,DR>  CR: 93000033  XER: e000007f
> [ 1366.867560] DEAR: c8fffffc, ESR: 00000000
> [ 1366.867560] TASK = c7c37030[202] 'gpio_test' THREAD: c752e000
> [ 1366.867560] GPR00: 00000000 c752fe90 c7c37030 c8fffffc 00000056 0000000c 
> c752feb0 00000000
> [ 1366.867560] GPR08: 00000000 11111111 ffffffe7 c7c5866c 00000000 10018dec 
> ffff8432 ffdf1d0f
> [ 1366.867560] GPR16: ffffffff ffffffff ffffffff ffffffff ffffffff 00000000 
> 100af244 10000858
> [ 1366.867560] GPR24: 10000c00 00000002 10000478 800c5a03 c7c58000 c7c5866c 
> 800c5a03 c0200000
> [ 1366.867560] NIP [c0108d50] XIo_In32+0x4/0xc
> [ 1366.867560] LR [c00e68c4] XGpio_GetDataDirection+0x84/0xac
> [ 1366.867560] Call Trace:
> [ 1366.867560] [c752fe90] [c00e66a8] xgpio_getinst+0x48/0xb0 (unreliable)
> [ 1366.867560] [c752fea0] [c00e6a8c] xgpio_ioctl+0x1a0/0x1fc
> [ 1366.867560] [c752fed0] [c006740c] vfs_ioctl+0x6c/0x84
> [ 1366.867560] [c752fee0] [c006778c] do_vfs_ioctl+0x368/0x39c
> [ 1366.867560] [c752ff10] [c0067800] sys_ioctl+0x40/0x70
> [ 1366.867560] [c752ff40] [c0002770] ret_from_syscall+0x0/0x3c
> [ 1366.867560] Instruction dump:
> [ 1366.867560] 7c634b78 7c031b78 4e800020 7c0006ac 88630000 5463063e 
> 4e800020 7c0006ac
> [ 1366.867560] a0630000 5463043e 4e800020 7c0006ac <80630000> 4e800020 
> 7c0006ac 7c601e2c
> Segmentation fault
> 
> 
> # dmesg | grep gpio
> [    0.120666] Registering device xilinx_gpio:0
> [    0.121672] Registering device xilinx_gpio:1
> [    0.122682] Registering device xilinx_gpio:2
> [    0.292352] xgpio0 #0 at 0x81400000 mapped to 0xC9000000 device: 10,185 
> using IRQ#7
> [    0.293805] xgpio1 #1 at 0x81420000 mapped to 0xC9020000 device: 10,186 
> using IRQ#6
> [    0.295062] xgpio2 #2 at 0x81440000 mapped to 0xC9040000 device: 10,187 
> using IRQ#5
> [ 1366.867560] TASK = c7c37030[202] 'gpio_test' THREAD: c752e000
> [ 1366.867560] [c752fe90] [c00e66a8] xgpio_getinst+0x48/0xb0 (unreliable)
> [ 1366.867560] [c752fea0] [c00e6a8c] xgpio_ioctl+0x1a0/0x1fc
> 
> 
> 
> Another program using a different strategy also fails:
> 
> #include <fcntl.h>
> #include <stdio.h>
> 
> int main (int argc, char *argv[]) {
>  if (argc==2 || argc==3) {
> 
>   int fd = open(argv[1], O_RDWR | O_NDELAY );
>   if (fd < 0) {
>      fprintf(stderr, "GPIO OPEN FAIL\n");
>      return -1;
>   }
> 
>   unsigned long buff = 0;
>   if (argc==2) {
>    if (read(fd, &buff, 4) != 4)
>       fprintf(stderr, "GPIO READ ERROR\n");
>    else printf( "%x\n", buff);
>   } else {
>    buff=atoi(argv[2]);
>    if (write(fd, &buff, 4) != 4)
>       fprintf(stderr, "GPIO WRITE ERROR value %x\n", buff);
>    else printf( "Written %x successfully\n", buff);
>   }
> 
>   close(fd);
>  } else {
>   fprintf(stderr, "Usage: %s device [value] to read or write data to gpio 
> device\n", argv[0]);
>   return 1;
>  }
> 
>  return 0;
> }
> 
> 
> # GpioReadWrite /dev/xgpio
> GPIO READ ERROR
> # GpioReadWrite /dev/xgpio 7
> GPIO WRITE ERROR value 0
> 
> I wanted to avoid writing a kernel module, but apparently I've ran out of 
> options...


________________________________________________________________________

John Bonesio
Commercial Linux Solutions
john.bonesio at xilinx.com
(408) 879-5569


This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20080527/f5c5e00f/attachment.htm>


More information about the Linuxppc-dev mailing list