SAMV71 Xplained Ultra Software Package 1.5

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