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>
21 __xdata unsigned char ep0_buffer[ MAX_CONTROL_XFER_DATA_SIZE];
25 int usb_init( usb_device_t *udev) {
27 usb_debug_print( DEBUG_LEVEL_LOW, ("init_usb\r\n"));
28 /* create dynamic fields - endpoints */
32 udev->configuration = 0;
33 //udev->altinterface = 0;
34 udev->ep0.udev = udev;
35 udev->ep0.flags = USB_STATE_IDLE;
38 // usb_init_stdreq_fnc( udev);
40 if ( usb_udev_is_fnc(udev,init)) {
41 ret = usb_udev_init( udev);
47 // connecting to USB by SoftConnect
48 int usb_connect( usb_device_t *udev) {
50 usb_debug_print( DEBUG_LEVEL_LOW,("USB:ON\n"));
54 udev->configuration = 0;
55 //udev->altinterface = 0;
56 udev->ep0.flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
58 if ( usb_udev_is_fnc(udev,connect)) {
59 ret = usb_udev_connect( udev);
65 int usb_disconnect( usb_device_t *udev) {
67 usb_debug_print( DEBUG_LEVEL_LOW,("USB:OFF\n"));
69 udev->flags &= ~USB_FLAG_CONFIGURED;
70 udev->configuration = 0;
72 //udev->altinterface = 0;
73 udev->ep0.flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
75 if ( usb_udev_is_fnc(udev,disconnect)) {
76 ret = usb_udev_disconnect( udev);
82 void usb_stall( usb_ep_t *ep) {
83 usb_debug_print( DEBUG_LEVEL_HIGH, ("USB:STALL %1d\n", ep->epnum));
84 if ( usb_udev_is_fnc(ep->udev,stall)) {
90 int usb_check_events( usb_device_t *udev)
93 if ( usb_udev_is_fnc( udev, check_events)) {
94 ret = usb_udev_check_events( udev);
100 // ************************************
101 // *** Control transfer functions ***
102 // ************************************
104 void usb_complete_control_transfer(usb_ep_t *ep0, int status) {
105 usb_debug_print( DEBUG_LEVEL_HIGH, ( "CCT:st=%d", status));
106 #ifdef USB_WITH_CB_FNC
107 if ( ep0->complete_fnc )
108 ep0->complete_fnc( ep0, status);
109 ep0->next_pkt_fnc = NULL;
110 ep0->complete_fnc = NULL;
111 #endif /*USB_WITH_CB_FNC*/
112 ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
115 /* Send any data in the data phase of the control transfer */
116 void usb_send_control_data( usb_device_t *udev, unsigned char *pData, unsigned short len) {
117 usb_ep_t *ep0 = &(udev->ep0);
118 usb_debug_print( DEBUG_LEVEL_HIGH, ( "SCD:ptr=%p,s=%d\n", pData, len));
122 if ( ep0->size > len) ep0->size = len;
124 /* Schedule TX processing for later execution */
125 ep0->flags = (ep0->flags & ~USB_STATE_MASK) | USB_STATE_TRANSMIT;
126 udev->flags |= USB_FLAG_EVENT_TX0;
129 void usb_set_control_endfnc( usb_device_t *udev, endfnc_t *efnc) { //REENTRANT_SIGN {
130 udev->ep0.efnc = efnc;
133 void usb_ack_setup( usb_ep_t *ep) {
134 usb_udev_ack_setup(ep->udev);
138 /*************************************************************
139 *** Control endpoint0 responses
140 *************************************************************/
141 int usb_control_response( usb_device_t *udev) {
143 usb_ep_t *ep0 = &(udev->ep0);
145 /* response to interrupt BusReset */
146 if ( udev->flags & USB_FLAG_BUS_RESET) {
147 udev->flags &= ~(USB_FLAG_BUS_RESET | USB_FLAG_SUSPEND); // usb_flags.bus_reset = 0; usb_flags.configured = 0;
148 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "USBreset\n"));
151 /* response to interrupt Suspend */
152 if ( udev->flags & USB_FLAG_SUSPEND) {
153 udev->flags &= ~(USB_FLAG_SUSPEND); //usb_flags.suspend = 0;
154 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "USBsuspend\n"));
159 /* response to interrupt SetupPacket execute response to standard device request or vendor request */
160 if ( udev->flags & USB_FLAG_SETUP) {
162 USB_DEVICE_REQUEST *preq = &(udev->request);
168 ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
169 udev->flags &= ~USB_FLAG_SETUP; // usb_flags.setup_packet = 0;
170 #ifdef USB_WITH_CB_FNC
171 ep0->next_pkt_fnc = NULL;
172 ep0->complete_fnc = NULL;
173 #endif /*USB_WITH_CB_FNC*/
175 if ( usb_udev_read_endpoint(ep0, preq, sizeof( USB_DEVICE_REQUEST))
176 != sizeof( USB_DEVICE_REQUEST)) {
177 usb_udev_stall( ep0);
180 #if __BYTE_ORDER == __BIG_ENDIAN
181 preq->wValue = bswap_16( preq->wValue);
182 preq->wIndex = bswap_16( preq->wIndex);
183 preq->wLength = bswap_16( preq->wLength);
185 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));
187 // acknowledge setup here
188 if(usb_udev_is_fnc( udev, ack_control_setup)) {
189 usb_udev_ack_control_setup(udev);
192 ep0->size = preq->wLength;
193 if ((( preq->bmRequestType & USB_DATA_DIR_MASK) == USB_DATA_DIR_FROM_HOST) && preq->wLength) {
194 ep0->ptr = ep0_buffer;
195 ep0->flags = (ep0->flags & ~USB_STATE_MASK) | USB_STATE_RECEIVE;
198 type = preq->bmRequestType & USB_REQUEST_TYPE_MASK;
199 if ( type == USB_STANDARD_REQUEST) {
201 #ifdef USB_WITH_CB_FNC
202 if ( udev->standard_fnc != NULL)
203 ret = udev->standard_fnc( udev);
205 #endif /*USB_WITH_CB_FNC*/
206 ret = usb_standard_control_response( udev);
208 usb_udev_stall( ep0);
210 if ( type == USB_VENDOR_REQUEST) {
211 #ifdef USB_WITH_CB_FNC
213 if ( udev->vendor_fnc != NULL)
214 ret = udev->vendor_fnc( udev);
216 usb_udev_stall( ep0);
217 #endif /*USB_WITH_CB_FNC*/
218 } else if ( type == USB_CLASS_REQUEST) {
219 #ifdef USB_WITH_CB_FNC
221 if( udev->class_fnc != NULL)
222 ret = udev->class_fnc( udev);
224 usb_udev_stall( ep0);
225 #endif /*USB_WITH_CB_FNC*/
227 usb_udev_stall( ep0);
232 /* response to interrupt Ep0RxInt - receive data */
233 if ( udev->flags & USB_FLAG_EVENT_RX0) {
235 udev->flags &= ~USB_FLAG_EVENT_RX0;
236 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "Ep0Rx\n"));
237 if (( ep0->flags & USB_STATE_MASK) == USB_STATE_RECEIVE) {
238 usb_debug_print( DEBUG_LEVEL_HIGH, ( "RCV:p=%04lX,s=%d\n", (unsigned long)ep0->ptr, ep0->size));
240 i = usb_udev_read_endpoint(ep0, ep0->ptr, ep0->max_packet_size);
244 #ifdef USB_WITH_CB_FNC
245 if ( ep0->next_pkt_fnc ) {
246 if( ep0->next_pkt_fnc( ep0, i, USB_NEXT_PKT_REC) < 0) {
247 usb_udev_stall( ep0);
251 #endif /*USB_WITH_CB_FNC*/
253 if (( i != ep0->max_packet_size) || ( ep0->actual >= ep0->size)) {
254 usb_complete_control_transfer( ep0, USB_COMPLETE_OK );
260 ep0->flags &= ~USB_STATE_MASK; //state = USB_STATE_IDLE;
264 /* response to interrupt Ep0TxInt */
265 if ( udev->flags & USB_FLAG_EVENT_TX0) {
266 short i = ep0->size - ep0->actual;
267 udev->flags &= ~USB_FLAG_EVENT_TX0;
268 //usb_debug_print( DEBUG_LEVEL_LOW, ("0S-%d(%d){%d}\n", ep0->state, ep0->size, ep0->max_packet_size));
269 usb_debug_print( DEBUG_LEVEL_MEDIUM, ( "EP0Tx:i=%d\n", i));
271 if (( ep0->flags & USB_STATE_MASK) == USB_STATE_TRANSMIT) {
273 if(i > ep0->max_packet_size) i = ep0->max_packet_size;
276 #ifdef USB_WITH_CB_FNC
277 if ( ep0->next_pkt_fnc) {
278 if( ep0->next_pkt_fnc( ep0, i, USB_NEXT_PKT_SEND) < 0) {
279 usb_udev_stall( ep0);
283 #endif /*USB_WITH_CB_FNC*/
284 usb_debug_print( DEBUG_LEVEL_HIGH, ("Wr(%d)\n",i));
285 usb_udev_write_endpoint( ep0, ep0->ptr, i);
289 if( i != ep0->max_packet_size) {
290 /* last packed without full size has been sent, state can change to idle */
291 usb_complete_control_transfer( ep0, USB_COMPLETE_OK );
294 usb_udev_ack_setup( udev); // Send zero packet at the end ???
295 usb_complete_control_transfer( ep0, USB_COMPLETE_OK );