⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fpga.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
字号:
/* * fpga.c * * Xilinx FPGA programming module. * This code uses GPIOs to program the Xilinx SpartanII family of FPGA * using the slave paraller mode to load the bit file. * It recognizes as input the .bit file generated by the VHDL compiler, * and expects an address of where the file is located in memory as argument. * * by Thomas E. Arvanitis (tharvan@inaccessnetworks.com) * by Dimitris Economou (decon@inaccessnetworks.com) */#include "config.h"#if INCLUDE_FPGA#include "SA-1100.h"#include "fpga.h"#include "genlib.h"#include "stddefs.h"#include "monapp.h"#include "tfs.h"#include "tfsprivate.h"void set_gpio_dirpin(int pin, int dir){    unsigned long reg_val;    reg_val = 0;    reg_val = rdreg(&GPDR);    switch(dir){    case 1:        reg_val |= (1<<pin);        break;    case 0:        reg_val &= ~(1<<pin);        break;    default:        ;    }    wrreg(&GPDR, reg_val);}void set_gpio_setpin(int pin){    GPSR |= (1<<pin);}void set_gpio_clspin(int pin){        GPCR |= (1<<pin);}unsigned long check_gpio_pin(int pin){    unsigned long reg_val, ret_val;    reg_val = 0;    reg_val = rdreg(&GPLR);    ret_val = reg_val & (1<<pin);    return ret_val;}void udelay(int us){    volatile int i;    int loops;    loops = us * LoopsPerSecond/1000000;        for (i=0; i<loops; i++);}/* * XILINX clean memory: * Initiate a memory clean configuration cycle */intfpga_mem_clean(void){   unsigned long reg_val;   reg_val = 0;   reg_val = rdreg(&GPDR);   set_gpio_dirpin(FPGA_PROG_PIN, OUTDIR);   set_gpio_dirpin(FPGA_INIT_PIN, INDIR);   set_gpio_clspin(FPGA_PROG_PIN);   udelay(WAIT_TIME);   set_gpio_setpin(FPGA_PROG_PIN);   D(if (!check_gpio_pin(FPGA_INIT_PIN))       printf("After PROGRAM goes HIGH INIT stays LOW for a while\n");)   /*    * Wait until the init goes down,    * means mem is clear.    */   while (!check_gpio_pin(FPGA_INIT_PIN));   return OK;}/* * XILINX programing mode: * Enter the fpga programming mode. * Download a byte sequence located at address_in. */int fpga_program(unsigned long *address_in){    register int i, j, k, cnt;    register unsigned char xbuf, tmp, rbyte;    register unsigned char *dst;    register unsigned long *buf;    register unsigned long ltmp;    int bitf_ok;        buf = address_in;    dst = (unsigned char *) FPGA_PROG_ADDR;    /*     * Search for the dummy byte in the bit file,     * and start from there on, to skip the embedded useless header     * of the bit file.     *     * We only search the first 512 bytes, else it is obvious     * it is not a bit file.     */    bitf_ok = 0;    cnt = 0;    while ((cnt < 4) && (buf < address_in+0x200)) {        for (j=0; j<4; j++) {            ltmp = *buf >> (j*8);            xbuf = (unsigned char) (ltmp & 0xff);            if (xbuf == XLNX_DBYTE) {                cnt++;                D(printf("Address of buf = 0x%08x\n", buf);)            } else                cnt = 0;            if (cnt == 4) {                bitf_ok = 1;                break;            }        }        buf++;    }    if (bitf_ok == 0)        return ERR_BITF;    buf--; /* go back one word */    j++;    /* buf has the address of current word and j points       first byte after the DUMMY WORD*/        for (k=0; k<4; k++) {/* Write the DUMMY WORD*/        *dst = XLNX_DBYTE;        D(printf("Downloaded word: 0x%x\n", XLNX_DBYTE);)    }        for (; j<4; j++) {        rbyte = 0;        ltmp = *buf >> (j*8);        xbuf = (unsigned char) (ltmp & 0xff);                    for (k=0; k<8; k++) {            tmp = xbuf >> k;            tmp &= 1;            rbyte |= tmp<<(7-k);        }        *dst = rbyte;        D(printf("Downloaded word: 0x%x\n", rbyte);)    }    buf++; /* Buf points to the next of DUMMY_WORD word */        for (i=0; i<FPGA_BYTE_LENGTH/4; i++) {        /* Reverse byte endianess */        for (j=0; j<4; j++) {            rbyte = 0;            ltmp = *buf >> (j*8);            xbuf = (unsigned char) (ltmp & 0xff);            for (k=0; k<8; k++) {                tmp = xbuf >> k;                tmp &= 1;                rbyte |= tmp<<(7-k);            }            *dst = rbyte;            D(if (i<5) {                printf("Downloaded word: 0x%x\n", rbyte);            })                    }        buf++;        udelay(WAIT_WRITE);    }    /* More accesses on FPGA_PROG_ADDR        in order to pass the startup phase */        for (i=0; i<10; i++) {        *dst = 0;    }        udelay(WAIT_TIME);    if (!check_gpio_pin(FPGA_INIT_PIN)){        printf("fpga error: INIT is LOW. It has to be HIGH\n");        return ERROR;    }    return OK;}char *XlnxHelp[] = {    "Xilinx Spartan-II programming",    "-[c] -[p:] -[f:]",    "",    "Options:",    "-c clear configuration memory",    "-p addr    program loading directly from addr",    "-f file    program reading from TFS file",    "",    "addr: source address in hex of Xilinx bit file.",    "file: filename of bit file in TFS.",    "",    "NOTE: In both programming modes -c is implicitly applied",    0};int Xlnx(int argc, char *argv[]){    unsigned long *address, *pr_addr;    char *filename;    int opt, addr_prog, file_prog, clear_mem;    int rval;    TFILE *fp;    if (argc < 2) {        printf("No arguments, exiting... use help\n");        return(0);    }    addr_prog = file_prog = clear_mem = 0;    while((opt=getopt(argc,argv,"cf:p:")) != -1) {        switch(opt) {            case 'c':                clear_mem = 1;                break;            case 'f':                filename = optarg;                file_prog = 1;                break;            case 'p':                address = (unsigned long *)(strtol(optarg, (char **)0, 16));                addr_prog = 1;                break;            default:                return(0);        }    }        printf("Cleaning FPGA memory... ");    if (fpga_mem_clean() < 0) {        printf("xlnx error: not cleaned\n");        return(0);    }    printf("OK\n");        if (addr_prog) {        pr_addr = address;    } else if (file_prog){        fp = tfsstat(filename);        if (fp == 0) {            printf("xlnx error: file %s not found!\n", filename);            return(0);        }        pr_addr = (unsigned long *)TFS_BASE(fp);    }    if (addr_prog || file_prog) {        printf("Programming FPGA memory... ");        if ((rval = fpga_program(pr_addr)) < 0) {            if (rval == ERR_BITF) {                printf("xlnx error: invalid bit file\n");            } else {                printf("xlnx error: failed\n");            }            return(0);        }        printf("OK\n");    }    return(0);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -