SAMV71 Xplained Ultra Software Package 1.5

ctrl_access.c

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  *
00031  * \file
00032  *
00033  * \brief Abstraction layer for memory interfaces.
00034  *
00035  * This module contains the interfaces:
00036  *   - MEM <-> USB;
00037  *   - MEM <-> RAM;
00038  *   - MEM <-> MEM.
00039  *
00040  * This module may be configured and expanded to support the following features:
00041  *   - write-protected globals;
00042  *   - password-protected data;
00043  *   - specific features;
00044  *   - etc.
00045  *
00046  ******************************************************************************/
00047 /*
00048  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
00049  */
00050 
00051 
00052 //_____ I N C L U D E S ____________________________________________________
00053 
00054 #ifdef FREERTOS_USED
00055     #include "FreeRTOS.h"
00056     #include "semphr.h"
00057 #endif
00058 #include "ctrl_access.h"
00059 
00060 
00061 //_____ D E F I N I T I O N S ______________________________________________
00062 
00063 #ifdef FREERTOS_USED
00064 
00065     /*! \name LUN Access Protection Macros
00066     */
00067     //! @{
00068 
00069     /*! \brief Locks accesses to LUNs.
00070     *
00071     * \return \c true if the access was successfully locked, else \c false.
00072     */
00073     #define Ctrl_access_lock()    ctrl_access_lock()
00074 
00075     /*! \brief Unlocks accesses to LUNs.
00076     */
00077     #define Ctrl_access_unlock()  xSemaphoreGive(ctrl_access_semphr)
00078 
00079     //! @}
00080 
00081     //! Handle to the semaphore protecting accesses to LUNs.
00082     static xSemaphoreHandle ctrl_access_semphr = NULL;
00083 
00084 #else
00085 
00086     /*! \name LUN Access Protection Macros
00087     */
00088     //! @{
00089 
00090     /*! \brief Locks accesses to LUNs.
00091     *
00092     * \return \c true if the access was successfully locked, else \c false.
00093     */
00094     #define Ctrl_access_lock()    true
00095 
00096     /*! \brief Unlocks accesses to LUNs.
00097     */
00098     #define Ctrl_access_unlock()
00099 
00100     //! @}
00101 
00102 #endif  // FREERTOS_USED
00103 
00104 
00105 #if MAX_LUN
00106 
00107 /*! \brief Initializes an entry of the LUN descriptor table.
00108  *
00109  * \param lun Logical Unit Number.
00110  *
00111  * \return LUN descriptor table entry initializer.
00112  */
00113 #if ACCESS_USB == true && ACCESS_MEM_TO_RAM == true
00114 #define Lun_desc_entry(lun) \
00115     {\
00116         TPASTE3(Lun_, lun, _test_unit_ready),\
00117         TPASTE3(Lun_, lun, _read_capacity),\
00118         TPASTE3(Lun_, lun, _unload),\
00119         TPASTE3(Lun_, lun, _wr_protect),\
00120         TPASTE3(Lun_, lun, _removal),\
00121         TPASTE3(Lun_, lun, _usb_read_10),\
00122         TPASTE3(Lun_, lun, _usb_write_10),\
00123         TPASTE3(Lun_, lun, _mem_2_ram),\
00124         TPASTE3(Lun_, lun, _ram_2_mem),\
00125         TPASTE3(LUN_, lun, _NAME)\
00126     }
00127 #elif ACCESS_USB == true
00128 #define Lun_desc_entry(lun) \
00129     {\
00130         TPASTE3(Lun_, lun, _test_unit_ready),\
00131         TPASTE3(Lun_, lun, _read_capacity),\
00132         TPASTE3(Lun_, lun, _unload),\
00133         TPASTE3(Lun_, lun, _wr_protect),\
00134         TPASTE3(Lun_, lun, _removal),\
00135         TPASTE3(Lun_, lun, _usb_read_10),\
00136         TPASTE3(Lun_, lun, _usb_write_10),\
00137         TPASTE3(LUN_, lun, _NAME)\
00138     }
00139 #elif ACCESS_MEM_TO_RAM == true
00140 #define Lun_desc_entry(lun) \
00141     {\
00142         TPASTE3(Lun_, lun, _test_unit_ready),\
00143         TPASTE3(Lun_, lun, _read_capacity),\
00144         TPASTE3(Lun_, lun, _unload),\
00145         TPASTE3(Lun_, lun, _wr_protect),\
00146         TPASTE3(Lun_, lun, _removal),\
00147         TPASTE3(Lun_, lun, _mem_2_ram),\
00148         TPASTE3(Lun_, lun, _ram_2_mem),\
00149         TPASTE3(LUN_, lun, _NAME)\
00150     }
00151 #else
00152 #define Lun_desc_entry(lun) \
00153     {\
00154         TPASTE3(Lun_, lun, _test_unit_ready),\
00155         TPASTE3(Lun_, lun, _read_capacity),\
00156         TPASTE3(Lun_, lun, _unload),\
00157         TPASTE3(Lun_, lun, _wr_protect),\
00158         TPASTE3(Lun_, lun, _removal),\
00159         TPASTE3(LUN_, lun, _NAME)\
00160     }
00161 #endif
00162 
00163 //! LUN descriptor table.
00164 static const struct {
00165     Ctrl_status (*test_unit_ready)(void);
00166     Ctrl_status (*read_capacity)(uint32_t *);
00167     bool (*unload)(bool);
00168     bool (*wr_protect)(void);
00169     bool (*removal)(void);
00170 #if ACCESS_USB == true
00171     Ctrl_status (*usb_read_10)(uint32_t, U16);
00172     Ctrl_status (*usb_write_10)(uint32_t, U16);
00173 #endif
00174 #if ACCESS_MEM_TO_RAM == true
00175     Ctrl_status (*mem_2_ram)(uint32_t, void *);
00176     Ctrl_status (*ram_2_mem)(uint32_t, const void *);
00177 #endif
00178     const char *name;
00179 } lun_desc[MAX_LUN] = {
00180 #if LUN_0 == ENABLE
00181 # ifndef Lun_0_unload
00182 #  define Lun_0_unload NULL
00183 # endif
00184     Lun_desc_entry(0),
00185 #endif
00186 #if LUN_1 == ENABLE
00187 # ifndef Lun_1_unload
00188 #  define Lun_1_unload NULL
00189 # endif
00190     Lun_desc_entry(1),
00191 #endif
00192 #if LUN_2 == ENABLE
00193 # ifndef Lun_2_unload
00194 #  define Lun_2_unload NULL
00195 # endif
00196     Lun_desc_entry(2),
00197 #endif
00198 #if LUN_3 == ENABLE
00199 # ifndef Lun_3_unload
00200 #  define Lun_3_unload NULL
00201 # endif
00202     Lun_desc_entry(3),
00203 #endif
00204 #if LUN_4 == ENABLE
00205 # ifndef Lun_4_unload
00206 #  define Lun_4_unload NULL
00207 # endif
00208     Lun_desc_entry(4),
00209 #endif
00210 #if LUN_5 == ENABLE
00211 # ifndef Lun_5_unload
00212 #  define Lun_5_unload NULL
00213 # endif
00214     Lun_desc_entry(5),
00215 #endif
00216 #if LUN_6 == ENABLE
00217 # ifndef Lun_6_unload
00218 #  define Lun_6_unload NULL
00219 # endif
00220     Lun_desc_entry(6),
00221 #endif
00222 #if LUN_7 == ENABLE
00223 # ifndef Lun_7_unload
00224 #  define Lun_7_unload NULL
00225 # endif
00226     Lun_desc_entry(7)
00227 #endif
00228 };
00229 
00230 #endif
00231 
00232 
00233 #if GLOBAL_WR_PROTECT == true
00234     bool g_wr_protect;
00235 #endif
00236 
00237 
00238 /*! \name Control Interface
00239  */
00240 //! @{
00241 
00242 
00243 #ifdef FREERTOS_USED
00244 
00245 bool ctrl_access_init(void)
00246 {
00247     // If the handle to the protecting semaphore is not valid,
00248     if (!ctrl_access_semphr) {
00249         // try to create the semaphore.
00250         vSemaphoreCreateBinary(ctrl_access_semphr);
00251 
00252         // If the semaphore could not be created, there is no backup solution.
00253         if (!ctrl_access_semphr) return false;
00254     }
00255 
00256     return true;
00257 }
00258 
00259 
00260 /*! \brief Locks accesses to LUNs.
00261  *
00262  * \return \c true if the access was successfully locked, else \c false.
00263  */
00264 static bool ctrl_access_lock(void)
00265 {
00266     // If the semaphore could not be created, there is no backup solution.
00267     if (!ctrl_access_semphr) return false;
00268 
00269     // Wait for the semaphore.
00270     while (!xSemaphoreTake(ctrl_access_semphr, portMAX_DELAY));
00271 
00272     return true;
00273 }
00274 
00275 #endif  // FREERTOS_USED
00276 
00277 
00278 uint8_t get_nb_lun(void)
00279 {
00280 #if MEM_USB == ENABLE
00281 #  ifndef Lun_usb_get_lun
00282 #    define Lun_usb_get_lun()  host_get_lun()
00283 #  endif
00284     uint8_t nb_lun;
00285 
00286     if (!Ctrl_access_lock()) return MAX_LUN;
00287 
00288     nb_lun = MAX_LUN + Lun_usb_get_lun();
00289 
00290     Ctrl_access_unlock();
00291 
00292     return nb_lun;
00293 #else
00294     return MAX_LUN;
00295 #endif
00296 }
00297 
00298 
00299 uint8_t get_cur_lun(void)
00300 {
00301     return LUN_ID_0;
00302 }
00303 
00304 
00305 Ctrl_status mem_test_unit_ready(uint8_t lun)
00306 {
00307     Ctrl_status status;
00308 
00309     if (!Ctrl_access_lock()) return CTRL_FAIL;
00310 
00311     status =
00312 #if MAX_LUN
00313         (lun < MAX_LUN) ? lun_desc[lun].test_unit_ready() :
00314 #endif
00315 #if LUN_USB == ENABLE
00316         Lun_usb_test_unit_ready(lun - LUN_ID_USB);
00317 #else
00318         CTRL_FAIL;
00319 #endif
00320 
00321     Ctrl_access_unlock();
00322 
00323     return status;
00324 }
00325 
00326 
00327 Ctrl_status mem_read_capacity(uint8_t lun, uint32_t *u32_nb_sector)
00328 {
00329     Ctrl_status status;
00330 
00331     if (!Ctrl_access_lock()) return CTRL_FAIL;
00332 
00333     status =
00334 #if MAX_LUN
00335         (lun < MAX_LUN) ? lun_desc[lun].read_capacity(u32_nb_sector) :
00336 #endif
00337 #if LUN_USB == ENABLE
00338         Lun_usb_read_capacity(lun - LUN_ID_USB, u32_nb_sector);
00339 #else
00340         CTRL_FAIL;
00341 #endif
00342 
00343     Ctrl_access_unlock();
00344 
00345     return status;
00346 }
00347 
00348 
00349 uint8_t mem_sector_size(uint8_t lun)
00350 {
00351     uint8_t sector_size;
00352 
00353     if (!Ctrl_access_lock()) return 0;
00354 
00355     sector_size =
00356 #if MAX_LUN
00357         (lun < MAX_LUN) ? 1 :
00358 #endif
00359 #if LUN_USB == ENABLE
00360         Lun_usb_read_sector_size(lun - LUN_ID_USB);
00361 #else
00362         0;
00363 #endif
00364 
00365     Ctrl_access_unlock();
00366 
00367     return sector_size;
00368 }
00369 
00370 
00371 bool mem_unload(uint8_t lun, bool unload)
00372 {
00373     bool unloaded;
00374 #if !MAX_LUN || !defined(Lun_usb_unload)
00375     UNUSED(lun);
00376 #endif
00377 
00378     if (!Ctrl_access_lock()) return false;
00379 
00380     unloaded =
00381 #if MAX_LUN
00382         (lun < MAX_LUN) ?
00383         (lun_desc[lun].unload ?
00384          lun_desc[lun].unload(unload) : !unload) :
00385 #endif
00386 #if LUN_USB == ENABLE
00387 # if defined(Lun_usb_unload)
00388         Lun_usb_unload(lun - LUN_ID_USB, unload);
00389 # else
00390         !unload; /* Can not unload: load success, unload fail */
00391 # endif
00392 #else
00393         false; /* No mem, unload/load fail */
00394 #endif
00395 
00396     Ctrl_access_unlock();
00397 
00398     return unloaded;
00399 }
00400 
00401 bool mem_wr_protect(uint8_t lun)
00402 {
00403     bool wr_protect;
00404 
00405     if (!Ctrl_access_lock()) return true;
00406 
00407     wr_protect =
00408 #if MAX_LUN
00409         (lun < MAX_LUN) ? lun_desc[lun].wr_protect() :
00410 #endif
00411 #if LUN_USB == ENABLE
00412         Lun_usb_wr_protect(lun - LUN_ID_USB);
00413 #else
00414         true;
00415 #endif
00416 
00417     Ctrl_access_unlock();
00418 
00419     return wr_protect;
00420 }
00421 
00422 
00423 bool mem_removal(uint8_t lun)
00424 {
00425     bool removal;
00426 #if MAX_LUN==0
00427     UNUSED(lun);
00428 #endif
00429 
00430     if (!Ctrl_access_lock()) return true;
00431 
00432     removal =
00433 #if MAX_LUN
00434         (lun < MAX_LUN) ? lun_desc[lun].removal() :
00435 #endif
00436 #if LUN_USB == ENABLE
00437         Lun_usb_removal();
00438 #else
00439         true;
00440 #endif
00441 
00442     Ctrl_access_unlock();
00443 
00444     return removal;
00445 }
00446 
00447 
00448 const char *mem_name(uint8_t lun)
00449 {
00450 #if MAX_LUN==0
00451     UNUSED(lun);
00452 #endif
00453     return
00454 #if MAX_LUN
00455         (lun < MAX_LUN) ? lun_desc[lun].name :
00456 #endif
00457 #if LUN_USB == ENABLE
00458         LUN_USB_NAME;
00459 #else
00460         NULL;
00461 #endif
00462 }
00463 
00464 
00465 //! @}
00466 
00467 
00468 #if ACCESS_USB == true
00469 
00470 /*! \name MEM <-> USB Interface
00471  */
00472 //! @{
00473 
00474 
00475 Ctrl_status memory_2_usb(uint8_t lun, uint32_t addr, U16 nb_sector)
00476 {
00477     Ctrl_status status;
00478 
00479     if (!Ctrl_access_lock()) return CTRL_FAIL;
00480 
00481     memory_start_read_action(nb_sector);
00482     status =
00483 #if MAX_LUN
00484         (lun < MAX_LUN) ? lun_desc[lun].usb_read_10(addr, nb_sector) :
00485 #endif
00486         CTRL_FAIL;
00487     memory_stop_read_action();
00488 
00489     Ctrl_access_unlock();
00490 
00491     return status;
00492 }
00493 
00494 
00495 Ctrl_status usb_2_memory(uint8_t lun, uint32_t addr, U16 nb_sector)
00496 {
00497     Ctrl_status status;
00498 
00499     if (!Ctrl_access_lock()) return CTRL_FAIL;
00500 
00501     memory_start_write_action(nb_sector);
00502     status =
00503 #if MAX_LUN
00504         (lun < MAX_LUN) ? lun_desc[lun].usb_write_10(addr, nb_sector) :
00505 #endif
00506         CTRL_FAIL;
00507     memory_stop_write_action();
00508 
00509     Ctrl_access_unlock();
00510 
00511     return status;
00512 }
00513 
00514 
00515 //! @}
00516 
00517 #endif  // ACCESS_USB == true
00518 
00519 
00520 #if ACCESS_MEM_TO_RAM == true
00521 
00522 /*! \name MEM <-> RAM Interface
00523  */
00524 //! @{
00525 
00526 
00527 Ctrl_status memory_2_ram(uint8_t lun, uint32_t addr, void *ram)
00528 {
00529     Ctrl_status status;
00530 #if MAX_LUN==0
00531     UNUSED(lun);
00532 #endif
00533 
00534     if (!Ctrl_access_lock()) return CTRL_FAIL;
00535 
00536     memory_start_read_action(1);
00537     status =
00538 #if MAX_LUN
00539         (lun < MAX_LUN) ? lun_desc[lun].mem_2_ram(addr, ram) :
00540 #endif
00541 #if LUN_USB == ENABLE
00542         Lun_usb_mem_2_ram(addr, ram);
00543 #else
00544         CTRL_FAIL;
00545 #endif
00546     memory_stop_read_action();
00547 
00548     Ctrl_access_unlock();
00549 
00550     return status;
00551 }
00552 
00553 
00554 Ctrl_status ram_2_memory(uint8_t lun, uint32_t addr, const void *ram)
00555 {
00556     Ctrl_status status;
00557 #if MAX_LUN==0
00558     UNUSED(lun);
00559 #endif
00560 
00561     if (!Ctrl_access_lock()) return CTRL_FAIL;
00562 
00563     memory_start_write_action(1);
00564     status =
00565 #if MAX_LUN
00566         (lun < MAX_LUN) ? lun_desc[lun].ram_2_mem(addr, ram) :
00567 #endif
00568 #if LUN_USB == ENABLE
00569         Lun_usb_ram_2_mem(addr, ram);
00570 #else
00571         CTRL_FAIL;
00572 #endif
00573     memory_stop_write_action();
00574 
00575     Ctrl_access_unlock();
00576 
00577     return status;
00578 }
00579 
00580 
00581 //! @}
00582 
00583 #endif  // ACCESS_MEM_TO_RAM == true
00584 
00585 
00586 #if ACCESS_STREAM == true
00587 
00588 /*! \name Streaming MEM <-> MEM Interface
00589  */
00590 //! @{
00591 
00592 
00593 #if ACCESS_MEM_TO_MEM == true
00594 
00595 #include "fat.h"
00596 
00597 Ctrl_status stream_mem_to_mem(uint8_t src_lun, uint32_t src_addr,
00598                               uint8_t dest_lun, uint32_t dest_addr, U16 nb_sector)
00599 {
00600     COMPILER_ALIGNED(4)
00601     static uint8_t sector_buf[FS_512B];
00602     Ctrl_status status = CTRL_GOOD;
00603 
00604     while (nb_sector--) {
00605         if ((status = memory_2_ram(src_lun, src_addr++,
00606                                    sector_buf)) != CTRL_GOOD) break;
00607 
00608         if ((status = ram_2_memory(dest_lun, dest_addr++,
00609                                    sector_buf)) != CTRL_GOOD) break;
00610     }
00611 
00612     return status;
00613 }
00614 
00615 #endif  // ACCESS_MEM_TO_MEM == true
00616 
00617 
00618 Ctrl_status stream_state(uint8_t id)
00619 {
00620     UNUSED(id);
00621     return CTRL_GOOD;
00622 }
00623 
00624 
00625 U16 stream_stop(uint8_t id)
00626 {
00627     UNUSED(id);
00628     return 0;
00629 }
00630 
00631 
00632 //! @}
00633 
00634 #endif  // ACCESS_STREAM == true
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines