2 * Copyright (C) 2008 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>
33 extern BOOL
handle_vendorcommand(BYTE cmd
);
34 extern BOOL
handle_set_configuration(BYTE cfg
);
35 extern BOOL
handle_get_interface(BYTE ifc
, BYTE
* alt_ifc
);
36 extern BOOL
handle_set_interface(BYTE ifc
,BYTE alt_ifc
);
37 extern BYTE
handle_get_configuration();
38 extern BOOL
handle_set_configuration(BYTE cfg
);
39 extern void handle_reset_ep(BYTE ep
);
42 * Predefs for handlers
47 BOOL
handle_get_status();
49 BOOL
handle_clear_feature();
52 BOOL
handle_set_feature();
54 // SET_ADDRESS=0x05, // this is handled by EZ-USB core unless RENUM=0
56 void handle_get_descriptor();
58 // GET_CONFIGURATION, // handled by callback
59 // SET_CONFIGURATION, // handled by callback
60 // GET_INTERFACE, // handled by callback
61 // SET_INTERFACE, // handled by callback
62 // SYNC_FRAME // not yet implemented
71 void handle_setupdata() {
72 //printf ( "Handle setupdat: %02x\n", SETUPDAT[1] );
74 switch ( SETUPDAT
[1] ) {
77 if (!handle_get_status())
81 if (!handle_clear_feature()) {
86 if (!handle_set_feature()) {
91 handle_get_descriptor();
93 case GET_CONFIGURATION
:
94 EP0BUF
[0] = handle_get_configuration();
98 case SET_CONFIGURATION
:
100 if( !handle_set_configuration(SETUPDAT
[2])) {
107 if (!handle_get_interface(SETUPDAT
[4],&alt_ifc
)) {
118 if ( !handle_set_interface(SETUPDAT
[4],SETUPDAT
[2])) {
123 if (!handle_vendorcommand(SETUPDAT
[1])) {
124 printf ( "Unhandled Vendor Command: %02x\n" , SETUPDAT
[1] );
136 xdata BYTE
* ep_addr(BYTE ep
) { // bit 8 of ep_num is the direction
137 BYTE ep_num
= ep
&~0x80; // mask the direction
139 case 0: return &EP0CS
;
140 case 1: return ep
&0x80? &EP1INCS
: &EP1OUTCS
;
141 case 2: return &EP2CS
;
142 case 4: return &EP4CS
;
143 case 6: return &EP6CS
;
144 case 8: return &EP8CS
;
145 default: return NULL
;
150 // Get status has three request types
151 #define GS_DEVICE 0x80
152 #define GS_INTERFACE 0x81
153 #define GS_ENDPOINT 0x82
156 BOOL
handle_get_status() {
158 switch ( SETUPDAT
[0] ) {
160 case GS_INTERFACE
: // NOTE this falls through only because GS_DEVICE is returning 0
161 // in all cases right now. If Device changes, make this always
162 // return two 0 bytes.
166 // byte 0 bit 0 = self powered bit 1 = remote wakeup
167 EP0BUF
[0] = 0; // currently lib supports neither
175 xdata BYTE
* pep
=ep_addr(SETUPDAT
[4]);
176 if ( !pep
) return FALSE
;
177 // byte 0 bit 0 = stall bit
178 EP0BUF
[0] = *pep
& bmEPSTALL
? 1 : 0;
185 printf ( "Unexpected Get Status: %02x\n", SETUPDAT
[0] );
195 #define GF_ENDPOINT 2
197 BOOL
handle_clear_feature() {
198 //printf ( "Clear Feature\n" );
199 switch ( SETUPDAT
[0] ) {
201 printf ( "(Clear) Remote Wakeup not supported.\n" );
202 STALLEP0(); // not currently supporting remote wakeup
205 if (SETUPDAT
[2] == 0) { // ep stall feature
206 xdata BYTE
* pep
=ep_addr(SETUPDAT
[4]);
207 printf ( "unstall endpoint %02X\n" , SETUPDAT
[4] );
210 printf ( "unsupported ep feature %02x", SETUPDAT
[2] );
211 STALLEP0(); // unsupported feature
215 return handle_vendorcommand(SETUPDAT
[1]);
220 BOOL
handle_set_feature() {
221 printf ( "Set Feature %02x\n", SETUPDAT
[0] );
222 switch ( SETUPDAT
[0] ) {
224 if (SETUPDAT
[2] == 2) break; // this is TEST_MODE and we simply need to return the handshake
225 printf ( "(Set) Remote Wakeup not supported.\n" );
226 return FALSE
;// everything else (remote wakeup) not currently supported
228 if ( SETUPDAT
[2] == 0 ) { // ep stall feature
230 // stall and endpoint
231 xdata BYTE
* pep
= ep_addr(SETUPDAT
[4]);
232 printf ( "Stall ep %d\n", SETUPDAT
[4] );
238 // should now reset data toggles
239 // write ep+dir to TOGCTL
240 RESETTOGGLE(SETUPDAT
[4]);
241 // restore stalled ep to default condition
243 //handle_reset_ep(SETUPDAT[4]);
246 printf ( "unsupported ep feature %02x\n", SETUPDAT
[2] );
251 return handle_vendorcommand(SETUPDAT
[1]);
256 /* these are devined in dscr.asm
257 and need to be customized then
258 linked in by the firmware manually */
259 extern code WORD dev_dscr
;
260 extern code WORD dev_qual_dscr
;
261 extern code WORD highspd_dscr
;
262 extern code WORD fullspd_dscr
;
263 extern code WORD dev_strings
;
265 WORD pDevConfig
= (WORD
)&fullspd_dscr
;
266 WORD pOtherConfig
= (WORD
)&highspd_dscr
;
268 void handle_hispeed() __critical
{
269 printf ( "Hi Speed Interrupt\n" );
270 pDevConfig
=(WORD
)&highspd_dscr
;
271 pOtherConfig
=(WORD
)&fullspd_dscr
;
282 void handle_get_descriptor() {
283 //printf ( "Get Descriptor\n" );
285 switch ( SETUPDAT
[3] ) {
286 case DSCR_DEVICE_TYPE
:
287 printf ( "Get Device Config\n" );
288 SUDPTRH
= MSB((WORD
)&dev_dscr
);
289 SUDPTRL
= LSB((WORD
)&dev_dscr
);
291 case DSCR_CONFIG_TYPE
:
292 // get the config descriptor
293 printf ( "Get Config Descriptor\n");
294 SUDPTRH
= MSB(pDevConfig
);
295 SUDPTRL
= LSB(pDevConfig
);
297 case DSCR_STRING_TYPE
:
298 //printf ( "Get String Descriptor idx: %d\n", SETUPDAT[2] );
300 STRING_DSCR
* pStr
= (STRING_DSCR
*)&dev_strings
;
301 // pStr points to string 0
302 BYTE idx
= SETUPDAT
[2];
303 BYTE cur
=0; // current check
305 if (idx
==cur
++) break;
306 //printf ( "Length of pStr: %d\n", pStr->dsc_len );
307 //printf ( "pstr: %04x to ", pStr );
308 pStr
= (STRING_DSCR
*)((BYTE
*)pStr
+ pStr
->dsc_len
);
309 //printf ( "%04x\n" , pStr );
310 if (pStr
->dsc_type
!= DSCR_STRING_TYPE
) pStr
=NULL
;
311 } while ( pStr
&& cur
<=idx
);
315 //printf ( "found str: '");
316 for (i=0;i<pStr->dsc_len-2;++i) {
317 printf ( i%2==0?"%c":"%02x", *((BYTE*)(&pStr->pstr)+i));
320 SUDPTRH
= MSB((WORD
)pStr
);
321 SUDPTRL
= LSB((WORD
)pStr
);
322 //SUDPTRH = MSB((WORD)&dev_strings);
323 //SUDPTRL = LSB((WORD)&dev_strings);
329 case DSCR_DEVQUAL_TYPE
:
330 printf ( "Get Device Qualifier Descriptor\n");
331 // assumes this is a high speed capable device
332 SUDPTRH
= MSB((WORD
)&dev_qual_dscr
);
333 SUDPTRL
= LSB((WORD
)&dev_qual_dscr
);
336 printf ( "Unhandled Get Descriptor: %02x\n", SETUPDAT
[3]);