OpenCores
URL https://opencores.org/ocsvn/gecko3/gecko3/trunk

Subversion Repositories gecko3

[/] [gecko3/] [trunk/] [GECKO3COM/] [gecko3com-fw/] [firmware/] [src/] [fpga_load.c] - Diff between revs 9 and 21

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 9 Rev 21
/* GECKO3COM
/* GECKO3COM
 *
 *
 * Copyright (C) 2008 by
 * Copyright (C) 2008 by
 *   ___    ____  _   _
 *   ___    ____  _   _
 *  (  _`\ (  __)( ) ( )
 *  (  _`\ (  __)( ) ( )
 *  | (_) )| (_  | |_| |   Bern University of Applied Sciences
 *  | (_) )| (_  | |_| |   Bern University of Applied Sciences
 *  |  _ <'|  _) |  _  |   School of Engineering and
 *  |  _ <'|  _) |  _  |   School of Engineering and
 *  | (_) )| |   | | | |   Information Technology
 *  | (_) )| |   | | | |   Information Technology
 *  (____/'(_)   (_) (_)
 *  (____/'(_)   (_) (_)
 *
 *
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * 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
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * (at your option) any later version.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 */
 
 
/*********************************************************************/
/*********************************************************************/
/** \file     fpga_load.c
/** \file     fpga_load.c
 *********************************************************************
 *********************************************************************
 * \brief     functions to programm an FPGA
 * \brief     functions to programm an FPGA
 *
 *
 *            These functions handle the bit file for an Xilinx Spartan3
 *            These functions handle the bit file for an Xilinx Spartan3
 *            FPGA and programm it in parallel slave mode.
 *            FPGA and programm it in parallel slave mode.
 *
 *
 * \note      Currently only Xilinx FPGA's are supported, function stubs
 * \note      Currently only Xilinx FPGA's are supported, function stubs
 *            to handle Altera are provided as a guide for porting.
 *            to handle Altera are provided as a guide for porting.
 *
 *
 * \author    GNUradio team, Matthias Zurbrügg bfh.ch,
 * \author    GNUradio team, Matthias Zurbrügg bfh.ch,
 *            Christoph Zimmermann bfh.ch
 *            Christoph Zimmermann bfh.ch
 * \date      2009-1-13
 * \date      2009-1-13
 *
 *
*/
*/
 
 
#include "gecko3com_common.h"
#include "gecko3com_common.h"
#include "gecko3com_regs.h"
#include "gecko3com_regs.h"
#include "fpga_load.h"
#include "fpga_load.h"
#include "delay.h"
#include "delay.h"
#include "debugprint.h"
#include "debugprint.h"
 
 
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* Xilinx stuff. We use slave parallel mode (select map) to configure the FPGA
/* Xilinx stuff. We use slave parallel mode (select map) to configure the FPGA
 */
 */
#ifdef XILINX
#ifdef XILINX
 
 
/** makro to toggle the configuration clock line */
/** makro to toggle the configuration clock line */
#define toggle_cclk() { \
#define toggle_cclk() { \
    XILINX_CCLK &= ~bmXILINX_CCLK;      /* bring CCLK low */            \
    XILINX_CCLK &= ~bmXILINX_CCLK;      /* bring CCLK low */            \
    XILINX_CCLK |= bmXILINX_CCLK;       /* bring CCLK high */           \
    XILINX_CCLK |= bmXILINX_CCLK;       /* bring CCLK high */           \
}
}
 
 
 
 
void init_fpga_interface(void) {
void init_fpga_interface(void) {
 
 
  /* IFCLK is generated internally and runs at 48 MHz; IO Pins configured as normal Ports */
  /* IFCLK is generated internally and runs at 48 MHz; IO Pins configured as normal Ports */
  //IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE;
  //IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE;
  IFCONFIG = bmIFCLKSRC | bmIFCLKOE;
  IFCONFIG = bmIFCLKSRC | bmIFCLKOE;
  SYNCDELAY;
  SYNCDELAY;
}
}
 
 
 
 
int8_t fpga_scan_file(const xdata unsigned char *p, idata uint16_t *offset, \
int8_t fpga_scan_file(const xdata unsigned char *p, idata uint16_t *offset, \
                       idata uint16_t *length, xdata Fpga_Info* info)
                       idata uint16_t *length, xdata Fpga_Info* info)
{
{
  idata uint8_t string_length = 0, chars_left_to_read = 0;
  idata uint8_t string_length = 0, chars_left_to_read = 0;
  xdata uint16_t local_position = *offset;
  xdata uint16_t local_position = *offset;
 
 
  for(local_position; local_position < *length; local_position++) {
  for(local_position; local_position < *length; local_position++) {
    //printf_tiny("fi: %d\n",local_position);
    //printf_tiny("fi: %d\n",local_position);
    /* information found, copy data to output array */
    /* information found, copy data to output array */
    if(chars_left_to_read < string_length) {
    if(chars_left_to_read < string_length) {
      info->info[chars_left_to_read++] = p[local_position];
      info->info[chars_left_to_read++] = p[local_position];
 
 
      /* end of information, return successfull */
      /* end of information, return successfull */
      if(chars_left_to_read == string_length) {
      if(chars_left_to_read == string_length) {
        info->position = local_position;
        info->position = local_position;
        *offset = local_position+1;
        *offset = local_position+1;
        return FPGA_INFO_COMPLETE;
        return FPGA_INFO_COMPLETE;
      }
      }
      else {
      else {
        continue; /* ignore rest of these loop, load next character */
        continue; /* ignore rest of these loop, load next character */
      }
      }
    }
    }
 
 
    /* search for the start of the desired type of information */
    /* search for the start of the desired type of information */
    if(chars_left_to_read == 0 && p[local_position] == info->type){
    if(chars_left_to_read == 0 && p[local_position] == info->type){
      chars_left_to_read = 1;
      chars_left_to_read = 1;
      continue; /* ignore rest of these loop, load next character */
      continue; /* ignore rest of these loop, load next character */
    }
    }
 
 
    /* start character found, check next character if it is \0 */
    /* start character found, check next character if it is \0 */
    if(chars_left_to_read == 1) {
    if(chars_left_to_read == 1) {
      if(p[local_position] == 0) {
      if(p[local_position] == 0) {
        chars_left_to_read = 2;
        chars_left_to_read = 2;
 
 
      }
      }
      else {
      else {
        /* false alert, continue searching */
        /* false alert, continue searching */
        chars_left_to_read = 0;
        chars_left_to_read = 0;
      }
      }
      continue; /* ignore rest of these loop, load next character */
      continue; /* ignore rest of these loop, load next character */
    }
    }
 
 
    /* start of information found, copy length of following string */
    /* start of information found, copy length of following string */
    if(chars_left_to_read == 2) {
    if(chars_left_to_read == 2) {
      chars_left_to_read = 0;
      chars_left_to_read = 0;
 
 
      if(p[local_position] > FPGA_INFO_LEN) {
      if(p[local_position] > FPGA_INFO_LEN) {
        string_length = FPGA_INFO_LEN;
        string_length = FPGA_INFO_LEN;
      }
      }
      else {
      else {
        string_length = p[local_position];
        string_length = p[local_position];
      }
      }
 
 
      /* exception: file length has a fixed length */
      /* exception: file length has a fixed length */
      if(info->type == FILE_LENGTH) {
      if(info->type == FILE_LENGTH) {
        string_length = 3;
        string_length = 3;
        chars_left_to_read = 1;
        chars_left_to_read = 1;
        info->info[0] = p[local_position];
        info->info[0] = p[local_position];
      }
      }
    }
    }
 
 
    /* end of for loop. nothing found yet, load next character */
    /* end of for loop. nothing found yet, load next character */
  }
  }
 
 
 
 
  /* end of packet reached, no info found or not finished copying string */
  /* end of packet reached, no info found or not finished copying string */
  info->position = local_position;
  info->position = local_position;
  *offset = local_position;
  *offset = local_position;
  return FPGA_INFO_NOT_COMPLETE;
  return FPGA_INFO_NOT_COMPLETE;
}
}
 
 
 
 
uint8_t fpga_load_begin(void)
uint8_t fpga_load_begin(void)
{
{
  idata uint8_t i;
  idata uint8_t i;
 
 
  /* enable autopointer 0 */
  /* enable autopointer 0 */
  AUTOPTRSETUP = bmAPTREN | bmAPTR1INC;
  AUTOPTRSETUP = bmAPTREN | bmAPTR1INC;
 
 
  /* CS_B, RDWR_B should be high after board initialization
  /* CS_B, RDWR_B should be high after board initialization
   * but when something went wrong during fpga config the state is unknown */
   * but when something went wrong during fpga config the state is unknown */
  if(!(XILINX_CS_B | bmXILINX_CS_B) || !(XILINX_RDWR_B | bmXILINX_RDWR_B)) {
  if(!(XILINX_CS_B | bmXILINX_CS_B) || !(XILINX_RDWR_B | bmXILINX_RDWR_B)) {
    /* bring first RDWR_B high to signal ABORT to the FPGA */
    /* bring first RDWR_B high to signal ABORT to the FPGA */
    XILINX_RDWR_B |= bmXILINX_RDWR_B;
    XILINX_RDWR_B |= bmXILINX_RDWR_B;
 
 
    /* toggle CCLK four times more to complete the abort sequenze  */
    /* toggle CCLK four times more to complete the abort sequenze  */
    for(i=0; i<4; i++) {
    for(i=0; i<4; i++) {
      toggle_cclk();
      toggle_cclk();
    }
    }
    XILINX_CS_B |= bmXILINX_CS_B;
    XILINX_CS_B |= bmXILINX_CS_B;
  }
  }
 
 
  /* bring Prog_B low brings the device in the initalisation mode */
  /* bring Prog_B low brings the device in the initalisation mode */
  XILINX_PROG_B &= ~bmXILINX_PROG_B;
  XILINX_PROG_B &= ~bmXILINX_PROG_B;
  udelay(100);                        // and hold it there
  udelay(100);                        // and hold it there
 
 
  /* bring Prog_B bit high */
  /* bring Prog_B bit high */
  XILINX_PROG_B |= bmXILINX_PROG_B;
  XILINX_PROG_B |= bmXILINX_PROG_B;
 
 
  /* if Init_B goes high the device is in the configuration load mode */
  /* if Init_B goes high the device is in the configuration load mode */
  for(i=0;i<50;i++) {
  for(i=0;i<50;i++) {
    if(XILINX_INIT_B & bmXILINX_INIT_B) {
    if(XILINX_INIT_B & bmXILINX_INIT_B) {
    //if(1) { /* this line is needed for LA tests, uncomment this and comment the line befor */
    //if(1) { /* this line is needed for LA tests, uncomment this and comment the line befor */
 
 
      /* bring CS_B, RDWR_B low */
      /* bring CS_B, RDWR_B low */
      XILINX_RDWR_B &= ~bmXILINX_RDWR_B;
      XILINX_RDWR_B &= ~bmXILINX_RDWR_B;
      XILINX_CS_B &= ~bmXILINX_CS_B;
      XILINX_CS_B &= ~bmXILINX_CS_B;
 
 
      return 1;
      return 1;
    }
    }
    mdelay(1);
    mdelay(1);
  }
  }
 
 
  /* FPGA not ready to configure */
  /* FPGA not ready to configure */
  return 0;
  return 0;
}
}
 
 
 
 
uint8_t fpga_load_xfer(xdata unsigned char *p, idata uint16_t *offset, \
uint8_t fpga_load_xfer(xdata unsigned char *p, idata uint16_t *offset, \
                       idata uint16_t *bytecount)
                       idata uint16_t *bytecount)
{
{
  idata uint16_t local_count;
  idata uint16_t local_count;
  uint8_t local_data;
  uint8_t local_data;
 
 
  //printf_tiny("off %d ",local_count);
  //printf_tiny("off %d ",local_count);
  //printf_tiny("c %d\n",*bytecount);
  //printf_tiny("c %d\n",*bytecount);
 
 
  local_count = *offset;
  local_count = *offset;
 
 
  /* setup  autopointer source adress from parameter p and the offset */
  /* setup  autopointer source adress from parameter p and the offset */
  AUTOPTRH1 = ((uintptr_t)p >> 8);
  AUTOPTRH1 = ((uintptr_t)p >> 8);
  AUTOPTRL1 = ((uintptr_t)p & 0xFF);
  AUTOPTRL1 = ((uintptr_t)p & 0xFF);
  AUTOPTRH1 += (local_count >> 8);
  AUTOPTRH1 += (local_count >> 8);
  AUTOPTRL1 += (local_count & 0xFF);
  AUTOPTRL1 += (local_count & 0xFF);
 
 
  /* setup a for loop to send the data to the fpga data port */
  /* setup a for loop to send the data to the fpga data port */
  for(local_count; local_count < *bytecount; local_count++ ) {
  for(local_count; local_count < *bytecount; local_count++ ) {
    //XILINX_DATA = AUTODAT1;           // drive Data Port with data
    //XILINX_DATA = AUTODAT1;           // drive Data Port with data
    local_data = AUTODAT1;
    local_data = AUTODAT1;
    XILINX_DATA = local_data;
    XILINX_DATA = local_data;
 
 
    toggle_cclk();
    toggle_cclk();
 
 
    //printf_tiny("0x%x ",local_data);
    //printf_tiny("0x%x ",local_data);
 
 
    /* no need for us because we are way to slow that a busy occours */
    /* no need for us because we are way to slow that a busy occours */
    /* loop while busy is true */
    /* loop while busy is true */
    /*while((XILINX_BUSY & bmXILINX_BUSY) ==  bmXILINX_BUSY) {
    /*while((XILINX_BUSY & bmXILINX_BUSY) ==  bmXILINX_BUSY) {
      // if FPGA busy, toggle CCLK
      // if FPGA busy, toggle CCLK
      toggle_cclk();
      toggle_cclk();
    }
    }
    */
    */
  }
  }
 
 
  *offset += *bytecount;
  *offset += *bytecount;
  return 1;
  return 1;
}
}
 
 
 
 
/*
/*
 * check for successful load...
 * check for successful load...
 */
 */
uint8_t
uint8_t
fpga_load_end(void)
fpga_load_end(void)
{
{
  idata uint8_t i;
  idata uint8_t i;
 
 
  /* toggle CCLK four times more to complete the startup sequenze  */
  /* toggle CCLK four times more to complete the startup sequenze  */
  for(i=0; i<4; i++) {
  for(i=0; i<4; i++) {
    toggle_cclk();
    toggle_cclk();
  }
  }
 
 
  /* bring CS_B, RDWR_B high */
  /* bring CS_B, RDWR_B high */
  XILINX_CS_B |= bmXILINX_CS_B;
  XILINX_CS_B |= bmXILINX_CS_B;
  XILINX_RDWR_B |= bmXILINX_RDWR_B;
  XILINX_RDWR_B |= bmXILINX_RDWR_B;
 
 
  if(!fpga_done()) {
  if(!fpga_done()) {
    /* if not DONE, an error occoured during configuration */
    /* if not DONE, an error occoured during configuration */
    print_err("fin.\n");
    //print_err("fin.\n");
    return 0;
    return 0;
  }
  }
 
 
  return 1;
  return 1;
}
}
#endif /* XILINX */
#endif /* XILINX */
 
 
 
 
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* Altera stuff. only copied from USRP source code. does not work. only a
/* Altera stuff. only copied from USRP source code. does not work. only a
 * guide to give you a start to port GECKO3COM to other boards using Altera
 * guide to give you a start to port GECKO3COM to other boards using Altera
 * devices
 * devices
 */
 */
 
 
