SAMV71 Xplained Ultra Software Package 1.4

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