usb_specific_request.c File Reference

#include "config.h"
#include "conf_usb.h"
#include "lib_mcu/usb/usb_drv.h"
#include "usb_descriptors.h"
#include "modules/usb/device_chap9/usb_standard_request.h"
#include "usb_specific_request.h"
#include "modules/control_access/ctrl_access.h"
#include "lib_mcu/flash/flash_drv.h"

Include dependency graph for usb_specific_request.c:

Go to the source code of this file.

Functions

void hid_get_report_descriptor (void)
void usb_hid_set_report_ouput (void)
void usb_hid_set_idle (U8 u8_report_id, U8 u8_duration)
void usb_hid_get_idle (U8 u8_report_id)
void hid_get_hid_descriptor (void)
void usb_hid_set_report_feature (void)
Bool usb_user_read_request (U8 type, U8 request)
 This function checks the specific request and if known then processes it
void usb_user_endpoint_init (U8 conf_nb)
U8 usb_user_interface_get (U16 wInterface)
void usb_user_interface_reset (U16 wInterface, U8 alternate_setting)
Bool usb_user_get_descriptor (U8 type, U8 string)
 This function fills the global descriptor.

Variables

bit ms_multiple_drive
U8 code * pbuffer
U8 data_to_transfer
code
S_usb_hid_report_descriptor_mouse 
usb_hid_report_descriptor_mouse
code
S_usb_hid_report_descriptor 
usb_hid_report_descriptor
U8 jump_bootloader = 0
U8 g_u8_report_rate = 0


Detailed Description

user call-back functions This file contains the user call-back functions corresponding to the application: - Compiler: IAR EWAVR and GNU GCC for AVR

Definition in file usb_specific_request.c.


Function Documentation

void hid_get_report_descriptor ( void   ) 

This function manages hit get repport request.

Definition at line 379 of file usb_specific_request.c.

References data_to_transfer, EP_CONTROL_LENGTH, FALSE, INTERFACE_NB_MOUSE, Is_usb_read_control_enabled, Is_usb_receive_out, LSB, MSB, pbuffer, S_usb_hid_report_descriptor::report, S_usb_hid_report_descriptor_mouse::report, TRUE, Usb_ack_receive_out, Usb_ack_receive_setup, usb_hid_report_descriptor, usb_hid_report_descriptor_mouse, Usb_read_byte, Usb_send_control_in, and Usb_write_byte.

Referenced by usb_user_read_request().

00380 {
00381    U16 wLength;
00382    U8  nb_byte;
00383    bit zlp = FALSE;
00384    U16 wInterface;
00385 
00386    LSB(wInterface)=Usb_read_byte();
00387    MSB(wInterface)=Usb_read_byte();
00388 
00389    if(wInterface==INTERFACE_NB_MOUSE)
00390    {
00391       data_to_transfer = sizeof(usb_hid_report_descriptor_mouse);
00392       pbuffer = &(usb_hid_report_descriptor_mouse.report[0]);
00393    }
00394    else
00395    {
00396       data_to_transfer = sizeof(usb_hid_report_descriptor);
00397       pbuffer = &(usb_hid_report_descriptor.report[0]);
00398    }
00399 
00400    LSB(wLength) = Usb_read_byte();
00401    MSB(wLength) = Usb_read_byte();
00402    Usb_ack_receive_setup();
00403 
00404    if (wLength > data_to_transfer)
00405    {
00406       if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
00407       else { zlp = FALSE; }
00408    }
00409    else
00410    {
00411       data_to_transfer = (U8)wLength;           // send only requested number of data
00412    }
00413 
00414    while((data_to_transfer != 0) && (!Is_usb_receive_out()))
00415    {
00416       while(!Is_usb_read_control_enabled());
00417 
00418       nb_byte=0;
00419       while(data_to_transfer != 0)              // Send data until necessary
00420       {
00421          if(nb_byte++==EP_CONTROL_LENGTH)       // Check endpoint 0 size
00422          {
00423             break;
00424          }
00425 #ifndef __GNUC__
00426          Usb_write_byte(*pbuffer++);
00427 #else    // AVRGCC does not support point to PGM space
00428 //warning with AVRGCC assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
00429          Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++));
00430 #endif
00431          data_to_transfer --;
00432       }
00433       Usb_send_control_in();
00434    }
00435 
00436    if(Is_usb_receive_out())
00437    { 
00438       // abort from Host
00439       Usb_ack_receive_out();
00440       return;
00441    }
00442    if(zlp == TRUE)
00443    { 
00444       while(!Is_usb_read_control_enabled());
00445       Usb_send_control_in();
00446    }
00447 
00448    while(!Is_usb_receive_out());
00449    Usb_ack_receive_out();
00450 }

