summaryrefslogtreecommitdiff
path: root/at91lib/peripherals
diff options
context:
space:
mode:
Diffstat (limited to 'at91lib/peripherals')
-rw-r--r--at91lib/peripherals/aic/aic.c87
-rw-r--r--at91lib/peripherals/aic/aic.h79
-rw-r--r--at91lib/peripherals/cp15/cp15.c268
-rw-r--r--at91lib/peripherals/cp15/cp15.h84
-rw-r--r--at91lib/peripherals/cp15/cp15_asm.S138
-rw-r--r--at91lib/peripherals/dbgu/dbgu.c174
-rw-r--r--at91lib/peripherals/dbgu/dbgu.h79
-rw-r--r--at91lib/peripherals/pio/pio.c346
-rw-r--r--at91lib/peripherals/pio/pio.h163
-rw-r--r--at91lib/peripherals/pio/pio_it.c395
-rw-r--r--at91lib/peripherals/pio/pio_it.h83
-rw-r--r--at91lib/peripherals/pit/pit.c122
-rw-r--r--at91lib/peripherals/pit/pit.h77
-rw-r--r--at91lib/peripherals/pmc/pmc.c186
-rw-r--r--at91lib/peripherals/pmc/pmc.h62
-rw-r--r--at91lib/peripherals/usart/usart.c272
-rw-r--r--at91lib/peripherals/usart/usart.h118
17 files changed, 2733 insertions, 0 deletions
diff --git a/at91lib/peripherals/aic/aic.c b/at91lib/peripherals/aic/aic.c
new file mode 100644
index 0000000..4ff52c2
--- /dev/null
+++ b/at91lib/peripherals/aic/aic.c
@@ -0,0 +1,87 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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 "aic.h"
+#include <board.h>
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Configures an interrupt in the AIC. The interrupt is identified by its
+/// source (AT91C_ID_xxx) and is configured to use the specified mode and
+/// interrupt handler function. Mode is the value that will be put in AIC_SMRx
+/// and the function address will be set in AIC_SVRx.
+/// The interrupt is disabled before configuration, so it is useless
+/// to do it before calling this function. When AIC_ConfigureIT returns, the
+/// interrupt will always be disabled and cleared; it must be enabled by a
+/// call to AIC_EnableIT().
+/// \param source Interrupt source to configure.
+/// \param mode Triggering mode and priority of the interrupt.
+/// \param handler Interrupt handler function.
+//------------------------------------------------------------------------------
+void AIC_ConfigureIT(
+ unsigned int source,
+ unsigned int mode,
+ void (*handler)(void))
+{
+ // Disable the interrupt first
+ AT91C_BASE_AIC->AIC_IDCR = 1 << source;
+
+ // Configure mode and handler
+ AT91C_BASE_AIC->AIC_SMR[source] = mode;
+ AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;
+
+ // Clear interrupt
+ AT91C_BASE_AIC->AIC_ICCR = 1 << source;
+}
+
+//------------------------------------------------------------------------------
+/// Enables interrupts coming from the given (unique) source (AT91C_ID_xxx).
+/// \param source Interrupt source to enable.
+//------------------------------------------------------------------------------
+void AIC_EnableIT(unsigned int source)
+{
+ AT91C_BASE_AIC->AIC_IECR = 1 << source;
+}
+
+//------------------------------------------------------------------------------
+/// Disables interrupts coming from the given (unique) source (AT91C_ID_xxx).
+/// \param source Interrupt source to enable.
+//------------------------------------------------------------------------------
+void AIC_DisableIT(unsigned int source)
+{
+ AT91C_BASE_AIC->AIC_IDCR = 1 << source;
+}
+
diff --git a/at91lib/peripherals/aic/aic.h b/at91lib/peripherals/aic/aic.h
new file mode 100644
index 0000000..bddf787
--- /dev/null
+++ b/at91lib/peripherals/aic/aic.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Methods and definitions for configuring interrupts using the Advanced
+/// Interrupt Controller (AIC).
+///
+/// !Usage
+///
+/// -# Configure an interrupt source using AIC_ConfigureIT
+/// -# Enable or disable interrupt generation of a particular source with
+/// AIC_EnableIT and AIC_DisableIT.
+///
+/// \note Most of the time, peripheral interrupts must be also configured
+/// inside the peripheral itself.
+//------------------------------------------------------------------------------
+
+#ifndef AIC_H
+#define AIC_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+#ifndef AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL
+ /// Interrupt is internal and uses a logical 1 level.
+ #define AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE
+#endif
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void AIC_ConfigureIT(unsigned int source,
+ unsigned int mode,
+ void (*handler)( void ));
+
+extern void AIC_EnableIT(unsigned int source);
+
+extern void AIC_DisableIT(unsigned int source);
+
+#endif //#ifndef AIC_H
+
diff --git a/at91lib/peripherals/cp15/cp15.c b/at91lib/peripherals/cp15/cp15.c
new file mode 100644
index 0000000..17a1f70
--- /dev/null
+++ b/at91lib/peripherals/cp15/cp15.c
@@ -0,0 +1,268 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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>
+
+#ifdef CP15_PRESENT
+
+#include <utility/trace.h>
+#include "cp15.h"
+
+#if defined(__ICCARM__)
+#include <intrinsics.h>
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Macros
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+/*
+#define CP15_RR_BIT 14 // RR bit Replacement strategy for ICache and DCache:
+ // 0 = Random replacement
+ // 1 = Round-robin replacement.
+
+#define CP15_V_BIT 13 // V bit Location of exception vectors:
+ // 0 = Normal exception vectors selected address range = 0x0000 0000 to 0x0000 001C
+ // 1 = High exception vect selected, address range = 0xFFFF 0000 to 0xFFFF 001C
+*/
+#define CP15_I_BIT 12 // I bit ICache enable/disable:
+ // 0 = ICache disabled
+ // 1 = ICache enabled
+/*
+#define CP15_R_BIT 9 // R bit ROM protection
+
+#define CP15_S_BIT 8 // S bit System protection
+
+#define CP15_B_BIT 7 // B bit Endianness:
+ // 0 = Little-endian operation
+ // 1 = Big-endian operation.
+*/
+#define CP15_C_BIT 2 // C bit DCache enable/disable:
+ // 0 = Cache disabled
+ // 1 = Cache enabled
+/*
+#define CP15_A_BIT 1 // A bit Alignment fault enable/disable:
+ // 0 = Data address alignment fault checking disabled
+ // 1 = Data address alignment fault checking enabled
+*/
+#define CP15_M_BIT 0 // M bit MMU enable/disable: 0 = disabled 1 = enabled.
+ // 0 = disabled
+ // 1 = enabled
+
+
+//-----------------------------------------------------------------------------
+// Global functions
+//-----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Check Instruction Cache
+/// \return 0 if I_Cache disable, 1 if I_Cache enable
+//------------------------------------------------------------------------------
+unsigned int CP15_Is_I_CacheEnabled(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+ return ((control & (1 << CP15_I_BIT)) != 0);
+}
+
+//------------------------------------------------------------------------------
+/// Enable Instruction Cache
+//------------------------------------------------------------------------------
+void CP15_Enable_I_Cache(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+
+ // Check if cache is disabled
+ if ((control & (1 << CP15_I_BIT)) == 0) {
+
+ control |= (1 << CP15_I_BIT);
+ _writeControlRegister(control);
+ TRACE_INFO("I cache enabled.\n\r");
+ }
+#if !defined(OP_BOOTSTRAP_on)
+ else {
+
+ TRACE_INFO("I cache is already enabled.\n\r");
+ }
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Disable Instruction Cache
+//------------------------------------------------------------------------------
+void CP15_Disable_I_Cache(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+
+ // Check if cache is enabled
+ if ((control & (1 << CP15_I_BIT)) != 0) {
+
+ control &= ~(1 << CP15_I_BIT);
+ _writeControlRegister(control);
+ TRACE_INFO("I cache disabled.\n\r");
+ }
+ else {
+
+ TRACE_INFO("I cache is already disabled.\n\r");
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Check MMU
+/// \return 0 if MMU disable, 1 if MMU enable
+//------------------------------------------------------------------------------
+unsigned int CP15_Is_MMUEnabled(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+ return ((control & (1 << CP15_M_BIT)) != 0);
+}
+
+//------------------------------------------------------------------------------
+/// Enable MMU
+//------------------------------------------------------------------------------
+void CP15_EnableMMU(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+
+ // Check if MMU is disabled
+ if ((control & (1 << CP15_M_BIT)) == 0) {
+
+ control |= (1 << CP15_M_BIT);
+ _writeControlRegister(control);
+ TRACE_INFO("MMU enabled.\n\r");
+ }
+ else {
+
+ TRACE_INFO("MMU is already enabled.\n\r");
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Disable MMU
+//------------------------------------------------------------------------------
+void CP15_DisableMMU(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+
+ // Check if MMU is enabled
+ if ((control & (1 << CP15_M_BIT)) != 0) {
+
+ control &= ~(1 << CP15_M_BIT);
+ control &= ~(1 << CP15_C_BIT);
+ _writeControlRegister(control);
+ TRACE_INFO("MMU disabled.\n\r");
+ }
+ else {
+
+ TRACE_INFO("MMU is already disabled.\n\r");
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Check D_Cache
+/// \return 0 if D_Cache disable, 1 if D_Cache enable (with MMU of course)
+//------------------------------------------------------------------------------
+unsigned int CP15_Is_DCacheEnabled(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+ return ((control & ((1 << CP15_C_BIT)||(1 << CP15_M_BIT))) != 0);
+}
+
+//------------------------------------------------------------------------------
+/// Enable Data Cache
+//------------------------------------------------------------------------------
+void CP15_Enable_D_Cache(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+
+ if( !CP15_Is_MMUEnabled() ) {
+ TRACE_ERROR("Do nothing: MMU not enabled\n\r");
+ }
+ else {
+ // Check if cache is disabled
+ if ((control & (1 << CP15_C_BIT)) == 0) {
+
+ control |= (1 << CP15_C_BIT);
+ _writeControlRegister(control);
+ TRACE_INFO("D cache enabled.\n\r");
+ }
+ else {
+
+ TRACE_INFO("D cache is already enabled.\n\r");
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Disable Data Cache
+//------------------------------------------------------------------------------
+void CP15_Disable_D_Cache(void)
+{
+ unsigned int control;
+
+ control = _readControlRegister();
+
+ // Check if cache is enabled
+ if ((control & (1 << CP15_C_BIT)) != 0) {
+
+ control &= ~(1 << CP15_C_BIT);
+ _writeControlRegister(control);
+ TRACE_INFO("D cache disabled.\n\r");
+ }
+ else {
+
+ TRACE_INFO("D cache is already disabled.\n\r");
+ }
+}
+
+#endif // CP15_PRESENT
+
diff --git a/at91lib/peripherals/cp15/cp15.h b/at91lib/peripherals/cp15/cp15.h
new file mode 100644
index 0000000..ddaaeb6
--- /dev/null
+++ b/at91lib/peripherals/cp15/cp15.h
@@ -0,0 +1,84 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Methods to manage the Coprocessor 15. Coprocessor 15, or System Control
+/// Coprocessor CP15, is used to configure and control all the items in the
+/// list below:
+/// • ARM core
+/// • Caches (ICache, DCache and write buffer)
+/// • TCM
+/// • MMU
+/// • Other system options
+///
+/// !Usage
+///
+/// -# Enable or disable D cache with Enable_D_Cache and Disable_D_Cache
+/// -# Enable or disable I cache with Enable_I_Cache and Disable_I_Cache
+///
+//------------------------------------------------------------------------------
+
+#ifndef _CP15_H
+#define _CP15_H
+
+#ifdef CP15_PRESENT
+
+//-----------------------------------------------------------------------------
+// Exported functions
+//-----------------------------------------------------------------------------
+extern void CP15_Enable_I_Cache(void);
+extern unsigned int CP15_Is_I_CacheEnabled(void);
+extern void CP15_Enable_I_Cache(void);
+extern void CP15_Disable_I_Cache(void);
+extern unsigned int CP15_Is_MMUEnabled(void);
+extern void CP15_EnableMMU(void);
+extern void CP15_DisableMMU(void);
+extern unsigned int CP15_Is_DCacheEnabled(void);
+extern void CP15_Enable_D_Cache(void);
+extern void CP15_Disable_D_Cache(void);
+
+//-----------------------------------------------------------------------------
+// External functions defined in cp15.S
+//-----------------------------------------------------------------------------
+extern unsigned int _readControlRegister(void);
+extern void _writeControlRegister(unsigned int value);
+extern void _waitForInterrupt(void);
+extern void _writeTTB(unsigned int value);
+extern void _writeDomain(unsigned int value);
+extern void _writeITLBLockdown(unsigned int value);
+extern void _prefetchICacheLine(unsigned int value);
+
+#endif // CP15_PRESENT
+
+#endif // #ifndef _CP15_H
+
diff --git a/at91lib/peripherals/cp15/cp15_asm.S b/at91lib/peripherals/cp15/cp15_asm.S
new file mode 100644
index 0000000..00ef47d
--- /dev/null
+++ b/at91lib/peripherals/cp15/cp15_asm.S
@@ -0,0 +1,138 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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
+//------------------------------------------------------------------------------
+
+#define __ASSEMBLY__
+#include "board.h"
+
+#ifdef CP15_PRESENT
+
+//------------------------------------------------------------------------------
+/// Functions to access CP15 coprocessor register
+//------------------------------------------------------------------------------
+
+ .global _readControlRegister
+ .global _writeControlRegister
+ .global _waitForInterrupt
+ .global _writeTTB
+ .global _writeDomain
+ .global _writeITLBLockdown
+ .global _prefetchICacheLine
+
+//------------------------------------------------------------------------------
+/// Control Register c1
+/// Register c1 is the Control Register for the ARM926EJ-S processor.
+/// This register specifies the configuration used to enable and disable the
+/// caches and MMU. It is recommended that you access this register using a
+/// read-modify-write sequence.
+//------------------------------------------------------------------------------
+// CP15 Read Control Register
+_readControlRegister:
+ mov r0, #0
+ mrc p15, 0, r0, c1, c0, 0
+ bx lr
+
+// CP15 Write Control Register
+_writeControlRegister:
+ mcr p15, 0, r0, c1, c0, 0
+ bx lr
+
+//------------------------------------------------------------------------------
+/// CP15 Wait For Interrupt operation
+/// The purpose of the Wait For Interrupt operation is to put the processor in
+/// to a low power state.
+/// This puts the processor into a low-power state and stops it executing more
+/// instructions until an interrupt, or debug request occurs, regardless of
+/// whether the interrupts are disabled by the masks in the CPSR.
+/// When an interrupt does occur, the MCR instruction completes and the IRQ or
+/// FIQ handler is entered as normal. The return link in r14_irq or r14_fiq
+/// contains the address of the MCR instruction plus 8, so that the normal
+/// instruction used for interrupt return (SUBS PC,R14,#4) returns to the
+/// instruction following the MCR.
+/// Wait For Interrupt : MCR p15, 0, <Rd>, c7, c0, 4
+//------------------------------------------------------------------------------
+_waitForInterrupt:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 4
+ bx lr
+
+//------------------------------------------------------------------------------
+/// CP15 Translation Table Base Register c2
+/// Register c2 is the Translation Table Base Register (TTBR), for the base
+/// address of the first-level translation table.
+/// Reading from c2 returns the pointer to the currently active first-level
+/// translation table in bits [31:14] and an Unpredictable value in bits [13:0].
+/// Writing to register c2 updates the pointer to the first-level translation
+/// table from the value in bits [31:14] of the written value. Bits [13:0]
+/// Should Be Zero.
+/// You can use the following instructions to access the TTBR:
+/// Read TTBR : MRC p15, 0, <Rd>, c2, c0, 0
+/// Write TTBR : MCR p15, 0, <Rd>, c2, c0, 0
+//------------------------------------------------------------------------------
+_writeTTB:
+ MCR p15, 0, r0, c2, c0, 0
+ bx lr
+
+//------------------------------------------------------------------------------
+/// Domain Access Control Register c3
+/// Read domain access permissions : MRC p15, 0, <Rd>, c3, c0, 0
+/// Write domain access permissions : MCR p15, 0, <Rd>, c3, c0, 0
+//------------------------------------------------------------------------------
+_writeDomain:
+ MCR p15, 0, r0, c3, c0, 0
+ bx lr
+
+//------------------------------------------------------------------------------
+/// TLB Lockdown Register c10
+/// The TLB Lockdown Register controls where hardware page table walks place the
+/// TLB entry, in the set associative region or the lockdown region of the TLB,
+/// and if in the lockdown region, which entry is written. The lockdown region
+/// of the TLB contains eight entries. See TLB structure for a description of
+/// the structure of the TLB.
+/// Read data TLB lockdown victim : MRC p15,0,<Rd>,c10,c0,0
+/// Write data TLB lockdown victim : MCR p15,0,<Rd>,c10,c0,0
+//------------------------------------------------------------------------------
+_writeITLBLockdown:
+ MCR p15, 0, r0, c10, c0, 0
+ bx lr
+
+//------------------------------------------------------------------------------
+/// Prefetch ICache line
+/// Performs an ICache lookup of the specified modified virtual address.
+/// If the cache misses, and the region is cacheable, a linefill is performed.
+/// Prefetch ICache line (MVA): MCR p15, 0, <Rd>, c7, c13, 1
+//------------------------------------------------------------------------------
+_prefetchICacheLine:
+ MCR p15, 0, r0, c7, c13, 1
+ bx lr
+#endif
+
diff --git a/at91lib/peripherals/dbgu/dbgu.c b/at91lib/peripherals/dbgu/dbgu.c
new file mode 100644
index 0000000..2034730
--- /dev/null
+++ b/at91lib/peripherals/dbgu/dbgu.c
@@ -0,0 +1,174 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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 "dbgu.h"
+#include <stdarg.h>
+#include <board.h>
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+/// Initializes the DBGU with the given parameters, and enables both the
+/// transmitter and the receiver. The mode parameter contains the value of the
+/// DBGU_MR register.
+/// Value DBGU_STANDARD can be used for mode to get the most common configuration
+/// (i.e. aysnchronous, 8bits, no parity, 1 stop bit, no flow control).
+/// \param mode Operating mode to configure.
+/// \param baudrate Desired baudrate (e.g. 115200).
+/// \param mck Frequency of the system master clock in Hz.
+//------------------------------------------------------------------------------
+void DBGU_Configure(
+ unsigned int mode,
+ unsigned int baudrate,
+ unsigned int mck)
+{
+ // Reset & disable receiver and transmitter, disable interrupts
+ AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX;
+ AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF;
+
+ // Configure baud rate
+ AT91C_BASE_DBGU->DBGU_BRGR = mck / (baudrate * 16);
+
+ // Configure mode register
+ AT91C_BASE_DBGU->DBGU_MR = mode;
+
+ // Disable DMA channel
+ AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
+
+ // Enable receiver and transmitter
+ AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a character on the DBGU line.
+/// \note This function is synchronous (i.e. uses polling).
+/// \param c Character to send.
+//------------------------------------------------------------------------------
+void DBGU_PutChar(unsigned char c)
+{
+ // Wait for the transmitter to be ready
+ while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0);
+
+ // Send character
+ AT91C_BASE_DBGU->DBGU_THR = c;
+
+ // Wait for the transfer to complete
+ while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY) == 0);
+}
+
+//------------------------------------------------------------------------------
+/// Return 1 if a character can be read in DBGU
+//------------------------------------------------------------------------------
+unsigned int DBGU_IsRxReady()
+{
+ return (AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY);
+}
+
+//------------------------------------------------------------------------------
+/// Reads and returns a character from the DBGU.
+/// \note This function is synchronous (i.e. uses polling).
+/// \return Character received.
+//------------------------------------------------------------------------------
+unsigned char DBGU_GetChar(void)
+{
+ while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY) == 0);
+ return AT91C_BASE_DBGU->DBGU_RHR;
+}
+
+#ifndef NOFPUT
+#include <stdio.h>
+
+//------------------------------------------------------------------------------
+/// \exclude
+/// Implementation of fputc using the DBGU as the standard output. Required
+/// for printf().
+/// \param c Character to write.
+/// \param pStream Output stream.
+/// \param The character written if successful, or -1 if the output stream is
+/// not stdout or stderr.
+//------------------------------------------------------------------------------
+signed int fputc(signed int c, FILE *pStream)
+{
+ if ((pStream == stdout) || (pStream == stderr)) {
+
+ DBGU_PutChar(c);
+ return c;
+ }
+ else {
+
+ return EOF;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// \exclude
+/// Implementation of fputs using the DBGU as the standard output. Required
+/// for printf(). Does NOT currently use the PDC.
+/// \param pStr String to write.
+/// \param pStream Output stream.
+/// \return Number of characters written if successful, or -1 if the output
+/// stream is not stdout or stderr.
+//------------------------------------------------------------------------------
+signed int fputs(const char *pStr, FILE *pStream)
+{
+ signed int num = 0;
+
+ while (*pStr != 0) {
+
+ if (fputc(*pStr, pStream) == -1) {
+
+ return -1;
+ }
+ num++;
+ pStr++;
+ }
+
+ return num;
+}
+
+#undef putchar
+
+//------------------------------------------------------------------------------
+/// \exclude
+/// Outputs a character on the DBGU.
+/// \param c Character to output.
+/// \return The character that was output.
+//------------------------------------------------------------------------------
+signed int putchar(signed int c)
+{
+ return fputc(c, stdout);
+}
+
+#endif //#ifndef NOFPUT
+
diff --git a/at91lib/peripherals/dbgu/dbgu.h b/at91lib/peripherals/dbgu/dbgu.h
new file mode 100644
index 0000000..816f11d
--- /dev/null
+++ b/at91lib/peripherals/dbgu/dbgu.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// This module provides definitions and functions for using the Debug Unit
+/// (DBGU).
+///
+/// It also overloads the fputc(), fputs() & putchar() functions so the printf()
+/// method outputs its data on the DBGU. This behavior can be suppressed by
+/// defining NOFPUT during compilation.
+///
+/// !Usage
+///
+/// -# Enable the DBGU pins (see pio & board.h).
+/// -# Configure the DBGU using DBGU_Configure with the desired operating mode.
+/// -# Send characters using DBGU_PutChar() or the printf() method.
+/// -# Receive characters using DBGU_GetChar().
+///
+/// \note Unless specified, all the functions defined here operate synchronously;
+/// i.e. they all wait the data is sent/received before returning.
+//------------------------------------------------------------------------------
+
+#ifndef DBGU_H
+#define DBGU_H
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+/// Standard operating mode (asynchronous, 8bit, no parity, 1 stop bit)
+#define DBGU_STANDARD AT91C_US_PAR_NONE
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void DBGU_Configure(
+ unsigned int mode,
+ unsigned int baudrate,
+ unsigned int mck);
+
+extern unsigned char DBGU_GetChar(void);
+
+extern void DBGU_PutChar(unsigned char c);
+
+extern unsigned int DBGU_IsRxReady(void);
+
+#endif //#ifndef DBGU_H
+
diff --git a/at91lib/peripherals/pio/pio.c b/at91lib/peripherals/pio/pio.c
new file mode 100644
index 0000000..5b21751
--- /dev/null
+++ b/at91lib/peripherals/pio/pio.c
@@ -0,0 +1,346 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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 "pio.h"
+#include <board.h>
+
+//------------------------------------------------------------------------------
+// Local Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// 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(
+ AT91S_PIO *pio,
+ unsigned int mask,
+ unsigned char enablePullUp)
+{
+ // Disable interrupts on the pin(s)
+ pio->PIO_IDR = mask;
+
+ // Enable the pull-up(s) if necessary
+ if (enablePullUp) {
+
+ pio->PIO_PPUER = mask;
+ }
+ else {
+
+ pio->PIO_PPUDR = mask;
+ }
+
+ // Configure pin
+ pio->PIO_ASR = mask;
+ pio->PIO_PDR = mask;
+}
+
+//------------------------------------------------------------------------------
+/// 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(
+ AT91S_PIO *pio,
+ unsigned int mask,
+ unsigned char enablePullUp)
+{
+ // Disable interrupts on the pin(s)
+ pio->PIO_IDR = mask;
+
+ // Enable the pull-up(s) if necessary
+ if (enablePullUp) {
+
+ pio->PIO_PPUER = mask;
+ }
+ else {
+
+ pio->PIO_PPUDR = mask;
+ }
+
+ // Configure pin
+ pio->PIO_BSR = mask;
+ pio->PIO_PDR = mask;
+}
+
+//------------------------------------------------------------------------------
+/// 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(
+ AT91S_PIO *pio,
+ unsigned int mask,
+ unsigned char enablePullUp,
+ unsigned char enableFilter)
+{
+ // Disable interrupts
+ pio->PIO_IDR = mask;
+
+ // Enable pull-up(s) if necessary
+ if (enablePullUp) {
+
+ pio->PIO_PPUER = mask;
+ }
+ else {
+
+ pio->PIO_PPUDR = mask;
+ }
+
+ // Enable filter(s) if necessary
+ if (enableFilter) {
+
+ pio->PIO_IFER = mask;
+ }
+ else {
+
+ pio->PIO_IFDR = mask;
+ }
+
+ // Configure pin as input
+ pio->PIO_ODR = mask;
+ pio->PIO_PER = mask;
+}
+
+//------------------------------------------------------------------------------
+/// 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(
+ AT91S_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_PPUER = mask;
+ }
+ else {
+
+ pio->PIO_PPUDR = 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
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// 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.
+//------------------------------------------------------------------------------
+unsigned char PIO_Configure(const Pin *list, unsigned int 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_INPUT:
+ AT91C_BASE_PMC->PMC_PCER = 1 << list->id;
+ PIO_SetInput(list->pio,
+ list->mask,
+ (list->attribute & PIO_PULLUP) ? 1 : 0,
+ (list->attribute & PIO_DEGLITCH)? 1 : 0);
+ 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;
+}
+
+//------------------------------------------------------------------------------
+/// 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;
+}
+
+//------------------------------------------------------------------------------
+/// 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;
+}
+
+//------------------------------------------------------------------------------
+/// 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;
+ }
+}
+
+
+//------------------------------------------------------------------------------
+/// 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;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Returns the value of ISR for the PIO controller of the pin.
+/// Reading this register acknoledges all the ITs.
+/// \param pin Pointer to a Pin instance describing one or more pins.
+//------------------------------------------------------------------------------
+unsigned int PIO_GetISR(const Pin *pin)
+{
+ return (pin->pio->PIO_ISR);
+}
+
diff --git a/at91lib/peripherals/pio/pio.h b/at91lib/peripherals/pio/pio.h
new file mode 100644
index 0000000..69fe29d
--- /dev/null
+++ b/at91lib/peripherals/pio/pio.h
@@ -0,0 +1,163 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !!!Purpose
+///
+/// This file provides a basic API for PIO configuration and usage of
+/// user-controlled pins. Please refer to the board.h file for a list of
+/// available pin definitions.
+///
+/// !!!Usage
+///
+/// -# Define a constant pin description array such as the following one, using
+/// the existing definitions provided by the board.h file if possible:
+/// \code
+/// const Pin pPins[] = {PIN_USART0_TXD, PIN_USART0_RXD};
+/// \endcode
+/// Alternatively, it is possible to add new pins by provided the full Pin
+/// structure:
+/// \code
+/// // Pin instance to configure PA10 & PA11 as inputs with the internal
+/// // pull-up enabled.
+/// const Pin pPins = {
+/// (1 << 10) | (1 << 11),
+/// AT91C_BASE_PIOA,
+/// AT91C_ID_PIOA,
+/// PIO_INPUT,
+/// PIO_PULLUP
+/// };
+/// \endcode
+/// -# Configure a pin array by calling PIO_Configure() with a pointer to the
+/// array and its size (which is computed using the PIO_LISTSIZE macro).
+/// -# Change and get the value of a user-controlled pin using the PIO_Set,
+/// PIO_Clear and PIO_Get methods.
+/// -# Get the level being currently output by a user-controlled pin configured
+/// as an output using PIO_GetOutputDataStatus().
+//------------------------------------------------------------------------------
+
+#ifndef PIO_H
+#define PIO_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+
+//------------------------------------------------------------------------------
+// Global Definitions
+//------------------------------------------------------------------------------
+
+/// The pin is controlled by the associated signal of peripheral A.
+#define PIO_PERIPH_A 0
+/// The pin is controlled by the associated signal of peripheral B.
+#define PIO_PERIPH_B 1
+/// The pin is an input.
+#define PIO_INPUT 2
+/// The pin is an output and has a default level of 0.
+#define PIO_OUTPUT_0 3
+/// The pin is an output and has a default level of 1.
+#define PIO_OUTPUT_1 4
+
+/// Default pin configuration (no attribute).
+#define PIO_DEFAULT (0 << 0)
+/// The internal pin pull-up is active.
+#define PIO_PULLUP (1 << 0)
+/// The internal glitch filter is active.
+#define PIO_DEGLITCH (1 << 1)
+/// The pin is open-drain.
+#define PIO_OPENDRAIN (1 << 2)
+
+//------------------------------------------------------------------------------
+// Global Macros
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Calculates the size of an array of Pin instances. The array must be defined
+/// locally (i.e. not a pointer), otherwise the computation will not be correct.
+/// \param pPins Local array of Pin instances.
+/// \return Number of elements in array.
+//------------------------------------------------------------------------------
+#define PIO_LISTSIZE(pPins) (sizeof(pPins) / sizeof(Pin))
+
+//------------------------------------------------------------------------------
+// Global Types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Describes the type and attribute of one PIO pin or a group of similar pins.
+/// The #type# field can have the following values:
+/// - PIO_PERIPH_A
+/// - PIO_PERIPH_B
+/// - PIO_OUTPUT_0
+/// - PIO_OUTPUT_1
+/// - PIO_INPUT
+///
+/// The #attribute# field is a bitmask that can either be set to PIO_DEFAULt,
+/// or combine (using bitwise OR '|') any number of the following constants:
+/// - PIO_PULLUP
+/// - PIO_DEGLITCH
+/// - PIO_OPENDRAIN
+//------------------------------------------------------------------------------
+typedef struct {
+
+ /// Bitmask indicating which pin(s) to configure.
+ unsigned int mask;
+ /// Pointer to the PIO controller which has the pin(s).
+ AT91S_PIO *pio;
+ /// Peripheral ID of the PIO controller which has the pin(s).
+ unsigned char id;
+ /// Pin type.
+ unsigned char type;
+ /// Pin attribute.
+ unsigned char attribute;
+
+} Pin;
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+extern unsigned char PIO_Configure(const Pin *list, unsigned int size);
+
+extern void PIO_Set(const Pin *pin);
+
+extern void PIO_Clear(const Pin *pin);
+
+extern unsigned char PIO_Get(const Pin *pin);
+
+extern unsigned int PIO_GetISR(const Pin *pin);
+
+extern unsigned char PIO_GetOutputDataStatus(const Pin *pin);
+
+#endif //#ifndef PIO_H
+
diff --git a/at91lib/peripherals/pio/pio_it.c b/at91lib/peripherals/pio/pio_it.c
new file mode 100644
index 0000000..266feb0
--- /dev/null
+++ b/at91lib/peripherals/pio/pio_it.c
@@ -0,0 +1,395 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+/// Disable traces for this file
+#undef TRACE_LEVEL
+#define TRACE_LEVEL 0
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "pio_it.h"
+#include "pio.h"
+#include <board.h>
+#include <aic/aic.h>
+#include <utility/assert.h>
+#include <utility/trace.h>
+
+//------------------------------------------------------------------------------
+// Local definitions
+//------------------------------------------------------------------------------
+
+/// \exclude
+/// Maximum number of interrupt sources that can be defined. This
+/// constant can be increased, but the current value is the smallest possible
+/// that will be compatible with all existing projects.
+#define MAX_INTERRUPT_SOURCES 7
+
+//------------------------------------------------------------------------------
+// Local types
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// \exclude
+/// Describes a PIO interrupt source, including the PIO instance triggering the
+/// interrupt and the associated interrupt handler.
+//------------------------------------------------------------------------------
+typedef struct {
+
+ /// Pointer to the source pin instance.
+ const Pin *pPin;
+
+ /// Interrupt handler.
+ void (*handler)(const Pin *);
+
+} InterruptSource;
+
+//------------------------------------------------------------------------------
+// Local variables
+//------------------------------------------------------------------------------
+
+/// List of interrupt sources.
+static InterruptSource pSources[MAX_INTERRUPT_SOURCES];
+
+/// Number of currently defined interrupt sources.
+static unsigned int numSources;
+
+//------------------------------------------------------------------------------
+// Local functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Handles all interrupts on the given PIO controller.
+/// \param id PIO controller ID.
+/// \param pPio PIO controller base address.
+//------------------------------------------------------------------------------
+static void PioInterruptHandler(unsigned int id, AT91S_PIO *pPio)
+{
+ unsigned int status;
+ unsigned int i;
+
+ // Read PIO controller status
+ status = pPio->PIO_ISR;
+ status &= pPio->PIO_IMR;
+
+ // Check pending events
+ if (status != 0) {
+
+ TRACE_DEBUG("PIO interrupt on PIO controller #%d\n\r", id);
+
+ // Find triggering source
+ i = 0;
+ while (status != 0) {
+
+ // There cannot be an unconfigured source enabled.
+ SANITY_CHECK(i < numSources);
+
+ // Source is configured on the same controller
+ if (pSources[i].pPin->id == id) {
+
+ // Source has PIOs whose statuses have changed
+ if ((status & pSources[i].pPin->mask) != 0) {
+
+ TRACE_DEBUG("Interrupt source #%d triggered\n\r", i);
+
+ pSources[i].handler(pSources[i].pPin);
+ status &= ~(pSources[i].pPin->mask);
+ }
+ }
+ i++;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Generic PIO interrupt handler. Single entry point for interrupts coming
+/// from any PIO controller (PIO A, B, C ...). Dispatches the interrupt to
+/// the user-configured handlers.
+//------------------------------------------------------------------------------
+static void InterruptHandler(void)
+{
+#if defined(AT91C_ID_PIOA)
+ // Treat PIOA interrupts
+ PioInterruptHandler(AT91C_ID_PIOA, AT91C_BASE_PIOA);
+#endif
+
+#if defined(AT91C_ID_PIOB)
+ // Treat PIOB interrupts
+ PioInterruptHandler(AT91C_ID_PIOB, AT91C_BASE_PIOB);
+#endif
+
+#if defined(AT91C_ID_PIOC)
+ // Treat PIOC interrupts
+ PioInterruptHandler(AT91C_ID_PIOC, AT91C_BASE_PIOC);
+#endif
+
+#if defined(AT91C_ID_PIOD)
+ // Treat PIOD interrupts
+ PioInterruptHandler(AT91C_ID_PIOD, AT91C_BASE_PIOD);
+#endif
+
+#if defined(AT91C_ID_PIOE)
+ // Treat PIOE interrupts
+ PioInterruptHandler(AT91C_ID_PIOE, AT91C_BASE_PIOE);
+#endif
+
+#if defined(AT91C_ID_PIOABCD)
+ // Treat PIOABCD interrupts
+ #if !defined(AT91C_ID_PIOA)
+ PioInterruptHandler(AT91C_ID_PIOABCD, AT91C_BASE_PIOA);
+ #endif
+ #if !defined(AT91C_ID_PIOB)
+ PioInterruptHandler(AT91C_ID_PIOABCD, AT91C_BASE_PIOB);
+ #endif
+ #if !defined(AT91C_ID_PIOC)
+ PioInterruptHandler(AT91C_ID_PIOABCD, AT91C_BASE_PIOC);
+ #endif
+ #if !defined(AT91C_ID_PIOD)
+ PioInterruptHandler(AT91C_ID_PIOABCD, AT91C_BASE_PIOD);
+ #endif
+#endif
+
+#if defined(AT91C_ID_PIOABCDE)
+ // Treat PIOABCDE interrupts
+ #if !defined(AT91C_ID_PIOA)
+ PioInterruptHandler(AT91C_ID_PIOABCDE, AT91C_BASE_PIOA);
+ #endif
+ #if !defined(AT91C_ID_PIOB)
+ PioInterruptHandler(AT91C_ID_PIOABCDE, AT91C_BASE_PIOB);
+ #endif
+ #if !defined(AT91C_ID_PIOC)
+ PioInterruptHandler(AT91C_ID_PIOABCDE, AT91C_BASE_PIOC);
+ #endif
+ #if !defined(AT91C_ID_PIOD)
+ PioInterruptHandler(AT91C_ID_PIOABCDE, AT91C_BASE_PIOD);
+ #endif
+ #if !defined(AT91C_ID_PIOE)
+ PioInterruptHandler(AT91C_ID_PIOABCDE, AT91C_BASE_PIOE);
+ #endif
+#endif
+
+#if defined(AT91C_ID_PIOCDE)
+ // Treat PIOCDE interrupts
+ #if !defined(AT91C_ID_PIOC)
+ PioInterruptHandler(AT91C_ID_PIOCDE, AT91C_BASE_PIOC);
+ #endif
+ #if !defined(AT91C_ID_PIOD)
+ PioInterruptHandler(AT91C_ID_PIOCDE, AT91C_BASE_PIOD);
+ #endif
+ #if !defined(AT91C_ID_PIOE)
+ PioInterruptHandler(AT91C_ID_PIOCDE, AT91C_BASE_PIOE);
+ #endif
+#endif
+}
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the PIO interrupt management logic. The desired priority of PIO
+/// interrupts must be provided. Calling this function multiple times result in
+/// the reset of currently configured interrupts.
+/// \param priority PIO controller interrupts priority.
+//------------------------------------------------------------------------------
+void PIO_InitializeInterrupts(unsigned int priority)
+{
+ TRACE_DEBUG("PIO_Initialize()\n\r");
+
+ SANITY_CHECK((priority & ~AT91C_AIC_PRIOR) == 0);
+
+ // Reset sources
+ numSources = 0;
+
+#ifdef AT91C_ID_PIOA
+ // Configure PIO interrupt sources
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOA\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA;
+ AT91C_BASE_PIOA->PIO_ISR;
+ AT91C_BASE_PIOA->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOA, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOA);
+#endif
+
+#ifdef AT91C_ID_PIOB
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOB\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB;
+ AT91C_BASE_PIOB->PIO_ISR;
+ AT91C_BASE_PIOB->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOB, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOB);
+#endif
+
+#ifdef AT91C_ID_PIOC
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOC\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOC;
+ AT91C_BASE_PIOC->PIO_ISR;
+ AT91C_BASE_PIOC->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOC, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOC);
+#endif
+
+#ifdef AT91C_ID_PIOD
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOD\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOD;
+ AT91C_BASE_PIOC->PIO_ISR;
+ AT91C_BASE_PIOC->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOD, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOD);
+#endif
+
+#ifdef AT91C_ID_PIOE
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOE\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOE;
+ AT91C_BASE_PIOC->PIO_ISR;
+ AT91C_BASE_PIOC->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOE, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOE);
+#endif
+
+#if defined(AT91C_ID_PIOABCD)
+ // Treat PIOABCD interrupts
+ #if !defined(AT91C_ID_PIOA) \
+ && !defined(AT91C_ID_PIOB) \
+ && !defined(AT91C_ID_PIOC) \
+ && !defined(AT91C_ID_PIOD)
+
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOABCD\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOABCD;
+ AT91C_BASE_PIOA->PIO_ISR;
+ AT91C_BASE_PIOA->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOABCD, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOABCD);
+ #endif
+#endif
+
+#if defined(AT91C_ID_PIOABCDE)
+ // Treat PIOABCDE interrupts
+ #if !defined(AT91C_ID_PIOA) \
+ && !defined(AT91C_ID_PIOB) \
+ && !defined(AT91C_ID_PIOC) \
+ && !defined(AT91C_ID_PIOD) \
+ && !defined(AT91C_ID_PIOE)
+
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOABCDE\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOABCDE;
+ AT91C_BASE_PIOA->PIO_ISR;
+ AT91C_BASE_PIOA->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOABCDE, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOABCDE);
+ #endif
+#endif
+
+#if defined(AT91C_ID_PIOCDE)
+ // Treat PIOCDE interrupts
+ #if !defined(AT91C_ID_PIOC) \
+ && !defined(AT91C_ID_PIOD) \
+ && !defined(AT91C_ID_PIOE)
+
+ TRACE_DEBUG("PIO_Initialize: Configuring PIOC\n\r");
+ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOCDE;
+ AT91C_BASE_PIOC->PIO_ISR;
+ AT91C_BASE_PIOC->PIO_IDR = 0xFFFFFFFF;
+ AIC_ConfigureIT(AT91C_ID_PIOCDE, priority, InterruptHandler);
+ AIC_EnableIT(AT91C_ID_PIOCDE);
+ #endif
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Configures a PIO or a group of PIO to generate an interrupt on status
+/// change. The provided interrupt handler will be called with the triggering
+/// pin as its parameter (enabling different pin instances to share the same
+/// handler).
+/// \param pPin Pointer to a Pin instance.
+/// \param handler Interrupt handler function pointer.
+//------------------------------------------------------------------------------
+void PIO_ConfigureIt(const Pin *pPin, void (*handler)(const Pin *))
+{
+ InterruptSource *pSource;
+
+ TRACE_DEBUG("PIO_ConfigureIt()\n\r");
+
+ SANITY_CHECK(pPin);
+ ASSERT(numSources < MAX_INTERRUPT_SOURCES,
+ "-F- PIO_ConfigureIt: Increase MAX_INTERRUPT_SOURCES\n\r");
+
+ // Define new source
+ TRACE_DEBUG("PIO_ConfigureIt: Defining new source #%d.\n\r", numSources);
+
+ pSource = &(pSources[numSources]);
+ pSource->pPin = pPin;
+ pSource->handler = handler;
+ numSources++;
+}
+
+//------------------------------------------------------------------------------
+/// Enables the given interrupt source if it has been configured. The status
+/// register of the corresponding PIO controller is cleared prior to enabling
+/// the interrupt.
+/// \param pPin Interrupt source to enable.
+//------------------------------------------------------------------------------
+void PIO_EnableIt(const Pin *pPin)
+{
+ TRACE_DEBUG("PIO_EnableIt()\n\r");
+
+ SANITY_CHECK(pPin);
+
+#ifndef NOASSERT
+ unsigned int i = 0;
+ unsigned char found = 0;
+ while ((i < numSources) && !found) {
+
+ if (pSources[i].pPin == pPin) {
+
+ found = 1;
+ }
+ i++;
+ }
+ ASSERT(found, "-F- PIO_EnableIt: Interrupt source has not been configured\n\r");
+#endif
+
+ pPin->pio->PIO_ISR;
+ pPin->pio->PIO_IER = pPin->mask;
+}
+
+//------------------------------------------------------------------------------
+/// Disables a given interrupt source, with no added side effects.
+/// \param pPin Interrupt source to disable.
+//------------------------------------------------------------------------------
+void PIO_DisableIt(const Pin *pPin)
+{
+ SANITY_CHECK(pPin);
+
+ TRACE_DEBUG("PIO_DisableIt()\n\r");
+
+ pPin->pio->PIO_IDR = pPin->mask;
+}
+
diff --git a/at91lib/peripherals/pio/pio_it.h b/at91lib/peripherals/pio/pio_it.h
new file mode 100644
index 0000000..0fcf7be
--- /dev/null
+++ b/at91lib/peripherals/pio/pio_it.h
@@ -0,0 +1,83 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !!!Purpose
+///
+/// Configuration and handling of interrupts on PIO status changes. The API
+/// provided here have several advantages over the traditional PIO interrupt
+/// configuration approach:
+/// - It is highly portable
+/// - It automatically demultiplexes interrupts when multiples pins have been
+/// configured on a single PIO controller
+/// - It allows a group of pins to share the same interrupt
+///
+/// However, it also has several minor drawbacks that may prevent from using it
+/// in particular applications:
+/// - It enables the clocks of all PIO controllers
+/// - PIO controllers all share the same interrupt handler, which does the
+/// demultiplexing and can be slower than direct configuration
+/// - It reserves space for a fixed number of interrupts, which can be
+/// increased by modifying the appropriate constant in pio_it.c.
+///
+/// !!!Usage
+///
+/// -# Initialize the PIO interrupt mechanism using PIO_InitializeInterrupts()
+/// with the desired priority (0 ... 7).
+/// -# Configure a status change interrupt on one or more pin(s) with
+/// PIO_ConfigureIt().
+/// -# Enable & disable interrupts on pins using PIO_EnableIt() and
+/// PIO_DisableIt().
+//------------------------------------------------------------------------------
+
+#ifndef PIO_IT_H
+#define PIO_IT_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "pio.h"
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+extern void PIO_InitializeInterrupts(unsigned int priority);
+
+extern void PIO_ConfigureIt(const Pin *pPin, void (*handler)(const Pin *));
+
+extern void PIO_EnableIt(const Pin *pPin);
+
+extern void PIO_DisableIt(const Pin *pPin);
+
+#endif //#ifndef PIO_IT_H
+
diff --git a/at91lib/peripherals/pit/pit.c b/at91lib/peripherals/pit/pit.c
new file mode 100644
index 0000000..f15610c
--- /dev/null
+++ b/at91lib/peripherals/pit/pit.c
@@ -0,0 +1,122 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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 "pit.h"
+#include <board.h>
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initialize the Periodic Interval Timer to generate a tick at the specified
+/// period, given the current master clock frequency.
+/// \param period Period in µsecond.
+/// \param pit_frequency Master clock frequency in MHz.
+//------------------------------------------------------------------------------
+void PIT_Init(unsigned int period, unsigned int pit_frequency)
+{
+ AT91C_BASE_PITC->PITC_PIMR = period? (period * pit_frequency + 8) >> 4 : 0;
+ AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;
+}
+
+//------------------------------------------------------------------------------
+/// Set the Periodic Interval Value of the PIT.
+/// \param piv PIV value to set.
+//------------------------------------------------------------------------------
+void PIT_SetPIV(unsigned int piv)
+{
+ AT91C_BASE_PITC->PITC_PIMR = (AT91C_BASE_PITC->PITC_PIMR & AT91C_PITC_PIV)
+ | piv;
+}
+
+//------------------------------------------------------------------------------
+/// Enables the PIT if this is not already the case.
+//------------------------------------------------------------------------------
+void PIT_Enable(void)
+{
+ AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;
+}
+
+//----------------------------------------------------------------------------
+/// Enable the PIT periodic interrupt.
+//----------------------------------------------------------------------------
+void PIT_EnableIT(void)
+{
+ AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITIEN;
+}
+
+//------------------------------------------------------------------------------
+/// Disables the PIT periodic interrupt.
+//------------------------------------------------------------------------------
+void PIT_DisableIT(void)
+{
+ AT91C_BASE_PITC->PITC_PIMR &= ~AT91C_PITC_PITIEN;
+}
+
+//------------------------------------------------------------------------------
+/// Returns the value of the PIT mode register.
+/// \return PIT_MR value.
+//------------------------------------------------------------------------------
+unsigned int PIT_GetMode(void)
+{
+ return AT91C_BASE_PITC->PITC_PIMR;
+}
+
+//------------------------------------------------------------------------------
+/// Returns the value of the PIT status register, clearing it as a side effect.
+/// \return PIT_SR value.
+//------------------------------------------------------------------------------
+unsigned int PIT_GetStatus(void)
+{
+ return AT91C_BASE_PITC->PITC_PISR;
+}
+
+//------------------------------------------------------------------------------
+/// Returns the value of the PIT Image Register, to read PICNT and CPIV without
+/// clearing the current values.
+/// \return PIT_PIIR value.
+//------------------------------------------------------------------------------
+unsigned int PIT_GetPIIR(void)
+{
+ return AT91C_BASE_PITC->PITC_PIIR;
+}
+
+//------------------------------------------------------------------------------
+/// Returns the value of the PIT Value Register, clearing it as a side effect.
+/// \return PIT_PIVR value.
+//------------------------------------------------------------------------------
+unsigned int PIT_GetPIVR(void)
+{
+ return AT91C_BASE_PITC->PITC_PIVR;
+}
diff --git a/at91lib/peripherals/pit/pit.h b/at91lib/peripherals/pit/pit.h
new file mode 100644
index 0000000..12aad31
--- /dev/null
+++ b/at91lib/peripherals/pit/pit.h
@@ -0,0 +1,77 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Interface for configuration the Periodic Interval Timer (PIT) peripheral.
+///
+/// !Usage
+///
+/// -# Initialize the PIT with the desired period using PIT_Init().
+/// Alternatively, the Periodic Interval Value (PIV) can be configured
+/// manually using PIT_SetPIV().
+/// -# Start the PIT counting using PIT_Enable().
+/// -# Enable & disable the PIT interrupt using PIT_EnableIT() and
+/// PIT_DisableIT().
+/// -# Retrieve the current status of the PIT using PIT_GetStatus().
+/// -# To get the current value of the internal counter and the number of ticks
+/// that have occurred, use either PIT_GetPIVR() or PIT_GetPIIR() depending
+/// on whether you want the values to be cleared or not.
+//------------------------------------------------------------------------------
+
+#ifndef PIT_H
+#define PIT_H
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+extern void PIT_Init(unsigned int period, unsigned int pit_frequency);
+
+extern void PIT_SetPIV(unsigned int piv);
+
+extern void PIT_Enable(void);
+
+extern void PIT_EnableIT(void);
+
+extern void PIT_DisableIT(void);
+
+extern unsigned int PIT_GetMode(void);
+
+extern unsigned int PIT_GetStatus(void);
+
+extern unsigned int PIT_GetPIIR(void);
+
+extern unsigned int PIT_GetPIVR(void);
+
+#endif //#ifndef PIT_H
+
diff --git a/at91lib/peripherals/pmc/pmc.c b/at91lib/peripherals/pmc/pmc.c
new file mode 100644
index 0000000..136e401
--- /dev/null
+++ b/at91lib/peripherals/pmc/pmc.c
@@ -0,0 +1,186 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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 "pmc.h"
+#include <board.h>
+#include <utility/assert.h>
+#include <utility/trace.h>
+
+#ifdef CP15_PRESENT
+#include <cp15/cp15.h>
+#endif
+
+#define MASK_STATUS 0x3FFFFFFC
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+#if defined(at91sam7l64) || defined(at91sam7l128)
+//------------------------------------------------------------------------------
+/// Sets the fast wake-up inputs that can get the device out of Wait mode.
+/// \param inputs Fast wake-up inputs to enable.
+//------------------------------------------------------------------------------
+void PMC_SetFastWakeUpInputs(unsigned int inputs)
+{
+ SANITY_CHECK((inputs & ~0xFF) == 0);
+ AT91C_BASE_PMC->PMC_FSMR = inputs;
+}
+
+#if !defined(__ICCARM__)
+__attribute__ ((section (".ramfunc"))) // GCC
+#endif
+//------------------------------------------------------------------------------
+/// Disables the main oscillator, making the device enter Wait mode.
+//------------------------------------------------------------------------------
+void PMC_DisableMainOscillatorForWaitMode(void)
+{
+ AT91C_BASE_PMC->PMC_MOR = 0x37 << 16;
+ while ((AT91C_BASE_PMC->PMC_MOR & AT91C_PMC_MAINSELS) != AT91C_PMC_MAINSELS);
+}
+
+#endif
+
+#if defined(at91sam7l)
+//------------------------------------------------------------------------------
+/// Disables the main oscillator when NOT running on it.
+//------------------------------------------------------------------------------
+void PMC_DisableMainOscillator(void)
+{
+ AT91C_BASE_PMC->PMC_MOR = 0x37 << 16;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MAINSELS) == AT91C_PMC_MAINSELS);
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Disables the processor clock
+//------------------------------------------------------------------------------
+void PMC_DisableProcessorClock(void)
+{
+ AT91C_BASE_PMC->PMC_SCDR = AT91C_PMC_PCK;
+ while ((AT91C_BASE_PMC->PMC_SCSR & AT91C_PMC_PCK) != AT91C_PMC_PCK);
+}
+
+//------------------------------------------------------------------------------
+/// Enables the clock of a peripheral. The peripheral ID (AT91C_ID_xxx) is used
+/// to identify which peripheral is targetted.
+/// Note that the ID must NOT be shifted (i.e. 1 << AT91C_ID_xxx).
+/// \param id Peripheral ID (AT91C_ID_xxx).
+//------------------------------------------------------------------------------
+void PMC_EnablePeripheral(unsigned int id)
+{
+ SANITY_CHECK(id < 32);
+
+ if ((AT91C_BASE_PMC->PMC_PCSR & (1 << id)) == (1 << id)) {
+
+ TRACE_INFO("PMC_EnablePeripheral: clock of peripheral"
+ " %u is already enabled\n\r",
+ id);
+ }
+ else {
+
+ AT91C_BASE_PMC->PMC_PCER = 1 << id;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Disables the clock of a peripheral. The peripheral ID (AT91C_ID_xxx) is used
+/// to identify which peripheral is targetted.
+/// Note that the ID must NOT be shifted (i.e. 1 << AT91C_ID_xxx).
+/// \param id Peripheral ID (AT91C_ID_xxx).
+//------------------------------------------------------------------------------
+void PMC_DisablePeripheral(unsigned int id)
+{
+ SANITY_CHECK(id < 32);
+
+ if ((AT91C_BASE_PMC->PMC_PCSR & (1 << id)) != (1 << id)) {
+
+ TRACE_INFO("PMC_DisablePeripheral: clock of peripheral"
+ " %u is not enabled\n\r",
+ id);
+ }
+ else {
+
+ AT91C_BASE_PMC->PMC_PCDR = 1 << id;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Enable all the periph clock via PMC
+/// (Becareful of the last 2 bits, it is not periph clock)
+//------------------------------------------------------------------------------
+void PMC_EnableAllPeripherals(void)
+{
+ AT91C_BASE_PMC->PMC_PCER = MASK_STATUS;
+ while( (AT91C_BASE_PMC->PMC_PCSR & MASK_STATUS) != MASK_STATUS);
+ TRACE_INFO("Enable all periph clocks\n\r");
+}
+
+//------------------------------------------------------------------------------
+/// Disable all the periph clock via PMC
+/// (Becareful of the last 2 bits, it is not periph clock)
+//------------------------------------------------------------------------------
+void PMC_DisableAllPeripherals(void)
+{
+ AT91C_BASE_PMC->PMC_PCDR = MASK_STATUS;
+ while((AT91C_BASE_PMC->PMC_PCSR & MASK_STATUS) != 0);
+ TRACE_INFO("Disable all periph clocks\n\r");
+}
+
+//-----------------------------------------------------------------------------
+/// Get Periph Status
+//-----------------------------------------------------------------------------
+unsigned int PMC_IsAllPeriphEnabled(void)
+{
+ return (AT91C_BASE_PMC->PMC_PCSR == MASK_STATUS);
+}
+
+//-----------------------------------------------------------------------------
+/// Get Periph Status
+//-----------------------------------------------------------------------------
+unsigned int PMC_IsPeriphEnabled(unsigned int id)
+{
+ return (AT91C_BASE_PMC->PMC_PCSR & (1 << id));
+}
+//------------------------------------------------------------------------------
+/// Put the CPU in Idle Mode for lower consumption
+//------------------------------------------------------------------------------
+void PMC_CPUInIdleMode(void)
+{
+ PMC_DisableProcessorClock();
+#ifdef CP15_PRESENT
+ _waitForInterrupt();
+#endif
+}
+
+
diff --git a/at91lib/peripherals/pmc/pmc.h b/at91lib/peripherals/pmc/pmc.h
new file mode 100644
index 0000000..a53b365
--- /dev/null
+++ b/at91lib/peripherals/pmc/pmc.h
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef PMC_H
+#define PMC_H
+
+//------------------------------------------------------------------------------
+// Global functions
+//------------------------------------------------------------------------------
+
+#if defined(at91sam7l64) || defined(at91sam7l128)
+extern void PMC_SetFastWakeUpInputs(unsigned int inputs);
+extern void PMC_DisableMainOscillator(void);
+extern
+#ifdef __ICCARM__
+__ramfunc
+#endif //__ICCARM__
+void PMC_DisableMainOscillatorForWaitMode(void);
+#endif // at91sam7l64 at91sam7l128
+
+extern void PMC_DisableProcessorClock(void);
+extern void PMC_EnablePeripheral(unsigned int id);
+extern void PMC_DisablePeripheral(unsigned int id);
+extern void PMC_CPUInIdleMode(void);
+
+
+extern void PMC_EnableAllPeripherals(void);
+
+extern void PMC_DisableAllPeripherals(void);
+
+extern unsigned int PMC_IsAllPeriphEnabled(void);
+
+extern unsigned int PMC_IsPeriphEnabled(unsigned int id);
+
+#endif //#ifndef PMC_H
+
diff --git a/at91lib/peripherals/usart/usart.c b/at91lib/peripherals/usart/usart.c
new file mode 100644
index 0000000..3f6d0e3
--- /dev/null
+++ b/at91lib/peripherals/usart/usart.c
@@ -0,0 +1,272 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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 "usart.h"
+#include <utility/trace.h>
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+/// Configures an USART peripheral with the specified parameters.
+/// \param usart Pointer to the USART peripheral to configure.
+/// \param mode Desired value for the USART mode register (see the datasheet).
+/// \param baudrate Baudrate at which the USART should operate (in Hz).
+/// \param masterClock Frequency of the system master clock (in Hz).
+//------------------------------------------------------------------------------
+void USART_Configure(AT91S_USART *usart,
+ unsigned int mode,
+ unsigned int baudrate,
+ unsigned int masterClock)
+{
+ // Reset and disable receiver & transmitter
+ usart->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX
+ | AT91C_US_RXDIS | AT91C_US_TXDIS;
+
+ // Configure mode
+ usart->US_MR = mode;
+
+ // Configure baudrate
+ // Asynchronous, no oversampling
+ if (((mode & AT91C_US_SYNC) == 0)
+ && ((mode & AT91C_US_OVER) == 0)) {
+
+ usart->US_BRGR = (masterClock / baudrate) / 16;
+ }
+ // TODO other modes
+}
+
+//------------------------------------------------------------------------------
+/// Enables or disables the transmitter of an USART peripheral.
+/// \param usart Pointer to an USART peripheral
+/// \param enabled If true, the transmitter is enabled; otherwise it is
+/// disabled.
+//------------------------------------------------------------------------------
+void USART_SetTransmitterEnabled(AT91S_USART *usart,
+ unsigned char enabled)
+{
+ if (enabled) {
+
+ usart->US_CR = AT91C_US_TXEN;
+ }
+ else {
+
+ usart->US_CR = AT91C_US_TXDIS;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Enables or disables the receiver of an USART peripheral
+/// \param usart Pointer to an USART peripheral
+/// \param enabled If true, the receiver is enabled; otherwise it is disabled.
+//------------------------------------------------------------------------------
+void USART_SetReceiverEnabled(AT91S_USART *usart,
+ unsigned char enabled)
+{
+ if (enabled) {
+
+ usart->US_CR = AT91C_US_RXEN;
+ }
+ else {
+
+ usart->US_CR = AT91C_US_RXDIS;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Sends one packet of data through the specified USART peripheral. This
+/// function operates synchronously, so it only returns when the data has been
+/// actually sent.
+/// \param usart Pointer to an USART peripheral.
+/// \param data Data to send including 9nth bit and sync field if necessary (in
+/// the same format as the US_THR register in the datasheet).
+/// \param timeOut Time out value (0 = no timeout).
+//------------------------------------------------------------------------------
+void USART_Write(
+ AT91S_USART *usart,
+ unsigned short data,
+ volatile unsigned int timeOut)
+{
+ if (timeOut == 0) {
+
+ while ((usart->US_CSR & AT91C_US_TXEMPTY) == 0);
+ }
+ else {
+
+ while ((usart->US_CSR & AT91C_US_TXEMPTY) == 0) {
+
+ if (timeOut == 0) {
+
+ TRACE_ERROR("USART_Write: Timed out.\n\r");
+ return;
+ }
+ timeOut--;
+ }
+ }
+
+ usart->US_THR = data;
+}
+
+//------------------------------------------------------------------------------
+/// Sends the contents of a data buffer through the specified USART peripheral.
+/// This function returns immediately (1 if the buffer has been queued, 0
+/// otherwise); poll the ENDTX and TXBUFE bits of the USART status register
+/// to check for the transfer completion.
+/// \param usart Pointer to an USART peripheral.
+/// \param buffer Pointer to the data buffer to send.
+/// \param size Size of the data buffer (in bytes).
+//------------------------------------------------------------------------------
+unsigned char USART_WriteBuffer(
+ AT91S_USART *usart,
+ void *buffer,
+ unsigned int size)
+{
+ // Check if the first PDC bank is free
+ if ((usart->US_TCR == 0) && (usart->US_TNCR == 0)) {
+
+ usart->US_TPR = (unsigned int) buffer;
+ usart->US_TCR = size;
+ usart->US_PTCR = AT91C_PDC_TXTEN;
+
+ return 1;
+ }
+ // Check if the second PDC bank is free
+ else if (usart->US_TNCR == 0) {
+
+ usart->US_TNPR = (unsigned int) buffer;
+ usart->US_TNCR = size;
+
+ return 1;
+ }
+ else {
+
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Reads and return a packet of data on the specified USART peripheral. This
+/// function operates asynchronously, so it waits until some data has been
+/// received.
+/// \param usart Pointer to an USART peripheral.
+/// \param timeOut Time out value (0 -> no timeout).
+//------------------------------------------------------------------------------
+unsigned short USART_Read(
+ AT91S_USART *usart,
+ volatile unsigned int timeOut)
+{
+ if (timeOut == 0) {
+
+ while ((usart->US_CSR & AT91C_US_RXRDY) == 0);
+ }
+ else {
+
+ while ((usart->US_CSR & AT91C_US_RXRDY) == 0) {
+
+ if (timeOut == 0) {
+
+ TRACE_ERROR("USART_Read: Timed out.\n\r");
+ return 0;
+ }
+ timeOut--;
+ }
+ }
+
+ return usart->US_RHR;
+}
+
+//------------------------------------------------------------------------------
+/// Reads data from an USART peripheral, filling the provided buffer until it
+/// becomes full. This function returns immediately with 1 if the buffer has
+/// been queued for transmission; otherwise 0.
+/// \param usart Pointer to an USART peripheral.
+/// \param buffer Pointer to the buffer where the received data will be stored.
+/// \param size Size of the data buffer (in bytes).
+//------------------------------------------------------------------------------
+unsigned char USART_ReadBuffer(AT91S_USART *usart,
+ void *buffer,
+ unsigned int size)
+{
+ // Check if the first PDC bank is free
+ if ((usart->US_RCR == 0) && (usart->US_RNCR == 0)) {
+
+ usart->US_RPR = (unsigned int) buffer;
+ usart->US_RCR = size;
+ usart->US_PTCR = AT91C_PDC_RXTEN;
+
+ return 1;
+ }
+ // Check if the second PDC bank is free
+ else if (usart->US_RNCR == 0) {
+
+ usart->US_RNPR = (unsigned int) buffer;
+ usart->US_RNCR = size;
+
+ return 1;
+ }
+ else {
+
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Returns 1 if some data has been received and can be read from an USART;
+/// otherwise returns 0.
+/// \param usart Pointer to an AT91S_USART instance.
+//------------------------------------------------------------------------------
+unsigned char USART_IsDataAvailable(AT91S_USART *usart)
+{
+ if ((usart->US_CSR & AT91C_US_RXRDY) != 0) {
+
+ return 1;
+ }
+ else {
+
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Sets the filter value for the IRDA demodulator.
+/// \param pUsart Pointer to an AT91S_USART instance.
+/// \param filter Filter value.
+//------------------------------------------------------------------------------
+void USART_SetIrdaFilter(AT91S_USART *pUsart, unsigned char filter)
+{
+ SANITY_CHECK(pUsart);
+
+ pUsart->US_IF = filter;
+}
+
diff --git a/at91lib/peripherals/usart/usart.h b/at91lib/peripherals/usart/usart.h
new file mode 100644
index 0000000..84a633c
--- /dev/null
+++ b/at91lib/peripherals/usart/usart.h
@@ -0,0 +1,118 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+/// !Purpose
+///
+/// This module provides several definitions and methods for using an USART
+/// peripheral.
+///
+/// !Usage
+/// -# Enable the USART peripheral clock in the PMC.
+/// -# Enable the required USART PIOs (see pio.h).
+/// -# Configure the UART by calling USART_Configure.
+/// -# Enable the transmitter and/or the receiver of the USART using
+/// USART_SetTransmitterEnabled and USART_SetReceiverEnabled.
+/// -# Send data through the USART using the USART_Write and
+/// USART_WriteBuffer methods.
+/// -# Receive data from the USART using the USART_Read and
+/// USART_ReadBuffer functions; the availability of data can be polled
+/// with USART_IsDataAvailable.
+/// -# Disable the transmitter and/or the receiver of the USART with
+/// USART_SetTransmitterEnabled and USART_SetReceiverEnabled.
+//------------------------------------------------------------------------------
+
+#ifndef USART_H
+#define USART_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// \page "USART modes"
+/// This page lists several common operating modes for an USART peripheral.
+///
+/// !Modes
+/// - USART_MODE_ASYNCHRONOUS
+/// - USART_MODE_IRDA
+
+/// Basic asynchronous mode, i.e. 8 bits no parity.
+#define USART_MODE_ASYNCHRONOUS (AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE)
+
+/// IRDA mode
+#define USART_MODE_IRDA (AT91C_US_USMODE_IRDA | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_FILTER)
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern void USART_Configure(
+ AT91S_USART *usart,
+ unsigned int mode,
+ unsigned int baudrate,
+ unsigned int masterClock);
+
+extern void USART_SetTransmitterEnabled(AT91S_USART *usart, unsigned char enabled);
+
+extern void USART_SetReceiverEnabled(AT91S_USART *usart, unsigned char enabled);
+
+extern void USART_Write(
+ AT91S_USART *usart,
+ unsigned short data,
+ volatile unsigned int timeOut);
+
+extern unsigned char USART_WriteBuffer(
+ AT91S_USART *usart,
+ void *buffer,
+ unsigned int size);
+
+extern unsigned short USART_Read(
+ AT91S_USART *usart,
+ volatile unsigned int timeOut);
+
+extern unsigned char USART_ReadBuffer(
+ AT91S_USART *usart,
+ void *buffer,
+ unsigned int size);
+
+extern unsigned char USART_IsDataAvailable(AT91S_USART *usart);
+
+extern void USART_SetIrdaFilter(AT91S_USART *pUsart, unsigned char filter);
+
+#endif //#ifndef USART_H
+
personal git repositories of Harald Welte. Your mileage may vary