00001 /* ---------------------------------------------------------------------------- 00002 * SAM Software Package License 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2014, 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 /** 00032 * \page eefc_pgm EEFC programming example 00033 * 00034 * \section Purpose 00035 * This basic example shows how to use the Enhance Embedded Flash (EEFC) 00036 * peripheral available on the newest Atmel samv7 Microcontrollers. 00037 * It details steps required to 00038 * program the internal flash, and manage secure and lock bits. 00039 * 00040 * \section Requirements 00041 * 00042 * This package can be used with SAM V71 Xplained Ultra board. 00043 * 00044 * \section Description 00045 * The samv7 ROM code embeds small In Application Programming Procedure. 00046 * Since this function is executed from ROM, this allows Flash programming 00047 * (such as sector write) to be done by code running in Flash.\n 00048 * 00049 * \section Note 00050 * The IAP function entry point is retrieved by reading the NMI vector in ROM (). 00051 * This function takes two argument in parameter: bank index (0 or 1) and the 00052 * command to be sent to the EEFC. 00053 * \code 00054 * static uint32_t (*IAP_PerformCommand)(uint32_t, uint32_t); 00055 * IAP_PerformCommand = (uint32_t (*)(uint32_t, uint32_t)) *((uint32_t *) 00056 * 0x00100008); 00057 * IAP_PerformCommand(0, (0x5A << 24) | (argument << 8) | command); 00058 * \endcode 00059 * IAP function returns the value of the MC_FSR register. 00060 * The required steps are: 00061 * - Unlock a page. 00062 * - Program a page of the embedded flash with incremental values 00063 * (0x0, 0x1, 0x2, 0x3...) by using the IAP function. 00064 * - Check the flash is correctly programmed by reading all the values programmed. 00065 * - Lock the page. 00066 * - Set the security bit. 00067 * 00068 * The samv7 features a security bit, based on a specific General Purpose NVM bit 0. 00069 * When the security is enabled, any access to the Flash, SRAM, Core Registers 00070 * and Internal Peripherals either through the ICE interface is forbidden. 00071 * This example will reproduce this scene. 00072 * 00073 * \section Usage 00074 * 00075 * -# Build the program and download it inside the SAM V71 Xplained Ultra board. 00076 * Please refer to the Getting Started with SAM V71 Microcontrollers.pdf 00077 * -# On the computer, open and configure a terminal application 00078 * (e.g. HyperTerminal on Microsoft Windows) with these settings: 00079 * - 115200 baud rate 00080 * - 8 bits of data 00081 * - No parity 00082 * - 1 stop bit 00083 * - No flow control 00084 * -# Start the application. 00085 * -# In the terminal window, the following text should appear: 00086 * \code 00087 * -- EEFC Programming Example xxx -- 00088 * -- xxxxxx-xx 00089 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00090 * -I- Unlocking last page 00091 * -I- Writing last page with walking bit pattern 00092 * -I- Checking page contents .................. ok 00093 * -I- Locking last page 00094 * -I- Try to program the locked page... 00095 * -I- Please open Segger's JMem program 00096 * -I- Read memory at address 0x0043FF00 to check contents 00097 * -I- Press any key to continue... 00098 * -I- Good job! 00099 * -I- Now set the security bit 00100 * -I- Press any key to continue to see what happened... 00101 * -I- Setting GPNVM #0 00102 * -I- All tests done 00103 * \endcode 00104 * 00105 * \section References 00106 * - eefc_pgm/main.c 00107 * - efc.c 00108 * - efc.h 00109 * - flashd.c 00110 * - flashd.h 00111 */ 00112 /** 00113 * \file 00114 * 00115 * This file contains all the specific code for the eefc_pgm example. 00116 * 00117 */ 00118 /*---------------------------------------------------------------------------- 00119 * Headers 00120 *----------------------------------------------------------------------------*/ 00121 00122 #include "board.h" 00123 #include <stdio.h> 00124 #include <stdarg.h> 00125 #include <assert.h> 00126 00127 /*---------------------------------------------------------------------------- 00128 * Global functions 00129 *----------------------------------------------------------------------------*/ 00130 00131 /** 00132 * \brief Application entry point for EEFC programming example. 00133 * 00134 * \return Unused (ANSI-C compatibility). 00135 */ 00136 00137 extern int main( void ) 00138 { 00139 uint32_t dwCnt; 00140 uint8_t ucError; 00141 uint32_t adwBuffer[IFLASH_PAGE_SIZE / 4]; 00142 uint32_t dwLastPageAddress; 00143 volatile uint32_t *pdwLastPageData; 00144 00145 /* Disable watchdog */ 00146 WDT_Disable( WDT ) ; 00147 00148 /* Enable I and D cache */ 00149 SCB_EnableICache(); 00150 SCB_EnableDCache(); 00151 00152 /* Update internal flash Region to Full Access*/ 00153 MPU_UpdateRegions(MPU_DEFAULT_IFLASH_REGION, IFLASH_START_ADDRESS, \ 00154 MPU_AP_FULL_ACCESS | 00155 INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | 00156 MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) | 00157 MPU_REGION_ENABLE); 00158 00159 /* Set 6 WS for internal Flash writing (refer to errata) */ 00160 EFC_SetWaitState(EFC, 6); 00161 00162 /* Output example information */ 00163 printf( "\n\r\n\r\n\r" ) ; 00164 printf( "EEFC Programming Example %s --\n\r", SOFTPACK_VERSION ) ; 00165 printf( "%s\n\r", BOARD_NAME ) ; 00166 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME); 00167 00168 /* Initialize flash driver */ 00169 FLASHD_Initialize(BOARD_MCK, 0); 00170 00171 /* Performs tests on last page (to avoid overriding existing program).*/ 00172 dwLastPageAddress = IFLASH_ADDR + IFLASH_SIZE/2 - IFLASH_PAGE_SIZE; 00173 pdwLastPageData = (volatile uint32_t *) dwLastPageAddress; 00174 00175 /* Unlock page */ 00176 printf("-I- Unlocking last page\n\r"); 00177 ucError = FLASHD_Unlock(dwLastPageAddress, dwLastPageAddress + IFLASH_PAGE_SIZE, 00178 0, 0); 00179 assert( !ucError ) ; 00180 00181 /* Write page with walking bit pattern (0x00000001, 0x00000002, ...) */ 00182 printf("-I- Writing last page with walking bit pattern\n\r"); 00183 for ( dwCnt=0 ; dwCnt < (IFLASH_PAGE_SIZE / 4); dwCnt++ ) 00184 { 00185 adwBuffer[dwCnt] = 1 << (dwCnt % 32); 00186 } 00187 ucError = FLASHD_Write(dwLastPageAddress, adwBuffer, IFLASH_PAGE_SIZE); 00188 assert(!ucError ) ; 00189 00190 /* Check page contents */ 00191 printf( "-I- Checking page contents " ) ; 00192 for (dwCnt=0; dwCnt < (IFLASH_PAGE_SIZE / 4); dwCnt++) 00193 { 00194 printf(".") ; 00195 if (pdwLastPageData[dwCnt] != (1u << (dwCnt % 32))) 00196 { 00197 printf("\n\r-F- Expected 0x%08X at address 0x%08X, found 0x%08X\n\r", 00198 (1u << (dwCnt % 32)), (unsigned int) &(pdwLastPageData[dwCnt]), 00199 (unsigned)(pdwLastPageData[dwCnt])); 00200 while(1); 00201 } 00202 } 00203 printf(" OK \n\r") ; 00204 00205 /* Lock page */ 00206 printf( "-I- Locking last page\n\r" ) ; 00207 ucError = FLASHD_Lock( dwLastPageAddress, dwLastPageAddress + IFLASH_PAGE_SIZE, 00208 0, 0 ) ; 00209 assert( !ucError ) ; 00210 00211 /* Check that associated region is locked*/ 00212 printf( "-I- Try to program the locked page... \n\r" ) ; 00213 ucError = FLASHD_Write( dwLastPageAddress, adwBuffer, IFLASH_PAGE_SIZE ) ; 00214 if ( ucError ) 00215 { 00216 printf( "-I- The page to be programmed belongs to a locked region.\n\r"); 00217 } 00218 00219 printf( "-I- Please open Segger's JMem program \n\r" ); 00220 printf( "-I- Read memory at address 0x%08x to check contents\n\r", 00221 (unsigned int)dwLastPageAddress ) ; 00222 printf( "-I- Press any key to continue...\n\r" ) ; 00223 while ( !DBG_GetChar() ) ; 00224 00225 printf( "-I- Good job!\n\r" ) ; 00226 printf( "-I- Now set the security bit \n\r" ) ; 00227 printf( "-I- Press any key to continue to see what happened...\n\r" ); 00228 while ( !DBG_GetChar() ) ; 00229 00230 /* Set GPNVM bit 0 (security bit) */ 00231 00232 /* SAMS7 features a security bit based on the GPNVM bit 0. When security is 00233 enabled, any access to the Flash, SRAM, core registers and internal 00234 peripherals, either through the SW-DP/JTAG-DP interface or through the 00235 Fast Flash Programming Interface, is forbidden. */ 00236 00237 printf( "-I- Setting GPNVM #%d\n\r", 0 ) ; 00238 ucError = FLASHD_SetGPNVM( 0 ) ; 00239 assert( !ucError ) ; 00240 00241 printf( "-I- All tests done\n\r" ) ; 00242 00243 /* Update internal flash Region to previous configurations */ 00244 MPU_UpdateRegions(MPU_DEFAULT_IFLASH_REGION, IFLASH_START_ADDRESS, \ 00245 MPU_AP_READONLY | 00246 INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | 00247 MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) | 00248 MPU_REGION_ENABLE); 00249 return 0; 00250 } 00251