Here is the caller graph for this function:

void usb_hid_set_report_ouput ( void   ) 

This function manages hit set report request.

Definition at line 455 of file usb_specific_request.c.

References Is_usb_receive_out, Usb_ack_receive_out, Usb_ack_receive_setup, and Usb_send_control_in.

Referenced by usb_user_read_request().

00456 {
00457    Usb_ack_receive_setup();
00458    Usb_send_control_in();
00459 
00460    while(!Is_usb_receive_out());
00461    Usb_ack_receive_out();
00462    Usb_send_control_in();
00463 }

Here is the caller graph for this function:

void usb_hid_set_idle ( U8  u8_report_id,
U8  u8_duration 
)

This function manages hid set idle request.

Parameters:
Duration When the upper byte of wValue is 0 (zero), the duration is indefinite else from 0.004 to 1.020 seconds
Report ID 0 the idle rate applies to all input reports, else only applies to the Report ID

Definition at line 471 of file usb_specific_request.c.

References g_u8_report_rate, Is_usb_in_ready, LSB, MSB, Usb_ack_receive_setup, Usb_read_byte, and Usb_send_control_in.

Referenced by usb_user_read_request().

00472 {
00473    U16 wInterface;
00474    
00475    // Get interface number to put in idle mode
00476    LSB(wInterface)=Usb_read_byte();
00477    MSB(wInterface)=Usb_read_byte();
00478    Usb_ack_receive_setup();
00479   
00480    g_u8_report_rate = u8_duration;
00481    
00482    Usb_send_control_in();
00483    while(!Is_usb_in_ready());
00484 }

Here is the caller graph for this function:

void usb_hid_get_idle ( U8  u8_report_id  ) 

This function manages hid get idle request.

Parameters:
Report ID 0 the idle rate applies to all input reports, else only applies to the Report ID

Definition at line 491 of file usb_specific_request.c.

References g_u8_report_rate, Is_usb_receive_out, LSB, MSB, Usb_ack_receive_out, Usb_ack_receive_setup, Usb_read_byte, Usb_send_control_in, and Usb_write_byte.

Referenced by usb_user_read_request().

00492 {
00493    U16 wLength;
00494    U16 wInterface;
00495 
00496    // Get interface number to put in idle mode
00497    LSB(wInterface)= Usb_read_byte();
00498    MSB(wInterface)= Usb_read_byte();
00499    LSB(wLength)   = Usb_read_byte();
00500    MSB(wLength)   = Usb_read_byte();
00501    Usb_ack_receive_setup();
00502    
00503    if( wLength != 0 )
00504    {
00505       Usb_write_byte(g_u8_report_rate);
00506       Usb_send_control_in();
00507    }
00508    
00509    while(!Is_usb_receive_out());
00510    Usb_ack_receive_out();
00511 }

Here is the caller graph for this function:

void hid_get_hid_descriptor ( void   ) 

This function manages hid get hid descriptor request.

Definition at line 534 of file usb_specific_request.c.

References S_usb_hid_descriptor::bLength, data_to_transfer, EP_CONTROL_LENGTH, FALSE, S_usb_user_configuration_descriptor::hid, S_usb_user_configuration_descriptor::hid_mouse, INTERFACE_NB_MOUSE, Is_usb_read_control_enabled, Is_usb_receive_out, LSB, MSB, pbuffer, TRUE, Usb_ack_receive_out, Usb_ack_receive_setup, usb_conf_desc, Usb_read_byte, Usb_send_control_in, and Usb_write_byte.

Referenced by usb_user_read_request().

