SAMV71 Xplained Ultra Software Package 1.3

MEDFlash.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 /**
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 
00101     return MED_STATUS_SUCCESS;
00102 }
00103 
00104 /**
00105  * \brief  Writes data on a flash media
00106  * \param  media    Pointer to a Media instance
00107  * \param  address  Address at which to write
00108  * \param  data     Pointer to the data to write
00109  * \param  length   Size of the data buffer
00110  * \param  callback Optional pointer to a callback function to invoke when
00111  *                   the write operation terminates
00112  * \param  argument Optional argument for the callback function
00113  * \return Operation result code
00114  * \see    Media
00115  * \see    Callback_f
00116  */
00117 static uint8_t FLA_Write(sMedia  *media,
00118                                 uint32_t address,
00119                                 void *data,
00120                                 uint32_t length,
00121                                 MediaCallback callback,
00122                                 void *argument)
00123 {
00124     uint8_t error;
00125 
00126     // Check that the media if ready
00127     if (media->state != MED_STATE_READY) {
00128 
00129         TRACE_WARNING("FLA_Write: Media is busy\n\r");
00130         return MED_STATUS_BUSY;
00131     }
00132 
00133     // Check that address is dword-aligned
00134     if (address%4 != 0) {
00135         TRACE_DEBUG("address = 0x%X\n\r", address);
00136         TRACE_WARNING("FLA_Write: Address must be dword-aligned\n\r");
00137         return MED_STATUS_ERROR;
00138     }
00139 
00140     // Check that length is a multiple of 4
00141     if (length%4 != 0) {
00142 
00143         TRACE_WARNING("FLA_Write: Data length must be a multiple of 4 bytes\n\r");
00144         return MED_STATUS_ERROR;
00145     }
00146 
00147     // Check that the data to write is not too big
00148     if ((length + address) > media->size) {
00149 
00150         TRACE_WARNING("FLA_Write: Data too big\n\r");
00151         return MED_STATUS_ERROR;
00152     }
00153 
00154     // Put the media in Busy state
00155     media->state = MED_STATE_BUSY;
00156 
00157     // Initialize the transfer descriptor
00158     media->transfer.data = data;
00159     media->transfer.address = address;
00160     media->transfer.length = length;
00161     media->transfer.callback = callback;
00162     media->transfer.argument = argument;
00163 
00164     // Start the write operation
00165     error = FLASHD_Write( address, data, length);
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     // End of transfer
00171     // Put the media in Ready state
00172     media->state = MED_STATE_READY;
00173 
00174     // Invoke the callback if it exists
00175     if (media->transfer.callback != 0) {
00176         media->transfer.callback(media->transfer.argument, 0, 0, 0);
00177     }
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 
00222     return MED_STATUS_SUCCESS ;
00223 }
00224 
00225 /*------------------------------------------------------------------------------
00226  *      Exported Functions
00227  *------------------------------------------------------------------------------*/
00228 /**
00229  * \brief  Initializes a Media instance and the associated physical interface
00230  * \param  media Pointer to the Media instance to initialize
00231  * \param  efc   Pointer to AT91S_EFC interface.
00232  * \see    Media
00233  */
00234 void FLA_Initialize( sMedia *media, Efc *efc )
00235 {
00236     TRACE_INFO("Flash init\n\r");
00237 
00238     // Initialize media fields
00239     media->write = FLA_Write;
00240     media->read = FLA_Read;
00241     media->lock = FLA_Lock;
00242     media->unlock = FLA_Unlock;
00243     media->flush = 0;
00244     media->handler = 0;
00245 
00246     media->blockSize = 1;
00247     media->baseAddress = 0; // Address based on whole memory space
00248     media->size = IFLASH_SIZE;
00249     media->interface = efc;
00250 
00251     media->mappedRD  = 0;
00252     media->mappedWR  = 0;
00253     media->protected = 0;
00254     media->removable = 0;
00255     media->state = MED_STATE_READY;
00256 
00257     media->transfer.data = 0;
00258     media->transfer.address = 0;
00259     media->transfer.length = 0;
00260     media->transfer.callback = 0;
00261     media->transfer.argument = 0;
00262 
00263     // Initialize low-level interface
00264     // Configure Flash Mode register
00265     efc->EEFC_FMR |= (BOARD_MCK / 666666) << 16;
00266 }
00267 
00268 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines