00001 /*This file has been prepared for Doxygen automatic documentation generation.*/ 00013 00014 /* Copyright (c) 2007, Atmel Corporation All rights reserved. 00015 * 00016 * Redistribution and use in source and binary forms, with or without 00017 * modification, are permitted provided that the following conditions are met: 00018 * 00019 * 1. Redistributions of source code must retain the above copyright notice, 00020 * this list of conditions and the following disclaimer. 00021 * 00022 * 2. Redistributions in binary form must reproduce the above copyright notice, 00023 * this list of conditions and the following disclaimer in the documentation 00024 * and/or other materials provided with the distribution. 00025 * 00026 * 3. The name of ATMEL may not be used to endorse or promote products derived 00027 * from this software without specific prior written permission. 00028 * 00029 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED 00030 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00031 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND 00032 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 00033 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00034 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00035 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00036 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00037 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00038 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00039 */ 00040 00041 //_____ I N C L U D E S ___________________________________________________ 00042 00043 #include "config.h" 00044 #include "conf_usb.h" 00045 #include "host_cdc_task.h" 00046 #include "modules/usb/host_chap9/usb_host_task.h" 00047 #include "modules/usb/host_chap9/usb_host_enum.h" 00048 #include "lib_mcu/usb/usb_drv.h" 00049 #ifdef CDC_USE_UART 00050 #include "lib_mcu/uart/uart_lib.h" 00051 #endif 00052 00053 //_____ M A C R O S ________________________________________________________ 00054 00055 #ifndef LOG_STR_CODE 00056 #define LOG_STR_CODE(str) 00057 #else 00058 U8 code log_cdc_connect[]="CDC Connected"; 00059 #endif 00060 00061 //_____ D E F I N I T I O N S ______________________________________________ 00062 00063 00064 //_____ D E C L A R A T I O N S ____________________________________________ 00065 00066 U8 cdc_connected; 00067 U8 cdc_interface_comm; 00068 U8 cdc_cpt_sof; 00069 00070 U8 pipe_cdc_comm_int; 00071 U8 pipe_cdc_data_bulkin; 00072 U8 pipe_cdc_data_bulkout; 00073 00074 U8 tx_counter; 00075 U8 rx_counter; 00076 U8 cdc_stream_out_array[CDC_STREAM_OUT_SIZE]; 00077 U8 cdc_stream_in_array[CDC_STREAM_IN_SIZE]; 00078 00079 00082 void host_cdc_task_init(void) 00083 { 00084 #ifdef CDC_USE_UART 00085 uart_init(); 00086 #endif 00087 Leds_init(); 00088 cdc_connected = 0; 00089 cdc_interface_comm = 0; 00090 Joy_init(); 00091 } 00092 00093 00096 void host_cdc_task(void) 00097 { 00098 U8 i; 00099 00100 if(Is_host_ready()) 00101 { 00102 if(Is_new_device_connection_event()) 00103 { 00104 cdc_connected=0; 00105 Led0_on(); 00106 for(i=0;i<Get_nb_supported_interface();i++) 00107 { 00108 // Data Interface 00109 if((Get_class(i)==CDC_DATA_CLASS) && (Get_protocol(i)==CDC_DATA_PROTOCOL)) 00110 { 00111 cdc_connected=1; 00112 Host_enable_sof_interrupt(); 00113 LOG_STR_CODE(log_cdc_connect); 00114 if(Is_ep_addr_in(Get_ep_addr(i,0))) 00115 { // Yes associate it to the CDC Data IN pipe 00116 pipe_cdc_data_bulkin = host_get_hwd_pipe_nb(Get_ep_addr(i,0)); 00117 pipe_cdc_data_bulkout = host_get_hwd_pipe_nb(Get_ep_addr(i,1)); 00118 } 00119 else 00120 { // No, invert... 00121 pipe_cdc_data_bulkin = host_get_hwd_pipe_nb(Get_ep_addr(i,1)); 00122 pipe_cdc_data_bulkout = host_get_hwd_pipe_nb(Get_ep_addr(i,0)); 00123 } 00124 Host_select_pipe(PIPE_CDC_DATA_IN); 00125 Host_continuous_in_mode(); 00126 Host_unfreeze_pipe(); 00127 break; 00128 } 00129 // Management Interface 00130 #ifdef CDC_USE_MANAGEMENT_INTERFACE 00131 if(Get_class(i)==CDC_COMM_CLASS && Get_protocol(i)==CDC_COMM_PROTOCOL) 00132 { 00133 cdc_interface_comm = i; // store interface number 00134 pipe_cdc_comm_int = host_get_hwd_pipe_nb(Get_ep_addr(i,0)); 00135 Host_select_pipe(PIPE_CDC_COMM); 00136 Host_continuous_in_mode(); 00137 Host_unfreeze_pipe(); 00138 } 00139 #endif 00140 } 00141 // Open port (according cdc spec 1.1 chapter 6.2.14) 00142 usb_request.bmRequestType = USB_SETUP_SET_CLASS_INTER; 00143 usb_request.bRequest = SETUP_CDC_SET_CONTROL_LINE_STATE; 00144 usb_request.wValue = 0x03; 00145 usb_request.wIndex = 0; 00146 usb_request.wLength = 0; 00147 usb_request.uncomplete_read = FALSE; 00148 if( CONTROL_GOOD == host_send_control(0)) 00149 { 00150 Led1_on(); 00151 } 00152 } 00153 00154 if(cdc_connected) 00155 { 00156 // Check DATA_PIPE_IN for incoming data 00157 // ************************************ 00158 // 1 -> UART-USB Mode 00159 // Data received is automatically sent on the UART 00160 // 2 -> Normal Mode 00161 // Data received is stored in the "cdc_stream_in_array[CDC_STREAM_IN_SIZE]" array and may be read by firmware 00162 // When firmware reads the array it must do it entirely and then set "rx_counter" variable to 0 00163 // It must not partially read the array and decrement rx_counter (will lead to array overflow) 00164 Host_select_pipe(PIPE_CDC_DATA_IN); 00165 if (Is_host_in_received() && (Is_host_stall()==FALSE)) 00166 { 00167 #ifdef CDC_USE_UART 00168 while (Host_data_length_U8() != 0) 00169 { 00170 uart_putchar(Host_read_byte()); 00171 } 00172 Host_ack_in_received(); // pipe is empty 00173 Host_send_in(); // ready to receive more data 00174 #else 00175 while ((rx_counter != CDC_STREAM_IN_SIZE) && (Host_data_length_U8() != 0)) 00176 { 00177 cdc_stream_in_array[rx_counter] = Host_read_byte(); 00178 rx_counter++; 00179 } 00180 if (Host_data_length_U8() == 0) 00181 { 00182 Host_ack_in_received(); // pipe is empty 00183 Host_send_in(); // ready to receive more data 00184 } 00185 #endif 00186 } 00187 00188 00189 // Check if data to send on DATA_PIPE_OUT state 00190 // ******************************************** 00191 // Data to be sent is stored in the "cdc_stream_out_array[CDC_STREAM_OUT_SIZE]" array 00192 // Data may come indifferently from neither UART or RAM (firmware) 00193 // Data is sent to CDC Device when : 00194 // - user requires it, by calling "cdc_pipe_out_usb_flush()" function 00195 // - time-out period is elapsed (CDC_NB_MS_BEFORE_FLUSH = number of SOF seen) 00196 // - buffer is full (tx_counter = CDC_STREAM_OUT_SIZE) 00197 00198 #ifdef CDC_USE_UART 00199 // Check if new byte in USART, to be stored for USB 00200 if (uart_test_hit() && (tx_counter != CDC_STREAM_OUT_SIZE)) 00201 { 00202 cdc_stream_out_array[tx_counter] = uart_getchar(); 00203 tx_counter++; 00204 } 00205 #endif 00206 00207 // Check if pipe flush is needed (buffer full or time-out period elapsed) 00208 if(((cdc_cpt_sof>=CDC_NB_MS_BEFORE_FLUSH) && (tx_counter!=0)) || (tx_counter == CDC_STREAM_OUT_SIZE)) //Flush buffer by Timeout 00209 { 00210 cdc_cpt_sof=0; 00211 cdc_pipe_out_usb_flush(); 00212 } 00213 00214 00215 // Check in COMM_PIPE_IN for incoming notifications 00216 // ************************************************ 00217 Host_select_pipe(PIPE_CDC_COMM); 00218 if (Is_host_in_received()) 00219 { 00220 // Handle here notification messages sent by device 00221 // Notifications messages have the following structure : 00222 // bmRequestType - bNotification - wValue - wIndex - wLength - Data (wLength is the number of bytes of the Data field) 00223 00224 // - NETWORK_CONNECTION : indicates that device has connected to network 00225 // - RESPONSE_AVAILABLE : indicates that device has a ready encapsulated response (wait for host request) 00226 // - SERIAL_STATE : indicates state of device' UART (errors, carriers and misc. signals) 00227 // - etc... 00228 00229 // ...and now...just coding... 00230 Host_ack_in_received(); 00231 Host_send_in(); 00232 } 00233 } 00234 } 00235 00236 // Device disconnection... 00237 if(Is_device_disconnection_event()) 00238 { 00239 Leds_off(); 00240 cdc_connected=0; 00241 cdc_interface_comm = 0; 00242 } 00243 } 00244 00245 00250 void sof_action(void) 00251 { 00252 cdc_cpt_sof++; 00253 } 00254 00255 00259 void cdc_pipe_out_usb_flush (void) 00260 { 00261 Host_select_pipe(PIPE_CDC_DATA_IN); // BULK IN must be frozen else BULK OUT may not be sent 00262 Host_freeze_pipe(); 00263 if (PIPE_GOOD == host_send_data(PIPE_CDC_DATA_OUT, tx_counter, cdc_stream_out_array)) 00264 { 00265 tx_counter = 0; // if frame not sent, will try again next time (no data loss) 00266 } 00267 Host_select_pipe(PIPE_CDC_DATA_IN); 00268 Host_unfreeze_pipe(); 00269 } 00270 00271
1.5.3