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

📄 fpga.c

📁 U-Boot1.1.2是最为常用的嵌入式系统Bootloader
💻 C
字号:
/* * (C) Copyright 2001 * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com *  and * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include <config.h>#include <common.h>#include "w7o.h"#include <asm/processor.h>#include "errors.h"static voidfpga_img_write(unsigned long *src, unsigned long len, unsigned short *daddr){    unsigned long i;    volatile unsigned long val;    volatile unsigned short *dest = daddr;	/* volatile-bypass optimizer */    for (i = 0; i < len; i++, src++) {	val = *src;	*dest = (unsigned short)((val & 0xff000000L) >> 16);	*dest = (unsigned short)((val & 0x00ff0000L) >> 8);	*dest = (unsigned short)(val & 0x0000ff00L);	*dest = (unsigned short)((val & 0x000000ffL) << 8);    }    /* Terminate programming with 4 C clocks */    dest = daddr;    val = *(unsigned short *)dest;    val = *(unsigned short *)dest;    val = *(unsigned short *)dest;    val = *(unsigned short *)dest;}intfpgaDownload(unsigned char *saddr,	     unsigned long size,	     unsigned short *daddr){    int i;					/* index, intr disable flag */    int start;					/* timer */    unsigned long greg, grego;			/* GPIO & output register */    unsigned long length;			/* image size in words */    unsigned long *source;			/* image source addr */    unsigned short *dest;			/* destination FPGA addr */    volatile unsigned short *ndest;		/* temp dest FPGA addr */    volatile unsigned short val;		/* temp val */    unsigned long cnfg = GPIO_XCV_CNFG;		/* FPGA CNFG */    unsigned long eirq = GPIO_XCV_IRQ;    int retval = -1;				/* Function return value */    /* Setup some basic values */    length = (size / 4) + 1;			/* size in words, rounding UP						    is OK */    source = (unsigned long *)saddr;    dest = (unsigned short *)daddr;    /* Get DCR output register */    grego = in32(IBM405GP_GPIO0_OR);    /* Reset FPGA */    grego &= ~GPIO_XCV_PROG;			/* PROG line low */    out32(IBM405GP_GPIO0_OR, grego);    /* Setup timeout timer */    start = get_timer(0);    /* Wait for FPGA init line */    while(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT) { /* Wait INIT line low */	/* Check for timeout - 100us max, so use 3ms */	if (get_timer(start) > 3) {	    printf("     failed to start init.\n");	    log_warn(ERR_XINIT0);		/* Don't halt */	    /* Reset line stays low */	    goto done;				/* I like gotos... */	}    }    /* Unreset FPGA */    grego |= GPIO_XCV_PROG;			/* PROG line high */    out32(IBM405GP_GPIO0_OR, grego);    /* Wait for FPGA end of init period .  */    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_INIT)) { /* Wait for INIT hi */	/* Check for timeout */	if (get_timer(start) > 3) {	    printf("     failed to exit init.\n");	    log_warn(ERR_XINIT1);	    /* Reset FPGA */	    grego &= ~GPIO_XCV_PROG;		/* PROG line low */	    out32(IBM405GP_GPIO0_OR, grego);	    goto done;	}    }    /* Now program FPGA ... */    ndest = dest;    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {	/* Toggle IRQ/GPIO */	greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */	greg |= eirq;				/* toggle irq/gpio */	mtdcr(CPC0_CR0, greg);			/*  ... just do it */	/* turn on open drain for CNFG */	greg = in32(IBM405GP_GPIO0_ODR);	/* get open drain register */	greg |= cnfg;				/* CNFG open drain */	out32(IBM405GP_GPIO0_ODR, greg);	/*  .. just do it */	/* Turn output enable on for CNFG */	greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */	greg |= cnfg;				/* CNFG tristate inactive */	out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */	/* Setup FPGA for programming */	grego &= ~cnfg;				/* CONFIG line low */	out32(IBM405GP_GPIO0_OR, grego);	/*	 * Program the FPGA	 */	printf("\n       destination: 0x%lx ", (unsigned long)ndest);	fpga_img_write(source,  length,  (unsigned short *)ndest);	/* Done programming */	grego |= cnfg;				/* CONFIG line high */	out32(IBM405GP_GPIO0_OR, grego);	/* Turn output enable OFF for CNFG */	greg = in32(IBM405GP_GPIO0_TCR);	/* get tristate register */	greg &= ~cnfg;				/* CNFG tristate inactive */	out32(IBM405GP_GPIO0_TCR, greg);	/*  ... just do it */	/* Toggle IRQ/GPIO */	greg = mfdcr(CPC0_CR0);			/* get chip ctrl register */	greg &= ~eirq;				/* toggle irq/gpio */	mtdcr(CPC0_CR0, greg);			/*  ... just do it */	ndest = (unsigned short *)((char *)ndest + 0x00100000L); /* XXX - Next FPGA addr */	cnfg >>= 1;				/* XXX - Next  */	eirq >>= 1;    }    /* Terminate programming with 4 C clocks */    ndest = dest;    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {	val = *ndest;	val = *ndest;	val = *ndest;	val = *ndest;	ndest = (unsigned short *)((char *)ndest + 0x00100000L);    }    /* Setup timer */    start = get_timer(0);    /* Wait for FPGA end of programming period .  */    while(!(in32(IBM405GP_GPIO0_IR) & GPIO_XCV_DONE)) { /* Test DONE low */	/* Check for timeout */	if (get_timer(start) > 3) {	    printf("     done failed to come high.\n");	    log_warn(ERR_XDONE1);	    /* Reset FPGA */	    grego &= ~GPIO_XCV_PROG;		/* PROG line low */	    out32(IBM405GP_GPIO0_OR, grego);	    goto done;	}    }    printf("\n       FPGA load succeeded\n");    retval = 0;					/* Program OK */done:    return retval;}/* FPGA image is stored in flash */extern flash_info_t    flash_info[];int init_fpga(void){    unsigned int i,j,ptr;			/* General purpose */    unsigned char bufchar;			/* General purpose character */    unsigned char *buf;				/* Start of image pointer */    unsigned long len;				/* Length of image */    unsigned char *fn_buf;			/* Start of filename string */    unsigned int fn_len;			/* Length of filename string */    unsigned char *xcv_buf;			/* Pointer to start of image */    unsigned long xcv_len;			/* Length of image */    unsigned long crc;				/* 30bit crc in image */    unsigned long calc_crc;			/* Calc'd 30bit crc */    int retval = -1;    /* Tell the world what we are doing */    printf("FPGA:  ");    /*     * Get address of first sector where the FPGA     * image is stored.     */    buf = (unsigned char *)flash_info[1].start[0];    /*     * Get the stored image's CRC & length.     */    crc = *(unsigned long *)(buf+4);		/* CRC is first long word */    len = *(unsigned long *)(buf+8);		/* Image len is next long */    /* Pedantic */    if ((len < 0x133A4) || (len > 0x80000))	goto bad_image;    /*     * Get the file name pointer and length.     */    fn_len = (*(unsigned short *)(buf+12) & 0xff); /* filename length						      is next short */    fn_buf = buf + 14;    /*     * Get the FPGA image pointer and length length.     */    xcv_buf = fn_buf + fn_len;			/* pointer to fpga image */    xcv_len = len - 14 - fn_len;		/* fpga image length */    /* Check for uninitialized FLASH */    if ((strncmp(buf, "w7o", 3)!=0) || (len > 0x0007ffffL) || (len == 0))	goto bad_image;    /*     * Calculate and Check the image's CRC.     */    calc_crc = crc32(0, xcv_buf, xcv_len);    if (crc != calc_crc) {	printf("\nfailed - bad CRC\n");	goto done;    }    /* Output the file name */    printf("file name  : ");    for (i=0;i<fn_len;i++) {	bufchar = fn_buf[+i];	if (bufchar<' ' || bufchar>'~') bufchar = '.';	putc(bufchar);    }    /*     * find rest of display data     */    ptr = 15;					/* Offset to ncd filename						   length in fpga image */    j = xcv_buf[ptr];				/* Get len of ncd filename */    if (j > 32) goto bad_image;    ptr = ptr + j + 3;				/* skip ncd filename string +						   3 bytes more bytes */    /*     * output target device string     */    j = xcv_buf[ptr++] - 1;			/* len of targ str less term */    if (j > 32) goto bad_image;    printf("\n       target     : ");    for (i = 0; i < j; i++) {	bufchar = (xcv_buf[ptr++]);	if (bufchar<' ' || bufchar>'~') bufchar = '.';	putc(bufchar);    }    /*     * output compilation date string and time string     */    ptr += 3;					/* skip 2 bytes */    printf("\n       synth time : ");    j = (xcv_buf[ptr++] - 1);			/* len of date str less term */    if (j > 32) goto bad_image;    for (i = 0; i < j; i++) {	bufchar = (xcv_buf[ptr++]);	if (bufchar<' ' || bufchar>'~') bufchar = '.';	putc(bufchar);    }    ptr += 3;					/* Skip 2 bytes */    printf(" - ");    j = (xcv_buf[ptr++] - 1);			/* slen = targ dev str len */    if (j > 32) goto bad_image;    for (i = 0; i < j; i++) {	bufchar = (xcv_buf[ptr++]);	if (bufchar<' ' || bufchar>'~') bufchar = '.';	putc(bufchar);    }    /*     * output crc and length strings     */    printf("\n       len & crc  : 0x%lx  0x%lx", len, crc);    /*     * Program the FPGA.     */    retval = fpgaDownload((unsigned char*)xcv_buf, xcv_len,			  (unsigned short *)0xfd000000L);    return retval;bad_image:    printf("\n       BAD FPGA image format @ %lx\n", flash_info[1].start[0]);    log_warn(ERR_XIMAGE);done:    return retval;}void test_fpga(unsigned short *daddr){    int i;    volatile unsigned short *ndest = daddr;    for (i = 0; i < CONFIG_NUM_FPGAS; i++) {#if defined(CONFIG_W7OLMG)	ndest[0x7e] = 0x55aa;	if (ndest[0x7e] != 0x55aa)	    log_warn(ERR_XRW1 + i);	ndest[0x7e] = 0xaa55;	if (ndest[0x7e] != 0xaa55)	    log_warn(ERR_XRW1 + i);	ndest[0x7e] = 0xc318;	if (ndest[0x7e] != 0xc318)	    log_warn(ERR_XRW1 + i);#elif defined(CONFIG_W7OLMC)	ndest[0x800] = 0x55aa;	ndest[0x801] = 0xaa55;	ndest[0x802] = 0xc318;	ndest[0x4800] = 0x55aa;	ndest[0x4801] = 0xaa55;	ndest[0x4802] = 0xc318;	if ((ndest[0x800] != 0x55aa) ||	    (ndest[0x801] != 0xaa55) ||	    (ndest[0x802] != 0xc318))	    log_warn(ERR_XRW1 + (2 * i));       /* Auto gen error code */	if ((ndest[0x4800] != 0x55aa) ||	    (ndest[0x4801] != 0xaa55) ||	    (ndest[0x4802] != 0xc318))	    log_warn(ERR_XRW2 + (2 * i));       /* Auto gen error code */#else# error "Unknown W7O board configuration"#endif    }    printf("       FPGA ready\n");    return;}

⌨️ 快捷键说明

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