免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6128 | 回复: 2
打印 上一主题 下一主题

[驱动] help me !!!Powerpc-linux下的GPIO驱动 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-17 18:41 |只看该作者 |倒序浏览
各位高手,帮我看看这个GPIO驱动,也不知道哪出问题了,搞了一个星期了(好郁闷,一个GPIO搞这么长时间)。先谢谢大家了。
    是这样的,我现在想用PS的方式配置一个FPGA(altera 的EP3C55F4817N)。
    现把详细信息列出:
        1、CPU:MPC8377
        2、系统:Linux2.6.25
        3、CPU与FPGA的连接信息
                 MPC8377引脚         I/O          信号名称                
                    IO2_4                  O           DATA0       
                    IO2_2                  I           nSTATUS       
                    IO2_0                  O           nCONFIG       
                    IO2_1                  I           CONF_DONE
                    IO2_3                  O           DCLK       

驱动程序
FPGA_GPIO.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/highmem.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <asm/irq.h>
#include <linux/vmalloc.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/ioctl.h>
#include "FPGA_GPIO.h"




#include <sysdev/fsl_soc.h>

#ifdef FPGA_DEBUG
#define DEBUG_INFO(fmt...) printk(fmt)
#else
#define DEBUG_INFO(fmt...) do{}while(0)
#endif

#define DEVICE_NAME  "fpga_gpio"
#define MPC8377core_FPGA_SlaveSerial_MAJOR 220

#define FPGA1_REG_ADDR   8
#define FPGA2_REG_ADDR   9

#define CPLD_PROG    31//GPIO2_0
#define CPLD_INIT    29//GPIO2_2
#define CPLD_DIN     27//GPIO2_4
#define CPLD_CCLK    28//GPIO2_3
#define CPLD_DONE    30//GPIO2_1


static int fpga_major = 0;
static struct cdev fpgaDevice;
static struct class *fpga_class;
MODULE_AUTHOR("hunwo");
MODULE_DESCRIPTION("Device Driver for MPC8377 FPGA_GPIO.");
MODULE_LICENSE("Dual BSD/GPL");

void  relase_source(void);
#if 0
void delay(int time)
{
while(time)
{
   time--;
}
}
#endif




#define SICRL           0x114  //system I/O configuretion register low
#define GPDIR          0xd00    //direction register
#define GPODR        0xd04    //open drain register
#define GPDAT         0xd08    //data register

       
unsigned int  GetIMMRBaseAddr(void);//用于获取IMMR基地址,并映射为相应的虚拟地址
void init_GPIO(void)
{
        volatile unsigned long gpio2_crl, gpio2_dir;
        u32 a1, b1;
        //system I/O register set
        volatile unsigned int  *p = (volatile unsigned int*)(GetIMMRBaseAddr()+SICRL);
        volatile unsigned int  *gpio_reg = (volatile unsigned int* )(GetIMMRBaseAddr()+GPDIR);
        volatile unsigned int  *a = (volatile unsigned int* )(GetIMMRBaseAddr()+GPODR);
        volatile unsigned int  *b = (volatile unsigned int* )(GetIMMRBaseAddr()+GPDAT);

        gpio2_crl = *p;
        /*Set SICRL to enable GIPO */
        printk("SICRL is  %08X\n", *p);
        gpio2_crl=0x000000;
        *p=gpio2_crl;
        printk("SICRL is set to %08X\n", *p);


        //GPIO register set
        //GPIO direction register
        gpio2_dir = *gpio_reg;
        printk("GPDIR is %08X\n",gpio2_dir);
        gpio2_dir=0x98000000;
        *gpio_reg=gpio2_dir;
        printk("GPDIR is set to %08X \n",*gpio_reg);



        //GPIO open drain register
        a1 = *a;
        printk("GPODR is %08X \n",a1);
        a1 = 0x00000000;
        *a=a1;
        printk("GPODR is set to %08X \n",*a);




        //GPIO data register
        b1 = *b;
        printk("GPDAT is %08X\n",b1);
        b1 = ~0;
        *b = b1;
        printk("GPDAT is get to %08x \n",*b);
        return 0;

}



//read the data register
unsigned  int   read_data()
{
        volatile unsigned int *b = (volatile unsigned int *)(GetIMMRBaseAddr()+GPDAT);       
        volatile unsigned int  gpiodata=*b;

        return gpiodata;
}

