【引用】基于s3c2440和linux的gpio测试代码

说明:版权所有,如有转载,请注明出处。

该程序能够实现对任意一个gpio管脚进行设置,例如设置为输出管腿,设置为高电平或者低电平,方便调试。

应用测试程序

//written by bcng xiyong,2007-7-1
//set gpj4 to zero to give a kill signal to chip ltc2950

//a guidline about how to use gpio_driver
//p[0] is the address of the iocon of the io
//p[1] is the bit place, from 0 to xx,
//for example, GPJ4, p[1] is 0x4;

//for write function, the 3th parameter, if the second bit is set,  them use keep before  

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <unistd.h>

#define GPJCON 0x560000d0
#define GPJ2 0x2

#define GPGCON 0x56000060
#define GPG4 0x4
int main(int argc,char *argv[] )
{
   int fd,FunctionIndex;
   unsigned long conreg,pin;
   unsigned long  p[2];
   fd=open("/dev/gpio",O_RDWR | O_NOCTTY);
   if (fd < 0)
        {
                printf("can not open led!\n");
  return -1;
        }
 
  p[0]=GPGCON;  //GPJCON
  p[1]=GPG4;
 
  if (argc==3)
  {
                sscanf(argv[1], "%x", &conreg);
                sscanf(argv[2], "%x", &pin);
                p[0]=conreg;  //GPJCON
    p[1]=pin;
    printf("con is %x,pin is %x\n",p[0],p[1]);
       
  }
  else
  {
   printf("inpt error\n");
   return -1;
  }

 

  
  printf("+----------------------------------------+\n");
  printf("|      ARM  Linux  GPIO driver test                  |\n");
  printf("|      Write on 2007.7.1   xiyong bcng GPG4        |\n");
  printf("+----------------------------------------+\n");
  printf("\n");

  printf("\n Please select the function to test ( Main Menu):");
  printf("\n  1: write 1 ");
  printf("\n  2: write 0 ");
  printf("\n  3: set pin to function10 ");
  printf("\n  4: set pin to function11 ");
  printf("\n  5: set pin to input ");
  printf("\n  6: set pullup ");
  printf("\n  7: disable pullup ");
  printf("\n  8: display register value ");
 
  printf("\n  0: exit ");
 
  for(;;)
  {
   scanf("%d",&FunctionIndex);
   switch(FunctionIndex)
   {
   case 1:
     
      printf("write 1\n");
      write(fd,p,1);
     
      break;
  
   case 2:
     
      printf("write 0\n");
      write(fd,p,0);
     
      break;
     
   case 3:
      printf("set pin to function10 \n");
      write(fd,p,2);
      break;
  
   case 4:
      printf("set pin to function11 \n");
      write(fd,p,4);
      break;
  
   case 5:
      printf("set pin to input \n");
      read(fd,p,0);
      break;
  
   case 6:
      printf("set pullup\n");
      read(fd,p,3);
      break;
  
   case 7:
      printf("disable pullup\n");
      read(fd,p,2);
      break;
     
   case 8:
      printf("display register value\n");
      read(fd,p,8);
      break;
     
   case 0:
      close(fd);
      exit(1);
   default:
      close(fd);
      exit(1);
  } 

   }

 

驱动程序:

#include <linux/config.h>
#include <linux/init.h>
                                                                             
//#include <kernel.h> 
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
#include <asm/arch/smdk.h>

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>

#include <linux/version.h>
#include <asm/arch/smdk.h>
#include <asm/arch/S3C2440.h>

#define LED0            (1 << 0)
#define LED1            (1 << 1)
#define LED2            (1 << 2)
#define LED3            (1 << 3)

#define __NO_VERSION__
                                                                              
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif
#define DEVICE_NAME "gpio_driv"
#define IOPORT_MAJOR 100 //定义主设备号,和前面的mknod/dev/gpiotestc 220 0匹配

#define GPIO_A_CON  0x56000000
#define GPIO_A_DAT  0x56000004
#define GPIO_B_CON  0x56000010
#define GPIO_B_DAT  0x56000014
#define GPIO_B_PUP  0x56000018
#define GPIO_C_CON  0x56000020
#define GPIO_C_DAT  0x56000024
#define GPIO_C_PUP  0x56000028
#define GPIO_D_CON  0x56000030
#define GPIO_D_DAT  0x56000034
#define GPIO_D_PUP  0x56000038
#define GPIO_E_CON  0x56000040
#define GPIO_E_DAT  0x56000044
#define GPIO_E_PUP  0x56000048
#define GPIO_F_CON  0x56000050
#define GPIO_F_DAT  0x56000054
#define GPIO_F_PUP  0x56000058
#define GPIO_G_CON  0x56000060
#define GPIO_G_DAT  0x56000064
#define GPIO_G_PUP  0x56000068
#define GPIO_H_CON  0x56000070
#define GPIO_H_DAT  0x56000074
#define GPIO_H_PUP  0x56000078
#define GPIO_J_CON  0x56000080
#define GPIO_J_DAT  0x56000084
#define GPIO_J_PUP  0x56000088


static int gpio_open(struct inode*, struct file *);
static int gpio_release(struct inode*, struct file *);
static int gpio_ioctl(struct inode *, struct file *, unsigned int intcommand, unsigned long arg);
static int gpio_read(struct file *file,
                            char *buffer,       /* The buffer to fill with data
*/                          size_t length,      /* The length of the buffer */
                            loff_t * offset);    /* Our offset in the file */
static int gpio_write(struct file *inode, const char *gdata, size_t length, loff_t *off_what);

                                                                               
char kernel_version [] = UTS_RELEASE;

static struct file_operations gpio_ctl_fops=
 { ioctl: gpio_ioctl,
    read: gpio_read,
    write:gpio_write,
    open: gpio_open,
    release: gpio_release,
};

                                                                      
static int gpio_open(struct inode *inode, struct file *file)
{
        MOD_INC_USE_COUNT;
   printk ("device_open(%p,%p)\n", inode, file);
                                                                               
        /*
         * Get major / minor numbers when needed
         */
        printk ("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
                                                                               
        return 0;
}
                                                                               
static int gpio_release(struct inode *inode, struct file *file)
{
        MOD_DEC_USE_COUNT;
        return 0;
}

                                                                               
static int gpio_ioctl(struct inode*inode,struct file *flip,unsigned intcommand,unsigned long arg)
{
return 0;
}


static int gpio_read(struct file *file,
                            char *buffer,     /*buffer[0-3]=addr buffer[4-7]= bit */
                            size_t length,     
                            loff_t * offset)  
{
      unsigned long templong,tempcon,tmpold;
      unsigned char i;
      int bit,GPIOAddr,GPIOData,temp_gdata[8];
       for(i=0;i<8;i++)
        temp_gdata[i]=(int)buffer[i];
      GPIOAddr=temp_gdata[0]+temp_gdata[1]*256+temp_gdata[2]*256*256+temp_gdata[3]*256*256*256;
      GPIOData=temp_gdata[4]+temp_gdata[5]*256+temp_gdata[6]*256*256+temp_gdata[7]*256*256*256;
//      printk("\n GPIOAddr=%x  GPIOData=%x", GPIOAddr,GPIOData);   
      tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr ));
      
      tmpold=tempcon;
     
      if (length&0x8)
      {
      printk("CON is %x,DAT is %x, PULL is %x\n",
      *((volatile unsigned long *)io_p2v( GPIOAddr  )),
      *((volatile unsigned long *)io_p2v( GPIOAddr+4)),
      *((volatile unsigned long *)io_p2v( GPIOAddr+8)));
      return 0;
      }

     if (length&0x2)  //about set pullup, 1 set, 0 disable 
     {
           switch(length&0x1)
           {
        case 1: 
         templong= *((volatile unsigned long *)io_p2v( GPIOAddr+8));
         *((volatile unsigned long *)io_p2v(GPIOAddr+8 ))=templong|(1<<GPIOData); //GP DAT =1
  break;
        
        case 0:
         templong= *((volatile unsigned long *)io_p2v(GPIOAddr+8 ));
         *((volatile unsigned long *)io_p2v(GPIOAddr+8 ))=templong&(~(1<<GPIOData)); //GP DAT = 0
         break;
        
        default: break;
           }
    
     return 0;
     }
    
    
    
     *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon&(~(3<<(GPIOData*2)));  // GP CON = 00 as input

     templong= *((volatile unsigned long *)io_p2v( GPIOAddr+4));
    
     if((templong&(1<<GPIOData))!=0)
        bit=1;
      else 
        bit=0;
       
 //    printk("\nGPIOData=%x GPIO con=%x", GPIOData,*((volatile unsigned long *)io_p2v(GPIOAddr)));
    
     if (length&0x4)
       *((volatile unsigned long *)io_p2v(GPIOAddr))=tmpold;  // Keep CON IO as before
     
     return bit;  
}

