SAMV71 Xplained Ultra Software Package 1.3

uhi_msc_mem.c

Go to the documentation of this file.
00001 /**
00002  * \file
00003  *
00004  * \brief USB host Mass Storage interface for control access module..
00005  *
00006  * Copyright (C) 2011-2015 Atmel Corporation. All rights reserved.
00007  *
00008  * \asf_license_start
00009  *
00010  * \page License
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions are met:
00014  *
00015  * 1. Redistributions of source code must retain the above copyright notice,
00016  *    this list of conditions and the following disclaimer.
00017  *
00018  * 2. Redistributions in binary form must reproduce the above copyright notice,
00019  *    this list of conditions and the following disclaimer in the documentation
00020  *    and/or other materials provided with the distribution.
00021  *
00022  * 3. The name of Atmel may not be used to endorse or promote products derived
00023  *    from this software without specific prior written permission.
00024  *
00025  * 4. This software may only be redistributed and used in connection with an
00026  *    Atmel microcontroller product.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00029  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00030  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00031  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00032  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00033  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00034  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00035  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00036  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00037  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00038  * POSSIBILITY OF SUCH DAMAGE.
00039  *
00040  * \asf_license_stop
00041  *
00042  */
00043 /*
00044  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
00045  */
00046 
00047 #include "uhi_msc.h"
00048 #include "uhi_msc_mem.h"
00049 
00050 /**
00051  * \ingroup uhi_msc_mem_group
00052  * \defgroup uhi_msc_mem_group_internal Implementation of USB host Mass Storage
00053  * interface for control access module
00054  *
00055  * Internal implementation 
00056  * @{
00057  */
00058 
00059 /**
00060  * \name Internal variables
00061  */
00062 //@{
00063 //! Current LUN selected
00064 static uint8_t uhi_msc_mem_lun;
00065 //! \name Volatile flag tested by functions in pooling mode and updated by a callback
00066 //@{
00067 static volatile bool uhi_msc_mem_command_ongoing;
00068 static volatile bool uhi_msc_mem_command_status;
00069 //@}
00070 //@}
00071 
00072 /**
00073  * \name Internal functions
00074  */
00075 //@{
00076 static void uhi_msc_mem_stop_pooling(bool b_success);
00077 static Ctrl_status uhi_msc_mem_translate_status(lun_status_t status);
00078 //@}
00079 
00080 
00081 /**
00082  * \name External functions
00083  */
00084 //@{
00085 
00086 uint8_t uhi_msc_mem_get_lun(void)
00087 {
00088     while (!uhi_msc_is_available());
00089     return uhi_msc_get_lun();
00090 }
00091 
00092 Ctrl_status uhi_msc_mem_test_unit_ready(uint8_t lun)
00093 {
00094     uhi_msc_lun_t *lun_desc;
00095 
00096     while (!uhi_msc_is_available());
00097 
00098     uhi_msc_mem_command_ongoing = true;
00099     uhi_msc_mem_lun = lun;
00100     if (!uhi_msc_scsi_test_unit_ready(uhi_msc_mem_lun, uhi_msc_mem_stop_pooling)) {
00101         return CTRL_FAIL;
00102     }
00103     while (uhi_msc_mem_command_ongoing);
00104     if (!uhi_msc_mem_command_status) {
00105         return CTRL_FAIL;
00106     }
00107     lun_desc = uhi_msc_get_lun_desc(uhi_msc_mem_lun);
00108     return uhi_msc_mem_translate_status(lun_desc->status);
00109 }
00110 
00111 Ctrl_status uhi_msc_mem_read_capacity(uint8_t lun, uint32_t * u32_nb_sector)
00112 {
00113     uhi_msc_lun_t *lun_desc;
00114     uint32_t *pBlockLen ;
00115 
00116     while (!uhi_msc_is_available());
00117     uhi_msc_mem_lun = lun;
00118     lun_desc = uhi_msc_get_lun_desc(uhi_msc_mem_lun);
00119     pBlockLen = (uint32_t *)&lun_desc->capacity.pLogicalBlockLength[0];
00120 
00121     if (lun_desc == NULL) {
00122         return CTRL_FAIL;
00123     }
00124     if (*pBlockLen != 512) {
00125         // Note: The ctrl_access module uses only the data transfer size of 512 bytes.
00126         // The uhi_msc_mem module does not implement a RAM cache 
00127         // to support the transfer size more than 512 bytes.
00128         return CTRL_FAIL; // Not supported
00129     }
00130     *u32_nb_sector = (uint32_t)&lun_desc->capacity.pLogicalBlockAddress[0];
00131     return uhi_msc_mem_translate_status(lun_desc->status);
00132 }
00133 
00134 uint8_t uhi_msc_mem_read_sector_size(uint8_t lun)
00135 {
00136     uhi_msc_lun_t *lun_desc;
00137     uint32_t *pBlockLen ;
00138     while (!uhi_msc_is_available());
00139     uhi_msc_mem_lun = lun;
00140     lun_desc = uhi_msc_get_lun_desc(uhi_msc_mem_lun);
00141     pBlockLen = (uint32_t *)&lun_desc->capacity.pLogicalBlockLength[0];
00142 
00143     if (lun_desc == NULL) {
00144         return 0;
00145     }
00146     return ((*pBlockLen) / 512);
00147 }
00148 
00149 bool uhi_msc_mem_wr_protect(uint8_t lun)
00150 {
00151     uhi_msc_lun_t *lun_desc;
00152     uint32_t *pBlockLen ;
00153     
00154     while (!uhi_msc_is_available());
00155     uhi_msc_mem_lun = lun;
00156     lun_desc = uhi_msc_get_lun_desc(uhi_msc_mem_lun);
00157     pBlockLen = (uint32_t *)&lun_desc->capacity.pLogicalBlockLength[0];
00158 
00159     if (lun_desc == NULL) {
00160         return true;
00161     }
00162     if (*pBlockLen != 512) {
00163         return true;
00164     }
00165     return lun_desc->b_write_protected;
00166 }
00167 
00168 bool uhi_msc_mem_removal(void)
00169 {
00170     return true;
00171 }
00172 
00173 Ctrl_status uhi_msc_mem_read_10_ram(uint32_t addr, void *ram)
00174 {
00175     uhi_msc_lun_t *lun_desc;
00176     uint32_t *pBlockLen ;
00177 
00178     while (!uhi_msc_is_available());
00179     // uhi_msc_mem_lun already selected by a previous command
00180     lun_desc = uhi_msc_get_lun_desc(uhi_msc_mem_lun);
00181     pBlockLen = (uint32_t *)&lun_desc->capacity.pLogicalBlockLength[0];
00182 
00183     if (lun_desc == NULL) {
00184         return CTRL_FAIL;
00185     }
00186     if (uhi_msc_mem_translate_status(lun_desc->status) != CTRL_GOOD) {
00187         return uhi_msc_mem_translate_status(lun_desc->status);
00188     }
00189     if (*pBlockLen != 512) {
00190         return CTRL_FAIL; // Not supported
00191     }
00192     uhi_msc_mem_command_ongoing = true;
00193     uhi_msc_scsi_read_10(uhi_msc_mem_lun, addr, ram, 1,
00194             uhi_msc_mem_stop_pooling);
00195     while (uhi_msc_mem_command_ongoing);
00196     if (!uhi_msc_mem_command_status) {
00197         return CTRL_FAIL;
00198     }
00199     return uhi_msc_mem_translate_status(lun_desc->status);
00200 
00201 }
00202 
00203 Ctrl_status uhi_msc_mem_write_10_ram(uint32_t addr, const void *ram)
00204 {
00205     uhi_msc_lun_t *lun_desc;
00206     uint32_t *pBlockLen;
00207 
00208     while (!uhi_msc_is_available());
00209     // uhi_msc_mem_lun already selected by a previous command
00210     lun_desc = uhi_msc_get_lun_desc(uhi_msc_mem_lun);
00211     pBlockLen = (uint32_t *)&lun_desc->capacity.pLogicalBlockLength[0];
00212 
00213     if (lun_desc == NULL) {
00214         return CTRL_FAIL;
00215     }
00216     if (uhi_msc_mem_translate_status(lun_desc->status) != CTRL_GOOD) {
00217         return uhi_msc_mem_translate_status(lun_desc->status);
00218     }
00219     if (*pBlockLen != 512) {
00220         return CTRL_FAIL; // Not supported
00221     }
00222     uhi_msc_mem_command_ongoing = true;
00223     uhi_msc_scsi_write_10(uhi_msc_mem_lun, addr, ram, 1,
00224             uhi_msc_mem_stop_pooling);
00225     while (uhi_msc_mem_command_ongoing);
00226     if (!uhi_msc_mem_command_status) {
00227         return CTRL_FAIL;
00228     }
00229     return uhi_msc_mem_translate_status(lun_desc->status);
00230 }
00231 
00232 //@}
00233 
00234 /**
00235  * \name Internal functions
00236  */
00237 //@{
00238 
00239 /**
00240  * \brief Callback to update volatile variable used by pooling
00241  *
00242  * \param b_success true, if the scsi command is successful
00243  */
00244 static void uhi_msc_mem_stop_pooling(bool b_success)
00245 {
00246     uhi_msc_mem_command_ongoing = false;
00247     uhi_msc_mem_command_status = b_success;
00248 }
00249 
00250 /**
00251  * \brief Translates the LUN status from UHI MSC to CTRL ACCESS module
00252  *
00253  * \param status   UHI MSC LUN status
00254  *
00255  * \return CTRL ACCESS LUN status
00256  */
00257 static Ctrl_status uhi_msc_mem_translate_status(lun_status_t status)
00258 {
00259     switch (status) {
00260     case LUN_GOOD:
00261         return CTRL_GOOD;
00262     case LUN_NOT_PRESENT:
00263         return CTRL_NO_PRESENT;
00264     case LUN_BUSY:
00265         return CTRL_BUSY;
00266     case LUN_FAIL:
00267     default:
00268         return CTRL_FAIL;
00269     }
00270 }
00271 
00272 //@}
00273 
00274 //@}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines