storage_task.c

Go to the documentation of this file.
00001 /*This file is prepared for Doxygen automatic documentation generation.*/
00013 
00014 /* Copyright (c) 2009 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  * 4. This software may only be redistributed and used in connection with an Atmel
00030  * AVR product.
00031  *
00032  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00033  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00034  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
00035  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00036  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00037  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00038  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00039  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00040  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00041  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00042  */
00043 
00044 //_____  I N C L U D E S ___________________________________________________
00045 
00046 #include "config.h"
00047 #include "conf_usb.h"
00048 #include "storage_task.h"
00049 #include "lib_mcu/usb/usb_drv.h"
00050 #include "usb_descriptors.h"
00051 #include "modules/usb/device_chap9/usb_standard_request.h"
00052 #include "usb_specific_request.h"
00053 #include "modules/scsi_decoder/scsi_decoder.h"
00054 #include "modules/control_access/ctrl_access.h"
00055 
00056 
00057 //_____ D E C L A R A T I O N S ____________________________________________
00058 
00059 
00060 
00061 bit ms_data_direction;
00062 static _MEM_TYPE_SLOW_ U8  dCBWTag[4];
00063 
00064 extern _MEM_TYPE_SLOW_ U8  g_scsi_status;
00065 extern _MEM_TYPE_FAST_ U32 g_scsi_data_remaining;
00066 extern bit ms_multiple_drive;
00067 extern _MEM_TYPE_SLOW_ U8  g_scsi_command[16];
00068 
00069 extern U8   endpoint_status[MAX_EP_NB];
00070 
00071 _MEM_TYPE_SLOW_ U8 usb_LUN;
00072 
00073 
00074 void usb_mass_storage_cbw (void);
00075 void usb_mass_storage_csw (void);
00076 
00086 void storage_task_init(void)
00087 {
00088    Leds_init();
00089    Usb_enable_sof_interrupt();
00090    df_mem_init();    // Init the hw/sw ressources required to drive the DF.
00091 }
00092 
00093 
00102 void storage_task(void)
00103 {
00104    if(Is_usb_id_device())
00105    {
00106       Usb_enable_sof_interrupt();   // In case of interrupt disabled when USB ID pin change
00107    }
00108    if (Is_device_enumerated())
00109    {
00110       Usb_select_endpoint(EP_MS_OUT);
00111       if (Is_usb_receive_out())
00112       {
00113          usb_mass_storage_cbw();
00114          usb_mass_storage_csw();
00115       }
00116    }
00117 }
00118 
00119 
00120 
00121 
00122 
00123 
00133 void usb_mass_storage_cbw (void)
00134 {
00135 bit cbw_error;
00136 U8  c;
00137 U8  dummy;
00138 
00139    cbw_error = FALSE;
00140    Usb_select_endpoint(EP_MS_OUT);           
00141    if (0x55 != Usb_read_byte())
00142       { cbw_error = TRUE; } 
00143    if (0x53 != Usb_read_byte())
00144       { cbw_error = TRUE; } 
00145    if (0x42 != Usb_read_byte())
00146       { cbw_error = TRUE; } 
00147    if (0x43 != Usb_read_byte())
00148       { cbw_error = TRUE; } 
00149    if (cbw_error)
00150    {
00151       Usb_ack_receive_out();
00152       Usb_select_endpoint(EP_MS_IN);
00153       Usb_enable_stall_handshake();
00154       endpoint_status[(EP_MS_IN & MSK_EP_DIR)] = 0x01;
00155       return;
00156    }
00157 
00158    dCBWTag[0] = Usb_read_byte();             
00159    dCBWTag[1] = Usb_read_byte();
00160    dCBWTag[2] = Usb_read_byte();
00161    dCBWTag[3] = Usb_read_byte();
00162    
00163    LSB0(g_scsi_data_remaining) = Usb_read_byte();
00164    LSB1(g_scsi_data_remaining) = Usb_read_byte();
00165    LSB2(g_scsi_data_remaining) = Usb_read_byte();
00166    LSB3(g_scsi_data_remaining) = Usb_read_byte();
00167 
00168    if (Usb_read_byte() != 0x00)              
00169    {
00170       Usb_set_ms_data_direction_in();
00171    }
00172    else
00173    {
00174       Usb_set_ms_data_direction_out();
00175    }
00176 
00177    usb_LUN = Usb_read_byte();
00178 
00179    if (!ms_multiple_drive)
00180    {
00181       usb_LUN = get_cur_lun();
00182    }
00183 
00184    dummy      = Usb_read_byte();                // dummy CBWCBLength read
00185 
00186 
00187    for (c=0; c<16; c++)                         // store scsi_command
00188    {
00189       g_scsi_command[c] = Usb_read_byte();
00190    }
00191    Usb_ack_receive_out();
00192 
00193    if (Is_usb_ms_data_direction_in())
00194    {
00195       Usb_select_endpoint(EP_MS_IN);
00196    }
00197 
00198    if (TRUE != scsi_decode_command())
00199    {
00200       U8 ep;
00201       Usb_enable_stall_handshake();
00202       if (Is_usb_ms_data_direction_in())
00203       {
00204          ep = (EP_MS_IN & MSK_EP_DIR);
00205       }else{
00206          ep = (EP_MS_OUT & MSK_EP_DIR);
00207       }
00208       endpoint_status[ep] = 0x01;
00209    }
00210 }
00211 
00212 
00221 void usb_mass_storage_csw (void)
00222 {
00223    Usb_select_endpoint(EP_MS_IN);
00224    while (Is_usb_endpoint_stall_requested())
00225    {
00226       Usb_select_endpoint(EP_CONTROL);
00227       if (Is_usb_receive_setup())       { usb_process_request(); }
00228       Usb_select_endpoint(EP_MS_IN);
00229    }
00230 
00231    Usb_select_endpoint(EP_MS_OUT);
00232    while (Is_usb_endpoint_stall_requested())
00233    {
00234       Usb_select_endpoint(EP_CONTROL);
00235       if (Is_usb_receive_setup())       { usb_process_request(); }
00236       Usb_select_endpoint(EP_MS_OUT);
00237    }
00238 
00239 
00240    Usb_select_endpoint(EP_MS_IN);
00241    while(!Is_usb_write_enabled())
00242    {
00243       if(!Is_usb_endpoint_enabled())   return; // USB Reset
00244    }
00246    Usb_write_byte(0x55);                                 
00247    Usb_write_byte(0x53);                                 
00248    Usb_write_byte(0x42);                                 
00249    Usb_write_byte(0x53);                                 
00250 
00251    Usb_write_byte(dCBWTag[0]);
00252    Usb_write_byte(dCBWTag[1]);
00253    Usb_write_byte(dCBWTag[2]);
00254    Usb_write_byte(dCBWTag[3]);
00256    Usb_write_byte( LSB0(g_scsi_data_remaining) );
00257    Usb_write_byte( LSB1(g_scsi_data_remaining) );
00258    Usb_write_byte( LSB2(g_scsi_data_remaining) );
00259    Usb_write_byte( LSB3(g_scsi_data_remaining) );
00260 
00262    Usb_write_byte(g_scsi_status);                        
00263 
00264    Usb_send_in();
00265 }

Generated on Wed Sep 23 09:37:10 2009 for ATMEL by  doxygen 1.5.3