linux 用户空间gpio加载FPGA

来源:互联网 发布:网络的特点是什么 编辑:程序博客网 时间:2024/05/17 21:58

实际项目中的代码,加载速度有点慢,但功能实现。

fpga.c



#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <getopt.h>


#include "fpga.h"
#include "gpio.h"




static const char *nCONFIG= "/sys/class/gpio/gpio494/value";
static const char *nSTATUS= "/sys/class/gpio/gpio495/value";
static const char *DATA = "/sys/class/gpio/gpio490/value";
static const char *CLK = "/sys/class/gpio/gpio486/value";
static const char *CONF_DONE= "/sys/class/gpio/gpio487/value";
static const char *FPGA_DAT= "/ffs/fpga.rbf";




uint8_t nconfig_fd,nstatus_fd,data_fd,clk_fd,conf_done_fd,fpga_dat_fd;
//int fpga_fd;


static void fpgadelay(UINT32 ms)
{
//usleep(ms);
while(ms--);// 3条指令
}


UINT StartConfig(void) //BOOL StartConfig(void)
{
int ret;
UINT DELAYDO;
volatile unsigned long ulLoop;
volatile UCHAR val;

/*nConfig(PE10) = 0*/
//CLR_BIT(GPIOE_PDOR,nCONFIG_MASK);
lseek(nconfig_fd, 0, SEEK_SET);
gpio_write_b(nconfig_fd, 0);


#if 0
for(ulLoop = 0; ulLoop < (490000*2); ulLoop++)
{
}
#endif
usleep(2000);
DELAYDO = 65000;


/*等待nSTATUS(PE6) = 0  --input*/
/* while((nSTATUS) && (CONF_DONE) && ( --DELAYDO>0 )); */
lseek(nstatus_fd, 0, SEEK_SET);
val = gpio_read_b(nstatus_fd);
while( !((val == 0) && ( DELAYDO>0 )) )
{
lseek(nstatus_fd, 0, SEEK_SET);
val = gpio_read_b(nstatus_fd);
DELAYDO--;

}
// printf("val2:%d;\n",val);



/* 超时,串口打印提示信息*/
if(DELAYDO == 0)
{
printf("DELAYDO timeout!!! \n");
return FALSE;
}


/*nConfig = 1*/
//SET_BIT(GPIOE_PDOR,nCONFIG_MASK);
lseek(nconfig_fd, 0, SEEK_SET);
gpio_write_b(nconfig_fd, 1);
#if 0
for(ulLoop = 0; ulLoop < (490000*2); ulLoop++)
{
}
#endif
usleep(2000);
DELAYDO = 165000;

/*等待nSTATUS = 1*/
lseek(nstatus_fd, 0, SEEK_SET);
val = gpio_read_b(nstatus_fd);

// printf("val5:%d;\n",val);



while( (!val )  ) 
{
lseek(nstatus_fd, 0, SEEK_SET);
val = gpio_read_b(nstatus_fd);
}

/*while((nSTATUS == 1;)  && ( --DELAYDO>0 )); */
/*超时,串口打印提示信息*/
if(DELAYDO == 0)
{
return FALSE;
}

return TRUE;
}




/*-------------------download from code--------------------*/
UINT DownloadFromCode(WORD Length,UCHAR *Address)
{
WORD i;
UCHAR TMP,val;
UCHAR DATA_SEND;
UCHAR j;

for(i=0;i<Length;i++)
{
TMP = Address[i];

for(j=0;j<8;j++)
{
/*DCLK_FPGA = 0;*/
//CLR_BIT(GPIOE_PDOR,DCLK_MASK);
lseek(clk_fd, 0, SEEK_SET);
gpio_write_b(clk_fd, 0);
// fpgadelay(2);


//DATA_SEND = TMP>>j;
DATA_SEND = TMP>>j;

if((DATA_SEND & 0x01))
{
//SET_BIT(GPIOE_PDOR,DATA_MASK);
lseek(data_fd, 0, SEEK_SET);
gpio_write_b(data_fd, 1);
}
else
{
//CLR_BIT(GPIOE_PDOR,DATA_MASK);
lseek(data_fd, 0, SEEK_SET);
gpio_write_b(data_fd, 0);
}
// fpgadelay(2);


/*DCLK_FPGA =1;*/
//SET_BIT(GPIOE_PDOR,DCLK_MASK);
lseek(clk_fd, 0, SEEK_SET);
gpio_write_b(clk_fd, 1);
// fpgadelay(2);
}


lseek(nstatus_fd, 0, SEEK_SET);
val = gpio_read_b(nstatus_fd);


if(!val)
{
return FALSE;
}
}

//CLI_PRINT("\r\n i = %d",i,0,0,0,0,0);
//CLI_PRINT("\r\nDownloadFromCode!\r\n",0,0,0,0,0,0);

return TRUE;
}


