]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/atmel_main.c
8f1225fff7316116ed9867a5f1ccc140ff9005f3
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D3x_Xplained_IAR / atmel_main.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License\r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2014, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\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
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\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
16  *\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
28  */\r
29 \r
30 \r
31 /**\r
32  *  \page getting-started Getting Started with sama5d3 Microcontrollers\r
33  *\r
34  *  \section Purpose\r
35  *\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
39  *\r
40  *  \section Requirements\r
41  *\r
42  *  This package can be used with sama5d3 xplained board.\r
43  *\r
44  *  \section Description\r
45  *\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
50  *  instead.\r
51  *\r
52  *  \section Usage\r
53  *\r
54  *  -# Build the program and download it inside the xplained board. Please\r
55  *     refer to the\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
66  *    - 115200 bauds\r
67  *    - 8 bits of data\r
68  *    - No parity\r
69  *    - 1 stop bit\r
70  *    - No flow control\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
74  *     \code\r
75  *      -- Getting Started Example xxx --\r
76  *      -- SAMxxxxx-xx\r
77  *      -- Compiled: xxx xx xxxx xx:xx:xx --\r
78  *     \endcode\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
83  *\r
84  *  \section References\r
85  *  - getting-started/main.c\r
86  *  - pio.h\r
87  *  - pio_it.h\r
88  *  - led.h\r
89  *  - trace.h\r
90  */\r
91 \r
92 /** \file\r
93  *\r
94  *  This file contains all the specific code for the getting-started example.\r
95  *\r
96  */\r
97 \r
98 /*----------------------------------------------------------------------------\r
99  *        Headers\r
100  *----------------------------------------------------------------------------*/\r
101 \r
102 #include "board.h"\r
103 \r
104 #include <stdbool.h>\r
105 #include <stdio.h>\r
106 \r
107 /*----------------------------------------------------------------------------\r
108  *        Local definitions\r
109  *----------------------------------------------------------------------------*/\r
110 \r
111 #define NO_PUSHBUTTON\r
112 \r
113 /** IRQ priority for PIO (The lower the value, the greater the priority) */\r
114 #define IRQ_PRIOR_PIO    0\r
115 \r
116 /** LED0 blink time, LED1 blink half this time, in ms */\r
117 #define BLINK_PERIOD        1000\r
118 \r
119 /** Delay for pushbutton debouncing (in milliseconds). */\r
120 #define DEBOUNCE_TIME       500\r
121 \r
122 /*----------------------------------------------------------------------------\r
123  *        Local variables\r
124  *----------------------------------------------------------------------------*/\r
125 \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
131 #endif\r
132 \r
133 /** LED0 blinking control. */\r
134 volatile bool bLed0Active = true ;\r
135 \r
136 /** LED1 blinking control. */\r
137 volatile bool bLed1Active = true ;\r
138 \r
139 /** Global timestamp in milliseconds since start of application */\r
140 volatile uint32_t dwTimeStamp = 0;\r
141 \r
142 /*----------------------------------------------------------------------------\r
143  *        Local functions\r
144  *----------------------------------------------------------------------------*/\r
145 \r
146 /**\r
147  *  \brief Process Buttons Events\r
148  *\r
149  *  Change active states of LEDs when corresponding button events happened.\r
150  */\r
151 static void ProcessButtonEvt( uint8_t ucButton )\r
152 {\r
153     if ( ucButton == 0 )\r
154     {\r
155         bLed0Active = !bLed0Active ;\r
156         if ( !bLed0Active )\r
157         {\r
158             LED_Clear( 0 );\r
159         }\r
160     }\r
161     else\r
162     {\r
163         bLed1Active = !bLed1Active ;\r
164 \r
165         /* Enable LED#2 and TC if they were disabled */\r
166         if ( bLed1Active )\r
167         {\r
168             LED_Set( 1 );\r
169             TC_Start( TC0, 0 );\r
170         }\r
171         /* Disable LED#2 and TC if they were enabled */\r
172         else\r
173         {\r
174             LED_Clear( 1 );\r
175             TC_Stop( TC0, 0 );\r
176         }\r
177     }\r
178 }\r
179 \r
180 #ifndef NO_PUSHBUTTON\r
181 /**\r
182  *  \brief Handler for Button 1 rising edge interrupt.\r
183  *\r
184  *  Handle process led1 status change.\r
185  */\r
186 static void _Button1_Handler( const Pin* pin )\r
187 {\r
188     pin = pin;\r
189     ProcessButtonEvt( 0 ) ;\r
190 }\r
191 \r
192 /**\r
193  *  \brief Handler for Button 2 falling edge interrupt.\r
194  *\r
195  *  Handle process led2 status change.\r
196  */\r
197 static void _Button2_Handler( const Pin* pin )\r
198 {\r
199     pin = pin;\r
200     ProcessButtonEvt( 1 ) ;\r
201 }\r
202 #else\r
203 /**\r
204  *  \brief Handler for DBGU input.\r
205  *\r
206  *  Handle process LED1 or LED2 status change.\r
207  */\r
208 static void _DBGU_Handler( void )\r
209 {\r
210     uint8_t key;\r
211     if ( !DBGU_IsRxReady( ) ) return ;\r
212     key = DBGU_GetChar( ) ;\r
213     switch ( key )\r
214     {\r
215         case '1': case '2':\r
216             ProcessButtonEvt( key - '1' ) ;\r
217         break;\r
218     }\r
219 }\r
220 #endif\r
221 \r
222 /**\r
223  *  \brief Handler for PIT interrupt.\r
224  */\r
225 static void _Pit_Handler( void )\r
226 {\r
227     uint32_t status;\r
228 \r
229     /* Read the PIT status register */\r
230     status = PIT_GetStatus() & PIT_SR_PITS;\r
231     if (status != 0) {\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
236     }\r
237 }\r
238 \r
239 /**\r
240  *  \brief Handler for Sysc interrupts.\r
241  */\r
242 static void _Sysc_Handler( void )\r
243 {\r
244     _Pit_Handler( ) ;\r
245   #ifdef NO_PUSHBUTTON\r
246     _DBGU_Handler( ) ;\r
247   #endif\r
248 }\r
249 \r
250 /**\r
251  *  \brief Configure the periodic interval timer (PIT) to generate an interrupt every\r
252  *  interrupt every millisecond\r
253  */\r
254 static void ConfigurePit(void)\r
255 {\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
262     PIT_EnableIT();\r
263     /* Enable the pit */\r
264     PIT_Enable();\r
265 }\r
266 \r
267 #ifndef NO_PUSHBUTTON\r
268 /**\r
269  *  \brief Configure the Pushbuttons\r
270  *\r
271  *  Configure the PIO as inputs and generate corresponding interrupt when\r
272  *  pressed or released.\r
273  */\r
274 static void _ConfigureButtons( void )\r
275 {\r
276     /* Configure pios as inputs. */\r
277     PIO_Configure( &pinPB1, 1 ) ;\r
278     PIO_Configure( &pinPB2, 1 ) ;\r
279 \r
280     /* Adjust pio debounce filter patameters, uses 10 Hz filter. */\r
281     PIO_SetDebounceFilter( &pinPB1, 10 ) ;\r
282     PIO_SetDebounceFilter( &pinPB1, 10 ) ;\r
283 \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
289 \r
290     /* Enable PIO line interrupts. */\r
291     PIO_EnableIt( &pinPB1 ) ;\r
292     PIO_EnableIt( &pinPB2 ) ;\r
293 }\r
294 #endif\r
295 \r
296 /**\r
297  *  \brief Configure LEDs\r
298  *\r
299  *  Configures LEDs \#1 and \#2 (cleared by default).\r
300  */\r
301 static void _ConfigureLeds( void )\r
302 {\r
303     LED_Configure( 0 ) ;\r
304     LED_Configure( 1 ) ;\r
305 }\r
306 \r
307 /**\r
308  *  Interrupt handler for TC0 interrupt. Toggles the state of LED\#2.\r
309  */\r
310 static void TC0_IrqHandler( void )\r
311 {\r
312     volatile uint32_t dummy;\r
313     /* Clear status bit to acknowledge interrupt */\r
314     dummy = TC0->TC_CHANNEL[ 0 ].TC_SR ;\r
315 \r
316     /** Toggle LED state. */\r
317     LED_Toggle( 1 ) ;\r
318     printf( "2 " ) ;\r
319 }\r
320 \r
321 /**\r
322  *  Configure Timer Counter 0 to generate an interrupt every 250ms.\r
323  */\r
324 static void _ConfigureTc( void )\r
325 {\r
326     uint32_t div;\r
327     uint32_t tcclks;\r
328 \r
329     /** Enable peripheral clock. */\r
330     PMC->PMC_PCER0 = 1 << ID_TC0;\r
331 \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
336 \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
341 \r
342     /** Start the counter if LED1 is enabled. */\r
343     if ( bLed1Active )\r
344     {\r
345         TC_Start( TC0, 0 );\r
346     }\r
347 }\r
348 \r
349 /**\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
353  */\r
354 static void _Wait( unsigned long delay )\r
355 {\r
356     volatile uint32_t start = dwTimeStamp;\r
357     uint32_t elapsed;\r
358     do {\r
359         elapsed = dwTimeStamp;\r
360         elapsed -= start;\r
361     }\r
362     while (elapsed < delay);\r
363 }\r
364 \r
365 /*----------------------------------------------------------------------------\r
366  *        Global functions\r
367  *----------------------------------------------------------------------------*/\r
368 \r
369 /**\r
370  *  \brief getting-started Application entry point.\r
371  *\r
372  *  \return Unused (ANSI-C compatibility).\r
373  */\r
374 int atmel_main( void );\r
375 int atmel_main( void )\r
376 {\r
377     /* Disable watchdog */\r
378     WDT_Disable( WDT ) ;\r
379 #if defined (ddram)\r
380     MMU_Initialize((uint32_t *)0x30C000);\r
381     CP15_EnableMMU();\r
382     CP15_EnableDcache();\r
383     CP15_EnableIcache();\r
384 #endif\r
385 \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
390 \r
391     /* Configure PIT. */\r
392     printf( "Configure PIT \n\r" ) ;\r
393 //__asm volatile( "cpsid i" );\r
394     ConfigurePit() ;\r
395 \r
396     /* PIO configuration for LEDs and Buttons. */\r
397     PIO_InitializeInterrupts( IRQ_PRIOR_PIO ) ;\r
398 \r
399     printf( "Configure TC.\n\r" );\r
400     _ConfigureTc() ;\r
401 \r
402     printf( "Configure LED PIOs.\n\r" ) ;\r
403     _ConfigureLeds() ;\r
404 \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
410 \r
411 #else\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
415 \r
416 #endif\r
417 \r
418     while ( 1 )\r
419     {\r
420         /* Wait for LED to be active */\r
421         while( !bLed0Active );\r
422 \r
423         /* Toggle LED state if active */\r
424         if ( bLed0Active )\r
425         {\r
426             LED_Toggle( 0 );\r
427             printf( "1 " );\r
428         }\r
429 \r
430         /* Wait for 500ms */\r
431         _Wait(500);\r
432     }\r
433 }\r