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 getting-started Getting Started Example 00032 * 00033 * \section Purpose 00034 * 00035 * The Getting Started example will help new users get familiar with Atmel's 00036 * SAMV7/E7 family of Microcontrollers. This basic application shows the startup 00037 * sequence of a chip and how to use its core peripherals. 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 * The demonstration program makes two LEDs on the board blink at a fixed rate. 00046 * This rate is generated by using Time tick timer. The blinking can be stopped 00047 * by typing '1' or '2' in the console (one for each LED). 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 * -# LED(s) should start blinking on the board. In the terminal window, the 00062 * following text should appear (values depend on the board and chip used): 00063 * \code 00064 * -- Getting Started Example xxx -- 00065 * -- xxxxxx-xx 00066 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00067 * \endcode 00068 * -# Press 'x' to start/stop the LEDx blinking 00069 * 00070 * \section References 00071 * - getting-started/main.c 00072 * - pio.h 00073 * - pio_it.h 00074 * - led.h 00075 * - trace.h 00076 */ 00077 00078 /** \file 00079 * 00080 * This file contains all the specific code for the getting-started example. 00081 * 00082 */ 00083 00084 /*---------------------------------------------------------------------------- 00085 * Headers 00086 *----------------------------------------------------------------------------*/ 00087 00088 #include "board.h" 00089 #include <stdbool.h> 00090 #include <stdio.h> 00091 00092 /*---------------------------------------------------------------------------- 00093 * Local definitions 00094 *----------------------------------------------------------------------------*/ 00095 00096 /** IRQ priority for PIO (The lower the value, the greater the priority) */ 00097 #define IRQ_PRIOR_PIO 0 00098 00099 /** LED0 blink time, LED1 blink half this time, in ms */ 00100 #define BLINK_PERIOD 1000 00101 00102 /*---------------------------------------------------------------------------- 00103 * Local variables 00104 *----------------------------------------------------------------------------*/ 00105 00106 /** LED0 blinking control. */ 00107 volatile bool bLed0Active = true; 00108 00109 /** LED1 blinking control. */ 00110 volatile bool bLed1Active = true; 00111 00112 /** Global timestamps in milliseconds since start of application */ 00113 volatile uint32_t dwTimeStamp = 0; 00114 00115 /** Global timestamps in milliseconds since start of application */ 00116 volatile uint32_t dwTcCounter = 0; 00117 00118 /*---------------------------------------------------------------------------- 00119 * Local functions 00120 *----------------------------------------------------------------------------*/ 00121 00122 /** 00123 * \brief Process Buttons Events 00124 * 00125 * Change active states of LEDs when corresponding button events happened. 00126 */ 00127 static void ProcessButtonEvt(uint8_t ucButton) 00128 { 00129 if (ucButton == 0) { 00130 bLed0Active = !bLed0Active; 00131 if (!bLed0Active) { 00132 LED_Clear(0); 00133 } 00134 } else { 00135 bLed1Active = !bLed1Active; 00136 #if 2 == LED_NUM 00137 /* Enable LED#2 and TC if they were disabled */ 00138 if (bLed1Active) { 00139 LED_Set(1); 00140 } 00141 /* Disable LED#2 and TC if they were enabled */ 00142 else { 00143 LED_Clear(1); 00144 } 00145 #endif 00146 } 00147 } 00148 00149 #ifndef NO_PUSHBUTTON 00150 /** 00151 * \brief Handler for Button 1 rising edge interrupt. 00152 * 00153 * Handle process led1 status change. 00154 */ 00155 static void _Button1_Handler(const Pin* pPin) 00156 { 00157 if (pPin == &pinPB1) { 00158 ProcessButtonEvt(0); 00159 } 00160 } 00161 00162 /** 00163 * \brief Handler for Button 2 falling edge interrupt. 00164 * 00165 * Handle process led2 status change. 00166 */ 00167 static void _Button2_Handler(const Pin* pPin) 00168 { 00169 if (pPin == &pinPB2) { 00170 ProcessButtonEvt(1); 00171 } 00172 } 00173 00174 /** 00175 * \brief Configure the Push-buttons 00176 * 00177 * Configure the PIO as inputs and generate corresponding interrupt when 00178 * pressed or released. 00179 */ 00180 static void _ConfigureButtons(void) 00181 { 00182 /* Configure PIO as inputs. */ 00183 PIO_Configure(&pinPB1, 1); 00184 PIO_Configure(&pinPB2, 1); 00185 00186 /* Adjust PIO denounce filter parameters, uses 10 Hz filter. */ 00187 PIO_SetDebounceFilter(&pinPB1, 10); 00188 PIO_SetDebounceFilter(&pinPB2, 10); 00189 00190 /* Initialize PIO interrupt handlers, see PIO definition in board.h. */ 00191 PIO_ConfigureIt(&pinPB1, _Button1_Handler); /* Interrupt on rising edge */ 00192 PIO_ConfigureIt(&pinPB2, _Button2_Handler); /* Interrupt on rising edge */ 00193 00194 /* Enable PIO controller IRQs. */ 00195 NVIC_EnableIRQ((IRQn_Type)pinPB1.id); 00196 NVIC_EnableIRQ((IRQn_Type)pinPB2.id); 00197 00198 /* Enable PIO line interrupts. */ 00199 PIO_EnableIt(&pinPB1); 00200 PIO_EnableIt(&pinPB2); 00201 } 00202 00203 #else 00204 00205 /** 00206 * \brief Handler for DBGU input. 00207 * 00208 * Handle process LED1 or LED2 status change. 00209 */ 00210 static void _DBGU_Handler(void) 00211 { 00212 uint8_t key; 00213 00214 if (!DBG_IsRxReady()) 00215 return; 00216 key = DBG_GetChar(); 00217 switch (key) { 00218 case '1': 00219 case '2': 00220 ProcessButtonEvt(key - '1'); 00221 break; 00222 } 00223 } 00224 #endif 00225 /** 00226 * \brief Configure LEDs 00227 * 00228 * Configures LEDs \#1 and \#2 (cleared by default). 00229 */ 00230 static void _ConfigureLeds(void) 00231 { 00232 uint32_t i; 00233 00234 for(i = 0; i < LED_NUM; i++) 00235 LED_Configure(i); 00236 } 00237 00238 00239 /** 00240 * Interrupt handler for TC0 interrupt. Toggles the state of LED\#2. 00241 */ 00242 void TC0_Handler(void) 00243 { 00244 volatile uint32_t dummy; 00245 00246 /* Clear status bit to acknowledge interrupt */ 00247 dummy = TC0->TC_CHANNEL[0].TC_SR; 00248 00249 /** Toggle LED state. */ 00250 if (bLed1Active) { 00251 #if 2 == LED_NUM 00252 LED_Toggle(1); 00253 #endif 00254 printf("2 "); 00255 } 00256 #ifdef NO_PUSHBUTTON 00257 _DBGU_Handler(); 00258 #endif 00259 00260 } 00261 00262 /** 00263 * Configure Timer Counter 0 to generate an interrupt every 250ms. 00264 */ 00265 static void _ConfigureTc(void) 00266 { 00267 uint32_t div; 00268 uint32_t tcclks; 00269 00270 /** Enable peripheral clock. */ 00271 PMC_EnablePeripheral(ID_TC0); 00272 /** Configure TC for a 4Hz frequency and trigger on RC compare. */ 00273 TC_FindMckDivisor(4, BOARD_MCK, &div, &tcclks, BOARD_MCK); 00274 00275 TC_Configure(TC0, 0, tcclks | TC_CMR_CPCTRG); 00276 TC0->TC_CHANNEL[0].TC_RC = (BOARD_MCK / div) / 4; 00277 00278 /* Configure and enable interrupt on RC compare */ 00279 NVIC_ClearPendingIRQ(TC0_IRQn); 00280 NVIC_EnableIRQ(TC0_IRQn); 00281 00282 TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS; 00283 00284 /** Start the counter if LED1 is enabled. */ 00285 if (bLed1Active) { 00286 TC_Start(TC0, 0); 00287 } 00288 } 00289 00290 00291 /*---------------------------------------------------------------------------- 00292 * Exported functions 00293 *----------------------------------------------------------------------------*/ 00294 /** 00295 * \brief getting-started Application entry point. 00296 * 00297 * \return Unused (ANSI-C compatibility). 00298 */ 00299 extern int main( void ) 00300 { 00301 00302 /* Disable watchdog */ 00303 WDT_Disable(WDT); 00304 00305 /* Output example information */ 00306 printf("\n\r-- Getting Started Example %s --\n\r", SOFTPACK_VERSION); 00307 printf("-- %s\n\r", BOARD_NAME); 00308 printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); 00309 00310 /* Enable I and D cache */ 00311 SCB_EnableICache(); 00312 SCB_EnableDCache(); 00313 00314 /* Configure systick for 1 ms. */ 00315 TimeTick_Configure(); 00316 00317 printf("Configure LED PIOs.\n\r"); 00318 _ConfigureLeds(); 00319 00320 printf("Configure TC.\n\r"); 00321 _ConfigureTc(); 00322 00323 #ifndef NO_PUSHBUTTON 00324 printf("Configure buttons with denouncing.\n\r"); 00325 _ConfigureButtons(); 00326 printf("Press USRBP1 to Start/Stop LED D1 blinking.\n\r"); 00327 printf("Press USRBP2 to Start/Stop LED D2 blinking.\n\r"); 00328 #else 00329 printf("No push buttons, uses DBG key 1 & 2 instead.\n\r"); 00330 printf("Press 1 to Start/Stop LED D1 blinking.\n\r"); 00331 printf("Press 2 to Start/Stop LED D2 blinking.\n\r"); 00332 #endif 00333 00334 while (1) { 00335 /* Wait for LED to be active */ 00336 while (!bLed0Active); 00337 00338 /* Toggle LED state if active */ 00339 if (bLed0Active) { 00340 LED_Toggle(0); 00341 printf("1 "); 00342 } 00343 00344 /* Wait for 500ms */ 00345 Wait(1000); 00346 } 00347 }