void ConfigCpldFromCode(void)
{
UCHAR   p[1024];
ULONG   j;
UINT32 size;
UINT32 len ;
int i = 0;



size = lseek(fpga_dat_fd, 0, SEEK_END);

printf("size=%d \n",size);

lseek(fpga_dat_fd, 0, SEEK_SET);
for(j = 0; j<=size; j+=1024)
{

if(j%(1024*4)==0)
{
printf(".");
}


if((j+1024) > size)
{
len = (size-j);
}
else
{
len = 1024;
}


// lseek(fpga_fd, 1024*i, SEEK_SET);
/*以page大小为读的单位*/
read(fpga_dat_fd, p, len);
i++;
// printf("%d.",i);
if(!DownloadFromCode(len,p))
{
break;
}
}



}




/*配置时间过长:超时  认为硬件自检错误 hardWareErr =1;配置起始地址*/
UINT ConfigCpld(void)
{
int ret;
UINT8 Try_configcpld;
char val;
volatile UINT8 num;



Try_configcpld = 0;
printf("ConfigCpld!\r\n");
lseek(nconfig_fd, 0, SEEK_SET);
val = gpio_read_b(nconfig_fd);


// printf("val1:%d;\n",val);

// while( Try_configcpld<2)
{
if(!StartConfig())
{
printf("\n StartConfig error!\n");
return FALSE;
}

lseek(nstatus_fd, 0, SEEK_SET);
val = gpio_read_b(nstatus_fd);

// printf("val6:%d \n",val);
if(!val )
{
printf("\n After Initialization,But the PIN nSTATUS from '1' to '0' !!\n");
}

ConfigCpldFromCode();

printf("\n Config cpld from code OK! \n");


lseek(nstatus_fd, 0, SEEK_SET);
val = gpio_read_b(nstatus_fd);
// printf("val7:%d \n",val);
if(!val)
{
printf("\n After Initialization,But the PIN nSTATUS from '1' to '0' !!\n");
}

Try_configcpld ++;
fpgadelay(10);
}


lseek(conf_done_fd, 0, SEEK_SET);
val = gpio_read_b(conf_done_fd);
// printf("val8:%d \n",val);
if(!val)
{
printf("\n After Configuration,But the PIN CONF_DONE CAN NOT be '1' !!\n");
return FALSE;
}

return TRUE;
}


void InitFpga(void)
{
/* ******************************************************   
nSTATUS=GPIO_15;--input
CONF_DONE=GPIO_07;--input

nCONFIG=GPIO_14;--output//
DCLK = GPIO_06;      --output
DATA = GPIO_10;--output


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

if(!ConfigCpld())
{
printf("Can NOT Initialize FPGA!\n");
return;
}
else
{
printf("Done \r\nConfigure FPGA Successfully !!!\n");
}



}
#if 0
int main(int argc, char *argv[])
{
fpga_fd = open("/ffs/fpga.rbf", O_RDONLY);
if (fpga_fd < 0) 

MSG("Failed to open fpga.rbf!\n"); 
return -1; 



fpga_gpio_init();
InitFpga();


close(fpga_fd);

}
#endif


int main(int argc, char *argv[])
{
int ret;


fpga_gpio_init();

/* open gpio nconfig file*/
nconfig_fd = open(nCONFIG, O_RDWR);
if (nconfig_fd < 0)
{
printf("can't open nconfig \n");
return;
}

/* open gpio nstatus file*/
nstatus_fd = open(nSTATUS, O_RDWR);
if (nstatus_fd < 0)
{
printf("can't open nstatus \n");
return;
}


/* open fpga.dat file*/
fpga_dat_fd = open(FPGA_DAT, O_RDWR);
if (fpga_dat_fd < 0)
{
printf("can't open fpga.dat \n");
return;
}


/* open gpio clk file*/
clk_fd = open(CLK, O_RDWR);
if (clk_fd < 0)
{
printf("can't open clk \n");
return;
}


/* open gpio data file*/
data_fd = open(DATA, O_RDWR);
if (data_fd < 0)
{
printf("can't open data \n");
return;
}


conf_done_fd = open(CONF_DONE, O_RDWR);
if (data_fd < 0)
{
printf("can't open conf_done \n");
return;
}

InitFpga();


close(nconfig_fd);
close(nstatus_fd);
close(fpga_dat_fd);
close(clk_fd);
close(data_fd);
close(conf_done_fd);


return ret;

}

gpio.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h> 
#include <poll.h>
#include "gpio.h"


int gpio_export(int pin) 

char buffer[64]; 
int len; 
int fd; 


fd = open("/sys/class/gpio/export", O_WRONLY); 

if (fd < 0) 

MSG("Failed to open export for writing!\n"); 
return(-1); 



len = snprintf(buffer, sizeof(buffer), "%d", pin); 
if (write(fd, buffer, len) < 0) 

MSG("Failed to export gpio!\n"); 
return -1; 



close(fd); 
return 0; 
}


int gpio_unexp(int pin) 

char buffer[64]; 
int len; 
int fd; 


fd = open("/sys/class/gpio/unexport", O_WRONLY); 
if (fd < 0) 

MSG("Failed to open unexport for writing!\n"); 
return -1; 



len = snprintf(buffer, sizeof(buffer), "%d", pin); 
if (write(fd, buffer, len) < 0) 

MSG("Failed to unexport gpio!"); 
return -1; 



close(fd); 
return 0; 
}


//dir: 0-->IN, 1-->OUT
int gpio_direction(int pin, int dir) 

static const char dir_str[] = "in,out"; 
char path[64]; 
int fd; 


snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin); 
fd = open(path, O_WRONLY); 

if (fd < 0) 

MSG("Failed to open gpio direction for writing!\n"); 
return -1; 

if (write(fd, &dir_str[dir == 0 ? 0 : 3], dir == 0 ? 2 : 3) < 0) 

MSG("Failed to set direction!\n"); 
return -1; 



close(fd); 
return 0; 
}


//value: 0-->LOW, 1-->HIGH
int gpio_write(int pin, int value) 

static const char values_str[] = "01"; 
char path[64]; 
int fd; 


snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); 
fd = open(path, O_WRONLY); 
if (fd < 0) 

MSG("Failed to open gpio value for writing!\n"); 
return -1; 



if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0) 

MSG("Failed to write value!\n"); 
return -1; 



close(fd); 
return 0; 
}
int gpio_write_b(int fd, int value) 

static const char values_str[] = "01"; 
char path[64]; 

if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0) 

MSG("Failed to write value!\n"); 
return -1; 



return 0; 
}


int gpio_read(int pin) 

char path[64]; 
char value_str[3]; 
int fd; 
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin); 
fd = open(path, O_RDONLY); 

if (fd < 0) 

MSG("Failed to open gpio value for reading!\n"); 
return -1; 



if (read(fd, value_str, 3) < 0) 

MSG("Failed to read value!\n"); 
return -1; 



close(fd); 
return (atoi(value_str));
}


int gpio_read_b(int fd) 

char path[64]; 
char value_str[1]; 

if (read(fd, value_str, 1) < 0) 

MSG("Failed to read value!\n"); 
return -1; 


return (atoi(value_str));
}
// none -->the pin is input, no interrupt
// rising -->the pin is interrupt input, the rising edge is triggered 
// falling -->the pin is interrupt input, the falling edge is triggered 
// both   -->the pin is interrupt input, the edge is triggered (边沿触发)
// 0-->none, 1-->rising, 2-->falling, 3-->both
int gpio_edge(int pin, int edge)
{
const char dir_str[] = "none\rising\falling\both"; 
char ptr;
char path[64]; 
int fd; 

switch(edge)
{
case 0:
ptr = 0;
break;

case 1:
ptr = 5;
break;

case 2:
ptr = 12;
break;

case 3:
ptr = 20;
break;

default:
ptr = 0;



snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", pin); 
fd = open(path, O_WRONLY); 

if (fd < 0) 

MSG("Failed to open gpio edge for writing!\n"); 
return -1; 

if (write(fd, &dir_str[ptr], strlen(&dir_str[ptr])) < 0) 

MSG("Failed to set edge!\n"); 
return -1; 



close(fd); 
return 0; 
}
void fpga_gpio_init()
{
/* fpga gpio init

gpio_06: clk
gpio_14: nconfig     --output
gpio_10: data

gpio_15: nstatus
gpio_07: conf_done   ---input


base add = 480


*/
gpio_export(486);
gpio_export(487);
gpio_export(490);
gpio_export(494);
gpio_export(495);

gpio_direction(486, 1);
gpio_direction(490, 1);
gpio_direction(494, 1);
gpio_direction(495, 0);
gpio_direction(487, 0);
}


#if 0
int main() 

int gpio_fd, ret;
struct pollfd fds[1];
char buff[10];
unsigned char cnt = 0;


//鎸夐敭寮曡剼鍒濆鍖?
gpio_export(49);
gpio_direction(49, 0);
gpio_edge(49,1);

gpio_fd = open("/sys/class/gpio/gpio49/value",O_RDONLY);
if(gpio_fd < 0)
{
MSG("Failed to open value!\n"); 
return -1; 
}

fds[0].fd = gpio_fd;
fds[0].events = POLLPRI;

ret = read(gpio_fd,buff,10);
if( ret == -1 )
{
MSG("read\n");
}

while(1)
{
ret = poll(fds,1,0);
if( ret == -1 )
MSG("poll\n");

if( fds[0].revents & POLLPRI)
{
ret = lseek(gpio_fd,0,SEEK_SET);
if( ret == -1 )
{
MSG("lseek\n");
}

ret = read(gpio_fd,buff,10);
if( ret == -1 )
{
MSG("read\n");
}

gpio_write(115, cnt++%2);
}

usleep(100000);
}

return 0;
}
#endif




0 0
原创粉丝点击