#ifdef ALTERA
#ifdef ALTERA
/*
/*
 * setup altera FPGA serial load (PS).
 * setup altera FPGA serial load (PS).
 *
 *
 * On entry:
 * On entry:
 *      don't care
 *      don't care
 *
 *
 * On exit:
 * On exit:
 *      ALTERA_DCLK    = 0
 *      ALTERA_DCLK    = 0
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NSTATUS = 1 (input)
 *      ALTERA_NSTATUS = 1 (input)
 */
 */
uint8_t
uint8_t
fpga_load_begin(void)
fpga_load_begin(void)
{
{
  ALTERA_CONFIG &= ~bmALTERA_BITS;              // clear all bits (NCONFIG low)
  ALTERA_CONFIG &= ~bmALTERA_BITS;              // clear all bits (NCONFIG low)
  udelay (40);                                  // wait 40 us
  udelay (40);                                  // wait 40 us
  ALTERA_CONFIG |= bmALTERA_NCONFIG;    // set NCONFIG high
  ALTERA_CONFIG |= bmALTERA_NCONFIG;    // set NCONFIG high
 
 
  if (UC_BOARD_HAS_FPGA){
  if (UC_BOARD_HAS_FPGA){
    // FIXME should really cap this loop with a counter so we
    // FIXME should really cap this loop with a counter so we
    //   don't hang forever on a hardware failure.
    //   don't hang forever on a hardware failure.
    while ((USRP_ALTERA_CONFIG & bmALTERA_NSTATUS) == 0) // wait for NSTATUS to go high
    while ((USRP_ALTERA_CONFIG & bmALTERA_NSTATUS) == 0) // wait for NSTATUS to go high
      ;
      ;
  }
  }
 
 
  // ready to xfer now
  // ready to xfer now
 
 
  return 1;
  return 1;
}
}
 
 
/*
/*
 * clock out the low bit of bits.
 * clock out the low bit of bits.
 *
 *
 * On entry:
 * On entry:
 *      ALTERA_DCLK    = 0
 *      ALTERA_DCLK    = 0
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NSTATUS = 1 (input)
 *      ALTERA_NSTATUS = 1 (input)
 *
 *
 * On exit:
 * On exit:
 *      ALTERA_DCLK    = 0
 *      ALTERA_DCLK    = 0
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NSTATUS = 1 (input)
 *      ALTERA_NSTATUS = 1 (input)
 */
 */
 
 
static void
static void
clock_out_config_byte(const uint8_t bits) _naked
clock_out_config_byte(const uint8_t bits) _naked
{
{
    _asm
    _asm
        mov     a, dpl
        mov     a, dpl
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        rrc     a
        rrc     a
        mov     _bitALTERA_DATA0,c
        mov     _bitALTERA_DATA0,c
        setb    _bitALTERA_DCLK
        setb    _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
        clr     _bitALTERA_DCLK
 
 
        ret
        ret
 
 
    _endasm;
    _endasm;
}
}
 
 
static void
static void
clock_out_bytes(const uint8_t bytecount,
clock_out_bytes(const uint8_t bytecount,
                 uint8_t xdata *p)
                 uint8_t xdata *p)
{
{
  while (bytecount-- > 0)
  while (bytecount-- > 0)
    clock_out_config_byte (*p++);
    clock_out_config_byte (*p++);
}
}
 
 
/*
/*
 * Transfer block of bytes from packet to FPGA serial configuration port
 * Transfer block of bytes from packet to FPGA serial configuration port
 *
 *
 * On entry:
 * On entry:
 *      ALTERA_DCLK    = 0
 *      ALTERA_DCLK    = 0
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NSTATUS = 1 (input)
 *      ALTERA_NSTATUS = 1 (input)
 *
 *
 * On exit:
 * On exit:
 *      ALTERA_DCLK    = 0
 *      ALTERA_DCLK    = 0
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NCONFIG = 1
 *      ALTERA_NSTATUS = 1 (input)
 *      ALTERA_NSTATUS = 1 (input)
 */
 */
uint8_t
uint8_t
fpga_load_xfer(const xdata uint8_t *p, const uint8_t bytecount)
fpga_load_xfer(const xdata uint8_t *p, const uint8_t bytecount)
{
{
  clock_out_bytes (bytecount, p);
  clock_out_bytes (bytecount, p);
  return 1;
  return 1;
}
}
 
 
/*
/*
 * check for successful load...
 * check for successful load...
 */
 */
uint8_t
uint8_t
fpga_load_end(void)
fpga_load_end(void)
{
{
  uint8_t status = ALTERA_CONFIG;
  uint8_t status = ALTERA_CONFIG;
 
 
  if (!UC_BOARD_HAS_FPGA)                       // always true if we don't have FPGA
  if (!UC_BOARD_HAS_FPGA)                       // always true if we don't have FPGA
    return 1;
    return 1;
 
 
  if ((status & bmALTERA_NSTATUS) == 0)          // failed to program
  if ((status & bmALTERA_NSTATUS) == 0)          // failed to program
    return 0;
    return 0;
 
 
  if ((status & bmALTERA_CONF_DONE) == bmALTERA_CONF_DONE)
  if ((status & bmALTERA_CONF_DONE) == bmALTERA_CONF_DONE)
    return 1;                                   // everything's cool
    return 1;                                   // everything's cool
 
 
  // I don't think this should happen.  It indicates that
  // I don't think this should happen.  It indicates that
  // programming is still in progress.
  // programming is still in progress.
 
 
  return 0;
  return 0;
}
}
 
 
#endif /* ALTERA */
#endif /* ALTERA */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.