#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>


#include "../dev/pci/sis1100_var.h"  
#include "../sis3100_calls/sis3100_vme_calls.h"

/* #include "flash_prom.h" */
#include "vme_sub_flashprom.h"



#define FLASHPROM  0x01000000
#define SHARCRAM   0x01200000
#define D48REG     0x01300000





#define swap_int(x)  ((((x)>>24)&0x000000ff) |\
                      (((x)>> 8)&0x0000ff00) |\
                      (((x)<< 8)&0x00ff0000) |\
                      (((x)<<24)&0xff000000))






/****************************************************************************/

/****************************************************************************/
int main(int argc, char* argv[])
{

int p;
u_int8_t read_data_8 ;
u_int8_t data_8 ;
u_int32_t data ;
u_int32_t addr ;

u_int32_t  mod_base ;
int return_code ;
int error ;

FILE *loaderfile;

unsigned int tempword[0x10000];
int retcode=1;

int count=0 ;
int loadcount=0; 
int currentaddress ;

/* int flash_busy ; */

/*
int i;
char *dummy;
*/


if (argc<4)
  {
  fprintf(stderr, "usage: %s PATH %s Sharc.ldr   BASE_ADDR   \n", argv[0]);
  return 1;
  }

if ((p=open(argv[1], O_RDWR, 0))<0) {
	perror("open");
	return 1;
}

mod_base   = strtoul(argv[3],NULL,0) ;




addr = mod_base + 0x0 ;                    /* Version */

return_code =  vme_A32D32_read(p, addr, &data ) ;
if (return_code != 0) { printf("vme_A32D32_read: return_code = 0x%08x at addr.= 0x%08x\n",return_code,addr);return 1;}
printf("\n");
printf("\n");
printf(" Version register:  0x%08x\n", data );
printf("\n");

/* 1. Reset SHARC */
  printf("resetting SHARC DSP\n");
  addr = mod_base + 0x10 ;                    
  return_code =  vme_A32D32_write(p, addr, 0x03000000) ;
  if (return_code != 0) {printf("vme_A32D32_write: return_code = 0x%08x at addr.= 0x%08x\n",return_code,addr);return -1;}


/*********************************************/
/*                                           */
/*   Clear Flashprom                         */
/*                                           */
/*                                           */
/*********************************************/

  printf("\n");
  printf(" Clear Flashprom in process\n");
  printf("\n");
  clear_flashprom (p, mod_base + FLASHPROM) ;  
  printf(" Clear Flashprom finished \n");
  printf("\n");



/* open SHARC loader file */
  loaderfile=fopen(argv[2],"r");

 
/* loaderfile=fopen("led_test.ldr","r");*/
 if (loaderfile>0) {
     printf("loader file opened\n");

     while (retcode>0) {
	 retcode=fscanf(loaderfile,"0x%4x\n",&tempword[count]);
         if (count<0x10000) {
            count++;
	 }
         else {
	     printf("load file size too big\n");
             return -1;
	 }
     }
     printf("load file length: %d\n",count);
 }
 else
 {
   printf(" no loaderfile \n");
   return 1 ;
 }     


 fclose(loaderfile);
 






/* load SHARC */


  printf("loading SHARC DSP\n");
  loadcount = 0 ;
  currentaddress = mod_base + FLASHPROM ;

  while (loadcount<count) {  
/*    printf(" count = 0x%08x  loadcount = 0x%08x     data = 0x%08x \n", count, loadcount,tempword[loadcount]); */
      data_8 =  (u_int8_t)tempword[loadcount]  ;
      write_flashprom (p, mod_base + FLASHPROM, currentaddress, data_8  ) ;
      currentaddress+=4;
      data_8 = (u_int8_t)(tempword[loadcount] >> 8)  ;
      write_flashprom (p, mod_base + FLASHPROM, currentaddress, data_8  ) ;
      loadcount = loadcount + 1 ;
      currentaddress+=4;
  }
  printf("SHARC DSP loaded\n");



/* Verifier SHARC */
/*  printf("loading SHARC DSP\n"); */
  error = 0 ;
  loadcount = 0 ;
  currentaddress = mod_base + FLASHPROM ;
  while (loadcount<count) {  
      data_8 =  (u_int8_t)tempword[loadcount]  ;
      read_flashprom (p, currentaddress, &read_data_8  ) ;
      if (data_8 != read_data_8) {
         printf(" Verifier Error: loadcount = 0x%08x  wdata = 0x%02x     rdata = 0x%02x \n", loadcount, data_8, read_data_8);
         error = error + 1 ;
         }
      currentaddress+=4;
      data_8 = (u_int8_t)(tempword[loadcount] >> 8)  ;
      read_flashprom (p, currentaddress, &read_data_8  ) ;
      if (data_8 != read_data_8) {
         printf(" Verifier Error: loadcount = 0x%08x  wdata = 0x%02x     rdata = 0x%02x \n", loadcount, data_8, read_data_8);
         error = error + 1 ;
         }
      loadcount = loadcount + 1 ;
      currentaddress+=4;
  }

  if (error != 0) {
   close(p);
   return -1 ;
  }
   else {
    printf("Verifier OK \n"); 
  }




 
/* 3. Run SHARC */
  printf("starting SHARC from Flashprom\n");


  addr = mod_base + 0x10 ;                    
  return_code =  vme_A32D32_write(p, addr, 0x0300) ;
  if (return_code != 0) {printf("vme_A32D32_write: return_code = 0x%08x at addr.= 0x%08x\n",return_code,addr);return -1;}

 

close(p);


return 0;
}

































