Example #1
0
/*
  Checks for commandline args, intializes globals, then  begins code download.
*/
int main(int argc, char **argv) {

   nf2.device_name = DEFAULT_IFACE;

   processArgs(argc, argv);

   if (check_iface(&nf2))
   {
	   exit(1);
   }
   if (openDescriptor(&nf2))
   {
      exit(1);
   }

   if (strncmp(log_file_name, "stdout",6)) {

      if ((log_file = fopen(log_file_name, "w")) == NULL) {
	 printf("Error: unable to open logfile %s for writing.\n",
		log_file_name);
	 exit(1);
      }
   }
   else
      log_file = stdout;

   InitGlobals();

   BeginCodeDownload(bin_file_name);

   if (!cpci_reprog)
      ResetDevice();

   /* reset the PHYs */
   NF2_WR32(MDIO_0_CONTROL_REG, 0x8000);
   NF2_WR32(MDIO_1_CONTROL_REG, 0x8000);
   NF2_WR32(MDIO_2_CONTROL_REG, 0x8000);
   NF2_WR32(MDIO_3_CONTROL_REG, 0x8000);

   /* wait until the resets have been completed */
   usleep(100);

   if (intr_enable)
   {
      /* PHY interrupt mask off for link status change */
      NF2_WR32(MDIO_0_INTERRUPT_MASK_REG, 0xfffd);
      NF2_WR32(MDIO_1_INTERRUPT_MASK_REG, 0xfffd);
      NF2_WR32(MDIO_2_INTERRUPT_MASK_REG, 0xfffd);
      NF2_WR32(MDIO_3_INTERRUPT_MASK_REG, 0xfffd);
   }

   VerifyDevInfo();

   fclose(log_file);

   closeDescriptor(&nf2);

   return SUCCESS;
}
/*
 * Reset the device
 */
