]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blob - fx2lib/lib/gpif.c
Add Hantek PSO2020 firmware support
[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, see <http://www.gnu.org/licenses/>.
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
27 void 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
122 void 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
134 void 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 }
143 void gpif_set_tc16(WORD tc) {
144     GPIFTCB1= MSB(tc);
145     SYNCDELAY();
146     GPIFTCB0= LSB(tc);
147 }
148
149
150 void 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
164 void 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
173 void gpif_fifo_read ( GPIF_EP_NUM ep_num ) {
174     while ( !(GPIFTRIG & 0x80 ) ); // wait until things are finished
175     GPIFTRIG = GPIFTRGRD | ep_num;
176 }
177
178 void 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 }