Contiki 2.5
usb_standard_request.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /*! \file *********************************************************************
3  *
4  * \brief
5  * This file contains the USB endpoint 0 management routines corresponding to
6  * the standard enumeration process (refer to chapter 9 of the USB
7  * specification.
8  * This file calls routines of the usb_specific_request.c file for non-standard
9  * request management.
10  * The enumeration parameters (descriptor tables) are contained in the
11  * usb_descriptors.c file.
12  *
13  * \addtogroup usbdriver
14  *
15  * \author
16  * Atmel Corporation: http://www.atmel.com \n
17  * Support email: avr@atmel.com
18  *
19  ******************************************************************************/
20 /* Copyright (c) 2008 ATMEL Corporation
21  All rights reserved.
22 
23  Redistribution and use in source and binary forms, with or without
24  modification, are permitted provided that the following conditions are met:
25 
26  * Redistributions of source code must retain the above copyright
27  notice, this list of conditions and the following disclaimer.
28  * Redistributions in binary form must reproduce the above copyright
29  notice, this list of conditions and the following disclaimer in
30  the documentation and/or other materials provided with the
31  distribution.
32  * Neither the name of the copyright holders nor the names of
33  contributors may be used to endorse or promote products derived
34  from this software without specific prior written permission.
35 
36  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
40  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46  POSSIBILITY OF SUCH DAMAGE.
47 */
48 
49 //_____ I N C L U D E S ____________________________________________________
50 
51 #include "config.h"
52 #include "usb_drv.h"
53 #include "usb_descriptors.h"
54 #include "usb_specific_request.h"
55 #include <string.h>
56 
57 //_____ M A C R O S ________________________________________________________
58 
59 
60 //_____ D E F I N I T I O N ________________________________________________
61 #define PRINTF printf
62 #define PRINTF_P printf_P
63 
64 //_____ P R I V A T E D E C L A R A T I O N ______________________________
65 
66 static void usb_get_descriptor( void);
67 static void usb_set_address( void);
68 static void usb_set_configuration(void);
69 static void usb_clear_feature( void);
70 static void usb_set_feature( void);
71 static void usb_get_status( void);
72 static void usb_get_configuration(void);
73 static void usb_get_interface (void);
74 static void usb_set_interface (void);
75 
76 
77 //_____ D E C L A R A T I O N ______________________________________________
78 
79 static bit zlp;
80 static U8 endpoint_status[NB_ENDPOINTS];
81 
82 #ifdef AVRGCC
83  PGM_VOID_P pbuffer;
84 #else
85  U8 FLASH *pbuffer;
86 #endif
87  U8 data_to_transfer;
88 
89  U16 wInterface;
90 
91 static U8 bmRequestType;
92 
94 
95  usb_mode_t usb_mode = rndis_debug;
96 
97 extern bit usb_connected;
98 extern FLASH S_usb_device_descriptor usb_user_device_descriptor_network;
99 extern FLASH S_usb_user_configuration_descriptor_network usb_user_configuration_descriptor_network;
100 extern FLASH S_usb_device_descriptor usb_user_device_descriptor_composite;
101 extern FLASH S_usb_user_configuration_descriptor_composite usb_user_configuration_descriptor_composite;
102 
103 //! usb_process_request.
104 //!
105 //! @brief This function reads the SETUP request sent to the default control endpoint
106 //! and calls the appropriate function. When exiting of the usb_read_request
107 //! function, the device is ready to manage the next request.
108 //!
109 //! @note list of supported requests:
110 //! GET_DESCRIPTOR
111 //! GET_CONFIGURATION
112 //! SET_ADDRESS
113 //! SET_CONFIGURATION
114 //! CLEAR_FEATURE
115 //! SET_FEATURE
116 //! GET_STATUS
117 //!
119 {
120  U8 bmRequest;
121 
122  bmRequestType = Usb_read_byte();
123  bmRequest = Usb_read_byte();
124 
125  switch (bmRequest)
126  {
127  case GET_DESCRIPTOR:
128  if (0x80 == bmRequestType) { usb_get_descriptor(); }
129  else goto user_read;
130  break;
131 
132  case GET_CONFIGURATION:
133  if (0x80 == bmRequestType) { usb_get_configuration(); }
134  else goto user_read;
135  break;
136 
137  case SET_ADDRESS:
138  if (0x00 == bmRequestType) { usb_set_address(); }
139  else goto user_read;
140  break;
141 
142  case SET_CONFIGURATION:
143  if (0x00 == bmRequestType) { usb_set_configuration(); }
144  else goto user_read;
145  break;
146 
147  case CLEAR_FEATURE:
148  if (0x02 >= bmRequestType) { usb_clear_feature(); }
149  else goto user_read;
150  break;
151 
152  case SET_FEATURE:
153  if (0x02 >= bmRequestType) { usb_set_feature(); }
154  else goto user_read;
155  break;
156 
157  case GET_STATUS:
158  if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
159  { usb_get_status(); }
160  else goto user_read;
161  break;
162 
163  case GET_INTERFACE:
164  if (bmRequestType == 0x81) { usb_get_interface(); }
165  else goto user_read;
166  break;
167 
168 
169  case SET_INTERFACE:
170  if (bmRequestType == 0x01) {usb_set_interface();}
171  break;
172 
173  case SET_DESCRIPTOR:
174  case SYNCH_FRAME:
175  default: //!< un-supported request => call to user read request
176  user_read:
177  usb_user_read_request(bmRequestType, bmRequest);
178  break;
179  }
180 
181  Usb_select_endpoint(EP_CONTROL);
182 
183  // If the receive setup flag hasn't been cleared
184  // by this point then we can assume that we didn't
185  // support this request and should stall.
188 
189  // Clear some flags.
193 }
194 
195 //! usb_set_address.
196 //!
197 //! This function manages the SET ADDRESS request. When complete, the device
198 //! will filter the requests using the new address.
199 //!
200 //! @warning Code:xx bytes (function code length)
201 //!
202 void usb_set_address(void)
203 {
205 
207 
208  Usb_send_control_in(); //!< send a ZLP for STATUS phase
209  while(!Is_usb_in_ready()); //!< waits for status phase done
210  //!< before using the new address
212 }
213 
214 //! usb_set_configuration.
215 //!
216 //! This function manages the SET CONFIGURATION request. If the selected
217 //! configuration is valid, this function call the usb_user_endpoint_init()
218 //! function that will configure the endpoints following the configuration
219 //! number.
220 //!
221 //! @warning Code:xx bytes (function code length)
222 //!
223 void usb_set_configuration( void )
224 {
225 U8 configuration_number;
226 
227  configuration_number = Usb_read_byte();
228 
229  // TODO: Verify configuration_number!
231  usb_configuration_nb = configuration_number;
232 
233  Usb_send_control_in(); //!< send a ZLP for STATUS phase
234  while(!Is_usb_in_ready());
235 
236  usb_user_endpoint_init(usb_configuration_nb); //!< endpoint configuration
237  Usb_set_configuration_action();
238 }
239 
240 
241 
242 
243 
244 void usb_get_string_descriptor_sram(U8 string_type) {
245  U16 requested_length;
246  U8 dummy;
247  const char* user_str;
248 
249  user_str = usb_user_get_string_sram(string_type);
250 
251  dummy = Usb_read_byte(); //!< don't care of wIndex field
252  dummy = Usb_read_byte();
253  requested_length = Usb_read_byte(); //!< read wLength
254  requested_length |= Usb_read_byte()<<8;
255 
256  if(!user_str)
257  return;
258 
259  const U8 actual_descriptor_size = 2+strlen(user_str)*2;
260 
261  if (requested_length > actual_descriptor_size) {
262  zlp = ((actual_descriptor_size % EP_CONTROL_LENGTH) == 0);
263  requested_length = actual_descriptor_size;
264  }
265 
266  Usb_ack_receive_setup() ; //!< clear the receive setup flag
267 
268  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
270  return;
271  }
272 
273  // Output the length
274  Usb_write_byte(actual_descriptor_size);
275 
276  // Output the type
277  Usb_write_byte(STRING_DESCRIPTOR);
278 
279  requested_length -= 2;
280  U8 nb_byte = 2;
281 
282  if(!requested_length) {
284  }
285 
286  while((requested_length != 0) && (!Is_usb_receive_out()))
287  {
288  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
290  break;
291  }
292 
293  while(requested_length != 0) //!< Send data until necessary
294  {
295  if(nb_byte==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
296  {
297  nb_byte=0;
298  break;
299  }
300 
301  Usb_write_byte(*user_str);
302  Usb_write_byte(0);
303  user_str++;
304  requested_length -=2;
305  nb_byte+=2;
306  }
308  }
309 
310 //bail:
311  if(Is_usb_receive_out()) {
312  //! abort from Host
314  return;
315  }
316 
317  if(zlp == TRUE) {
318  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
320  return;
321  }
323  }
324 
325  usb_endpoint_wait_for_receive_out();
327 }
328 
329 
330 void usb_get_string_descriptor(U8 string_type) {
331  U16 requested_length;
332  U8 dummy;
333  PGM_P user_str;
334 
335  user_str = usb_user_get_string(string_type);
336 
337  if(!user_str) {
338  usb_get_string_descriptor_sram(string_type);
339  return;
340  }
341 
342  dummy = Usb_read_byte(); //!< don't care of wIndex field
343  dummy = Usb_read_byte();
344  requested_length = Usb_read_byte(); //!< read wLength
345  requested_length |= Usb_read_byte()<<8;
346 
347 
348  const U8 actual_descriptor_size = 2+strlen_P(user_str)*2;
349 
350  if (requested_length > actual_descriptor_size) {
351  zlp = ((actual_descriptor_size % EP_CONTROL_LENGTH) == 0);
352  requested_length = actual_descriptor_size;
353  }
354 
355  Usb_ack_receive_setup() ; //!< clear the receive setup flag
356 
357  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
359  return;
360  }
361  U8 nb_byte = 0;
362 
363  // Output the length
364  if(requested_length) {
365  Usb_write_byte(actual_descriptor_size);
366  requested_length--;
367  nb_byte++;
368  }
369 
370  // Output the type
371  if(requested_length) {
372  Usb_write_byte(STRING_DESCRIPTOR);
373  requested_length--;
374  nb_byte++;
375  }
376 
377  if(!requested_length) {
379  }
380 
381  while((requested_length != 0) && (!Is_usb_receive_out()))
382  {
383  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
385  break;
386  }
387 
388  while(requested_length != 0) //!< Send data until necessary
389  {
390  if(nb_byte==EP_CONTROL_LENGTH) { //!< Check endpoint 0 size
391  nb_byte=0;
392  break;
393  }
394 
395  Usb_write_byte(pgm_read_byte_near((unsigned int)user_str++));
396  requested_length--;
397  nb_byte++;
398  if(requested_length) {
399  Usb_write_byte(0);
400  requested_length--;
401  nb_byte++;
402  }
403  }
405  }
406 
407 //bail:
408 
409  if(Is_usb_receive_out()) {
410  //! abort from Host
412  return;
413  }
414 
415  if(zlp == TRUE) {
416  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
418  return;
419  }
421  }
422 
423  usb_endpoint_wait_for_receive_out();
425 }
426 
427 
428 //! usb_get_descriptor.
429 //!
430 //! This function manages the GET DESCRIPTOR request. The device descriptor,
431 //! the configuration descriptor and the device qualifier are supported. All
432 //! other descriptors must be supported by the usb_user_get_descriptor
433 //! function.
434 //! Only 1 configuration is supported.
435 //!
436 //! @warning Code:xx bytes (function code length)
437 //!
438 void usb_get_descriptor(void)
439 {
440  U8 LSBwLength, MSBwLength;
441  U8 descriptor_type ;
442  U8 string_type ;
443  U8 dummy;
444  U8 byteswereread;
445 
446  zlp = FALSE; /* no zero length packet */
447  string_type = Usb_read_byte(); /* read LSB of wValue */
448  descriptor_type = Usb_read_byte(); /* read MSB of wValue */
449  byteswereread = 0;
450 
451  switch (descriptor_type)
452  {
453  case DEVICE_DESCRIPTOR:
454  data_to_transfer = Usb_get_dev_desc_length(); //!< sizeof (usb_user_device_descriptor);
455  pbuffer = Usb_get_dev_desc_pointer();
456  break;
457  case CONFIGURATION_DESCRIPTOR:
458  data_to_transfer = Usb_get_conf_desc_length(string_type); //!< sizeof (usb_user_configuration_descriptor);
459  pbuffer = Usb_get_conf_desc_pointer(string_type);
460  break;
461 #if 1
462  case STRING_DESCRIPTOR:
463  if(string_type!=LANG_ID) {
464  usb_get_string_descriptor(string_type);
465  return;
466  }
467 #endif
468  default:
469  dummy = Usb_read_byte();
470  dummy = Usb_read_byte();
471  LSBwLength = Usb_read_byte();
472  MSBwLength = Usb_read_byte();
473  byteswereread=1;
474  if( usb_user_get_descriptor(descriptor_type, string_type)==FALSE ) {
475  Usb_enable_stall_handshake(); //TODO:is this necessary, Win7 flaky without?
477  return;
478  }
479  break;
480  }
481  if (byteswereread==0) {
482  dummy = Usb_read_byte(); //!< don't care of wIndex field
483  dummy = Usb_read_byte();
484  LSBwLength = Usb_read_byte(); //!< read wLength
485  MSBwLength = Usb_read_byte();
486  }
487 
488  Usb_ack_receive_setup() ; //!< clear the receive setup flag
489 
490  if ((LSBwLength > data_to_transfer) || (MSBwLength)) {
491  if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
492  else { zlp = FALSE; } //!< no need of zero length packet
493 
494  LSBwLength = data_to_transfer;
495  MSBwLength = 0x00;
496  } else {
497  data_to_transfer = LSBwLength; //!< send only requested number of data
498  }
499 
500  while((data_to_transfer != 0) && (!Is_usb_receive_out())) {
501  U8 nb_byte = 0;
502  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
504  break;
505  }
506 
507  //! Send data until necessary
508  while(data_to_transfer != 0) {
509 // if(Is_usb_write_enabled()) //!< Check endpoint 0 size
510  if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size
511  break;
512 
513  Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++));
514  data_to_transfer --;
515 
516  }
518  }
519 
520  if(Is_usb_receive_out()) {
521  //! abort from Host
523  return;
524  }
525 
526  if(zlp == TRUE) {
527  if(usb_endpoint_wait_for_read_control_enabled()!=0) {
529  return;
530  }
532  }
533 
534  usb_endpoint_wait_for_receive_out();
536 }
537 
538 //! usb_get_configuration.
539 //!
540 //! This function manages the GET CONFIGURATION request. The current
541 //! configuration number is returned.
542 //!
543 //! @warning Code:xx bytes (function code length)
544 //!
545 void usb_get_configuration(void)
546 {
548 
551 
552  usb_endpoint_wait_for_receive_out();
554 }
555 
556 //! usb_get_status.
557 //!
558 //! This function manages the GET STATUS request. The device, interface or
559 //! endpoint status is returned.
560 //!
561 //! @warning Code:xx bytes (function code length)
562 //!
563 void usb_get_status(void)
564 {
565 U8 wIndex;
566 U8 dummy;
567 
568  dummy = Usb_read_byte(); //!< dummy read
569  dummy = Usb_read_byte(); //!< dummy read
570  wIndex = Usb_read_byte();
571 
572  switch(bmRequestType)
573  {
574  case REQUEST_DEVICE_STATUS: Usb_ack_receive_setup();
575  Usb_write_byte(DEVICE_STATUS);
576  break;
577 
578  case REQUEST_INTERFACE_STATUS: Usb_ack_receive_setup();
579  Usb_write_byte(INTERFACE_STATUS);
580  break;
581 
582  case REQUEST_ENDPOINT_STATUS: Usb_ack_receive_setup();
583  wIndex = wIndex & MSK_EP_DIR;
584  Usb_write_byte(endpoint_status[wIndex]);
585  break;
586  default:
589  return;
590  }
591 
592  Usb_write_byte(0x00);
594 
595  usb_endpoint_wait_for_receive_out();
597 }
598 
599 //! usb_set_feature.
600 //!
601 //! This function manages the SET FEATURE request. The USB test modes are
602 //! supported by this function.
603 //!
604 //! @warning Code:xx bytes (function code length)
605 //!
606 void usb_set_feature(void)
607 {
608 U8 wValue;
609 U8 wIndex;
610 U8 dummy;
611 
612  if (bmRequestType == INTERFACE_TYPE)
613  {
614  return;
615  }
616  else if (bmRequestType == ENDPOINT_TYPE)
617  {
618  wValue = Usb_read_byte();
619  dummy = Usb_read_byte(); //!< dummy read
620 
621  if (wValue == FEATURE_ENDPOINT_HALT)
622  {
623  wIndex = (Usb_read_byte() & MSK_EP_DIR);
624 
625  if (wIndex == EP_CONTROL)
626  {
627  return;
628  }
629 
630  Usb_select_endpoint(wIndex);
632  {
634  Usb_select_endpoint(EP_CONTROL);
635  endpoint_status[wIndex] = 0x01;
638  }
639  else
640  {
641  Usb_select_endpoint(EP_CONTROL);
642  return;
643  }
644  }
645  else
646  {
647  return;
648  }
649  }
650 }
651 
652 //! usb_clear_feature.
653 //!
654 //! This function manages the SET FEATURE request.
655 //!
656 //! @warning Code:xx bytes (function code length)
657 //!
658 void usb_clear_feature(void)
659 {
660 U8 wValue;
661 U8 wIndex;
662 U8 dummy;
663 
664  if (bmRequestType == ZERO_TYPE)
665  {
666  return;
667  }
668  else if (bmRequestType == INTERFACE_TYPE)
669  {
670  return;
671  }
672  else if (bmRequestType == ENDPOINT_TYPE)
673  {
674  wValue = Usb_read_byte();
675  dummy = Usb_read_byte(); //!< dummy read
676 
677  if (wValue == FEATURE_ENDPOINT_HALT)
678  {
679  wIndex = (Usb_read_byte() & MSK_EP_DIR);
680 
681  Usb_select_endpoint(wIndex);
683  {
684  if(wIndex != EP_CONTROL)
685  {
687  Usb_reset_endpoint(wIndex);
689  }
690  Usb_select_endpoint(EP_CONTROL);
691  endpoint_status[wIndex] = 0x00;
694 
695  }
696  else
697  {
698  return;
699  }
700  }
701  else
702  {
703  return;
704  }
705  }
706 }
707 
708 //! usb_get_interface.
709 //!
710 //! TThis function manages the GET_INTERFACE request.
711 //!
712 //! @warning Code:xx bytes (function code length)
713 //!
714 void usb_get_interface (void)
715 {
716  // Not yet implemented.
717 }
718 
719 //! usb_set_interface.
720 //!
721 //! TThis function manages the SET_INTERFACE request.
722 //!
723 //! @warning Code:xx bytes (function code length)
724 //!
725 void usb_set_interface (void)
726 {
727  U8 alt_setting;
728  U8 dummy;
729  U8 interface;
730 
731  alt_setting = Usb_read_byte();
732  dummy = Usb_read_byte();
733  interface = Usb_read_byte();
734 
735  if(usb_user_set_alt_interface(interface, alt_setting)) {
737  Usb_send_control_in(); //!< send a ZLP for STATUS phase
738  while(!Is_usb_in_ready());
739 
740  usb_endpoint_wait_for_receive_out();
742  }
743 
744 }