00001 //----------------------------------------------------------------------------- 00002 // USB_Class_Requests.c 00003 //----------------------------------------------------------------------------- 00004 00005 //----------------------------------------------------------------------------- 00006 // Includes 00007 //----------------------------------------------------------------------------- 00008 00009 #include "USB_Type.h" 00010 #include "USB_Configuration.h" 00011 #include "USB_Descriptor.h" 00012 #include "USB_Standard_Requests.h" 00013 #include "USB_ISR.h" 00014 #include "USB_CDC_UART.h" 00015 #include "USB_Main.h" 00016 #include "USB_Class_Requests.h" 00017 00018 //----------------------------------------------------------------------------- 00019 // Global Variables 00020 //----------------------------------------------------------------------------- 00021 00022 #define CS_TEMPBUF_SIZE sizeof(TLine_Coding) // size of temporary buffer 00023 // must be greater than sizeof(TLine_Coding) (= 7 bytes) 00024 BYTE idata cs_temp_buffer[ CS_TEMPBUF_SIZE ]; // temporary buffer for 00025 // CS_Get_Encapsulated_Command 00026 // CS_Send_Encapsulated_Command 00027 // CS_Set_Line_Coding and CS_Get_Line_Coding 00028 00029 //----------------------------------------------------------------------------- 00030 // Static Variables in this file 00031 //----------------------------------------------------------------------------- 00032 00033 /* 00034 #define CS_TEMP_BUF_SIZE 0x10 00035 static BYTE cs_temp_buffer[ CS_TEMP_BUF_SIZE ]; 00036 */ 00037 00038 //----------------------------------------------------------------------------- 00039 // Local function prototypes 00040 //----------------------------------------------------------------------------- 00041 00042 //----------------------------------------------------------------------------- 00043 // Local Function prototypes 00044 //----------------------------------------------------------------------------- 00045 00046 // for CDC 00047 static void CS_Send_Encapsulated_Command(void); 00048 static void CS_Get_Encapsulated_Command(void); 00049 static void CS_Set_Line_Coding(void); 00050 static bit CS_Set_Line_Coding_Complete(void); 00051 static void CS_Get_Line_Coding(void); 00052 static void CS_Set_ControlLine_State(void); 00053 static void CS_Send_Break(void); 00054 00055 #if defined BIG_ENDIAN 00056 00057 void swap_endian_long( ULONG idata *lptr ); 00058 00059 #endif // end of BIG_ENDIAN 00060 00061 00062 //----------------------------------------------------------------------------- 00063 // SDCC suport 00064 //----------------------------------------------------------------------------- 00065 #if defined SDCC 00066 #pragma nooverlay 00067 #endif // SDCC 00068 00069 //----------------------------------------------------------------------------- 00070 // class specific request dispatcher 00071 //----------------------------------------------------------------------------- 00072 00073 void Class_Request( void ) 00074 { 00075 // CDC class request dispatcher 00076 if ( Setup.wIndex.i == DSC_INTERFACE_CDC_comm ) 00077 { 00078 switch(Setup.bRequest) 00079 { 00080 case SEND_ENCAPSULATED_COMMAND: CS_Send_Encapsulated_Command(); break; 00081 case GET_ENCAPSULATED_RESPONSE: CS_Get_Encapsulated_Command(); break; 00082 case SET_LINE_CODING: CS_Set_Line_Coding(); break; 00083 case GET_LINE_CODING: CS_Get_Line_Coding(); break; 00084 case SET_CONTROL_LINE_STATE: CS_Set_ControlLine_State(); break; 00085 case SEND_BREAK: CS_Send_Break(); break; 00086 default: break; 00087 } 00088 } 00089 } 00090 00091 //----------------------------------------------------------------------------- 00092 // CDC class request handlers 00093 //----------------------------------------------------------------------------- 00094 00095 //----------------------------------------------------------------------------- 00096 // Send_Encapsulated_Command 00097 //----------------------------------------------------------------------------- 00098 // 00099 // Nothing to do other than unloading the data sent in the data stage. 00100 // 00101 //----------------------------------------------------------------------------- 00102 00103 void CS_Send_Encapsulated_Command(void) 00104 { 00105 if ( (Setup.bmRequestType == OUT_CL_INTERFACE) 00106 && (Setup.wValue.i == 0 ) 00107 && (Setup.wLength.i <= CS_TEMPBUF_SIZE) ) // less than the buffer size 00108 { 00109 Ep_Status0 = EP_RX; // Put endpoint in recieve mode 00110 DataPtr = (BYTE *)cs_temp_buffer; 00111 DataSize = Setup.wLength.i; // Read out the command sent 00112 setup_handled = TRUE; 00113 } 00114 } 00115 00116 //----------------------------------------------------------------------------- 00117 // Get_Encapsulated_Command 00118 //----------------------------------------------------------------------------- 00119 // 00120 // Return a zero-length packet 00121 // 00122 //----------------------------------------------------------------------------- 00123 00124 void CS_Get_Encapsulated_Command(void) 00125 { 00126 if ( (Setup.bmRequestType == IN_CL_INTERFACE) 00127 && (Setup.wValue.i == 0) ) 00128 { 00129 Ep_Status0 = EP_TX; // Put endpoint in transmit mode 00130 DataPtr = (BYTE *)cs_temp_buffer; 00131 DataSize = 0; // Send ZLP 00132 setup_handled = TRUE; 00133 } 00134 } 00135 00136 //----------------------------------------------------------------------------- 00137 // Set_Line_Coding 00138 //----------------------------------------------------------------------------- 00139 // 00140 // Unload the line coding structure (7 bytes) sent in the data stage. 00141 // Apply this setting to the UART 00142 // Flush the communication buffer 00143 // 00144 // Line Coding Structure (7 bytes) 00145 // 0-3 dwDTERate Data terminal rate (baudrate), in bits per second (LSB first) 00146 // 4 bCharFormat Stop bits: 0 - 1 Stop bit, 1 - 1.5 Stop bits, 2 - 2 Stop bits 00147 // 5 bParityType Parity: 0 - None, 1 - Odd, 2 - Even, 3 - Mark, 4 - Space 00148 // 6 bDataBits Data bits: 5, 6, 7, 8, 16 00149 // 00150 //----------------------------------------------------------------------------- 00151 00152 void CS_Set_Line_Coding(void) 00153 { 00154 if ( (Setup.bmRequestType == OUT_CL_INTERFACE) 00155 && (Setup.wValue.i == 0) 00156 && (Setup.wLength.i == sizeof(TLine_Coding)) ) 00157 { 00158 Ep_Status0 = EP_RX; // Put endpoint in recieve mode 00159 DataPtr = (BYTE *)cs_temp_buffer; 00160 DataSize = sizeof(TLine_Coding); // Read out the command sent 00161 USB_request_callback = CS_Set_Line_Coding_Complete; 00162 setup_handled = TRUE; 00163 } 00164 } 00165 00166 // called at the end of data stage 00167 bit CS_Set_Line_Coding_Complete(void) 00168 { 00169 00170 #if defined BIG_ENDIAN 00171 // swap baudrate field LSB first --> MSB first 00172 swap_endian_long( (ULONG idata *)cs_temp_buffer ); 00173 00174 #endif // end of BIG_ENDIAN 00175 00176 return Set_Line_Coding( (TLine_Coding idata *)cs_temp_buffer ); 00177 } 00178 00179 //----------------------------------------------------------------------------- 00180 // Get_Line_Coding 00181 //----------------------------------------------------------------------------- 00182 // 00183 // Return the line coding structure 00184 // 00185 //----------------------------------------------------------------------------- 00186 00187 void CS_Get_Line_Coding(void) 00188 { 00189 if ( (Setup.bmRequestType == IN_CL_INTERFACE) 00190 && (Setup.wValue.i == 0) 00191 && (Setup.wLength.i == sizeof(TLine_Coding)) ) 00192 { 00193 00194 #if defined BIG_ENDIAN 00195 BYTE cnt; 00196 BYTE idata * dst; 00197 BYTE idata * src; 00198 00199 dst = cs_temp_buffer; // copy line coding structure 00200 src = (BYTE idata *)&uart_line_coding; 00201 for (cnt = sizeof( TLine_Coding ); cnt > 0; cnt--) 00202 *dst++ = *src++; 00203 00204 swap_endian_long( (ULONG idata *)cs_temp_buffer ); 00205 00206 DataPtr = (BYTE *)cs_temp_buffer; 00207 #else 00208 DataPtr = (BYTE *)(&uart_line_coding); // send it directly 00209 #endif // end of BIG_ENDIAN 00210 00211 Ep_Status0 = EP_TX; // Put endpoint in transmit mode 00212 DataSize = sizeof(TLine_Coding); // Send Line coding 00213 setup_handled = TRUE; 00214 } 00215 } 00216 00217 //----------------------------------------------------------------------------- 00218 // Set_ControlLine_State 00219 //----------------------------------------------------------------------------- 00220 // 00221 // Set/reset RTS/DTR according to wValue 00222 // wValue 00223 // bit 1 RTS 00224 // bit 0 DTR 00225 // 00226 //----------------------------------------------------------------------------- 00227 00228 void CS_Set_ControlLine_State(void) 00229 { 00230 if ( (Setup.bmRequestType == OUT_CL_INTERFACE) 00231 && (Setup.wLength.i == 0) ) 00232 { 00233 Set_Line_State( Setup.wValue.c[LSB] & (CDC_RTS | CDC_DTR ) ); 00234 setup_handled = TRUE; 00235 } 00236 } 00237 00238 //----------------------------------------------------------------------------- 00239 // Send_Break 00240 //----------------------------------------------------------------------------- 00241 // 00242 // Send break from UART TX port, for wValue (msec) duration. 00243 // wValue 00244 // 0xFFFF: continuous break 00245 // 0x0000: stop break 00246 // 00247 //----------------------------------------------------------------------------- 00248 00249 void CS_Send_Break(void) 00250 { 00251 if ( (Setup.bmRequestType == OUT_CL_INTERFACE) 00252 && (Setup.wLength.i == 0) ) 00253 { 00254 Send_Break( Setup.wValue.i ); 00255 setup_handled = TRUE; 00256 } 00257 } 00258 00259 //----------------------------------------------------------------------------- 00260 // swap_endian_long 00261 //----------------------------------------------------------------------------- 00262 // swap endian for long varialbe 00263 //----------------------------------------------------------------------------- 00264 00265 #if defined BIG_ENDIAN 00266 00267 void swap_endian_long( ULONG idata *lptr ) 00268 { 00269 BYTE tmp[4]; 00270 BYTE idata * ptr = (BYTE idata *)lptr; 00271 00272 tmp[3] = ptr[0]; 00273 tmp[2] = ptr[1]; 00274 tmp[1] = ptr[2]; 00275 tmp[0] = ptr[3]; 00276 00277 ptr[0] = tmp[0]; 00278 ptr[1] = tmp[1]; 00279 ptr[2] = tmp[2]; 00280 ptr[3] = tmp[3]; 00281 } 00282 00283 #endif // end of BIG_ENDIAN 00284 00285 00286 //----------------------------------------------------------------------------- 00287 // End Of File 00288 //-----------------------------------------------------------------------------