static int gpio_write(struct file *inode, const char *gdata, size_t length, loff_t *off_what)
  {
      unsigned long templong,tempcon,tmpold;
      unsigned char i;
      int GPIOAddr,GPIOData,temp_gdata[8];
     
     
     
      for(i=0;i<8;i++)
        temp_gdata[i]=(int)gdata[i];
      GPIOAddr=temp_gdata[0]+temp_gdata[1]*256+temp_gdata[2]*256*256+temp_gdata[3]*256*256*256;
      GPIOData=temp_gdata[4]+temp_gdata[5]*256+temp_gdata[6]*256*256+temp_gdata[7]*256*256*256;
    //  printk("\n GPIOAddr=%x  GPIOData=%x", GPIOAddr,GPIOData);   
      tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr ));
      tmpold=tempcon;
     
      if (length&0x4)  //about set function11 
      {
              *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon|((3<<(GPIOData*2)));  // GP CON = 11 as FUNCTION2
              return 0;
      }

      if (length&0x2)  //about set function10 
      {
             *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon&(~(1<<(GPIOData*2)));  // GP CON = 10 as FUNCTION1
             tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr ));
              *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon|((1<<(GPIOData*2+1)));  // GP CON = 10 as FUNCTION1
              return 0;
      }
     
     
     
      *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon&(~(1<<(GPIOData*2+1)));  // GP CON = 01 as output
      tempcon=*((volatile unsigned long *)io_p2v(GPIOAddr ));
      *((volatile unsigned long *)io_p2v(GPIOAddr))=tempcon|((1<<(GPIOData*2)));  // GP CON = 01 as output
     
      switch(length&0x1)
     {
      case 1: 
        templong= *((volatile unsigned long *)io_p2v( GPIOAddr+4));
        *((volatile unsigned long *)io_p2v(GPIOAddr+4 ))=templong|(1<<GPIOData); //GP DAT =1
//        printk("Write gpio %d\n",length);
        break;
      case 0:
        templong= *((volatile unsigned long *)io_p2v(GPIOAddr+4 ));
        *((volatile unsigned long *)io_p2v(GPIOAddr+4 ))=templong&(~(1<<GPIOData)); //GP DAT = 0
  //      printk(" Write gpio %d\n",length);
        break;
      default: break;
     }
     
