]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blame - fx2lib/lib/gpif.c
Add Hantek PSO2020 firmware support
[sigrok-firmware-fx2lafw.git] / fx2lib / lib / gpif.c
CommitLineData
3608c106
UH
1/**
2 * Copyright (C) 2009 Ubixum, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
040a6eae 15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
3608c106
UH
16 **/
17
18
19#include <fx2regs.h>
20#include <fx2macros.h>
21#include <delay.h>
22
23#include <gpif.h>
24
25#define SYNCDELAY() SYNCDELAY4
26
27void gpif_init( BYTE* wavedata, BYTE* initdata ) {
28
29 BYTE i;
30
31 // Registers which require a synchronization delay, see section 15.14
32 // FIFORESET FIFOPINPOLAR
33 // INPKTEND OUTPKTEND
34 // EPxBCH:L REVCTL
35 // GPIFTCB3 GPIFTCB2
36 // GPIFTCB1 GPIFTCB0
37 // EPxFIFOPFH:L EPxAUTOINLENH:L
38 // EPxFIFOCFG EPxGPIFFLGSEL
39 // PINFLAGSxx EPxFIFOIRQ
40 // EPxFIFOIE GPIFIRQ
41 // GPIFIE GPIFADRH:L
42 // UDMACRCH:L EPxGPIFTRIG
43 // GPIFTRIG
44
45 // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
46 // ...these have been replaced by GPIFTC[B3:B0] registers
47
48 // 8051 doesn't have access to waveform memories 'til
49 // the part is in GPIF mode.
50
51 // IFCLKSRC=1 , FIFOs executes on internal clk source
52 // xMHz=1 , 48MHz internal clk rate
53 // IFCLKOE=0 , Don't drive IFCLK pin signal at 48MHz
54 // IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk
55 // ASYNC=1 , master samples asynchronous
56 // GSTATE=1 , Drive GPIF states out on PORTE[2:0], debug WF
57 // IFCFG[1:0]=10, FX2 in GPIF master mode IFCONFIG
58 IFCONFIG &= ~0x03; // turn off IFCFG[1:0]
59 IFCONFIG |= 0x02; // set's IFCFG[1:0] to 10 to put in GPIF master mode.
60
61
62 GPIFABORT = 0xFF; // abort any waveforms pending
63
64 GPIFREADYCFG = initdata[ 0 ];
65 GPIFCTLCFG = initdata[ 1 ];
66 GPIFIDLECS = initdata[ 2 ];
67 GPIFIDLECTL = initdata[ 3 ];
68 GPIFWFSELECT = initdata[ 5 ];
69 GPIFREADYSTAT = initdata[ 6 ];
70
71 // use dual autopointer feature...
72 AUTOPTRSETUP = 0x07; // inc both pointers,
73 // ...warning: this introduces pdata hole(s)
74 // ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
75
76 // source
77 AUTOPTRH1 = MSB( (WORD)wavedata );
78 AUTOPTRL1 = LSB( (WORD)wavedata );
79
80 // destination
81 AUTOPTRH2 = 0xE4;
82 AUTOPTRL2 = 0x00;
83
84 // transfer
85 for ( i = 0x00; i < 128; i++ )
86 {
87 EXTAUTODAT2 = EXTAUTODAT1;
88 }
89
90// Configure GPIF Address pins, output initial value,
91// these instructions don't do anything on the
92// smaller chips (e.g., 56 pin model only has ports a,b,d)
93 PORTCCFG = 0xFF; // [7:0] as alt. func. GPIFADR[7:0]
94 OEC = 0xFF; // and as outputs
95 PORTECFG |= 0x80; // [8] as alt. func. GPIFADR[8]
96 OEE |= 0x80; // and as output
97
98// ...OR... tri-state GPIFADR[8:0] pins
99// PORTCCFG = 0x00; // [7:0] as port I/O
100// OEC = 0x00; // and as inputs
101// PORTECFG &= 0x7F; // [8] as port I/O
102// OEE &= 0x7F; // and as input
103
104// GPIF address pins update when GPIFADRH/L written
105 SYNCDELAY(); //
106 GPIFADRH = 0x00; // bits[7:1] always 0
107 SYNCDELAY(); //
108 GPIFADRL = 0x00; // point to PERIPHERAL address 0x0000
109
110// set the initial flowstates to be all 0 in case flow states are not used
111
112 FLOWSTATE = 0;
113 FLOWLOGIC = 0;
114 FLOWEQ0CTL = 0;
115 FLOWEQ1CTL = 0;
116 FLOWHOLDOFF = 0;
117 FLOWSTB = 0;
118 FLOWSTBEDGE = 0;
119 FLOWSTBHPERIOD = 0;
120}
121
122void gpif_setflowstate( BYTE* flowstates, BYTE bank) {
123 BYTE base = 9*bank;
124 FLOWSTATE = flowstates[ base ];
125 FLOWLOGIC = flowstates[ base+1 ];
126 FLOWEQ0CTL = flowstates[ base+2 ];
127 FLOWEQ1CTL = flowstates[ base+3 ];
128 FLOWHOLDOFF = flowstates[ base+4 ];
129 FLOWSTB = flowstates[ base+5 ];
130 FLOWSTBEDGE = flowstates[ base+6 ];
131 FLOWSTBHPERIOD = flowstates[ base+7 ];
132}
133
134void gpif_set_tc32(DWORD tc) {
135 GPIFTCB3 = MSB(MSW(tc));
136 SYNCDELAY();
137 GPIFTCB2 = LSB(MSW(tc));
138 SYNCDELAY();
139 GPIFTCB1 = MSB(LSW(tc));
140 SYNCDELAY();
141 GPIFTCB0 = LSB(LSW(tc));
142}
143void gpif_set_tc16(WORD tc) {
144 GPIFTCB1= MSB(tc);
145 SYNCDELAY();
146 GPIFTCB0= LSB(tc);
147}
148
149
150void gpif_single_read16( WORD* res, WORD len ){
151 BYTE c;
152 while (!(GPIFTRIG & 0x80)); // wait done
153 // dummy read to trigger real read
154 res[0] = XGPIFSGLDATLX;
155 for (c=0;c<len;++c) {
156 while ( !(GPIFTRIG & 0x80) ); // wait done
157 // real read
158 res[c] = GPIFSGLDATH << 8;
159 // whether or not to do another transfer is controlled by GPIFSGLDATLNOX or ..DATLX
160 res[c] |= c==len-1 ? GPIFSGLDATLNOX : GPIFSGLDATLX ;
161 }
162}
163
164void gpif_single_write16( WORD* dat, WORD len) {
165 BYTE c;
166 for (c=0;c<len;++c) {
167 while (!(GPIFTRIG & 0x80) );
168 XGPIFSGLDATH = MSB(dat[c]);
169 XGPIFSGLDATLX = LSB(dat[c]);
170 }
171}
172
173void gpif_fifo_read ( GPIF_EP_NUM ep_num ) {
174 while ( !(GPIFTRIG & 0x80 ) ); // wait until things are finished
175 GPIFTRIG = GPIFTRGRD | ep_num;
176}
177
178void gpif_fifo_write ( GPIF_EP_NUM ep_num ) {
179 while ( !(GPIFTRIG & 0x80) ); // wait until things are finished
180 GPIFTRIG = ep_num; // R/W=0, E[1:0] = ep_num
181}