您的位置:首页 > 运维架构 > Linux

linux 用户空间gpio加载FPGA

2017-03-21 15:58 281 查看
实际项目中的代码,加载速度有点慢,但功能实现。

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息