]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blob - gpif-acquisition.c
Moved gpif code out to separate source file
[sigrok-firmware-fx2lafw.git] / gpif-acquisition.c
1 /*
2  * This file is part of the fx2lafw project.
3  *
4  * Copyright (C) 2011-2012 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20  */
21
22 #include <fx2regs.h>
23 #include <fx2macros.h>
24 #include <delay.h>
25 #include <gpif.h>
26
27 #include <fx2lafw.h>
28 #include <gpif-acquisition.h>
29
30 /* GPIF terminology: DP = decision point, NDP = non-decision-point */
31
32 /*
33  * GPIF waveforms.
34  *
35  * See section "10.3.4 State Instructions" in the TRM for details.
36  */
37 static const BYTE wavedata[128] = {
38         /* Waveform 0: */
39
40         /*
41          * This is the basic algorithm implemented in our GPIF state machine:
42          *
43          * State 0: NDP: Sample the FIFO data bus.
44          * State 1: DP: If EP2 is full, go to state 7 (the IDLE state), i.e.,
45          *          end the current waveform. Otherwise, go to state 0 again,
46          *          i.e., sample data until EP2 is full.
47          * State 2: Unused.
48          * State 3: Unused.
49          * State 4: Unused.
50          * State 5: Unused.
51          * State 6: Unused.
52          */
53
54         /* S0-S6: LENGTH/BRANCH */
55         /*
56          * For NDPs (LENGTH): Number of IFCLK cycles to stay in this state.
57          * For DPs (BRANCH): [7] ReExec, [5:3]: BRANCHON1, [2:0]: BRANCHON0.
58          *
59          * 0x01: Stay one IFCLK cycle in this state.
60          * 0x38: No Re-execution, BRANCHON1 = state 7, BRANCHON0 = state 0.
61          */
62         // 0x01, 0x38, 0x01, 0x01, 0x01, 0x01, 0x01,
63         // FIXME: For now just loop over the "sample data" state forever.
64         0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
65         /* TRM says "reserved", but GPIF designer always puts a 0x07 here. */
66         0x07,
67
68         /* S0-S6: OPCODE */
69         /*
70          * 0x02: NDP, sample the FIFO data bus.
71          * 0x01: DP, don't sample the FIFO data bus.
72          */
73         0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
74         /* Reserved */
75         0x00,
76
77         /* S0-S6: OUTPUT */
78         /* Unused, we don't output anything, we only sample the pins. */
79         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80         /* Reserved */
81         0x00,
82
83         /* S0-S6: LOGIC FUNCTION (not used for NDPs) */
84         /*
85          * 0x36: LFUNC = "A AND B", A = FIFO flag, B = FIFO flag.
86          * The FIFO flag (FF == full flag, in our case) is configured via
87          * EP2GPIFFLGSEL.
88          *
89          * So: If the EP2 FIFO is full and the EP2 FIFO is full, go to
90          * the state specified by BRANCHON1 (state 7), otherwise BRANCHON0
91          * (state 0). See the LENGTH/BRANCH value above for details.
92          */
93         0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
94         /* TRM says "reserved", but GPIF designer always puts a 0x3f here. */
95         0x3f,
96
97         /* TODO: Must unused waveforms be "valid"? */
98
99         /* Waveform 1 (unused): */
100         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104
105         /* Waveform 2 (unused): */
106         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110
111         /* Waveform 3 (unused): */
112         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 };
117
118 static void gpif_setup_registers(void)
119 {
120         /* TODO. Value probably irrelevant, as we don't use RDY* signals? */
121         GPIFREADYCFG = 0;
122
123         /*
124          * Set TRICTL = 0, thus CTL0-CTL5 are CMOS outputs.
125          * TODO: Probably irrelevant, as we don't use CTL0-CTL5?
126          */
127         GPIFCTLCFG = 0;
128
129         /* When GPIF is idle, tri-state the data bus. */
130         /* Bit 7: DONE, bit 0: IDLEDRV. TODO: Set/clear DONE bit? */
131         GPIFIDLECS = (1 << 0);
132
133         /* When GPIF is idle, set CTL0-CTL5 to 0. */
134         GPIFIDLECTL = 0;
135
136         /*
137          * Map index 0 in wavedata[] to FIFORD. The rest is assigned too,
138          * but not used by us.
139          *
140          * GPIFWFSELECT: [7:6] = SINGLEWR index, [5:4] = SINGLERD index,
141          *               [3:2] = FIFOWR index, [1:0] = FIFORD index
142          */
143         GPIFWFSELECT = (0x3 << 6) | (0x2 << 4) | (0x1 << 2) | (0x0 << 0);
144
145         /* Contains RDY* pin values. Read-only according to TRM. */
146         GPIFREADYSTAT = 0;
147 }
148
149 static void gpif_write_waveforms(void)
150 {
151         int i;
152
153         /*
154          * Write the four waveforms into the respective WAVEDATA register
155          * locations (0xe400 - 0xe47f) using the FX2's autopointer feature.
156          */
157         AUTOPTRSETUP = 0x07;             /* Increment autopointers 1 & 2. */
158         AUTOPTRH1 = MSB((WORD)wavedata); /* Source is the 'wavedata' array. */
159         AUTOPTRL1 = LSB((WORD)wavedata);
160         AUTOPTRH2 = 0xe4;                /* Dest is WAVEDATA (0xe400). */
161         AUTOPTRL2 = 0x00;
162         for (i = 0; i < 128; i++)
163                 EXTAUTODAT2 = EXTAUTODAT1;
164 }
165
166 static void gpif_init_addr_pins(void)
167 {
168         /*
169          * Configure the 9 GPIF address pins (GPIFADR[8:0], which consist of
170          * PORTC[7:0] and PORTE[7]), and output an initial address (zero).
171          * TODO: Probably irrelevant, the 56pin FX2 has no ports C and E.
172          */
173         PORTCCFG = 0xff;    /* Set PORTC[7:0] as alt. func. (GPIFADR[7:0]). */
174         OEC = 0xff;         /* Configure PORTC[7:0] as outputs. */
175         PORTECFG |= 0x80;   /* Set PORTE[7] as alt. func. (GPIFADR[8]). */
176         OEE |= 0x80;        /* Configure PORTE[7] as output. */
177         SYNCDELAY();
178         GPIFADRL = 0x00;    /* Clear GPIFADR[7:0]. */
179         SYNCDELAY();
180         GPIFADRH = 0x00;    /* Clear GPIFADR[8]. */
181 }
182
183 static void gpif_init_flowstates(void)
184 {
185         /* Clear all flowstate registers, we don't use this functionality. */
186         FLOWSTATE = 0;
187         FLOWLOGIC = 0;
188         FLOWEQ0CTL = 0;
189         FLOWEQ1CTL = 0;
190         FLOWHOLDOFF = 0;
191         FLOWSTB = 0;
192         FLOWSTBEDGE = 0;
193         FLOWSTBHPERIOD = 0;
194 }
195
196 void gpif_init_la(void)
197 {
198         /*
199          * Setup the FX2 in GPIF master mode, using the internal clock
200          * (non-inverted) at 48MHz, and using async sampling.
201          */
202         IFCONFIG = 0xee;
203
204         /* Abort currently executing GPIF waveform (if any). */
205         GPIFABORT = 0xff;
206
207         /* Setup the GPIF registers. */
208         gpif_setup_registers();
209
210         /* Write the four GPIF waveforms into the WAVEDATA register. */
211         gpif_write_waveforms();
212
213         /* Initialize GPIF address pins, output initial values. */
214         gpif_init_addr_pins();
215
216         /* Initialize flowstate registers (not used by us). */
217         gpif_init_flowstates();
218 }
219
220 void gpif_acquisition_start(void)
221 {
222         /* Perform the initial GPIF read. */
223         gpif_fifo_read(GPIF_EP2);
224 }