//      if (length&0x4)
//       *((volatile unsigned long *)io_p2v(GPIOAddr))=tmpold;  // Keep CON IO as before
     
      return 0;
  }
                                                                              
static int __init
gpio_init(void)
{
  int ret;                                                        
   ret = register_chrdev(IOPORT_MAJOR, DEVICE_NAME, &gpio_ctl_fops);
        if(ret < 0) {
                printk(DEVICE_NAME " can't get major number\n");
                return ret;
        }
//   gpio_Major = ret;
   printk ("_____________________ board gpio registred: major= %d\n",IOPORT_MAJOR);
 
  return 0;
}        

static void __exit
gpio_cleanup(void)
{
   int ret;
                                                                               
        /*
         * Unregister the device
         */
        ret = unregister_chrdev (IOPORT_MAJOR, DEVICE_NAME);
                                                                               
        /*
         * If there's an error, report it
         */
        if (ret < 0) {
                printk ("unregister_chrdev: error %d\n", ret);
        }

}
/*
int init_module (void)
{
int ret ;
 ret=gpio_init();
}
                                                                              
void cleanup_module (void)
{
 int ret;
 ret=gpio_cleanup();
}
                                                                            
  */                                                                    
module_init(gpio_init);
module_exit(gpio_cleanup);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值