//write the data register
void   write_data(unsigned int  data)
{
        volatile unsigned int  *b = (volatile  unsigned int *)(GetIMMRBaseAddr()+GPDAT);
        *b=data;
}
/*
   write bit to CCLK.
FPGA_config_reg:FPGA config register addr.
data: if data equal 0,bit 0 will be wrote,else bit 1 will be wrote;
*/
void wt_cclk(unsigned char data)
{


        volatile unsigned int  data_in;
        data_in = read_data();


        if(data)
        {
                data_in |=1<<CPLD_CCLK;

        }
        else
        {
                data_in &=~(1<<CPLD_CCLK);

        }
        write_data( data_in);

}

/*
   write bit to DIN.
FPGA_config_reg:FPGA config register addr.
data: if data equal 0, bit 0 will be wrote ,else  bit 1 will be wrote;
*/



void wt_din(unsigned char data)
{
        volatile unsigned   int  data_in;

        data_in =read_data();
        if(data)
        {
                data_in |=1<<CPLD_DIN;

        }
        else
        {
                data_in &=~(1<<CPLD_DIN);

        }
        write_data(data_in);
}


/*
   write bit to PROG.
FPGA_config_reg:FPGA config register addr.
data: if data equal 0, bit 0 will be wrote, else bit 1 will be wrote;
*/

void wt_prog(unsigned char data)
{
        volatile unsigned  int  data_in;

        data_in =read_data();
        if(data)
        {
                data_in |=1<<CPLD_PROG;

        }
        else
        {
                data_in &=~(1<<CPLD_PROG);

        }
        write_data(data_in);


}



/*
   read DONE bit
FPGA_config_reg:FPGA config register.
*/

unsigned char rd_done()
{
        volatile unsigned  int   data=read_data();
        if(data & (1<<CPLD_DONE) )
        {
                return 1;       
        }
        else
        {
                return 0;
        }
}

/*
   read  INIT bit
FPGA_config_reg:FPGA config register.
*/
unsigned char rd_init()
{
   volatile unsigned   int  data=read_data();

        if(data & (1<<CPLD_INIT) )
        {
                return 1;       
        }
        else
        {
                return 0;
        }
}





//void CMD_InitSlaveFPGA()
unsigned char  init_prog()
{

        printk("data---<0x%X\n",read_data());
        wt_prog(0);
        wt_cclk(0);
        udelay(100);

        printk("int %d\n",rd_init());       
        printk("data---<0x%X\n",read_data());
        if(!rd_init())                       
                printk("OK\n");
        else  return 1;
        wt_prog(1);
        udelay(100);
        return 0;//data;
}



int  slaveGPIO_output(unsigned char data)
{

        int i;
        for(i=0;i<8;i++)
        {
                if(data & 0x1)
                {

                        wt_din(1);       
                }
                else
                {
                        wt_din(0);       
                }
                data>>=1;
                wt_cclk(1);
                if(!rd_init())
                                printk("error!\n");

                wt_cclk(0);
               


        }
        return 1;

}

void check_done_bit(void)
{
        //unsigned char data;
        unsigned int  i;
        printk("The  data  is  send  finish !\n");

       
        for(i=0; i<3180; i++)
                {
                wt_cclk(1);
                wt_cclk(0);
                }
                printk("done :%d\n",rd_done());
        if (rd_done() == 1){                     //If DONE Pin is High, display message
                        printk("proger  is  start!!!\n");
        }
        else
        {
                printk("error load to FPGA\n");       
        }



}

void  relase_source(){

}
int mpc8377_FPGA_GPIO_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
        FPGA_slaveGPIO_BUF *p=(FPGA_slaveGPIO_BUF *)(arg);

        switch(cmd){
                case CMD_init_prog:
                        if(init_prog()){
                                printk("init_prog fail\n");
                                //释放资源
                                relase_source();
                                break;
                        }
                        printk("init_proge sucess!\n");
                        break;
                case CMD_SlaveGPIOOutput:
                        slaveGPIO_output(p->data);

                        break;

                case CMD_CheckDoneBit:
                        check_done_bit();
                        break;       
                case CMD_SlaveGPIOInitReset:
                        init_prog();  
                        break;
                default:
                        printk("wrong cmd in FPGA_GPIO ioctl\n ");
        }
        return 0;
}


/**********************************************************/
int mpc8377_FPGA_GPIO_open(struct inode *inode, struct file *file)
{

        return 0;
}

/**********************************************************/
static int mpc8377_FPGA_GPIO_close(struct inode *inode, struct file *file)
{
        return 0;
}

/**********************************************************/
static struct file_operations mpc8377_FPGA_GPIO_fops = {
owner:                THIS_MODULE,
ioctl:                mpc8377_FPGA_GPIO_ioctl,
open:                mpc8377_FPGA_GPIO_open,
release:        mpc8377_FPGA_GPIO_close,
};

/**********************************************************/



// Install the MPC8377core LED driver
static int __init mpc8377_FPGA_GPIO_init(void)
{
        int result;
        int err;
        dev_t dev = MKDEV(fpga_major, 0);
        //cpld_test();
        if (fpga_major)
                result = register_chrdev_region(dev, 1, DEVICE_NAME);
        else {
                result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
                fpga_major = MAJOR(dev);
        }
        if (result < 0)
        {
                printk("unable to get major %d\n", fpga_major);
                return result;
        }
        printk("get major is %d\n", fpga_major);
        if (fpga_major == 0)
                fpga_major = result;

        cdev_init(&fpgaDevice, &mpc8377_FPGA_GPIO_fops);
        fpgaDevice.owner = THIS_MODULE;
        fpgaDevice.ops = &mpc8377_FPGA_GPIO_fops;
        err = cdev_add(&fpgaDevice, dev, 1);
        if (err)
                printk("error %d add fpga ", err);

        fpga_class = class_create(THIS_MODULE, DEVICE_NAME);
        if (IS_ERR(fpga_class))
        {
                printk("Err:failed in creating class.\n");
                return -1;
        }
        class_device_create(fpga_class, NULL, MKDEV(fpga_major, 0), NULL, "%s", DEVICE_NAME);
        //        device_create(fpga_class, NULL, MKDEV(fpga_major,0), NULL,"%s%d", DEVICE_NAME,0);
        printk("MPC8377core FPGA_GPIO_driver installed OK\n");



        init_GPIO();
        return 0;
}

/**********************************************************/
// Remove the MPC8377core LED driver
static void mpc8377_FPGA_GPIO_exit(void)
{
        //        device_destroy(fpga_class, MKDEV(fpga_major, 0));
        cdev_del(&fpgaDevice);
        class_device_destroy(fpga_class, MKDEV(fpga_major, 0));
        class_destroy(fpga_class);
        unregister_chrdev_region(MKDEV(fpga_major, 0), 2);

        relase_source();
        printk ("MPC8377core FPGA_GPIO driver uninstalled OK\n");
}

/**********************************************************/
module_init(mpc8377_FPGA_GPIO_init);

module_exit(mpc8377_FPGA_GPIO_exit);


应用程序

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "FPGA_SlaveGPIO.h"

#define DEVICE_PPCLED        "/dev/fpga_gpio"

#define CMD_init_prog       15
#define CMD_SlaveGPIOOutput     16
#define CMD_CheckDoneBit        17
#define CMD_SlaveGPIOInitReset   18


typedef struct _FPGA_slectMap_BUF_
{
int number;
unsigned char data;
}FPGA_slaveGPIO_BUF;

int main(int argc , char **argv)
{
  
        char *filename="/mnt/fpga_test.bin";

        if(argc>1)
                filename = argv[1];

        printf("Now Start Download FPGA File %s\n",filename);
        FPGA_SlaveGPIODownload(filename);

        return 0;
}

int FPGA_SlaveGPIODownload(char *filename)
{
         
        int fp;
        FPGA_slaveGPIO_BUF arg;
        FILE *filep;
           arg.number=0;
        unsigned long size=0;

        if((fp=open(DEVICE_PPCLED,O_RDWR))<0)
        {
                perror("can not open device");
                exit(1);
        }

        filep=fopen(filename,"rb");
        if(filep==NULL)
        {
               printf("can not open file %s\n",filename);
               exit(1);       
        }
        ioctl(fp,CMD_init_prog,&arg);//init FPGA,
        while(!feof(filep))
        {
                fread(&(arg.data),sizeof(unsigned char),1,filep);
                  size++;
                  ioctl(fp,CMD_SlaveGPIOOutput,&arg); //output data to FPGA
        }

        ioctl(fp,CMD_CheckDoneBit,&arg);//check FPGA DONE BIT

        fclose(filep);//close file

        close(fp);
        return 0;
}

这有一个用CPU配置Altera公司的FPGA的参考文档, 用CPU配置Altera公司的FPGA.zip (177.92 KB, 下载次数: 64)

论坛徽章:
0
2 [报告]
发表于 2011-09-19 19:28 |只看该作者
没人回呀???

论坛徽章:
0
3 [报告]
发表于 2011-09-20 13:23 |只看该作者
搞定了。原来是硬件的问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP