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
22word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
23void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
24void 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/* ----------------------------------------------------------------------- */
35int 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
139return 0;
140}
141
142