SAMV71 Xplained Ultra Software Package 1.5

uhi_msc_mem.c

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