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 * \page qspi_xip QSPI XIP Example 00032 * 00033 * \section Purpose 00034 * 00035 * This example demonstrates how to setup the QSPI Flash in XIP mode to execute 00036 * code from QSPI flash. 00037 * 00038 * \section Requirements 00039 * 00040 * This package can be used with SAMV7x evaluation kits. 00041 * 00042 * \section Description 00043 * 00044 * Ths code writes the coremark benchmark code into flash via SPI and enables 00045 * quad mode spi to read code and to execute from it. 00046 * 00047 * \section Usage 00048 * 00049 * -# Build the program and download it inside the SAM V71 Xplained Ultra board. 00050 * Please refer to the Getting Started with SAM V71 Microcontrollers.pdf 00051 * -# Optionally, on the computer, open and configure a terminal application 00052 * (e.g. HyperTerminal on Microsoft Windows) with these settings: 00053 * - 115200 bauds 00054 * - 8 bits of data 00055 * - No parity 00056 * - 1 stop bit 00057 * - No flow control 00058 * -# Start the application. 00059 * -# Upon startup, the application will output the following lines on the 00060 * terminal window: 00061 * \code 00062 * -- QSPI XIP Example xxx -- 00063 * -- SAMxxxxx-xx 00064 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00065 * QSPI drivers initialized 00066 * \endcode 00067 * \section References 00068 * - qspi_flash/main.c 00069 * - qspi.c 00070 * - s25fl1.c 00071 */ 00072 00073 /** 00074 * \file 00075 * 00076 * This file contains all the specific code for the Qspi_serialflash example. 00077 */ 00078 00079 /*---------------------------------------------------------------------------- 00080 * Headers 00081 *----------------------------------------------------------------------------*/ 00082 00083 #include <board.h> 00084 #include <stdio.h> 00085 #include <assert.h> 00086 #include <string.h> 00087 #include "stdlib.h" 00088 #include "getting_started_hex.h" 00089 00090 /*---------------------------------------------------------------------------- 00091 * Local definitions 00092 *----------------------------------------------------------------------------*/ 00093 00094 /** SPI peripheral pins to configure to access the serial flash. */ 00095 #define QSPI_PINS PINS_QSPI 00096 00097 /*---------------------------------------------------------------------------- 00098 * Local variables 00099 *----------------------------------------------------------------------------*/ 00100 /** Pins to configure for the application. */ 00101 static Pin pins[] = QSPI_PINS; 00102 00103 COMPILER_ALIGNED(32) static uint32_t Buffer[4]; 00104 00105 /*---------------------------------------------------------------------------- 00106 * Global functions 00107 *----------------------------------------------------------------------------*/ 00108 00109 /** 00110 * \brief Application entry point for QSPI_XIP example. 00111 * Initializes the serial flash and performs XIP. 00112 * 00113 * \return Unused (ANSI-C compatibility). 00114 */ 00115 00116 int main(void) 00117 { 00118 uint8_t MemVerify = 0; 00119 uint32_t __Start_SP, idx; 00120 uint32_t (*__Start_New)(void); 00121 uint8_t *pMemory = (uint8_t *)( QSPIMEM_ADDR ); 00122 00123 /* Disable watchdog */ 00124 WDT_Disable(WDT); 00125 00126 SCB_EnableICache(); 00127 SCB_EnableDCache(); 00128 00129 /* Output example information */ 00130 printf("-- QSPI XIP Example %s --\n\r", SOFTPACK_VERSION); 00131 printf("-- %s\n\r", BOARD_NAME); 00132 printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); 00133 00134 /* Configure systick */ 00135 TimeTick_Configure(); 00136 00137 /* Initialize the QSPI and serial flash */ 00138 PIO_Configure(pins, PIO_LISTSIZE(pins)); 00139 00140 /* Enable the clock of QSPI */ 00141 ENABLE_PERIPHERAL(ID_QSPI); 00142 00143 S25FL1D_InitFlashInterface(1); 00144 printf("QSPI drivers initialized\n\r"); 00145 00146 /* enable quad mode */ 00147 S25FL1D_QuadMode(ENABLE); 00148 00149 /* get the code at the beginning of QSPI, run the code directly if it's valid */ 00150 S25FL1D_ReadQuadIO(Buffer, sizeof(Buffer), 0, 1, 0); 00151 printf("-I- data at the beginning of QSPI: %08x %08x %08x %08x\n\r", 00152 (unsigned int)Buffer[0], (unsigned int)Buffer[1], 00153 (unsigned int)Buffer[2], (unsigned int)Buffer[3]); 00154 if ((IRAM_ADDR <= Buffer[0]) && (IRAM_ADDR + IRAM_SIZE > Buffer[0]) && 00155 (QSPIMEM_ADDR < Buffer[1]) && (1 == (Buffer[1]&0x3))) { 00156 __Start_New = (uint32_t(*)(void)) Buffer[1]; 00157 __Start_SP = Buffer[0]; 00158 00159 printf("-I- a valid application is already in QSPI, run it from QSPI\n\r"); 00160 printf("========================================================= \n\r"); 00161 00162 __set_MSP(__Start_SP); 00163 __Start_New(); 00164 } else { 00165 printf("-I- there isn't a valid application in QSPI, program first\n\r"); 00166 } 00167 00168 if (S25FL1D_Unprotect()) { 00169 printf("Unprotect QSPI Flash failed!\n\r"); 00170 while (1); 00171 } 00172 00173 /* erase entire chip */ 00174 S25FL1D_EraseChip(); 00175 00176 /* Flash the code to QSPI flash */ 00177 printf("Writing to Memory\n\r"); 00178 00179 S25FL1D_Write((uint32_t *)pBuffercode, sizeof(pBuffercode), 0, 0); 00180 00181 printf("Example code written 0x%x to Memory\n\r", sizeof(pBuffercode)); 00182 00183 printf("Verifying \n\r"); 00184 00185 /* Update QSPI Region to Full Access and cacheable*/ 00186 MPU_UpdateRegions(MPU_QSPIMEM_REGION, QSPI_START_ADDRESS, \ 00187 MPU_AP_FULL_ACCESS | 00188 INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | 00189 MPU_CalMPURegionSize(QSPI_END_ADDRESS - QSPI_START_ADDRESS) | 00190 MPU_REGION_ENABLE); 00191 00192 /* Start continuous read mode to enter in XIP mode*/ 00193 S25FL1D_ReadQuadIO(Buffer, sizeof(Buffer), 0, 1, 0); 00194 00195 for (idx = 0; idx < sizeof(pBuffercode); idx++) { 00196 if (*pMemory == pBuffercode[idx]) { 00197 pMemory++; 00198 } else { 00199 MemVerify = 1; 00200 printf("Data does not match at 0x%x \n\r", (unsigned)pMemory); 00201 break; 00202 } 00203 } 00204 if (!MemVerify) { 00205 printf("Everything is OK \n\r"); 00206 /* set PC and SP */ 00207 __Start_New = (uint32_t(*) (void) ) Buffer[1]; 00208 __Start_SP = Buffer[0]; 00209 00210 printf("\n\r Starting getting started example from QSPI flash \n\r"); 00211 printf("========================================================= \n\r"); 00212 00213 __set_MSP(__Start_SP); 00214 00215 __Start_New(); 00216 } 00217 while (1); 00218 }