2 * Copyright (C) 2009 Ubixum, Inc.
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.
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.
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
19 //#define DEBUG_SETUPDAT
22 #include <stdio.h> // NOTE this needs deleted
25 #define NULL (void*)0;
29 #include <fx2macros.h>
34 extern BOOL handle_vendorcommand(BYTE cmd);
35 extern BOOL handle_set_configuration(BYTE cfg);
36 extern BOOL handle_get_interface(BYTE ifc, BYTE* alt_ifc);
37 extern BOOL handle_set_interface(BYTE ifc,BYTE alt_ifc);
38 extern BYTE handle_get_configuration();
39 extern BOOL handle_set_configuration(BYTE cfg);
40 extern void handle_reset_ep(BYTE ep);
43 * Predefs for handlers
48 BOOL handle_get_status();
50 BOOL handle_clear_feature();
53 BOOL handle_set_feature();
55 // SET_ADDRESS=0x05, // this is handled by EZ-USB core unless RENUM=0
57 void handle_get_descriptor();
59 // GET_CONFIGURATION, // handled by callback
60 // SET_CONFIGURATION, // handled by callback
61 // GET_INTERFACE, // handled by callback
62 // SET_INTERFACE, // handled by callback
63 // SYNC_FRAME // not yet implemented
72 void handle_setupdata() {
73 //printf ( "Handle setupdat: %02x\n", SETUPDAT[1] );
75 switch ( SETUPDAT[1] ) {
78 if (!handle_get_status())
82 if (!handle_clear_feature()) {
87 if (!handle_set_feature()) {
92 handle_get_descriptor();
94 case GET_CONFIGURATION:
95 EP0BUF[0] = handle_get_configuration();
99 case SET_CONFIGURATION:
101 if( !handle_set_configuration(SETUPDAT[2])) {
108 if (!handle_get_interface(SETUPDAT[4],&alt_ifc)) {
119 if ( !handle_set_interface(SETUPDAT[4],SETUPDAT[2])) {
124 if (!handle_vendorcommand(SETUPDAT[1])) {
125 printf ( "Unhandled Vendor Command: %02x\n" , SETUPDAT[1] );
137 __xdata BYTE* ep_addr(BYTE ep) { // bit 8 of ep_num is the direction
138 BYTE ep_num = ep&~0x80; // mask the direction
140 case 0: return &EP0CS;
141 case 1: return ep&0x80? &EP1INCS : &EP1OUTCS;
142 case 2: return &EP2CS;
143 case 4: return &EP4CS;
144 case 6: return &EP6CS;
145 case 8: return &EP8CS;
146 default: return NULL;
151 // Get status has three request types
152 #define GS_DEVICE 0x80
153 #define GS_INTERFACE 0x81
154 #define GS_ENDPOINT 0x82
157 volatile BOOL self_powered=FALSE;
158 volatile BOOL remote_wakeup_allowed=FALSE;
160 BOOL handle_get_status() {
162 switch ( SETUPDAT[0] ) {
164 // case 0: // sometimes we get a 0 status too
174 // byte 0 bit 0 = self powered bit 1 = remote wakeup
175 EP0BUF[0] = (remote_wakeup_allowed << 1) | self_powered;
183 __xdata BYTE* pep=ep_addr(SETUPDAT[4]);
184 if ( !pep ) return FALSE;
185 // byte 0 bit 0 = stall bit
186 EP0BUF[0] = *pep & bmEPSTALL ? 1 : 0;
193 printf ( "Unexpected Get Status: %02x\n", SETUPDAT[0] );
203 #define GF_ENDPOINT 2
205 BOOL handle_clear_feature() {
206 //printf ( "Clear Feature\n" );
207 switch ( SETUPDAT[0] ) {
209 if (SETUPDAT[2] == 1) {
210 remote_wakeup_allowed=FALSE;
215 if (SETUPDAT[2] == 0) { // ep stall feature
216 __xdata BYTE* pep=ep_addr(SETUPDAT[4]);
217 printf ( "unstall endpoint %02X\n" , SETUPDAT[4] );
220 printf ( "unsupported ep feature %02x", SETUPDAT[2] );
226 return handle_vendorcommand(SETUPDAT[1]);
231 BOOL handle_set_feature() {
232 printf ( "Set Feature %02x\n", SETUPDAT[0] );
233 switch ( SETUPDAT[0] ) {
235 if (SETUPDAT[2] == 2) break; // this is TEST_MODE and we simply need to return the handshake
236 if (SETUPDAT[2] == 1) {
237 remote_wakeup_allowed=TRUE;
242 if ( SETUPDAT[2] == 0 ) { // ep stall feature
244 // stall and endpoint
245 __xdata BYTE* pep = ep_addr(SETUPDAT[4]);
246 printf ( "Stall ep %d\n", SETUPDAT[4] );
252 // should now reset data toggles
253 // write ep+dir to TOGCTL
254 RESETTOGGLE(SETUPDAT[4]);
255 // restore stalled ep to default condition
257 //handle_reset_ep(SETUPDAT[4]);
260 printf ( "unsupported ep feature %02x\n", SETUPDAT[2] );
265 return handle_vendorcommand(SETUPDAT[1]);
270 /* these are devined in dscr.asm
271 and need to be customized then
272 linked in by the firmware manually */
273 extern __code WORD dev_dscr;
274 extern __code WORD dev_qual_dscr;
275 extern __code WORD highspd_dscr;
276 extern __code WORD fullspd_dscr;
277 extern __code WORD dev_strings;
279 WORD pDevConfig = (WORD)&fullspd_dscr;
280 WORD pOtherConfig = (WORD)&highspd_dscr;
282 void handle_hispeed(BOOL highspeed) {
284 printf ( "Hi Speed or reset Interrupt\n" );
286 pDevConfig=(WORD)&highspd_dscr;
287 pOtherConfig=(WORD)&fullspd_dscr;
289 pDevConfig=(WORD)&fullspd_dscr;
290 pOtherConfig=(WORD)&highspd_dscr;
303 void handle_get_descriptor() {
304 //printf ( "Get Descriptor\n" );
306 switch ( SETUPDAT[3] ) {
307 case DSCR_DEVICE_TYPE:
308 printf ( "Get Device Config\n" );
309 SUDPTRH = MSB((WORD)&dev_dscr);
310 SUDPTRL = LSB((WORD)&dev_dscr);
312 case DSCR_CONFIG_TYPE:
313 // get the config descriptor
314 printf ( "Get Config Descriptor\n");
315 SUDPTRH = MSB(pDevConfig);
316 SUDPTRL = LSB(pDevConfig);
318 case DSCR_STRING_TYPE:
319 //printf ( "Get String Descriptor idx: %d\n", SETUPDAT[2] );
321 STRING_DSCR* pStr = (STRING_DSCR*)&dev_strings;
322 // pStr points to string 0
323 BYTE idx = SETUPDAT[2];
324 BYTE cur=0; // current check
326 if (idx==cur++) break;
327 //printf ( "Length of pStr: %d\n", pStr->dsc_len );
328 //printf ( "pstr: %04x to ", pStr );
329 pStr = (STRING_DSCR*)((BYTE*)pStr + pStr->dsc_len);
330 //printf ( "%04x\n" , pStr );
331 if (pStr->dsc_type != DSCR_STRING_TYPE) pStr=NULL;
332 } while ( pStr && cur<=idx);
336 //printf ( "found str: '");
337 for (i=0;i<pStr->dsc_len-2;++i) {
338 printf ( i%2==0?"%c":"%02x", *((BYTE*)(&pStr->pstr)+i));
341 SUDPTRH = MSB((WORD)pStr);
342 SUDPTRL = LSB((WORD)pStr);
343 //SUDPTRH = MSB((WORD)&dev_strings);
344 //SUDPTRL = LSB((WORD)&dev_strings);
350 case DSCR_DEVQUAL_TYPE:
351 printf ( "Get Device Qualifier Descriptor\n");
352 // assumes this is a high speed capable device
353 SUDPTRH = MSB((WORD)&dev_qual_dscr);
354 SUDPTRL = LSB((WORD)&dev_qual_dscr);
356 case DSCR_OTHERSPD_TYPE:
357 printf ( "Other Speed Descriptor\n");
358 SUDPTRH = MSB(pOtherConfig);
359 SUDPTRL = LSB(pOtherConfig);
362 printf ( "Unhandled Get Descriptor: %02x\n", SETUPDAT[3]);