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