initial
diff --git a/sam3s_example/src/board_cstartup_gnu.c b/sam3s_example/src/board_cstartup_gnu.c
new file mode 100644
index 0000000..423e775
--- /dev/null
+++ b/sam3s_example/src/board_cstartup_gnu.c
@@ -0,0 +1,172 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2010, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,

+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ----------------------------------------------------------------------------

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "board.h"

+#include "board_lowlevel.h"

+

+/*----------------------------------------------------------------------------

+ *        Exported variables

+ *----------------------------------------------------------------------------*/

+

+/* Stack Configuration */  

+#define STACK_SIZE       0x900     /** Stack size (in DWords) */

+__attribute__ ((aligned(8),section(".stack")))

+uint32_t pdwStack[STACK_SIZE] ;     

+

+/* Initialize segments */

+extern uint32_t _sfixed;

+extern uint32_t _efixed;

+extern uint32_t _etext;

+extern uint32_t _srelocate;

+extern uint32_t _erelocate;

+extern uint32_t _szero;

+extern uint32_t _ezero;

+

+

+/*----------------------------------------------------------------------------

+ *        ProtoTypes

+ *----------------------------------------------------------------------------*/

+extern int main( void ) ;

+extern void __libc_init_array( void ) ;

+void ResetException( void ) ;

+

+/*------------------------------------------------------------------------------

+ *         Exception Table

+ *------------------------------------------------------------------------------*/

+

+__attribute__((section(".vectors")))

+IntFunc exception_table[] = {

+

+    /* Configure Initial Stack Pointer, using linker-generated symbols */

+    (IntFunc)(&pdwStack[STACK_SIZE-1]),

+    ResetException,

+

+    NMI_Handler,

+    HardFault_Handler,

+    MemManage_Handler,

+    BusFault_Handler,

+    UsageFault_Handler,

+    0, 0, 0, 0,         /* Reserved */

+    SVC_Handler,

+    DebugMon_Handler,

+    0,                  /* Reserved  */

+    PendSV_Handler,

+    SysTick_Handler,

+

+    /* Configurable interrupts  */

+    SUPC_IrqHandler,    /* 0  Supply Controller */

+    RSTC_IrqHandler,    /* 1  Reset Controller */

+    RTC_IrqHandler,     /* 2  Real Time Clock */

+    RTT_IrqHandler,     /* 3  Real Time Timer */

+    WDT_IrqHandler,     /* 4  Watchdog Timer */

+    PMC_IrqHandler,     /* 5  PMC */

+    EEFC_IrqHandler,    /* 6  EEFC */

+    IrqHandlerNotUsed,  /* 7  Reserved */

+    UART0_IrqHandler,   /* 8  UART0 */

+    UART1_IrqHandler,   /* 9  UART1 */

+    SMC_IrqHandler,     /* 10 SMC */

+    PIOA_IrqHandler,    /* 11 Parallel IO Controller A */

+    PIOB_IrqHandler,    /* 12 Parallel IO Controller B */

+    PIOC_IrqHandler,    /* 13 Parallel IO Controller C */

+    USART0_IrqHandler,  /* 14 USART 0 */

+    USART1_IrqHandler,  /* 15 USART 1 */

+    IrqHandlerNotUsed,  /* 16 Reserved */

+    IrqHandlerNotUsed,  /* 17 Reserved */

+    MCI_IrqHandler,     /* 18 MCI */

+    TWI0_IrqHandler,    /* 19 TWI 0 */

+    TWI1_IrqHandler,    /* 20 TWI 1 */

+    SPI_IrqHandler,     /* 21 SPI */

+    SSC_IrqHandler,     /* 22 SSC */

+    TC0_IrqHandler,     /* 23 Timer Counter 0 */

+    TC1_IrqHandler,     /* 24 Timer Counter 1 */

+    TC2_IrqHandler,     /* 25 Timer Counter 2 */

+    TC3_IrqHandler,     /* 26 Timer Counter 3 */

+    TC4_IrqHandler,     /* 27 Timer Counter 4 */

+    TC5_IrqHandler,     /* 28 Timer Counter 5 */

+    ADC_IrqHandler,     /* 29 ADC controller */

+    DAC_IrqHandler,     /* 30 DAC controller */

+    PWM_IrqHandler,     /* 31 PWM */

+    CRCCU_IrqHandler,   /* 32 CRC Calculation Unit */

+    ACC_IrqHandler,     /* 33 Analog Comparator */

+    USBD_IrqHandler,    /* 34 USB Device Port */

+    IrqHandlerNotUsed   /* 35 not used */

+};

+

+/**

+ * \brief This is the code that gets called on processor reset.

+ * To initialize the device, and call the main() routine.

+ */

+void ResetException( void )

+{

+    uint32_t *pSrc, *pDest ;

+

+    /* Low level Initialize */

+    LowLevelInit() ;

+

+    /* Initialize the relocate segment */

+    pSrc = &_etext ;

+    pDest = &_srelocate ;

+

+    if ( pSrc != pDest )

+    {

+        for ( ; pDest < &_erelocate ; )

+        {

+            *pDest++ = *pSrc++ ;

+        }

+    }

+

+    /* Clear the zero segment */

+    for ( pDest = &_szero ; pDest < &_ezero ; )

+    {

+        *pDest++ = 0;

+    }

+

+    /* Set the vector table base address */

+    pSrc = (uint32_t *)&_sfixed;

+    SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ) ;

+    

+    if ( ((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE) )

+    {

+	    SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;

+    }

+

+    /* Initialize the C library */

+    __libc_init_array() ;

+

+    /* Branch to main function */

+    main() ;

+

+    /* Infinite loop */

+    while ( 1 ) ;

+}

+

