Imported Upstream version 3.0
[debian/gnuradio] / usrp / firmware / src / common / fpga_load.c
1 /* 
2  * USRP - Universal Software Radio Peripheral
3  *
4  * Copyright (C) 2003 Free Software Foundation, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
19  */
20
21 #include "usrp_common.h"
22 #include "fpga_load.h"
23 #include "delay.h"
24
25 /*
26  * setup altera FPGA serial load (PS).
27  *
28  * On entry:
29  *      don't care
30  *
31  * On exit:
32  *      ALTERA_DCLK    = 0
33  *      ALTERA_NCONFIG = 1
34  *      ALTERA_NSTATUS = 1 (input)
35  */
36 unsigned char
37 fpga_load_begin (void)
38 {
39   USRP_ALTERA_CONFIG &= ~bmALTERA_BITS;         // clear all bits (NCONFIG low)
40   udelay (40);                                  // wait 40 us
41   USRP_ALTERA_CONFIG |= bmALTERA_NCONFIG;       // set NCONFIG high
42
43   if (UC_BOARD_HAS_FPGA){
44     // FIXME should really cap this loop with a counter so we
45     //   don't hang forever on a hardware failure.
46     while ((USRP_ALTERA_CONFIG & bmALTERA_NSTATUS) == 0) // wait for NSTATUS to go high
47       ;
48   }
49
50   // ready to xfer now
51
52   return 1;
53 }
54
55 /*
56  * clock out the low bit of bits.
57  *
58  * On entry:
59  *      ALTERA_DCLK    = 0
60  *      ALTERA_NCONFIG = 1
61  *      ALTERA_NSTATUS = 1 (input)
62  *
63  * On exit:
64  *      ALTERA_DCLK    = 0
65  *      ALTERA_NCONFIG = 1
66  *      ALTERA_NSTATUS = 1 (input)
67  */
68
69
70 #if 0
71
72 static void
73 clock_out_config_byte (unsigned char bits)
74 {
75   unsigned char i;
76
77   // clock out configuration byte, least significant bit first
78
79   for (i = 0; i < 8; i++){
80
81     USRP_ALTERA_CONFIG = ((USRP_ALTERA_CONFIG & ~bmALTERA_DATA0) | ((bits & 1) ? bmALTERA_DATA0 : 0));
82     USRP_ALTERA_CONFIG |= bmALTERA_DCLK;                /* set DCLK to 1 */
83     USRP_ALTERA_CONFIG &= ~bmALTERA_DCLK;               /* set DCLK to 0 */
84
85     bits = bits >> 1;
86   }
87 }
88         
89 #else
90
91 static void 
92 clock_out_config_byte (unsigned char bits) _naked
93 {
94     _asm
95         mov     a, dpl
96         
97         rrc     a
98         mov     _bitALTERA_DATA0,c
99         setb    _bitALTERA_DCLK
100         clr     _bitALTERA_DCLK
101         
102         rrc     a
103         mov     _bitALTERA_DATA0,c
104         setb    _bitALTERA_DCLK
105         clr     _bitALTERA_DCLK
106         
107         rrc     a
108         mov     _bitALTERA_DATA0,c
109         setb    _bitALTERA_DCLK
110         clr     _bitALTERA_DCLK
111         
112         rrc     a
113         mov     _bitALTERA_DATA0,c
114         setb    _bitALTERA_DCLK
115         clr     _bitALTERA_DCLK
116         
117         rrc     a
118         mov     _bitALTERA_DATA0,c
119         setb    _bitALTERA_DCLK
120         clr     _bitALTERA_DCLK
121         
122         rrc     a
123         mov     _bitALTERA_DATA0,c
124         setb    _bitALTERA_DCLK
125         clr     _bitALTERA_DCLK
126         
127         rrc     a
128         mov     _bitALTERA_DATA0,c
129         setb    _bitALTERA_DCLK
130         clr     _bitALTERA_DCLK
131         
132         rrc     a
133         mov     _bitALTERA_DATA0,c
134         setb    _bitALTERA_DCLK
135         clr     _bitALTERA_DCLK
136         
137         ret     
138
139     _endasm;
140 }
141
142 #endif
143
144 static void
145 clock_out_bytes (unsigned char bytecount,
146                  unsigned char xdata *p)
147 {
148   while (bytecount-- > 0)
149     clock_out_config_byte (*p++);
150 }
151
152 /*
153  * Transfer block of bytes from packet to FPGA serial configuration port
154  *
155  * On entry:
156  *      ALTERA_DCLK    = 0
157  *      ALTERA_NCONFIG = 1
158  *      ALTERA_NSTATUS = 1 (input)
159  *
160  * On exit:
161  *      ALTERA_DCLK    = 0
162  *      ALTERA_NCONFIG = 1
163  *      ALTERA_NSTATUS = 1 (input)
164  */
165 unsigned char
166 fpga_load_xfer (xdata unsigned char *p, unsigned char bytecount)
167 {
168   clock_out_bytes (bytecount, p);
169   return 1;
170 }
171
172 /*
173  * check for successful load...
174  */
175 unsigned char
176 fpga_load_end (void)
177 {
178   unsigned char status = USRP_ALTERA_CONFIG;
179
180   if (!UC_BOARD_HAS_FPGA)                       // always true if we don't have FPGA
181     return 1;
182
183   if ((status & bmALTERA_NSTATUS) == 0)         // failed to program
184     return 0;
185
186   if ((status & bmALTERA_CONF_DONE) == bmALTERA_CONF_DONE)
187     return 1;                                   // everything's cool
188
189   // I don't think this should happen.  It indicates that
190   // programming is still in progress.
191
192   return 0;
193 }