SAMV71 Xplained Ultra Software Package 1.5

MEDFlash.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 flash.
00034  *
00035  */
00036 
00037 /*------------------------------------------------------------------------------
00038  *      Includes
00039  *----------------------------------------------------------------------------*/
00040 
00041 #include "libstoragemedia.h"
00042 #include <assert.h>
00043 
00044 /*------------------------------------------------------------------------------
00045  *      Internal Functions
00046  *----------------------------------------------------------------------------*/
00047 
00048 /**
00049  * \brief  Reads a specified amount of data from a flash memory
00050  * \param  media    Pointer to a Media instance
00051  * \param  address  Address of the data to read
00052  * \param  data     Pointer to the buffer in which to store the retrieved
00053  *                   data
00054  * \param  length   Length of the buffer
00055  * \param  callback Optional pointer to a callback function to invoke when
00056  *                   the operation is finished
00057  * \param  argument Optional pointer to an argument for the callback
00058  * \return Operation result code
00059 */
00060 static uint8_t FLA_Read(sMedia *media,
00061                         uint32_t address,
00062                         void *data,
00063                         uint32_t length,
00064                         MediaCallback callback,
00065                         void *argument)
00066 {
00067     uint8_t *source = (uint8_t *) address;
00068     uint8_t *dest = (uint8_t *) data;
00069 
00070     // Check that the media is ready
00071     if (media->state != MED_STATE_READY) {
00072         TRACE_INFO("Media busy\n\r");
00073         return MED_STATUS_BUSY;
00074     }
00075 
00076     // Check that the data to read is not too big
00077     if ((length + address) > media->size) {
00078         TRACE_WARNING("FLA_Read: Data too big\n\r");
00079         return MED_STATUS_ERROR;
00080     }
00081 
00082     // Enter Busy state
00083     media->state = MED_STATE_BUSY;
00084 
00085     // Read data
00086     while (length > 0) {
00087         *dest = *source;
00088         dest++;
00089         source++;
00090         length--;
00091     }
00092 
00093     // Leave the Busy state
00094     media->state = MED_STATE_READY;
00095 
00096     // Invoke callback
00097     if (callback != 0)
00098         callback(argument, MED_STATUS_SUCCESS, 0, 0);
00099 
00100     return MED_STATUS_SUCCESS;
00101 }
00102 
00103 /**
00104  * \brief  Writes data on a flash media
00105  * \param  media    Pointer to a Media instance
00106  * \param  address  Address at which to write
00107  * \param  data     Pointer to the data to write
00108  * \param  length   Size of the data buffer
00109  * \param  callback Optional pointer to a callback function to invoke when
00110  *                   the write operation terminates
00111  * \param  argument Optional argument for the callback function
00112  * \return Operation result code
00113  * \see    Media
00114  * \see    Callback_f
00115  */
00116 static uint8_t FLA_Write(sMedia  *media,
00117                          uint32_t address,
00118                          void *data,
00119                          uint32_t length,
00120                          MediaCallback callback,
00121                          void *argument)
00122 {
00123     uint8_t error;
00124 
00125     // Check that the media if ready
00126     if (media->state != MED_STATE_READY) {
00127 
00128         TRACE_WARNING("FLA_Write: Media is busy\n\r");
00129         return MED_STATUS_BUSY;
00130     }
00131 
00132     // Check that address is dword-aligned
00133     if (address % 4 != 0) {
00134         TRACE_DEBUG("address = 0x%X\n\r", address);
00135         TRACE_WARNING("FLA_Write: Address must be dword-aligned\n\r");
00136         return MED_STATUS_ERROR;
00137     }
00138 
00139     // Check that length is a multiple of 4
00140     if (length % 4 != 0) {
00141 
00142         TRACE_WARNING("FLA_Write: Data length must be a multiple of 4 bytes\n\r");
00143         return MED_STATUS_ERROR;
00144     }
00145 
00146     // Check that the data to write is not too big
00147     if ((length + address) > media->size) {
00148 
00149         TRACE_WARNING("FLA_Write: Data too big\n\r");
00150         return MED_STATUS_ERROR;
00151     }
00152 
00153     // Put the media in Busy state
00154     media->state = MED_STATE_BUSY;
00155 
00156     // Initialize the transfer descriptor
00157     media->transfer.data = data;
00158     media->transfer.address = address;
00159     media->transfer.length = length;
00160     media->transfer.callback = callback;
00161     media->transfer.argument = argument;
00162 
00163     // Start the write operation
00164     error = FLASHD_Write(address, data, length);
00165 
00166     if (error) {
00167         TRACE_ERROR("-F- Error when trying to write page (0x%02X)\n\r", error);
00168         return MED_STATUS_ERROR;
00169     }
00170 
00171     // End of transfer
00172     // Put the media in Ready state
00173     media->state = MED_STATE_READY;
00174 
00175     // Invoke the callback if it exists
00176     if (media->transfer.callback != 0)
00177         media->transfer.callback(media->transfer.argument, 0, 0, 0);
00178 
00179     return MED_STATUS_SUCCESS;
00180 }
00181 
00182 /**
00183  * \brief Lock all the regions in the given address range. The actual unlock
00184  *        range is reported through two output parameters.
00185  * \param media Pointer to Media instance.
00186  * \param start  Start address of unlock range.
00187  * \param end  End address of unlock range.
00188  * \param pActualStart  Start address of the actual unlock range (optional).
00189  * \param pActualEnd  End address of the actual unlock range (optional).
00190  * \return 0 if successful; otherwise returns an error code.
00191  */
00192 static uint8_t FLA_Lock(sMedia *media, uint32_t start, uint32_t end,
00193                          uint32_t *pActualStart, uint32_t *pActualEnd)
00194 {
00195     media = media;
00196 
00197     if (FLASHD_Lock(start, end, pActualStart, pActualEnd))
00198         return MED_STATUS_ERROR;
00199 
00200     return MED_STATUS_SUCCESS;
00201 }
00202 
00203 /**
00204  * \brief Unlock all the regions in the given address range. The actual unlock
00205  *        range is reported through two output parameters.
00206  * \param media Pointer to Media instance.
00207  * \param start  Start address of unlock range.
00208  * \param end  End address of unlock range.
00209  * \param pActualStart  Start address of the actual unlock range (optional).
00210  * \param pActualEnd  End address of the actual unlock range (optional).
00211  * \return 0 if successful; otherwise returns an error code.
00212  */
00213 static uint8_t FLA_Unlock(sMedia *media, uint32_t start, uint32_t end,
00214                            uint32_t *pActualStart, uint32_t *pActualEnd)
00215 {
00216     media = media;
00217 
00218     if (FLASHD_Unlock(start, end, pActualStart, pActualEnd))
00219         return MED_STATUS_ERROR;
00220 
00221     return MED_STATUS_SUCCESS;
00222 }
00223 
00224 /*------------------------------------------------------------------------------
00225  *      Exported Functions
00226  *------------------------------------------------------------------------------*/
00227 /**
00228  * \brief  Initializes a Media instance and the associated physical interface
00229  * \param  media Pointer to the Media instance to initialize
00230  * \param  efc   Pointer to AT91S_EFC interface.
00231  * \see    Media
00232  */
00233 void FLA_Initialize(sMedia *media, Efc *efc)
00234 {
00235     TRACE_INFO("Flash init\n\r");
00236 
00237     // Initialize media fields
00238     media->write = FLA_Write;
00239     media->read = FLA_Read;
00240     media->lock = FLA_Lock;
00241     media->unlock = FLA_Unlock;
00242     media->flush = 0;
00243     media->handler = 0;
00244 
00245     media->blockSize = 1;
00246     media->baseAddress = 0; // Address based on whole memory space
00247     media->size = IFLASH_SIZE;
00248     media->interface = efc;
00249 
00250     media->mappedRD  = 0;
00251     media->mappedWR  = 0;
00252     media->protected = 0;
00253     media->removable = 0;
00254     media->state = MED_STATE_READY;
00255 
00256     media->transfer.data = 0;
00257     media->transfer.address = 0;
00258     media->transfer.length = 0;
00259     media->transfer.callback = 0;
00260     media->transfer.argument = 0;
00261 
00262     // Initialize low-level interface
00263     // Configure Flash Mode register
00264     efc->EEFC_FMR |= (BOARD_MCK / 666666) << 16;
00265 }
00266 
00267 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines