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
- linux 用户空间gpio加载FPGA
- Linux GPIO用户空间操作
- [Linux应用]通过sysfs在用户空间使用GPIO
- [Linux应用]通过sysfs在用户空间使用GPIO
- [Linux驱动炼成记]02-用户空间控制GPIO
- android 用户空间控制gpio
- 用户空间GPIO的调用
- 通过sysfs在用户空间使用GPIO
- 通过sysfs在用户空间使用GPIO
- linux平台上GPIO模拟I2C && 安卓平台用户空间I2C读写工具
- Linux内核驱动基础(8)gpio用户空间另一使用案例
- 把GPIO 通过sysfs导出到 用户空间
- GPIO在用户空间(Sysfs)中的检测与控制
- linux的用户层GPIO接口管理
- linux内核:用户空间和系统空间
- linux内核空间和用户空间详解
- Linux内核空间和用户空间
- linux 内核空间和用户空间
- 关于SystemUI状态栏显示黄色背景的问题
- RabbitMQ集群笔记
- iOS 自带三种提示框使用、UIAlertView以及UIAlertController的使用
- jmeter: JDBC Request (查询数据库获取数据库数据) 的使用
- Eclipse 解决启动慢
- linux 用户空间gpio加载FPGA
- trainCascadeObjectDetector
- Leetcode 227. Basic Calculator II
- HDMI转EDP芯片目前市面上兼容最好的桥接芯片NCS8803支持HDMI转EDP
- Android权限
- Qt5 实现文件复制并在指定路径下创建文件夹
- 使用jquery对输入框内容设置自动校验,只允许数字的输入
- hdu1495 非常可乐 bfs基础
- AS的gradle报错的解决方法