diff --git a/sam3s_example/src/board_lowlevel.c b/sam3s_example/src/board_lowlevel.c
new file mode 100644
index 0000000..ca9f9dc
--- /dev/null
+++ b/sam3s_example/src/board_lowlevel.c
@@ -0,0 +1,124 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2009, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,

+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ----------------------------------------------------------------------------

+ */

+

+/**

+ * \file

+ *

+ * Provides the low-level initialization function that called on chip startup.

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "board.h"

+#include "board_lowlevel.h"

+

+/*----------------------------------------------------------------------------

+ *        Local definitions

+ *----------------------------------------------------------------------------*/

+

+/* Clock settings at 48MHz */

+#if (BOARD_MCK == 48000000)

+#define BOARD_OSCOUNT   (CKGR_MOR_MOSCXTST(0x8))

+#define BOARD_PLLAR     (CKGR_PLLAR_STUCKTO1 \

+                       | CKGR_PLLAR_MULA(0x7) \

+                       | CKGR_PLLAR_PLLACOUNT(0x1) \

+                       | CKGR_PLLAR_DIVA(0x1))

+#define BOARD_MCKR      (PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)

+

+/* Clock settings at 64MHz */

+#elif (BOARD_MCK == 64000000)

+#define BOARD_OSCOUNT   (CKGR_MOR_MOSCXTST(0x8))

+#define BOARD_PLLAR     (CKGR_PLLAR_STUCKTO1 \

+                       | CKGR_PLLAR_MULA(0x0f) \

+                       | CKGR_PLLAR_PLLACOUNT(0x1) \

+                       | CKGR_PLLAR_DIVA(0x3))

+#define BOARD_MCKR      (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)

+

+#else

+    #error "No settings for current BOARD_MCK."

+#endif

+

+/* Define clock timeout */

+#define CLOCK_TIMEOUT    0xFFFFFFFF

+

+/*----------------------------------------------------------------------------

+ *        Exported functions

+ *----------------------------------------------------------------------------*/

+

+/**

+ * \brief Performs the low-level initialization of the chip.

+ * This includes EFC and master clock configuration.

+ * It also enable a low level on the pin NRST triggers a user reset.

+ */

+WEAK void LowLevelInit( void )

+{

+    uint32_t timeout = 0;

+

+    /* Set 3 FWS for Embedded Flash Access */

+    EFC->EEFC_FMR = EEFC_FMR_FWS(3);

+

+    /* Select external slow clock */

+#if 0

+    if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST)

+    {

+        SUPC->SUPC_CR = (uint32_t)(SUPC_CR_XTALSEL_CRYSTAL_SEL | SUPC_CR_KEY(0xA5));

+        timeout = 0;

+        while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST) );

+    }

+#endif

+

+    /* Initialize main oscillator */

+    if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )

+    {

+        PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;

+        timeout = 0;

+        while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));

+    }

+

+    /* Switch to 3-20MHz Xtal oscillator */

+    PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;

+    timeout = 0;

+    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));

+    PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;

+    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

+

+    /* Initialize PLLA */

+    PMC->CKGR_PLLAR = BOARD_PLLAR;

+    timeout = 0;

+    while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));

+

+    /* Switch to main clock */

+    PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;

+    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

+

+    PMC->PMC_MCKR = BOARD_MCKR ;

+    for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );

+}

diff --git a/sam3s_example/src/exceptions.c b/sam3s_example/src/exceptions.c
new file mode 100644
index 0000000..6c55ede
--- /dev/null
+++ b/sam3s_example/src/exceptions.c
@@ -0,0 +1,384 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2009, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,

+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ----------------------------------------------------------------------------

+ */

+

+/**

+ * \file

+ * This file contains the default exception handlers.

+ *

+ * \note

+ * The exception handler has weak aliases.

+ * As they are weak aliases, any function with the same name will override

+ * this definition.

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "chip.h"

+

+/*----------------------------------------------------------------------------

+ *        Exported functions

+ *----------------------------------------------------------------------------*/

+

+/**

+ * \brief Default interrupt handler for not used irq.

+ */