void ResetDevice(void) {
   u_int val;

   /* Read the current value of the control register so that we can modify
    * it to do a reset */
   val = NF2_RD32(CPCI_CTRL);

   NF2_WR32(CPCI_CLK, freq);
   /* Write to the control register to reset it */
   NF2_WR32(CPCI_CTRL, val | 0x100);

   //NF2_WR32(CPCI_CLK, 0x0);
   /* Sleep for a while to let the reset complete */
   usleep(1);
}
Example #3
0
/*
  Given a block of bytes to write, and a bytecount, create 32 bit words from these
  bytes and write them to the programming RAM in the Virtex
*/
void DownloadCPCICodeBlock (u_char *code_data, int code_data_size) {

   u_int result;
   u_int data_word;
   int bytes_left;
   u_int count = 0;

   bytes_left = code_data_size;

   while (bytes_left)
      {
	 data_word = ((u_int) (*code_data++)) << 24; bytes_left--;
	 if (bytes_left) { data_word |= ((u_int) (*code_data++))<<16 ; bytes_left--;}
	 if (bytes_left) { data_word |= ((u_int) (*code_data++))<<8  ; bytes_left--;}
	 if (bytes_left) { data_word |= ((u_int) (*code_data++))     ; bytes_left--;}

	 NF2_WR32(prog_addr, data_word);
         prog_addr += 4;
      }
}
Example #4
0
/*
  Given a block of bytes to write, and a bytecount, create 32 bit words from these
  bytes and write them to the Programming FIFO.
  After each 8 words stop and check that the FIFO is empty.
*/
void DownloadVirtexCodeBlock (u_char *code_data, int code_data_size) {

   u_int result;
   u_int data_word;
   int bytes_left;
   u_int count = 0;

   bytes_left = code_data_size;

   while (bytes_left)
      {
	 data_word = (u_int) (*code_data++); bytes_left--;
	 if (bytes_left) { data_word |= ((u_int) (*code_data++))<<8 ; bytes_left--;}
	 if (bytes_left) { data_word |= ((u_int) (*code_data++))<<16 ; bytes_left--;}
	 if (bytes_left) { data_word |= ((u_int) (*code_data++))<<24 ; bytes_left--;}

	 NF2_WR32(CPCI_PROGRAMMING_DATA, data_word);

	 /* Every 8 words we need to check the FIFO - should always be empty!
	  * (or the done flag should be asserted)
	  */
	 if (++count == 8) {
	    count = 0;
	    while (((result = NF2_RD32(CPCI_PROGRAMMING_STATUS)) & 0x10002) != 2 && (result & 0x100) != 0x100) {
	       if (result & 0x10000) {
	          fprintf(log_file, "INIT went active during programming - there was an error!\n");
                  exit(1);
	       }
	       fprintf(log_file, "Strange. FIFO wasnt empty... trying again.\n");
	       usleep(100);
	       result = NF2_RD32(CPCI_PROGRAMMING_STATUS);
	       if ((result & 0x10002) != 2) {
	          fprintf(log_file, "Retrying ... FIFO still not empty. Giving up.\n");
	          fprintf(log_file, "Last status word read was 0x%0x\n", result);
   	       }
	    }
	 }
      }
}
Example #5
0
/*
   Download the codefile by writing it to the programming register in CPCI.
*/
void DownloadCode(FILE *code_file) {

   u_int result;
   u_int version;
   int code_data_size;
   unsigned char * code_data;
   u_int retries;
   int bytes_expected;

   /*
    * Identify what version of the board we are running
    */
   version = NF2_RD32(CPCI_ID);
   version &= 0xffffff;

   if (!cpci_reprog) {
      /*
         First, make sure the download interface is reset.
         This flushes buffers, resets state machines etc.
      */

      NF2_WR32(CPCI_PROGRAMMING_CONTROL, 1);

      /* Clear the error registers */
      NF2_WR32(CPCI_ERROR, 0);

      /* Wait a while for the PROG_B cycle to finish. */
      usleep(100);

      /*
         Read programming status:
         Check that DONE bit (bit 8) is zero and FIFO (bit 1) is empty (1).
      */

      result = NF2_RD32(CPCI_PROGRAMMING_STATUS);

      if ((result & 0x102) != 0x2) {
         fprintf(log_file, "After resetting Programming interface, expected status to be 1 (FIFO empty).\n");
         fprintf(log_file, "However status & 0x102 is 0x%0x\n", (result & 0x102));
         FatalError();
      }

      /* Check the error register */
      fprintf(log_file, "Error Registers: %x\n", NF2_RD32(CPCI_ERROR));

      fprintf(log_file, "Good, after resetting programming interface the FIFO is empty\n");

      /* Sleep for a while to allow the INIT pin to be reset */
      usleep(10000);
      retries = 3;

      while (NF2_RD32(CPCI_PROGRAMMING_STATUS) & 0x10002)
      {
         if ((NF2_RD32(CPCI_PROGRAMMING_STATUS) & 0x10000))
             usleep(10000);
         else {
            break;
         }
         retries--;

         if (retries <= 0)
         {
            printf("CPCI's INIT signal did not clear in time, exiting\n");
            printf ("CPCI_PROGRAMMING_STATUS: 0x%08x\n", NF2_RD32(CPCI_PROGRAMMING_STATUS));
            exit(1);
         }
      }
   } // if (!cpci_reprog)


   /* Read the code file, and write it to the card.  */

   code_data = (unsigned char *) malloc(sizeof(unsigned char) * READ_BUFFER_SIZE);

   /* check num bytes read */
   while (code_data_size = fread(code_data, sizeof(unsigned char), READ_BUFFER_SIZE, code_file))
      {
         if (cpci_reprog)
	    DownloadCPCICodeBlock(code_data, code_data_size);
         else
	    DownloadVirtexCodeBlock(code_data, code_data_size);
	 bytes_sent += code_data_size;
      }

   /* Free the code_data variable */
   free(code_data);

   /* Work out how large the download should have been */
   if (cpci_reprog) {
      bytes_expected = CPCI_BIN_SIZE;
   }
   else {
      switch (version) {
         case 1: bytes_expected = VIRTEX_BIN_SIZE_V2_0; break;
         case 2:
         case 3:
         case 4: bytes_expected = VIRTEX_BIN_SIZE_V2_1; break;
         default : bytes_expected = -1;
      }
      if (version < CPCI_MIN_VER || version > CPCI_MAX_VER)
         fprintf(log_file, "\n"
               "WARNING: Unkown CPCI version (%d).\n"
               "         Known versions are between %d and %d inclusive.\n"
               "         Expected number of bytes will be displayed as -1.\n\n",
               version, CPCI_MIN_VER, CPCI_MAX_VER);
   }

   fprintf(log_file, "Download completed -  %d bytes. (expected %d).\n", bytes_sent, bytes_expected);

   /*
    * Kick off the programming process or wait for the process to complete
    */
   if (cpci_reprog) {
      NF2_WR32(VIRTEX_PROGRAM_CTRL_ADDR, DISABLE_RESET | START_PROGRAMMING);
      fprintf(log_file, "Instructed CPCI reprogramming to start. Please reload PCI BARs.\n");
   }
   else {
      /*
      Now wait to see that DONE goes high (bit 8) and INIT (16) is low
      */
      for (retries=0; retries<3; retries++) {
         sleep(1);
         result = NF2_RD32(CPCI_PROGRAMMING_STATUS);
         if  ((result & 0x100) == 0x100 ) {
            fprintf(log_file, "DONE went high - chip has been successfully programmed.\n");
            return;
         }
         if  ((result & 0x10000) == 0x10000 ) {
            fprintf(log_file, "INIT went high - appears to be a programming error.\n");
            FatalError();
         }
         if (retries == 2) {
            fprintf(log_file, "DONE has not gone high - looks like an error\n");
            FatalError();
         }
      }
   }
}