1 /*****************************************************/
2 /*** Module : USB module ***/
3 /*** Author : Roman Bartosinski (C) 28.04.2002 ***/
4 /*** Modify : 08.08.2002, 16.04.2003 ***/
5 /*****************************************************/
10 #include <system_def.h>
12 #if __BYTE_ORDER == __BIG_ENDIAN
16 //#include <usb/pdiusb.h> /* to by tu pak nemelo bejt vubec ... */
18 #include <usb/usbdebug.h>
20 #include <usb/usb_srq.h> /* temporary include - standard control request responses */
23 xdata unsigned char ep0_buffer[ MAX_CONTROL_XFER_DATA_SIZE];
27 int usb_init( usb_device_t *udev) {
29 usb_debug_print( DEBUG_LEVEL_LOW, ("init_usb\r\n"));
30 /* create dynamic fields - endpoints */
34 udev->configuration = 0;
35 //udev->altinterface = 0;
36 udev->ep0.udev = udev;
37 udev->ep0.flags = USB_STATE_IDLE;
40 // usb_init_stdreq_fnc( udev);
42 if ( usb_udev_is_fnc(udev,init)) {
43 ret = usb_udev_init( udev);
49 // connecting to USB by SoftConnect
50 int usb_connect( usb_device_t *udev) {
52 usb_debug_print( DEBUG_LEVEL_LOW,("USB:ON\n"));
56 udev->configuration = 0;
57 //udev->altinterface = 0;
58 udev->ep0.flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
60 if ( usb_udev_is_fnc(udev,connect)) {
61 ret = usb_udev_connect( udev);
67 int usb_disconnect( usb_device_t *udev) {
69 usb_debug_print( DEBUG_LEVEL_LOW,("USB:OFF\n"));
71 udev->flags &= ~USB_FLAG_CONFIGURED;
72 udev->configuration = 0;
74 //udev->altinterface = 0;
75 udev->ep0.flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
77 if ( usb_udev_is_fnc(udev,disconnect)) {
78 ret = usb_udev_disconnect( udev);
84 void usb_stall( usb_ep_t *ep) {
85 usb_debug_print( DEBUG_LEVEL_HIGH, ("USB:STALL %1d\n", ep->epnum));
86 if ( usb_udev_is_fnc(ep->udev,stall)) {
92 int usb_check_events( usb_device_t *udev)
95 if ( usb_udev_is_fnc( udev, check_events)) {
96 ret = usb_udev_check_events( udev);
102 // ************************************
103 // *** Control transfer functions ***
104 // ************************************
106 void usb_complete_control_transfer(usb_ep_t *ep0, int status) {
107 usb_debug_print( DEBUG_LEVEL_HIGH, ( "CCT:st=%d", status));
108 #ifdef USB_WITH_CB_FNC
109 if ( ep0->complete_fnc )
110 ep0->complete_fnc( ep0, status);
111 ep0->next_pkt_fnc = NULL;
112 ep0->complete_fnc = NULL;
113 #endif /*USB_WITH_CB_FNC*/
114 ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
117 /* Send any data in the data phase of the control transfer */
118 void usb_send_control_data( usb_device_t *udev, unsigned char *pData, unsigned short len) {
119 usb_ep_t *ep0 = &(udev->ep0);
120 usb_debug_print( DEBUG_LEVEL_HIGH, ( "SCD:ptr=%p,s=%d\n", pData, len));
124 if ( ep0->size > len) ep0->size = len;
126 /* Schedule TX processing for later execution */
127 ep0->flags = (ep0->flags & ~USB_STATE_MASK) | USB_STATE_TRANSMIT;
128 udev->flags |= USB_FLAG_EVENT_TX0;
131 void usb_set_control_endfnc( usb_device_t *udev, endfnc_t *efnc) { //REENTRANT_SIGN {
132 udev->ep0.efnc = efnc;
135 void usb_ack_setup( usb_ep_t *ep) {
136 usb_udev_ack_setup(ep->udev);
140 /*************************************************************
141 *** Control endpoint0 responses
142 *************************************************************/
143 int usb_control_response( usb_device_t *udev) {
145 usb_ep_t *ep0 = &(udev->ep0);
147 /* response to interrupt BusReset */
148 if ( udev->flags & USB_FLAG_BUS_RESET) {
149 udev->flags &= ~(USB_FLAG_BUS_RESET | USB_FLAG_SUSPEND); // usb_flags.bus_reset = 0; usb_flags.configured = 0;
150 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "USBreset\n"));
153 /* response to interrupt Suspend */
154 if ( udev->flags & USB_FLAG_SUSPEND) {
155 udev->flags &= ~(USB_FLAG_SUSPEND); //usb_flags.suspend = 0;
156 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "USBsuspend\n"));
161 /* response to interrupt SetupPacket execute response to standard device request or vendor request */
162 if ( udev->flags & USB_FLAG_SETUP) {
163 unsigned char type, req;
164 USB_DEVICE_REQUEST *preq = &(udev->request);
170 ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
171 udev->flags &= ~USB_FLAG_SETUP; // usb_flags.setup_packet = 0;
172 #ifdef USB_WITH_CB_FNC
173 ep0->next_pkt_fnc = NULL;
174 ep0->complete_fnc = NULL;
175 #endif /*USB_WITH_CB_FNC*/
177 if ( usb_udev_read_endpoint(ep0, preq, sizeof( USB_DEVICE_REQUEST))
178 != sizeof( USB_DEVICE_REQUEST)) {
179 usb_udev_stall( ep0);
182 #if __BYTE_ORDER == __BIG_ENDIAN
183 preq->wValue = bswap_16( preq->wValue);
184 preq->wIndex = bswap_16( preq->wIndex);
185 preq->wLength = bswap_16( preq->wLength);
187 usb_debug_print( DEBUG_LEVEL_MEDIUM,( "SePa:x%02X,x%02X,x%04X,x%04X,x%04X\n", preq->bmRequestType, preq->bRequest, preq->wValue, preq->wIndex, preq->wLength));
189 // acknowledge setup here
190 if(usb_udev_is_fnc( udev, ack_control_setup)) {
191 usb_udev_ack_control_setup(udev);
194 ep0->size = preq->wLength;
195 if ((( preq->bmRequestType & USB_DATA_DIR_MASK) == USB_DATA_DIR_FROM_HOST) && preq->wLength) {
196 ep0->ptr = ep0_buffer;
197 ep0->flags = (ep0->flags & ~USB_STATE_MASK) | USB_STATE_RECEIVE;
200 type = preq->bmRequestType & USB_REQUEST_TYPE_MASK;
201 req = preq->bRequest & USB_REQUEST_MASK;
202 if ( type == USB_STANDARD_REQUEST) {
204 usb_debug_print( DEBUG_LEVEL_HIGH, ( "StdReq-%d\n", req));
206 if ( (udev->stdreq[ req]) != NULL) {
207 ret = udev->stdreq[ req]( udev);
210 udev->ack_setup( udev);
213 case USB_REQUEST_GET_STATUS: ret=usb_stdreq_get_status( udev); break;
214 case USB_REQUEST_CLEAR_FEATURE: ret=usb_stdreq_clear_feature( udev); break;
215 case USB_REQUEST_SET_FEATURE: ret=usb_stdreq_set_feature( udev); break;
216 case USB_REQUEST_SET_ADDRESS: ret=usb_stdreq_set_address( udev); break;
218 case USB_REQUEST_GET_DESCRIPTOR: ret=usb_stdreq_get_descriptor( udev); break;
219 // case USB_REQUEST_SET_DESCRIPTOR: break;
220 case USB_REQUEST_GET_CONFIGURATION: ret=usb_stdreq_get_configuration( udev); break;
221 case USB_REQUEST_SET_CONFIGURATION: ret=usb_stdreq_set_configuration( udev); break;
222 case USB_REQUEST_GET_INTERFACE: ret=usb_stdreq_get_interface( udev); break;
223 case USB_REQUEST_SET_INTERFACE: ret=usb_stdreq_set_interface( udev); break;
224 // case USB_REQUEST_SYNC_FRAME: break;
225 // default: ret=-1; break;
228 usb_udev_stall( ep0);
230 if ( type == USB_VENDOR_REQUEST) {
232 #ifdef USB_WITH_CB_FNC
234 // if(USBVendorRequestCBFnc != NULL)
235 // ret = USBVendorRequestCBFnc(&usb_ep0, &dreq);
236 if ( udev->vendor_fnc != NULL)
237 ret = udev->vendor_fnc( udev);
239 usb_udev_stall( ep0);
240 // #else /*USB_WITH_CB_FNC*/
241 // if ( USBVendorRequest(&dreq) == -1)
242 // udev->ack_setup( udev);
243 #endif /*USB_WITH_CB_FNC*/
244 } else if ( type == USB_CLASS_REQUEST) {
245 #ifdef USB_WITH_CB_FNC
247 // if(USBClassRequestCBFnc != NULL)
248 // ret = USBClassRequestCBFnc(&usb_ep0, &dreq);
249 if( udev->class_fnc != NULL)
250 ret = udev->class_fnc( udev);
252 usb_udev_stall( ep0);
253 // #else /*USB_WITH_CB_FNC*/
254 // if ( USBClassRequest(&dreq) == -1)
255 // udev->ack_setup( udev);
256 #endif /*USB_WITH_CB_FNC*/
258 usb_udev_stall( ep0);
263 /* response to interrupt Ep0RxInt - receive data */
264 if ( udev->flags & USB_FLAG_EVENT_RX0) {
266 udev->flags &= ~USB_FLAG_EVENT_RX0;
267 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "Ep0Rx\n"));
268 if (( ep0->flags & USB_STATE_MASK) == USB_STATE_RECEIVE) {
269 usb_debug_print( DEBUG_LEVEL_HIGH, ( "RCV:p=%04lX,s=%d\n", (unsigned long)ep0->ptr, ep0->size));
271 i = usb_udev_read_endpoint(ep0, ep0->ptr, ep0->max_packet_size);
275 #ifdef USB_WITH_CB_FNC
276 if ( ep0->next_pkt_fnc ) {
277 if( ep0->next_pkt_fnc( ep0, i, USB_NEXT_PKT_REC) < 0) {
278 usb_udev_stall( ep0);
282 #endif /*USB_WITH_CB_FNC*/
284 if (( i != ep0->max_packet_size) || ( ep0->actual >= ep0->size)) {
285 usb_complete_control_transfer( ep0, USB_COMPLETE_OK );
291 ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
295 /* response to interrupt Ep0TxInt */
296 if ( udev->flags & USB_FLAG_EVENT_TX0) {
297 short i = ep0->size - ep0->actual;
298 udev->flags &= ~USB_FLAG_EVENT_TX0;
299 //usb_debug_print( DEBUG_LEVEL_LOW, ("0S-%d(%d){%d}\n", ep0->state, ep0->size, ep0->max_packet_size));
300 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "EP0Tx:i=%d\n", i));
302 if (( ep0->flags & USB_STATE_MASK) == USB_STATE_TRANSMIT) {
304 if(i > ep0->max_packet_size) i = ep0->max_packet_size;
307 #ifdef USB_WITH_CB_FNC
308 if ( ep0->next_pkt_fnc) {
309 if( ep0->next_pkt_fnc( ep0, i, USB_NEXT_PKT_SEND) < 0) {
310 usb_udev_stall( ep0);
314 #endif /*USB_WITH_CB_FNC*/
315 usb_debug_print( DEBUG_LEVEL_HIGH, ("Wr(%d)\n",i));
316 usb_udev_write_endpoint( ep0, ep0->ptr, i);
320 if( i != ep0->max_packet_size) {
321 /* last packed without full size has been sent, state can change to idle */
322 usb_complete_control_transfer( ep0, USB_COMPLETE_OK );
325 usb_udev_ack_setup( udev); // Send zero packet at the end ???
326 usb_complete_control_transfer( ep0, USB_COMPLETE_OK );