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

📄 bfload.c

📁 CNC 的开放码,EMC2 V2.2.8版
💻 C
📖 第 1 页 / 共 3 页
字号:
        printf("\n");        sleep(4);        config_file_name = argv[1];        card_number = 0;        if ( argc == 3 ) {            if (sscanf(argv[2], "%d", &card_number) != 1) {                errmsg(__func__,"bad card number: %s", argv[2]);                return -1;            }        }        if (card_number > 15) {            errmsg(__func__,"card number %d out of range (range is 0 to 15)", card_number);            return -1;        }        return 0;    } else if (errno != ENOENT) {        errmsg(__func__, "error stating '%s': %s\n", argv[1], strerror(errno));        return -1;    }    //    // if we get here it doesnt look like an old-style command-line    // (or the file was missing or misspelled)    //    r = parse_program_command(argv[1]);    if (r != 0) {        return -1;    }    return 0;}/* program FPGA on PCI board 'devnum', with data from bitfile chunk 'ch' */static int program_5i20_fpga(struct board_info *bd, struct bitfile_chunk *ch){    int ctrl_region, data_region, count;    __u32 status, control;    __u8 *dp;    printf("Opening PCI regions...\n");    /* open regions for access */    ctrl_region = upci_open_region(bd->io.pci.upci_devnum, 1);    if ( ctrl_region < 0 ) {	errmsg(__func__, "could not open device %d, region %d (5i20 control port)",	    bd->io.pci.upci_devnum, 1 );	goto cleanup0;    }    data_region = upci_open_region(bd->io.pci.upci_devnum, 2);    if ( data_region < 0 ) {	errmsg(__func__, "could not open device %d, region %d (5i20 data port)",	    bd->io.pci.upci_devnum, 2 );	goto cleanup1;    }    //    // fix up LASxBRD READY if needed    //    {        int offsets[] = { LAS0BRD_OFFSET, LAS1BRD_OFFSET, LAS2BRD_OFFSET, LAS3BRD_OFFSET };        int i;        printf("checking #READY in EEPROM:\n" );        for (i = 0; i < 4; i ++) {            __u32 val;            int offset = offsets[i];            val = upci_read_u32(ctrl_region, offset);            printf("    LAS%dBRD (0x%04x): 0x%08x", i, offset, val);            if (val & LASxBRD_READY) {                printf(" ok\n");            } else {                printf("    *** #READY is OFF, i'll fix it for you just this once but you should upgrade your ancient EEPROM\n");                val |= LASxBRD_READY;                upci_write_u32(ctrl_region, offset, val);            }        }    }    printf("Resetting FPGA...\n" );    /* read current state of register */    status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET);    /* set /PROGRAM bit low  to reset device */    control = status & ~_PROGRAM_MASK;    /* set /WRITE and /LED high, (idle state) */    control |= _WRITE_MASK | _LED_MASK;    /* and write it back */    upci_write_u32(ctrl_region, CTRL_STAT_OFFSET, control);    /* verify that /INIT and DONE went low */    status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET);    if ( status & (DONE_MASK | _INIT_MASK) ) {	errmsg(__func__, "FPGA did not reset: /INIT = %d, DONE = %d",	    (status & _INIT_MASK ? 1 : 0), (status & DONE_MASK ? 1 : 0) );	goto cleanup2;    }    /* set /PROGRAM high, let FPGA come out of reset */    control = status | _PROGRAM_MASK;    upci_write_u32(ctrl_region, CTRL_STAT_OFFSET, control);    /* wait for /INIT to go high when it finishes clearing memory	This should take no more than 100uS.  If we assume each PCI read	takes 30nS (one PCI clock), that is 3300 reads.  Reads actually	take several clocks, but even at a microsecond each, 3.3mS is not	an excessive timeout value */    count = 3300;    do {	status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET);	if ( status & _INIT_MASK ) break;    } while ( --count > 0 );    if ( count == 0 ) {	errmsg(__func__, "FPGA did not come out of /INIT" );	goto cleanup3;    }    /* set /WRITE low for data transfer, and turn on LED */    control = status & ~_WRITE_MASK & ~_LED_MASK;    upci_write_u32(ctrl_region, CTRL_STAT_OFFSET, control);    /* Program the card */    count = ch->len;    dp = ch->body;    printf("Writing data to FPGA....\n" );    while ( count-- > 0 ) {	upci_write_u8(data_region, 0, bit_reverse(*(dp++)));    }    /* all bytes transferred, clear "bytes to go" indicator */    printf("Data transfer complete...\n");    status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET);    if ( ! (status & _INIT_MASK) ) {	/* /INIT goes low on CRC error */	errmsg(__func__, "FPGA asserted /INIT: CRC error" );	goto cleanup3;    }    if ( ! (status & DONE_MASK) ) {	errmsg(__func__, "FPGA did not assert DONE" );	goto cleanup3;    }    /* turn off write enable and LED */    control = status | _WRITE_MASK | _LED_MASK;    upci_write_u32(ctrl_region, CTRL_STAT_OFFSET, control);    printf("Successfully programmed %u bytes\n", ch->len);    return 0;cleanup3:    /* set /PROGRAM low (reset device), /WRITE high and LED off */    status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET);    control = status & ~_PROGRAM_MASK;    control |= _WRITE_MASK | _LED_MASK;    upci_write_u32(ctrl_region, CTRL_STAT_OFFSET, control);cleanup2:    upci_close_region(data_region);cleanup1:    upci_close_region(ctrl_region);cleanup0:    return -1;}static int program_5i22_fpga(struct board_info *bd, struct bitfile_chunk *ch){    int ctrl_region, data_region, count;    __u32 status, control;    __u8 *dp;    printf("Opening PCI regions...\n");    /* open regions for access */    ctrl_region = upci_open_region(bd->io.pci.upci_devnum, 1);    if ( ctrl_region < 0 ) {		errmsg(__func__, "could not open device %d, region %d (5i22 control port)",		    bd->io.pci.upci_devnum, 1 );		goto cleanup22_0;    }    data_region = upci_open_region(bd->io.pci.upci_devnum, 2);    if ( data_region < 0 ) {		errmsg(__func__, "could not open device %d, region %d (5i22 data port)",		    bd->io.pci.upci_devnum, 2 );		goto cleanup22_1;    }    printf("Resetting FPGA...\n" );	/* Enable programming.	*/	printf("\nProgramming...\n") ;	/* set GPIO bits to GPIO function */	status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET_5I22);	control = status | (DONE_ENABLE_5I22 | _PROG_ENABLE_5I22);	upci_write_u32(ctrl_region, CTRL_STAT_OFFSET_5I22, control) ;	/* Turn off /PROGRAM bit and insure that DONE isn't asserted */	upci_write_u32(ctrl_region, CTRL_STAT_OFFSET_5I22, control & ~_PROGRAM_MASK_5I22) ;	status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET_5I22);	if ((status & DONE_MASK_5I22) == DONE_MASK_5I22) {		/* Note that if we see DONE at the start of programming, it's most likely due			 to an attempt to access the FPGA at the wrong I/O location.  */		errmsg(__func__, "<DONE> status bit indicates busy at start of programming.") ;		return EC_HDW;	}	/* turn on /PROGRAM output bit */	upci_write_u32(ctrl_region, CTRL_STAT_OFFSET_5I22, control | _PROGRAM_MASK_5I22) ;	/* Delay for at least 100 uS. to allow the FPGA to finish its reset		 sequencing.  3300 reads is at least 100 us, could be as long as a few ms	*/    for (count=0;count<3300;count++) {		status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET);    }	/* Program the card. */	count = ch->len;	dp = ch->body;	while (count-- > 0) {		upci_write_u8(data_region, 0, bit_reverse(*dp++));	};	/* Wait for completion of programming. */	for (count=0;count<DONE_WAIT_5I22;count++) {			status = upci_read_u32(ctrl_region, CTRL_STAT_OFFSET_5I22);			if ((status & DONE_MASK_5I22) == DONE_MASK_5I22)				break;		}	if (count >= DONE_WAIT_5I22) {		errmsg(__func__, "Error: Not <DONE>; programming not completed.") ;		return EC_HDW;	}	printf("\nSuccessfully programmed 5i22.");	return EC_OK;    upci_close_region(data_region);cleanup22_1:    upci_close_region(ctrl_region);cleanup22_0:    return -1;}// returns TRUE if the FPGA reset, FALSE on errorstatic int m7i43_cpld_reset(struct board_info *board) {    uint8_t byte;    // select the control register    epp_addr8(&board->io.epp, 1);    // bring the Spartan3's PROG_B line low for 1 us (the specs require 300-500 ns or longer)    epp_write(&board->io.epp, 0x00);    usleep(1);    // bring the Spartan3's PROG_B line high and wait for 2 ms before sending firmware (required by spec)    epp_write(&board->io.epp, 0x01);    usleep(2 * 1000);    // make sure the FPGA is not asserting its DONE bit    byte = epp_read(&board->io.epp);    if ((byte & 0x01) != 0) {        printf("error: DONE is not low after CPLD reset!\n");        return 0;    }    return 1;}// this function resets the FPGA *only* if it's currently configured with the HostMot2 firmwarestatic void m7i43_hm2_reset(struct board_info *board) {    epp_addr16(&board->io.epp, 0x7F7F);    epp_write(&board->io.epp, 0x5A);}// returns FPGA size in K-gatesstatic int m7i43_cpld_get_fpga_size(struct board_info *board) {    uint8_t byte;    //  select data register    epp_addr8(&board->io.epp, 0);    byte = epp_read(&board->io.epp);    if ((byte & 0x01) == 0x01) {        return 400;    } else {        return 200;    }}static int m7i43_cpld_send_firmware(struct board_info *board, struct bitfile_chunk *ch) {    int i;    uint8_t *dp;    // select the CPLD's data address    epp_addr8(&board->io.epp, 0);    dp = ch->body;    for (i = 0; i < ch->len; i ++) {        epp_write(&board->io.epp, bit_reverse(*dp));        dp ++;    }    // see if it worked    if (epp_check_for_timeout(&board->io.epp)) {        printf("EPP Timeout while sending firmware!\n");        return 0;    }    return 1;}static int program_7i43_fpga(struct board_info *board, struct bitfile_chunk *ch) {    int fpga_size;    // set up the parport for EPP    epp_init(&board->io.epp);    //     // reset the FPGA, then send appropriate firmware    //    m7i43_hm2_reset(board);    if (!m7i43_cpld_reset(board)) {        printf("error resetting FPGA, aborting load\n");        return -1;    }    fpga_size = m7i43_cpld_get_fpga_size(board);    if (        ((strcmp(board->chip_type, "3s400tq144") == 0) && (fpga_size == 400))        || ((strcmp(board->chip_type, "3s200tq144") == 0) && (fpga_size == 200))    ) {        if (!m7i43_cpld_send_firmware(board, ch)) {            printf("error sending FPGA firmware\n");            return -1;        }        return 0;    } else {        printf("FPGA part mismatch\n");        printf("The selected board reports fpga chip size %d K gates\n", fpga_size);        printf("The requested firmware is for the other 7i43 FPGA\n");        return -1;    }}/* the fpga was originally designed to be programmed serially... even   though we are doing it using a parallel interface, the bit ordering   is based on the serial interface, and the data needs to be reversed*/static __u8 bit_reverse (__u8 data){    static const __u8 swaptab[256] = {	0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,	0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,	0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,	0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,	0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,	0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,	0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,	0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,	0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,	0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,	0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,	0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,	0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,	0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,	0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,	0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF };    return swaptab[data];}/* write data from bitfile chunk 'ch' to FPGA on board 'devnum' */static int write_fpga_ram(struct board_info *bd, struct bitfile_chunk *ch){    int mem_region, n;    __u32 data;    printf("Opening PCI region %d...\n", bd->io.pci.fpga_pci_region);    mem_region = upci_open_region(bd->io.pci.upci_devnum, bd->io.pci.fpga_pci_region);    if ( mem_region < 0 ) {	errmsg(__func__, "could not open device %d, region %d (FPGA memory)",	    bd->io.pci.upci_devnum, bd->io.pci.fpga_pci_region );	return -1;    }    printf("Writing data to FPGA...\n");    data = 0;    for ( n = 0 ; n < ch->len ; n++ ) {	data |= ch->body[n] << ((n & 3) * 8);	if ( (n & 3) == 3 ) {	    /* have 32 bits, write to the RAM */	    upci_write_u32(mem_region, (n & ~3), data);	    /* prep for next 32 */	    data = 0;	}    }    if ( (n & 3) != 0 ) {	/* have residual bits, write to the RAM */	upci_write_u32(mem_region, (n & ~3), data);    }    printf("Transferred %d bytes\n", n);    upci_close_region(mem_region);    return 0;}

⌨️ 快捷键说明

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