SAMV71 Xplained Ultra Software Package 1.5

MEDRamDisk.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 /*---------------------------------------------------------------------------
00033  *         Headers
00034  *---------------------------------------------------------------------------*/
00035 
00036 #include <board.h>
00037 #include "Media.h"
00038 #include "MedRamDisk.h"
00039 
00040 /*---------------------------------------------------------------------------
00041  *      Types
00042  *---------------------------------------------------------------------------*/
00043 
00044 /** Do copy and modify pointer */
00045 typedef void copyFunction(uint8_t **, uint8_t **, uint32_t);
00046 
00047 /*---------------------------------------------------------------------------
00048  *      Internal Functions
00049  *---------------------------------------------------------------------------*/
00050 
00051 /**
00052  * Do copy for 8-byte aligned data
00053  */
00054 static void AlignedCopy(uint8_t * *src,
00055                         uint8_t * *dst,
00056                         uint32_t len)
00057 {
00058     uint32_t *src32, *dst32;
00059     src32 = (uint32_t *)(void *)*src;
00060     dst32 = (uint32_t *)(void *)*dst;
00061 
00062     for (; len > 0; len -= 8) {
00063         *dst32 ++ = *src32 ++;
00064         *dst32 ++ = *src32 ++;
00065     }
00066 
00067     *src = (uint8_t *)src32;
00068     *dst = (uint8_t *)dst32;
00069 }
00070 
00071 /**
00072  * Do copy for byte-aligned data
00073  */
00074 static void UnalignedCopy(uint8_t * *src,
00075                           uint8_t * *dst,
00076                           uint32_t  len)
00077 {
00078     for (; len > 0; len --)
00079         *(*dst) ++ = *(*src) ++;
00080 }
00081 
00082 /**
00083  * \brief  Reads a specified amount of data from a RAM Disk memory
00084  * \param  media    Pointer to a Media instance
00085  * \param  address  Address of the data to read
00086  * \param  data     Pointer to the buffer in which to store the retrieved
00087  *                  data
00088  * \param  length   Length of the buffer
00089  * \param  callback Optional pointer to a callback function to invoke when
00090  *                  the operation is finished
00091  * \param  argument Optional pointer to an argument for the callback
00092  * \return Operation result code
00093  */
00094 static uint8_t MEDRamDisk_Read(sMedia        *media,
00095                                uint32_t      address,
00096                                void          *data,
00097                                uint32_t      length,
00098                                MediaCallback callback,
00099                                void          *argument)
00100 {
00101     uint8_t *source;
00102     uint8_t *dest;
00103     copyFunction  *pCpy;
00104 
00105     // Check that the media is ready
00106     if (media->state != MED_STATE_READY) {
00107         TRACE_INFO("Media busy\n\r");
00108         return MED_STATUS_BUSY;
00109     }
00110 
00111     // Check that the data to read is not too big
00112     if ((length + address) > media->size) {
00113         TRACE_WARNING("RamDisk_Read: Data too big: %u, 0x%08X\n\r",
00114                       (unsigned int)length, (unsigned int)address);
00115         return MED_STATUS_ERROR;
00116     }
00117 
00118     // Enter Busy state
00119     media->state = MED_STATE_BUSY;
00120 
00121     // Source & Destination
00122     source = (uint8_t *)(media->blockSize
00123                          * (address + media->baseAddress));
00124     dest   = (uint8_t *)data;
00125 
00126     // Align/Unaligned copy
00127     pCpy   = (((uint32_t)source % 4) == 0 && (media->blockSize % 8) == 0)
00128              ? AlignedCopy : UnalignedCopy;
00129 
00130     for (; length > 0; length --)
00131         pCpy(&source, &dest, media->blockSize);
00132 
00133     // Leave the Busy state
00134     media->state = MED_STATE_READY;
00135 
00136     // Invoke callback
00137     if (callback != 0)
00138         callback(argument, MED_STATUS_SUCCESS, 0, 0);
00139 
00140     return MED_STATUS_SUCCESS;
00141 }
00142 
00143 /**
00144  *  \brief  Writes data on a Ram Disk media
00145  *  \param  media    Pointer to a Media instance
00146  *  \param  address  Address at which to write
00147  *  \param  data     Pointer to the data to write
00148  *  \param  length   Size of the data buffer
00149  *  \param  callback Optional pointer to a callback function to invoke when
00150  *                    the write operation terminates
00151  *  \param  argument Optional argument for the callback function
00152  *  \return Operation result code
00153  *  \see    Media
00154  *  \see    MediaCallback
00155  */
00156 static uint8_t MEDRamDisk_Write(sMedia         *media,
00157                                 uint32_t       address,
00158                                 void           *data,
00159                                 uint32_t       length,
00160                                 MediaCallback  callback,
00161                                 void           *argument)
00162 {
00163     uint8_t *source;
00164     uint8_t *dest;
00165     copyFunction  *pCpy;
00166 
00167     // Check that the media if ready
00168     if (media->state != MED_STATE_READY) {
00169         TRACE_WARNING("RamDisk_Write: busy\n\r");
00170         return MED_STATUS_BUSY;
00171     }
00172 
00173     // Check that the data to write is not too big
00174     if ((length + address) > media->size) {
00175         TRACE_WARNING("RamDisk_Write: Data too big\n\r");
00176         return MED_STATUS_ERROR;
00177     }
00178 
00179     // Put the media in Busy state
00180     media->state = MED_STATE_BUSY;
00181 
00182     // Compute function parameters
00183     source = (uint8_t *) data;
00184     dest = (uint8_t *) (media->blockSize *
00185                         (media->baseAddress + address));
00186 
00187     // Align/Unaligned copy
00188     pCpy   = (((uint32_t)source % 4) == 0 && (media->blockSize % 8) == 0)
00189              ? AlignedCopy : UnalignedCopy;
00190 
00191     for (; length > 0; length --)
00192         pCpy(&source, &dest, media->blockSize);
00193 
00194     // Leave the Busy state
00195     media->state = MED_STATE_READY;
00196 
00197     // Invoke the callback if it exists
00198     if (callback != 0)
00199         callback(argument, MED_STATUS_SUCCESS, 0, 0);
00200 
00201     return MED_STATUS_SUCCESS;
00202 }
00203 
00204 /*---------------------------------------------------------------------------
00205  *      Exported Functions
00206  *---------------------------------------------------------------------------*/
00207 
00208 /**
00209  *  \brief  Initializes a block of RAM as Media block.
00210  *  \param  media Pointer to the Media instance to initialize
00211  *  \see    Media
00212  */
00213 extern void MEDRamDisk_Initialize(sMedia   *media,
00214                                   uint32_t  blockSize,
00215                                   uint32_t  baseAddress,
00216                                   uint32_t  size,
00217                                   uint8_t   mappedRW)
00218 {
00219     TRACE_INFO("RAM Disk init\n\r");
00220 
00221     // Initialize media fields
00222     media->write = MEDRamDisk_Write;
00223     media->read = MEDRamDisk_Read;
00224     media->lock = 0;
00225     media->unlock = 0;
00226     media->handler = 0;
00227     media->flush = 0;
00228 
00229     media->blockSize = blockSize;
00230     media->baseAddress = baseAddress;
00231     media->size = size;
00232 
00233     media->mappedRD  = mappedRW;
00234     media->mappedWR  = mappedRW;
00235     media->protected = 0;
00236     media->removable = 0;
00237     media->state = MED_STATE_READY;
00238 
00239     media->transfer.data = 0;
00240     media->transfer.address = 0;
00241     media->transfer.length = 0;
00242     media->transfer.callback = 0;
00243     media->transfer.argument = 0;
00244 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines