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