SAMV71 Xplained Ultra Software Package 1.3

efc.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 /** \addtogroup efc_module Working with EEFC
00031  *
00032  * The EEFC driver provides the interface to configure and use the EEFC
00033  * peripheral.
00034  *
00035  * The user needs to set the number of wait states depending on the frequency
00036  * used.\n
00037  * Configure number of cycles for flash read/write operations in the FWS field 
00038  * of EEFC_FMR.
00039  *
00040  * It offers a function to send flash command to EEFC and waits for the
00041  * flash to be ready.
00042  *
00043  * To send flash command, the user could do in either of following way:
00044  * <ul>
00045  * <li>Write a correct key, command and argument in EEFC_FCR. </li>
00046  * <li>Or, Use IAP (In Application Programming) function which is executed from
00047  * ROM directly, this allows flash programming to be done by code running in 
00048  * flash.</li>
00049  * <li>Once the command is achieved, it can be detected even by polling 
00050  * EEFC_FSR or interrupt.
00051  * </ul>
00052  *
00053  * The command argument could be a page number,GPNVM number or nothing, it 
00054  * depends on the command itself. Some useful functions in this driver could 
00055  * help user translate physical flash address into a page number and vice verse.
00056  *
00057  * For more accurate information, please look at the EEFC section of the
00058  * Datasheet.
00059  *
00060  * Related files :\n
00061  * \ref efc.c\n
00062  * \ref efc.h.\n
00063  */
00064 /*@{*/
00065 /*@}*/
00066 
00067 
00068 /**
00069  * \file
00070  *
00071  * Implementation of Enhanced Embedded Flash Controller (EEFC).
00072  *
00073  */
00074 
00075 
00076 /*----------------------------------------------------------------------------
00077  *        Headers
00078  *----------------------------------------------------------------------------*/
00079 #include "chip.h"
00080 
00081 #include <assert.h>
00082 
00083  
00084 /*----------------------------------------------------------------------------
00085  *        Macro 
00086  *----------------------------------------------------------------------------*/
00087 #define EEFC_FCR_FCMD(value) ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))
00088 
00089 /*----------------------------------------------------------------------------
00090  *        Exported functions
00091  *----------------------------------------------------------------------------*/
00092 
00093 extern void EFC_WriteFMR( Efc* efc, uint32_t dwFmr );
00094 
00095 #ifdef __ICCARM__
00096 extern __ramfunc void EFC_WriteFMR( Efc* efc, uint32_t dwFmr )
00097 #else
00098     __attribute__ ((section (".ramfunc")))
00099 extern void EFC_WriteFMR( Efc* efc, uint32_t dwFmr )
00100 #endif
00101 {
00102     efc->EEFC_FMR = dwFmr;
00103 }
00104 
00105 /**
00106  * \brief Enables the flash ready interrupt source on the EEFC peripheral.
00107  *
00108  * \param efc  Pointer to a Efc instance
00109  */
00110 extern void EFC_EnableFrdyIt( Efc* efc )
00111 {
00112     uint32_t dwFmr;
00113 
00114     dwFmr = efc->EEFC_FMR |= EEFC_FMR_FRDY;
00115     EFC_WriteFMR(efc, dwFmr);
00116 }
00117 
00118 /**
00119  * \brief Disables the flash ready interrupt source on the EEFC peripheral.
00120  *
00121  * \param efc  Pointer to a Efc instance
00122  */
00123 extern void EFC_DisableFrdyIt( Efc* efc )
00124 {
00125     uint32_t dwFmr;
00126 
00127     dwFmr = efc->EEFC_FMR & (~EEFC_FMR_FRDY);
00128     EFC_WriteFMR(efc, dwFmr);
00129 }
00130 
00131 
00132 /**
00133  * \brief Set read/write wait state on the EEFC peripheral.
00134  *
00135  * \param efc  Pointer to a Efc instance
00136  * \param cycles  the number of wait states in cycle.
00137  */
00138 extern void EFC_SetWaitState( Efc* efc, uint8_t ucCycles )
00139 {
00140     uint32_t dwFmr ;
00141 
00142     dwFmr = efc->EEFC_FMR ;
00143     dwFmr &= ~((uint32_t)EEFC_FMR_FWS_Msk) ;
00144     dwFmr |= EEFC_FMR_FWS(ucCycles);
00145     EFC_WriteFMR(efc, dwFmr);
00146 }
00147 
00148 /**
00149  * \brief Returns the current status of the EEFC.
00150  *
00151  * \note Keep in mind that this function clears the value of some status bits 
00152  * (LOCKE, PROGE).
00153  *
00154  * \param efc  Pointer to a Efc instance
00155  */
00156 extern uint32_t EFC_GetStatus( Efc* efc )
00157 {
00158     return efc->EEFC_FSR ;
00159 }
00160 
00161 /**
00162  * \brief Returns the result of the last executed command.
00163  *
00164  * \param efc  Pointer to a Efc instance
00165  */
00166 extern uint32_t EFC_GetResult( Efc* efc )
00167 {
00168     return efc->EEFC_FRR ;
00169 }
00170 
00171 /**
00172  * \brief Translates the given address page and offset values.
00173  * \note The resulting values are stored in the provided variables if they are
00174  * not null.
00175  *
00176  * \param efc  Pointer to a Efc instance
00177  * \param address  Address to translate.
00178  * \param pPage  First page accessed.
00179  * \param pOffset  Byte offset in first page.
00180  */
00181 extern void EFC_TranslateAddress( Efc** ppEfc, uint32_t dwAddress, uint16_t* pwPage,
00182                                 uint16_t* pwOffset )
00183 {
00184     assert( dwAddress >= IFLASH_ADDR ) ;
00185     assert( dwAddress <= (IFLASH_ADDR + IFLASH_SIZE) ) ;
00186 
00187     /* Store values */
00188     if ( ppEfc )    {
00189         *ppEfc = EFC ;
00190     }
00191 
00192     if ( pwPage ) {
00193         *pwPage = (dwAddress - IFLASH_ADDR) / IFLASH_PAGE_SIZE ;
00194     }
00195 
00196     if ( pwOffset ) {
00197         *pwOffset = (dwAddress - IFLASH_ADDR) % IFLASH_PAGE_SIZE; ;
00198     }
00199 }
00200 
00201 
00202 /**
00203  * \brief Computes the address of a flash access given the page and offset.
00204  *
00205  * \param efc  Pointer to a Efc instance
00206  * \param page  Page number.
00207  * \param offset  Byte offset inside page.
00208  * \param pAddress  Computed address (optional).
00209  */
00210 extern void EFC_ComputeAddress( Efc *efc, uint16_t wPage, uint16_t wOffset,
00211                             uint32_t *pdwAddress )
00212 {
00213     uint32_t dwAddress ;
00214 
00215     /* Stop warning */
00216     efc = efc;
00217 
00218     assert( efc ) ;
00219     assert( wPage <= IFLASH_NB_OF_PAGES ) ;
00220     assert( wOffset < IFLASH_PAGE_SIZE ) ;
00221     dwAddress = IFLASH_ADDR + wPage * IFLASH_PAGE_SIZE + wOffset ;
00222 
00223     /* Store result */
00224     if ( pdwAddress != NULL ) {
00225         *pdwAddress = dwAddress ;
00226     }
00227 }
00228 
00229 /**
00230  * \brief Performs the given command and wait until its completion (or an error).
00231  *
00232  * \param efc  Pointer to a Efc instance
00233  * \param command  Command to perform.
00234  * \param argument  Optional command argument.
00235  *
00236  * \return 0 if successful, otherwise returns an error code.
00237  */
00238 
00239 extern uint32_t EFC_PerformCommand( Efc* efc, uint32_t dwCommand, 
00240                                 uint32_t dwArgument, uint32_t dwUseIAP )
00241 {
00242     if ( dwUseIAP != 0 ) {
00243         /* Pointer on IAP function in ROM */
00244         static uint32_t (*IAP_PerformCommand)( uint32_t, uint32_t ) ;
00245 
00246         IAP_PerformCommand = (uint32_t (*)( uint32_t, uint32_t )) 
00247                 *((uint32_t*)CHIP_FLASH_IAP_ADDRESS ) ;
00248         if (efc == EFC) {
00249             IAP_PerformCommand( 0, EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(dwArgument) 
00250                     | EEFC_FCR_FCMD(dwCommand) ) ;
00251         }
00252         return (efc->EEFC_FSR & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR)) ;
00253     } else {
00254         uint32_t dwStatus ;
00255 
00256         efc->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(dwArgument) 
00257                 | EEFC_FCR_FCMD(dwCommand) ;
00258         do {
00259             dwStatus = efc->EEFC_FSR ;
00260         }
00261         while ( (dwStatus & EEFC_FSR_FRDY) != EEFC_FSR_FRDY ) ;
00262 
00263         return ( dwStatus & (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR) ) ;
00264     }
00265 }
00266 
00267 /**
00268  * \brief Set flash access mode.
00269  *
00270  * \param dwMode - 0:128-bit, (1<<24):64-bit
00271  */
00272 extern void EFC_SetFlashAccessMode(Efc* efc, uint32_t dwMode)
00273 {
00274     uint32_t dwFmr;
00275 
00276     dwFmr = dwMode;
00277     EFC_WriteFMR(efc, dwFmr);
00278 }
00279 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines