1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2014, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
32 * \page getting-started Getting Started with sama5d3 Microcontrollers
\r
36 * The Getting Started example will help new users get familiar with Atmel's
\r
37 * sama5d3x microcontroller. This basic application shows the startup
\r
38 * sequence of a chip and how to use its core peripherals.
\r
40 * \section Requirements
\r
42 * This package can be used with sama5d3 xplained board.
\r
44 * \section Description
\r
46 * The demonstration program makes two LEDs on the board blink at a fixed rate.
\r
47 * This rate is generated by using Time tick timer. The blinking can be stopped
\r
48 * using two buttons (one for each LED). If there is no enough buttons on board, please
\r
49 * type "1" or "2" in the terminal application on PC to control the LEDs
\r
54 * -# Build the program and download it inside the xplained board. Please
\r
56 * <a href="http://www.atmel.com/dyn/resources/prod_documents/6421B.pdf">
\r
57 * SAM-BA User Guide</a>, the
\r
58 * <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">
\r
59 * GNU-Based Software Development</a>
\r
60 * application note or to the
\r
61 * <a href="ftp://ftp.iar.se/WWWfiles/arm/Guides/EWARM_UserGuide.ENU.pdf">
\r
62 * IAR EWARM User Guide</a>,
\r
63 * depending on your chosen solution.
\r
64 * -# On the computer, open and configure a terminal application
\r
65 * (e.g. HyperTerminal on Microsoft Windows) with these settings:
\r
71 * -# Start the application.
\r
72 * -# Two LEDs should start blinking on the board. In the terminal window, the
\r
73 * following text should appear (values depend on the board and chip used):
\r
75 * -- Getting Started Example xxx --
\r
77 * -- Compiled: xxx xx xxxx xx:xx:xx --
\r
79 * -# Pressing and release button 1 or type "1" in the terminal application on
\r
80 * PC should make the first LED stop & restart blinking.
\r
81 * Pressing and release button 2 or type "1" in the terminal application on
\r
82 * PC should make the other LED stop & restart blinking.
\r
84 * \section References
\r
85 * - getting-started/main.c
\r
94 * This file contains all the specific code for the getting-started example.
\r
98 /*----------------------------------------------------------------------------
\r
100 *----------------------------------------------------------------------------*/
\r
104 #include <stdbool.h>
\r
107 /*----------------------------------------------------------------------------
\r
108 * Local definitions
\r
109 *----------------------------------------------------------------------------*/
\r
111 #define NO_PUSHBUTTON
\r
113 /** IRQ priority for PIO (The lower the value, the greater the priority) */
\r
114 #define IRQ_PRIOR_PIO 0
\r
116 /** LED0 blink time, LED1 blink half this time, in ms */
\r
117 #define BLINK_PERIOD 1000
\r
119 /** Delay for pushbutton debouncing (in milliseconds). */
\r
120 #define DEBOUNCE_TIME 500
\r
122 /*----------------------------------------------------------------------------
\r
124 *----------------------------------------------------------------------------*/
\r
126 #ifndef NO_PUSHBUTTON
\r
127 /** Pushbutton \#1 pin instance. */
\r
128 const Pin pinPB1 = PIN_PUSHBUTTON_1 ;
\r
129 /** Pushbutton \#1 pin instance. */
\r
130 const Pin pinPB2 = PIN_PUSHBUTTON_2 ;
\r
133 /** LED0 blinking control. */
\r
134 volatile bool bLed0Active = true ;
\r
136 /** LED1 blinking control. */
\r
137 volatile bool bLed1Active = true ;
\r
139 /** Global timestamp in milliseconds since start of application */
\r
140 volatile uint32_t dwTimeStamp = 0;
\r
142 /*----------------------------------------------------------------------------
\r
144 *----------------------------------------------------------------------------*/
\r
147 * \brief Process Buttons Events
\r
149 * Change active states of LEDs when corresponding button events happened.
\r
151 static void ProcessButtonEvt( uint8_t ucButton )
\r
153 if ( ucButton == 0 )
\r
155 bLed0Active = !bLed0Active ;
\r
156 if ( !bLed0Active )
\r
163 bLed1Active = !bLed1Active ;
\r
165 /* Enable LED#2 and TC if they were disabled */
\r
169 TC_Start( TC0, 0 );
\r
171 /* Disable LED#2 and TC if they were enabled */
\r
180 #ifndef NO_PUSHBUTTON
\r
182 * \brief Handler for Button 1 rising edge interrupt.
\r
184 * Handle process led1 status change.
\r
186 static void _Button1_Handler( const Pin* pin )
\r
189 ProcessButtonEvt( 0 ) ;
\r
193 * \brief Handler for Button 2 falling edge interrupt.
\r
195 * Handle process led2 status change.
\r
197 static void _Button2_Handler( const Pin* pin )
\r
200 ProcessButtonEvt( 1 ) ;
\r
204 * \brief Handler for DBGU input.
\r
206 * Handle process LED1 or LED2 status change.
\r
208 static void _DBGU_Handler( void )
\r
211 if ( !DBGU_IsRxReady( ) ) return ;
\r
212 key = DBGU_GetChar( ) ;
\r
215 case '1': case '2':
\r
216 ProcessButtonEvt( key - '1' ) ;
\r
223 * \brief Handler for PIT interrupt.
\r
225 static void _Pit_Handler( void )
\r
229 /* Read the PIT status register */
\r
230 status = PIT_GetStatus() & PIT_SR_PITS;
\r
232 /* 1 = The Periodic Interval timer has reached PIV since the last read of PIT_PIVR.
\r
233 Read the PIVR to acknowledge interrupt and get number of ticks
\r
234 Returns the number of occurrences of periodic intervals since the last read of PIT_PIVR. */
\r
235 dwTimeStamp += (PIT_GetPIVR() >> 20);
\r
240 * \brief Handler for Sysc interrupts.
\r
242 static void _Sysc_Handler( void )
\r
245 #ifdef NO_PUSHBUTTON
\r
251 * \brief Configure the periodic interval timer (PIT) to generate an interrupt every
\r
252 * interrupt every millisecond
\r
254 static void ConfigurePit(void)
\r
256 PMC->PMC_PCER0 = 1 << ID_PIT;
\r
257 /* Initialize the PIT to the desired frequency */
\r
258 PIT_Init(BLINK_PERIOD, BOARD_MCK / 1000000);
\r
259 /* Configure interrupt on PIT */
\r
260 IRQ_ConfigureIT(ID_PIT, 0, _Sysc_Handler);
\r
261 IRQ_EnableIT(ID_PIT);
\r
263 /* Enable the pit */
\r
267 #ifndef NO_PUSHBUTTON
\r
269 * \brief Configure the Pushbuttons
\r
271 * Configure the PIO as inputs and generate corresponding interrupt when
\r
272 * pressed or released.
\r
274 static void _ConfigureButtons( void )
\r
276 /* Configure pios as inputs. */
\r
277 PIO_Configure( &pinPB1, 1 ) ;
\r
278 PIO_Configure( &pinPB2, 1 ) ;
\r
280 /* Adjust pio debounce filter patameters, uses 10 Hz filter. */
\r
281 PIO_SetDebounceFilter( &pinPB1, 10 ) ;
\r
282 PIO_SetDebounceFilter( &pinPB1, 10 ) ;
\r
284 /* Enable PIO controller IRQs. */
\r
285 PIO_InitializeInterrupts(0);
\r
286 /* Initialize pios interrupt handlers, see PIO definition in board.h. */
\r
287 PIO_ConfigureIt(&pinPB1, (void (*)(const Pin *))_Button1_Handler);
\r
288 PIO_ConfigureIt(&pinPB2, (void (*)(const Pin *))_Button2_Handler);
\r
290 /* Enable PIO line interrupts. */
\r
291 PIO_EnableIt( &pinPB1 ) ;
\r
292 PIO_EnableIt( &pinPB2 ) ;
\r
297 * \brief Configure LEDs
\r
299 * Configures LEDs \#1 and \#2 (cleared by default).
\r
301 static void _ConfigureLeds( void )
\r
303 LED_Configure( 0 ) ;
\r
304 LED_Configure( 1 ) ;
\r
308 * Interrupt handler for TC0 interrupt. Toggles the state of LED\#2.
\r
310 static void TC0_IrqHandler( void )
\r
312 volatile uint32_t dummy;
\r
313 /* Clear status bit to acknowledge interrupt */
\r
314 dummy = TC0->TC_CHANNEL[ 0 ].TC_SR ;
\r
316 /** Toggle LED state. */
\r
322 * Configure Timer Counter 0 to generate an interrupt every 250ms.
\r
324 static void _ConfigureTc( void )
\r
329 /** Enable peripheral clock. */
\r
330 PMC->PMC_PCER0 = 1 << ID_TC0;
\r
332 /** Configure TC for a 4Hz frequency and trigger on RC compare. */
\r
333 TC_FindMckDivisor( 4, BOARD_MCK, &div, &tcclks, BOARD_MCK );
\r
334 TC_Configure( TC0, 0, tcclks | TC_CMR_CPCTRG );
\r
335 TC0->TC_CHANNEL[ 0 ].TC_RC = ( BOARD_MCK / div ) / 4;
\r
337 /* Configure and enable interrupt on RC compare */
\r
338 IRQ_ConfigureIT(ID_TC0, 0, TC0_IrqHandler);
\r
339 TC0->TC_CHANNEL[ 0 ].TC_IER = TC_IER_CPCS;
\r
340 IRQ_EnableIT(ID_TC0);
\r
342 /** Start the counter if LED1 is enabled. */
\r
345 TC_Start( TC0, 0 );
\r
350 * Waits for the given number of milliseconds (using the dwTimeStamp generated
\r
351 * by the SAM3's microcontrollers's system tick).
\r
352 * \param delay Delay to wait for, in milliseconds.
\r
354 static void _Wait( unsigned long delay )
\r
356 volatile uint32_t start = dwTimeStamp;
\r
359 elapsed = dwTimeStamp;
\r
362 while (elapsed < delay);
\r
365 /*----------------------------------------------------------------------------
\r
367 *----------------------------------------------------------------------------*/
\r
370 * \brief getting-started Application entry point.
\r
372 * \return Unused (ANSI-C compatibility).
\r
374 int atmel_main( void );
\r
375 int atmel_main( void )
\r
377 /* Disable watchdog */
\r
378 WDT_Disable( WDT ) ;
\r
379 #if defined (ddram)
\r
380 MMU_Initialize((uint32_t *)0x30C000);
\r
382 CP15_EnableDcache();
\r
383 CP15_EnableIcache();
\r
386 /* Output example information */
\r
387 printf( "-- Getting Started Example %s --\n\r", SOFTPACK_VERSION ) ;
\r
388 printf( "-- %s\n\r", BOARD_NAME ) ;
\r
389 printf( "-- Compiled: %s %s --\n\r", __DATE__, __TIME__ ) ;
\r
391 /* Configure PIT. */
\r
392 printf( "Configure PIT \n\r" ) ;
\r
393 //__asm volatile( "cpsid i" );
\r
396 /* PIO configuration for LEDs and Buttons. */
\r
397 PIO_InitializeInterrupts( IRQ_PRIOR_PIO ) ;
\r
399 printf( "Configure TC.\n\r" );
\r
402 printf( "Configure LED PIOs.\n\r" ) ;
\r
405 #ifndef NO_PUSHBUTTON
\r
406 printf( "Configure buttons with debouncing.\n\r" ) ;
\r
407 _ConfigureButtons() ;
\r
408 printf( "Press USRBP1 to Start/Stop the blue LED D1 blinking.\n\r" ) ;
\r
409 printf( "Press USRBP2 to Start/Stop the red LED D2 blinking.\n\r" ) ;
\r
412 printf( "No push buttons, uses DBG key 1 & 2 instead.\n\r" ) ;
\r
413 printf( "Press 1 to Start/Stop the blue LED D1 blinking.\n\r" ) ;
\r
414 printf( "Press 2 to Start/Stop the red LED D2 blinking.\n\r" ) ;
\r
420 /* Wait for LED to be active */
\r
421 while( !bLed0Active );
\r
423 /* Toggle LED state if active */
\r
430 /* Wait for 500ms */
\r