host_cdc_task.c

Go to the documentation of this file.
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 

Generated on Fri Oct 31 16:05:52 2008 for ATMEL by  doxygen 1.5.3