]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/atmel_main.c
7d50230d4cd6b06ad554c8b0e81216ba36c46d64
[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 void _Sysc_Handler( void );\r
243 void _Sysc_Handler( void )\r
244 {\r
245     _Pit_Handler( ) ;\r
246   #ifdef NO_PUSHBUTTON\r
247     _DBGU_Handler( ) ;\r
248   #endif\r
249 }\r
250 \r
251 /**\r
252  *  \brief Configure the periodic interval timer (PIT) to generate an interrupt every\r
253  *  interrupt every millisecond\r
254  */\r
255 static void ConfigurePit(void)\r
256 {\r
257     PMC->PMC_PCER0 = 1 << ID_PIT;\r
258    /* Initialize the PIT to the desired frequency */\r
259     PIT_Init(BLINK_PERIOD, BOARD_MCK / 1000000);\r
260     /* Configure interrupt on PIT */\r
261     IRQ_ConfigureIT(ID_PIT, 0, _Sysc_Handler);\r
262     IRQ_EnableIT(ID_PIT);\r
263     PIT_EnableIT();\r
264     /* Enable the pit */\r
265     PIT_Enable();\r
266 }\r
267 \r
268 #ifndef NO_PUSHBUTTON\r
269 /**\r
270  *  \brief Configure the Pushbuttons\r
271  *\r
272  *  Configure the PIO as inputs and generate corresponding interrupt when\r
273  *  pressed or released.\r
274  */\r
275 static void _ConfigureButtons( void )\r
276 {\r
277     /* Configure pios as inputs. */\r
278     PIO_Configure( &pinPB1, 1 ) ;\r
279     PIO_Configure( &pinPB2, 1 ) ;\r
280 \r
281     /* Adjust pio debounce filter patameters, uses 10 Hz filter. */\r
282     PIO_SetDebounceFilter( &pinPB1, 10 ) ;\r
283     PIO_SetDebounceFilter( &pinPB1, 10 ) ;\r
284 \r
285     /* Enable PIO controller IRQs. */\r
286     PIO_InitializeInterrupts(0);\r
287     /* Initialize pios interrupt handlers, see PIO definition in board.h. */\r
288     PIO_ConfigureIt(&pinPB1, (void (*)(const Pin *))_Button1_Handler);\r
289     PIO_ConfigureIt(&pinPB2, (void (*)(const Pin *))_Button2_Handler);\r
290 \r
291     /* Enable PIO line interrupts. */\r
292     PIO_EnableIt( &pinPB1 ) ;\r
293     PIO_EnableIt( &pinPB2 ) ;\r
294 }\r
295 #endif\r
296 \r
297 /**\r
298  *  \brief Configure LEDs\r
299  *\r
300  *  Configures LEDs \#1 and \#2 (cleared by default).\r
301  */\r
302 static void _ConfigureLeds( void )\r
303 {\r
304     LED_Configure( 0 ) ;\r
305     LED_Configure( 1 ) ;\r
306 }\r
307 \r
308 /**\r
309  *  Interrupt handler for TC0 interrupt. Toggles the state of LED\#2.\r
310  */\r
311 static void TC0_IrqHandler( void )\r
312 {\r
313     volatile uint32_t dummy;\r
314     /* Clear status bit to acknowledge interrupt */\r
315     dummy = TC0->TC_CHANNEL[ 0 ].TC_SR ;\r
316 \r
317     /** Toggle LED state. */\r
318     LED_Toggle( 1 ) ;\r
319     printf( "2 " ) ;\r
320 }\r
321 \r
322 /**\r
323  *  Configure Timer Counter 0 to generate an interrupt every 250ms.\r
324  */\r
325 static void _ConfigureTc( void )\r
326 {\r
327     uint32_t div;\r
328     uint32_t tcclks;\r
329 \r
330     /** Enable peripheral clock. */\r
331     PMC->PMC_PCER0 = 1 << ID_TC0;\r
332 \r
333     /** Configure TC for a 4Hz frequency and trigger on RC compare. */\r
334     TC_FindMckDivisor( 4, BOARD_MCK, &div, &tcclks, BOARD_MCK );\r
335     TC_Configure( TC0, 0, tcclks | TC_CMR_CPCTRG );\r
336     TC0->TC_CHANNEL[ 0 ].TC_RC = ( BOARD_MCK / div ) / 4;\r
337 \r
338     /* Configure and enable interrupt on RC compare */\r
339     IRQ_ConfigureIT(ID_TC0, 0, TC0_IrqHandler);\r
340     TC0->TC_CHANNEL[ 0 ].TC_IER = TC_IER_CPCS;\r
341     IRQ_EnableIT(ID_TC0);\r
342 \r
343     /** Start the counter if LED1 is enabled. */\r
344     if ( bLed1Active )\r
345     {\r
346         TC_Start( TC0, 0 );\r
347     }\r
348 }\r
349 \r
350 /**\r
351  *  Waits for the given number of milliseconds (using the dwTimeStamp generated\r
352  *  by the SAM3's microcontrollers's system tick).\r
353  *  \param delay  Delay to wait for, in milliseconds.\r
354  */\r
355 static void _Wait( unsigned long delay )\r
356 {\r
357     volatile uint32_t start = dwTimeStamp;\r
358     uint32_t elapsed;\r
359     do {\r
360         elapsed = dwTimeStamp;\r
361         elapsed -= start;\r
362     }\r
363     while (elapsed < delay);\r
364 }\r
365 \r
366 /*----------------------------------------------------------------------------\r
367  *        Global functions\r
368  *----------------------------------------------------------------------------*/\r
369 \r
370 /**\r
371  *  \brief getting-started Application entry point.\r
372  *\r
373  *  \return Unused (ANSI-C compatibility).\r
374  */\r
375 int atmel_main( void );\r
376 int atmel_main( void )\r
377 {\r
378     /* Disable watchdog */\r
379     WDT_Disable( WDT ) ;\r
380 #if defined (ddram)\r
381     MMU_Initialize((uint32_t *)0x30C000);\r
382     CP15_EnableMMU();\r
383     CP15_EnableDcache();\r
384     CP15_EnableIcache();\r
385 #endif\r
386 \r
387     /* Output example information */\r
388     printf( "-- Getting Started Example %s --\n\r", SOFTPACK_VERSION ) ;\r
389     printf( "-- %s\n\r", BOARD_NAME ) ;\r
390     printf( "-- Compiled: %s %s --\n\r", __DATE__, __TIME__ ) ;\r
391 \r
392     /* Configure PIT. */\r
393     printf( "Configure PIT \n\r" ) ;\r
394 //__asm volatile( "cpsid i" );\r
395     ConfigurePit() ;\r
396 \r
397     /* PIO configuration for LEDs and Buttons. */\r
398     PIO_InitializeInterrupts( IRQ_PRIOR_PIO ) ;\r
399 \r
400     printf( "Configure TC.\n\r" );\r
401     _ConfigureTc() ;\r
402 \r
403     printf( "Configure LED PIOs.\n\r" ) ;\r
404     _ConfigureLeds() ;\r
405 \r
406 #ifndef NO_PUSHBUTTON\r
407     printf( "Configure buttons with debouncing.\n\r" ) ;\r
408     _ConfigureButtons() ;\r
409     printf( "Press USRBP1 to Start/Stop the blue LED D1 blinking.\n\r" ) ;\r
410     printf( "Press USRBP2 to Start/Stop the red LED D2 blinking.\n\r" ) ;\r
411 \r
412 #else\r
413     printf( "No push buttons, uses DBG key 1 & 2 instead.\n\r" ) ;\r
414     printf( "Press 1 to Start/Stop the blue LED D1 blinking.\n\r" ) ;\r
415     printf( "Press 2 to Start/Stop the red LED D2 blinking.\n\r" ) ;\r
416 \r
417 #endif\r
418 \r
419     while ( 1 )\r
420     {\r
421         /* Wait for LED to be active */\r
422         while( !bLed0Active );\r
423 \r
424         /* Toggle LED state if active */\r
425         if ( bLed0Active )\r
426         {\r
427             LED_Toggle( 0 );\r
428             printf( "1 " );\r
429         }\r
430 \r
431         /* Wait for 500ms */\r
432         _Wait(500);\r
433     }\r
434 }\r