00535 {
00536    U16 wLength;
00537    U8  nb_byte;
00538    bit zlp=FALSE;
00539    U16 wInterface;
00540 
00541    LSB(wInterface)=Usb_read_byte();
00542    MSB(wInterface)=Usb_read_byte();
00543 
00544    if(wInterface==INTERFACE_NB_MOUSE)
00545    {
00546       data_to_transfer = sizeof(usb_conf_desc.hid_mouse);
00547       pbuffer = &(usb_conf_desc.hid_mouse.bLength);
00548    }
00549    else
00550    {
00551       data_to_transfer = sizeof(usb_conf_desc.hid);
00552       pbuffer = &(usb_conf_desc.hid.bLength);
00553    }
00554 
00555    LSB(wLength) = Usb_read_byte();
00556    MSB(wLength) = Usb_read_byte();
00557    Usb_ack_receive_setup();
00558 
00559    if (wLength > data_to_transfer)
00560    {
00561       if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
00562       else { zlp = FALSE; }                     // no need of zero length packet
00563    }
00564    else
00565    {
00566       data_to_transfer = (U8)wLength;           // send only requested number of data
00567    }
00568 
00569    while((data_to_transfer != 0) && (!Is_usb_receive_out()))
00570    {
00571       while(!Is_usb_read_control_enabled());
00572 
00573       nb_byte=0;
00574       while(data_to_transfer != 0)              // Send data until necessary
00575       {
00576          if(nb_byte++==EP_CONTROL_LENGTH)       // Check endpoint 0 size
00577          {
00578             break;
00579          }
00580 #ifndef __GNUC__
00581          Usb_write_byte(*pbuffer++);
00582 #else    // AVRGCC does not support point to PGM space
00583 //warning with AVRGCC assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
00584          Usb_write_byte(pgm_read_byte_near((unsigned int)pbuffer++));
00585 #endif
00586          data_to_transfer --;
00587       }
00588       Usb_send_control_in();
00589    }
00590 
00591    if(Is_usb_receive_out())
00592    { 
00593       // abort from Host
00594       Usb_ack_receive_out();
00595       return;
00596    }
00597    if(zlp == TRUE)
00598    { 
00599       while(!Is_usb_read_control_enabled());
00600       Usb_send_control_in();
00601    }
00602 
00603    while(!Is_usb_receive_out());
00604    Usb_ack_receive_out();
00605 }

Here is the caller graph for this function:

void usb_hid_set_report_feature ( void   ) 

Definition at line 513 of file usb_specific_request.c.

References Is_usb_in_ready, Is_usb_receive_out, jump_bootloader, Usb_ack_receive_out, Usb_ack_receive_setup, Usb_read_byte, and Usb_send_control_in.

Referenced by usb_user_read_request().

00514 {
00515    Usb_ack_receive_setup();
00516    Usb_send_control_in();
00517 
00518    while(!Is_usb_receive_out());
00519 
00520    if(Usb_read_byte()==0x55)
00521       if(Usb_read_byte()==0xAA)
00522          if(Usb_read_byte()==0x55)
00523             if(Usb_read_byte()==0xAA)
00524             {
00525                jump_bootloader=1;
00526             }
00527    Usb_ack_receive_out();
00528    Usb_send_control_in();
00529    while(!Is_usb_in_ready());
00530 }

Here is the caller graph for this function:

Bool usb_user_read_request ( U8  type,
U8  request 
)

This function checks the specific request and if known then processes it

Parameters:
type corresponding at bmRequestType (see USB specification)
request corresponding at bRequest (see USB specification)
Returns:
TRUE, when the request is processed

FALSE, if the request is'nt know (STALL handshake is managed by the main standard request function).

Definition at line 95 of file usb_specific_request.c.

Referenced by usb_process_request().