+void IrqHandlerNotUsed( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default NMI interrupt handler.

+ */

+WEAK void NMI_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default HardFault interrupt handler.

+ */

+WEAK void HardFault_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default MemManage interrupt handler.

+ */

+WEAK void MemManage_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default BusFault interrupt handler.

+ */

+WEAK void BusFault_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default UsageFault interrupt handler.

+ */

+WEAK void UsageFault_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SVC interrupt handler.

+ */

+WEAK void SVC_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default DebugMon interrupt handler.

+ */

+WEAK void DebugMon_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default PendSV interrupt handler.

+ */

+WEAK void PendSV_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SysTick interrupt handler.

+ */

+WEAK void SysTick_Handler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for Supply Controller.

+ */

+WEAK void SUPC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for Reset Controller.

+ */

+WEAK void RSTC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for Real Time Clock.

+ */

+WEAK void RTC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for Real Time Timer.

+ */

+WEAK void RTT_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for Watchdog Timer.

+ */

+WEAK void WDT_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for PMC.

+ */

+WEAK void PMC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for EEFC.

+ */

+WEAK void EEFC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for UART0.

+ */

+WEAK void UART0_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for UART1.

+ */

+WEAK void UART1_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for SMC.

+ */

+WEAK void SMC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for PIOA Controller.

+ */

+WEAK void PIOA_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for PIOB Controller.

+ */

+WEAK void PIOB_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for PIOC Controller.

+ */

+WEAK void PIOC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for USART0.

+ */

+WEAK void USART0_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for USART1.

+ */

+WEAK void USART1_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for MCI.

+ */

+WEAK void MCI_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for TWI0.

+ */

+WEAK void TWI0_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for TWI1.

+ */

+WEAK void TWI1_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for SPI.

+ */

+WEAK void SPI_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for SSC.

+ */

+WEAK void SSC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for TC0.

+ */

+WEAK void TC0_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for TC1.

+ */

+WEAK void TC1_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default interrupt handler for TC2.

+ */

+WEAK void TC2_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for TC3.

+ */

+WEAK void TC3_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for TC4.

+ */

+WEAK void TC4_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for TC5.

+ */

+WEAK void TC5_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for ADC.

+ */

+WEAK void ADC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for DAC.

+ */

+WEAK void DAC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for PWM.

+ */

+WEAK void PWM_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for CRCCU.

+ */

+WEAK void CRCCU_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for ACC.

+ */

+WEAK void ACC_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

+

+/**

+ * \brief Default SUPC interrupt handler for USBD.

+ */

+WEAK void USBD_IrqHandler( void )

+{

+    while ( 1 ) ;

+}

diff --git a/sam3s_example/src/pio.c b/sam3s_example/src/pio.c
new file mode 100644
index 0000000..3bc258e
--- /dev/null
+++ b/sam3s_example/src/pio.c
@@ -0,0 +1,454 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2010, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,

+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ----------------------------------------------------------------------------

+ */

+

+/** \file */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+#include "chip.h"

+#include "pio.h"

+#include "pmc.h"

+

+

+/*----------------------------------------------------------------------------

+ *        Local functions

+ *----------------------------------------------------------------------------*/

+

+/**

+ * \brief Configures one or more pin(s) of a PIO controller as being controlled by

+ * peripheral A. Optionally, the corresponding internal pull-up(s) can be enabled.

+ *

+ * \param pio  Pointer to a PIO controller.

+ * \param mask  Bitmask of one or more pin(s) to configure.

+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be

+ *                      configured.

+ */

+static void PIO_SetPeripheralA(

+    Pio *pio,

+    unsigned int mask,

+    unsigned char enablePullUp)

+{

+    unsigned int abcdsr;

+    /* Disable interrupts on the pin(s) */

+    pio->PIO_IDR = mask;

+

+    /* Enable the pull-up(s) if necessary */

+    if (enablePullUp) {

+        pio->PIO_PUER = mask;

+    }

+    else {

+

+        pio->PIO_PUDR = mask;

+    }

+

+    abcdsr = pio->PIO_ABCDSR[0];

+    pio->PIO_ABCDSR[0] &= (~mask & abcdsr);

+    abcdsr = pio->PIO_ABCDSR[1];

+    pio->PIO_ABCDSR[1] &= (~mask & abcdsr);

+    pio->PIO_PDR = mask;

+}

+

+/**

+ * \brief Configures one or more pin(s) of a PIO controller as being controlled by

+ * peripheral B. Optionally, the corresponding internal pull-up(s) can be enabled.

+ *

+ * \param pio  Pointer to a PIO controller.

+ * \param mask  Bitmask of one or more pin(s) to configure.

+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be

+ *                      configured.

+ */

+static void PIO_SetPeripheralB(

+    Pio *pio,

+    unsigned int mask,

+    unsigned char enablePullUp)

+{

+    unsigned int abcdsr;

+    /* Disable interrupts on the pin(s) */

+    pio->PIO_IDR = mask;

+

+    /* Enable the pull-up(s) if necessary */

+    if (enablePullUp) {

+

+        pio->PIO_PUER = mask;

+    }

+    else {

+

+        pio->PIO_PUDR = mask;

+    }

+

+    abcdsr = pio->PIO_ABCDSR[0];

+    pio->PIO_ABCDSR[0] = (mask | abcdsr);

+    abcdsr = pio->PIO_ABCDSR[1];

+    pio->PIO_ABCDSR[1] &= (~mask & abcdsr);

+

+    pio->PIO_PDR = mask;

+}

+

+/**

+ * \brief Configures one or more pin(s) of a PIO controller as being controlled by

+ * peripheral C. Optionally, the corresponding internal pull-up(s) can be enabled.

+ *

+ * \param pio  Pointer to a PIO controller.

+ * \param mask  Bitmask of one or more pin(s) to configure.

+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be

+ *                      configured.

+ */

+static void PIO_SetPeripheralC(

+    Pio *pio,

+    unsigned int mask,

+    unsigned char enablePullUp)

+{

+    unsigned int abcdsr;

+    /* Disable interrupts on the pin(s) */

+    pio->PIO_IDR = mask;

+

+    /* Enable the pull-up(s) if necessary */

+    if (enablePullUp) {

+

+        pio->PIO_PUER = mask;

+    }

+    else {

+

+        pio->PIO_PUDR = mask;

+    }

+

+    abcdsr = pio->PIO_ABCDSR[0];

+    pio->PIO_ABCDSR[0] &= (~mask & abcdsr);

+    abcdsr = pio->PIO_ABCDSR[1];

+    pio->PIO_ABCDSR[1] = (mask | abcdsr);

+

+    pio->PIO_PDR = mask;

+}

+

+/**

+ * \brief Configures one or more pin(s) of a PIO controller as being controlled by

+ * peripheral D. Optionally, the corresponding internal pull-up(s) can be enabled.

+ *

+ * \param pio  Pointer to a PIO controller.

+ * \param mask  Bitmask of one or more pin(s) to configure.

+ * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be

+ *                      configured.

+ */

+static void PIO_SetPeripheralD(

+    Pio *pio,

+    unsigned int mask,

+    unsigned char enablePullUp)

+{

+    unsigned int abcdsr;

+    /* Disable interrupts on the pin(s) */

+    pio->PIO_IDR = mask;

+

+    /* Enable the pull-up(s) if necessary */

+    if (enablePullUp) {

+

+        pio->PIO_PUER = mask;

+    }

+    else {

+

+        pio->PIO_PUDR = mask;

+    }

+

+    abcdsr = pio->PIO_ABCDSR[0];

+    pio->PIO_ABCDSR[0] = (mask | abcdsr);

+    abcdsr = pio->PIO_ABCDSR[1];

+    pio->PIO_ABCDSR[1] = (mask | abcdsr);

+

+    pio->PIO_PDR = mask;

+}

+

+/**

+ * \brief Configures one or more pin(s) or a PIO controller as inputs. Optionally,

+ * the corresponding internal pull-up(s) and glitch filter(s) can be enabled.

+ *

+ * \param pio  Pointer to a PIO controller.

+ * \param mask  Bitmask indicating which pin(s) to configure as input(s).

+ * \param enablePullUp  Indicates if the internal pull-up(s) must be enabled.

+ * \param enableFilter  Indicates if the glitch filter(s) must be enabled.

+ */

+static void PIO_SetInput(

+    Pio *pio,

+    unsigned int mask,

+    unsigned char attribute)

+{

+    /* Disable interrupts */

+    pio->PIO_IDR = mask;

+

+    /* Enable pull-up(s) if necessary */

+    if (attribute & PIO_PULLUP)

+        pio->PIO_PUER = mask;

+    else

+        pio->PIO_PUDR = mask;

+

+    /* Enable Input Filter if necessary */

+    if (attribute & (PIO_DEGLITCH | PIO_DEBOUNCE))

+        pio->PIO_IFER = mask;

+    else

+        pio->PIO_IFDR = mask;

+

+    /* Enable de-glitch or de-bounce if necessary */

+    if (attribute & PIO_DEGLITCH)

+    {

+        pio->PIO_IFSCDR = mask;

+    }

+    else

+    {

+        if (attribute & PIO_DEBOUNCE)

+        {

+            pio->PIO_IFSCER = mask;

+        }

+    }

+

+    /* Configure pin as input */

+    pio->PIO_ODR = mask;

+    pio->PIO_PER = mask;

+}

+

+/**

+ * \brief Configures one or more pin(s) of a PIO controller as outputs, with the

+ * given default value. Optionally, the multi-drive feature can be enabled

+ * on the pin(s).

+ *

+ * \param pio  Pointer to a PIO controller.

+ * \param mask  Bitmask indicating which pin(s) to configure.

+ * \param defaultValue  Default level on the pin(s).

+ * \param enableMultiDrive  Indicates if the pin(s) shall be configured as

+ *                          open-drain.

+ * \param enablePullUp  Indicates if the pin shall have its pull-up activated.

+ */

+static void PIO_SetOutput(

+    Pio *pio,

+    unsigned int mask,

+    unsigned char defaultValue,

+    unsigned char enableMultiDrive,

+    unsigned char enablePullUp)

+{

+    /* Disable interrupts */

+    pio->PIO_IDR = mask;

+

+    /* Enable pull-up(s) if necessary */

+    if (enablePullUp) {

+

+        pio->PIO_PUER = mask;

+    }

+    else {

+

+        pio->PIO_PUDR = mask;

+    }

+

+    /* Enable multi-drive if necessary */

+    if (enableMultiDrive) {

+

+        pio->PIO_MDER = mask;

+    }

+    else {

+

+        pio->PIO_MDDR = mask;

+    }

+

+    /* Set default value */

+    if (defaultValue) {

+

+        pio->PIO_SODR = mask;

+    }

+    else {

+

+        pio->PIO_CODR = mask;

+    }

+

+    /* Configure pin(s) as output(s) */

+    pio->PIO_OER = mask;

+    pio->PIO_PER = mask;

+}

+

+/*----------------------------------------------------------------------------

+ *         Global functions

+ *----------------------------------------------------------------------------*/

+

+/**

+ * \brief Configures a list of Pin instances, each of which can either hold a single

+ * pin or a group of pins, depending on the mask value; all pins are configured

+ * by this function. The size of the array must also be provided and is easily

+ * computed using PIO_LISTSIZE whenever its length is not known in advance.

+ *

+ * \param list  Pointer to a list of Pin instances.

+ * \param size  Size of the Pin list (calculated using PIO_LISTSIZE).

+ *

+ * \return 1 if the pins have been configured properly; otherwise 0.

+ */

+uint8_t PIO_Configure( const Pin *list, uint32_t size )

+{

+    /* Configure pins */

+    while ( size > 0 )

+    {

+        switch ( list->type )

+        {

+

+            case PIO_PERIPH_A:

+                PIO_SetPeripheralA(list->pio,

+                                   list->mask,

+                                   (list->attribute & PIO_PULLUP) ? 1 : 0);

+            break;

+

+            case PIO_PERIPH_B:

+                PIO_SetPeripheralB(list->pio,

+                                   list->mask,

+                                   (list->attribute & PIO_PULLUP) ? 1 : 0);

+            break;

+

+            case PIO_PERIPH_C:

+                PIO_SetPeripheralC(list->pio,

+                                   list->mask,

+                                   (list->attribute & PIO_PULLUP) ? 1 : 0);

+            break;

+

+            case PIO_PERIPH_D:

+                PIO_SetPeripheralD(list->pio,

+                                   list->mask,

+                                   (list->attribute & PIO_PULLUP) ? 1 : 0);

+            break;

+            case PIO_INPUT:

+                PMC_EnablePeripheral(list->id);

+                PIO_SetInput(list->pio,

+                             list->mask,

+                             list->attribute);

+                break;

+

+            case PIO_OUTPUT_0:

+            case PIO_OUTPUT_1:

+                PIO_SetOutput(list->pio,

+                              list->mask,

+                              (list->type == PIO_OUTPUT_1),

+                              (list->attribute & PIO_OPENDRAIN) ? 1 : 0,

+                              (list->attribute & PIO_PULLUP) ? 1 : 0);

+                break;

+

+            default: return 0;

+        }

+

+        list++;

+        size--;

+    }

+

+    return 1;

+}

+

+/**

+ * \brief Sets a high output level on all the PIOs defined in the given Pin instance.

+ * This has no immediate effects on PIOs that are not output, but the PIO

+ * controller will memorize the value they are changed to outputs.

+ *

+ * \param pin  Pointer to a Pin instance describing one or more pins.

+ */

+void PIO_Set(const Pin *pin)

+{

+    pin->pio->PIO_SODR = pin->mask;

+}

+

+/**

+ * \brief Sets a low output level on all the PIOs defined in the given Pin instance.

+ * This has no immediate effects on PIOs that are not output, but the PIO

+ * controller will memorize the value they are changed to outputs.

+ *

+ * \param pin  Pointer to a Pin instance describing one or more pins.

+ */

+void PIO_Clear(const Pin *pin)

+{

+    pin->pio->PIO_CODR = pin->mask;

+}

+

+/**

+ * \brief Returns 1 if one or more PIO of the given Pin instance currently have

+ * a high level; otherwise returns 0. This method returns the actual value that

+ * is being read on the pin. To return the supposed output value of a pin, use

+ * PIO_GetOutputDataStatus() instead.

+ *

+ * \param pin  Pointer to a Pin instance describing one or more pins.

+ *

+ * \return 1 if the Pin instance contains at least one PIO that currently has

+ * a high level; otherwise 0.

+ */

+unsigned char PIO_Get( const Pin *pin )

+{

+    unsigned int reg ;

+

+    if ( (pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1) )

+    {

+        reg = pin->pio->PIO_ODSR ;

+    }

+    else

+    {

+        reg = pin->pio->PIO_PDSR ;

+    }

+

+    if ( (reg & pin->mask) == 0 )

+    {

+        return 0 ;

+    }

+    else

+    {

+        return 1 ;

+    }

+}

+

+/**

+ * \brief Returns 1 if one or more PIO of the given Pin are configured to output a

+ * high level (even if they are not output).

+ * To get the actual value of the pin, use PIO_Get() instead.

+ *

+ * \param pin  Pointer to a Pin instance describing one or more pins.

+ *

+ * \return 1 if the Pin instance contains at least one PIO that is configured

+ * to output a high level; otherwise 0.

+ */

+unsigned char PIO_GetOutputDataStatus(const Pin *pin)

+{

+    if ((pin->pio->PIO_ODSR & pin->mask) == 0) {

+

+        return 0;

+    }

+    else {

+

+        return 1;

+    }

+}

+

+/*

+ * \brief Configures Glitch or Debouncing filter for input.

+ *

+ * \param pin  Pointer to a Pin instance describing one or more pins.

+ * \param cuttoff  Cutt off frequency for debounce filter.

+ */

+void PIO_SetDebounceFilter( const Pin *pin, uint32_t cuttoff )

+{

+    Pio *pio = pin->pio;

+

+    pio->PIO_IFSCER = pin->mask; /* set Debouncing, 0 bit field no effect */

+    pio->PIO_SCDR = ((32678/(2*(cuttoff))) - 1) & 0x3FFF; /* the lowest 14 bits work */

+}

diff --git a/sam3s_example/src/pmc.c b/sam3s_example/src/pmc.c
new file mode 100644
index 0000000..4efc8ba
--- /dev/null
+++ b/sam3s_example/src/pmc.c
@@ -0,0 +1,161 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2009, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,

+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ----------------------------------------------------------------------------

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "chip.h"

+

+#include <assert.h>

+

+/*----------------------------------------------------------------------------

+ *        Local definitions

+ *----------------------------------------------------------------------------*/

+

+#define MASK_STATUS0 0xFFFFFFFC

+#define MASK_STATUS1 0xFFFFFFFF

+

+/*----------------------------------------------------------------------------

+ *        Exported functions

+ *----------------------------------------------------------------------------*/

+

+/**

+ * \brief Enables the clock of a peripheral. The peripheral ID is used

+ * to identify which peripheral is targetted.

+ *

+ * \note The ID must NOT be shifted (i.e. 1 << ID_xxx).

+ *

+ * \param id  Peripheral ID (ID_xxx).

+ */

+extern void PMC_EnablePeripheral( uint32_t dwId )

+{

+    assert( dwId < 35 ) ;

+

+    if ( dwId < 32 )

+    {

+        if ( (PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId) )

+        {

+        }

+        else

+        {

+            PMC->PMC_PCER0 = 1 << dwId ;

+        }

+    }

+    else

+    {

+        dwId -= 32;

+        if ((PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) == ((uint32_t)1 << dwId))

+        {

+        }

+        else

+        {

+            PMC->PMC_PCER1 = 1 << dwId ;

+        }

+    }

+}

+

+/**

+ * \brief Disables the clock of a peripheral. The peripheral ID is used

+ * to identify which peripheral is targetted.

+ *

+ * \note The ID must NOT be shifted (i.e. 1 << ID_xxx).

+ *

+ * \param id  Peripheral ID (ID_xxx).

+ */

+extern void PMC_DisablePeripheral( uint32_t dwId )

+{

+    assert( dwId < 35 ) ;

+

+    if ( dwId < 32 )

+    {

+        if ( (PMC->PMC_PCSR0 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId) )

+        {

+        }

+        else

+        {

+            PMC->PMC_PCDR0 = 1 << dwId ;

+        }

+    }

+    else

+    {

+        dwId -= 32 ;

+        if ( (PMC->PMC_PCSR1 & ((uint32_t)1 << dwId)) != ((uint32_t)1 << dwId) )

+        {

+        }

+        else

+        {

+            PMC->PMC_PCDR1 = 1 << dwId ;

+        }

+    }

+}

+

+/**

+ * \brief Enable all the periph clock via PMC.

+ */

+extern void PMC_EnableAllPeripherals( void )

+{

+    PMC->PMC_PCER0 = MASK_STATUS0 ;

+    while ( (PMC->PMC_PCSR0 & MASK_STATUS0) != MASK_STATUS0 ) ;

+

+    PMC->PMC_PCER1 = MASK_STATUS1 ;

+    while ( (PMC->PMC_PCSR1 & MASK_STATUS1) != MASK_STATUS1 ) ;

+

+}

+

+/**

+ * \brief Disable all the periph clock via PMC.

+ */

+extern void PMC_DisableAllPeripherals( void )

+{

+    PMC->PMC_PCDR0 = MASK_STATUS0 ;

+    while ( (PMC->PMC_PCSR0 & MASK_STATUS0) != 0 ) ;

+

+    PMC->PMC_PCDR1 = MASK_STATUS1 ;

+    while ( (PMC->PMC_PCSR1 & MASK_STATUS1) != 0 ) ;

+

+}

+

+/**

+ * \brief Get Periph Status for the given peripheral ID.

+ *

+ * \param id  Peripheral ID (ID_xxx).

+ */

+extern uint32_t PMC_IsPeriphEnabled( uint32_t dwId )

+{

+    assert( dwId < 35 ) ;

+

+    if ( dwId < 32 )

+    {

+        return ( PMC->PMC_PCSR0 & (1 << dwId) ) ;

+    }

+    else {

+        return ( PMC->PMC_PCSR1 & (1 << (dwId - 32)) ) ;

+    }

+}

diff --git a/sam3s_example/src/spi.c b/sam3s_example/src/spi.c
new file mode 100644
index 0000000..8e4b965
--- /dev/null
+++ b/sam3s_example/src/spi.c
@@ -0,0 +1,352 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2009, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,

+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ----------------------------------------------------------------------------

+ */

+

+/** \addtogroup spi_module Working with SPI

+ * The SPI driver provides the interface to configure and use the SPI

+ * peripheral.

+ *

+ * The Serial Peripheral Interface (SPI) circuit is a synchronous serial

+ * data link that provides communication with external devices in Master

+ * or Slave Mode.

+ *

+ * To use the SPI, the user has to follow these few steps:

+ * -# Enable the SPI pins required by the application (see pio.h).

+ * -# Configure the SPI using the \ref SPI_Configure(). This enables the

+ *    peripheral clock. The mode register is loaded with the given value.

+ * -# Configure all the necessary chip selects with \ref SPI_ConfigureNPCS().

+ * -# Enable the SPI by calling \ref SPI_Enable().

+ * -# Send/receive data using \ref SPI_Write() and \ref SPI_Read(). Note that \ref SPI_Read()

+ *    must be called after \ref SPI_Write() to retrieve the last value read.

+ * -# Send/receive data using the PDC with the \ref SPI_WriteBuffer() and

+ *    \ref SPI_ReadBuffer() functions.

+ * -# Disable the SPI by calling \ref SPI_Disable().

+ *

+ * For more accurate information, please look at the SPI section of the

+ * Datasheet.

+ *

+ * Related files :\n

+ * \ref spi.c\n

+ * \ref spi.h.\n

+*/

+/*@{*/

+/*@}*/

+

+/**

+ * \file

+ *

+ * Implementation of Serial Peripheral Interface (SPI) controller.

+ *

+ */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+#include "chip.h"

+#include "pmc.h"

+#include "spi.h"

+

+#include <stdint.h>

+

+/*----------------------------------------------------------------------------

+ *        Exported functions

+ *----------------------------------------------------------------------------*/

+

+/**

+ * \brief Enables a SPI peripheral.

+ *

+ * \param spi  Pointer to an Spi instance.

+ */

+extern void SPI_Enable( Spi* spi )

+{

+    spi->SPI_CR = SPI_CR_SPIEN ;

+}

+

+/**

+ * \brief Disables a SPI peripheral.

+ *

+ * \param spi  Pointer to an Spi instance.

+ */

+extern void SPI_Disable( Spi* spi )

+{

+    spi->SPI_CR = SPI_CR_SPIDIS ;

+}

+

+/**

+ * \brief Enables one or more interrupt sources of a SPI peripheral.

+ *

+ * \param spi  Pointer to an Spi instance.

+ * \param sources Bitwise OR of selected interrupt sources.

+ */

+extern void SPI_EnableIt( Spi* spi, uint32_t dwSources )

+{

+    spi->SPI_IER = dwSources ;

+}

+

+/**

+ * \brief Disables one or more interrupt sources of a SPI peripheral.

+ *

+ * \param spi  Pointer to an Spi instance.

+ * \param sources Bitwise OR of selected interrupt sources.

+ */

+extern void SPI_DisableIt( Spi* spi, uint32_t dwSources )

+{

+    spi->SPI_IDR = dwSources ;

+}

+

+/**

+ * \brief Configures a SPI peripheral as specified. The configuration can be computed

+ * using several macros (see \ref spi_configuration_macros).

+ *

+ * \param spi  Pointer to an Spi instance.

+ * \param id   Peripheral ID of the SPI.

+ * \param configuration  Value of the SPI configuration register.

+ */

+extern void SPI_Configure( Spi* spi, uint32_t dwId, uint32_t dwConfiguration )

+{

+    PMC_EnablePeripheral( dwId ) ;

+    spi->SPI_CR = SPI_CR_SPIDIS ;

+

+    /* Execute a software reset of the SPI twice */

+    spi->SPI_CR = SPI_CR_SWRST ;

+    spi->SPI_CR = SPI_CR_SWRST ;

+    spi->SPI_MR = dwConfiguration ;

+}

+

+

+/**

+ * \brief Configures a chip select of a SPI peripheral. The chip select configuration

+ * is computed using several macros (see \ref spi_configuration_macros).

+ *

+ * \param spi   Pointer to an Spi instance.

+ * \param npcs  Chip select to configure (0, 1, 2 or 3).

+ * \param configuration  Desired chip select configuration.

+ */

+void SPI_ConfigureNPCS( Spi* spi, uint32_t dwNpcs, uint32_t dwConfiguration )

+{

+    spi->SPI_CSR[dwNpcs] = dwConfiguration ;

+}

+

+/**

+ * \brief Get the current status register of the given SPI peripheral.

+ * \note This resets the internal value of the status register, so further

+ * read may yield different values.

+ * \param spi   Pointer to a Spi instance.

+ * \return  SPI status register.

+ */

+extern uint32_t SPI_GetStatus( Spi* spi )

+{

+    return spi->SPI_SR ;

+}

+

+/**

+ * \brief Reads and returns the last word of data received by a SPI peripheral. This

+ * method must be called after a successful SPI_Write call.

+ *

+ * \param spi  Pointer to an Spi instance.

+ *

+ * \return readed data.

+ */

+extern uint32_t SPI_Read( Spi* spi )

+{

+    while ( (spi->SPI_SR & SPI_SR_RDRF) == 0 ) ;

+

+    return spi->SPI_RDR & 0xFFFF ;

+}

+

+/**

+ * \brief Sends data through a SPI peripheral. If the SPI is configured to use a fixed

+ * peripheral select, the npcs value is meaningless. Otherwise, it identifies

+ * the component which shall be addressed.

+ *

+ * \param spi   Pointer to an Spi instance.

+ * \param npcs  Chip select of the component to address (0, 1, 2 or 3).

+ * \param data  Word of data to send.

+ */

+extern void SPI_Write( Spi* spi, uint32_t dwNpcs, uint16_t wData )

+{

+    /* Send data */

+    while ( (spi->SPI_SR & SPI_SR_TXEMPTY) == 0 ) ;

+    spi->SPI_TDR = wData | SPI_PCS( dwNpcs ) ;

+    while ( (spi->SPI_SR & SPI_SR_TDRE) == 0 ) ;

+}

+

+/**

+ * \brief Check if SPI transfer finish.

+ *

+ * \param spi  Pointer to an Spi instance.

+ *

+ * \return Returns 1 if there is no pending write operation on the SPI; otherwise

+ * returns 0.

+ */

+extern uint32_t SPI_IsFinished( Spi* spi )

+{

+    return ((spi->SPI_SR & SPI_SR_TXEMPTY) != 0) ;

+}

+

+/**

+ * \brief Enable Spi PDC transmit

+ * \param spi  Pointer to an Spi instance.

+*/

+extern void SPI_PdcEnableTx( Spi* spi )

+{

+    spi->SPI_PTCR = SPI_PTCR_TXTEN ;

+}

+

+/**

+ * \brief Disable Spi PDC transmit

+ * \param spi  Pointer to an Spi instance.

+*/

+extern void SPI_PdcDisableTx( Spi* spi )

+{

+    spi->SPI_PTCR = SPI_PTCR_TXTDIS ;

+}

+

+/**

+ * \brief Enable Spi PDC receive

+ * \param spi  Pointer to an Spi instance.

+*/

+extern void SPI_PdcEnableRx( Spi* spi )

+{

+    spi->SPI_PTCR = SPI_PTCR_RXTEN ;

+}

+

+/**

+ * \brief Disable Spi PDC receive

+ * \param spi  Pointer to an Spi instance.

+*/

+extern void SPI_PdcDisableRx( Spi* spi )

+{

+    spi->SPI_PTCR = SPI_PTCR_RXTDIS ;

+}

+

+/**

+ * \brief Set PDC transmit and next transmit buffer address and size.

+ *

+ * \param spi    Pointer to an Spi instance.

+ * \param txBuf  PDC transmit buffer address.

+ * \param txCount  Length in bytes of the transmit buffer.

+ * \param txNextBuf  PDC next transmit buffer address.

+ * \param txNextCount  Length in bytes of the next transmit buffer.

+ */

+extern void SPI_PdcSetTx( Spi* spi, void* pvTxBuf, uint32_t dwTxCount, void* pvTxNextBuf, uint32_t dwTxNextCount )

+{

+    spi->SPI_TPR = (uint32_t)pvTxBuf ;

+    spi->SPI_TCR = dwTxCount ;

+    spi->SPI_TNPR = (uint32_t)pvTxNextBuf ;

+    spi->SPI_TNCR = dwTxNextCount ;

+}

+

+/**

+ * \brief Set PDC receive and next receive buffer address and size.

+ *

+ * \param spi    Pointer to an Spi instance.

+ * \param rxBuf  PDC receive buffer address.

+ * \param rxCount  Length in bytes of the receive buffer.

+ * \param rxNextBuf  PDC next receive buffer address.

+ * \param rxNextCount  Length in bytes of the next receive buffer.

+ */

+extern void SPI_PdcSetRx( Spi* spi, void* pvRxBuf, uint32_t dwRxCount, void* pvRxNextBuf, uint32_t dwRxNextCount )

+{

+    spi->SPI_RPR = (uint32_t)pvRxBuf ;

+    spi->SPI_RCR = dwRxCount ;

+    spi->SPI_RNPR = (uint32_t)pvRxNextBuf ;

+    spi->SPI_RNCR = dwRxNextCount ;

+}

+

+/**

+ * \brief Sends the contents of buffer through a SPI peripheral, using the PDC to

+ * take care of the transfer.

+ *

+ * \param spi     Pointer to an Spi instance.

+ * \param buffer  Data buffer to send.

+ * \param length  Length of the data buffer.

+ */

+extern uint32_t SPI_WriteBuffer( Spi* spi, void* pvBuffer, uint32_t dwLength )

+{

+    /* Check if first bank is free */

+    if ( spi->SPI_TCR == 0 )

+    {

+        spi->SPI_TPR = (uint32_t)pvBuffer ;

+        spi->SPI_TCR = dwLength ;

+        spi->SPI_PTCR = PERIPH_PTCR_TXTEN ;

+

+        return 1 ;

+    }

+    /* Check if second bank is free */

+    else

+    {

+        if ( spi->SPI_TNCR == 0 )

+        {

+            spi->SPI_TNPR = (uint32_t)pvBuffer ;

+            spi->SPI_TNCR = dwLength ;

+

+            return 1 ;

+        }

+    }

+

+    /* No free banks */

+    return 0 ;

+}

+

+/**

+ * \brief Reads data from a SPI peripheral until the provided buffer is filled. This

+ * method does NOT need to be called after SPI_Write or SPI_WriteBuffer.

+ *

+ * \param spi     Pointer to an Spi instance.

+ * \param buffer  Data buffer to store incoming bytes.

+ * \param length  Length in bytes of the data buffer.

+ */

+extern uint32_t SPI_ReadBuffer( Spi* spi, void *pvBuffer, uint32_t dwLength )

+{

+    /* Check if the first bank is free */

+    if ( spi->SPI_RCR == 0 )

+    {

+        spi->SPI_RPR = (uint32_t)pvBuffer ;

+        spi->SPI_RCR = dwLength ;

+        spi->SPI_PTCR = PERIPH_PTCR_RXTEN ;

+

+        return 1 ;

+    }

+    /* Check if second bank is free */

+    else

+    {

+        if ( spi->SPI_RNCR == 0 )

+        {

+            spi->SPI_RNPR = (uint32_t)pvBuffer ;

+            spi->SPI_RNCR = dwLength ;

+            return 1 ;

+        }

+    }

+

+    /* No free bank */

+    return 0 ;

+}

+

+

diff --git a/sam3s_example/src/syscalls.c b/sam3s_example/src/syscalls.c
new file mode 100644
index 0000000..9b3bfec
--- /dev/null
+++ b/sam3s_example/src/syscalls.c
@@ -0,0 +1,143 @@
+/* ----------------------------------------------------------------------------

+ *         ATMEL Microcontroller Software Support

+ * ----------------------------------------------------------------------------

+ * Copyright (c) 2009, Atmel Corporation

+ *

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright notice,

+ * this list of conditions and the disclaimer below.

+ *

+ * Atmel's name may not be used to endorse or promote products derived from

+ * this software without specific prior written permission.

+ *

+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR

+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE

+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,

+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF

+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ * ----------------------------------------------------------------------------

+ */

+

+/**

+  * \file syscalls.c

+  *

+  * Implementation of newlib syscall.

+  *

+  */

+

+/*----------------------------------------------------------------------------

+ *        Headers

+ *----------------------------------------------------------------------------*/

+

+

+#include "board.h"

+

+#include <stdio.h>

+#include <stdarg.h>

+#include <sys/types.h>

+#include <sys/stat.h>

+

+/*----------------------------------------------------------------------------

+ *        Exported variables

+ *----------------------------------------------------------------------------*/

+

+#undef errno

+extern int errno ;

+extern int  _end ;

+

+/*----------------------------------------------------------------------------

+ *        Exported functions

+ *----------------------------------------------------------------------------*/

+extern void _exit( int status ) ;

+extern void _kill( int pid, int sig ) ;

+extern int _getpid ( void ) ;

+

+extern caddr_t _sbrk ( int incr )

+{

+    static unsigned char *heap = NULL ;

+    unsigned char *prev_heap ;

+

+    if ( heap == NULL )

+    {

+        heap = (unsigned char *)&_end ;

+    }

+    prev_heap = heap;

+

+    heap += incr ;

+

+    return (caddr_t) prev_heap ;

+}

+

+extern int link( char *old, char *new )

+{

+    return -1 ;

+}

+

+extern int _close( int file )

+{

+    return -1 ;

+}

+

+extern int _fstat( int file, struct stat *st )

+{

+    st->st_mode = S_IFCHR ;

+

+    return 0 ;

+}

+

+extern int _isatty( int file )

+{

+    return 1 ;

+}

+

+extern int _lseek( int file, int ptr, int dir )

+{

+    return 0 ;

+}

+

+extern int _read(int file, char *ptr, int len)

+{

+    return 0 ;

+}

+

+extern int _write( int file, char *ptr, int len )

+{

+    //int iIndex ;

+    

+    

+//    for ( ; *ptr != 0 ; ptr++ )

+/*    for ( iIndex=0 ; iIndex < len ; iIndex++, ptr++ )

+    {

+        UART_PutChar( *ptr ) ;

+    }

+

+    return iIndex ;

+    */

+    return 0;

+}

+

+extern void _exit( int status )

+{

+    printf( "Exiting with status %d.\n", status ) ;

+

+    for ( ; ; ) ;

+}

+

+extern void _kill( int pid, int sig )

+{

+    return ; 

+}

+

+extern int _getpid ( void )

+{

+    return -1 ;

+}