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_get_descriptor(void);
35 extern BOOL
handle_vendorcommand(BYTE cmd
);
36 extern BOOL
handle_set_configuration(BYTE cfg
);
37 extern BOOL
handle_get_interface(BYTE ifc
, BYTE
* alt_ifc
);
38 extern BOOL
handle_set_interface(BYTE ifc
,BYTE alt_ifc
);
39 extern BYTE
handle_get_configuration(void);
40 extern void handle_reset_ep(BYTE ep
);
43 * Predefs for handlers
48 BOOL
handle_get_status(void);
50 BOOL
handle_clear_feature(void);
53 BOOL
handle_set_feature(void);
55 // SET_ADDRESS=0x05, // this is handled by EZ-USB core unless RENUM=0
57 void _handle_get_descriptor(void);
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(void) {
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 if (!handle_get_descriptor())
93 _handle_get_descriptor();
95 case GET_CONFIGURATION
:
96 EP0BUF
[0] = handle_get_configuration();
100 case SET_CONFIGURATION
:
102 if( !handle_set_configuration(SETUPDAT
[2])) {
109 if (!handle_get_interface(SETUPDAT
[4],&alt_ifc
)) {
120 if ( !handle_set_interface(SETUPDAT
[4],SETUPDAT
[2])) {
125 if (!handle_vendorcommand(SETUPDAT
[1])) {
126 printf ( "Unhandled Vendor Command: %02x\n" , SETUPDAT
[1] );
138 __xdata BYTE
* ep_addr(BYTE ep
) { // bit 8 of ep_num is the direction
139 BYTE ep_num
= ep
&~0x80; // mask the direction
141 case 0: return &EP0CS
;
142 case 1: return ep
&0x80? &EP1INCS
: &EP1OUTCS
;
143 case 2: return &EP2CS
;
144 case 4: return &EP4CS
;
145 case 6: return &EP6CS
;
146 case 8: return &EP8CS
;
147 default: return NULL
;
152 // Get status has three request types
153 #define GS_DEVICE 0x80
154 #define GS_INTERFACE 0x81
155 #define GS_ENDPOINT 0x82
158 volatile BOOL self_powered
=FALSE
;
159 volatile BOOL remote_wakeup_allowed
=FALSE
;
161 BOOL
handle_get_status(void) {
163 switch ( SETUPDAT
[0] ) {
165 // case 0: // sometimes we get a 0 status too
175 // byte 0 bit 0 = self powered bit 1 = remote wakeup
176 EP0BUF
[0] = (remote_wakeup_allowed
<< 1) | self_powered
;
184 __xdata BYTE
* pep
=ep_addr(SETUPDAT
[4]);
185 if ( !pep
) return FALSE
;
186 // byte 0 bit 0 = stall bit
187 EP0BUF
[0] = *pep
& bmEPSTALL
? 1 : 0;
194 printf ( "Unexpected Get Status: %02x\n", SETUPDAT
[0] );
204 #define GF_ENDPOINT 2
206 BOOL
handle_clear_feature(void) {
207 //printf ( "Clear Feature\n" );
208 switch ( SETUPDAT
[0] ) {
210 if (SETUPDAT
[2] == 1) {
211 remote_wakeup_allowed
=FALSE
;
215 if (SETUPDAT
[2] == 6) // debug feature
219 if (SETUPDAT
[2] == 0) { // ep stall feature
220 __xdata BYTE
* pep
=ep_addr(SETUPDAT
[4]);
221 printf ( "unstall endpoint %02X\n" , SETUPDAT
[4] );
223 RESETTOGGLE(SETUPDAT
[4]);
225 printf ( "unsupported ep feature %02x", SETUPDAT
[2] );
231 return handle_vendorcommand(SETUPDAT
[1]);
236 BOOL
handle_set_feature(void) {
237 printf ( "Set Feature %02x\n", SETUPDAT
[0] );
238 switch ( SETUPDAT
[0] ) {
240 if (SETUPDAT
[2] == 2) break; // this is TEST_MODE and we simply need to return the handshake
241 if (SETUPDAT
[2] == 1) {
242 remote_wakeup_allowed
=TRUE
;
245 if (SETUPDAT
[2] == 6) // debug feature
249 if ( SETUPDAT
[2] == 0 ) { // ep stall feature
251 // stall and endpoint
252 __xdata BYTE
* pep
= ep_addr(SETUPDAT
[4]);
253 printf ( "Stall ep %d\n", SETUPDAT
[4] );
259 // should now reset data toggles
260 // write ep+dir to TOGCTL
261 RESETTOGGLE(SETUPDAT
[4]);
262 // restore stalled ep to default condition
264 //handle_reset_ep(SETUPDAT[4]);
267 printf ( "unsupported ep feature %02x\n", SETUPDAT
[2] );
272 return handle_vendorcommand(SETUPDAT
[1]);
277 /* these are devined in dscr.asm
278 and need to be customized then
279 linked in by the firmware manually */
280 extern __code WORD dev_dscr
;
281 extern __code WORD dev_qual_dscr
;
282 extern __code WORD highspd_dscr
;
283 extern __code WORD fullspd_dscr
;
284 extern __code WORD dev_strings
;
286 WORD pDevConfig
= (WORD
)&fullspd_dscr
;
287 WORD pOtherConfig
= (WORD
)&highspd_dscr
;
289 void handle_hispeed(BOOL highspeed
) {
291 printf ( "Hi Speed or reset Interrupt\n" );
293 pDevConfig
=(WORD
)&highspd_dscr
;
294 pOtherConfig
=(WORD
)&fullspd_dscr
;
296 pDevConfig
=(WORD
)&fullspd_dscr
;
297 pOtherConfig
=(WORD
)&highspd_dscr
;
310 void _handle_get_descriptor(void) {
311 //printf ( "Get Descriptor\n" );
313 switch ( SETUPDAT
[3] ) {
314 case DSCR_DEVICE_TYPE
:
315 printf ( "Get Device Config\n" );
316 SUDPTRH
= MSB((WORD
)&dev_dscr
);
317 SUDPTRL
= LSB((WORD
)&dev_dscr
);
319 case DSCR_CONFIG_TYPE
:
320 // get the config descriptor
321 printf ( "Get Config Descriptor\n");
322 SUDPTRH
= MSB(pDevConfig
);
323 SUDPTRL
= LSB(pDevConfig
);
325 case DSCR_STRING_TYPE
:
326 //printf ( "Get String Descriptor idx: %d\n", SETUPDAT[2] );
328 STRING_DSCR
* pStr
= (STRING_DSCR
*)&dev_strings
;
329 // pStr points to string 0
330 BYTE idx
= SETUPDAT
[2];
331 BYTE cur
=0; // current check
333 if (idx
==cur
++) break;
334 //printf ( "Length of pStr: %d\n", pStr->dsc_len );
335 //printf ( "pstr: %04x to ", pStr );
336 pStr
= (STRING_DSCR
*)((BYTE
*)pStr
+ pStr
->dsc_len
);
337 //printf ( "%04x\n" , pStr );
338 if (pStr
->dsc_type
!= DSCR_STRING_TYPE
) pStr
=NULL
;
339 } while ( pStr
&& cur
<=idx
);
343 //printf ( "found str: '");
344 for (i=0;i<pStr->dsc_len-2;++i) {
345 printf ( i%2==0?"%c":"%02x", *((BYTE*)(&pStr->pstr)+i));
348 SUDPTRH
= MSB((WORD
)pStr
);
349 SUDPTRL
= LSB((WORD
)pStr
);
350 //SUDPTRH = MSB((WORD)&dev_strings);
351 //SUDPTRL = LSB((WORD)&dev_strings);
357 case DSCR_DEVQUAL_TYPE
:
358 printf ( "Get Device Qualifier Descriptor\n");
359 // assumes this is a high speed capable device
360 SUDPTRH
= MSB((WORD
)&dev_qual_dscr
);
361 SUDPTRL
= LSB((WORD
)&dev_qual_dscr
);
363 case DSCR_OTHERSPD_TYPE
:
364 printf ( "Other Speed Descriptor\n");
365 SUDPTRH
= MSB(pOtherConfig
);
366 SUDPTRL
= LSB(pOtherConfig
);
369 printf ( "Unhandled Get Descriptor: %02x\n", SETUPDAT
[3]);