00096 {
00097    U16   wInterface;
00098    U8    wValue_msb;
00099    U8    wValue_lsb;
00100 
00101    // Read wValue
00102    wValue_lsb = Usb_read_byte();
00103    wValue_msb = Usb_read_byte();
00104 
00105    //** Specific request from Class HID
00106    if( USB_SETUP_GET_STAND_INTERFACE == type )
00107    {
00108       switch( request )
00109       {
00110          case SETUP_GET_DESCRIPTOR:
00111          switch( wValue_msb ) // Descriptor ID
00112          {
00113             case DESCRIPTOR_HID:
00114             hid_get_hid_descriptor();
00115             return TRUE;
00116             break;
00117    
00118             case DESCRIPTOR_REPORT:
00119             hid_get_report_descriptor();
00120             return TRUE;
00121    
00122             case DESCRIPTOR_PHYSICAL:
00123             // TODO
00124             break;
00125          }
00126          break;
00127       }
00128    }
00129    if( USB_SETUP_SET_CLASS_INTER == type )
00130    {
00131       switch( request )
00132       {
00133          case SETUP_HID_SET_REPORT:
00134          // The MSB wValue field specifies the Report Type
00135          // The LSB wValue field specifies the Report ID
00136          switch (wValue_msb)
00137          {
00138             case REPORT_TYPE_INPUT:
00139             // TODO
00140             break;
00141             
00142             case REPORT_TYPE_OUTPUT:
00143             usb_hid_set_report_ouput();
00144             return TRUE;
00145             break;
00146 
00147             case REPORT_TYPE_FEATURE:
00148             usb_hid_set_report_feature();
00149             return TRUE;
00150             break;
00151          }
00152          break;
00153 
00154          case SETUP_HID_SET_IDLE:
00155          usb_hid_set_idle(wValue_lsb,wValue_msb);
00156          return TRUE;
00157    
00158          case SETUP_HID_SET_PROTOCOL:
00159          // TODO
00160          break;
00161       }
00162    }
00163    if( USB_SETUP_GET_CLASS_INTER == type )
00164    {
00165       switch( request )
00166       {
00167          case SETUP_HID_GET_REPORT:
00168          // TODO
00169          break;
00170          case SETUP_HID_GET_IDLE:
00171          usb_hid_get_idle(wValue_lsb);
00172          return TRUE;
00173          case SETUP_HID_GET_PROTOCOL:
00174          // TODO
00175          break;
00176       }
00177    }
00178  
00179    //** Specific request from Class MassStorage
00180    if( USB_SETUP_SET_CLASS_INTER == type )
00181    {
00182       switch( request )
00183       {
00184          case SETUP_MASS_STORAGE_RESET:
00185          // wValue must be 0
00186          // wIndex = Interface
00187          if( (0!=wValue_lsb) || (0!=wValue_msb) )
00188             break;
00189          LSB(wInterface)=Usb_read_byte();
00190          MSB(wInterface)=Usb_read_byte();
00191          if( INTERFACE_NB != wInterface )
00192             break;
00193          Usb_ack_receive_setup();
00194          Usb_send_control_in();
00195          while(!Is_usb_in_ready());
00196          return TRUE;
00197          break;
00198       }
00199    }
00200    if( USB_SETUP_GET_CLASS_INTER == type )
00201    {
00202       switch( request )
00203       {
00204          case SETUP_MASS_STORAGE_GET_MAX_LUN:
00205          // wValue must be 0
00206          // wIndex = Interface
00207          if( (0!=wValue_lsb) || (0!=wValue_msb) )
00208             break;
00209          LSB(wInterface)=Usb_read_byte();
00210          MSB(wInterface)=Usb_read_byte();
00211          if( INTERFACE_NB != wInterface )
00212             break;
00213          Usb_ack_receive_setup();
00214          Usb_write_byte( (get_nb_lun()-1) );
00215          Usb_send_control_in();
00216          while(!Is_usb_in_ready());
00217          while( !Is_usb_receive_out() );
00218          Usb_ack_receive_out();
00219          ms_multiple_drive = 1;
00220          return TRUE;
00221          break;
00222       }
00223    }
00224    
00225    return FALSE;  // No supported request
00226 }

Here is the caller graph for this function:

void usb_user_endpoint_init ( U8  conf_nb  ) 

This function configures the endpoints

Parameters:
conf_nb configuration number choosed by USB host

Definition at line 233 of file usb_specific_request.c.

Referenced by usb_set_configuration().

00234 {
00235    usb_configure_endpoint( EP_MOUSE_IN,   \
00236                            TYPE_INTERRUPT,\
00237                            DIRECTION_IN,  \
00238                            SIZE_8,        \
00239                            ONE_BANK,      \
00240                            NYET_ENABLED);
00241 
00242    usb_configure_endpoint( EP_MS_IN,      \
00243                            TYPE_BULK,     \
00244                            DIRECTION_IN,  \
00245                            SIZE_64,       \
00246                            TWO_BANKS,     \
00247                            NYET_ENABLED);
00248 
00249    usb_configure_endpoint( EP_MS_OUT,     \
00250                            TYPE_BULK,     \
00251                            DIRECTION_OUT, \
00252                            SIZE_64,       \
00253                            TWO_BANKS,     \
00254                            NYET_ENABLED);
00255 
00256    usb_configure_endpoint( EP_HID_IN,     \
00257                            TYPE_INTERRUPT,\
00258                            DIRECTION_IN,  \
00259                            SIZE_8,        \
00260                            ONE_BANK,      \
00261                            NYET_ENABLED);
00262 
00263    usb_configure_endpoint( EP_HID_OUT,    \
00264                            TYPE_INTERRUPT,\
00265                            DIRECTION_OUT, \
00266                            SIZE_8,        \
00267                            ONE_BANK,      \
00268                            NYET_ENABLED);
00269 }

Here is the caller graph for this function:

U8 usb_user_interface_get ( U16  wInterface  ) 

This function returns the interface alternate setting

Parameters:
wInterface Interface selected
Returns:
alternate setting configurated

Definition at line 278 of file usb_specific_request.c.

Referenced by usb_get_interface().

00279 {
00280    return 0;  // Only one alternate setting possible for all interface
00281 }

Here is the caller graph for this function:

void usb_user_interface_reset ( U16  wInterface,
U8  alternate_setting 
)

This function selects (and resets) the interface alternate setting

Parameters:
wInterface Interface selected
alternate_setting alternate setting selected

Definition at line 289 of file usb_specific_request.c.

Referenced by usb_set_interface().

00290 {  
00291    // default setting selected = reset data toggle
00292    if( INTERFACE_NB_MOUSE == wInterface )
00293    {
00294       // Interface mouse
00295       Usb_select_endpoint(EP_MOUSE_IN);
00296       Usb_disable_stall_handshake();
00297       Usb_reset_endpoint(EP_MOUSE_IN);
00298       Usb_reset_data_toggle();
00299    }
00300    if( INTERFACE_NB == wInterface )
00301    {
00302       // Interface Mass Storage
00303       Usb_select_endpoint(EP_MS_IN);
00304       Usb_disable_stall_handshake();
00305       Usb_reset_endpoint(EP_MS_IN);
00306       Usb_reset_data_toggle();
00307       Usb_select_endpoint(EP_MS_OUT);
00308       Usb_disable_stall_handshake();
00309       Usb_reset_endpoint(EP_MS_OUT);
00310       Usb_reset_data_toggle();
00311    }
00312    if( INTERFACE_NB_HID == wInterface )
00313    {
00314       // Interface Mass Storage
00315       Usb_select_endpoint(EP_HID_IN);
00316       Usb_disable_stall_handshake();
00317       Usb_reset_endpoint(EP_HID_IN);
00318       Usb_reset_data_toggle();
00319       Usb_select_endpoint(EP_HID_OUT);
00320       Usb_disable_stall_handshake();
00321       Usb_reset_endpoint(EP_HID_OUT);
00322       Usb_reset_data_toggle();
00323    }
00324 }

Here is the caller graph for this function:

Bool usb_user_get_descriptor ( U8  type,
U8  string 
)

This function fills the global descriptor.

Parameters:
type corresponding at MSB of wValue (see USB specification)
string corresponding at LSB of wValue (see USB specification)
Returns:
FALSE, if the global descriptor no filled

Definition at line 334 of file usb_specific_request.c.

Referenced by usb_get_descriptor().

00335 {
00336    switch(type)
00337    {
00338       case DESCRIPTOR_STRING:
00339       switch (string)
00340       {
00341          case LANG_ID:
00342          data_to_transfer = sizeof (usb_user_language_id);
00343          pbuffer = &(usb_user_language_id.bLength);
00344          return TRUE;
00345          break;
00346         
00347          case MAN_INDEX:
00348          data_to_transfer = sizeof (usb_user_manufacturer_string_descriptor);
00349          pbuffer = &(usb_user_manufacturer_string_descriptor.bLength);
00350          return TRUE;
00351          break;
00352         
00353          case PROD_INDEX:
00354          data_to_transfer = sizeof (usb_user_product_string_descriptor);
00355          pbuffer = &(usb_user_product_string_descriptor.bLength);
00356          return TRUE;
00357          break;
00358            
00359 #if (USB_DEVICE_SN_USE==ENABLE)              
00360          case SN_INDEX:
00361          data_to_transfer = sizeof (usb_user_serial_number);
00362          pbuffer = &(usb_user_serial_number.bLength);
00363 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
00364          f_get_serial_string=TRUE;
00365          data_to_transfer += (SN_LENGTH*4);
00366 #endif
00367          return TRUE;
00368          break;
00369 #endif
00370       }
00371       break;
00372    }
00373    return FALSE;
00374 }

Here is the caller graph for this function:


Variable Documentation

bit ms_multiple_drive

Definition at line 63 of file usb_specific_request.c.

U8 code* pbuffer

Definition at line 94 of file usb_standard_request.c.

Referenced by hid_get_hid_descriptor(), hid_get_report_descriptor(), usb_get_descriptor(), and usb_user_get_descriptor().

U8 data_to_transfer

Definition at line 99 of file usb_standard_request.c.

Referenced by hid_get_hid_descriptor(), hid_get_report_descriptor(), usb_get_descriptor(), and usb_user_get_descriptor().

code S_usb_hid_report_descriptor_mouse usb_hid_report_descriptor_mouse

Definition at line 243 of file usb_descriptors.c.

code S_usb_hid_report_descriptor usb_hid_report_descriptor

Definition at line 274 of file usb_descriptors.c.

U8 jump_bootloader = 0

Definition at line 73 of file usb_specific_request.c.

U8 g_u8_report_rate = 0

Definition at line 75 of file usb_specific_request.c.

Referenced by usb_hid_get_idle(), and usb_hid_set_idle().


Generated on Wed Sep 23 09:49:44 2009 for ATMEL by  doxygen 1.5.3