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 ;
+}