SAMV71 Xplained Ultra Software Package 1.4

MEDRamDisk.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2012, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
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     for (;len > 0; len -= 8) {
00062         *dst32 ++ = *src32 ++;
00063         *dst32 ++ = *src32 ++;
00064     }
00065     *src = (uint8_t*)src32;
00066     *dst = (uint8_t*)dst32;
00067 }
00068 
00069 /**
00070  * Do copy for byte-aligned data
00071  */
00072 static void UnalignedCopy(uint8_t * *src,
00073                           uint8_t * *dst,
00074                           uint32_t  len)
00075 {
00076     for (;len > 0; len --) {
00077         *(*dst) ++ = *(*src) ++;
00078     }
00079 }
00080 
00081 /**
00082  * \brief  Reads a specified amount of data from a RAM Disk memory
00083  * \param  media    Pointer to a Media instance
00084  * \param  address  Address of the data to read
00085  * \param  data     Pointer to the buffer in which to store the retrieved
00086  *                  data
00087  * \param  length   Length of the buffer
00088  * \param  callback Optional pointer to a callback function to invoke when
00089  *                  the operation is finished
00090  * \param  argument Optional pointer to an argument for the callback
00091  * \return Operation result code
00092  */
00093 static uint8_t MEDRamDisk_Read(sMedia        *media,
00094                              uint32_t      address,
00095                              void          *data,
00096                              uint32_t      length,
00097                              MediaCallback callback,
00098                              void          *argument)
00099 {
00100     uint8_t *source;
00101     uint8_t *dest;
00102     copyFunction  *pCpy;
00103 
00104     // Check that the media is ready
00105     if (media->state != MED_STATE_READY) {
00106         TRACE_INFO("Media busy\n\r");
00107         return MED_STATUS_BUSY;
00108     }
00109 
00110     // Check that the data to read is not too big
00111     if ((length + address) > media->size) {
00112         TRACE_WARNING("RamDisk_Read: Data too big: %u, 0x%08X\n\r",
00113                       (unsigned int)length, (unsigned int)address);
00114         return MED_STATUS_ERROR;
00115     }
00116 
00117     // Enter Busy state
00118     media->state = MED_STATE_BUSY;
00119 
00120     // Source & Destination
00121     source = (uint8_t *)(media->blockSize
00122                                     * (address + media->baseAddress));
00123     dest   = (uint8_t *)data;
00124 
00125     // Align/Unaligned copy
00126     pCpy   = (((uint32_t)source%4) == 0 && (media->blockSize%8) == 0)
00127                         ? AlignedCopy : UnalignedCopy;
00128 
00129     for (; length > 0; length --) {
00130         pCpy(&source, &dest, media->blockSize);
00131     }
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 
00195     // Leave the Busy state
00196     media->state = MED_STATE_READY;
00197 
00198     // Invoke the callback if it exists
00199     if (callback != 0) {
00200         callback(argument, MED_STATUS_SUCCESS, 0, 0);
00201     }
00202 
00203     return MED_STATUS_SUCCESS;
00204 }
00205 
00206 /*---------------------------------------------------------------------------
00207  *      Exported Functions
00208  *---------------------------------------------------------------------------*/
00209 
00210 /**
00211  *  \brief  Initializes a block of RAM as Media block.
00212  *  \param  media Pointer to the Media instance to initialize
00213  *  \see    Media
00214  */
00215 extern void MEDRamDisk_Initialize(sMedia   *media,
00216                                   uint32_t  blockSize,
00217                                   uint32_t  baseAddress,
00218                                   uint32_t  size,
00219                                   uint8_t   mappedRW)
00220 {
00221     TRACE_INFO("RAM Disk init\n\r");
00222 
00223     // Initialize media fields
00224     media->write = MEDRamDisk_Write;
00225     media->read = MEDRamDisk_Read;
00226     media->lock = 0;
00227     media->unlock = 0;
00228     media->handler = 0;
00229     media->flush = 0;
00230 
00231     media->blockSize = blockSize;
00232     media->baseAddress = baseAddress;
00233     media->size = size;
00234 
00235     media->mappedRD  = mappedRW;
00236     media->mappedWR  = mappedRW;
00237     media->protected = 0;
00238     media->removable = 0;
00239     media->state = MED_STATE_READY;
00240 
00241     media->transfer.data = 0;
00242     media->transfer.address = 0;
00243     media->transfer.length = 0;
00244     media->transfer.callback = 0;
00245     media->transfer.argument = 0;
00246 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines