-/* ----------------------------------------------------------------------------\r
- * SAM Software Package License\r
- * ----------------------------------------------------------------------------\r
- * Copyright (c) 2014, Atmel Corporation\r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * - Redistributions of source code must retain the above copyright notice,\r
- * this list of conditions and the disclaimer below.\r
- *\r
- * Atmel's name may not be used to endorse or promote products derived from\r
- * this software without specific prior written permission.\r
- *\r
- * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
- * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * ----------------------------------------------------------------------------\r
- */\r
-\r
-\r
-/**\r
- * \page getting-started Getting Started with sama5d3 Microcontrollers\r
- *\r
- * \section Purpose\r
- *\r
- * The Getting Started example will help new users get familiar with Atmel's\r
- * sama5d3x microcontroller. This basic application shows the startup\r
- * sequence of a chip and how to use its core peripherals.\r
- *\r
- * \section Requirements\r
- *\r
- * This package can be used with sama5d3 xplained board.\r
- *\r
- * \section Description\r
- *\r
- * The demonstration program makes two LEDs on the board blink at a fixed rate.\r
- * This rate is generated by using Time tick timer. The blinking can be stopped\r
- * using two buttons (one for each LED). If there is no enough buttons on board, please\r
- * type "1" or "2" in the terminal application on PC to control the LEDs\r
- * instead.\r
- *\r
- * \section Usage\r
- *\r
- * -# Build the program and download it inside the xplained board. Please\r
- * refer to the\r
- * <a href="http://www.atmel.com/dyn/resources/prod_documents/6421B.pdf">\r
- * SAM-BA User Guide</a>, the\r
- * <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">\r
- * GNU-Based Software Development</a>\r
- * application note or to the\r
- * <a href="ftp://ftp.iar.se/WWWfiles/arm/Guides/EWARM_UserGuide.ENU.pdf">\r
- * IAR EWARM User Guide</a>,\r
- * depending on your chosen solution.\r
- * -# On the computer, open and configure a terminal application\r
- * (e.g. HyperTerminal on Microsoft Windows) with these settings:\r
- * - 115200 bauds\r
- * - 8 bits of data\r
- * - No parity\r
- * - 1 stop bit\r
- * - No flow control\r
- * -# Start the application.\r
- * -# Two LEDs should start blinking on the board. In the terminal window, the\r
- * following text should appear (values depend on the board and chip used):\r
- * \code\r
- * -- Getting Started Example xxx --\r
- * -- SAMxxxxx-xx\r
- * -- Compiled: xxx xx xxxx xx:xx:xx --\r
- * \endcode\r
- * -# Pressing and release button 1 or type "1" in the terminal application on\r
- * PC should make the first LED stop & restart blinking.\r
- * Pressing and release button 2 or type "1" in the terminal application on\r
- * PC should make the other LED stop & restart blinking.\r
- *\r
- * \section References\r
- * - getting-started/main.c\r
- * - pio.h\r
- * - pio_it.h\r
- * - led.h\r
- * - trace.h\r
- */\r
-\r
-/** \file\r
- *\r
- * This file contains all the specific code for the getting-started example.\r
- *\r
- */\r
-\r
-/*----------------------------------------------------------------------------\r
- * Headers\r
- *----------------------------------------------------------------------------*/\r
-\r
-#include "board.h"\r
-\r
-#include <stdbool.h>\r
-#include <stdio.h>\r
-\r
-/*----------------------------------------------------------------------------\r
- * Local definitions\r
- *----------------------------------------------------------------------------*/\r
-\r
-#define NO_PUSHBUTTON\r
-\r
-/** IRQ priority for PIO (The lower the value, the greater the priority) */\r
-#define IRQ_PRIOR_PIO 0\r
-\r
-/** LED0 blink time, LED1 blink half this time, in ms */\r
-#define BLINK_PERIOD 1000\r
-\r
-/** Delay for pushbutton debouncing (in milliseconds). */\r
-#define DEBOUNCE_TIME 500\r
-\r
-/*----------------------------------------------------------------------------\r
- * Local variables\r
- *----------------------------------------------------------------------------*/\r
-\r
-#ifndef NO_PUSHBUTTON\r
-/** Pushbutton \#1 pin instance. */\r
-const Pin pinPB1 = PIN_PUSHBUTTON_1 ;\r
-/** Pushbutton \#1 pin instance. */\r
-const Pin pinPB2 = PIN_PUSHBUTTON_2 ;\r
-#endif\r
-\r
-/** LED0 blinking control. */\r
-volatile bool bLed0Active = true ;\r
-\r
-/** LED1 blinking control. */\r
-volatile bool bLed1Active = true ;\r
-\r
-/** Global timestamp in milliseconds since start of application */\r
-volatile uint32_t dwTimeStamp = 0;\r
-\r
-/*----------------------------------------------------------------------------\r
- * Local functions\r
- *----------------------------------------------------------------------------*/\r
-\r
-/**\r
- * \brief Process Buttons Events\r
- *\r
- * Change active states of LEDs when corresponding button events happened.\r
- */\r
-static void ProcessButtonEvt( uint8_t ucButton )\r
-{\r
- if ( ucButton == 0 )\r
- {\r
- bLed0Active = !bLed0Active ;\r
- if ( !bLed0Active )\r
- {\r
- LED_Clear( 0 );\r
- }\r
- }\r
- else\r
- {\r
- bLed1Active = !bLed1Active ;\r
-\r
- /* Enable LED#2 and TC if they were disabled */\r
- if ( bLed1Active )\r
- {\r
- LED_Set( 1 );\r
- TC_Start( TC0, 0 );\r
- }\r
- /* Disable LED#2 and TC if they were enabled */\r
- else\r
- {\r
- LED_Clear( 1 );\r
- TC_Stop( TC0, 0 );\r
- }\r
- }\r
-}\r
-\r
-#ifndef NO_PUSHBUTTON\r
-/**\r
- * \brief Handler for Button 1 rising edge interrupt.\r
- *\r
- * Handle process led1 status change.\r
- */\r
-static void _Button1_Handler( const Pin* pin )\r
-{\r
- pin = pin;\r
- ProcessButtonEvt( 0 ) ;\r
-}\r
-\r
-/**\r
- * \brief Handler for Button 2 falling edge interrupt.\r
- *\r
- * Handle process led2 status change.\r
- */\r
-static void _Button2_Handler( const Pin* pin )\r
-{\r
- pin = pin;\r
- ProcessButtonEvt( 1 ) ;\r
-}\r
-#else\r
-/**\r
- * \brief Handler for DBGU input.\r
- *\r
- * Handle process LED1 or LED2 status change.\r
- */\r
-static void _DBGU_Handler( void )\r
-{\r
- uint8_t key;\r
- if ( !DBGU_IsRxReady( ) ) return ;\r
- key = DBGU_GetChar( ) ;\r
- switch ( key )\r
- {\r
- case '1': case '2':\r
- ProcessButtonEvt( key - '1' ) ;\r
- break;\r
- }\r
-}\r
-#endif\r
-\r
-/**\r
- * \brief Handler for PIT interrupt.\r
- */\r
-static void _Pit_Handler( void )\r
-{\r
- uint32_t status;\r
-\r
- /* Read the PIT status register */\r
- status = PIT_GetStatus() & PIT_SR_PITS;\r
- if (status != 0) {\r
- /* 1 = The Periodic Interval timer has reached PIV since the last read of PIT_PIVR.\r
- Read the PIVR to acknowledge interrupt and get number of ticks\r
- Returns the number of occurrences of periodic intervals since the last read of PIT_PIVR. */\r
- dwTimeStamp += (PIT_GetPIVR() >> 20);\r
- }\r
-}\r
-\r
-/**\r
- * \brief Handler for Sysc interrupts.\r
- */\r
-void _Sysc_Handler( void );\r
-void _Sysc_Handler( void )\r
-{\r
- _Pit_Handler( ) ;\r
- #ifdef NO_PUSHBUTTON\r
- _DBGU_Handler( ) ;\r
- #endif\r
-}\r
-\r
-/**\r
- * \brief Configure the periodic interval timer (PIT) to generate an interrupt every\r
- * interrupt every millisecond\r
- */\r
-static void ConfigurePit(void)\r
-{\r
- PMC->PMC_PCER0 = 1 << ID_PIT;\r
- /* Initialize the PIT to the desired frequency */\r
- PIT_Init(BLINK_PERIOD, BOARD_MCK / 1000000);\r
- /* Configure interrupt on PIT */\r
- IRQ_ConfigureIT(ID_PIT, 0, _Sysc_Handler);\r
- IRQ_EnableIT(ID_PIT);\r
- PIT_EnableIT();\r
- /* Enable the pit */\r
- PIT_Enable();\r
-}\r
-\r
-#ifndef NO_PUSHBUTTON\r
-/**\r
- * \brief Configure the Pushbuttons\r
- *\r
- * Configure the PIO as inputs and generate corresponding interrupt when\r
- * pressed or released.\r
- */\r
-static void _ConfigureButtons( void )\r
-{\r
- /* Configure pios as inputs. */\r
- PIO_Configure( &pinPB1, 1 ) ;\r
- PIO_Configure( &pinPB2, 1 ) ;\r
-\r
- /* Adjust pio debounce filter patameters, uses 10 Hz filter. */\r
- PIO_SetDebounceFilter( &pinPB1, 10 ) ;\r
- PIO_SetDebounceFilter( &pinPB1, 10 ) ;\r
-\r
- /* Enable PIO controller IRQs. */\r
- PIO_InitializeInterrupts(0);\r
- /* Initialize pios interrupt handlers, see PIO definition in board.h. */\r
- PIO_ConfigureIt(&pinPB1, (void (*)(const Pin *))_Button1_Handler);\r
- PIO_ConfigureIt(&pinPB2, (void (*)(const Pin *))_Button2_Handler);\r
-\r
- /* Enable PIO line interrupts. */\r
- PIO_EnableIt( &pinPB1 ) ;\r
- PIO_EnableIt( &pinPB2 ) ;\r
-}\r
-#endif\r
-\r
-/**\r
- * \brief Configure LEDs\r
- *\r
- * Configures LEDs \#1 and \#2 (cleared by default).\r
- */\r
-static void _ConfigureLeds( void )\r
-{\r
- LED_Configure( 0 ) ;\r
- LED_Configure( 1 ) ;\r
-}\r
-\r
-/**\r
- * Interrupt handler for TC0 interrupt. Toggles the state of LED\#2.\r
- */\r
-static void TC0_IrqHandler( void )\r
-{\r
- volatile uint32_t dummy;\r
- /* Clear status bit to acknowledge interrupt */\r
- dummy = TC0->TC_CHANNEL[ 0 ].TC_SR ;\r
-\r
- /** Toggle LED state. */\r
- LED_Toggle( 1 ) ;\r
- printf( "2 " ) ;\r
-}\r
-\r
-/**\r
- * Configure Timer Counter 0 to generate an interrupt every 250ms.\r
- */\r
-static void _ConfigureTc( void )\r
-{\r
- uint32_t div;\r
- uint32_t tcclks;\r
-\r
- /** Enable peripheral clock. */\r
- PMC->PMC_PCER0 = 1 << ID_TC0;\r
-\r
- /** Configure TC for a 4Hz frequency and trigger on RC compare. */\r
- TC_FindMckDivisor( 4, BOARD_MCK, &div, &tcclks, BOARD_MCK );\r
- TC_Configure( TC0, 0, tcclks | TC_CMR_CPCTRG );\r
- TC0->TC_CHANNEL[ 0 ].TC_RC = ( BOARD_MCK / div ) / 4;\r
-\r
- /* Configure and enable interrupt on RC compare */\r
- IRQ_ConfigureIT(ID_TC0, 0, TC0_IrqHandler);\r
- TC0->TC_CHANNEL[ 0 ].TC_IER = TC_IER_CPCS;\r
- IRQ_EnableIT(ID_TC0);\r
-\r
- /** Start the counter if LED1 is enabled. */\r
- if ( bLed1Active )\r
- {\r
- TC_Start( TC0, 0 );\r
- }\r
-}\r
-\r
-/**\r
- * Waits for the given number of milliseconds (using the dwTimeStamp generated\r
- * by the SAM3's microcontrollers's system tick).\r
- * \param delay Delay to wait for, in milliseconds.\r
- */\r
-static void _Wait( unsigned long delay )\r
-{\r
- volatile uint32_t start = dwTimeStamp;\r
- uint32_t elapsed;\r
- do {\r
- elapsed = dwTimeStamp;\r
- elapsed -= start;\r
- }\r
- while (elapsed < delay);\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- * Global functions\r
- *----------------------------------------------------------------------------*/\r
-\r
-/**\r
- * \brief getting-started Application entry point.\r
- *\r
- * \return Unused (ANSI-C compatibility).\r
- */\r
-int atmel_main( void );\r
-int atmel_main( void )\r
-{\r
- /* Disable watchdog */\r
- WDT_Disable( WDT ) ;\r
-#if defined (ddram)\r
- MMU_Initialize((uint32_t *)0x30C000);\r
- CP15_EnableMMU();\r
- CP15_EnableDcache();\r
- CP15_EnableIcache();\r
-#endif\r
-\r
- /* Output example information */\r
- printf( "-- Getting Started Example %s --\n\r", SOFTPACK_VERSION ) ;\r
- printf( "-- %s\n\r", BOARD_NAME ) ;\r
- printf( "-- Compiled: %s %s --\n\r", __DATE__, __TIME__ ) ;\r
-\r
- /* Configure PIT. */\r
- printf( "Configure PIT \n\r" ) ;\r
-//__asm volatile( "cpsid i" );\r
- ConfigurePit() ;\r
-\r
- /* PIO configuration for LEDs and Buttons. */\r
- PIO_InitializeInterrupts( IRQ_PRIOR_PIO ) ;\r
-\r
- printf( "Configure TC.\n\r" );\r
- _ConfigureTc() ;\r
-\r
- printf( "Configure LED PIOs.\n\r" ) ;\r
- _ConfigureLeds() ;\r
-\r
-#ifndef NO_PUSHBUTTON\r
- printf( "Configure buttons with debouncing.\n\r" ) ;\r
- _ConfigureButtons() ;\r
- printf( "Press USRBP1 to Start/Stop the blue LED D1 blinking.\n\r" ) ;\r
- printf( "Press USRBP2 to Start/Stop the red LED D2 blinking.\n\r" ) ;\r
-\r
-#else\r
- printf( "No push buttons, uses DBG key 1 & 2 instead.\n\r" ) ;\r
- printf( "Press 1 to Start/Stop the blue LED D1 blinking.\n\r" ) ;\r
- printf( "Press 2 to Start/Stop the red LED D2 blinking.\n\r" ) ;\r
-\r
-#endif\r
-\r
- while ( 1 )\r
- {\r
- /* Wait for LED to be active */\r
- while( !bLed0Active );\r
-\r
- /* Toggle LED state if active */\r
- if ( bLed0Active )\r
- {\r
- LED_Toggle( 0 );\r
- printf( "1 " );\r
- }\r
-\r
- /* Wait for 500ms */\r
- _Wait(500);\r
- }\r
-}\r