]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blob - fx2lib/examples/bulkloop/bulkloop.c
Import fx2lib into fx2lafw directly.
[sigrok-firmware-fx2lafw.git] / fx2lib / examples / bulkloop / bulkloop.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 #include <stdio.h>
19
20 #include <fx2regs.h>
21 #include <fx2macros.h>
22 #include <serial.h>
23 #include <delay.h>
24 #include <autovector.h>
25 #include <lights.h>
26 #include <setupdat.h>
27 #include <eputils.h>
28
29
30 #define SYNCDELAY() SYNCDELAY4
31 #define REARMVAL 0x80
32 #define REARM() EP2BCL=REARMVAL
33
34
35
36 volatile WORD bytes;
37 volatile bit gotbuf;
38 volatile BYTE icount;
39 volatile bit got_sud;
40 DWORD lcount;
41 bit on;
42
43 void main() {
44
45  REVCTL=0; // not using advanced endpoint controls
46
47  d2off();
48  on=0;
49  lcount=0;
50  got_sud=FALSE;
51  icount=0;
52  gotbuf=FALSE;
53  bytes=0;
54
55  // renumerate
56  RENUMERATE_UNCOND(); 
57  
58
59  SETCPUFREQ(CLK_48M);
60  SETIF48MHZ();
61  sio0_init(57600);
62  
63  
64  USE_USB_INTS(); 
65  ENABLE_SUDAV();
66  ENABLE_SOF();
67  ENABLE_HISPEED();
68  ENABLE_USBRESET();
69  
70  
71  // only valid endpoints are 2/6
72  EP2CFG = 0xA2; // 10100010
73  SYNCDELAY();
74  EP6CFG = 0xE2; // 11100010 
75  SYNCDELAY();
76  EP1INCFG &= ~bmVALID;
77  SYNCDELAY();
78  EP1OUTCFG &= ~bmVALID;
79  SYNCDELAY();
80  EP4CFG &= ~bmVALID;
81  SYNCDELAY();
82  EP8CFG &= ~bmVALID;
83  SYNCDELAY(); 
84  
85  
86  // arm ep2
87  EP2BCL = 0x80; // write once
88  SYNCDELAY();
89  EP2BCL = 0x80; // do it again
90
91  
92  // make it so we enumberate
93  
94
95  EA=1; // global interrupt enable 
96  printf ( "Done initializing stuff\n" );
97
98  
99  d3off();
100  
101  while(TRUE) {
102  
103   if ( got_sud ) {
104       printf ( "Handle setupdata\n" );
105       handle_setupdata(); 
106       got_sud=FALSE;
107   }
108
109   if ( !(EP2468STAT & bmEP2EMPTY) ) {
110        printf ( "ep2 out received data\n" );
111       if  ( !(EP2468STAT & bmEP6FULL) ) { // wait for at least one empty in buffer
112                  WORD i;
113                  printf ( "Sending data to ep6 in\n");
114     
115                  bytes = MAKEWORD(EP2BCH,EP2BCL);
116                  
117                  for (i=0;i<bytes;++i) EP6FIFOBUF[i] = EP2FIFOBUF[i];
118                  
119                  // can copy whole string w/ autoptr instead.
120                  // or copy directly from one buf to another
121
122                  // ARM ep6 out
123                  EP6BCH=MSB(bytes);
124                  SYNCDELAY();
125                  EP6BCL=LSB(bytes); 
126
127                  REARM(); // ep2
128                  //printf ( "Re-Armed ep2\n" );
129
130          }
131    }
132  }
133
134 }
135
136 // copied routines from setupdat.h
137
138 // value (low byte) = ep
139 #define VC_EPSTAT 0xB1
140
141 BOOL handle_vendorcommand(BYTE cmd) {
142
143  switch ( cmd ) {
144  
145      case VC_EPSTAT:
146         {         
147          xdata BYTE* pep= ep_addr(SETUPDAT[2]);
148          printf ( "ep %02x\n" , *pep );
149          if (pep) {
150           EP0BUF[0] = *pep;
151           EP0BCH=0;
152           EP0BCL=1;
153           return TRUE;
154          } 
155         }
156      default:
157           printf ( "Need to implement vendor command: %02x\n", cmd );
158  }
159  return FALSE;
160 }
161
162 // this firmware only supports 0,0
163 BOOL handle_get_interface(BYTE ifc, BYTE* alt_ifc) { 
164  printf ( "Get Interface\n" );
165  if (ifc==0) {*alt_ifc=0; return TRUE;} else { return FALSE;}
166 }
167 BOOL handle_set_interface(BYTE ifc, BYTE alt_ifc) { 
168  printf ( "Set interface %d to alt: %d\n" , ifc, alt_ifc );
169  
170  if (ifc==0&&alt_ifc==0) {
171     // SEE TRM 2.3.7
172     // reset toggles
173     RESETTOGGLE(0x02);
174     RESETTOGGLE(0x86);
175     // restore endpoints to default condition
176     RESETFIFO(0x02);
177     EP2BCL=0x80;
178     SYNCDELAY();
179     EP2BCL=0X80;
180     SYNCDELAY();
181     RESETFIFO(0x86);
182     return TRUE;
183  } else 
184     return FALSE;
185 }
186
187 // get/set configuration
188 BYTE handle_get_configuration() {
189  return 1; 
190  }
191 BOOL handle_set_configuration(BYTE cfg) { 
192  return cfg==1 ? TRUE : FALSE; // we only handle cfg 1
193 }
194
195
196 // copied usb jt routines from usbjt.h
197 void sudav_isr() interrupt SUDAV_ISR {
198   
199   got_sud=TRUE;
200   CLEAR_SUDAV();
201 }
202
203 bit on5;
204 xdata WORD sofct=0;
205 void sof_isr () interrupt SOF_ISR using 1 {
206     ++sofct;
207     if(sofct==8000) { // about 8000 sof interrupts per second at high speed
208         on5=!on5;
209         if (on5) {d5on();} else {d5off();}
210         sofct=0;
211     }
212     CLEAR_SOF();
213 }
214
215 void usbreset_isr() interrupt USBRESET_ISR {
216     handle_hispeed(FALSE);
217     CLEAR_USBRESET();
218 }
219 void hispeed_isr() interrupt HISPEED_ISR {
220     handle_hispeed(TRUE);
221     CLEAR_HISPEED();
222 }
223