1 /*
2  * Copyright (C) Eicon Technology Corporation, 2000.
3  *
4  * Eicon File Revision :    1.2
5  *
6  * This software may be used and distributed according to the terms
7  * of the GNU General Public License, incorporated herein by reference.
8  *
9  */
10 
11 #include "sys.h"
12 #include "idi.h"
13 #include "uxio.h"
14 
15 #define FPGA_PORT		0x6E
16 #define FPGA_DLOAD_BUFLEN   	256
17 #define NAME_OFFSET         	0x10
18 #define NAME_MAXLEN         	12
19 #define DATE_OFFSET         	0x2c
20 #define DATE_MAXLEN         	10
21 
22 word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
23 void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
24 void UxPause(long int);
25 
26 /*-------------------------------------------------------------------------*/
27 /* Loads the FPGA configuration file onto the hardware.                    */
28 /* Function returns 0 on success, else an error number.                    */
29 /* On success, an identifier string is returned in the buffer              */
30 /*                                                                         */
31 /* A buffer of FPGA_BUFSIZE, a handle to the already opened bitstream      */
32 /* file and a file read function has to be provided by the operating       */
33 /* system part.                                                            */
34 /* ----------------------------------------------------------------------- */
FPGA_Download(word cardtype,dword RegBase,byte * strbuf,byte FPGA_SRC[],int FPGA_LEN)35 int FPGA_Download( word      cardtype,
36                         dword     RegBase,
37                         byte *strbuf,
38                         byte FPGA_SRC[],
39 			int FPGA_LEN
40                       )
41 {
42   word        i, j, k;
43   word        baseval, Mask_PROGRAM, Mask_DONE, Mask_CCLK, Mask_DIN;
44   dword       addr;
45   byte        *pFPGA;
46 
47   //--- check for legal cardtype
48   switch (cardtype)
49   {
50     case IDI_ADAPTER_MAESTRAQ:
51       addr          = RegBase ; // address where to access FPGA
52       Mask_PROGRAM  = 0x0001;         // FPGA pins at address
53       Mask_DONE     = 0x0002;
54       Mask_CCLK     = 0x0100;
55       Mask_DIN      = 0x0400;
56       baseval       = 0x000d;         // PROGRAM hi, CCLK lo, DIN lo by default
57     break;
58 
59     default:
60 
61   	DPRINTF(("divas: FPGA Download ,Illegal Card"));
62       	return -1; // illegal card
63   }
64 
65   //--- generate id string from file content
66   for (j=NAME_OFFSET, k=0; j<(NAME_OFFSET+NAME_MAXLEN); j++, k++) //name
67   {
68     if (!FPGA_SRC[j]) break;
69     strbuf[k] = FPGA_SRC[j];
70   }
71   strbuf[k++] = ' ';
72   for (j=DATE_OFFSET; j<(DATE_OFFSET+DATE_MAXLEN); j++, k++) // date
73   {
74     if (!FPGA_SRC[j]) break;
75     strbuf[k] = FPGA_SRC[j];
76   }
77   strbuf[k] = 0;
78 
79   DPRINTF(("divas: FPGA Download - %s", strbuf));
80 
81   //--- prepare download, Pulse PROGRAM pin down.
82   UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval &~Mask_PROGRAM);  // PROGRAM low pulse
83   UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);                 // release
84   UxPause(50);  // wait until FPGA finised internal memory clear
85 
86   //--- check done pin, must be low
87   if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE)
88   {
89     DPRINTF(("divas: FPGA_ERR_DONE_WRONG_LEVEL"));
90     return -1;
91   }
92 
93   pFPGA = FPGA_SRC;
94 
95   i = 0;
96   /* Move past the header */
97   while ((FPGA_SRC[i] != 0xFF) && (i < FPGA_LEN))
98   {
99     i++;
100   }
101 
102   // We've hit the 0xFF so move on to the next byte
103   // i++;
104   DPRINTF(("divas: FPGA Code starts at offset %d", i));
105 
106   //--- put data onto the FPGA
107   for (;i<FPGA_LEN; i++)
108   {
109     //--- put byte onto FPGA
110     for (j=0; j<8; j++)
111     {
112       if (FPGA_SRC[i] &(0x80>>j)) baseval |= Mask_DIN; // write a hi
113       else                      baseval &=~Mask_DIN; // write a lo
114       UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);
115       UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK);     // set CCLK hi
116       UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);                 // set CCLK lo
117     }
118   }
119 
120   //--- add some additional startup clock cycles and check done pin
121   for (i=0; i<5; i++)
122   {
123     UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval | Mask_CCLK);     // set CCLK hi
124     UxCardPortIoOutW(NULL, (byte *) addr, FPGA_PORT, baseval);                 // set CCLK lo
125   }
126 
127   UxPause(100);
128 
129   if (UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT) &Mask_DONE)
130   {
131     DPRINTF(("divas: FPGA download successful"));
132   }
133   else
134   {
135     DPRINTF(("divas: FPGA download failed - 0x%x", UxCardPortIoInW(NULL, (byte *) addr, FPGA_PORT)));
136 	return -1;
137   }
138 
139 return 0;
140 }
141 
142