SAMV71 Xplained Ultra Software Package 1.5

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