SAMV71 Xplained Ultra Software Package 1.3

ctrl_access.c

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