- 论坛徽章:
- 0
|
各位高手,帮我看看这个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)
|
|