SAMV71 Xplained Ultra Software Package 1.5

main.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 /**
00031  *  \page mpu MPU with SAMV7/E7 Microcontrollers
00032  *
00033  *  \section Purpose
00034  *
00035  *  The MPU example will help new users get familiar with the MPU of cortex-m7
00036  *  on Atmel's SAMV7/E7 family of microcontrollers. This basic application shows
00037  *  the setup of the basic MPU memory regions and how to use the MPU module.
00038  *
00039  *  \section Requirements
00040  *
00041  *  This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board.
00042  *
00043  *  \section Description
00044  *
00045  *  At startup, the program will setup basic memory regions, then user can
00046  *  update and observe the memory management fault exception through the serial
00047  *  port.
00048  *
00049  *  \section Usage
00050  *
00051  *  -# Build the program and download it inside the board.
00052  *  Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00053  *  -# On the computer, open and configure a terminal application
00054  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00055  *    - 115200 baud rate
00056  *    - 8 bits of data
00057  *    - No parity
00058  *    - 1 stop bit
00059  *    - No flow control
00060  *  -# Start the application.
00061  *  -# In the terminal window, the following text should appear (values depend
00062  *  on the board and chip used):
00063  *     \code
00064  *      -- MPU Example xxx --
00065  *      -- xxxxxx-xx
00066  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00067  *     \endcode
00068  *
00069  * \section References
00070  * - mpu\main.c
00071  *
00072  */
00073 
00074 /** \file
00075  *
00076  *  This file contains all the specific code for the MPU example.
00077  *
00078  */
00079 
00080 /*----------------------------------------------------------------------------
00081  *        Headers
00082  *----------------------------------------------------------------------------*/
00083 #include "board.h"
00084 #include <stdbool.h>
00085 #include <stdio.h>
00086 
00087 /*----------------------------------------------------------------------------
00088  *        Local definitions
00089  *----------------------------------------------------------------------------*/
00090 
00091 #define MPU_UNPRIVILEGED_RAM_REGION       ( 0 )
00092 #define MPU_PRIVILEGE_RAM_REGION          ( 1 )
00093 #define MPU_PRIVILEGE_RAM_REGION_2        ( 2 )
00094 #define MPU_UNPRIVILEGED_FLASH_REGION     ( 3 )
00095 #define MPU_PRIVILEGED_FLASH_REGION       ( 4 )
00096 #define MPU_PERIPHERALS_REGION_0          ( 5 )
00097 #define MPU_PERIPHERALS_REGION_1          ( 6 )
00098 #define MPU_PIOC_REGION_REGION            ( 7 )
00099 
00100 /**************  Peripherals memory region macros for MPU example ********/
00101 #define MPU_PERIPHERALS_START_ADDRESS_0     0x40000000UL
00102 #define MPU_PERIPHERALS_END_ADDRESS_0       (0x400E0E00UL - 1)
00103 
00104 /**************  Peripherals memory region macros for MPU example ********/
00105 #define MPU_PERIPHERALS_START_ADDRESS_1     0x400E0E00UL
00106 #define MPU_PERIPHERALS_END_ADDRESS_1       0x400E2000UL
00107 
00108 /**************  Peripherals memory sub region macros for MPU example ********/
00109 #define MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS    0x400E1200UL
00110 #define MPU_PIOC_PERIPHERALS_REGION_END_ADDRESS      0x400E1400UL
00111 
00112 /**************  sram memory  unprivileged for MPU example ********/
00113 #define MPU_SRAM_UNPRIVILEGE_START_ADDRESS      (SRAM_START_ADDRESS+0)
00114 #define MPU_SRAM_UNPRIVILEGE_END_ADDRESS        (SRAM_START_ADDRESS+0x2FFFF)
00115 
00116 /**************  sram memory  privileged for MPU example ********/
00117 #define MPU_SRAM_PRIVILEGE_START_ADDRESS        (SRAM_START_ADDRESS+0x30000)
00118 #define MPU_SRAM_PRIVILEGE_END_ADDRESS          (SRAM_START_ADDRESS+0x4FFFF)
00119 
00120 /**************  Second part of sram memory  privileged for MPU example *******/
00121 #define MPU_SRAM_PRIVILEGE2_START_ADDRESS        (SRAM_START_ADDRESS+0x50000)
00122 #define MPU_SRAM_PRIVILEGE2_END_ADDRESS          (SRAM_START_ADDRESS+0x5FFFF)
00123 
00124 /*----------------------------------------------------------------------------
00125  *        Local Variables
00126  *----------------------------------------------------------------------------*/
00127 /** Flag to indicate whether the SVC is done */
00128 uint32_t dwRaisePriDone = 0;
00129 
00130 /*----------------------------------------------------------------------------
00131  *        Local functions
00132  *----------------------------------------------------------------------------*/
00133 
00134 /**
00135  * \brief Function to raise the privilege, used by the assemble code
00136  */
00137 static void _RaisePrivilege(void)
00138 {
00139     /* As this function is called in privilege mode, we don't need to set the
00140             privilege mode*/
00141     printf("\n\r-I- Raise to Privilege mode\n\r");
00142     __set_CONTROL(PRIVILEGE_MODE);
00143 }
00144 
00145 /**
00146  * \brief Default SVC interrupt handler.
00147  */
00148 void SVC_Handler(void)
00149 {
00150     /* Set to privilege mode */
00151     __set_CONTROL(PRIVILEGE_MODE);
00152 
00153     /* Set flag */
00154     dwRaisePriDone = 1;
00155 }
00156 
00157 /**
00158  * \brief Default MemManage interrupt handler.
00159  * There is a weak handler by default and if the MPU feature is enabled,
00160  * it must be implemented with the actual handler
00161  */
00162 void MemManage_Handler(void)
00163 {
00164     uint32_t nCfsr, nMmfar;
00165     printf("\n\r-I- Memory Exceptions!!! \n\r");
00166     /* adjust the code to exit the MMF */
00167     nCfsr = SCB->CFSR;
00168     nMmfar = SCB->MMFAR;
00169     if (!(nCfsr & ( 1 << 1)))
00170         _RaisePrivilege();
00171     if ((nMmfar & 0x20400000) || (nMmfar & 0x400E0E00) )
00172         _RaisePrivilege();
00173     printf("\n\r-I- Exit Memory Exceptions!\n\r");
00174 }
00175 
00176 /**
00177  * \brief Setup a memory region.
00178  */
00179 static void _SetupMPU(void)
00180 {
00181 
00182     uint32_t dwRegionBaseAddr;
00183     uint32_t dwRegionAttr;
00184 
00185     /* Internal flash privilege memory region */
00186     dwRegionBaseAddr = IFLASH_PRIVILEGE_START_ADDRESS |
00187         MPU_REGION_VALID |
00188         MPU_PRIVILEGED_FLASH_REGION;
00189 
00190     dwRegionAttr = MPU_AP_FULL_ACCESS |
00191         MPU_CalMPURegionSize(IFLASH_PRIVILEGE_END_ADDRESS -
00192                 IFLASH_PRIVILEGE_START_ADDRESS) |
00193         MPU_REGION_ENABLE;
00194 
00195     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00196 
00197 
00198     /* Internal flash unprivileged memory region */
00199     dwRegionBaseAddr = IFLASH_START_ADDRESS |
00200         MPU_REGION_VALID |
00201         MPU_UNPRIVILEGED_FLASH_REGION;
00202 
00203     dwRegionAttr = MPU_AP_READONLY |
00204         MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) |
00205         MPU_REGION_ENABLE;
00206 
00207     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00208 
00209     /* SRAM memory unprivileged region */
00210     dwRegionBaseAddr = MPU_SRAM_UNPRIVILEGE_START_ADDRESS |
00211         MPU_REGION_VALID |
00212         MPU_UNPRIVILEGED_RAM_REGION;
00213 
00214     dwRegionAttr = MPU_AP_FULL_ACCESS |
00215         INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) |
00216         MPU_CalMPURegionSize(MPU_SRAM_UNPRIVILEGE_END_ADDRESS -
00217                 MPU_SRAM_UNPRIVILEGE_START_ADDRESS) |
00218         MPU_REGION_ENABLE;
00219 
00220     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00221 
00222     /* SRAM memory privilege region */
00223     dwRegionBaseAddr = MPU_SRAM_PRIVILEGE_START_ADDRESS |
00224         MPU_REGION_VALID |
00225         MPU_PRIVILEGE_RAM_REGION;
00226 
00227     dwRegionAttr = MPU_AP_FULL_ACCESS |
00228         INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE ) |
00229         MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE_END_ADDRESS -
00230                 MPU_SRAM_PRIVILEGE_START_ADDRESS) |
00231         MPU_REGION_ENABLE;
00232 
00233     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00234 
00235     /* SRAM memory privilege region */
00236     dwRegionBaseAddr = MPU_SRAM_PRIVILEGE2_START_ADDRESS |
00237         MPU_REGION_VALID |
00238         MPU_PRIVILEGE_RAM_REGION_2;
00239 
00240     dwRegionAttr = MPU_AP_FULL_ACCESS |
00241         INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE ) |
00242         MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE2_END_ADDRESS -
00243                 MPU_SRAM_PRIVILEGE2_START_ADDRESS) |
00244         MPU_REGION_ENABLE;
00245 
00246     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00247 
00248     /* Peripheral memory region */
00249     dwRegionBaseAddr = MPU_PERIPHERALS_START_ADDRESS_0 |
00250         MPU_REGION_VALID |
00251         MPU_PERIPHERALS_REGION_0;
00252 
00253     dwRegionAttr = MPU_AP_FULL_ACCESS |
00254         MPU_REGION_EXECUTE_NEVER |
00255         MPU_CalMPURegionSize(MPU_PERIPHERALS_END_ADDRESS_0 -
00256                 MPU_PERIPHERALS_START_ADDRESS_0) |
00257         MPU_REGION_ENABLE;
00258 
00259     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00260 
00261     /* Peripheral memory region */
00262     dwRegionBaseAddr = MPU_PERIPHERALS_START_ADDRESS_1 |
00263         MPU_REGION_VALID |
00264         MPU_PERIPHERALS_REGION_1;
00265 
00266     dwRegionAttr = MPU_AP_FULL_ACCESS |
00267         MPU_REGION_EXECUTE_NEVER |
00268         1 << MPU_RASR_SRD_Pos |
00269         MPU_CalMPURegionSize(MPU_PERIPHERALS_END_ADDRESS_1 -
00270                 MPU_PERIPHERALS_START_ADDRESS_1) |
00271         MPU_REGION_ENABLE;
00272 
00273     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00274 
00275     /* Sub Peripheral memory region */
00276     dwRegionBaseAddr = MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS |
00277         MPU_REGION_VALID |
00278         MPU_PIOC_REGION_REGION;
00279 
00280     dwRegionAttr = MPU_AP_FULL_ACCESS |
00281         MPU_REGION_EXECUTE_NEVER |
00282         MPU_CalMPURegionSize(MPU_PIOC_PERIPHERALS_REGION_END_ADDRESS -
00283                 MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS) |
00284         MPU_REGION_ENABLE;
00285 
00286     MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr);
00287 
00288     /* Enable the memory management fault exception */
00289     SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
00290 
00291     /* Enable the MPU region */
00292     MPU_Enable(MPU_ENABLE | MPU_PRIVDEFENA);
00293 }
00294 
00295 
00296 /**
00297  *  \brief Update MPU regions.
00298  *
00299  *  \return Unused (ANSI-C compatibility).
00300  */
00301 static void _UpdateMPU( uint32_t dwRegionNum, uint32_t dwRegionBaseAddr,
00302                         uint32_t dwRegionAttr)
00303 {
00304     /* Raise privilege, the MPU register could be set only in privilege mode */
00305 
00306     __ASM volatile(" svc 0x00 ");
00307 
00308     while (!dwRaisePriDone);
00309     dwRaisePriDone = 0;
00310 
00311     /* Disable interrupt */
00312     __disable_irq();
00313 
00314     /* Clean up data and instruction buffer */
00315     __DSB();
00316     __ISB();
00317 
00318     /* Set active region */
00319     MPU_SetRegionNum(dwRegionNum);
00320 
00321     /* Disable region */
00322     MPU_DisableRegion();
00323 
00324     /* Update region attribute */
00325     MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr);
00326 
00327     /* Clean up data and instruction buffer to make the new region taking
00328            effect at once */
00329     __DSB();
00330     __ISB();
00331 
00332     /* Enable the interrupt */
00333     __enable_irq();
00334 
00335     /* Reset to thread mode */
00336     __set_CONTROL(USER_MODE);
00337 }
00338 
00339 /*----------------------------------------------------------------------------
00340  *        Exported functions
00341  *----------------------------------------------------------------------------*/
00342 
00343 /**
00344  *  \brief Application entry point for MPU example.
00345  *
00346  *  \return Unused (ANSI-C compatibility).
00347  */
00348 extern int main( void )
00349 {
00350     uint8_t ucChoice = 0;
00351 
00352     /* Disable watchdog */
00353     WDT_Disable(WDT);
00354 
00355     uint32_t *pdw = (uint32_t *)MPU_SRAM_PRIVILEGE_START_ADDRESS;
00356 
00357     /* Output example information */
00358     printf("\n\r\n\r\n\r");
00359     printf("-- MPU Example %s --\n\r", SOFTPACK_VERSION);
00360     printf("-- %s\n\r", BOARD_NAME);
00361     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME);
00362 
00363     LED_Configure(LED_YELLOW0);
00364 
00365     /* Set up the default memory regions */
00366     _SetupMPU();
00367 
00368     /* Set the environment to thread mode */
00369     __set_CONTROL(USER_MODE);
00370 
00371     while (ucChoice != '9') {
00372         printf("----------------------------------------\n\r");
00373         printf("    Choose an option below:\n\r");
00374         printf("    1. Protect the Yellow LED region\n\r");
00375         printf("    2. UN-protect the Yellow LED region\n\r");
00376         printf("    3. Toggle the green LED\n\r");
00377         printf("    4. Set the RAM region to read only \n\r");
00378         printf("    5. Set the RAM region to read/write\n\r");
00379         printf("    6. Read the RAM content at offset 0\n\r");
00380         printf("    7. Write the RAM context at offset 0\n\r");
00381         printf("    8. Quit the external program\n\r");
00382         printf("\n\r");
00383         printf("  Choice: ");
00384 
00385         ucChoice = DBG_GetChar();
00386         DBG_PutChar(ucChoice);
00387         printf("\n\r");
00388 
00389         switch (ucChoice) {
00390         case '1':
00391             _UpdateMPU(MPU_PIOC_REGION_REGION,
00392                     MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS |
00393                     MPU_REGION_VALID |
00394                     MPU_PIOC_REGION_REGION,
00395                     MPU_AP_UNPRIVILEGED_READONLY |
00396                     MPU_REGION_EXECUTE_NEVER |
00397                     MPU_CalMPURegionSize(MPU_PIOC_PERIPHERALS_REGION_END_ADDRESS - MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS) |
00398                         MPU_REGION_ENABLE);
00399             break;
00400 
00401         case '2':
00402             _UpdateMPU(MPU_PIOC_REGION_REGION,
00403                     MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS |
00404                     MPU_REGION_VALID |
00405                     MPU_PIOC_REGION_REGION,
00406                     MPU_AP_FULL_ACCESS |
00407                     MPU_REGION_EXECUTE_NEVER |
00408                     MPU_CalMPURegionSize(MPU_PIOC_PERIPHERALS_REGION_END_ADDRESS -
00409                         MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS) |
00410                     MPU_REGION_ENABLE);
00411             break;
00412 
00413         case '3':
00414         /* Set back to unprivileged mode*/
00415 
00416             LED_Toggle(LED_YELLOW0);
00417             __set_CONTROL(USER_MODE);
00418             break;
00419 
00420         case '4':
00421             _UpdateMPU(MPU_PRIVILEGE_RAM_REGION,
00422                     MPU_SRAM_PRIVILEGE_START_ADDRESS |
00423                     MPU_REGION_VALID |
00424                     MPU_PRIVILEGE_RAM_REGION,
00425                     MPU_AP_UNPRIVILEGED_READONLY |
00426                     MPU_REGION_CACHEABLE |
00427                     MPU_REGION_BUFFERABLE |
00428                     MPU_TEX_B001|
00429                     MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE_END_ADDRESS -
00430                     MPU_SRAM_PRIVILEGE_START_ADDRESS) |
00431                     MPU_REGION_ENABLE);
00432             break;
00433 
00434         case '5':
00435             _UpdateMPU(MPU_PRIVILEGE_RAM_REGION,
00436                     MPU_SRAM_PRIVILEGE_START_ADDRESS |
00437                     MPU_REGION_VALID |
00438                     MPU_PRIVILEGE_RAM_REGION,
00439                     MPU_AP_FULL_ACCESS |
00440                     MPU_REGION_CACHEABLE |
00441                     MPU_REGION_BUFFERABLE |
00442                     MPU_TEX_B001|
00443                     MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE_END_ADDRESS -
00444                     MPU_SRAM_PRIVILEGE_START_ADDRESS) |
00445                     MPU_REGION_ENABLE);
00446 
00447             break;
00448 
00449         case '6':
00450             printf("-I- RAM address has content %x \n\r",(unsigned)(pdw[0]));
00451             break;
00452 
00453         case '7':
00454             printf("-I- Write offset 0 of RAM region with content 0x55AA55AA\n\r");
00455             pdw[0] = 0x55AA55AA;
00456             break;
00457 
00458         case '8':
00459             printf("-I- MPU TEST FINISH ...\n\r");
00460             break;
00461 
00462         default:
00463             printf("-I- This option is not valid\n\r");
00464             break;
00465         }
00466     }
00467     /* Setback to privilege mode, before entering the main routine,
00468        it is supervisor mode*/
00469     __ASM volatile(" svc 0x00 ");
00470     while (!dwRaisePriDone);
00471     dwRaisePriDone = 0;
00472 
00473     __set_CONTROL(PRIVILEGE_MODE);
00474 
00475     return 0;
00476 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines