usb_specific_request.c

Go to the documentation of this file.
00001 /*This file is prepared for Doxygen automatic documentation generation.*/
00016 
00017 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
00018  *
00019  * Redistribution and use in source and binary forms, with or without
00020  * modification, are permitted provided that the following conditions are met:
00021  *
00022  * 1. Redistributions of source code must retain the above copyright notice,
00023  * this list of conditions and the following disclaimer.
00024  *
00025  * 2. Redistributions in binary form must reproduce the above copyright notice,
00026  * this list of conditions and the following disclaimer in the documentation
00027  * and/or other materials provided with the distribution.
00028  *
00029  * 3. The name of Atmel may not be used to endorse or promote products derived
00030  * from this software without specific prior written permission.
00031  *
00032  * 4. This software may only be redistributed and used in connection with an Atmel
00033  * AVR product.
00034  *
00035  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00036  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00037  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
00038  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00039  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00040  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00041  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00042  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00043  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00044  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00045  */
00046 
00047 
00048 //_____ I N C L U D E S ____________________________________________________
00049 
00050 #include "config.h"
00051 #include "conf_usb.h"
00052 #include "lib_mcu/usb/usb_drv.h"
00053 #include "usb_descriptors.h"
00054 #include "modules/usb/device_chap9/usb_standard_request.h"
00055 #include "usb_specific_request.h"
00056 #include "lib_mcu/uart/uart_lib.h"
00057 #if ((USB_DEVICE_SN_USE==ENABLE) && (USE_DEVICE_SN_UNIQUE==ENABLE))
00058 #include "lib_mcu/flash/flash_drv.h"
00059 #endif
00060 
00061 //_____ D E F I N I T I O N ________________________________________________
00062 
00063 #ifdef __GNUC__
00064 extern PGM_VOID_P pbuffer;
00065 #else
00066 extern U8   code *pbuffer;
00067 #endif
00068 extern U8   data_to_transfer;
00069 extern S_line_coding   line_coding;
00070 extern S_line_status line_status;
00071 
00072 
00073 // We buffer the old state as it is wize only to send this interrupt message if
00074 // sstate has changed.
00075 extern S_serial_state serial_state;         // actual state
00076 static S_serial_state serial_state_saved;   // buffered previously sent state
00077 volatile U8 usb_request_break_generation=FALSE;
00078 
00079 
00080 //_____ D E C L A R A T I O N ______________________________________________
00081 
00090 Bool usb_user_read_request(U8 type, U8 request)
00091 {
00092    U16 wValue;
00093 
00094    LSB(wValue) = Usb_read_byte();
00095    MSB(wValue) = Usb_read_byte();
00096 
00097    //** Specific request from Class CDC
00098    if( USB_SETUP_SET_CLASS_INTER == type )
00099    {
00100       switch( request )
00101       {
00102          case SETUP_CDC_SET_LINE_CODING:
00103          cdc_set_line_coding();
00104          return TRUE;
00105          break;
00106    
00107          case SETUP_CDC_SET_CONTROL_LINE_STATE:
00108          cdc_set_control_line_state(wValue); // according cdc spec 1.1 chapter 6.2.14
00109          return TRUE;
00110          break;
00111    
00112          case SETUP_CDC_SEND_BREAK:
00113          cdc_send_break(wValue);             // wValue contains break lenght
00114          return TRUE;
00115          break;
00116       }
00117    }
00118    if( USB_SETUP_GET_CLASS_INTER == type )
00119    {
00120       switch( request )
00121       {
00122          case SETUP_CDC_GET_LINE_CODING:
00123          cdc_get_line_coding();
00124          return TRUE;
00125          break;
00126       }
00127    }
00128    return FALSE;  // No supported request
00129 }
00130 
00131 
00136 void usb_user_endpoint_init(U8 conf_nb)
00137 {
00138   usb_configure_endpoint(INT_EP,        \
00139                          TYPE_INTERRUPT,\
00140                          DIRECTION_IN,  \
00141                          SIZE_32,       \
00142                          ONE_BANK,      \
00143                          NYET_ENABLED);
00144 
00145   usb_configure_endpoint(TX_EP,         \
00146                          TYPE_BULK,     \
00147                          DIRECTION_IN,  \
00148                          SIZE_32,       \
00149                          ONE_BANK,      \
00150                          NYET_ENABLED);
00151 
00152   usb_configure_endpoint(RX_EP,         \
00153                          TYPE_BULK,     \
00154                          DIRECTION_OUT, \
00155                          SIZE_32,       \
00156                          ONE_BANK,      \
00157                          NYET_ENABLED);
00158 
00159   Usb_reset_endpoint(INT_EP);
00160   Usb_reset_endpoint(TX_EP);
00161   Usb_reset_endpoint(RX_EP);
00162 }
00163 
00164 
00171 U8   usb_user_interface_get( U16 wInterface )
00172 {
00173    return 0;  // Only one alternate setting possible for all interface
00174 }
00175 
00176 
00182 void usb_user_interface_reset(U16 wInterface, U8 alternate_setting)
00183 {  
00184    // default setting selected = reset data toggle
00185    if( INTERFACE0_NB == wInterface )
00186    {
00187       // Interface CDC ACM Com
00188       Usb_select_endpoint(INT_EP);
00189       Usb_disable_stall_handshake();
00190       Usb_reset_endpoint(INT_EP);
00191       Usb_reset_data_toggle();
00192    }
00193    if( INTERFACE1_NB == wInterface )
00194    {
00195       // Interface CDC ACM Data
00196       Usb_select_endpoint(TX_EP);
00197       Usb_disable_stall_handshake();
00198       Usb_reset_endpoint(TX_EP);
00199       Usb_reset_data_toggle();
00200       Usb_select_endpoint(RX_EP);
00201       Usb_disable_stall_handshake();
00202       Usb_reset_endpoint(RX_EP);
00203       Usb_reset_data_toggle();
00204    }
00205 }
00206 
00207 
00215 Bool usb_user_get_descriptor(U8 type, U8 string)
00216 { 
00217    switch(type)
00218    {
00219       case DESCRIPTOR_STRING:
00220       switch (string)
00221       {           
00222          case LANG_ID:
00223          data_to_transfer = sizeof (usb_user_language_id);
00224          pbuffer = &(usb_user_language_id.bLength);
00225          return TRUE;
00226          break;
00227                 
00228 #if (USB_DEVICE_SN_USE==ENABLE)              
00229          case SN_INDEX:
00230          data_to_transfer = sizeof (usb_user_serial_number);
00231          pbuffer = &(usb_user_serial_number.bLength);
00232 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
00233          f_get_serial_string=TRUE;
00234          data_to_transfer += (SN_LENGTH*4);
00235 #endif
00236          return TRUE;
00237          break;
00238 #endif
00239       }
00240       break;
00241    }
00242    return FALSE;
00243 }
00244 
00253 void cdc_get_line_coding(void)
00254 {
00255      Usb_ack_receive_setup();
00256      Usb_write_byte(LSB0(line_coding.dwDTERate));
00257      Usb_write_byte(LSB1(line_coding.dwDTERate));
00258      Usb_write_byte(LSB2(line_coding.dwDTERate));
00259      Usb_write_byte(LSB3(line_coding.dwDTERate));
00260      Usb_write_byte(line_coding.bCharFormat);
00261      Usb_write_byte(line_coding.bParityType);
00262      Usb_write_byte(line_coding.bDataBits);
00263 
00264      Usb_send_control_in();
00265      while(!(Is_usb_read_control_enabled()));
00266      //Usb_clear_tx_complete();
00267 
00268    while(!Is_usb_receive_out());
00269    Usb_ack_receive_out();
00270 }
00271 
00272 
00281 void cdc_set_line_coding (void)
00282 {
00283    Usb_ack_receive_setup();
00284    while (!(Is_usb_receive_out()));
00285    LSB0(line_coding.dwDTERate) = Usb_read_byte();
00286    LSB1(line_coding.dwDTERate) = Usb_read_byte();
00287    LSB2(line_coding.dwDTERate) = Usb_read_byte();
00288    LSB3(line_coding.dwDTERate) = Usb_read_byte();
00289    line_coding.bCharFormat = Usb_read_byte();
00290    line_coding.bParityType = Usb_read_byte();
00291    line_coding.bDataBits = Usb_read_byte();
00292      Usb_ack_receive_out();
00293 
00294      Usb_send_control_in();                // send a ZLP for STATUS phase
00295      while(!(Is_usb_read_control_enabled()));
00296 #ifdef UART_U2
00297    Uart_set_baudrate((line_coding.dwDTERate)/2);
00298 #else
00299    Uart_set_baudrate(line_coding.dwDTERate);
00300 #endif
00301 }
00302 
00303 
00314 void cdc_set_control_line_state (U16 state)
00315 {
00316      Usb_ack_receive_setup();
00317    Usb_send_control_in();
00318    line_status.all = state;
00319    
00320      while(!(Is_usb_read_control_enabled()));
00321 
00322 }
00323 
00336 Bool cdc_update_serial_state()
00337 {
00338    if( serial_state_saved.all != serial_state.all)
00339    {
00340       serial_state_saved.all = serial_state.all;
00341       
00342       Usb_select_endpoint(INT_EP);
00343       if (Is_usb_write_enabled())
00344       {
00345          Usb_write_byte(USB_SETUP_GET_CLASS_INTER);   // bmRequestType
00346          Usb_write_byte(SETUP_CDC_BN_SERIAL_STATE);   // bNotification
00347          
00348          Usb_write_byte(0x00);   // wValue (zero)
00349          Usb_write_byte(0x00);
00350          
00351          Usb_write_byte(0x00);   // wIndex (Interface)
00352          Usb_write_byte(0x00);
00353          
00354          Usb_write_byte(0x02);   // wLength (data count = 2)
00355          Usb_write_byte(0x00);
00356          
00357          Usb_write_byte(LSB(serial_state.all));   // data 0: LSB first of serial state
00358          Usb_write_byte(MSB(serial_state.all));   // data 1: MSB follows
00359          Usb_ack_in_ready();
00360       }
00361       return TRUE;
00362    }
00363    return FALSE;
00364 }
00365 
00372 void cdc_send_break(U16 break_duration)
00373 {
00374    Usb_ack_receive_setup();
00375     Usb_send_control_in();
00376    usb_request_break_generation=TRUE;
00377    while(!(Is_usb_read_control_enabled()));
00378 }
00379 
00380 

Generated on Fri Sep 11 14:46:05 2009 for ATMEL by  doxygen 1.5.3