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 * \page wdt Watchdog with IRQ Interrupt Example 00032 * 00033 * \section Purpose 00034 * 00035 * This example demonstrates user to trigger a watchdog interrupt 00036 * if the software becomes trapped in a deadlock. 00037 * 00038 * \section Requirements 00039 * 00040 * This package can be used with SAM V71 Xplained Ultra board. 00041 * 00042 * \section Description 00043 * 00044 * When launched, this program reloads the watchdog at regular intervals 00045 * before the timer underflow occurs, a LED is blinked. User could press 00046 * button1 to make the program run in a infinite loop without 00047 * reloading the watchdog. So a watchdog interrupt will be triggered, and 00048 * "Enter watchdog interrupt." will print to terminal. 00049 * 00050 * \note 00051 * -# User can enable a watchdog reset instead of an interrupt by setting 00052 * WDRSTEN bit in WDT_MR register. 00053 * 00054 * \section Usage 00055 * 00056 * -# Build the program and download it inside the SAM V71 Xplained Ultra board. 00057 * Please refer to the Getting Started with SAM V71 Microcontrollers.pdf 00058 * -# On the computer, open and configure a terminal application 00059 * (e.g. HyperTerminal on Microsoft Windows) with these settings: 00060 * - 115200 bauds 00061 * - 8 bits of data 00062 * - No parity 00063 * - 1 stop bit 00064 * - No flow control 00065 * -# Start the application. 00066 * -# In the terminal window, the following text should appear: 00067 * \code 00068 * -- Watchdog with IRQ Interrupt Example xxx -- 00069 * -- xxxxxx-xx 00070 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00071 * \endcode 00072 * 00073 * The user could press the button1 to trigger a watchdog interrupt. 00074 * 00075 * \section References 00076 * - wdt/main.c 00077 * - wdt.c 00078 * - wdt.h 00079 */ 00080 00081 /** 00082 * \file 00083 * 00084 * This file contains all the specific code for the wdt example. 00085 */ 00086 00087 /*---------------------------------------------------------------------------- 00088 * Headers 00089 *----------------------------------------------------------------------------*/ 00090 00091 #include "board.h" 00092 00093 /* These headers were introduced in C99 by working group ISO/IEC JTC1/SC22/WG14. */ 00094 #include <stdbool.h> 00095 #include <stdio.h> 00096 00097 /*---------------------------------------------------------------------------- 00098 * Local definitions 00099 *----------------------------------------------------------------------------*/ 00100 00101 /** LED used in this program */ 00102 #define LED_ID 1 00103 00104 /** LED blink time, in ms */ 00105 #define BLINK_PERIOD 300 00106 00107 /** Watchdog period, in ms */ 00108 #define WDT_PERIOD 3000 00109 /** Watchdog restart period, in ms */ 00110 #define WDT_RESTART_PERIOD 2000 00111 00112 /*---------------------------------------------------------------------------- 00113 * Local variables 00114 *----------------------------------------------------------------------------*/ 00115 00116 /** Pushbutton \#1 pin instance. */ 00117 const Pin pinPB1 = PIN_PUSHBUTTON_0; 00118 00119 /** Pushbutton \#1 pin event flag. */ 00120 volatile bool button1Evt = false; 00121 00122 volatile uint32_t gSystick = 0; 00123 /*---------------------------------------------------------------------------- 00124 * Local functions 00125 *----------------------------------------------------------------------------*/ 00126 00127 00128 /** 00129 * \brief Handler for Button 1 rising edge interrupt. 00130 * 00131 * Set button1 event flag (button1Evt). 00132 */ 00133 static void _Button1_Handler( const Pin* pPin ) 00134 { 00135 if ( pPin == &pinPB1 ) { 00136 button1Evt = true ; 00137 } 00138 } 00139 00140 /** 00141 * \brief Handler for watchdog interrupt. 00142 */ 00143 void WDT_Handler( void ) 00144 { 00145 Wdt *pWdt = WDT ; 00146 volatile uint32_t dummy ; 00147 00148 /* Clear status bit to acknowledge interrupt */ 00149 dummy = pWdt->WDT_SR ; 00150 00151 printf( "Enter watchdog interrupt.\n\r" ) ; 00152 #ifdef sram 00153 WDT_Restart( WDT ) ; 00154 printf( "The watchdog timer was restarted.\n\r" ) ; 00155 #else 00156 printf( "Processor reset\n\n\n\r" ) ; 00157 RSTC_ExtReset(); 00158 #endif 00159 } 00160 00161 /** 00162 * \brief Configure the Pushbuttons 00163 * 00164 * Configure the PIO as inputs and generate corresponding interrupt when 00165 * pressed or released. 00166 */ 00167 static void _ConfigureButtons( void ) 00168 { 00169 /* Configure PIO as inputs. */ 00170 PIO_Configure( &pinPB1, 1 ) ; 00171 00172 /* Adjust PIO debounce filter parameters, uses 10 Hz filter. */ 00173 PIO_SetDebounceFilter( &pinPB1, 10 ) ; 00174 00175 /* Initialize PIO interrupt handlers, see PIO definition in board.h. */ 00176 PIO_ConfigureIt( &pinPB1, _Button1_Handler ) ; /* Interrupt on rising edge */ 00177 00178 /* Enable PIO controller IRQs. */ 00179 NVIC_EnableIRQ( (IRQn_Type)pinPB1.id ) ; 00180 00181 /* Enable PIO line interrupts. */ 00182 PIO_EnableIt( &pinPB1 ) ; 00183 } 00184 00185 /** 00186 * \brief Configure LEDs 00187 * 00188 * Configures LED (cleared by default). 00189 */ 00190 static void _ConfigureLeds( void ) 00191 { 00192 LED_Configure( LED_ID ) ; 00193 } 00194 00195 /*---------------------------------------------------------------------------- 00196 * Global functions 00197 *----------------------------------------------------------------------------*/ 00198 00199 /** 00200 * \brief Application entry point for wdg_irq example. 00201 * 00202 * \return Unused (ANSI-C compatibility). 00203 */ 00204 extern int main( void ) 00205 { 00206 uint32_t dwPeriod ; 00207 uint32_t startTime; 00208 00209 SCB_EnableICache(); 00210 SCB_EnableDCache(); 00211 00212 /* Output example information */ 00213 printf( "-- Watchdog with IRQ Interrupt Example %s --\n\r", SOFTPACK_VERSION ) ; 00214 printf( "-- %s\n\r", BOARD_NAME ) ; 00215 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ; 00216 00217 /* Sys tick configuration. */ 00218 printf( "Configure sys tick to get 1ms tick period.\n\r" ) ; 00219 00220 TimeTick_Configure(); 00221 00222 /* PIO configuration for LEDs and Buttons. */ 00223 PIO_InitializeInterrupts( 0 ) ; 00224 _ConfigureLeds() ; 00225 _ConfigureButtons() ; 00226 00227 /* Configure WDT to trigger a interrupt (or reset) */ 00228 printf( "Enable watchdog with %u millisecond period\n\r", 00229 (unsigned int)WDT_PERIOD ) ; 00230 dwPeriod = WDT_GetPeriod( WDT_PERIOD ) ; 00231 00232 #if 1 /* trigger a watchdog interrupt */ 00233 WDT_Enable( WDT, WDT_MR_WDFIEN | WDT_MR_WDDBGHLT 00234 | WDT_MR_WDIDLEHLT | (dwPeriod << 16) | dwPeriod ) ; 00235 NVIC_DisableIRQ( WDT_IRQn ) ; 00236 NVIC_ClearPendingIRQ( WDT_IRQn ) ; 00237 NVIC_SetPriority( WDT_IRQn, 0 ) ; 00238 NVIC_EnableIRQ( WDT_IRQn ) ; 00239 #else /* trigger a watchdog reset */ 00240 WDT_Enable( WDT, WDT_MR_WDRSTEN | WDT_MR_WDDBGHLT 00241 | WDT_MR_WDIDLEHLT | (dwPeriod << 16) | dwPeriod ) ; 00242 #endif 00243 startTime = GetTicks(); 00244 printf( "Press USRPB0 to simulate a deadlock loop.\n\r" ) ; 00245 00246 while( 1 ) { 00247 if((gSystick != GetTicks()) && 00248 ((GetDelayInTicks( startTime, GetTicks())) < 0xFFFFFFFF)) { 00249 gSystick = GetTicks(); 00250 /* Toggle led at given period */ 00251 if ( (GetTicks() % BLINK_PERIOD) == 0 ) { 00252 LED_Toggle( LED_ID ) ; 00253 } 00254 /* Restart watchdog at given period */ 00255 if ( (GetTicks() % WDT_RESTART_PERIOD) == 0 ) { 00256 WDT_Restart( WDT ) ; 00257 } 00258 } 00259 00260 /* Simulate deadlock when button be pressed */ 00261 if ( button1Evt == true ) { 00262 printf( "Program enter infinite loop for triggering watchdog \ 00263 interrupt.\n\r" ) ; 00264 while( 1 ) ; 00265 } 00266 } 00267 } 00268