summaryrefslogtreecommitdiff
path: root/openpicc/os
diff options
context:
space:
mode:
authorhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-11-06 20:26:48 +0000
committerhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2007-11-06 20:26:48 +0000
commit633c646ab36368caf6eaeedd326d9f1835196afd (patch)
treefdd0f60747745d3e528c0f5d8f8895b26fb79633 /openpicc/os
parent3b41196cb6b64cf6ba8ba41d6995428f73d4764a (diff)
Initial import of FreeRTOS code for OpenPICC
git-svn-id: https://svn.openpcd.org:2342/trunk@311 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpicc/os')
-rw-r--r--openpicc/os/boot/Cstartup_SAM7.c67
-rw-r--r--openpicc/os/boot/boot.s161
-rw-r--r--openpicc/os/core/ARM7_AT91SAM7S/AT91SAM7.h1969
-rw-r--r--openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.c424
-rw-r--r--openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.h3417
-rw-r--r--openpicc/os/core/ARM7_AT91SAM7S/port.c237
-rw-r--r--openpicc/os/core/ARM7_AT91SAM7S/portISR.c239
-rw-r--r--openpicc/os/core/ARM7_AT91SAM7S/portmacro.h266
-rw-r--r--openpicc/os/core/MemMang/heap_1.c143
-rw-r--r--openpicc/os/core/MemMang/heap_2.c255
-rw-r--r--openpicc/os/core/MemMang/heap_3.c82
-rw-r--r--openpicc/os/core/include/FreeRTOS.h114
-rw-r--r--openpicc/os/core/include/blocktim.h42
-rw-r--r--openpicc/os/core/include/comtest.h46
-rw-r--r--openpicc/os/core/include/comtest2.h44
-rw-r--r--openpicc/os/core/include/crhook.h50
-rw-r--r--openpicc/os/core/include/croutine.h720
-rw-r--r--openpicc/os/core/include/death.h42
-rw-r--r--openpicc/os/core/include/dynamic.h42
-rw-r--r--openpicc/os/core/include/fileIO.h44
-rw-r--r--openpicc/os/core/include/list.h272
-rw-r--r--openpicc/os/core/include/mevents.h42
-rw-r--r--openpicc/os/core/include/portable.h233
-rw-r--r--openpicc/os/core/include/print.h43
-rw-r--r--openpicc/os/core/include/projdefs.h56
-rw-r--r--openpicc/os/core/include/queue.h492
-rw-r--r--openpicc/os/core/include/semphr.h291
-rw-r--r--openpicc/os/core/include/serial.h116
-rw-r--r--openpicc/os/core/include/task.h960
-rw-r--r--openpicc/os/core/list.c215
-rw-r--r--openpicc/os/core/queue.c1002
-rw-r--r--openpicc/os/core/tasks.c1988
-rw-r--r--openpicc/os/license.txt399
-rw-r--r--openpicc/os/usb/USB-CDC.c953
-rw-r--r--openpicc/os/usb/USB-CDC.h87
-rw-r--r--openpicc/os/usb/USBIsr.c169
-rw-r--r--openpicc/os/usb/descriptors.h190
-rw-r--r--openpicc/os/usb/usb.h146
38 files changed, 16058 insertions, 0 deletions
diff --git a/openpicc/os/boot/Cstartup_SAM7.c b/openpicc/os/boot/Cstartup_SAM7.c
new file mode 100644
index 0000000..450a95e
--- /dev/null
+++ b/openpicc/os/boot/Cstartup_SAM7.c
@@ -0,0 +1,67 @@
+//*----------------------------------------------------------------------------
+//* ATMEL Microcontroller Software Support - ROUSSET -
+//*----------------------------------------------------------------------------
+//* The software is delivered "AS IS" without warranty or condition of any
+//* kind, either express, implied or statutory. This includes without
+//* limitation any warranty or condition with respect to merchantability or
+//* fitness for any particular purpose, or against the infringements of
+//* intellectual property rights of others.
+//*----------------------------------------------------------------------------
+//* File Name : Cstartup_SAM7.c
+//* Object : Low level initializations written in C for IAR
+//* tools
+//* 1.0 08/Sep/04 JPP : Creation
+//* 1.10 10/Sep/04 JPP : Update AT91C_CKGR_PLLCOUNT filed
+//*----------------------------------------------------------------------------
+
+
+// Include the board file description
+#include <board.h>
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_LowLevelInit
+//* \brief This function performs very low level HW initialization
+//* this function can be use a Stack, depending the compilation
+//* optimization mode
+//*----------------------------------------------------------------------------
+void AT91F_LowLevelInit (void)
+{
+ AT91PS_PMC pPMC = AT91C_BASE_PMC;
+
+ //* Set flash wait state
+ // Single Cycle Access at Up to 30 MHz, or 40
+ // if MCK = 47923200 I have 50 Cycle for 1 useconde ( flied MC_FMR->FMCN
+ AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN) & (75 << 16)) | AT91C_MC_FWS_1FWS;
+
+ //* Watchdog Enable
+ AT91C_BASE_WDTC->WDTC_WDMR = (0x80 << 16) | AT91C_WDTC_WDRSTEN | 0x80;
+
+ //* Set MCK at 47 923 200
+ // 1 Enabling the Main Oscillator:
+ // SCK = 1/32768 = 30.51 uSeconde
+ // Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms
+ pPMC->PMC_MOR = (((AT91C_CKGR_OSCOUNT & (0x06 << 8)) | AT91C_CKGR_MOSCEN));
+ // Wait the startup time
+
+ while (!(pPMC->PMC_SR & AT91C_PMC_MOSCS));
+ // 2 Checking the Main Oscillator Frequency (Optional)
+ // 3 Setting PLL and divider:
+ // - div by 5 Fin = 3,6864 =(18,432 / 5)
+ // - Mul 25+1: Fout = 95,8464 =(3,6864 *26)
+ // for 96 MHz the erroe is 0.16%
+ //eld out NOT USED = 0 Fi
+ pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 5) |
+ (AT91C_CKGR_PLLCOUNT & (28 << 8)) |
+ (AT91C_CKGR_MUL & (25 << 16)));
+
+ // Wait the startup time
+ while (!(pPMC->PMC_SR & AT91C_PMC_LOCK));
+
+ // 4. Selection of Master Clock and Processor Clock
+ // select the PLL clock divided by 2
+ pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
+ while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
+
+ pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
+ while (!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
+}
diff --git a/openpicc/os/boot/boot.s b/openpicc/os/boot/boot.s
new file mode 100644
index 0000000..6bd5db2
--- /dev/null
+++ b/openpicc/os/boot/boot.s
@@ -0,0 +1,161 @@
+ /* Sample initialization file */
+
+ .extern main
+ .extern exit
+ .extern AT91F_LowLevelInit
+
+ .text
+ .code 32
+
+
+ .align 0
+
+ .extern __stack_end__
+ .extern __bss_beg__
+ .extern __bss_end__
+ .extern __data_beg__
+ .extern __data_end__
+ .extern __data+beg_src__
+
+ .global start
+ .global endless_loop
+
+ /* Stack Sizes */
+ .set UND_STACK_SIZE, 0x00000004
+ .set ABT_STACK_SIZE, 0x00000004
+ .set FIQ_STACK_SIZE, 0x00000004
+ .set IRQ_STACK_SIZE, 0X00000400
+ .set SVC_STACK_SIZE, 0x00000400
+
+ /* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
+ .set MODE_USR, 0x10 /* User Mode */
+ .set MODE_FIQ, 0x11 /* FIQ Mode */
+ .set MODE_IRQ, 0x12 /* IRQ Mode */
+ .set MODE_SVC, 0x13 /* Supervisor Mode */
+ .set MODE_ABT, 0x17 /* Abort Mode */
+ .set MODE_UND, 0x1B /* Undefined Mode */
+ .set MODE_SYS, 0x1F /* System Mode */
+
+ .equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
+ .equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
+
+
+start:
+_start:
+_mainCRTStartup:
+
+ /* Setup a stack for each mode - note that this only sets up a usable stack
+ for system/user, SWI and IRQ modes. Also each mode is setup with
+ interrupts initially disabled. */
+ ldr r0, .LC6
+ msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
+ mov sp, r0
+ sub r0, r0, #UND_STACK_SIZE
+ msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
+ mov sp, r0
+ sub r0, r0, #ABT_STACK_SIZE
+ msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
+ mov sp, r0
+ sub r0, r0, #FIQ_STACK_SIZE
+ msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
+ mov sp, r0
+ sub r0, r0, #IRQ_STACK_SIZE
+ msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
+ mov sp, r0
+ sub r0, r0, #SVC_STACK_SIZE
+ msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */
+ mov sp, r0
+
+ /* We want to start in supervisor mode. Operation will switch to system
+ mode when the first task starts. */
+ msr CPSR_c, #MODE_SVC|I_BIT|F_BIT
+
+ bl AT91F_LowLevelInit
+
+ /* Clear BSS. */
+
+ mov a2, #0 /* Fill value */
+ mov fp, a2 /* Null frame pointer */
+ mov r7, a2 /* Null frame pointer for Thumb */
+
+ ldr r1, .LC1 /* Start of memory block */
+ ldr r3, .LC2 /* End of memory block */
+ subs r3, r3, r1 /* Length of block */
+ beq .end_clear_loop
+ mov r2, #0
+
+.clear_loop:
+ strb r2, [r1], #1
+ subs r3, r3, #1
+ bgt .clear_loop
+
+.end_clear_loop:
+
+ /* Initialise data. */
+
+ ldr r1, .LC3 /* Start of memory block */
+ ldr r2, .LC4 /* End of memory block */
+ ldr r3, .LC5
+ subs r3, r3, r1 /* Length of block */
+ beq .end_set_loop
+
+.set_loop:
+ ldrb r4, [r2], #1
+ strb r4, [r1], #1
+ subs r3, r3, #1
+ bgt .set_loop
+
+.end_set_loop:
+
+ mov r0, #0 /* no arguments */
+ mov r1, #0 /* no argv either */
+
+ ldr lr, =main
+ bx lr
+
+endless_loop:
+ b endless_loop
+
+
+ .align 0
+
+ .LC1:
+ .word __bss_beg__
+ .LC2:
+ .word __bss_end__
+ .LC3:
+ .word __data_beg__
+ .LC4:
+ .word __data_beg_src__
+ .LC5:
+ .word __data_end__
+ .LC6:
+ .word __stack_end__
+
+
+ /* Setup vector table. Note that undf, pabt, dabt, fiq just execute
+ a null loop. */
+
+.section .startup,"ax"
+ .code 32
+ .align 0
+
+ b _start /* reset - _start */
+ ldr pc, _undf /* undefined - _undf */
+ ldr pc, _swi /* SWI - _swi */
+ ldr pc, _pabt /* program abort - _pabt */
+ ldr pc, _dabt /* data abort - _dabt */
+ nop /* reserved */
+ ldr pc, [pc,#-0xF20] /* IRQ - read the AIC */
+ ldr pc, _fiq /* FIQ - _fiq */
+
+_undf: .word __undf /* undefined */
+_swi: .word swi_handler /* SWI */
+_pabt: .word __pabt /* program abort */
+_dabt: .word __dabt /* data abort */
+_fiq: .word __fiq /* FIQ */
+
+__undf: b . /* undefined */
+__pabt: b . /* program abort */
+__dabt: b . /* data abort */
+__fiq: b . /* FIQ */
diff --git a/openpicc/os/core/ARM7_AT91SAM7S/AT91SAM7.h b/openpicc/os/core/ARM7_AT91SAM7S/AT91SAM7.h
new file mode 100644
index 0000000..a788325
--- /dev/null
+++ b/openpicc/os/core/ARM7_AT91SAM7S/AT91SAM7.h
@@ -0,0 +1,1969 @@
+// ----------------------------------------------------------------------------
+// ATMEL Microcontroller Software Support - ROUSSET -
+// ----------------------------------------------------------------------------
+// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// ----------------------------------------------------------------------------
+// File Name : AT91SAM7S64.h
+// Object : AT91SAM7S64 definitions
+// Generated : AT91 SW Application Group 08/30/2005 (15:52:59)
+//
+// CVS Reference : /AT91SAM7S64.pl/1.21/Tue Aug 30 11:55:03 2005//
+// CVS Reference : /SYS_SAM7S.pl/1.2/Tue Feb 1 17:01:52 2005//
+// CVS Reference : /MC_SAM7S.pl/1.3/Fri May 20 14:12:30 2005//
+// CVS Reference : /PMC_SAM7S_USB.pl/1.4/Tue Feb 8 13:58:22 2005//
+// CVS Reference : /RSTC_SAM7S.pl/1.2/Wed Jul 13 14:57:40 2005//
+// CVS Reference : /UDP_SAM7S.pl/1.1/Tue May 10 11:34:52 2005//
+// CVS Reference : /PWM_SAM7S.pl/1.1/Tue May 10 11:53:07 2005//
+// CVS Reference : /RTTC_6081A.pl/1.2/Tue Nov 9 14:43:58 2004//
+// CVS Reference : /PITC_6079A.pl/1.2/Tue Nov 9 14:43:56 2004//
+// CVS Reference : /WDTC_6080A.pl/1.3/Tue Nov 9 14:44:00 2004//
+// CVS Reference : /VREG_6085B.pl/1.1/Tue Feb 1 16:05:48 2005//
+// CVS Reference : /AIC_6075B.pl/1.3/Fri May 20 14:01:30 2005//
+// CVS Reference : /PIO_6057A.pl/1.2/Thu Feb 3 10:18:28 2005//
+// CVS Reference : /DBGU_6059D.pl/1.1/Mon Jan 31 13:15:32 2005//
+// CVS Reference : /US_6089C.pl/1.1/Mon Jul 12 18:23:26 2004//
+// CVS Reference : /SPI_6088D.pl/1.3/Fri May 20 14:08:59 2005//
+// CVS Reference : /SSC_6078A.pl/1.1/Tue Jul 13 07:45:40 2004//
+// CVS Reference : /TC_6082A.pl/1.7/Fri Mar 11 12:52:17 2005//
+// CVS Reference : /TWI_6061A.pl/1.1/Tue Jul 13 07:38:06 2004//
+// CVS Reference : /PDC_6074C.pl/1.2/Thu Feb 3 08:48:54 2005//
+// CVS Reference : /ADC_6051C.pl/1.1/Fri Oct 17 09:12:38 2003//
+// ----------------------------------------------------------------------------
+
+#ifndef __AT91SAM7_H__
+#define __AT91SAM7_H__
+
+typedef volatile unsigned int AT91_REG; // Hardware register definition
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR System Peripherals
+// *****************************************************************************
+typedef struct _AT91S_SYS
+{
+ AT91_REG AIC_SMR[32]; // Source Mode Register
+ AT91_REG AIC_SVR[32]; // Source Vector Register
+ AT91_REG AIC_IVR; // IRQ Vector Register
+ AT91_REG AIC_FVR; // FIQ Vector Register
+ AT91_REG AIC_ISR; // Interrupt Status Register
+ AT91_REG AIC_IPR; // Interrupt Pending Register
+ AT91_REG AIC_IMR; // Interrupt Mask Register
+ AT91_REG AIC_CISR; // Core Interrupt Status Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG AIC_IECR; // Interrupt Enable Command Register
+ AT91_REG AIC_IDCR; // Interrupt Disable Command Register
+ AT91_REG AIC_ICCR; // Interrupt Clear Command Register
+ AT91_REG AIC_ISCR; // Interrupt Set Command Register
+ AT91_REG AIC_EOICR; // End of Interrupt Command Register
+ AT91_REG AIC_SPU; // Spurious Vector Register
+ AT91_REG AIC_DCR; // Debug Control Register (Protect)
+ AT91_REG Reserved1[1]; //
+ AT91_REG AIC_FFER; // Fast Forcing Enable Register
+ AT91_REG AIC_FFDR; // Fast Forcing Disable Register
+ AT91_REG AIC_FFSR; // Fast Forcing Status Register
+ AT91_REG Reserved2[45]; //
+ AT91_REG DBGU_CR; // Control Register
+ AT91_REG DBGU_MR; // Mode Register
+ AT91_REG DBGU_IER; // Interrupt Enable Register
+ AT91_REG DBGU_IDR; // Interrupt Disable Register
+ AT91_REG DBGU_IMR; // Interrupt Mask Register
+ AT91_REG DBGU_CSR; // Channel Status Register
+ AT91_REG DBGU_RHR; // Receiver Holding Register
+ AT91_REG DBGU_THR; // Transmitter Holding Register
+ AT91_REG DBGU_BRGR; // Baud Rate Generator Register
+ AT91_REG Reserved3[7]; //
+ AT91_REG DBGU_CIDR; // Chip ID Register
+ AT91_REG DBGU_EXID; // Chip ID Extension Register
+ AT91_REG DBGU_FNTR; // Force NTRST Register
+ AT91_REG Reserved4[45]; //
+ AT91_REG DBGU_RPR; // Receive Pointer Register
+ AT91_REG DBGU_RCR; // Receive Counter Register
+ AT91_REG DBGU_TPR; // Transmit Pointer Register
+ AT91_REG DBGU_TCR; // Transmit Counter Register
+ AT91_REG DBGU_RNPR; // Receive Next Pointer Register
+ AT91_REG DBGU_RNCR; // Receive Next Counter Register
+ AT91_REG DBGU_TNPR; // Transmit Next Pointer Register
+ AT91_REG DBGU_TNCR; // Transmit Next Counter Register
+ AT91_REG DBGU_PTCR; // PDC Transfer Control Register
+ AT91_REG DBGU_PTSR; // PDC Transfer Status Register
+ AT91_REG Reserved5[54]; //
+ AT91_REG PIOA_PER; // PIO Enable Register
+ AT91_REG PIOA_PDR; // PIO Disable Register
+ AT91_REG PIOA_PSR; // PIO Status Register
+ AT91_REG Reserved6[1]; //
+ AT91_REG PIOA_OER; // Output Enable Register
+ AT91_REG PIOA_ODR; // Output Disable Registerr
+ AT91_REG PIOA_OSR; // Output Status Register
+ AT91_REG Reserved7[1]; //
+ AT91_REG PIOA_IFER; // Input Filter Enable Register
+ AT91_REG PIOA_IFDR; // Input Filter Disable Register
+ AT91_REG PIOA_IFSR; // Input Filter Status Register
+ AT91_REG Reserved8[1]; //
+ AT91_REG PIOA_SODR; // Set Output Data Register
+ AT91_REG PIOA_CODR; // Clear Output Data Register
+ AT91_REG PIOA_ODSR; // Output Data Status Register
+ AT91_REG PIOA_PDSR; // Pin Data Status Register
+ AT91_REG PIOA_IER; // Interrupt Enable Register
+ AT91_REG PIOA_IDR; // Interrupt Disable Register
+ AT91_REG PIOA_IMR; // Interrupt Mask Register
+ AT91_REG PIOA_ISR; // Interrupt Status Register
+ AT91_REG PIOA_MDER; // Multi-driver Enable Register
+ AT91_REG PIOA_MDDR; // Multi-driver Disable Register
+ AT91_REG PIOA_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved9[1]; //
+ AT91_REG PIOA_PPUDR; // Pull-up Disable Register
+ AT91_REG PIOA_PPUER; // Pull-up Enable Register
+ AT91_REG PIOA_PPUSR; // Pull-up Status Register
+ AT91_REG Reserved10[1]; //
+ AT91_REG PIOA_ASR; // Select A Register
+ AT91_REG PIOA_BSR; // Select B Register
+ AT91_REG PIOA_ABSR; // AB Select Status Register
+ AT91_REG Reserved11[9]; //
+ AT91_REG PIOA_OWER; // Output Write Enable Register
+ AT91_REG PIOA_OWDR; // Output Write Disable Register
+ AT91_REG PIOA_OWSR; // Output Write Status Register
+ AT91_REG Reserved12[469]; //
+ AT91_REG PMC_SCER; // System Clock Enable Register
+ AT91_REG PMC_SCDR; // System Clock Disable Register
+ AT91_REG PMC_SCSR; // System Clock Status Register
+ AT91_REG Reserved13[1]; //
+ AT91_REG PMC_PCER; // Peripheral Clock Enable Register
+ AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
+ AT91_REG PMC_PCSR; // Peripheral Clock Status Register
+ AT91_REG Reserved14[1]; //
+ AT91_REG PMC_MOR; // Main Oscillator Register
+ AT91_REG PMC_MCFR; // Main Clock Frequency Register
+ AT91_REG Reserved15[1]; //
+ AT91_REG PMC_PLLR; // PLL Register
+ AT91_REG PMC_MCKR; // Master Clock Register
+ AT91_REG Reserved16[3]; //
+ AT91_REG PMC_PCKR[3]; // Programmable Clock Register
+ AT91_REG Reserved17[5]; //
+ AT91_REG PMC_IER; // Interrupt Enable Register
+ AT91_REG PMC_IDR; // Interrupt Disable Register
+ AT91_REG PMC_SR; // Status Register
+ AT91_REG PMC_IMR; // Interrupt Mask Register
+ AT91_REG Reserved18[36]; //
+ AT91_REG RSTC_RCR; // Reset Control Register
+ AT91_REG RSTC_RSR; // Reset Status Register
+ AT91_REG RSTC_RMR; // Reset Mode Register
+ AT91_REG Reserved19[5]; //
+ AT91_REG RTTC_RTMR; // Real-time Mode Register
+ AT91_REG RTTC_RTAR; // Real-time Alarm Register
+ AT91_REG RTTC_RTVR; // Real-time Value Register
+ AT91_REG RTTC_RTSR; // Real-time Status Register
+ AT91_REG PITC_PIMR; // Period Interval Mode Register
+ AT91_REG PITC_PISR; // Period Interval Status Register
+ AT91_REG PITC_PIVR; // Period Interval Value Register
+ AT91_REG PITC_PIIR; // Period Interval Image Register
+ AT91_REG WDTC_WDCR; // Watchdog Control Register
+ AT91_REG WDTC_WDMR; // Watchdog Mode Register
+ AT91_REG WDTC_WDSR; // Watchdog Status Register
+ AT91_REG Reserved20[5]; //
+ AT91_REG VREG_MR; // Voltage Regulator Mode Register
+} AT91S_SYS, *AT91PS_SYS;
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Advanced Interrupt Controller
+// *****************************************************************************
+typedef struct _AT91S_AIC
+{
+ AT91_REG AIC_SMR[32]; // Source Mode Register
+ AT91_REG AIC_SVR[32]; // Source Vector Register
+ AT91_REG AIC_IVR; // IRQ Vector Register
+ AT91_REG AIC_FVR; // FIQ Vector Register
+ AT91_REG AIC_ISR; // Interrupt Status Register
+ AT91_REG AIC_IPR; // Interrupt Pending Register
+ AT91_REG AIC_IMR; // Interrupt Mask Register
+ AT91_REG AIC_CISR; // Core Interrupt Status Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG AIC_IECR; // Interrupt Enable Command Register
+ AT91_REG AIC_IDCR; // Interrupt Disable Command Register
+ AT91_REG AIC_ICCR; // Interrupt Clear Command Register
+ AT91_REG AIC_ISCR; // Interrupt Set Command Register
+ AT91_REG AIC_EOICR; // End of Interrupt Command Register
+ AT91_REG AIC_SPU; // Spurious Vector Register
+ AT91_REG AIC_DCR; // Debug Control Register (Protect)
+ AT91_REG Reserved1[1]; //
+ AT91_REG AIC_FFER; // Fast Forcing Enable Register
+ AT91_REG AIC_FFDR; // Fast Forcing Disable Register
+ AT91_REG AIC_FFSR; // Fast Forcing Status Register
+} AT91S_AIC, *AT91PS_AIC;
+
+// -------- AIC_SMR : (AIC Offset: 0x0) Control Register --------
+#define AT91C_AIC_PRIOR ((unsigned int) 0x7 << 0) // (AIC) Priority Level
+#define AT91C_AIC_PRIOR_LOWEST ((unsigned int) 0x0) // (AIC) Lowest priority level
+#define AT91C_AIC_PRIOR_HIGHEST ((unsigned int) 0x7) // (AIC) Highest priority level
+#define AT91C_AIC_SRCTYPE ((unsigned int) 0x3 << 5) // (AIC) Interrupt Source Type
+#define AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL ((unsigned int) 0x0 << 5) // (AIC) Internal Sources Code Label High-level Sensitive
+#define AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL ((unsigned int) 0x0 << 5) // (AIC) External Sources Code Label Low-level Sensitive
+#define AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE ((unsigned int) 0x1 << 5) // (AIC) Internal Sources Code Label Positive Edge triggered
+#define AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE ((unsigned int) 0x1 << 5) // (AIC) External Sources Code Label Negative Edge triggered
+#define AT91C_AIC_SRCTYPE_HIGH_LEVEL ((unsigned int) 0x2 << 5) // (AIC) Internal Or External Sources Code Label High-level Sensitive
+#define AT91C_AIC_SRCTYPE_POSITIVE_EDGE ((unsigned int) 0x3 << 5) // (AIC) Internal Or External Sources Code Label Positive Edge triggered
+// -------- AIC_CISR : (AIC Offset: 0x114) AIC Core Interrupt Status Register --------
+#define AT91C_AIC_NFIQ ((unsigned int) 0x1 << 0) // (AIC) NFIQ Status
+#define AT91C_AIC_NIRQ ((unsigned int) 0x1 << 1) // (AIC) NIRQ Status
+// -------- AIC_DCR : (AIC Offset: 0x138) AIC Debug Control Register (Protect) --------
+#define AT91C_AIC_DCR_PROT ((unsigned int) 0x1 << 0) // (AIC) Protection Mode
+#define AT91C_AIC_DCR_GMSK ((unsigned int) 0x1 << 1) // (AIC) General Mask
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Peripheral DMA Controller
+// *****************************************************************************
+typedef struct _AT91S_PDC
+{
+ AT91_REG PDC_RPR; // Receive Pointer Register
+ AT91_REG PDC_RCR; // Receive Counter Register
+ AT91_REG PDC_TPR; // Transmit Pointer Register
+ AT91_REG PDC_TCR; // Transmit Counter Register
+ AT91_REG PDC_RNPR; // Receive Next Pointer Register
+ AT91_REG PDC_RNCR; // Receive Next Counter Register
+ AT91_REG PDC_TNPR; // Transmit Next Pointer Register
+ AT91_REG PDC_TNCR; // Transmit Next Counter Register
+ AT91_REG PDC_PTCR; // PDC Transfer Control Register
+ AT91_REG PDC_PTSR; // PDC Transfer Status Register
+} AT91S_PDC, *AT91PS_PDC;
+
+// -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register --------
+#define AT91C_PDC_RXTEN ((unsigned int) 0x1 << 0) // (PDC) Receiver Transfer Enable
+#define AT91C_PDC_RXTDIS ((unsigned int) 0x1 << 1) // (PDC) Receiver Transfer Disable
+#define AT91C_PDC_TXTEN ((unsigned int) 0x1 << 8) // (PDC) Transmitter Transfer Enable
+#define AT91C_PDC_TXTDIS ((unsigned int) 0x1 << 9) // (PDC) Transmitter Transfer Disable
+// -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Debug Unit
+// *****************************************************************************
+typedef struct _AT91S_DBGU
+{
+ AT91_REG DBGU_CR; // Control Register
+ AT91_REG DBGU_MR; // Mode Register
+ AT91_REG DBGU_IER; // Interrupt Enable Register
+ AT91_REG DBGU_IDR; // Interrupt Disable Register
+ AT91_REG DBGU_IMR; // Interrupt Mask Register
+ AT91_REG DBGU_CSR; // Channel Status Register
+ AT91_REG DBGU_RHR; // Receiver Holding Register
+ AT91_REG DBGU_THR; // Transmitter Holding Register
+ AT91_REG DBGU_BRGR; // Baud Rate Generator Register
+ AT91_REG Reserved0[7]; //
+ AT91_REG DBGU_CIDR; // Chip ID Register
+ AT91_REG DBGU_EXID; // Chip ID Extension Register
+ AT91_REG DBGU_FNTR; // Force NTRST Register
+ AT91_REG Reserved1[45]; //
+ AT91_REG DBGU_RPR; // Receive Pointer Register
+ AT91_REG DBGU_RCR; // Receive Counter Register
+ AT91_REG DBGU_TPR; // Transmit Pointer Register
+ AT91_REG DBGU_TCR; // Transmit Counter Register
+ AT91_REG DBGU_RNPR; // Receive Next Pointer Register
+ AT91_REG DBGU_RNCR; // Receive Next Counter Register
+ AT91_REG DBGU_TNPR; // Transmit Next Pointer Register
+ AT91_REG DBGU_TNCR; // Transmit Next Counter Register
+ AT91_REG DBGU_PTCR; // PDC Transfer Control Register
+ AT91_REG DBGU_PTSR; // PDC Transfer Status Register
+} AT91S_DBGU, *AT91PS_DBGU;
+
+// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register --------
+#define AT91C_US_RSTRX ((unsigned int) 0x1 << 2) // (DBGU) Reset Receiver
+#define AT91C_US_RSTTX ((unsigned int) 0x1 << 3) // (DBGU) Reset Transmitter
+#define AT91C_US_RXEN ((unsigned int) 0x1 << 4) // (DBGU) Receiver Enable
+#define AT91C_US_RXDIS ((unsigned int) 0x1 << 5) // (DBGU) Receiver Disable
+#define AT91C_US_TXEN ((unsigned int) 0x1 << 6) // (DBGU) Transmitter Enable
+#define AT91C_US_TXDIS ((unsigned int) 0x1 << 7) // (DBGU) Transmitter Disable
+#define AT91C_US_RSTSTA ((unsigned int) 0x1 << 8) // (DBGU) Reset Status Bits
+// -------- DBGU_MR : (DBGU Offset: 0x4) Debug Unit Mode Register --------
+#define AT91C_US_PAR ((unsigned int) 0x7 << 9) // (DBGU) Parity type
+#define AT91C_US_PAR_EVEN ((unsigned int) 0x0 << 9) // (DBGU) Even Parity
+#define AT91C_US_PAR_ODD ((unsigned int) 0x1 << 9) // (DBGU) Odd Parity
+#define AT91C_US_PAR_SPACE ((unsigned int) 0x2 << 9) // (DBGU) Parity forced to 0 (Space)
+#define AT91C_US_PAR_MARK ((unsigned int) 0x3 << 9) // (DBGU) Parity forced to 1 (Mark)
+#define AT91C_US_PAR_NONE ((unsigned int) 0x4 << 9) // (DBGU) No Parity
+#define AT91C_US_PAR_MULTI_DROP ((unsigned int) 0x6 << 9) // (DBGU) Multi-drop mode
+#define AT91C_US_CHMODE ((unsigned int) 0x3 << 14) // (DBGU) Channel Mode
+#define AT91C_US_CHMODE_NORMAL ((unsigned int) 0x0 << 14) // (DBGU) Normal Mode: The USART channel operates as an RX/TX USART.
+#define AT91C_US_CHMODE_AUTO ((unsigned int) 0x1 << 14) // (DBGU) Automatic Echo: Receiver Data Input is connected to the TXD pin.
+#define AT91C_US_CHMODE_LOCAL ((unsigned int) 0x2 << 14) // (DBGU) Local Loopback: Transmitter Output Signal is connected to Receiver Input Signal.
+#define AT91C_US_CHMODE_REMOTE ((unsigned int) 0x3 << 14) // (DBGU) Remote Loopback: RXD pin is internally connected to TXD pin.
+// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_US_RXRDY ((unsigned int) 0x1 << 0) // (DBGU) RXRDY Interrupt
+#define AT91C_US_TXRDY ((unsigned int) 0x1 << 1) // (DBGU) TXRDY Interrupt
+#define AT91C_US_ENDRX ((unsigned int) 0x1 << 3) // (DBGU) End of Receive Transfer Interrupt
+#define AT91C_US_ENDTX ((unsigned int) 0x1 << 4) // (DBGU) End of Transmit Interrupt
+#define AT91C_US_OVRE ((unsigned int) 0x1 << 5) // (DBGU) Overrun Interrupt
+#define AT91C_US_FRAME ((unsigned int) 0x1 << 6) // (DBGU) Framing Error Interrupt
+#define AT91C_US_PARE ((unsigned int) 0x1 << 7) // (DBGU) Parity Error Interrupt
+#define AT91C_US_TXEMPTY ((unsigned int) 0x1 << 9) // (DBGU) TXEMPTY Interrupt
+#define AT91C_US_TXBUFE ((unsigned int) 0x1 << 11) // (DBGU) TXBUFE Interrupt
+#define AT91C_US_RXBUFF ((unsigned int) 0x1 << 12) // (DBGU) RXBUFF Interrupt
+#define AT91C_US_COMM_TX ((unsigned int) 0x1 << 30) // (DBGU) COMM_TX Interrupt
+#define AT91C_US_COMM_RX ((unsigned int) 0x1 << 31) // (DBGU) COMM_RX Interrupt
+// -------- DBGU_IDR : (DBGU Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- DBGU_IMR : (DBGU Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- DBGU_CSR : (DBGU Offset: 0x14) Debug Unit Channel Status Register --------
+// -------- DBGU_FNTR : (DBGU Offset: 0x48) Debug Unit FORCE_NTRST Register --------
+#define AT91C_US_FORCE_NTRST ((unsigned int) 0x1 << 0) // (DBGU) Force NTRST in JTAG
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Parallel Input Output Controler
+// *****************************************************************************
+typedef struct _AT91S_PIO
+{
+ AT91_REG PIO_PER; // PIO Enable Register
+ AT91_REG PIO_PDR; // PIO Disable Register
+ AT91_REG PIO_PSR; // PIO Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG PIO_OER; // Output Enable Register
+ AT91_REG PIO_ODR; // Output Disable Registerr
+ AT91_REG PIO_OSR; // Output Status Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG PIO_IFER; // Input Filter Enable Register
+ AT91_REG PIO_IFDR; // Input Filter Disable Register
+ AT91_REG PIO_IFSR; // Input Filter Status Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG PIO_SODR; // Set Output Data Register
+ AT91_REG PIO_CODR; // Clear Output Data Register
+ AT91_REG PIO_ODSR; // Output Data Status Register
+ AT91_REG PIO_PDSR; // Pin Data Status Register
+ AT91_REG PIO_IER; // Interrupt Enable Register
+ AT91_REG PIO_IDR; // Interrupt Disable Register
+ AT91_REG PIO_IMR; // Interrupt Mask Register
+ AT91_REG PIO_ISR; // Interrupt Status Register
+ AT91_REG PIO_MDER; // Multi-driver Enable Register
+ AT91_REG PIO_MDDR; // Multi-driver Disable Register
+ AT91_REG PIO_MDSR; // Multi-driver Status Register
+ AT91_REG Reserved3[1]; //
+ AT91_REG PIO_PPUDR; // Pull-up Disable Register
+ AT91_REG PIO_PPUER; // Pull-up Enable Register
+ AT91_REG PIO_PPUSR; // Pull-up Status Register
+ AT91_REG Reserved4[1]; //
+ AT91_REG PIO_ASR; // Select A Register
+ AT91_REG PIO_BSR; // Select B Register
+ AT91_REG PIO_ABSR; // AB Select Status Register
+ AT91_REG Reserved5[9]; //
+ AT91_REG PIO_OWER; // Output Write Enable Register
+ AT91_REG PIO_OWDR; // Output Write Disable Register
+ AT91_REG PIO_OWSR; // Output Write Status Register
+} AT91S_PIO, *AT91PS_PIO;
+
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Clock Generator Controler
+// *****************************************************************************
+typedef struct _AT91S_CKGR
+{
+ AT91_REG CKGR_MOR; // Main Oscillator Register
+ AT91_REG CKGR_MCFR; // Main Clock Frequency Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG CKGR_PLLR; // PLL Register
+} AT91S_CKGR, *AT91PS_CKGR;
+
+// -------- CKGR_MOR : (CKGR Offset: 0x0) Main Oscillator Register --------
+#define AT91C_CKGR_MOSCEN ((unsigned int) 0x1 << 0) // (CKGR) Main Oscillator Enable
+#define AT91C_CKGR_OSCBYPASS ((unsigned int) 0x1 << 1) // (CKGR) Main Oscillator Bypass
+#define AT91C_CKGR_OSCOUNT ((unsigned int) 0xFF << 8) // (CKGR) Main Oscillator Start-up Time
+// -------- CKGR_MCFR : (CKGR Offset: 0x4) Main Clock Frequency Register --------
+#define AT91C_CKGR_MAINF ((unsigned int) 0xFFFF << 0) // (CKGR) Main Clock Frequency
+#define AT91C_CKGR_MAINRDY ((unsigned int) 0x1 << 16) // (CKGR) Main Clock Ready
+// -------- CKGR_PLLR : (CKGR Offset: 0xc) PLL B Register --------
+#define AT91C_CKGR_DIV ((unsigned int) 0xFF << 0) // (CKGR) Divider Selected
+#define AT91C_CKGR_DIV_0 ((unsigned int) 0x0) // (CKGR) Divider output is 0
+#define AT91C_CKGR_DIV_BYPASS ((unsigned int) 0x1) // (CKGR) Divider is bypassed
+#define AT91C_CKGR_PLLCOUNT ((unsigned int) 0x3F << 8) // (CKGR) PLL Counter
+#define AT91C_CKGR_OUT ((unsigned int) 0x3 << 14) // (CKGR) PLL Output Frequency Range
+#define AT91C_CKGR_OUT_0 ((unsigned int) 0x0 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_OUT_1 ((unsigned int) 0x1 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_OUT_2 ((unsigned int) 0x2 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_OUT_3 ((unsigned int) 0x3 << 14) // (CKGR) Please refer to the PLL datasheet
+#define AT91C_CKGR_MUL ((unsigned int) 0x7FF << 16) // (CKGR) PLL Multiplier
+#define AT91C_CKGR_USBDIV ((unsigned int) 0x3 << 28) // (CKGR) Divider for USB Clocks
+#define AT91C_CKGR_USBDIV_0 ((unsigned int) 0x0 << 28) // (CKGR) Divider output is PLL clock output
+#define AT91C_CKGR_USBDIV_1 ((unsigned int) 0x1 << 28) // (CKGR) Divider output is PLL clock output divided by 2
+#define AT91C_CKGR_USBDIV_2 ((unsigned int) 0x2 << 28) // (CKGR) Divider output is PLL clock output divided by 4
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Power Management Controler
+// *****************************************************************************
+typedef struct _AT91S_PMC
+{
+ AT91_REG PMC_SCER; // System Clock Enable Register
+ AT91_REG PMC_SCDR; // System Clock Disable Register
+ AT91_REG PMC_SCSR; // System Clock Status Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG PMC_PCER; // Peripheral Clock Enable Register
+ AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
+ AT91_REG PMC_PCSR; // Peripheral Clock Status Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG PMC_MOR; // Main Oscillator Register
+ AT91_REG PMC_MCFR; // Main Clock Frequency Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG PMC_PLLR; // PLL Register
+ AT91_REG PMC_MCKR; // Master Clock Register
+ AT91_REG Reserved3[3]; //
+ AT91_REG PMC_PCKR[3]; // Programmable Clock Register
+ AT91_REG Reserved4[5]; //
+ AT91_REG PMC_IER; // Interrupt Enable Register
+ AT91_REG PMC_IDR; // Interrupt Disable Register
+ AT91_REG PMC_SR; // Status Register
+ AT91_REG PMC_IMR; // Interrupt Mask Register
+} AT91S_PMC, *AT91PS_PMC;
+
+// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register --------
+#define AT91C_PMC_PCK ((unsigned int) 0x1 << 0) // (PMC) Processor Clock
+#define AT91C_PMC_UDP ((unsigned int) 0x1 << 7) // (PMC) USB Device Port Clock
+#define AT91C_PMC_PCK0 ((unsigned int) 0x1 << 8) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK1 ((unsigned int) 0x1 << 9) // (PMC) Programmable Clock Output
+#define AT91C_PMC_PCK2 ((unsigned int) 0x1 << 10) // (PMC) Programmable Clock Output
+// -------- PMC_SCDR : (PMC Offset: 0x4) System Clock Disable Register --------
+// -------- PMC_SCSR : (PMC Offset: 0x8) System Clock Status Register --------
+// -------- CKGR_MOR : (PMC Offset: 0x20) Main Oscillator Register --------
+// -------- CKGR_MCFR : (PMC Offset: 0x24) Main Clock Frequency Register --------
+// -------- CKGR_PLLR : (PMC Offset: 0x2c) PLL B Register --------
+// -------- PMC_MCKR : (PMC Offset: 0x30) Master Clock Register --------
+#define AT91C_PMC_CSS ((unsigned int) 0x3 << 0) // (PMC) Programmable Clock Selection
+#define AT91C_PMC_CSS_SLOW_CLK ((unsigned int) 0x0) // (PMC) Slow Clock is selected
+#define AT91C_PMC_CSS_MAIN_CLK ((unsigned int) 0x1) // (PMC) Main Clock is selected
+#define AT91C_PMC_CSS_PLL_CLK ((unsigned int) 0x3) // (PMC) Clock from PLL is selected
+#define AT91C_PMC_PRES ((unsigned int) 0x7 << 2) // (PMC) Programmable Clock Prescaler
+#define AT91C_PMC_PRES_CLK ((unsigned int) 0x0 << 2) // (PMC) Selected clock
+#define AT91C_PMC_PRES_CLK_2 ((unsigned int) 0x1 << 2) // (PMC) Selected clock divided by 2
+#define AT91C_PMC_PRES_CLK_4 ((unsigned int) 0x2 << 2) // (PMC) Selected clock divided by 4
+#define AT91C_PMC_PRES_CLK_8 ((unsigned int) 0x3 << 2) // (PMC) Selected clock divided by 8
+#define AT91C_PMC_PRES_CLK_16 ((unsigned int) 0x4 << 2) // (PMC) Selected clock divided by 16
+#define AT91C_PMC_PRES_CLK_32 ((unsigned int) 0x5 << 2) // (PMC) Selected clock divided by 32
+#define AT91C_PMC_PRES_CLK_64 ((unsigned int) 0x6 << 2) // (PMC) Selected clock divided by 64
+// -------- PMC_PCKR : (PMC Offset: 0x40) Programmable Clock Register --------
+// -------- PMC_IER : (PMC Offset: 0x60) PMC Interrupt Enable Register --------
+#define AT91C_PMC_MOSCS ((unsigned int) 0x1 << 0) // (PMC) MOSC Status/Enable/Disable/Mask
+#define AT91C_PMC_LOCK ((unsigned int) 0x1 << 2) // (PMC) PLL Status/Enable/Disable/Mask
+#define AT91C_PMC_MCKRDY ((unsigned int) 0x1 << 3) // (PMC) MCK_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK0RDY ((unsigned int) 0x1 << 8) // (PMC) PCK0_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK1RDY ((unsigned int) 0x1 << 9) // (PMC) PCK1_RDY Status/Enable/Disable/Mask
+#define AT91C_PMC_PCK2RDY ((unsigned int) 0x1 << 10) // (PMC) PCK2_RDY Status/Enable/Disable/Mask
+// -------- PMC_IDR : (PMC Offset: 0x64) PMC Interrupt Disable Register --------
+// -------- PMC_SR : (PMC Offset: 0x68) PMC Status Register --------
+// -------- PMC_IMR : (PMC Offset: 0x6c) PMC Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Reset Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_RSTC
+{
+ AT91_REG RSTC_RCR; // Reset Control Register
+ AT91_REG RSTC_RSR; // Reset Status Register
+ AT91_REG RSTC_RMR; // Reset Mode Register
+} AT91S_RSTC, *AT91PS_RSTC;
+
+// -------- RSTC_RCR : (RSTC Offset: 0x0) Reset Control Register --------
+#define AT91C_RSTC_PROCRST ((unsigned int) 0x1 << 0) // (RSTC) Processor Reset
+#define AT91C_RSTC_PERRST ((unsigned int) 0x1 << 2) // (RSTC) Peripheral Reset
+#define AT91C_RSTC_EXTRST ((unsigned int) 0x1 << 3) // (RSTC) External Reset
+#define AT91C_RSTC_KEY ((unsigned int) 0xFF << 24) // (RSTC) Password
+// -------- RSTC_RSR : (RSTC Offset: 0x4) Reset Status Register --------
+#define AT91C_RSTC_URSTS ((unsigned int) 0x1 << 0) // (RSTC) User Reset Status
+#define AT91C_RSTC_BODSTS ((unsigned int) 0x1 << 1) // (RSTC) Brownout Detection Status
+#define AT91C_RSTC_RSTTYP ((unsigned int) 0x7 << 8) // (RSTC) Reset Type
+#define AT91C_RSTC_RSTTYP_POWERUP ((unsigned int) 0x0 << 8) // (RSTC) Power-up Reset. VDDCORE rising.
+#define AT91C_RSTC_RSTTYP_WAKEUP ((unsigned int) 0x1 << 8) // (RSTC) WakeUp Reset. VDDCORE rising.
+#define AT91C_RSTC_RSTTYP_WATCHDOG ((unsigned int) 0x2 << 8) // (RSTC) Watchdog Reset. Watchdog overflow occured.
+#define AT91C_RSTC_RSTTYP_SOFTWARE ((unsigned int) 0x3 << 8) // (RSTC) Software Reset. Processor reset required by the software.
+#define AT91C_RSTC_RSTTYP_USER ((unsigned int) 0x4 << 8) // (RSTC) User Reset. NRST pin detected low.
+#define AT91C_RSTC_RSTTYP_BROWNOUT ((unsigned int) 0x5 << 8) // (RSTC) Brownout Reset occured.
+#define AT91C_RSTC_NRSTL ((unsigned int) 0x1 << 16) // (RSTC) NRST pin level
+#define AT91C_RSTC_SRCMP ((unsigned int) 0x1 << 17) // (RSTC) Software Reset Command in Progress.
+// -------- RSTC_RMR : (RSTC Offset: 0x8) Reset Mode Register --------
+#define AT91C_RSTC_URSTEN ((unsigned int) 0x1 << 0) // (RSTC) User Reset Enable
+#define AT91C_RSTC_URSTIEN ((unsigned int) 0x1 << 4) // (RSTC) User Reset Interrupt Enable
+#define AT91C_RSTC_ERSTL ((unsigned int) 0xF << 8) // (RSTC) User Reset Length
+#define AT91C_RSTC_BODIEN ((unsigned int) 0x1 << 16) // (RSTC) Brownout Detection Interrupt Enable
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Real Time Timer Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_RTTC
+{
+ AT91_REG RTTC_RTMR; // Real-time Mode Register
+ AT91_REG RTTC_RTAR; // Real-time Alarm Register
+ AT91_REG RTTC_RTVR; // Real-time Value Register
+ AT91_REG RTTC_RTSR; // Real-time Status Register
+} AT91S_RTTC, *AT91PS_RTTC;
+
+// -------- RTTC_RTMR : (RTTC Offset: 0x0) Real-time Mode Register --------
+#define AT91C_RTTC_RTPRES ((unsigned int) 0xFFFF << 0) // (RTTC) Real-time Timer Prescaler Value
+#define AT91C_RTTC_ALMIEN ((unsigned int) 0x1 << 16) // (RTTC) Alarm Interrupt Enable
+#define AT91C_RTTC_RTTINCIEN ((unsigned int) 0x1 << 17) // (RTTC) Real Time Timer Increment Interrupt Enable
+#define AT91C_RTTC_RTTRST ((unsigned int) 0x1 << 18) // (RTTC) Real Time Timer Restart
+// -------- RTTC_RTAR : (RTTC Offset: 0x4) Real-time Alarm Register --------
+#define AT91C_RTTC_ALMV ((unsigned int) 0x0 << 0) // (RTTC) Alarm Value
+// -------- RTTC_RTVR : (RTTC Offset: 0x8) Current Real-time Value Register --------
+#define AT91C_RTTC_CRTV ((unsigned int) 0x0 << 0) // (RTTC) Current Real-time Value
+// -------- RTTC_RTSR : (RTTC Offset: 0xc) Real-time Status Register --------
+#define AT91C_RTTC_ALMS ((unsigned int) 0x1 << 0) // (RTTC) Real-time Alarm Status
+#define AT91C_RTTC_RTTINC ((unsigned int) 0x1 << 1) // (RTTC) Real-time Timer Increment
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Periodic Interval Timer Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_PITC
+{
+ AT91_REG PITC_PIMR; // Period Interval Mode Register
+ AT91_REG PITC_PISR; // Period Interval Status Register
+ AT91_REG PITC_PIVR; // Period Interval Value Register
+ AT91_REG PITC_PIIR; // Period Interval Image Register
+} AT91S_PITC, *AT91PS_PITC;
+
+// -------- PITC_PIMR : (PITC Offset: 0x0) Periodic Interval Mode Register --------
+#define AT91C_PITC_PIV ((unsigned int) 0xFFFFF << 0) // (PITC) Periodic Interval Value
+#define AT91C_PITC_PITEN ((unsigned int) 0x1 << 24) // (PITC) Periodic Interval Timer Enabled
+#define AT91C_PITC_PITIEN ((unsigned int) 0x1 << 25) // (PITC) Periodic Interval Timer Interrupt Enable
+// -------- PITC_PISR : (PITC Offset: 0x4) Periodic Interval Status Register --------
+#define AT91C_PITC_PITS ((unsigned int) 0x1 << 0) // (PITC) Periodic Interval Timer Status
+// -------- PITC_PIVR : (PITC Offset: 0x8) Periodic Interval Value Register --------
+#define AT91C_PITC_CPIV ((unsigned int) 0xFFFFF << 0) // (PITC) Current Periodic Interval Value
+#define AT91C_PITC_PICNT ((unsigned int) 0xFFF << 20) // (PITC) Periodic Interval Counter
+// -------- PITC_PIIR : (PITC Offset: 0xc) Periodic Interval Image Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Watchdog Timer Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_WDTC
+{
+ AT91_REG WDTC_WDCR; // Watchdog Control Register
+ AT91_REG WDTC_WDMR; // Watchdog Mode Register
+ AT91_REG WDTC_WDSR; // Watchdog Status Register
+} AT91S_WDTC, *AT91PS_WDTC;
+
+// -------- WDTC_WDCR : (WDTC Offset: 0x0) Periodic Interval Image Register --------
+#define AT91C_WDTC_WDRSTT ((unsigned int) 0x1 << 0) // (WDTC) Watchdog Restart
+#define AT91C_WDTC_KEY ((unsigned int) 0xFF << 24) // (WDTC) Watchdog KEY Password
+// -------- WDTC_WDMR : (WDTC Offset: 0x4) Watchdog Mode Register --------
+#define AT91C_WDTC_WDV ((unsigned int) 0xFFF << 0) // (WDTC) Watchdog Timer Restart
+#define AT91C_WDTC_WDFIEN ((unsigned int) 0x1 << 12) // (WDTC) Watchdog Fault Interrupt Enable
+#define AT91C_WDTC_WDRSTEN ((unsigned int) 0x1 << 13) // (WDTC) Watchdog Reset Enable
+#define AT91C_WDTC_WDRPROC ((unsigned int) 0x1 << 14) // (WDTC) Watchdog Timer Restart
+#define AT91C_WDTC_WDDIS ((unsigned int) 0x1 << 15) // (WDTC) Watchdog Disable
+#define AT91C_WDTC_WDD ((unsigned int) 0xFFF << 16) // (WDTC) Watchdog Delta Value
+#define AT91C_WDTC_WDDBGHLT ((unsigned int) 0x1 << 28) // (WDTC) Watchdog Debug Halt
+#define AT91C_WDTC_WDIDLEHLT ((unsigned int) 0x1 << 29) // (WDTC) Watchdog Idle Halt
+// -------- WDTC_WDSR : (WDTC Offset: 0x8) Watchdog Status Register --------
+#define AT91C_WDTC_WDUNF ((unsigned int) 0x1 << 0) // (WDTC) Watchdog Underflow
+#define AT91C_WDTC_WDERR ((unsigned int) 0x1 << 1) // (WDTC) Watchdog Error
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Voltage Regulator Mode Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_VREG
+{
+ AT91_REG VREG_MR; // Voltage Regulator Mode Register
+} AT91S_VREG, *AT91PS_VREG;
+
+// -------- VREG_MR : (VREG Offset: 0x0) Voltage Regulator Mode Register --------
+#define AT91C_VREG_PSTDBY ((unsigned int) 0x1 << 0) // (VREG) Voltage Regulator Power Standby Mode
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Memory Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_MC
+{
+ AT91_REG MC_RCR; // MC Remap Control Register
+ AT91_REG MC_ASR; // MC Abort Status Register
+ AT91_REG MC_AASR; // MC Abort Address Status Register
+ AT91_REG Reserved0[21]; //
+ AT91_REG MC_FMR; // MC Flash Mode Register
+ AT91_REG MC_FCR; // MC Flash Command Register
+ AT91_REG MC_FSR; // MC Flash Status Register
+} AT91S_MC, *AT91PS_MC;
+
+// -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register --------
+#define AT91C_MC_RCB ((unsigned int) 0x1 << 0) // (MC) Remap Command Bit
+// -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register --------
+#define AT91C_MC_UNDADD ((unsigned int) 0x1 << 0) // (MC) Undefined Addess Abort Status
+#define AT91C_MC_MISADD ((unsigned int) 0x1 << 1) // (MC) Misaligned Addess Abort Status
+#define AT91C_MC_ABTSZ ((unsigned int) 0x3 << 8) // (MC) Abort Size Status
+#define AT91C_MC_ABTSZ_BYTE ((unsigned int) 0x0 << 8) // (MC) Byte
+#define AT91C_MC_ABTSZ_HWORD ((unsigned int) 0x1 << 8) // (MC) Half-word
+#define AT91C_MC_ABTSZ_WORD ((unsigned int) 0x2 << 8) // (MC) Word
+#define AT91C_MC_ABTTYP ((unsigned int) 0x3 << 10) // (MC) Abort Type Status
+#define AT91C_MC_ABTTYP_DATAR ((unsigned int) 0x0 << 10) // (MC) Data Read
+#define AT91C_MC_ABTTYP_DATAW ((unsigned int) 0x1 << 10) // (MC) Data Write
+#define AT91C_MC_ABTTYP_FETCH ((unsigned int) 0x2 << 10) // (MC) Code Fetch
+#define AT91C_MC_MST0 ((unsigned int) 0x1 << 16) // (MC) Master 0 Abort Source
+#define AT91C_MC_MST1 ((unsigned int) 0x1 << 17) // (MC) Master 1 Abort Source
+#define AT91C_MC_SVMST0 ((unsigned int) 0x1 << 24) // (MC) Saved Master 0 Abort Source
+#define AT91C_MC_SVMST1 ((unsigned int) 0x1 << 25) // (MC) Saved Master 1 Abort Source
+// -------- MC_FMR : (MC Offset: 0x60) MC Flash Mode Register --------
+#define AT91C_MC_FRDY ((unsigned int) 0x1 << 0) // (MC) Flash Ready
+#define AT91C_MC_LOCKE ((unsigned int) 0x1 << 2) // (MC) Lock Error
+#define AT91C_MC_PROGE ((unsigned int) 0x1 << 3) // (MC) Programming Error
+#define AT91C_MC_NEBP ((unsigned int) 0x1 << 7) // (MC) No Erase Before Programming
+#define AT91C_MC_FWS ((unsigned int) 0x3 << 8) // (MC) Flash Wait State
+#define AT91C_MC_FWS_0FWS ((unsigned int) 0x0 << 8) // (MC) 1 cycle for Read, 2 for Write operations
+#define AT91C_MC_FWS_1FWS ((unsigned int) 0x1 << 8) // (MC) 2 cycles for Read, 3 for Write operations
+#define AT91C_MC_FWS_2FWS ((unsigned int) 0x2 << 8) // (MC) 3 cycles for Read, 4 for Write operations
+#define AT91C_MC_FWS_3FWS ((unsigned int) 0x3 << 8) // (MC) 4 cycles for Read, 4 for Write operations
+#define AT91C_MC_FMCN ((unsigned int) 0xFF << 16) // (MC) Flash Microsecond Cycle Number
+// -------- MC_FCR : (MC Offset: 0x64) MC Flash Command Register --------
+#define AT91C_MC_FCMD ((unsigned int) 0xF << 0) // (MC) Flash Command
+#define AT91C_MC_FCMD_START_PROG ((unsigned int) 0x1) // (MC) Starts the programming of th epage specified by PAGEN.
+#define AT91C_MC_FCMD_LOCK ((unsigned int) 0x2) // (MC) Starts a lock sequence of the sector defined by the bits 4 to 7 of the field PAGEN.
+#define AT91C_MC_FCMD_PROG_AND_LOCK ((unsigned int) 0x3) // (MC) The lock sequence automatically happens after the programming sequence is completed.
+#define AT91C_MC_FCMD_UNLOCK ((unsigned int) 0x4) // (MC) Starts an unlock sequence of the sector defined by the bits 4 to 7 of the field PAGEN.
+#define AT91C_MC_FCMD_ERASE_ALL ((unsigned int) 0x8) // (MC) Starts the erase of the entire flash.If at least a page is locked, the command is cancelled.
+#define AT91C_MC_FCMD_SET_GP_NVM ((unsigned int) 0xB) // (MC) Set General Purpose NVM bits.
+#define AT91C_MC_FCMD_CLR_GP_NVM ((unsigned int) 0xD) // (MC) Clear General Purpose NVM bits.
+#define AT91C_MC_FCMD_SET_SECURITY ((unsigned int) 0xF) // (MC) Set Security Bit.
+#define AT91C_MC_PAGEN ((unsigned int) 0x3FF << 8) // (MC) Page Number
+#define AT91C_MC_KEY ((unsigned int) 0xFF << 24) // (MC) Writing Protect Key
+// -------- MC_FSR : (MC Offset: 0x68) MC Flash Command Register --------
+#define AT91C_MC_SECURITY ((unsigned int) 0x1 << 4) // (MC) Security Bit Status
+#define AT91C_MC_GPNVM0 ((unsigned int) 0x1 << 8) // (MC) Sector 0 Lock Status
+#define AT91C_MC_GPNVM1 ((unsigned int) 0x1 << 9) // (MC) Sector 1 Lock Status
+#define AT91C_MC_GPNVM2 ((unsigned int) 0x1 << 10) // (MC) Sector 2 Lock Status
+#define AT91C_MC_GPNVM3 ((unsigned int) 0x1 << 11) // (MC) Sector 3 Lock Status
+#define AT91C_MC_GPNVM4 ((unsigned int) 0x1 << 12) // (MC) Sector 4 Lock Status
+#define AT91C_MC_GPNVM5 ((unsigned int) 0x1 << 13) // (MC) Sector 5 Lock Status
+#define AT91C_MC_GPNVM6 ((unsigned int) 0x1 << 14) // (MC) Sector 6 Lock Status
+#define AT91C_MC_GPNVM7 ((unsigned int) 0x1 << 15) // (MC) Sector 7 Lock Status
+#define AT91C_MC_LOCKS0 ((unsigned int) 0x1 << 16) // (MC) Sector 0 Lock Status
+#define AT91C_MC_LOCKS1 ((unsigned int) 0x1 << 17) // (MC) Sector 1 Lock Status
+#define AT91C_MC_LOCKS2 ((unsigned int) 0x1 << 18) // (MC) Sector 2 Lock Status
+#define AT91C_MC_LOCKS3 ((unsigned int) 0x1 << 19) // (MC) Sector 3 Lock Status
+#define AT91C_MC_LOCKS4 ((unsigned int) 0x1 << 20) // (MC) Sector 4 Lock Status
+#define AT91C_MC_LOCKS5 ((unsigned int) 0x1 << 21) // (MC) Sector 5 Lock Status
+#define AT91C_MC_LOCKS6 ((unsigned int) 0x1 << 22) // (MC) Sector 6 Lock Status
+#define AT91C_MC_LOCKS7 ((unsigned int) 0x1 << 23) // (MC) Sector 7 Lock Status
+#define AT91C_MC_LOCKS8 ((unsigned int) 0x1 << 24) // (MC) Sector 8 Lock Status
+#define AT91C_MC_LOCKS9 ((unsigned int) 0x1 << 25) // (MC) Sector 9 Lock Status
+#define AT91C_MC_LOCKS10 ((unsigned int) 0x1 << 26) // (MC) Sector 10 Lock Status
+#define AT91C_MC_LOCKS11 ((unsigned int) 0x1 << 27) // (MC) Sector 11 Lock Status
+#define AT91C_MC_LOCKS12 ((unsigned int) 0x1 << 28) // (MC) Sector 12 Lock Status
+#define AT91C_MC_LOCKS13 ((unsigned int) 0x1 << 29) // (MC) Sector 13 Lock Status
+#define AT91C_MC_LOCKS14 ((unsigned int) 0x1 << 30) // (MC) Sector 14 Lock Status
+#define AT91C_MC_LOCKS15 ((unsigned int) 0x1 << 31) // (MC) Sector 15 Lock Status
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Serial Parallel Interface
+// *****************************************************************************
+typedef struct _AT91S_SPI
+{
+ AT91_REG SPI_CR; // Control Register
+ AT91_REG SPI_MR; // Mode Register
+ AT91_REG SPI_RDR; // Receive Data Register
+ AT91_REG SPI_TDR; // Transmit Data Register
+ AT91_REG SPI_SR; // Status Register
+ AT91_REG SPI_IER; // Interrupt Enable Register
+ AT91_REG SPI_IDR; // Interrupt Disable Register
+ AT91_REG SPI_IMR; // Interrupt Mask Register
+ AT91_REG Reserved0[4]; //
+ AT91_REG SPI_CSR[4]; // Chip Select Register
+ AT91_REG Reserved1[48]; //
+ AT91_REG SPI_RPR; // Receive Pointer Register
+ AT91_REG SPI_RCR; // Receive Counter Register
+ AT91_REG SPI_TPR; // Transmit Pointer Register
+ AT91_REG SPI_TCR; // Transmit Counter Register
+ AT91_REG SPI_RNPR; // Receive Next Pointer Register
+ AT91_REG SPI_RNCR; // Receive Next Counter Register
+ AT91_REG SPI_TNPR; // Transmit Next Pointer Register
+ AT91_REG SPI_TNCR; // Transmit Next Counter Register
+ AT91_REG SPI_PTCR; // PDC Transfer Control Register
+ AT91_REG SPI_PTSR; // PDC Transfer Status Register
+} AT91S_SPI, *AT91PS_SPI;
+
+// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register --------
+#define AT91C_SPI_SPIEN ((unsigned int) 0x1 << 0) // (SPI) SPI Enable
+#define AT91C_SPI_SPIDIS ((unsigned int) 0x1 << 1) // (SPI) SPI Disable
+#define AT91C_SPI_SWRST ((unsigned int) 0x1 << 7) // (SPI) SPI Software reset
+#define AT91C_SPI_LASTXFER ((unsigned int) 0x1 << 24) // (SPI) SPI Last Transfer
+// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register --------
+#define AT91C_SPI_MSTR ((unsigned int) 0x1 << 0) // (SPI) Master/Slave Mode
+#define AT91C_SPI_PS ((unsigned int) 0x1 << 1) // (SPI) Peripheral Select
+#define AT91C_SPI_PS_FIXED ((unsigned int) 0x0 << 1) // (SPI) Fixed Peripheral Select
+#define AT91C_SPI_PS_VARIABLE ((unsigned int) 0x1 << 1) // (SPI) Variable Peripheral Select
+#define AT91C_SPI_PCSDEC ((unsigned int) 0x1 << 2) // (SPI) Chip Select Decode
+#define AT91C_SPI_FDIV ((unsigned int) 0x1 << 3) // (SPI) Clock Selection
+#define AT91C_SPI_MODFDIS ((unsigned int) 0x1 << 4) // (SPI) Mode Fault Detection
+#define AT91C_SPI_LLB ((unsigned int) 0x1 << 7) // (SPI) Clock Selection
+#define AT91C_SPI_PCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select
+#define AT91C_SPI_DLYBCS ((unsigned int) 0xFF << 24) // (SPI) Delay Between Chip Selects
+// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register --------
+#define AT91C_SPI_RD ((unsigned int) 0xFFFF << 0) // (SPI) Receive Data
+#define AT91C_SPI_RPCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register --------
+#define AT91C_SPI_TD ((unsigned int) 0xFFFF << 0) // (SPI) Transmit Data
+#define AT91C_SPI_TPCS ((unsigned int) 0xF << 16) // (SPI) Peripheral Chip Select Status
+// -------- SPI_SR : (SPI Offset: 0x10) Status Register --------
+#define AT91C_SPI_RDRF ((unsigned int) 0x1 << 0) // (SPI) Receive Data Register Full
+#define AT91C_SPI_TDRE ((unsigned int) 0x1 << 1) // (SPI) Transmit Data Register Empty
+#define AT91C_SPI_MODF ((unsigned int) 0x1 << 2) // (SPI) Mode Fault Error
+#define AT91C_SPI_OVRES ((unsigned int) 0x1 << 3) // (SPI) Overrun Error Status
+#define AT91C_SPI_ENDRX ((unsigned int) 0x1 << 4) // (SPI) End of Receiver Transfer
+#define AT91C_SPI_ENDTX ((unsigned int) 0x1 << 5) // (SPI) End of Receiver Transfer
+#define AT91C_SPI_RXBUFF ((unsigned int) 0x1 << 6) // (SPI) RXBUFF Interrupt
+#define AT91C_SPI_TXBUFE ((unsigned int) 0x1 << 7) // (SPI) TXBUFE Interrupt
+#define AT91C_SPI_NSSR ((unsigned int) 0x1 << 8) // (SPI) NSSR Interrupt
+#define AT91C_SPI_TXEMPTY ((unsigned int) 0x1 << 9) // (SPI) TXEMPTY Interrupt
+#define AT91C_SPI_SPIENS ((unsigned int) 0x1 << 16) // (SPI) Enable Status
+// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register --------
+// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register --------
+// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register --------
+// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register --------
+#define AT91C_SPI_CPOL ((unsigned int) 0x1 << 0) // (SPI) Clock Polarity
+#define AT91C_SPI_NCPHA ((unsigned int) 0x1 << 1) // (SPI) Clock Phase
+#define AT91C_SPI_CSAAT ((unsigned int) 0x1 << 3) // (SPI) Chip Select Active After Transfer
+#define AT91C_SPI_BITS ((unsigned int) 0xF << 4) // (SPI) Bits Per Transfer
+#define AT91C_SPI_BITS_8 ((unsigned int) 0x0 << 4) // (SPI) 8 Bits Per transfer
+#define AT91C_SPI_BITS_9 ((unsigned int) 0x1 << 4) // (SPI) 9 Bits Per transfer
+#define AT91C_SPI_BITS_10 ((unsigned int) 0x2 << 4) // (SPI) 10 Bits Per transfer
+#define AT91C_SPI_BITS_11 ((unsigned int) 0x3 << 4) // (SPI) 11 Bits Per transfer
+#define AT91C_SPI_BITS_12 ((unsigned int) 0x4 << 4) // (SPI) 12 Bits Per transfer
+#define AT91C_SPI_BITS_13 ((unsigned int) 0x5 << 4) // (SPI) 13 Bits Per transfer
+#define AT91C_SPI_BITS_14 ((unsigned int) 0x6 << 4) // (SPI) 14 Bits Per transfer
+#define AT91C_SPI_BITS_15 ((unsigned int) 0x7 << 4) // (SPI) 15 Bits Per transfer
+#define AT91C_SPI_BITS_16 ((unsigned int) 0x8 << 4) // (SPI) 16 Bits Per transfer
+#define AT91C_SPI_SCBR ((unsigned int) 0xFF << 8) // (SPI) Serial Clock Baud Rate
+#define AT91C_SPI_DLYBS ((unsigned int) 0xFF << 16) // (SPI) Delay Before SPCK
+#define AT91C_SPI_DLYBCT ((unsigned int) 0xFF << 24) // (SPI) Delay Between Consecutive Transfers
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Analog to Digital Convertor
+// *****************************************************************************
+typedef struct _AT91S_ADC
+{
+ AT91_REG ADC_CR; // ADC Control Register
+ AT91_REG ADC_MR; // ADC Mode Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG ADC_CHER; // ADC Channel Enable Register
+ AT91_REG ADC_CHDR; // ADC Channel Disable Register
+ AT91_REG ADC_CHSR; // ADC Channel Status Register
+ AT91_REG ADC_SR; // ADC Status Register
+ AT91_REG ADC_LCDR; // ADC Last Converted Data Register
+ AT91_REG ADC_IER; // ADC Interrupt Enable Register
+ AT91_REG ADC_IDR; // ADC Interrupt Disable Register
+ AT91_REG ADC_IMR; // ADC Interrupt Mask Register
+ AT91_REG ADC_CDR0; // ADC Channel Data Register 0
+ AT91_REG ADC_CDR1; // ADC Channel Data Register 1
+ AT91_REG ADC_CDR2; // ADC Channel Data Register 2
+ AT91_REG ADC_CDR3; // ADC Channel Data Register 3
+ AT91_REG ADC_CDR4; // ADC Channel Data Register 4
+ AT91_REG ADC_CDR5; // ADC Channel Data Register 5
+ AT91_REG ADC_CDR6; // ADC Channel Data Register 6
+ AT91_REG ADC_CDR7; // ADC Channel Data Register 7
+ AT91_REG Reserved1[44]; //
+ AT91_REG ADC_RPR; // Receive Pointer Register
+ AT91_REG ADC_RCR; // Receive Counter Register
+ AT91_REG ADC_TPR; // Transmit Pointer Register
+ AT91_REG ADC_TCR; // Transmit Counter Register
+ AT91_REG ADC_RNPR; // Receive Next Pointer Register
+ AT91_REG ADC_RNCR; // Receive Next Counter Register
+ AT91_REG ADC_TNPR; // Transmit Next Pointer Register
+ AT91_REG ADC_TNCR; // Transmit Next Counter Register
+ AT91_REG ADC_PTCR; // PDC Transfer Control Register
+ AT91_REG ADC_PTSR; // PDC Transfer Status Register
+} AT91S_ADC, *AT91PS_ADC;
+
+// -------- ADC_CR : (ADC Offset: 0x0) ADC Control Register --------
+#define AT91C_ADC_SWRST ((unsigned int) 0x1 << 0) // (ADC) Software Reset
+#define AT91C_ADC_START ((unsigned int) 0x1 << 1) // (ADC) Start Conversion
+// -------- ADC_MR : (ADC Offset: 0x4) ADC Mode Register --------
+#define AT91C_ADC_TRGEN ((unsigned int) 0x1 << 0) // (ADC) Trigger Enable
+#define AT91C_ADC_TRGEN_DIS ((unsigned int) 0x0) // (ADC) Hradware triggers are disabled. Starting a conversion is only possible by software
+#define AT91C_ADC_TRGEN_EN ((unsigned int) 0x1) // (ADC) Hardware trigger selected by TRGSEL field is enabled.
+#define AT91C_ADC_TRGSEL ((unsigned int) 0x7 << 1) // (ADC) Trigger Selection
+#define AT91C_ADC_TRGSEL_TIOA0 ((unsigned int) 0x0 << 1) // (ADC) Selected TRGSEL = TIAO0
+#define AT91C_ADC_TRGSEL_TIOA1 ((unsigned int) 0x1 << 1) // (ADC) Selected TRGSEL = TIAO1
+#define AT91C_ADC_TRGSEL_TIOA2 ((unsigned int) 0x2 << 1) // (ADC) Selected TRGSEL = TIAO2
+#define AT91C_ADC_TRGSEL_TIOA3 ((unsigned int) 0x3 << 1) // (ADC) Selected TRGSEL = TIAO3
+#define AT91C_ADC_TRGSEL_TIOA4 ((unsigned int) 0x4 << 1) // (ADC) Selected TRGSEL = TIAO4
+#define AT91C_ADC_TRGSEL_TIOA5 ((unsigned int) 0x5 << 1) // (ADC) Selected TRGSEL = TIAO5
+#define AT91C_ADC_TRGSEL_EXT ((unsigned int) 0x6 << 1) // (ADC) Selected TRGSEL = External Trigger
+#define AT91C_ADC_LOWRES ((unsigned int) 0x1 << 4) // (ADC) Resolution.
+#define AT91C_ADC_LOWRES_10_BIT ((unsigned int) 0x0 << 4) // (ADC) 10-bit resolution
+#define AT91C_ADC_LOWRES_8_BIT ((unsigned int) 0x1 << 4) // (ADC) 8-bit resolution
+#define AT91C_ADC_SLEEP ((unsigned int) 0x1 << 5) // (ADC) Sleep Mode
+#define AT91C_ADC_SLEEP_NORMAL_MODE ((unsigned int) 0x0 << 5) // (ADC) Normal Mode
+#define AT91C_ADC_SLEEP_MODE ((unsigned int) 0x1 << 5) // (ADC) Sleep Mode
+#define AT91C_ADC_PRESCAL ((unsigned int) 0x3F << 8) // (ADC) Prescaler rate selection
+#define AT91C_ADC_STARTUP ((unsigned int) 0x1F << 16) // (ADC) Startup Time
+#define AT91C_ADC_SHTIM ((unsigned int) 0xF << 24) // (ADC) Sample & Hold Time
+// -------- ADC_CHER : (ADC Offset: 0x10) ADC Channel Enable Register --------
+#define AT91C_ADC_CH0 ((unsigned int) 0x1 << 0) // (ADC) Channel 0
+#define AT91C_ADC_CH1 ((unsigned int) 0x1 << 1) // (ADC) Channel 1
+#define AT91C_ADC_CH2 ((unsigned int) 0x1 << 2) // (ADC) Channel 2
+#define AT91C_ADC_CH3 ((unsigned int) 0x1 << 3) // (ADC) Channel 3
+#define AT91C_ADC_CH4 ((unsigned int) 0x1 << 4) // (ADC) Channel 4
+#define AT91C_ADC_CH5 ((unsigned int) 0x1 << 5) // (ADC) Channel 5
+#define AT91C_ADC_CH6 ((unsigned int) 0x1 << 6) // (ADC) Channel 6
+#define AT91C_ADC_CH7 ((unsigned int) 0x1 << 7) // (ADC) Channel 7
+// -------- ADC_CHDR : (ADC Offset: 0x14) ADC Channel Disable Register --------
+// -------- ADC_CHSR : (ADC Offset: 0x18) ADC Channel Status Register --------
+// -------- ADC_SR : (ADC Offset: 0x1c) ADC Status Register --------
+#define AT91C_ADC_EOC0 ((unsigned int) 0x1 << 0) // (ADC) End of Conversion
+#define AT91C_ADC_EOC1 ((unsigned int) 0x1 << 1) // (ADC) End of Conversion
+#define AT91C_ADC_EOC2 ((unsigned int) 0x1 << 2) // (ADC) End of Conversion
+#define AT91C_ADC_EOC3 ((unsigned int) 0x1 << 3) // (ADC) End of Conversion
+#define AT91C_ADC_EOC4 ((unsigned int) 0x1 << 4) // (ADC) End of Conversion
+#define AT91C_ADC_EOC5 ((unsigned int) 0x1 << 5) // (ADC) End of Conversion
+#define AT91C_ADC_EOC6 ((unsigned int) 0x1 << 6) // (ADC) End of Conversion
+#define AT91C_ADC_EOC7 ((unsigned int) 0x1 << 7) // (ADC) End of Conversion
+#define AT91C_ADC_OVRE0 ((unsigned int) 0x1 << 8) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE1 ((unsigned int) 0x1 << 9) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE2 ((unsigned int) 0x1 << 10) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE3 ((unsigned int) 0x1 << 11) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE4 ((unsigned int) 0x1 << 12) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE5 ((unsigned int) 0x1 << 13) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE6 ((unsigned int) 0x1 << 14) // (ADC) Overrun Error
+#define AT91C_ADC_OVRE7 ((unsigned int) 0x1 << 15) // (ADC) Overrun Error
+#define AT91C_ADC_DRDY ((unsigned int) 0x1 << 16) // (ADC) Data Ready
+#define AT91C_ADC_GOVRE ((unsigned int) 0x1 << 17) // (ADC) General Overrun
+#define AT91C_ADC_ENDRX ((unsigned int) 0x1 << 18) // (ADC) End of Receiver Transfer
+#define AT91C_ADC_RXBUFF ((unsigned int) 0x1 << 19) // (ADC) RXBUFF Interrupt
+// -------- ADC_LCDR : (ADC Offset: 0x20) ADC Last Converted Data Register --------
+#define AT91C_ADC_LDATA ((unsigned int) 0x3FF << 0) // (ADC) Last Data Converted
+// -------- ADC_IER : (ADC Offset: 0x24) ADC Interrupt Enable Register --------
+// -------- ADC_IDR : (ADC Offset: 0x28) ADC Interrupt Disable Register --------
+// -------- ADC_IMR : (ADC Offset: 0x2c) ADC Interrupt Mask Register --------
+// -------- ADC_CDR0 : (ADC Offset: 0x30) ADC Channel Data Register 0 --------
+#define AT91C_ADC_DATA ((unsigned int) 0x3FF << 0) // (ADC) Converted Data
+// -------- ADC_CDR1 : (ADC Offset: 0x34) ADC Channel Data Register 1 --------
+// -------- ADC_CDR2 : (ADC Offset: 0x38) ADC Channel Data Register 2 --------
+// -------- ADC_CDR3 : (ADC Offset: 0x3c) ADC Channel Data Register 3 --------
+// -------- ADC_CDR4 : (ADC Offset: 0x40) ADC Channel Data Register 4 --------
+// -------- ADC_CDR5 : (ADC Offset: 0x44) ADC Channel Data Register 5 --------
+// -------- ADC_CDR6 : (ADC Offset: 0x48) ADC Channel Data Register 6 --------
+// -------- ADC_CDR7 : (ADC Offset: 0x4c) ADC Channel Data Register 7 --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Synchronous Serial Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_SSC
+{
+ AT91_REG SSC_CR; // Control Register
+ AT91_REG SSC_CMR; // Clock Mode Register
+ AT91_REG Reserved0[2]; //
+ AT91_REG SSC_RCMR; // Receive Clock ModeRegister
+ AT91_REG SSC_RFMR; // Receive Frame Mode Register
+ AT91_REG SSC_TCMR; // Transmit Clock Mode Register
+ AT91_REG SSC_TFMR; // Transmit Frame Mode Register
+ AT91_REG SSC_RHR; // Receive Holding Register
+ AT91_REG SSC_THR; // Transmit Holding Register
+ AT91_REG Reserved1[2]; //
+ AT91_REG SSC_RSHR; // Receive Sync Holding Register
+ AT91_REG SSC_TSHR; // Transmit Sync Holding Register
+ AT91_REG SSC_RC0R; // Receive Compare 0 Register
+ AT91_REG SSC_RC1R; // Receive Compare 1 Register
+ AT91_REG SSC_SR; // Status Register
+ AT91_REG SSC_IER; // Interrupt Enable Register
+ AT91_REG SSC_IDR; // Interrupt Disable Register
+ AT91_REG SSC_IMR; // Interrupt Mask Register
+ AT91_REG Reserved3[44]; //
+ AT91_REG SSC_RPR; // Receive Pointer Register
+ AT91_REG SSC_RCR; // Receive Counter Register
+ AT91_REG SSC_TPR; // Transmit Pointer Register
+ AT91_REG SSC_TCR; // Transmit Counter Register
+ AT91_REG SSC_RNPR; // Receive Next Pointer Register
+ AT91_REG SSC_RNCR; // Receive Next Counter Register
+ AT91_REG SSC_TNPR; // Transmit Next Pointer Register
+ AT91_REG SSC_TNCR; // Transmit Next Counter Register
+ AT91_REG SSC_PTCR; // PDC Transfer Control Register
+ AT91_REG SSC_PTSR; // PDC Transfer Status Register
+} AT91S_SSC, *AT91PS_SSC;
+
+// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register --------
+#define AT91C_SSC_RXEN ((unsigned int) 0x1 << 0) // (SSC) Receive Enable
+#define AT91C_SSC_RXDIS ((unsigned int) 0x1 << 1) // (SSC) Receive Disable
+#define AT91C_SSC_TXEN ((unsigned int) 0x1 << 8) // (SSC) Transmit Enable
+#define AT91C_SSC_TXDIS ((unsigned int) 0x1 << 9) // (SSC) Transmit Disable
+#define AT91C_SSC_SWRST ((unsigned int) 0x1 << 15) // (SSC) Software Reset
+// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register --------
+#define AT91C_SSC_CKS ((unsigned int) 0x3 << 0) // (SSC) Receive/Transmit Clock Selection
+#define AT91C_SSC_CKS_DIV ((unsigned int) 0x0) // (SSC) Divided Clock
+#define AT91C_SSC_CKS_TK ((unsigned int) 0x1) // (SSC) TK Clock signal
+#define AT91C_SSC_CKS_RK ((unsigned int) 0x2) // (SSC) RK pin
+#define AT91C_SSC_CKO ((unsigned int) 0x7 << 2) // (SSC) Receive/Transmit Clock Output Mode Selection
+#define AT91C_SSC_CKO_NONE ((unsigned int) 0x0 << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only
+#define AT91C_SSC_CKO_CONTINOUS ((unsigned int) 0x1 << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output
+#define AT91C_SSC_CKO_DATA_TX ((unsigned int) 0x2 << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output
+#define AT91C_SSC_CKI ((unsigned int) 0x1 << 5) // (SSC) Receive/Transmit Clock Inversion
+#define AT91C_SSC_START ((unsigned int) 0xF << 8) // (SSC) Receive/Transmit Start Selection
+#define AT91C_SSC_START_CONTINOUS ((unsigned int) 0x0 << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data.
+#define AT91C_SSC_START_TX ((unsigned int) 0x1 << 8) // (SSC) Transmit/Receive start
+#define AT91C_SSC_START_LOW_RF ((unsigned int) 0x2 << 8) // (SSC) Detection of a low level on RF input
+#define AT91C_SSC_START_HIGH_RF ((unsigned int) 0x3 << 8) // (SSC) Detection of a high level on RF input
+#define AT91C_SSC_START_FALL_RF ((unsigned int) 0x4 << 8) // (SSC) Detection of a falling edge on RF input
+#define AT91C_SSC_START_RISE_RF ((unsigned int) 0x5 << 8) // (SSC) Detection of a rising edge on RF input
+#define AT91C_SSC_START_LEVEL_RF ((unsigned int) 0x6 << 8) // (SSC) Detection of any level change on RF input
+#define AT91C_SSC_START_EDGE_RF ((unsigned int) 0x7 << 8) // (SSC) Detection of any edge on RF input
+#define AT91C_SSC_START_0 ((unsigned int) 0x8 << 8) // (SSC) Compare 0
+#define AT91C_SSC_STTDLY ((unsigned int) 0xFF << 16) // (SSC) Receive/Transmit Start Delay
+#define AT91C_SSC_PERIOD ((unsigned int) 0xFF << 24) // (SSC) Receive/Transmit Period Divider Selection
+// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register --------
+#define AT91C_SSC_DATLEN ((unsigned int) 0x1F << 0) // (SSC) Data Length
+#define AT91C_SSC_LOOP ((unsigned int) 0x1 << 5) // (SSC) Loop Mode
+#define AT91C_SSC_MSBF ((unsigned int) 0x1 << 7) // (SSC) Most Significant Bit First
+#define AT91C_SSC_DATNB ((unsigned int) 0xF << 8) // (SSC) Data Number per Frame
+#define AT91C_SSC_FSLEN ((unsigned int) 0xF << 16) // (SSC) Receive/Transmit Frame Sync length
+#define AT91C_SSC_FSOS ((unsigned int) 0x7 << 20) // (SSC) Receive/Transmit Frame Sync Output Selection
+#define AT91C_SSC_FSOS_NONE ((unsigned int) 0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only
+#define AT91C_SSC_FSOS_NEGATIVE ((unsigned int) 0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse
+#define AT91C_SSC_FSOS_POSITIVE ((unsigned int) 0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse
+#define AT91C_SSC_FSOS_LOW ((unsigned int) 0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer
+#define AT91C_SSC_FSOS_HIGH ((unsigned int) 0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer
+#define AT91C_SSC_FSOS_TOGGLE ((unsigned int) 0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer
+#define AT91C_SSC_FSEDGE ((unsigned int) 0x1 << 24) // (SSC) Frame Sync Edge Detection
+// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register --------
+// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register --------
+#define AT91C_SSC_DATDEF ((unsigned int) 0x1 << 5) // (SSC) Data Default Value
+#define AT91C_SSC_MSBF ((unsigned int) 0x1 << 7) // (SSC) MSB First
+#define AT91C_SSC_FSDEN ((unsigned int) 0x1 << 23) // (SSC) Frame Sync Data Enable
+// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register --------
+#define AT91C_SSC_TXRDY ((unsigned int) 0x1 << 0) // (SSC) Transmit Ready
+#define AT91C_SSC_TXEMPTY ((unsigned int) 0x1 << 1) // (SSC) Transmit Empty
+#define AT91C_SSC_ENDTX ((unsigned int) 0x1 << 2) // (SSC) End Of Transmission
+#define AT91C_SSC_TXBUFE ((unsigned int) 0x1 << 3) // (SSC) Transmit Buffer Empty
+#define AT91C_SSC_RXRDY ((unsigned int) 0x1 << 4) // (SSC) Receive Ready
+#define AT91C_SSC_OVRUN ((unsigned int) 0x1 << 5) // (SSC) Receive Overrun
+#define AT91C_SSC_ENDRX ((unsigned int) 0x1 << 6) // (SSC) End of Reception
+#define AT91C_SSC_RXBUFF ((unsigned int) 0x1 << 7) // (SSC) Receive Buffer Full
+#define AT91C_SSC_CP0 ((unsigned int) 0x1 << 8) // (SSC) Compare 0
+#define AT91C_SSC_CP1 ((unsigned int) 0x1 << 9) // (SSC) Compare 1
+#define AT91C_SSC_TXSYN ((unsigned int) 0x1 << 10) // (SSC) Transmit Sync
+#define AT91C_SSC_RXSYN ((unsigned int) 0x1 << 11) // (SSC) Receive Sync
+#define AT91C_SSC_TXENA ((unsigned int) 0x1 << 16) // (SSC) Transmit Enable
+#define AT91C_SSC_RXENA ((unsigned int) 0x1 << 17) // (SSC) Receive Enable
+// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register --------
+// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register --------
+// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Usart
+// *****************************************************************************
+typedef struct _AT91S_USART
+{
+ AT91_REG US_CR; // Control Register
+ AT91_REG US_MR; // Mode Register
+ AT91_REG US_IER; // Interrupt Enable Register
+ AT91_REG US_IDR; // Interrupt Disable Register
+ AT91_REG US_IMR; // Interrupt Mask Register
+ AT91_REG US_CSR; // Channel Status Register
+ AT91_REG US_RHR; // Receiver Holding Register
+ AT91_REG US_THR; // Transmitter Holding Register
+ AT91_REG US_BRGR; // Baud Rate Generator Register
+ AT91_REG US_RTOR; // Receiver Time-out Register
+ AT91_REG US_TTGR; // Transmitter Time-guard Register
+ AT91_REG Reserved0[5]; //
+ AT91_REG US_FIDI; // FI_DI_Ratio Register
+ AT91_REG US_NER; // Nb Errors Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG US_IF; // IRDA_FILTER Register
+ AT91_REG Reserved2[44]; //
+ AT91_REG US_RPR; // Receive Pointer Register
+ AT91_REG US_RCR; // Receive Counter Register
+ AT91_REG US_TPR; // Transmit Pointer Register
+ AT91_REG US_TCR; // Transmit Counter Register
+ AT91_REG US_RNPR; // Receive Next Pointer Register
+ AT91_REG US_RNCR; // Receive Next Counter Register
+ AT91_REG US_TNPR; // Transmit Next Pointer Register
+ AT91_REG US_TNCR; // Transmit Next Counter Register
+ AT91_REG US_PTCR; // PDC Transfer Control Register
+ AT91_REG US_PTSR; // PDC Transfer Status Register
+} AT91S_USART, *AT91PS_USART;
+
+// -------- US_CR : (USART Offset: 0x0) Debug Unit Control Register --------
+#define AT91C_US_STTBRK ((unsigned int) 0x1 << 9) // (USART) Start Break
+#define AT91C_US_STPBRK ((unsigned int) 0x1 << 10) // (USART) Stop Break
+#define AT91C_US_STTTO ((unsigned int) 0x1 << 11) // (USART) Start Time-out
+#define AT91C_US_SENDA ((unsigned int) 0x1 << 12) // (USART) Send Address
+#define AT91C_US_RSTIT ((unsigned int) 0x1 << 13) // (USART) Reset Iterations
+#define AT91C_US_RSTNACK ((unsigned int) 0x1 << 14) // (USART) Reset Non Acknowledge
+#define AT91C_US_RETTO ((unsigned int) 0x1 << 15) // (USART) Rearm Time-out
+#define AT91C_US_DTREN ((unsigned int) 0x1 << 16) // (USART) Data Terminal ready Enable
+#define AT91C_US_DTRDIS ((unsigned int) 0x1 << 17) // (USART) Data Terminal ready Disable
+#define AT91C_US_RTSEN ((unsigned int) 0x1 << 18) // (USART) Request to Send enable
+#define AT91C_US_RTSDIS ((unsigned int) 0x1 << 19) // (USART) Request to Send Disable
+// -------- US_MR : (USART Offset: 0x4) Debug Unit Mode Register --------
+#define AT91C_US_USMODE ((unsigned int) 0xF << 0) // (USART) Usart mode
+#define AT91C_US_USMODE_NORMAL ((unsigned int) 0x0) // (USART) Normal
+#define AT91C_US_USMODE_RS485 ((unsigned int) 0x1) // (USART) RS485
+#define AT91C_US_USMODE_HWHSH ((unsigned int) 0x2) // (USART) Hardware Handshaking
+#define AT91C_US_USMODE_MODEM ((unsigned int) 0x3) // (USART) Modem
+#define AT91C_US_USMODE_ISO7816_0 ((unsigned int) 0x4) // (USART) ISO7816 protocol: T = 0
+#define AT91C_US_USMODE_ISO7816_1 ((unsigned int) 0x6) // (USART) ISO7816 protocol: T = 1
+#define AT91C_US_USMODE_IRDA ((unsigned int) 0x8) // (USART) IrDA
+#define AT91C_US_USMODE_SWHSH ((unsigned int) 0xC) // (USART) Software Handshaking
+#define AT91C_US_CLKS ((unsigned int) 0x3 << 4) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define AT91C_US_CLKS_CLOCK ((unsigned int) 0x0 << 4) // (USART) Clock
+#define AT91C_US_CLKS_FDIV1 ((unsigned int) 0x1 << 4) // (USART) fdiv1
+#define AT91C_US_CLKS_SLOW ((unsigned int) 0x2 << 4) // (USART) slow_clock (ARM)
+#define AT91C_US_CLKS_EXT ((unsigned int) 0x3 << 4) // (USART) External (SCK)
+#define AT91C_US_CHRL ((unsigned int) 0x3 << 6) // (USART) Clock Selection (Baud Rate generator Input Clock
+#define AT91C_US_CHRL_5_BITS ((unsigned int) 0x0 << 6) // (USART) Character Length: 5 bits
+#define AT91C_US_CHRL_6_BITS ((unsigned int) 0x1 << 6) // (USART) Character Length: 6 bits
+#define AT91C_US_CHRL_7_BITS ((unsigned int) 0x2 << 6) // (USART) Character Length: 7 bits
+#define AT91C_US_CHRL_8_BITS ((unsigned int) 0x3 << 6) // (USART) Character Length: 8 bits
+#define AT91C_US_SYNC ((unsigned int) 0x1 << 8) // (USART) Synchronous Mode Select
+#define AT91C_US_NBSTOP ((unsigned int) 0x3 << 12) // (USART) Number of Stop bits
+#define AT91C_US_NBSTOP_1_BIT ((unsigned int) 0x0 << 12) // (USART) 1 stop bit
+#define AT91C_US_NBSTOP_15_BIT ((unsigned int) 0x1 << 12) // (USART) Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits
+#define AT91C_US_NBSTOP_2_BIT ((unsigned int) 0x2 << 12) // (USART) 2 stop bits
+#define AT91C_US_MSBF ((unsigned int) 0x1 << 16) // (USART) Bit Order
+#define AT91C_US_MODE9 ((unsigned int) 0x1 << 17) // (USART) 9-bit Character length
+#define AT91C_US_CKLO ((unsigned int) 0x1 << 18) // (USART) Clock Output Select
+#define AT91C_US_OVER ((unsigned int) 0x1 << 19) // (USART) Over Sampling Mode
+#define AT91C_US_INACK ((unsigned int) 0x1 << 20) // (USART) Inhibit Non Acknowledge
+#define AT91C_US_DSNACK ((unsigned int) 0x1 << 21) // (USART) Disable Successive NACK
+#define AT91C_US_MAX_ITER ((unsigned int) 0x1 << 24) // (USART) Number of Repetitions
+#define AT91C_US_FILTER ((unsigned int) 0x1 << 28) // (USART) Receive Line Filter
+// -------- US_IER : (USART Offset: 0x8) Debug Unit Interrupt Enable Register --------
+#define AT91C_US_RXBRK ((unsigned int) 0x1 << 2) // (USART) Break Received/End of Break
+#define AT91C_US_TIMEOUT ((unsigned int) 0x1 << 8) // (USART) Receiver Time-out
+#define AT91C_US_ITERATION ((unsigned int) 0x1 << 10) // (USART) Max number of Repetitions Reached
+#define AT91C_US_NACK ((unsigned int) 0x1 << 13) // (USART) Non Acknowledge
+#define AT91C_US_RIIC ((unsigned int) 0x1 << 16) // (USART) Ring INdicator Input Change Flag
+#define AT91C_US_DSRIC ((unsigned int) 0x1 << 17) // (USART) Data Set Ready Input Change Flag
+#define AT91C_US_DCDIC ((unsigned int) 0x1 << 18) // (USART) Data Carrier Flag
+#define AT91C_US_CTSIC ((unsigned int) 0x1 << 19) // (USART) Clear To Send Input Change Flag
+// -------- US_IDR : (USART Offset: 0xc) Debug Unit Interrupt Disable Register --------
+// -------- US_IMR : (USART Offset: 0x10) Debug Unit Interrupt Mask Register --------
+// -------- US_CSR : (USART Offset: 0x14) Debug Unit Channel Status Register --------
+#define AT91C_US_RI ((unsigned int) 0x1 << 20) // (USART) Image of RI Input
+#define AT91C_US_DSR ((unsigned int) 0x1 << 21) // (USART) Image of DSR Input
+#define AT91C_US_DCD ((unsigned int) 0x1 << 22) // (USART) Image of DCD Input
+#define AT91C_US_CTS ((unsigned int) 0x1 << 23) // (USART) Image of CTS Input
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Two-wire Interface
+// *****************************************************************************
+typedef struct _AT91S_TWI
+{
+ AT91_REG TWI_CR; // Control Register
+ AT91_REG TWI_MMR; // Master Mode Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG TWI_IADR; // Internal Address Register
+ AT91_REG TWI_CWGR; // Clock Waveform Generator Register
+ AT91_REG Reserved1[3]; //
+ AT91_REG TWI_SR; // Status Register
+ AT91_REG TWI_IER; // Interrupt Enable Register
+ AT91_REG TWI_IDR; // Interrupt Disable Register
+ AT91_REG TWI_IMR; // Interrupt Mask Register
+ AT91_REG TWI_RHR; // Receive Holding Register
+ AT91_REG TWI_THR; // Transmit Holding Register
+} AT91S_TWI, *AT91PS_TWI;
+
+// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register --------
+#define AT91C_TWI_START ((unsigned int) 0x1 << 0) // (TWI) Send a START Condition
+#define AT91C_TWI_STOP ((unsigned int) 0x1 << 1) // (TWI) Send a STOP Condition
+#define AT91C_TWI_MSEN ((unsigned int) 0x1 << 2) // (TWI) TWI Master Transfer Enabled
+#define AT91C_TWI_MSDIS ((unsigned int) 0x1 << 3) // (TWI) TWI Master Transfer Disabled
+#define AT91C_TWI_SWRST ((unsigned int) 0x1 << 7) // (TWI) Software Reset
+// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register --------
+#define AT91C_TWI_IADRSZ ((unsigned int) 0x3 << 8) // (TWI) Internal Device Address Size
+#define AT91C_TWI_IADRSZ_NO ((unsigned int) 0x0 << 8) // (TWI) No internal device address
+#define AT91C_TWI_IADRSZ_1_BYTE ((unsigned int) 0x1 << 8) // (TWI) One-byte internal device address
+#define AT91C_TWI_IADRSZ_2_BYTE ((unsigned int) 0x2 << 8) // (TWI) Two-byte internal device address
+#define AT91C_TWI_IADRSZ_3_BYTE ((unsigned int) 0x3 << 8) // (TWI) Three-byte internal device address
+#define AT91C_TWI_MREAD ((unsigned int) 0x1 << 12) // (TWI) Master Read Direction
+#define AT91C_TWI_DADR ((unsigned int) 0x7F << 16) // (TWI) Device Address
+// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator Register --------
+#define AT91C_TWI_CLDIV ((unsigned int) 0xFF << 0) // (TWI) Clock Low Divider
+#define AT91C_TWI_CHDIV ((unsigned int) 0xFF << 8) // (TWI) Clock High Divider
+#define AT91C_TWI_CKDIV ((unsigned int) 0x7 << 16) // (TWI) Clock Divider
+// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register --------
+#define AT91C_TWI_TXCOMP ((unsigned int) 0x1 << 0) // (TWI) Transmission Completed
+#define AT91C_TWI_RXRDY ((unsigned int) 0x1 << 1) // (TWI) Receive holding register ReaDY
+#define AT91C_TWI_TXRDY ((unsigned int) 0x1 << 2) // (TWI) Transmit holding register ReaDY
+#define AT91C_TWI_OVRE ((unsigned int) 0x1 << 6) // (TWI) Overrun Error
+#define AT91C_TWI_UNRE ((unsigned int) 0x1 << 7) // (TWI) Underrun Error
+#define AT91C_TWI_NACK ((unsigned int) 0x1 << 8) // (TWI) Not Acknowledged
+// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register --------
+// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register --------
+// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Timer Counter Channel Interface
+// *****************************************************************************
+typedef struct _AT91S_TC
+{
+ AT91_REG TC_CCR; // Channel Control Register
+ AT91_REG TC_CMR; // Channel Mode Register (Capture Mode / Waveform Mode)
+ AT91_REG Reserved0[2]; //
+ AT91_REG TC_CV; // Counter Value
+ AT91_REG TC_RA; // Register A
+ AT91_REG TC_RB; // Register B
+ AT91_REG TC_RC; // Register C
+ AT91_REG TC_SR; // Status Register
+ AT91_REG TC_IER; // Interrupt Enable Register
+ AT91_REG TC_IDR; // Interrupt Disable Register
+ AT91_REG TC_IMR; // Interrupt Mask Register
+} AT91S_TC, *AT91PS_TC;
+
+// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register --------
+#define AT91C_TC_CLKEN ((unsigned int) 0x1 << 0) // (TC) Counter Clock Enable Command
+#define AT91C_TC_CLKDIS ((unsigned int) 0x1 << 1) // (TC) Counter Clock Disable Command
+#define AT91C_TC_SWTRG ((unsigned int) 0x1 << 2) // (TC) Software Trigger Command
+// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode --------
+#define AT91C_TC_CLKS ((unsigned int) 0x7 << 0) // (TC) Clock Selection
+#define AT91C_TC_CLKS_TIMER_DIV1_CLOCK ((unsigned int) 0x0) // (TC) Clock selected: TIMER_DIV1_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV2_CLOCK ((unsigned int) 0x1) // (TC) Clock selected: TIMER_DIV2_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV3_CLOCK ((unsigned int) 0x2) // (TC) Clock selected: TIMER_DIV3_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV4_CLOCK ((unsigned int) 0x3) // (TC) Clock selected: TIMER_DIV4_CLOCK
+#define AT91C_TC_CLKS_TIMER_DIV5_CLOCK ((unsigned int) 0x4) // (TC) Clock selected: TIMER_DIV5_CLOCK
+#define AT91C_TC_CLKS_XC0 ((unsigned int) 0x5) // (TC) Clock selected: XC0
+#define AT91C_TC_CLKS_XC1 ((unsigned int) 0x6) // (TC) Clock selected: XC1
+#define AT91C_TC_CLKS_XC2 ((unsigned int) 0x7) // (TC) Clock selected: XC2
+#define AT91C_TC_CLKI ((unsigned int) 0x1 << 3) // (TC) Clock Invert
+#define AT91C_TC_BURST ((unsigned int) 0x3 << 4) // (TC) Burst Signal Selection
+#define AT91C_TC_BURST_NONE ((unsigned int) 0x0 << 4) // (TC) The clock is not gated by an external signal
+#define AT91C_TC_BURST_XC0 ((unsigned int) 0x1 << 4) // (TC) XC0 is ANDed with the selected clock
+#define AT91C_TC_BURST_XC1 ((unsigned int) 0x2 << 4) // (TC) XC1 is ANDed with the selected clock
+#define AT91C_TC_BURST_XC2 ((unsigned int) 0x3 << 4) // (TC) XC2 is ANDed with the selected clock
+#define AT91C_TC_CPCSTOP ((unsigned int) 0x1 << 6) // (TC) Counter Clock Stopped with RC Compare
+#define AT91C_TC_LDBSTOP ((unsigned int) 0x1 << 6) // (TC) Counter Clock Stopped with RB Loading
+#define AT91C_TC_CPCDIS ((unsigned int) 0x1 << 7) // (TC) Counter Clock Disable with RC Compare
+#define AT91C_TC_LDBDIS ((unsigned int) 0x1 << 7) // (TC) Counter Clock Disabled with RB Loading
+#define AT91C_TC_ETRGEDG ((unsigned int) 0x3 << 8) // (TC) External Trigger Edge Selection
+#define AT91C_TC_ETRGEDG_NONE ((unsigned int) 0x0 << 8) // (TC) Edge: None
+#define AT91C_TC_ETRGEDG_RISING ((unsigned int) 0x1 << 8) // (TC) Edge: rising edge
+#define AT91C_TC_ETRGEDG_FALLING ((unsigned int) 0x2 << 8) // (TC) Edge: falling edge
+#define AT91C_TC_ETRGEDG_BOTH ((unsigned int) 0x3 << 8) // (TC) Edge: each edge
+#define AT91C_TC_EEVTEDG ((unsigned int) 0x3 << 8) // (TC) External Event Edge Selection
+#define AT91C_TC_EEVTEDG_NONE ((unsigned int) 0x0 << 8) // (TC) Edge: None
+#define AT91C_TC_EEVTEDG_RISING ((unsigned int) 0x1 << 8) // (TC) Edge: rising edge
+#define AT91C_TC_EEVTEDG_FALLING ((unsigned int) 0x2 << 8) // (TC) Edge: falling edge
+#define AT91C_TC_EEVTEDG_BOTH ((unsigned int) 0x3 << 8) // (TC) Edge: each edge
+#define AT91C_TC_EEVT ((unsigned int) 0x3 << 10) // (TC) External Event Selection
+#define AT91C_TC_EEVT_TIOB ((unsigned int) 0x0 << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input
+#define AT91C_TC_EEVT_XC0 ((unsigned int) 0x1 << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output
+#define AT91C_TC_EEVT_XC1 ((unsigned int) 0x2 << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output
+#define AT91C_TC_EEVT_XC2 ((unsigned int) 0x3 << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output
+#define AT91C_TC_ABETRG ((unsigned int) 0x1 << 10) // (TC) TIOA or TIOB External Trigger Selection
+#define AT91C_TC_ENETRG ((unsigned int) 0x1 << 12) // (TC) External Event Trigger enable
+#define AT91C_TC_WAVESEL ((unsigned int) 0x3 << 13) // (TC) Waveform Selection
+#define AT91C_TC_WAVESEL_UP ((unsigned int) 0x0 << 13) // (TC) UP mode without atomatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UPDOWN ((unsigned int) 0x1 << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UP_AUTO ((unsigned int) 0x2 << 13) // (TC) UP mode with automatic trigger on RC Compare
+#define AT91C_TC_WAVESEL_UPDOWN_AUTO ((unsigned int) 0x3 << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare
+#define AT91C_TC_CPCTRG ((unsigned int) 0x1 << 14) // (TC) RC Compare Trigger Enable
+#define AT91C_TC_WAVE ((unsigned int) 0x1 << 15) // (TC)
+#define AT91C_TC_ACPA ((unsigned int) 0x3 << 16) // (TC) RA Compare Effect on TIOA
+#define AT91C_TC_ACPA_NONE ((unsigned int) 0x0 << 16) // (TC) Effect: none
+#define AT91C_TC_ACPA_SET ((unsigned int) 0x1 << 16) // (TC) Effect: set
+#define AT91C_TC_ACPA_CLEAR ((unsigned int) 0x2 << 16) // (TC) Effect: clear
+#define AT91C_TC_ACPA_TOGGLE ((unsigned int) 0x3 << 16) // (TC) Effect: toggle
+#define AT91C_TC_LDRA ((unsigned int) 0x3 << 16) // (TC) RA Loading Selection
+#define AT91C_TC_LDRA_NONE ((unsigned int) 0x0 << 16) // (TC) Edge: None
+#define AT91C_TC_LDRA_RISING ((unsigned int) 0x1 << 16) // (TC) Edge: rising edge of TIOA
+#define AT91C_TC_LDRA_FALLING ((unsigned int) 0x2 << 16) // (TC) Edge: falling edge of TIOA
+#define AT91C_TC_LDRA_BOTH ((unsigned int) 0x3 << 16) // (TC) Edge: each edge of TIOA
+#define AT91C_TC_ACPC ((unsigned int) 0x3 << 18) // (TC) RC Compare Effect on TIOA
+#define AT91C_TC_ACPC_NONE ((unsigned int) 0x0 << 18) // (TC) Effect: none
+#define AT91C_TC_ACPC_SET ((unsigned int) 0x1 << 18) // (TC) Effect: set
+#define AT91C_TC_ACPC_CLEAR ((unsigned int) 0x2 << 18) // (TC) Effect: clear
+#define AT91C_TC_ACPC_TOGGLE ((unsigned int) 0x3 << 18) // (TC) Effect: toggle
+#define AT91C_TC_LDRB ((unsigned int) 0x3 << 18) // (TC) RB Loading Selection
+#define AT91C_TC_LDRB_NONE ((unsigned int) 0x0 << 18) // (TC) Edge: None
+#define AT91C_TC_LDRB_RISING ((unsigned int) 0x1 << 18) // (TC) Edge: rising edge of TIOA
+#define AT91C_TC_LDRB_FALLING ((unsigned int) 0x2 << 18) // (TC) Edge: falling edge of TIOA
+#define AT91C_TC_LDRB_BOTH ((unsigned int) 0x3 << 18) // (TC) Edge: each edge of TIOA
+#define AT91C_TC_AEEVT ((unsigned int) 0x3 << 20) // (TC) External Event Effect on TIOA
+#define AT91C_TC_AEEVT_NONE ((unsigned int) 0x0 << 20) // (TC) Effect: none
+#define AT91C_TC_AEEVT_SET ((unsigned int) 0x1 << 20) // (TC) Effect: set
+#define AT91C_TC_AEEVT_CLEAR ((unsigned int) 0x2 << 20) // (TC) Effect: clear
+#define AT91C_TC_AEEVT_TOGGLE ((unsigned int) 0x3 << 20) // (TC) Effect: toggle
+#define AT91C_TC_ASWTRG ((unsigned int) 0x3 << 22) // (TC) Software Trigger Effect on TIOA
+#define AT91C_TC_ASWTRG_NONE ((unsigned int) 0x0 << 22) // (TC) Effect: none
+#define AT91C_TC_ASWTRG_SET ((unsigned int) 0x1 << 22) // (TC) Effect: set
+#define AT91C_TC_ASWTRG_CLEAR ((unsigned int) 0x2 << 22) // (TC) Effect: clear
+#define AT91C_TC_ASWTRG_TOGGLE ((unsigned int) 0x3 << 22) // (TC) Effect: toggle
+#define AT91C_TC_BCPB ((unsigned int) 0x3 << 24) // (TC) RB Compare Effect on TIOB
+#define AT91C_TC_BCPB_NONE ((unsigned int) 0x0 << 24) // (TC) Effect: none
+#define AT91C_TC_BCPB_SET ((unsigned int) 0x1 << 24) // (TC) Effect: set
+#define AT91C_TC_BCPB_CLEAR ((unsigned int) 0x2 << 24) // (TC) Effect: clear
+#define AT91C_TC_BCPB_TOGGLE ((unsigned int) 0x3 << 24) // (TC) Effect: toggle
+#define AT91C_TC_BCPC ((unsigned int) 0x3 << 26) // (TC) RC Compare Effect on TIOB
+#define AT91C_TC_BCPC_NONE ((unsigned int) 0x0 << 26) // (TC) Effect: none
+#define AT91C_TC_BCPC_SET ((unsigned int) 0x1 << 26) // (TC) Effect: set
+#define AT91C_TC_BCPC_CLEAR ((unsigned int) 0x2 << 26) // (TC) Effect: clear
+#define AT91C_TC_BCPC_TOGGLE ((unsigned int) 0x3 << 26) // (TC) Effect: toggle
+#define AT91C_TC_BEEVT ((unsigned int) 0x3 << 28) // (TC) External Event Effect on TIOB
+#define AT91C_TC_BEEVT_NONE ((unsigned int) 0x0 << 28) // (TC) Effect: none
+#define AT91C_TC_BEEVT_SET ((unsigned int) 0x1 << 28) // (TC) Effect: set
+#define AT91C_TC_BEEVT_CLEAR ((unsigned int) 0x2 << 28) // (TC) Effect: clear
+#define AT91C_TC_BEEVT_TOGGLE ((unsigned int) 0x3 << 28) // (TC) Effect: toggle
+#define AT91C_TC_BSWTRG ((unsigned int) 0x3 << 30) // (TC) Software Trigger Effect on TIOB
+#define AT91C_TC_BSWTRG_NONE ((unsigned int) 0x0 << 30) // (TC) Effect: none
+#define AT91C_TC_BSWTRG_SET ((unsigned int) 0x1 << 30) // (TC) Effect: set
+#define AT91C_TC_BSWTRG_CLEAR ((unsigned int) 0x2 << 30) // (TC) Effect: clear
+#define AT91C_TC_BSWTRG_TOGGLE ((unsigned int) 0x3 << 30) // (TC) Effect: toggle
+// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register --------
+#define AT91C_TC_COVFS ((unsigned int) 0x1 << 0) // (TC) Counter Overflow
+#define AT91C_TC_LOVRS ((unsigned int) 0x1 << 1) // (TC) Load Overrun
+#define AT91C_TC_CPAS ((unsigned int) 0x1 << 2) // (TC) RA Compare
+#define AT91C_TC_CPBS ((unsigned int) 0x1 << 3) // (TC) RB Compare
+#define AT91C_TC_CPCS ((unsigned int) 0x1 << 4) // (TC) RC Compare
+#define AT91C_TC_LDRAS ((unsigned int) 0x1 << 5) // (TC) RA Loading
+#define AT91C_TC_LDRBS ((unsigned int) 0x1 << 6) // (TC) RB Loading
+#define AT91C_TC_ETRGS ((unsigned int) 0x1 << 7) // (TC) External Trigger
+#define AT91C_TC_CLKSTA ((unsigned int) 0x1 << 16) // (TC) Clock Enabling
+#define AT91C_TC_MTIOA ((unsigned int) 0x1 << 17) // (TC) TIOA Mirror
+#define AT91C_TC_MTIOB ((unsigned int) 0x1 << 18) // (TC) TIOA Mirror
+// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register --------
+// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register --------
+// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Timer Counter Interface
+// *****************************************************************************
+typedef struct _AT91S_TCB
+{
+ AT91S_TC TCB_TC0; // TC Channel 0
+ AT91_REG Reserved0[4]; //
+ AT91S_TC TCB_TC1; // TC Channel 1
+ AT91_REG Reserved1[4]; //
+ AT91S_TC TCB_TC2; // TC Channel 2
+ AT91_REG Reserved2[4]; //
+ AT91_REG TCB_BCR; // TC Block Control Register
+ AT91_REG TCB_BMR; // TC Block Mode Register
+} AT91S_TCB, *AT91PS_TCB;
+
+// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register --------
+#define AT91C_TCB_SYNC ((unsigned int) 0x1 << 0) // (TCB) Synchro Command
+// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register --------
+#define AT91C_TCB_TC0XC0S ((unsigned int) 0x3 << 0) // (TCB) External Clock Signal 0 Selection
+#define AT91C_TCB_TC0XC0S_TCLK0 ((unsigned int) 0x0) // (TCB) TCLK0 connected to XC0
+#define AT91C_TCB_TC0XC0S_NONE ((unsigned int) 0x1) // (TCB) None signal connected to XC0
+#define AT91C_TCB_TC0XC0S_TIOA1 ((unsigned int) 0x2) // (TCB) TIOA1 connected to XC0
+#define AT91C_TCB_TC0XC0S_TIOA2 ((unsigned int) 0x3) // (TCB) TIOA2 connected to XC0
+#define AT91C_TCB_TC1XC1S ((unsigned int) 0x3 << 2) // (TCB) External Clock Signal 1 Selection
+#define AT91C_TCB_TC1XC1S_TCLK1 ((unsigned int) 0x0 << 2) // (TCB) TCLK1 connected to XC1
+#define AT91C_TCB_TC1XC1S_NONE ((unsigned int) 0x1 << 2) // (TCB) None signal connected to XC1
+#define AT91C_TCB_TC1XC1S_TIOA0 ((unsigned int) 0x2 << 2) // (TCB) TIOA0 connected to XC1
+#define AT91C_TCB_TC1XC1S_TIOA2 ((unsigned int) 0x3 << 2) // (TCB) TIOA2 connected to XC1
+#define AT91C_TCB_TC2XC2S ((unsigned int) 0x3 << 4) // (TCB) External Clock Signal 2 Selection
+#define AT91C_TCB_TC2XC2S_TCLK2 ((unsigned int) 0x0 << 4) // (TCB) TCLK2 connected to XC2
+#define AT91C_TCB_TC2XC2S_NONE ((unsigned int) 0x1 << 4) // (TCB) None signal connected to XC2
+#define AT91C_TCB_TC2XC2S_TIOA0 ((unsigned int) 0x2 << 4) // (TCB) TIOA0 connected to XC2
+#define AT91C_TCB_TC2XC2S_TIOA1 ((unsigned int) 0x3 << 4) // (TCB) TIOA2 connected to XC2
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR PWMC Channel Interface
+// *****************************************************************************
+typedef struct _AT91S_PWMC_CH
+{
+ AT91_REG PWMC_CMR; // Channel Mode Register
+ AT91_REG PWMC_CDTYR; // Channel Duty Cycle Register
+ AT91_REG PWMC_CPRDR; // Channel Period Register
+ AT91_REG PWMC_CCNTR; // Channel Counter Register
+ AT91_REG PWMC_CUPDR; // Channel Update Register
+ AT91_REG PWMC_Reserved[3]; // Reserved
+} AT91S_PWMC_CH, *AT91PS_PWMC_CH;
+
+// -------- PWMC_CMR : (PWMC_CH Offset: 0x0) PWMC Channel Mode Register --------
+#define AT91C_PWMC_CPRE ((unsigned int) 0xF << 0) // (PWMC_CH) Channel Pre-scaler : PWMC_CLKx
+#define AT91C_PWMC_CPRE_MCK ((unsigned int) 0x0) // (PWMC_CH)
+#define AT91C_PWMC_CPRE_MCKA ((unsigned int) 0xB) // (PWMC_CH)
+#define AT91C_PWMC_CPRE_MCKB ((unsigned int) 0xC) // (PWMC_CH)
+#define AT91C_PWMC_CALG ((unsigned int) 0x1 << 8) // (PWMC_CH) Channel Alignment
+#define AT91C_PWMC_CPOL ((unsigned int) 0x1 << 9) // (PWMC_CH) Channel Polarity
+#define AT91C_PWMC_CPD ((unsigned int) 0x1 << 10) // (PWMC_CH) Channel Update Period
+// -------- PWMC_CDTYR : (PWMC_CH Offset: 0x4) PWMC Channel Duty Cycle Register --------
+#define AT91C_PWMC_CDTY ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Duty Cycle
+// -------- PWMC_CPRDR : (PWMC_CH Offset: 0x8) PWMC Channel Period Register --------
+#define AT91C_PWMC_CPRD ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Period
+// -------- PWMC_CCNTR : (PWMC_CH Offset: 0xc) PWMC Channel Counter Register --------
+#define AT91C_PWMC_CCNT ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Counter
+// -------- PWMC_CUPDR : (PWMC_CH Offset: 0x10) PWMC Channel Update Register --------
+#define AT91C_PWMC_CUPD ((unsigned int) 0x0 << 0) // (PWMC_CH) Channel Update
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR Pulse Width Modulation Controller Interface
+// *****************************************************************************
+typedef struct _AT91S_PWMC
+{
+ AT91_REG PWMC_MR; // PWMC Mode Register
+ AT91_REG PWMC_ENA; // PWMC Enable Register
+ AT91_REG PWMC_DIS; // PWMC Disable Register
+ AT91_REG PWMC_SR; // PWMC Status Register
+ AT91_REG PWMC_IER; // PWMC Interrupt Enable Register
+ AT91_REG PWMC_IDR; // PWMC Interrupt Disable Register
+ AT91_REG PWMC_IMR; // PWMC Interrupt Mask Register
+ AT91_REG PWMC_ISR; // PWMC Interrupt Status Register
+ AT91_REG Reserved0[55]; //
+ AT91_REG PWMC_VR; // PWMC Version Register
+ AT91_REG Reserved1[64]; //
+ AT91S_PWMC_CH PWMC_CH[4]; // PWMC Channel
+} AT91S_PWMC, *AT91PS_PWMC;
+
+// -------- PWMC_MR : (PWMC Offset: 0x0) PWMC Mode Register --------
+#define AT91C_PWMC_DIVA ((unsigned int) 0xFF << 0) // (PWMC) CLKA divide factor.
+#define AT91C_PWMC_PREA ((unsigned int) 0xF << 8) // (PWMC) Divider Input Clock Prescaler A
+#define AT91C_PWMC_PREA_MCK ((unsigned int) 0x0 << 8) // (PWMC)
+#define AT91C_PWMC_DIVB ((unsigned int) 0xFF << 16) // (PWMC) CLKB divide factor.
+#define AT91C_PWMC_PREB ((unsigned int) 0xF << 24) // (PWMC) Divider Input Clock Prescaler B
+#define AT91C_PWMC_PREB_MCK ((unsigned int) 0x0 << 24) // (PWMC)
+// -------- PWMC_ENA : (PWMC Offset: 0x4) PWMC Enable Register --------
+#define AT91C_PWMC_CHID0 ((unsigned int) 0x1 << 0) // (PWMC) Channel ID 0
+#define AT91C_PWMC_CHID1 ((unsigned int) 0x1 << 1) // (PWMC) Channel ID 1
+#define AT91C_PWMC_CHID2 ((unsigned int) 0x1 << 2) // (PWMC) Channel ID 2
+#define AT91C_PWMC_CHID3 ((unsigned int) 0x1 << 3) // (PWMC) Channel ID 3
+// -------- PWMC_DIS : (PWMC Offset: 0x8) PWMC Disable Register --------
+// -------- PWMC_SR : (PWMC Offset: 0xc) PWMC Status Register --------
+// -------- PWMC_IER : (PWMC Offset: 0x10) PWMC Interrupt Enable Register --------
+// -------- PWMC_IDR : (PWMC Offset: 0x14) PWMC Interrupt Disable Register --------
+// -------- PWMC_IMR : (PWMC Offset: 0x18) PWMC Interrupt Mask Register --------
+// -------- PWMC_ISR : (PWMC Offset: 0x1c) PWMC Interrupt Status Register --------
+
+// *****************************************************************************
+// SOFTWARE API DEFINITION FOR USB Device Interface
+// *****************************************************************************
+typedef struct _AT91S_UDP
+{
+ AT91_REG UDP_NUM; // Frame Number Register
+ AT91_REG UDP_GLBSTATE; // Global State Register
+ AT91_REG UDP_FADDR; // Function Address Register
+ AT91_REG Reserved0[1]; //
+ AT91_REG UDP_IER; // Interrupt Enable Register
+ AT91_REG UDP_IDR; // Interrupt Disable Register
+ AT91_REG UDP_IMR; // Interrupt Mask Register
+ AT91_REG UDP_ISR; // Interrupt Status Register
+ AT91_REG UDP_ICR; // Interrupt Clear Register
+ AT91_REG Reserved1[1]; //
+ AT91_REG UDP_RSTEP; // Reset Endpoint Register
+ AT91_REG Reserved2[1]; //
+ AT91_REG UDP_CSR[4]; // Endpoint Control and Status Register
+ AT91_REG Reserved3[4]; //
+ AT91_REG UDP_FDR[4]; // Endpoint FIFO Data Register
+ AT91_REG Reserved4[5]; //
+ AT91_REG UDP_TXVC; // Transceiver Control Register
+} AT91S_UDP, *AT91PS_UDP;
+
+// -------- UDP_FRM_NUM : (UDP Offset: 0x0) USB Frame Number Register --------
+#define AT91C_UDP_FRM_NUM ((unsigned int) 0x7FF << 0) // (UDP) Frame Number as Defined in the Packet Field Formats
+#define AT91C_UDP_FRM_ERR ((unsigned int) 0x1 << 16) // (UDP) Frame Error
+#define AT91C_UDP_FRM_OK ((unsigned int) 0x1 << 17) // (UDP) Frame OK
+// -------- UDP_GLB_STATE : (UDP Offset: 0x4) USB Global State Register --------
+#define AT91C_UDP_FADDEN ((unsigned int) 0x1 << 0) // (UDP) Function Address Enable
+#define AT91C_UDP_CONFG ((unsigned int) 0x1 << 1) // (UDP) Configured
+#define AT91C_UDP_ESR ((unsigned int) 0x1 << 2) // (UDP) Enable Send Resume
+#define AT91C_UDP_RSMINPR ((unsigned int) 0x1 << 3) // (UDP) A Resume Has Been Sent to the Host
+#define AT91C_UDP_RMWUPE ((unsigned int) 0x1 << 4) // (UDP) Remote Wake Up Enable
+// -------- UDP_FADDR : (UDP Offset: 0x8) USB Function Address Register --------
+#define AT91C_UDP_FADD ((unsigned int) 0xFF << 0) // (UDP) Function Address Value
+#define AT91C_UDP_FEN ((unsigned int) 0x1 << 8) // (UDP) Function Enable
+// -------- UDP_IER : (UDP Offset: 0x10) USB Interrupt Enable Register --------
+#define AT91C_UDP_EPINT0 ((unsigned int) 0x1 << 0) // (UDP) Endpoint 0 Interrupt
+#define AT91C_UDP_EPINT1 ((unsigned int) 0x1 << 1) // (UDP) Endpoint 1 Interrupt
+#define AT91C_UDP_EPINT2 ((unsigned int) 0x1 << 2) // (UDP) Endpoint 2 Interrupt
+#define AT91C_UDP_EPINT3 ((unsigned int) 0x1 << 3) // (UDP) Endpoint 3 Interrupt
+#define AT91C_UDP_RXSUSP ((unsigned int) 0x1 << 8) // (UDP) USB Suspend Interrupt
+#define AT91C_UDP_RXRSM ((unsigned int) 0x1 << 9) // (UDP) USB Resume Interrupt
+#define AT91C_UDP_EXTRSM ((unsigned int) 0x1 << 10) // (UDP) USB External Resume Interrupt
+#define AT91C_UDP_SOFINT ((unsigned int) 0x1 << 11) // (UDP) USB Start Of frame Interrupt
+#define AT91C_UDP_WAKEUP ((unsigned int) 0x1 << 13) // (UDP) USB Resume Interrupt
+// -------- UDP_IDR : (UDP Offset: 0x14) USB Interrupt Disable Register --------
+// -------- UDP_IMR : (UDP Offset: 0x18) USB Interrupt Mask Register --------
+// -------- UDP_ISR : (UDP Offset: 0x1c) USB Interrupt Status Register --------
+#define AT91C_UDP_ENDBUSRES ((unsigned int) 0x1 << 12) // (UDP) USB End Of Bus Reset Interrupt
+// -------- UDP_ICR : (UDP Offset: 0x20) USB Interrupt Clear Register --------
+// -------- UDP_RST_EP : (UDP Offset: 0x28) USB Reset Endpoint Register --------
+#define AT91C_UDP_EP0 ((unsigned int) 0x1 << 0) // (UDP) Reset Endpoint 0
+#define AT91C_UDP_EP1 ((unsigned int) 0x1 << 1) // (UDP) Reset Endpoint 1
+#define AT91C_UDP_EP2 ((unsigned int) 0x1 << 2) // (UDP) Reset Endpoint 2
+#define AT91C_UDP_EP3 ((unsigned int) 0x1 << 3) // (UDP) Reset Endpoint 3
+// -------- UDP_CSR : (UDP Offset: 0x30) USB Endpoint Control and Status Register --------
+#define AT91C_UDP_TXCOMP ((unsigned int) 0x1 << 0) // (UDP) Generates an IN packet with data previously written in the DPR
+#define AT91C_UDP_RX_DATA_BK0 ((unsigned int) 0x1 << 1) // (UDP) Receive Data Bank 0
+#define AT91C_UDP_RXSETUP ((unsigned int) 0x1 << 2) // (UDP) Sends STALL to the Host (Control endpoints)
+#define AT91C_UDP_ISOERROR ((unsigned int) 0x1 << 3) // (UDP) Isochronous error (Isochronous endpoints)
+#define AT91C_UDP_STALLSENT ((unsigned int) 0x1 << 3) // (UDP) Stall Sent (Control endpoints)
+#define AT91C_UDP_TXPKTRDY ((unsigned int) 0x1 << 4) // (UDP) Transmit Packet Ready
+#define AT91C_UDP_FORCESTALL ((unsigned int) 0x1 << 5) // (UDP) Force Stall (used by Control, Bulk and Isochronous endpoints).
+#define AT91C_UDP_RX_DATA_BK1 ((unsigned int) 0x1 << 6) // (UDP) Receive Data Bank 1 (only used by endpoints with ping-pong attributes).
+#define AT91C_UDP_DIR ((unsigned int) 0x1 << 7) // (UDP) Transfer Direction
+#define AT91C_UDP_EPTYPE ((unsigned int) 0x7 << 8) // (UDP) Endpoint type
+#define AT91C_UDP_EPTYPE_CTRL ((unsigned int) 0x0 << 8) // (UDP) Control
+#define AT91C_UDP_EPTYPE_ISO_OUT ((unsigned int) 0x1 << 8) // (UDP) Isochronous OUT
+#define AT91C_UDP_EPTYPE_BULK_OUT ((unsigned int) 0x2 << 8) // (UDP) Bulk OUT
+#define AT91C_UDP_EPTYPE_INT_OUT ((unsigned int) 0x3 << 8) // (UDP) Interrupt OUT
+#define AT91C_UDP_EPTYPE_ISO_IN ((unsigned int) 0x5 << 8) // (UDP) Isochronous IN
+#define AT91C_UDP_EPTYPE_BULK_IN ((unsigned int) 0x6 << 8) // (UDP) Bulk IN
+#define AT91C_UDP_EPTYPE_INT_IN ((unsigned int) 0x7 << 8) // (UDP) Interrupt IN
+#define AT91C_UDP_DTGLE ((unsigned int) 0x1 << 11) // (UDP) Data Toggle
+#define AT91C_UDP_EPEDS ((unsigned int) 0x1 << 15) // (UDP) Endpoint Enable Disable
+#define AT91C_UDP_RXBYTECNT ((unsigned int) 0x7FF << 16) // (UDP) Number Of Bytes Available in the FIFO
+// -------- UDP_TXVC : (UDP Offset: 0x74) Transceiver Control Register --------
+#define AT91C_UDP_TXVDIS ((unsigned int) 0x1 << 8) // (UDP)
+
+// *****************************************************************************
+// REGISTER ADDRESS DEFINITION FOR AT91SAM7S64
+// *****************************************************************************
+// ========== Register definition for SYS peripheral ==========
+// ========== Register definition for AIC peripheral ==========
+#define AT91C_AIC_IVR ((AT91_REG *) 0xFFFFF100) // (AIC) IRQ Vector Register
+#define AT91C_AIC_SMR ((AT91_REG *) 0xFFFFF000) // (AIC) Source Mode Register
+#define AT91C_AIC_FVR ((AT91_REG *) 0xFFFFF104) // (AIC) FIQ Vector Register
+#define AT91C_AIC_DCR ((AT91_REG *) 0xFFFFF138) // (AIC) Debug Control Register (Protect)
+#define AT91C_AIC_EOICR ((AT91_REG *) 0xFFFFF130) // (AIC) End of Interrupt Command Register
+#define AT91C_AIC_SVR ((AT91_REG *) 0xFFFFF080) // (AIC) Source Vector Register
+#define AT91C_AIC_FFSR ((AT91_REG *) 0xFFFFF148) // (AIC) Fast Forcing Status Register
+#define AT91C_AIC_ICCR ((AT91_REG *) 0xFFFFF128) // (AIC) Interrupt Clear Command Register
+#define AT91C_AIC_ISR ((AT91_REG *) 0xFFFFF108) // (AIC) Interrupt Status Register
+#define AT91C_AIC_IMR ((AT91_REG *) 0xFFFFF110) // (AIC) Interrupt Mask Register
+#define AT91C_AIC_IPR ((AT91_REG *) 0xFFFFF10C) // (AIC) Interrupt Pending Register
+#define AT91C_AIC_FFER ((AT91_REG *) 0xFFFFF140) // (AIC) Fast Forcing Enable Register
+#define AT91C_AIC_IECR ((AT91_REG *) 0xFFFFF120) // (AIC) Interrupt Enable Command Register
+#define AT91C_AIC_ISCR ((AT91_REG *) 0xFFFFF12C) // (AIC) Interrupt Set Command Register
+#define AT91C_AIC_FFDR ((AT91_REG *) 0xFFFFF144) // (AIC) Fast Forcing Disable Register
+#define AT91C_AIC_CISR ((AT91_REG *) 0xFFFFF114) // (AIC) Core Interrupt Status Register
+#define AT91C_AIC_IDCR ((AT91_REG *) 0xFFFFF124) // (AIC) Interrupt Disable Command Register
+#define AT91C_AIC_SPU ((AT91_REG *) 0xFFFFF134) // (AIC) Spurious Vector Register
+// ========== Register definition for PDC_DBGU peripheral ==========
+#define AT91C_DBGU_TCR ((AT91_REG *) 0xFFFFF30C) // (PDC_DBGU) Transmit Counter Register
+#define AT91C_DBGU_RNPR ((AT91_REG *) 0xFFFFF310) // (PDC_DBGU) Receive Next Pointer Register
+#define AT91C_DBGU_TNPR ((AT91_REG *) 0xFFFFF318) // (PDC_DBGU) Transmit Next Pointer Register
+#define AT91C_DBGU_TPR ((AT91_REG *) 0xFFFFF308) // (PDC_DBGU) Transmit Pointer Register
+#define AT91C_DBGU_RPR ((AT91_REG *) 0xFFFFF300) // (PDC_DBGU) Receive Pointer Register
+#define AT91C_DBGU_RCR ((AT91_REG *) 0xFFFFF304) // (PDC_DBGU) Receive Counter Register
+#define AT91C_DBGU_RNCR ((AT91_REG *) 0xFFFFF314) // (PDC_DBGU) Receive Next Counter Register
+#define AT91C_DBGU_PTCR ((AT91_REG *) 0xFFFFF320) // (PDC_DBGU) PDC Transfer Control Register
+#define AT91C_DBGU_PTSR ((AT91_REG *) 0xFFFFF324) // (PDC_DBGU) PDC Transfer Status Register
+#define AT91C_DBGU_TNCR ((AT91_REG *) 0xFFFFF31C) // (PDC_DBGU) Transmit Next Counter Register
+// ========== Register definition for DBGU peripheral ==========
+#define AT91C_DBGU_EXID ((AT91_REG *) 0xFFFFF244) // (DBGU) Chip ID Extension Register
+#define AT91C_DBGU_BRGR ((AT91_REG *) 0xFFFFF220) // (DBGU) Baud Rate Generator Register
+#define AT91C_DBGU_IDR ((AT91_REG *) 0xFFFFF20C) // (DBGU) Interrupt Disable Register
+#define AT91C_DBGU_CSR ((AT91_REG *) 0xFFFFF214) // (DBGU) Channel Status Register
+#define AT91C_DBGU_CIDR ((AT91_REG *) 0xFFFFF240) // (DBGU) Chip ID Register
+#define AT91C_DBGU_MR ((AT91_REG *) 0xFFFFF204) // (DBGU) Mode Register
+#define AT91C_DBGU_IMR ((AT91_REG *) 0xFFFFF210) // (DBGU) Interrupt Mask Register
+#define AT91C_DBGU_CR ((AT91_REG *) 0xFFFFF200) // (DBGU) Control Register
+#define AT91C_DBGU_FNTR ((AT91_REG *) 0xFFFFF248) // (DBGU) Force NTRST Register
+#define AT91C_DBGU_THR ((AT91_REG *) 0xFFFFF21C) // (DBGU) Transmitter Holding Register
+#define AT91C_DBGU_RHR ((AT91_REG *) 0xFFFFF218) // (DBGU) Receiver Holding Register
+#define AT91C_DBGU_IER ((AT91_REG *) 0xFFFFF208) // (DBGU) Interrupt Enable Register
+// ========== Register definition for PIOA peripheral ==========
+#define AT91C_PIOA_ODR ((AT91_REG *) 0xFFFFF414) // (PIOA) Output Disable Registerr
+#define AT91C_PIOA_SODR ((AT91_REG *) 0xFFFFF430) // (PIOA) Set Output Data Register
+#define AT91C_PIOA_ISR ((AT91_REG *) 0xFFFFF44C) // (PIOA) Interrupt Status Register
+#define AT91C_PIOA_ABSR ((AT91_REG *) 0xFFFFF478) // (PIOA) AB Select Status Register
+#define AT91C_PIOA_IER ((AT91_REG *) 0xFFFFF440) // (PIOA) Interrupt Enable Register
+#define AT91C_PIOA_PPUDR ((AT91_REG *) 0xFFFFF460) // (PIOA) Pull-up Disable Register
+#define AT91C_PIOA_IMR ((AT91_REG *) 0xFFFFF448) // (PIOA) Interrupt Mask Register
+#define AT91C_PIOA_PER ((AT91_REG *) 0xFFFFF400) // (PIOA) PIO Enable Register
+#define AT91C_PIOA_IFDR ((AT91_REG *) 0xFFFFF424) // (PIOA) Input Filter Disable Register
+#define AT91C_PIOA_OWDR ((AT91_REG *) 0xFFFFF4A4) // (PIOA) Output Write Disable Register
+#define AT91C_PIOA_MDSR ((AT91_REG *) 0xFFFFF458) // (PIOA) Multi-driver Status Register
+#define AT91C_PIOA_IDR ((AT91_REG *) 0xFFFFF444) // (PIOA) Interrupt Disable Register
+#define AT91C_PIOA_ODSR ((AT91_REG *) 0xFFFFF438) // (PIOA) Output Data Status Register
+#define AT91C_PIOA_PPUSR ((AT91_REG *) 0xFFFFF468) // (PIOA) Pull-up Status Register
+#define AT91C_PIOA_OWSR ((AT91_REG *) 0xFFFFF4A8) // (PIOA) Output Write Status Register
+#define AT91C_PIOA_BSR ((AT91_REG *) 0xFFFFF474) // (PIOA) Select B Register
+#define AT91C_PIOA_OWER ((AT91_REG *) 0xFFFFF4A0) // (PIOA) Output Write Enable Register
+#define AT91C_PIOA_IFER ((AT91_REG *) 0xFFFFF420) // (PIOA) Input Filter Enable Register
+#define AT91C_PIOA_PDSR ((AT91_REG *) 0xFFFFF43C) // (PIOA) Pin Data Status Register
+#define AT91C_PIOA_PPUER ((AT91_REG *) 0xFFFFF464) // (PIOA) Pull-up Enable Register
+#define AT91C_PIOA_OSR ((AT91_REG *) 0xFFFFF418) // (PIOA) Output Status Register
+#define AT91C_PIOA_ASR ((AT91_REG *) 0xFFFFF470) // (PIOA) Select A Register
+#define AT91C_PIOA_MDDR ((AT91_REG *) 0xFFFFF454) // (PIOA) Multi-driver Disable Register
+#define AT91C_PIOA_CODR ((AT91_REG *) 0xFFFFF434) // (PIOA) Clear Output Data Register
+#define AT91C_PIOA_MDER ((AT91_REG *) 0xFFFFF450) // (PIOA) Multi-driver Enable Register
+#define AT91C_PIOA_PDR ((AT91_REG *) 0xFFFFF404) // (PIOA) PIO Disable Register
+#define AT91C_PIOA_IFSR ((AT91_REG *) 0xFFFFF428) // (PIOA) Input Filter Status Register
+#define AT91C_PIOA_OER ((AT91_REG *) 0xFFFFF410) // (PIOA) Output Enable Register
+#define AT91C_PIOA_PSR ((AT91_REG *) 0xFFFFF408) // (PIOA) PIO Status Register
+// ========== Register definition for CKGR peripheral ==========
+#define AT91C_CKGR_MOR ((AT91_REG *) 0xFFFFFC20) // (CKGR) Main Oscillator Register
+#define AT91C_CKGR_PLLR ((AT91_REG *) 0xFFFFFC2C) // (CKGR) PLL Register
+#define AT91C_CKGR_MCFR ((AT91_REG *) 0xFFFFFC24) // (CKGR) Main Clock Frequency Register
+// ========== Register definition for PMC peripheral ==========
+#define AT91C_PMC_IDR ((AT91_REG *) 0xFFFFFC64) // (PMC) Interrupt Disable Register
+#define AT91C_PMC_MOR ((AT91_REG *) 0xFFFFFC20) // (PMC) Main Oscillator Register
+#define AT91C_PMC_PLLR ((AT91_REG *) 0xFFFFFC2C) // (PMC) PLL Register
+#define AT91C_PMC_PCER ((AT91_REG *) 0xFFFFFC10) // (PMC) Peripheral Clock Enable Register
+#define AT91C_PMC_PCKR ((AT91_REG *) 0xFFFFFC40) // (PMC) Programmable Clock Register
+#define AT91C_PMC_MCKR ((AT91_REG *) 0xFFFFFC30) // (PMC) Master Clock Register
+#define AT91C_PMC_SCDR ((AT91_REG *) 0xFFFFFC04) // (PMC) System Clock Disable Register
+#define AT91C_PMC_PCDR ((AT91_REG *) 0xFFFFFC14) // (PMC) Peripheral Clock Disable Register
+#define AT91C_PMC_SCSR ((AT91_REG *) 0xFFFFFC08) // (PMC) System Clock Status Register
+#define AT91C_PMC_PCSR ((AT91_REG *) 0xFFFFFC18) // (PMC) Peripheral Clock Status Register
+#define AT91C_PMC_MCFR ((AT91_REG *) 0xFFFFFC24) // (PMC) Main Clock Frequency Register
+#define AT91C_PMC_SCER ((AT91_REG *) 0xFFFFFC00) // (PMC) System Clock Enable Register
+#define AT91C_PMC_IMR ((AT91_REG *) 0xFFFFFC6C) // (PMC) Interrupt Mask Register
+#define AT91C_PMC_IER ((AT91_REG *) 0xFFFFFC60) // (PMC) Interrupt Enable Register
+#define AT91C_PMC_SR ((AT91_REG *) 0xFFFFFC68) // (PMC) Status Register
+// ========== Register definition for RSTC peripheral ==========
+#define AT91C_RSTC_RCR ((AT91_REG *) 0xFFFFFD00) // (RSTC) Reset Control Register
+#define AT91C_RSTC_RMR ((AT91_REG *) 0xFFFFFD08) // (RSTC) Reset Mode Register
+#define AT91C_RSTC_RSR ((AT91_REG *) 0xFFFFFD04) // (RSTC) Reset Status Register
+// ========== Register definition for RTTC peripheral ==========
+#define AT91C_RTTC_RTSR ((AT91_REG *) 0xFFFFFD2C) // (RTTC) Real-time Status Register
+#define AT91C_RTTC_RTMR ((AT91_REG *) 0xFFFFFD20) // (RTTC) Real-time Mode Register
+#define AT91C_RTTC_RTVR ((AT91_REG *) 0xFFFFFD28) // (RTTC) Real-time Value Register
+#define AT91C_RTTC_RTAR ((AT91_REG *) 0xFFFFFD24) // (RTTC) Real-time Alarm Register
+// ========== Register definition for PITC peripheral ==========
+#define AT91C_PITC_PIVR ((AT91_REG *) 0xFFFFFD38) // (PITC) Period Interval Value Register
+#define AT91C_PITC_PISR ((AT91_REG *) 0xFFFFFD34) // (PITC) Period Interval Status Register
+#define AT91C_PITC_PIIR ((AT91_REG *) 0xFFFFFD3C) // (PITC) Period Interval Image Register
+#define AT91C_PITC_PIMR ((AT91_REG *) 0xFFFFFD30) // (PITC) Period Interval Mode Register
+// ========== Register definition for WDTC peripheral ==========
+#define AT91C_WDTC_WDCR ((AT91_REG *) 0xFFFFFD40) // (WDTC) Watchdog Control Register
+#define AT91C_WDTC_WDSR ((AT91_REG *) 0xFFFFFD48) // (WDTC) Watchdog Status Register
+#define AT91C_WDTC_WDMR ((AT91_REG *) 0xFFFFFD44) // (WDTC) Watchdog Mode Register
+// ========== Register definition for VREG peripheral ==========
+#define AT91C_VREG_MR ((AT91_REG *) 0xFFFFFD60) // (VREG) Voltage Regulator Mode Register
+// ========== Register definition for MC peripheral ==========
+#define AT91C_MC_ASR ((AT91_REG *) 0xFFFFFF04) // (MC) MC Abort Status Register
+#define AT91C_MC_RCR ((AT91_REG *) 0xFFFFFF00) // (MC) MC Remap Control Register
+#define AT91C_MC_FCR ((AT91_REG *) 0xFFFFFF64) // (MC) MC Flash Command Register
+#define AT91C_MC_AASR ((AT91_REG *) 0xFFFFFF08) // (MC) MC Abort Address Status Register
+#define AT91C_MC_FSR ((AT91_REG *) 0xFFFFFF68) // (MC) MC Flash Status Register
+#define AT91C_MC_FMR ((AT91_REG *) 0xFFFFFF60) // (MC) MC Flash Mode Register
+// ========== Register definition for PDC_SPI peripheral ==========
+#define AT91C_SPI_PTCR ((AT91_REG *) 0xFFFE0120) // (PDC_SPI) PDC Transfer Control Register
+#define AT91C_SPI_TPR ((AT91_REG *) 0xFFFE0108) // (PDC_SPI) Transmit Pointer Register
+#define AT91C_SPI_TCR ((AT91_REG *) 0xFFFE010C) // (PDC_SPI) Transmit Counter Register
+#define AT91C_SPI_RCR ((AT91_REG *) 0xFFFE0104) // (PDC_SPI) Receive Counter Register
+#define AT91C_SPI_PTSR ((AT91_REG *) 0xFFFE0124) // (PDC_SPI) PDC Transfer Status Register
+#define AT91C_SPI_RNPR ((AT91_REG *) 0xFFFE0110) // (PDC_SPI) Receive Next Pointer Register
+#define AT91C_SPI_RPR ((AT91_REG *) 0xFFFE0100) // (PDC_SPI) Receive Pointer Register
+#define AT91C_SPI_TNCR ((AT91_REG *) 0xFFFE011C) // (PDC_SPI) Transmit Next Counter Register
+#define AT91C_SPI_RNCR ((AT91_REG *) 0xFFFE0114) // (PDC_SPI) Receive Next Counter Register
+#define AT91C_SPI_TNPR ((AT91_REG *) 0xFFFE0118) // (PDC_SPI) Transmit Next Pointer Register
+// ========== Register definition for SPI peripheral ==========
+#define AT91C_SPI_IER ((AT91_REG *) 0xFFFE0014) // (SPI) Interrupt Enable Register
+#define AT91C_SPI_SR ((AT91_REG *) 0xFFFE0010) // (SPI) Status Register
+#define AT91C_SPI_IDR ((AT91_REG *) 0xFFFE0018) // (SPI) Interrupt Disable Register
+#define AT91C_SPI_CR ((AT91_REG *) 0xFFFE0000) // (SPI) Control Register
+#define AT91C_SPI_MR ((AT91_REG *) 0xFFFE0004) // (SPI) Mode Register
+#define AT91C_SPI_IMR ((AT91_REG *) 0xFFFE001C) // (SPI) Interrupt Mask Register
+#define AT91C_SPI_TDR ((AT91_REG *) 0xFFFE000C) // (SPI) Transmit Data Register
+#define AT91C_SPI_RDR ((AT91_REG *) 0xFFFE0008) // (SPI) Receive Data Register
+#define AT91C_SPI_CSR ((AT91_REG *) 0xFFFE0030) // (SPI) Chip Select Register
+// ========== Register definition for PDC_ADC peripheral ==========
+#define AT91C_ADC_PTSR ((AT91_REG *) 0xFFFD8124) // (PDC_ADC) PDC Transfer Status Register
+#define AT91C_ADC_PTCR ((AT91_REG *) 0xFFFD8120) // (PDC_ADC) PDC Transfer Control Register
+#define AT91C_ADC_TNPR ((AT91_REG *) 0xFFFD8118) // (PDC_ADC) Transmit Next Pointer Register
+#define AT91C_ADC_TNCR ((AT91_REG *) 0xFFFD811C) // (PDC_ADC) Transmit Next Counter Register
+#define AT91C_ADC_RNPR ((AT91_REG *) 0xFFFD8110) // (PDC_ADC) Receive Next Pointer Register
+#define AT91C_ADC_RNCR ((AT91_REG *) 0xFFFD8114) // (PDC_ADC) Receive Next Counter Register
+#define AT91C_ADC_RPR ((AT91_REG *) 0xFFFD8100) // (PDC_ADC) Receive Pointer Register
+#define AT91C_ADC_TCR ((AT91_REG *) 0xFFFD810C) // (PDC_ADC) Transmit Counter Register
+#define AT91C_ADC_TPR ((AT91_REG *) 0xFFFD8108) // (PDC_ADC) Transmit Pointer Register
+#define AT91C_ADC_RCR ((AT91_REG *) 0xFFFD8104) // (PDC_ADC) Receive Counter Register
+// ========== Register definition for ADC peripheral ==========
+#define AT91C_ADC_CDR2 ((AT91_REG *) 0xFFFD8038) // (ADC) ADC Channel Data Register 2
+#define AT91C_ADC_CDR3 ((AT91_REG *) 0xFFFD803C) // (ADC) ADC Channel Data Register 3
+#define AT91C_ADC_CDR0 ((AT91_REG *) 0xFFFD8030) // (ADC) ADC Channel Data Register 0
+#define AT91C_ADC_CDR5 ((AT91_REG *) 0xFFFD8044) // (ADC) ADC Channel Data Register 5
+#define AT91C_ADC_CHDR ((AT91_REG *) 0xFFFD8014) // (ADC) ADC Channel Disable Register
+#define AT91C_ADC_SR ((AT91_REG *) 0xFFFD801C) // (ADC) ADC Status Register
+#define AT91C_ADC_CDR4 ((AT91_REG *) 0xFFFD8040) // (ADC) ADC Channel Data Register 4
+#define AT91C_ADC_CDR1 ((AT91_REG *) 0xFFFD8034) // (ADC) ADC Channel Data Register 1
+#define AT91C_ADC_LCDR ((AT91_REG *) 0xFFFD8020) // (ADC) ADC Last Converted Data Register
+#define AT91C_ADC_IDR ((AT91_REG *) 0xFFFD8028) // (ADC) ADC Interrupt Disable Register
+#define AT91C_ADC_CR ((AT91_REG *) 0xFFFD8000) // (ADC) ADC Control Register
+#define AT91C_ADC_CDR7 ((AT91_REG *) 0xFFFD804C) // (ADC) ADC Channel Data Register 7
+#define AT91C_ADC_CDR6 ((AT91_REG *) 0xFFFD8048) // (ADC) ADC Channel Data Register 6
+#define AT91C_ADC_IER ((AT91_REG *) 0xFFFD8024) // (ADC) ADC Interrupt Enable Register
+#define AT91C_ADC_CHER ((AT91_REG *) 0xFFFD8010) // (ADC) ADC Channel Enable Register
+#define AT91C_ADC_CHSR ((AT91_REG *) 0xFFFD8018) // (ADC) ADC Channel Status Register
+#define AT91C_ADC_MR ((AT91_REG *) 0xFFFD8004) // (ADC) ADC Mode Register
+#define AT91C_ADC_IMR ((AT91_REG *) 0xFFFD802C) // (ADC) ADC Interrupt Mask Register
+// ========== Register definition for PDC_SSC peripheral ==========
+#define AT91C_SSC_TNCR ((AT91_REG *) 0xFFFD411C) // (PDC_SSC) Transmit Next Counter Register
+#define AT91C_SSC_RPR ((AT91_REG *) 0xFFFD4100) // (PDC_SSC) Receive Pointer Register
+#define AT91C_SSC_RNCR ((AT91_REG *) 0xFFFD4114) // (PDC_SSC) Receive Next Counter Register
+#define AT91C_SSC_TPR ((AT91_REG *) 0xFFFD4108) // (PDC_SSC) Transmit Pointer Register
+#define AT91C_SSC_PTCR ((AT91_REG *) 0xFFFD4120) // (PDC_SSC) PDC Transfer Control Register
+#define AT91C_SSC_TCR ((AT91_REG *) 0xFFFD410C) // (PDC_SSC) Transmit Counter Register
+#define AT91C_SSC_RCR ((AT91_REG *) 0xFFFD4104) // (PDC_SSC) Receive Counter Register
+#define AT91C_SSC_RNPR ((AT91_REG *) 0xFFFD4110) // (PDC_SSC) Receive Next Pointer Register
+#define AT91C_SSC_TNPR ((AT91_REG *) 0xFFFD4118) // (PDC_SSC) Transmit Next Pointer Register
+#define AT91C_SSC_PTSR ((AT91_REG *) 0xFFFD4124) // (PDC_SSC) PDC Transfer Status Register
+// ========== Register definition for SSC peripheral ==========
+#define AT91C_SSC_RHR ((AT91_REG *) 0xFFFD4020) // (SSC) Receive Holding Register
+#define AT91C_SSC_RSHR ((AT91_REG *) 0xFFFD4030) // (SSC) Receive Sync Holding Register
+#define AT91C_SSC_TFMR ((AT91_REG *) 0xFFFD401C) // (SSC) Transmit Frame Mode Register
+#define AT91C_SSC_IDR ((AT91_REG *) 0xFFFD4048) // (SSC) Interrupt Disable Register
+#define AT91C_SSC_THR ((AT91_REG *) 0xFFFD4024) // (SSC) Transmit Holding Register
+#define AT91C_SSC_RCMR ((AT91_REG *) 0xFFFD4010) // (SSC) Receive Clock ModeRegister
+#define AT91C_SSC_IER ((AT91_REG *) 0xFFFD4044) // (SSC) Interrupt Enable Register
+#define AT91C_SSC_TSHR ((AT91_REG *) 0xFFFD4034) // (SSC) Transmit Sync Holding Register
+#define AT91C_SSC_SR ((AT91_REG *) 0xFFFD4040) // (SSC) Status Register
+#define AT91C_SSC_CMR ((AT91_REG *) 0xFFFD4004) // (SSC) Clock Mode Register
+#define AT91C_SSC_TCMR ((AT91_REG *) 0xFFFD4018) // (SSC) Transmit Clock Mode Register
+#define AT91C_SSC_CR ((AT91_REG *) 0xFFFD4000) // (SSC) Control Register
+#define AT91C_SSC_IMR ((AT91_REG *) 0xFFFD404C) // (SSC) Interrupt Mask Register
+#define AT91C_SSC_RFMR ((AT91_REG *) 0xFFFD4014) // (SSC) Receive Frame Mode Register
+// ========== Register definition for PDC_US1 peripheral ==========
+#define AT91C_US1_RNCR ((AT91_REG *) 0xFFFC4114) // (PDC_US1) Receive Next Counter Register
+#define AT91C_US1_PTCR ((AT91_REG *) 0xFFFC4120) // (PDC_US1) PDC Transfer Control Register
+#define AT91C_US1_TCR ((AT91_REG *) 0xFFFC410C) // (PDC_US1) Transmit Counter Register
+#define AT91C_US1_PTSR ((AT91_REG *) 0xFFFC4124) // (PDC_US1) PDC Transfer Status Register
+#define AT91C_US1_TNPR ((AT91_REG *) 0xFFFC4118) // (PDC_US1) Transmit Next Pointer Register
+#define AT91C_US1_RCR ((AT91_REG *) 0xFFFC4104) // (PDC_US1) Receive Counter Register
+#define AT91C_US1_RNPR ((AT91_REG *) 0xFFFC4110) // (PDC_US1) Receive Next Pointer Register
+#define AT91C_US1_RPR ((AT91_REG *) 0xFFFC4100) // (PDC_US1) Receive Pointer Register
+#define AT91C_US1_TNCR ((AT91_REG *) 0xFFFC411C) // (PDC_US1) Transmit Next Counter Register
+#define AT91C_US1_TPR ((AT91_REG *) 0xFFFC4108) // (PDC_US1) Transmit Pointer Register
+// ========== Register definition for US1 peripheral ==========
+#define AT91C_US1_IF ((AT91_REG *) 0xFFFC404C) // (US1) IRDA_FILTER Register
+#define AT91C_US1_NER ((AT91_REG *) 0xFFFC4044) // (US1) Nb Errors Register
+#define AT91C_US1_RTOR ((AT91_REG *) 0xFFFC4024) // (US1) Receiver Time-out Register
+#define AT91C_US1_CSR ((AT91_REG *) 0xFFFC4014) // (US1) Channel Status Register
+#define AT91C_US1_IDR ((AT91_REG *) 0xFFFC400C) // (US1) Interrupt Disable Register
+#define AT91C_US1_IER ((AT91_REG *) 0xFFFC4008) // (US1) Interrupt Enable Register
+#define AT91C_US1_THR ((AT91_REG *) 0xFFFC401C) // (US1) Transmitter Holding Register
+#define AT91C_US1_TTGR ((AT91_REG *) 0xFFFC4028) // (US1) Transmitter Time-guard Register
+#define AT91C_US1_RHR ((AT91_REG *) 0xFFFC4018) // (US1) Receiver Holding Register
+#define AT91C_US1_BRGR ((AT91_REG *) 0xFFFC4020) // (US1) Baud Rate Generator Register
+#define AT91C_US1_IMR ((AT91_REG *) 0xFFFC4010) // (US1) Interrupt Mask Register
+#define AT91C_US1_FIDI ((AT91_REG *) 0xFFFC4040) // (US1) FI_DI_Ratio Register
+#define AT91C_US1_CR ((AT91_REG *) 0xFFFC4000) // (US1) Control Register
+#define AT91C_US1_MR ((AT91_REG *) 0xFFFC4004) // (US1) Mode Register
+// ========== Register definition for PDC_US0 peripheral ==========
+#define AT91C_US0_TNPR ((AT91_REG *) 0xFFFC0118) // (PDC_US0) Transmit Next Pointer Register
+#define AT91C_US0_RNPR ((AT91_REG *) 0xFFFC0110) // (PDC_US0) Receive Next Pointer Register
+#define AT91C_US0_TCR ((AT91_REG *) 0xFFFC010C) // (PDC_US0) Transmit Counter Register
+#define AT91C_US0_PTCR ((AT91_REG *) 0xFFFC0120) // (PDC_US0) PDC Transfer Control Register
+#define AT91C_US0_PTSR ((AT91_REG *) 0xFFFC0124) // (PDC_US0) PDC Transfer Status Register
+#define AT91C_US0_TNCR ((AT91_REG *) 0xFFFC011C) // (PDC_US0) Transmit Next Counter Register
+#define AT91C_US0_TPR ((AT91_REG *) 0xFFFC0108) // (PDC_US0) Transmit Pointer Register
+#define AT91C_US0_RCR ((AT91_REG *) 0xFFFC0104) // (PDC_US0) Receive Counter Register
+#define AT91C_US0_RPR ((AT91_REG *) 0xFFFC0100) // (PDC_US0) Receive Pointer Register
+#define AT91C_US0_RNCR ((AT91_REG *) 0xFFFC0114) // (PDC_US0) Receive Next Counter Register
+// ========== Register definition for US0 peripheral ==========
+#define AT91C_US0_BRGR ((AT91_REG *) 0xFFFC0020) // (US0) Baud Rate Generator Register
+#define AT91C_US0_NER ((AT91_REG *) 0xFFFC0044) // (US0) Nb Errors Register
+#define AT91C_US0_CR ((AT91_REG *) 0xFFFC0000) // (US0) Control Register
+#define AT91C_US0_IMR ((AT91_REG *) 0xFFFC0010) // (US0) Interrupt Mask Register
+#define AT91C_US0_FIDI ((AT91_REG *) 0xFFFC0040) // (US0) FI_DI_Ratio Register
+#define AT91C_US0_TTGR ((AT91_REG *) 0xFFFC0028) // (US0) Transmitter Time-guard Register
+#define AT91C_US0_MR ((AT91_REG *) 0xFFFC0004) // (US0) Mode Register
+#define AT91C_US0_RTOR ((AT91_REG *) 0xFFFC0024) // (US0) Receiver Time-out Register
+#define AT91C_US0_CSR ((AT91_REG *) 0xFFFC0014) // (US0) Channel Status Register
+#define AT91C_US0_RHR ((AT91_REG *) 0xFFFC0018) // (US0) Receiver Holding Register
+#define AT91C_US0_IDR ((AT91_REG *) 0xFFFC000C) // (US0) Interrupt Disable Register
+#define AT91C_US0_THR ((AT91_REG *) 0xFFFC001C) // (US0) Transmitter Holding Register
+#define AT91C_US0_IF ((AT91_REG *) 0xFFFC004C) // (US0) IRDA_FILTER Register
+#define AT91C_US0_IER ((AT91_REG *) 0xFFFC0008) // (US0) Interrupt Enable Register
+// ========== Register definition for TWI peripheral ==========
+#define AT91C_TWI_IER ((AT91_REG *) 0xFFFB8024) // (TWI) Interrupt Enable Register
+#define AT91C_TWI_CR ((AT91_REG *) 0xFFFB8000) // (TWI) Control Register
+#define AT91C_TWI_SR ((AT91_REG *) 0xFFFB8020) // (TWI) Status Register
+#define AT91C_TWI_IMR ((AT91_REG *) 0xFFFB802C) // (TWI) Interrupt Mask Register
+#define AT91C_TWI_THR ((AT91_REG *) 0xFFFB8034) // (TWI) Transmit Holding Register
+#define AT91C_TWI_IDR ((AT91_REG *) 0xFFFB8028) // (TWI) Interrupt Disable Register
+#define AT91C_TWI_IADR ((AT91_REG *) 0xFFFB800C) // (TWI) Internal Address Register
+#define AT91C_TWI_MMR ((AT91_REG *) 0xFFFB8004) // (TWI) Master Mode Register
+#define AT91C_TWI_CWGR ((AT91_REG *) 0xFFFB8010) // (TWI) Clock Waveform Generator Register
+#define AT91C_TWI_RHR ((AT91_REG *) 0xFFFB8030) // (TWI) Receive Holding Register
+// ========== Register definition for TC0 peripheral ==========
+#define AT91C_TC0_SR ((AT91_REG *) 0xFFFA0020) // (TC0) Status Register
+#define AT91C_TC0_RC ((AT91_REG *) 0xFFFA001C) // (TC0) Register C
+#define AT91C_TC0_RB ((AT91_REG *) 0xFFFA0018) // (TC0) Register B
+#define AT91C_TC0_CCR ((AT91_REG *) 0xFFFA0000) // (TC0) Channel Control Register
+#define AT91C_TC0_CMR ((AT91_REG *) 0xFFFA0004) // (TC0) Channel Mode Register (Capture Mode / Waveform Mode)
+#define AT91C_TC0_IER ((AT91_REG *) 0xFFFA0024) // (TC0) Interrupt Enable Register
+#define AT91C_TC0_RA ((AT91_REG *) 0xFFFA0014) // (TC0) Register A
+#define AT91C_TC0_IDR ((AT91_REG *) 0xFFFA0028) // (TC0) Interrupt Disable Register
+#define AT91C_TC0_CV ((AT91_REG *) 0xFFFA0010) // (TC0) Counter Value
+#define AT91C_TC0_IMR ((AT91_REG *) 0xFFFA002C) // (TC0) Interrupt Mask Register
+// ========== Register definition for TC1 peripheral ==========
+#define AT91C_TC1_RB ((AT91_REG *) 0xFFFA0058) // (TC1) Register B
+#define AT91C_TC1_CCR ((AT91_REG *) 0xFFFA0040) // (TC1) Channel Control Register
+#define AT91C_TC1_IER ((AT91_REG *) 0xFFFA0064) // (TC1) Interrupt Enable Register
+#define AT91C_TC1_IDR ((AT91_REG *) 0xFFFA0068) // (TC1) Interrupt Disable Register
+#define AT91C_TC1_SR ((AT91_REG *) 0xFFFA0060) // (TC1) Status Register
+#define AT91C_TC1_CMR ((AT91_REG *) 0xFFFA0044) // (TC1) Channel Mode Register (Capture Mode / Waveform Mode)
+#define AT91C_TC1_RA ((AT91_REG *) 0xFFFA0054) // (TC1) Register A
+#define AT91C_TC1_RC ((AT91_REG *) 0xFFFA005C) // (TC1) Register C
+#define AT91C_TC1_IMR ((AT91_REG *) 0xFFFA006C) // (TC1) Interrupt Mask Register
+#define AT91C_TC1_CV ((AT91_REG *) 0xFFFA0050) // (TC1) Counter Value
+// ========== Register definition for TC2 peripheral ==========
+#define AT91C_TC2_CMR ((AT91_REG *) 0xFFFA0084) // (TC2) Channel Mode Register (Capture Mode / Waveform Mode)
+#define AT91C_TC2_CCR ((AT91_REG *) 0xFFFA0080) // (TC2) Channel Control Register
+#define AT91C_TC2_CV ((AT91_REG *) 0xFFFA0090) // (TC2) Counter Value
+#define AT91C_TC2_RA ((AT91_REG *) 0xFFFA0094) // (TC2) Register A
+#define AT91C_TC2_RB ((AT91_REG *) 0xFFFA0098) // (TC2) Register B
+#define AT91C_TC2_IDR ((AT91_REG *) 0xFFFA00A8) // (TC2) Interrupt Disable Register
+#define AT91C_TC2_IMR ((AT91_REG *) 0xFFFA00AC) // (TC2) Interrupt Mask Register
+#define AT91C_TC2_RC ((AT91_REG *) 0xFFFA009C) // (TC2) Register C
+#define AT91C_TC2_IER ((AT91_REG *) 0xFFFA00A4) // (TC2) Interrupt Enable Register
+#define AT91C_TC2_SR ((AT91_REG *) 0xFFFA00A0) // (TC2) Status Register
+// ========== Register definition for TCB peripheral ==========
+#define AT91C_TCB_BMR ((AT91_REG *) 0xFFFA00C4) // (TCB) TC Block Mode Register
+#define AT91C_TCB_BCR ((AT91_REG *) 0xFFFA00C0) // (TCB) TC Block Control Register
+// ========== Register definition for PWMC_CH3 peripheral ==========
+#define AT91C_PWMC_CH3_CUPDR ((AT91_REG *) 0xFFFCC270) // (PWMC_CH3) Channel Update Register
+#define AT91C_PWMC_CH3_Reserved ((AT91_REG *) 0xFFFCC274) // (PWMC_CH3) Reserved
+#define AT91C_PWMC_CH3_CPRDR ((AT91_REG *) 0xFFFCC268) // (PWMC_CH3) Channel Period Register
+#define AT91C_PWMC_CH3_CDTYR ((AT91_REG *) 0xFFFCC264) // (PWMC_CH3) Channel Duty Cycle Register
+#define AT91C_PWMC_CH3_CCNTR ((AT91_REG *) 0xFFFCC26C) // (PWMC_CH3) Channel Counter Register
+#define AT91C_PWMC_CH3_CMR ((AT91_REG *) 0xFFFCC260) // (PWMC_CH3) Channel Mode Register
+// ========== Register definition for PWMC_CH2 peripheral ==========
+#define AT91C_PWMC_CH2_Reserved ((AT91_REG *) 0xFFFCC254) // (PWMC_CH2) Reserved
+#define AT91C_PWMC_CH2_CMR ((AT91_REG *) 0xFFFCC240) // (PWMC_CH2) Channel Mode Register
+#define AT91C_PWMC_CH2_CCNTR ((AT91_REG *) 0xFFFCC24C) // (PWMC_CH2) Channel Counter Register
+#define AT91C_PWMC_CH2_CPRDR ((AT91_REG *) 0xFFFCC248) // (PWMC_CH2) Channel Period Register
+#define AT91C_PWMC_CH2_CUPDR ((AT91_REG *) 0xFFFCC250) // (PWMC_CH2) Channel Update Register
+#define AT91C_PWMC_CH2_CDTYR ((AT91_REG *) 0xFFFCC244) // (PWMC_CH2) Channel Duty Cycle Register
+// ========== Register definition for PWMC_CH1 peripheral ==========
+#define AT91C_PWMC_CH1_Reserved ((AT91_REG *) 0xFFFCC234) // (PWMC_CH1) Reserved
+#define AT91C_PWMC_CH1_CUPDR ((AT91_REG *) 0xFFFCC230) // (PWMC_CH1) Channel Update Register
+#define AT91C_PWMC_CH1_CPRDR ((AT91_REG *) 0xFFFCC228) // (PWMC_CH1) Channel Period Register
+#define AT91C_PWMC_CH1_CCNTR ((AT91_REG *) 0xFFFCC22C) // (PWMC_CH1) Channel Counter Register
+#define AT91C_PWMC_CH1_CDTYR ((AT91_REG *) 0xFFFCC224) // (PWMC_CH1) Channel Duty Cycle Register
+#define AT91C_PWMC_CH1_CMR ((AT91_REG *) 0xFFFCC220) // (PWMC_CH1) Channel Mode Register
+// ========== Register definition for PWMC_CH0 peripheral ==========
+#define AT91C_PWMC_CH0_Reserved ((AT91_REG *) 0xFFFCC214) // (PWMC_CH0) Reserved
+#define AT91C_PWMC_CH0_CPRDR ((AT91_REG *) 0xFFFCC208) // (PWMC_CH0) Channel Period Register
+#define AT91C_PWMC_CH0_CDTYR ((AT91_REG *) 0xFFFCC204) // (PWMC_CH0) Channel Duty Cycle Register
+#define AT91C_PWMC_CH0_CMR ((AT91_REG *) 0xFFFCC200) // (PWMC_CH0) Channel Mode Register
+#define AT91C_PWMC_CH0_CUPDR ((AT91_REG *) 0xFFFCC210) // (PWMC_CH0) Channel Update Register
+#define AT91C_PWMC_CH0_CCNTR ((AT91_REG *) 0xFFFCC20C) // (PWMC_CH0) Channel Counter Register
+// ========== Register definition for PWMC peripheral ==========
+#define AT91C_PWMC_IDR ((AT91_REG *) 0xFFFCC014) // (PWMC) PWMC Interrupt Disable Register
+#define AT91C_PWMC_DIS ((AT91_REG *) 0xFFFCC008) // (PWMC) PWMC Disable Register
+#define AT91C_PWMC_IER ((AT91_REG *) 0xFFFCC010) // (PWMC) PWMC Interrupt Enable Register
+#define AT91C_PWMC_VR ((AT91_REG *) 0xFFFCC0FC) // (PWMC) PWMC Version Register
+#define AT91C_PWMC_ISR ((AT91_REG *) 0xFFFCC01C) // (PWMC) PWMC Interrupt Status Register
+#define AT91C_PWMC_SR ((AT91_REG *) 0xFFFCC00C) // (PWMC) PWMC Status Register
+#define AT91C_PWMC_IMR ((AT91_REG *) 0xFFFCC018) // (PWMC) PWMC Interrupt Mask Register
+#define AT91C_PWMC_MR ((AT91_REG *) 0xFFFCC000) // (PWMC) PWMC Mode Register
+#define AT91C_PWMC_ENA ((AT91_REG *) 0xFFFCC004) // (PWMC) PWMC Enable Register
+// ========== Register definition for UDP peripheral ==========
+#define AT91C_UDP_IMR ((AT91_REG *) 0xFFFB0018) // (UDP) Interrupt Mask Register
+#define AT91C_UDP_FADDR ((AT91_REG *) 0xFFFB0008) // (UDP) Function Address Register
+#define AT91C_UDP_NUM ((AT91_REG *) 0xFFFB0000) // (UDP) Frame Number Register
+#define AT91C_UDP_FDR ((AT91_REG *) 0xFFFB0050) // (UDP) Endpoint FIFO Data Register
+#define AT91C_UDP_ISR ((AT91_REG *) 0xFFFB001C) // (UDP) Interrupt Status Register
+#define AT91C_UDP_CSR ((AT91_REG *) 0xFFFB0030) // (UDP) Endpoint Control and Status Register
+#define AT91C_UDP_IDR ((AT91_REG *) 0xFFFB0014) // (UDP) Interrupt Disable Register
+#define AT91C_UDP_ICR ((AT91_REG *) 0xFFFB0020) // (UDP) Interrupt Clear Register
+#define AT91C_UDP_RSTEP ((AT91_REG *) 0xFFFB0028) // (UDP) Reset Endpoint Register
+#define AT91C_UDP_TXVC ((AT91_REG *) 0xFFFB0074) // (UDP) Transceiver Control Register
+#define AT91C_UDP_GLBSTATE ((AT91_REG *) 0xFFFB0004) // (UDP) Global State Register
+#define AT91C_UDP_IER ((AT91_REG *) 0xFFFB0010) // (UDP) Interrupt Enable Register
+
+// *****************************************************************************
+// PIO DEFINITIONS FOR AT91SAM7S64
+// *****************************************************************************
+#define AT91C_PIO_PA0 ((unsigned int) 1 << 0) // Pin Controlled by PA0
+#define AT91C_PA0_PWM0 ((unsigned int) AT91C_PIO_PA0) // PWM Channel 0
+#define AT91C_PA0_TIOA0 ((unsigned int) AT91C_PIO_PA0) // Timer Counter 0 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA1 ((unsigned int) 1 << 1) // Pin Controlled by PA1
+#define AT91C_PA1_PWM1 ((unsigned int) AT91C_PIO_PA1) // PWM Channel 1
+#define AT91C_PA1_TIOB0 ((unsigned int) AT91C_PIO_PA1) // Timer Counter 0 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA10 ((unsigned int) 1 << 10) // Pin Controlled by PA10
+#define AT91C_PA10_DTXD ((unsigned int) AT91C_PIO_PA10) // DBGU Debug Transmit Data
+#define AT91C_PA10_NPCS2 ((unsigned int) AT91C_PIO_PA10) // SPI Peripheral Chip Select 2
+#define AT91C_PIO_PA11 ((unsigned int) 1 << 11) // Pin Controlled by PA11
+#define AT91C_PA11_NPCS0 ((unsigned int) AT91C_PIO_PA11) // SPI Peripheral Chip Select 0
+#define AT91C_PA11_PWM0 ((unsigned int) AT91C_PIO_PA11) // PWM Channel 0
+#define AT91C_PIO_PA12 ((unsigned int) 1 << 12) // Pin Controlled by PA12
+#define AT91C_PA12_MISO ((unsigned int) AT91C_PIO_PA12) // SPI Master In Slave
+#define AT91C_PA12_PWM1 ((unsigned int) AT91C_PIO_PA12) // PWM Channel 1
+#define AT91C_PIO_PA13 ((unsigned int) 1 << 13) // Pin Controlled by PA13
+#define AT91C_PA13_MOSI ((unsigned int) AT91C_PIO_PA13) // SPI Master Out Slave
+#define AT91C_PA13_PWM2 ((unsigned int) AT91C_PIO_PA13) // PWM Channel 2
+#define AT91C_PIO_PA14 ((unsigned int) 1 << 14) // Pin Controlled by PA14
+#define AT91C_PA14_SPCK ((unsigned int) AT91C_PIO_PA14) // SPI Serial Clock
+#define AT91C_PA14_PWM3 ((unsigned int) AT91C_PIO_PA14) // PWM Channel 3
+#define AT91C_PIO_PA15 ((unsigned int) 1 << 15) // Pin Controlled by PA15
+#define AT91C_PA15_TF ((unsigned int) AT91C_PIO_PA15) // SSC Transmit Frame Sync
+#define AT91C_PA15_TIOA1 ((unsigned int) AT91C_PIO_PA15) // Timer Counter 1 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA16 ((unsigned int) 1 << 16) // Pin Controlled by PA16
+#define AT91C_PA16_TK ((unsigned int) AT91C_PIO_PA16) // SSC Transmit Clock
+#define AT91C_PA16_TIOB1 ((unsigned int) AT91C_PIO_PA16) // Timer Counter 1 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA17 ((unsigned int) 1 << 17) // Pin Controlled by PA17
+#define AT91C_PA17_TD ((unsigned int) AT91C_PIO_PA17) // SSC Transmit data
+#define AT91C_PA17_PCK1 ((unsigned int) AT91C_PIO_PA17) // PMC Programmable Clock Output 1
+#define AT91C_PIO_PA18 ((unsigned int) 1 << 18) // Pin Controlled by PA18
+#define AT91C_PA18_RD ((unsigned int) AT91C_PIO_PA18) // SSC Receive Data
+#define AT91C_PA18_PCK2 ((unsigned int) AT91C_PIO_PA18) // PMC Programmable Clock Output 2
+#define AT91C_PIO_PA19 ((unsigned int) 1 << 19) // Pin Controlled by PA19
+#define AT91C_PA19_RK ((unsigned int) AT91C_PIO_PA19) // SSC Receive Clock
+#define AT91C_PA19_FIQ ((unsigned int) AT91C_PIO_PA19) // AIC Fast Interrupt Input
+#define AT91C_PIO_PA2 ((unsigned int) 1 << 2) // Pin Controlled by PA2
+#define AT91C_PA2_PWM2 ((unsigned int) AT91C_PIO_PA2) // PWM Channel 2
+#define AT91C_PA2_SCK0 ((unsigned int) AT91C_PIO_PA2) // USART 0 Serial Clock
+#define AT91C_PIO_PA20 ((unsigned int) 1 << 20) // Pin Controlled by PA20
+#define AT91C_PA20_RF ((unsigned int) AT91C_PIO_PA20) // SSC Receive Frame Sync
+#define AT91C_PA20_IRQ0 ((unsigned int) AT91C_PIO_PA20) // External Interrupt 0
+#define AT91C_PIO_PA21 ((unsigned int) 1 << 21) // Pin Controlled by PA21
+#define AT91C_PA21_RXD1 ((unsigned int) AT91C_PIO_PA21) // USART 1 Receive Data
+#define AT91C_PA21_PCK1 ((unsigned int) AT91C_PIO_PA21) // PMC Programmable Clock Output 1
+#define AT91C_PIO_PA22 ((unsigned int) 1 << 22) // Pin Controlled by PA22
+#define AT91C_PA22_TXD1 ((unsigned int) AT91C_PIO_PA22) // USART 1 Transmit Data
+#define AT91C_PA22_NPCS3 ((unsigned int) AT91C_PIO_PA22) // SPI Peripheral Chip Select 3
+#define AT91C_PIO_PA23 ((unsigned int) 1 << 23) // Pin Controlled by PA23
+#define AT91C_PA23_SCK1 ((unsigned int) AT91C_PIO_PA23) // USART 1 Serial Clock
+#define AT91C_PA23_PWM0 ((unsigned int) AT91C_PIO_PA23) // PWM Channel 0
+#define AT91C_PIO_PA24 ((unsigned int) 1 << 24) // Pin Controlled by PA24
+#define AT91C_PA24_RTS1 ((unsigned int) AT91C_PIO_PA24) // USART 1 Ready To Send
+#define AT91C_PA24_PWM1 ((unsigned int) AT91C_PIO_PA24) // PWM Channel 1
+#define AT91C_PIO_PA25 ((unsigned int) 1 << 25) // Pin Controlled by PA25
+#define AT91C_PA25_CTS1 ((unsigned int) AT91C_PIO_PA25) // USART 1 Clear To Send
+#define AT91C_PA25_PWM2 ((unsigned int) AT91C_PIO_PA25) // PWM Channel 2
+#define AT91C_PIO_PA26 ((unsigned int) 1 << 26) // Pin Controlled by PA26
+#define AT91C_PA26_DCD1 ((unsigned int) AT91C_PIO_PA26) // USART 1 Data Carrier Detect
+#define AT91C_PA26_TIOA2 ((unsigned int) AT91C_PIO_PA26) // Timer Counter 2 Multipurpose Timer I/O Pin A
+#define AT91C_PIO_PA27 ((unsigned int) 1 << 27) // Pin Controlled by PA27
+#define AT91C_PA27_DTR1 ((unsigned int) AT91C_PIO_PA27) // USART 1 Data Terminal ready
+#define AT91C_PA27_TIOB2 ((unsigned int) AT91C_PIO_PA27) // Timer Counter 2 Multipurpose Timer I/O Pin B
+#define AT91C_PIO_PA28 ((unsigned int) 1 << 28) // Pin Controlled by PA28
+#define AT91C_PA28_DSR1 ((unsigned int) AT91C_PIO_PA28) // USART 1 Data Set ready
+#define AT91C_PA28_TCLK1 ((unsigned int) AT91C_PIO_PA28) // Timer Counter 1 external clock input
+#define AT91C_PIO_PA29 ((unsigned int) 1 << 29) // Pin Controlled by PA29
+#define AT91C_PA29_RI1 ((unsigned int) AT91C_PIO_PA29) // USART 1 Ring Indicator
+#define AT91C_PA29_TCLK2 ((unsigned int) AT91C_PIO_PA29) // Timer Counter 2 external clock input
+#define AT91C_PIO_PA3 ((unsigned int) 1 << 3) // Pin Controlled by PA3
+#define AT91C_PA3_TWD ((unsigned int) AT91C_PIO_PA3) // TWI Two-wire Serial Data
+#define AT91C_PA3_NPCS3 ((unsigned int) AT91C_PIO_PA3) // SPI Peripheral Chip Select 3
+#define AT91C_PIO_PA30 ((unsigned int) 1 << 30) // Pin Controlled by PA30
+#define AT91C_PA30_IRQ1 ((unsigned int) AT91C_PIO_PA30) // External Interrupt 1
+#define AT91C_PA30_NPCS2 ((unsigned int) AT91C_PIO_PA30) // SPI Peripheral Chip Select 2
+#define AT91C_PIO_PA31 ((unsigned int) 1 << 31) // Pin Controlled by PA31
+#define AT91C_PA31_NPCS1 ((unsigned int) AT91C_PIO_PA31) // SPI Peripheral Chip Select 1
+#define AT91C_PA31_PCK2 ((unsigned int) AT91C_PIO_PA31) // PMC Programmable Clock Output 2
+#define AT91C_PIO_PA4 ((unsigned int) 1 << 4) // Pin Controlled by PA4
+#define AT91C_PA4_TWCK ((unsigned int) AT91C_PIO_PA4) // TWI Two-wire Serial Clock
+#define AT91C_PA4_TCLK0 ((unsigned int) AT91C_PIO_PA4) // Timer Counter 0 external clock input
+#define AT91C_PIO_PA5 ((unsigned int) 1 << 5) // Pin Controlled by PA5
+#define AT91C_PA5_RXD0 ((unsigned int) AT91C_PIO_PA5) // USART 0 Receive Data
+#define AT91C_PA5_NPCS3 ((unsigned int) AT91C_PIO_PA5) // SPI Peripheral Chip Select 3
+#define AT91C_PIO_PA6 ((unsigned int) 1 << 6) // Pin Controlled by PA6
+#define AT91C_PA6_TXD0 ((unsigned int) AT91C_PIO_PA6) // USART 0 Transmit Data
+#define AT91C_PA6_PCK0 ((unsigned int) AT91C_PIO_PA6) // PMC Programmable Clock Output 0
+#define AT91C_PIO_PA7 ((unsigned int) 1 << 7) // Pin Controlled by PA7
+#define AT91C_PA7_RTS0 ((unsigned int) AT91C_PIO_PA7) // USART 0 Ready To Send
+#define AT91C_PA7_PWM3 ((unsigned int) AT91C_PIO_PA7) // PWM Channel 3
+#define AT91C_PIO_PA8 ((unsigned int) 1 << 8) // Pin Controlled by PA8
+#define AT91C_PA8_CTS0 ((unsigned int) AT91C_PIO_PA8) // USART 0 Clear To Send
+#define AT91C_PA8_ADTRG ((unsigned int) AT91C_PIO_PA8) // ADC External Trigger
+#define AT91C_PIO_PA9 ((unsigned int) 1 << 9) // Pin Controlled by PA9
+#define AT91C_PA9_DRXD ((unsigned int) AT91C_PIO_PA9) // DBGU Debug Receive Data
+#define AT91C_PA9_NPCS1 ((unsigned int) AT91C_PIO_PA9) // SPI Peripheral Chip Select 1
+
+// *****************************************************************************
+// PERIPHERAL ID DEFINITIONS FOR AT91SAM7S
+// *****************************************************************************
+#define AT91C_ID_FIQ ((unsigned int) 0) // Advanced Interrupt Controller (FIQ)
+#define AT91C_ID_SYS ((unsigned int) 1) // System Peripheral
+#define AT91C_ID_PIOA ((unsigned int) 2) // Parallel IO Controller
+#define AT91C_ID_PIOB ((unsigned int) 3) // Parallel IO Controller B
+#define AT91C_ID_ADC ((unsigned int) 4) // Analog-to-Digital Converter
+#define AT91C_ID_SPI ((unsigned int) 5) // Serial Peripheral Interface
+#define AT91C_ID_US0 ((unsigned int) 6) // USART 0
+#define AT91C_ID_US1 ((unsigned int) 7) // USART 1
+#define AT91C_ID_SSC ((unsigned int) 8) // Serial Synchronous Controller
+#define AT91C_ID_TWI ((unsigned int) 9) // Two-Wire Interface
+#define AT91C_ID_PWMC ((unsigned int) 10) // PWM Controller
+#define AT91C_ID_UDP ((unsigned int) 11) // USB Device Port
+#define AT91C_ID_TC0 ((unsigned int) 12) // Timer Counter 0
+#define AT91C_ID_TC1 ((unsigned int) 13) // Timer Counter 1
+#define AT91C_ID_TC2 ((unsigned int) 14) // Timer Counter 2
+#define AT91C_ID_15_Reserved ((unsigned int) 15) // Reserved
+#define AT91C_ID_16_Reserved ((unsigned int) 16) // Reserved
+#define AT91C_ID_17_Reserved ((unsigned int) 17) // Reserved
+#define AT91C_ID_18_Reserved ((unsigned int) 18) // Reserved
+#define AT91C_ID_19_Reserved ((unsigned int) 19) // Reserved
+#define AT91C_ID_20_Reserved ((unsigned int) 20) // Reserved
+#define AT91C_ID_21_Reserved ((unsigned int) 21) // Reserved
+#define AT91C_ID_22_Reserved ((unsigned int) 22) // Reserved
+#define AT91C_ID_23_Reserved ((unsigned int) 23) // Reserved
+#define AT91C_ID_24_Reserved ((unsigned int) 24) // Reserved
+#define AT91C_ID_25_Reserved ((unsigned int) 25) // Reserved
+#define AT91C_ID_26_Reserved ((unsigned int) 26) // Reserved
+#define AT91C_ID_27_Reserved ((unsigned int) 27) // Reserved
+#define AT91C_ID_28_Reserved ((unsigned int) 28) // Reserved
+#define AT91C_ID_29_Reserved ((unsigned int) 29) // Reserved
+#define AT91C_ID_IRQ0 ((unsigned int) 30) // Advanced Interrupt Controller (IRQ0)
+#define AT91C_ID_IRQ1 ((unsigned int) 31) // Advanced Interrupt Controller (IRQ1)
+#define AT91C_ALL_INT ((unsigned int) 0xC0007FF7) // ALL VALID INTERRUPTS
+
+// *****************************************************************************
+// BASE ADDRESS DEFINITIONS FOR AT91SAM7S64
+// *****************************************************************************
+#define AT91C_BASE_SYS ((AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address
+#define AT91C_BASE_AIC ((AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address
+#define AT91C_BASE_PDC_DBGU ((AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address
+#define AT91C_BASE_DBGU ((AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address
+#define AT91C_BASE_PIOA ((AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address
+#define AT91C_BASE_CKGR ((AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address
+#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address
+#define AT91C_BASE_RSTC ((AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address
+#define AT91C_BASE_RTTC ((AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address
+#define AT91C_BASE_PITC ((AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address
+#define AT91C_BASE_WDTC ((AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address
+#define AT91C_BASE_VREG ((AT91PS_VREG) 0xFFFFFD60) // (VREG) Base Address
+#define AT91C_BASE_MC ((AT91PS_MC) 0xFFFFFF00) // (MC) Base Address
+#define AT91C_BASE_PDC_SPI ((AT91PS_PDC) 0xFFFE0100) // (PDC_SPI) Base Address
+#define AT91C_BASE_SPI ((AT91PS_SPI) 0xFFFE0000) // (SPI) Base Address
+#define AT91C_BASE_PDC_ADC ((AT91PS_PDC) 0xFFFD8100) // (PDC_ADC) Base Address
+#define AT91C_BASE_ADC ((AT91PS_ADC) 0xFFFD8000) // (ADC) Base Address
+#define AT91C_BASE_PDC_SSC ((AT91PS_PDC) 0xFFFD4100) // (PDC_SSC) Base Address
+#define AT91C_BASE_SSC ((AT91PS_SSC) 0xFFFD4000) // (SSC) Base Address
+#define AT91C_BASE_PDC_US1 ((AT91PS_PDC) 0xFFFC4100) // (PDC_US1) Base Address
+#define AT91C_BASE_US1 ((AT91PS_USART) 0xFFFC4000) // (US1) Base Address
+#define AT91C_BASE_PDC_US0 ((AT91PS_PDC) 0xFFFC0100) // (PDC_US0) Base Address
+#define AT91C_BASE_US0 ((AT91PS_USART) 0xFFFC0000) // (US0) Base Address
+#define AT91C_BASE_TWI ((AT91PS_TWI) 0xFFFB8000) // (TWI) Base Address
+#define AT91C_BASE_TC0 ((AT91PS_TC) 0xFFFA0000) // (TC0) Base Address
+#define AT91C_BASE_TC1 ((AT91PS_TC) 0xFFFA0040) // (TC1) Base Address
+#define AT91C_BASE_TC2 ((AT91PS_TC) 0xFFFA0080) // (TC2) Base Address
+#define AT91C_BASE_TCB ((AT91PS_TCB) 0xFFFA0000) // (TCB) Base Address
+#define AT91C_BASE_PWMC_CH3 ((AT91PS_PWMC_CH) 0xFFFCC260) // (PWMC_CH3) Base Address
+#define AT91C_BASE_PWMC_CH2 ((AT91PS_PWMC_CH) 0xFFFCC240) // (PWMC_CH2) Base Address
+#define AT91C_BASE_PWMC_CH1 ((AT91PS_PWMC_CH) 0xFFFCC220) // (PWMC_CH1) Base Address
+#define AT91C_BASE_PWMC_CH0 ((AT91PS_PWMC_CH) 0xFFFCC200) // (PWMC_CH0) Base Address
+#define AT91C_BASE_PWMC ((AT91PS_PWMC) 0xFFFCC000) // (PWMC) Base Address
+#define AT91C_BASE_UDP ((AT91PS_UDP) 0xFFFB0000) // (UDP) Base Address
+
+// *****************************************************************************
+// MEMORY MAPPING DEFINITIONS FOR AT91SAM7S64
+// *****************************************************************************
+// ISRAM
+#define AT91C_ISRAM ((char *) 0x00200000) // Internal SRAM base address
+// IFLASH
+#define AT91C_IFLASH ((char *) 0x00100000) // Internal FLASH base address
+
+#if defined(__AT91SAM7S32__)
+#define AT91C_ISRAM_SIZE ((unsigned int) 0x00002000) // Internal SRAM size in byte (8 Kbytes)
+#define AT91C_IFLASH_SIZE ((unsigned int) 0x00008000) // Internal FLASH size in byte (32 Kbytes)
+#define AT91C_IFLASH_PAGE_SIZE ((unsigned int) 128) // Internal FLASH Page Size: 128 bytes
+#define AT91C_IFLASH_PAGE_SHIFT 7
+#define AT91C_IFLASH_NB_OF_LOCK_BITS ((unsigned int) 8) // Internal FLASH Number of Lock Bits: 8
+#elif defined(__AT91SAM7S64__)
+#define AT91C_ISRAM_SIZE ((unsigned int) 0x00004000) // Internal SRAM size in byte (16 Kbytes)
+#define AT91C_IFLASH_SIZE ((unsigned int) 0x00010000) // Internal FLASH size in byte (64 Kbytes)
+#define AT91C_IFLASH_PAGE_SIZE ((unsigned int) 128) // Internal FLASH Page Size: 128 bytes
+#define AT91C_IFLASH_PAGE_SHIFT 7
+#define AT91C_IFLASH_NB_OF_LOCK_BITS ((unsigned int) 16) // Internal FLASH Number of Lock Bits: 16
+#elif defined(__AT91SAM7S128__)
+#define AT91C_ISRAM_SIZE ((unsigned int) 0x00008000) // Internal SRAM size in byte (32 Kbytes)
+#define AT91C_IFLASH_SIZE ((unsigned int) 0x00020000) // Internal FLASH size in byte (128 Kbytes)
+#define AT91C_IFLASH_PAGE_SIZE ((unsigned int) 256) // Internal FLASH Page Size: 256 bytes
+#define AT91C_IFLASH_PAGE_SHIFT 8
+#define AT91C_IFLASH_NB_OF_LOCK_BITS ((unsigned int) 8) // Internal FLASH Number of Lock Bits: 8
+#elif defined(__AT91SAM7S256__)
+#define AT91C_ISRAM_SIZE ((unsigned int) 0x00010000) // Internal SRAM size in byte (64 Kbytes)
+#define AT91C_IFLASH_SIZE ((unsigned int) 0x00040000) // Internal FLASH size in byte (256 Kbytes)
+#define AT91C_IFLASH_PAGE_SIZE ((unsigned int) 256) // Internal FLASH Page Size: 256 bytes
+#define AT91C_IFLASH_PAGE_SHIFT 8
+#define AT91C_IFLASH_NB_OF_LOCK_BITS ((unsigned int) 16) // Internal FLASH Number of Lock Bits: 16
+#else
+#error Have to define which __AT91SAM7Sxxx__ type
+#endif
+
+#define AT91C_IFLASH_NB_OF_PAGES (AT91C_IFLASH_SIZE>>AT91C_IFLASH_PAGE_SHIFT)
+#define AT91C_IFLASH_LOCK_REGION_SIZE (AT91C_IFLASH_SIZE/AT91C_IFLASH_NB_OF_LOCK_BITS)
+
+#endif/*__AT91SAM7_H__*/
diff --git a/openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.c b/openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.c
new file mode 100644
index 0000000..bf9ae6d
--- /dev/null
+++ b/openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.c
@@ -0,0 +1,424 @@
+//* ----------------------------------------------------------------------------
+//* ATMEL Microcontroller Software Support - ROUSSET -
+//* ----------------------------------------------------------------------------
+//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//* ----------------------------------------------------------------------------
+//* File Name : lib_AT91SAM7S64.h
+//* Object : AT91SAM7S64 inlined functions
+//* Generated : AT91 SW Application Group 08/30/2005 (15:52:59)
+//*
+
+#include <sys/types.h>
+#include <AT91SAM7.h>
+#include <lib_AT91SAM7.h>
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_ConfigureIt
+//* \brief Interrupt Handler Initialization
+//*----------------------------------------------------------------------------
+unsigned int
+AT91F_AIC_ConfigureIt (unsigned int irq_id, // \arg interrupt number to initialize
+ unsigned int priority, // \arg priority to give to the interrupt
+ unsigned int src_type, // \arg activation and sense of activation
+ THandler handler) // \arg address of the interrupt handler
+{
+ unsigned int oldHandler;
+ unsigned int mask;
+
+ oldHandler = AT91C_BASE_AIC->AIC_SVR[irq_id];
+
+ mask = 0x1 << irq_id;
+ //* Disable the interrupt on the interrupt controller
+ AT91C_BASE_AIC->AIC_IDCR = mask;
+ //* Save the interrupt handler routine pointer and the interrupt priority
+ AT91C_BASE_AIC->AIC_SVR[irq_id] = (unsigned int) handler;
+ //* Store the Source Mode Register
+ AT91C_BASE_AIC->AIC_SMR[irq_id] = src_type | priority;
+ //* Clear the interrupt on the interrupt controller
+ AT91C_BASE_AIC->AIC_ICCR = mask;
+
+ return (unsigned int) handler;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_SetExceptionVector
+//* \brief Configure vector handler
+//*----------------------------------------------------------------------------
+unsigned int
+AT91F_AIC_SetExceptionVector (unsigned int *pVector, // \arg pointer to the AIC registers
+ THandler Handler) // \arg Interrupt Handler
+{
+ unsigned int oldVector = *pVector;
+
+ if ((unsigned int) Handler == (unsigned int) AT91C_AIC_BRANCH_OPCODE)
+ *pVector = (unsigned int) AT91C_AIC_BRANCH_OPCODE;
+ else
+ *pVector =
+ (((((unsigned int) Handler) - ((unsigned int) pVector) -
+ 0x8) >> 2) & 0x00FFFFFF) | 0xEA000000;
+
+ return oldVector;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_Open
+//* \brief Set exception vectors and AIC registers to default values
+//*----------------------------------------------------------------------------
+void
+AT91F_AIC_Open (THandler IrqHandler, // \arg Default IRQ vector exception
+ THandler FiqHandler, // \arg Default FIQ vector exception
+ THandler DefaultHandler, // \arg Default Handler set in ISR
+ THandler SpuriousHandler, // \arg Default Spurious Handler
+ unsigned int protectMode) // \arg Debug Control Register
+{
+ int i;
+
+ // Disable all interrupts and set IVR to the default handler
+ for (i = 0; i < 32; ++i)
+ {
+ AT91F_AIC_DisableIt (i);
+ AT91F_AIC_ConfigureIt (i, AT91C_AIC_PRIOR_LOWEST,
+ AT91C_AIC_SRCTYPE_HIGH_LEVEL, DefaultHandler);
+ }
+
+ // Set the IRQ exception vector
+ AT91F_AIC_SetExceptionVector ((unsigned int *) 0x18, IrqHandler);
+ // Set the Fast Interrupt exception vector
+ AT91F_AIC_SetExceptionVector ((unsigned int *) 0x1C, FiqHandler);
+
+ AT91C_BASE_AIC->AIC_SPU = (unsigned int) SpuriousHandler;
+ AT91C_BASE_AIC->AIC_DCR = protectMode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_Open
+//* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX
+//*----------------------------------------------------------------------------
+void
+AT91F_PDC_Open (AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ //* Disable the RX and TX PDC transfer requests
+ AT91F_PDC_DisableRx (pPDC);
+ AT91F_PDC_DisableTx (pPDC);
+
+ //* Reset all Counter register Next buffer first
+ AT91F_PDC_SetNextTx (pPDC, NULL, 0);
+ AT91F_PDC_SetNextRx (pPDC, NULL, 0);
+ AT91F_PDC_SetTx (pPDC, NULL, 0);
+ AT91F_PDC_SetRx (pPDC, NULL, 0);
+
+ //* Enable the RX and TX PDC transfer requests
+ AT91F_PDC_EnableRx (pPDC);
+ AT91F_PDC_EnableTx (pPDC);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_Close
+//* \brief Close PDC: disable TX and RX reset transfer descriptors
+//*----------------------------------------------------------------------------
+void
+AT91F_PDC_Close (AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ //* Disable the RX and TX PDC transfer requests
+ AT91F_PDC_DisableRx (pPDC);
+ AT91F_PDC_DisableTx (pPDC);
+
+ //* Reset all Counter register Next buffer first
+ AT91F_PDC_SetNextTx (pPDC, NULL, 0);
+ AT91F_PDC_SetNextRx (pPDC, NULL, 0);
+ AT91F_PDC_SetTx (pPDC, NULL, 0);
+ AT91F_PDC_SetRx (pPDC, NULL, 0);
+
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SendFrame
+//* \brief Close PDC: disable TX and RX reset transfer descriptors
+//*----------------------------------------------------------------------------
+unsigned int
+AT91F_PDC_SendFrame (AT91PS_PDC pPDC,
+ const unsigned char *pBuffer,
+ unsigned int szBuffer,
+ const unsigned char *pNextBuffer,
+ unsigned int szNextBuffer)
+{
+ if (AT91F_PDC_IsTxEmpty (pPDC))
+ {
+ //* Buffer and next buffer can be initialized
+ AT91F_PDC_SetTx (pPDC, pBuffer, szBuffer);
+ AT91F_PDC_SetNextTx (pPDC, pNextBuffer, szNextBuffer);
+ return 2;
+ }
+ else if (AT91F_PDC_IsNextTxEmpty (pPDC))
+ {
+ //* Only one buffer can be initialized
+ AT91F_PDC_SetNextTx (pPDC, pBuffer, szBuffer);
+ return 1;
+ }
+ else
+ {
+ //* All buffer are in use...
+ return 0;
+ }
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_ReceiveFrame
+//* \brief Close PDC: disable TX and RX reset transfer descriptors
+//*----------------------------------------------------------------------------
+unsigned int
+AT91F_PDC_ReceiveFrame (AT91PS_PDC pPDC,
+ unsigned char *pBuffer,
+ unsigned int szBuffer,
+ unsigned char *pNextBuffer, unsigned int szNextBuffer)
+{
+ if (AT91F_PDC_IsRxEmpty (pPDC))
+ {
+ //* Buffer and next buffer can be initialized
+ AT91F_PDC_SetRx (pPDC, pBuffer, szBuffer);
+ AT91F_PDC_SetNextRx (pPDC, pNextBuffer, szNextBuffer);
+ return 2;
+ }
+ else if (AT91F_PDC_IsNextRxEmpty (pPDC))
+ {
+ //* Only one buffer can be initialized
+ AT91F_PDC_SetNextRx (pPDC, pBuffer, szBuffer);
+ return 1;
+ }
+ else
+ {
+ //* All buffer are in use...
+ return 0;
+ }
+}
+
+//*------------------------------------------------------------------------------
+//* \fn AT91F_PMC_GetMasterClock
+//* \brief Return master clock in Hz which correponds to processor clock for ARM7
+//*------------------------------------------------------------------------------
+unsigned int
+AT91F_PMC_GetMasterClock (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ AT91PS_CKGR pCKGR, // \arg pointer to CKGR controller
+ unsigned int slowClock) // \arg slowClock in Hz
+{
+ unsigned int reg = pPMC->PMC_MCKR;
+ unsigned int prescaler = (1 << ((reg & AT91C_PMC_PRES) >> 2));
+ unsigned int pllDivider, pllMultiplier;
+
+ switch (reg & AT91C_PMC_CSS)
+ {
+ case AT91C_PMC_CSS_SLOW_CLK: // Slow clock selected
+ return slowClock / prescaler;
+ case AT91C_PMC_CSS_MAIN_CLK: // Main clock is selected
+ return AT91F_CKGR_GetMainClock (pCKGR, slowClock) / prescaler;
+ case AT91C_PMC_CSS_PLL_CLK: // PLLB clock is selected
+ reg = pCKGR->CKGR_PLLR;
+ pllDivider = (reg & AT91C_CKGR_DIV);
+ pllMultiplier = ((reg & AT91C_CKGR_MUL) >> 16) + 1;
+ return AT91F_CKGR_GetMainClock (pCKGR,
+ slowClock) / pllDivider *
+ pllMultiplier / prescaler;
+ }
+ return 0;
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_ReadValue()
+//* \brief Read the RTT value
+//*--------------------------------------------------------------------------------------
+unsigned int
+AT91F_RTTReadValue (AT91PS_RTTC pRTTC)
+{
+ register volatile unsigned int val1, val2;
+ do
+ {
+ val1 = pRTTC->RTTC_RTVR;
+ val2 = pRTTC->RTTC_RTVR;
+ }
+ while (val1 != val2);
+ return (val1);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_Close
+//* \brief Close SPI: disable IT disable transfert, close PDC
+//*----------------------------------------------------------------------------
+void
+AT91F_SPI_Close (AT91PS_SPI pSPI) // \arg pointer to a SPI controller
+{
+ //* Reset all the Chip Select register
+ pSPI->SPI_CSR[0] = 0;
+ pSPI->SPI_CSR[1] = 0;
+ pSPI->SPI_CSR[2] = 0;
+ pSPI->SPI_CSR[3] = 0;
+
+ //* Reset the SPI mode
+ pSPI->SPI_MR = 0;
+
+ //* Disable all interrupts
+ pSPI->SPI_IDR = 0xFFFFFFFF;
+
+ //* Abort the Peripheral Data Transfers
+ AT91F_PDC_Close ((AT91PS_PDC) & (pSPI->SPI_RPR));
+
+ //* Disable receiver and transmitter and stop any activity immediately
+ pSPI->SPI_CR = AT91C_SPI_SPIDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_CfgTimings
+//* \brief Configure the different necessary timings of the ADC controller
+//*----------------------------------------------------------------------------
+void
+AT91F_ADC_CfgTimings (AT91PS_ADC pADC, // pointer to a ADC controller
+ unsigned int mck_clock, // in MHz
+ unsigned int adc_clock, // in MHz
+ unsigned int startup_time, // in us
+ unsigned int sample_and_hold_time) // in ns
+{
+ unsigned int prescal, startup, shtim;
+
+ prescal = mck_clock / (2 * adc_clock) - 1;
+ startup = adc_clock * startup_time / 8 - 1;
+ shtim = adc_clock * sample_and_hold_time / 1000 - 1;
+
+ //* Write to the MR register
+ pADC->ADC_MR =
+ ((prescal << 8) & AT91C_ADC_PRESCAL) | ((startup << 16) &
+ AT91C_ADC_STARTUP) | ((shtim <<
+ 24) &
+ AT91C_ADC_SHTIM);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_SetBaudrate
+//* \brief Set the baudrate according to the CPU clock
+//*----------------------------------------------------------------------------
+void
+AT91F_SSC_SetBaudrate (AT91PS_SSC pSSC, // \arg pointer to a SSC controller
+ unsigned int mainClock, // \arg peripheral clock
+ unsigned int speed) // \arg SSC baudrate
+{
+ unsigned int baud_value;
+ //* Define the baud rate divisor register
+ if (speed == 0)
+ baud_value = 0;
+ else
+ {
+ baud_value = (unsigned int) (mainClock * 10) / (2 * speed);
+ if ((baud_value % 10) >= 5)
+ baud_value = (baud_value / 10) + 1;
+ else
+ baud_value /= 10;
+ }
+
+ pSSC->SSC_CMR = baud_value;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_Configure
+//* \brief Configure SSC
+//*----------------------------------------------------------------------------
+void
+AT91F_SSC_Configure (AT91PS_SSC pSSC, // \arg pointer to a SSC controller
+ unsigned int syst_clock, // \arg System Clock Frequency
+ unsigned int baud_rate, // \arg Expected Baud Rate Frequency
+ unsigned int clock_rx, // \arg Receiver Clock Parameters
+ unsigned int mode_rx, // \arg mode Register to be programmed
+ unsigned int clock_tx, // \arg Transmitter Clock Parameters
+ unsigned int mode_tx) // \arg mode Register to be programmed
+{
+ //* Disable interrupts
+ pSSC->SSC_IDR = (unsigned int) -1;
+
+ //* Reset receiver and transmitter
+ pSSC->SSC_CR = AT91C_SSC_SWRST | AT91C_SSC_RXDIS | AT91C_SSC_TXDIS;
+
+ //* Define the Clock Mode Register
+ AT91F_SSC_SetBaudrate (pSSC, syst_clock, baud_rate);
+
+ //* Write the Receive Clock Mode Register
+ pSSC->SSC_RCMR = clock_rx;
+
+ //* Write the Transmit Clock Mode Register
+ pSSC->SSC_TCMR = clock_tx;
+
+ //* Write the Receive Frame Mode Register
+ pSSC->SSC_RFMR = mode_rx;
+
+ //* Write the Transmit Frame Mode Register
+ pSSC->SSC_TFMR = mode_tx;
+
+ //* Clear Transmit and Receive Counters
+ AT91F_PDC_Open ((AT91PS_PDC) & (pSSC->SSC_RPR));
+
+
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_Configure
+//* \brief Configure USART
+//*----------------------------------------------------------------------------
+void
+AT91F_US_Configure (AT91PS_USART pUSART, // \arg pointer to a USART controller
+ unsigned int mainClock, // \arg peripheral clock
+ unsigned int mode, // \arg mode Register to be programmed
+ unsigned int baudRate, // \arg baudrate to be programmed
+ unsigned int timeguard) // \arg timeguard to be programmed
+{
+ //* Disable interrupts
+ pUSART->US_IDR = (unsigned int) -1;
+
+ //* Reset receiver and transmitter
+ pUSART->US_CR =
+ AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
+
+ //* Define the baud rate divisor register
+ AT91F_US_SetBaudrate (pUSART, mainClock, baudRate);
+
+ //* Write the Timeguard Register
+ AT91F_US_SetTimeguard (pUSART, timeguard);
+
+ //* Clear Transmit and Receive Counters
+ AT91F_PDC_Open ((AT91PS_PDC) & (pUSART->US_RPR));
+
+ //* Define the USART mode
+ pUSART->US_MR = mode;
+
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_Close
+//* \brief Close USART: disable IT disable receiver and transmitter, close PDC
+//*----------------------------------------------------------------------------
+void
+AT91F_US_Close (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ //* Reset the baud rate divisor register
+ pUSART->US_BRGR = 0;
+
+ //* Reset the USART mode
+ pUSART->US_MR = 0;
+
+ //* Reset the Timeguard Register
+ pUSART->US_TTGR = 0;
+
+ //* Disable all interrupts
+ pUSART->US_IDR = 0xFFFFFFFF;
+
+ //* Abort the Peripheral Data Transfers
+ AT91F_PDC_Close ((AT91PS_PDC) & (pUSART->US_RPR));
+
+ //* Disable receiver and transmitter and stop any activity immediately
+ pUSART->US_CR =
+ AT91C_US_TXDIS | AT91C_US_RXDIS | AT91C_US_RSTTX | AT91C_US_RSTRX;
+}
diff --git a/openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.h b/openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.h
new file mode 100644
index 0000000..4f58088
--- /dev/null
+++ b/openpicc/os/core/ARM7_AT91SAM7S/lib_AT91SAM7.h
@@ -0,0 +1,3417 @@
+//* ----------------------------------------------------------------------------
+//* ATMEL Microcontroller Software Support - ROUSSET -
+//* ----------------------------------------------------------------------------
+//* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+//* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+//* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+//* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+//* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+//* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//* ----------------------------------------------------------------------------
+//* File Name : lib_AT91SAM7S64.h
+//* Object : AT91SAM7S64 inlined functions
+//* Generated : AT91 SW Application Group 08/30/2005 (15:52:59)
+//*
+//* CVS Reference : /lib_dbgu.h/1.1/Thu Aug 25 12:56:22 2005//
+//* CVS Reference : /lib_pmc_SAM7S.h/1.4/Tue Aug 30 13:00:43 2005//
+//* CVS Reference : /lib_VREG_6085B.h/1.1/Tue Feb 1 16:20:47 2005//
+//* CVS Reference : /lib_rstc_6098A.h/1.1/Wed Oct 6 10:39:20 2004//
+//* CVS Reference : /lib_ssc.h/1.4/Fri Jan 31 12:19:20 2003//
+//* CVS Reference : /lib_wdtc_6080A.h/1.1/Wed Oct 6 10:38:30 2004//
+//* CVS Reference : /lib_usart.h/1.5/Thu Nov 21 16:01:54 2002//
+//* CVS Reference : /lib_spi2.h/1.2/Tue Aug 23 15:37:28 2005//
+//* CVS Reference : /lib_pitc_6079A.h/1.2/Tue Nov 9 14:43:56 2004//
+//* CVS Reference : /lib_aic_6075b.h/1.2/Thu Jul 7 07:48:22 2005//
+//* CVS Reference : /lib_twi.h/1.3/Mon Jul 19 14:27:58 2004//
+//* CVS Reference : /lib_adc.h/1.6/Fri Oct 17 09:12:38 2003//
+//* CVS Reference : /lib_rttc_6081A.h/1.1/Wed Oct 6 10:39:38 2004//
+//* CVS Reference : /lib_udp.h/1.5/Tue Aug 30 12:13:47 2005//
+//* CVS Reference : /lib_tc_1753b.h/1.1/Fri Jan 31 12:20:02 2003//
+//* CVS Reference : /lib_MC_SAM7S.h/1.1/Thu Mar 25 15:19:14 2004//
+//* CVS Reference : /lib_pio.h/1.3/Fri Jan 31 12:18:56 2003//
+//* CVS Reference : /lib_PWM_SAM.h/1.3/Thu Jan 22 10:10:50 2004//
+//* CVS Reference : /lib_pdc.h/1.2/Tue Jul 2 13:29:40 2002//
+//* ----------------------------------------------------------------------------
+
+#ifndef lib_AT91SAM7_H
+#define lib_AT91SAM7_H
+
+#include <AT91SAM7.h>
+
+typedef void (*THandler) (void);
+
+/* *****************************************************************************
+ SOFTWARE API FOR AIC
+ ***************************************************************************** */
+#define AT91C_AIC_BRANCH_OPCODE ((void (*) ()) 0xE51FFF20) // ldr, pc, [pc, #-&F20]
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_ConfigureIt
+//* \brief Interrupt Handler Initialization
+//*----------------------------------------------------------------------------
+extern unsigned int AT91F_AIC_ConfigureIt (unsigned int irq_id, // \arg interrupt number to initialize
+ unsigned int priority, // \arg priority to give to the interrupt
+ unsigned int src_type, // \arg activation and sense of activation
+ THandler handler); // \arg address of the interrupt handler
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_EnableIt
+//* \brief Enable corresponding IT number
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_AIC_EnableIt (unsigned int irq_id) // \arg interrupt number to initialize
+{
+ //* Enable the interrupt on the interrupt controller
+ AT91C_BASE_AIC->AIC_IECR = 0x1 << irq_id;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_DisableIt
+//* \brief Disable corresponding IT number
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_AIC_DisableIt (unsigned int irq_id) // \arg interrupt number to initialize
+{
+ unsigned int mask = 0x1 << irq_id;
+ //* Disable the interrupt on the interrupt controller
+ AT91C_BASE_AIC->AIC_IDCR = mask;
+ //* Clear the interrupt on the Interrupt Controller ( if one is pending )
+ AT91C_BASE_AIC->AIC_ICCR = mask;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_ClearIt
+//* \brief Clear corresponding IT number
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_AIC_ClearIt (unsigned int irq_id) // \arg interrupt number to initialize
+{
+ //* Clear the interrupt on the Interrupt Controller ( if one is pending )
+ AT91C_BASE_AIC->AIC_ICCR = (0x1 << irq_id);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_AcknowledgeIt
+//* \brief Acknowledge corresponding IT number
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_AIC_AcknowledgeIt (void)
+{
+ AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_AIC->AIC_EOICR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_SetExceptionVector
+//* \brief Configure vector handler
+//*----------------------------------------------------------------------------
+extern unsigned int AT91F_AIC_SetExceptionVector (unsigned int *pVector, // \arg pointer to the AIC registers
+ THandler Handler); // \arg Interrupt Handler
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_Trig
+//* \brief Trig an IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_AIC_Trig (AT91PS_AIC pAic, // \arg pointer to the AIC registers
+ unsigned int irq_id) // \arg interrupt number
+{
+ pAic->AIC_ISCR = (0x1 << irq_id);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_IsActive
+//* \brief Test if an IT is active
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_AIC_IsActive (AT91PS_AIC pAic, // \arg pointer to the AIC registers
+ unsigned int irq_id) // \arg Interrupt Number
+{
+ return (pAic->AIC_ISR & (0x1 << irq_id));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_IsPending
+//* \brief Test if an IT is pending
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_AIC_IsPending (AT91PS_AIC pAic, // \arg pointer to the AIC registers
+ unsigned int irq_id) // \arg Interrupt Number
+{
+ return (pAic->AIC_IPR & (0x1 << irq_id));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_Open
+//* \brief Set exception vectors and AIC registers to default values
+//*----------------------------------------------------------------------------
+extern void AT91F_AIC_Open (THandler IrqHandler, // \arg Default IRQ vector exception
+ THandler FiqHandler, // \arg Default FIQ vector exception
+ THandler DefaultHandler, // \arg Default Handler set in ISR
+ THandler SpuriousHandler, // \arg Default Spurious Handler
+ unsigned int protectMode); // \arg Debug Control Register
+
+/* *****************************************************************************
+ SOFTWARE API FOR PDC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetNextRx
+//* \brief Set the next receive transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetNextRx (AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ unsigned char *address, // \arg address to the next bloc to be received
+ unsigned int bytes) // \arg number of bytes to be received
+{
+ pPDC->PDC_RNPR = (unsigned int) address;
+ pPDC->PDC_RNCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetNextTx
+//* \brief Set the next transmit transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetNextTx (AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ const unsigned char *address, // \arg address to the next bloc to be transmitted
+ unsigned int bytes) // \arg number of bytes to be transmitted
+{
+ pPDC->PDC_TNPR = (unsigned int) address;
+ pPDC->PDC_TNCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetRx
+//* \brief Set the receive transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetRx (AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ unsigned char *address, // \arg address to the next bloc to be received
+ unsigned int bytes) // \arg number of bytes to be received
+{
+ pPDC->PDC_RPR = (unsigned int) address;
+ pPDC->PDC_RCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SetTx
+//* \brief Set the transmit transfer descriptor
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_SetTx (AT91PS_PDC pPDC, // \arg pointer to a PDC controller
+ const unsigned char *address, // \arg address to the next bloc to be transmitted
+ unsigned int bytes) // \arg number of bytes to be transmitted
+{
+ pPDC->PDC_TPR = (unsigned int) address;
+ pPDC->PDC_TCR = bytes;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_EnableTx
+//* \brief Enable transmit
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_EnableTx (AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_TXTEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_EnableRx
+//* \brief Enable receive
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_EnableRx (AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_DisableTx
+//* \brief Disable transmit
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_DisableTx (AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_TXTDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_DisableRx
+//* \brief Disable receive
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PDC_DisableRx (AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ pPDC->PDC_PTCR = AT91C_PDC_RXTDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_IsTxEmpty
+//* \brief Test if the current transfer descriptor has been sent
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PDC_IsTxEmpty ( // \return return 1 if transfer is complete
+ AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ return !(pPDC->PDC_TCR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_IsNextTxEmpty
+//* \brief Test if the next transfer descriptor has been moved to the current td
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PDC_IsNextTxEmpty ( // \return return 1 if transfer is complete
+ AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ return !(pPDC->PDC_TNCR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_IsRxEmpty
+//* \brief Test if the current transfer descriptor has been filled
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PDC_IsRxEmpty ( // \return return 1 if transfer is complete
+ AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ return !(pPDC->PDC_RCR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_IsNextRxEmpty
+//* \brief Test if the next transfer descriptor has been moved to the current td
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PDC_IsNextRxEmpty ( // \return return 1 if transfer is complete
+ AT91PS_PDC pPDC) // \arg pointer to a PDC controller
+{
+ return !(pPDC->PDC_RNCR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_Open
+//* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX
+//*----------------------------------------------------------------------------
+extern void AT91F_PDC_Open (AT91PS_PDC pPDC); // \arg pointer to a PDC controller
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_Close
+//* \brief Close PDC: disable TX and RX reset transfer descriptors
+//*----------------------------------------------------------------------------
+extern void AT91F_PDC_Close (AT91PS_PDC pPDC); // \arg pointer to a PDC controller
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_SendFrame
+//* \brief Close PDC: disable TX and RX reset transfer descriptors
+//*----------------------------------------------------------------------------
+extern unsigned int AT91F_PDC_SendFrame (AT91PS_PDC pPDC,
+ const unsigned char *pBuffer,
+ unsigned int szBuffer,
+ const unsigned char *pNextBuffer,
+ unsigned int szNextBuffer);
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PDC_ReceiveFrame
+//* \brief Close PDC: disable TX and RX reset transfer descriptors
+//*----------------------------------------------------------------------------
+extern unsigned int AT91F_PDC_ReceiveFrame (AT91PS_PDC pPDC,
+ unsigned char *pBuffer,
+ unsigned int szBuffer,
+ unsigned char *pNextBuffer,
+ unsigned int szNextBuffer);
+
+/* *****************************************************************************
+ SOFTWARE API FOR DBGU
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_DBGU_InterruptEnable
+//* \brief Enable DBGU Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_DBGU_InterruptEnable (AT91PS_DBGU pDbgu, // \arg pointer to a DBGU controller
+ unsigned int flag) // \arg dbgu interrupt to be enabled
+{
+ pDbgu->DBGU_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_DBGU_InterruptDisable
+//* \brief Disable DBGU Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_DBGU_InterruptDisable (AT91PS_DBGU pDbgu, // \arg pointer to a DBGU controller
+ unsigned int flag) // \arg dbgu interrupt to be disabled
+{
+ pDbgu->DBGU_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_DBGU_GetInterruptMaskStatus
+//* \brief Return DBGU Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_DBGU_GetInterruptMaskStatus ( // \return DBGU Interrupt Mask Status
+ AT91PS_DBGU pDbgu) // \arg pointer to a DBGU controller
+{
+ return pDbgu->DBGU_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_DBGU_IsInterruptMasked
+//* \brief Test if DBGU Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_DBGU_IsInterruptMasked (AT91PS_DBGU pDbgu, // \arg pointer to a DBGU controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_DBGU_GetInterruptMaskStatus (pDbgu) & flag);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR PIO
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgPeriph
+//* \brief Enable pins to be drived by peripheral
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_CfgPeriph (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int periphAEnable, // \arg PERIPH A to enable
+ unsigned int periphBEnable) // \arg PERIPH B to enable
+{
+ pPio->PIO_ASR = periphAEnable;
+ pPio->PIO_BSR = periphBEnable;
+ pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgOutput
+//* \brief Enable PIO in output mode
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_CfgOutput (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int pioEnable) // \arg PIO to be enabled
+{
+ pPio->PIO_PER = pioEnable; // Set in PIO mode
+ pPio->PIO_OER = pioEnable; // Configure in Output
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgInput
+//* \brief Enable PIO in input mode
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_CfgInput (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int inputEnable) // \arg PIO to be enabled
+{
+ // Disable output
+ pPio->PIO_ODR = inputEnable;
+ pPio->PIO_PER = inputEnable;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgOpendrain
+//* \brief Configure PIO in open drain
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_CfgOpendrain (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int multiDrvEnable) // \arg pio to be configured in open drain
+{
+ // Configure the multi-drive option
+ pPio->PIO_MDDR = ~multiDrvEnable;
+ pPio->PIO_MDER = multiDrvEnable;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgPullup
+//* \brief Enable pullup on PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_CfgPullup (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int pullupEnable) // \arg enable pullup on PIO
+{
+ // Connect or not Pullup
+ pPio->PIO_PPUDR = ~pullupEnable;
+ pPio->PIO_PPUER = pullupEnable;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgDirectDrive
+//* \brief Enable direct drive on PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_CfgDirectDrive (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int directDrive) // \arg PIO to be configured with direct drive
+{
+ // Configure the Direct Drive
+ pPio->PIO_OWDR = ~directDrive;
+ pPio->PIO_OWER = directDrive;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_CfgInputFilter
+//* \brief Enable input filter on input PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_CfgInputFilter (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int inputFilter) // \arg PIO to be configured with input filter
+{
+ // Configure the Direct Drive
+ pPio->PIO_IFDR = ~inputFilter;
+ pPio->PIO_IFER = inputFilter;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetInput
+//* \brief Return PIO input value
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetInput ( // \return PIO input
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_PDSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsInputSet
+//* \brief Test if PIO is input flag is active
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsInputSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetInput (pPio) & flag);
+}
+
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_SetOutput
+//* \brief Set to 1 output PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_SetOutput (const AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ const unsigned int flag) // \arg output to be set
+{
+ pPio->PIO_SODR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_ClearOutput
+//* \brief Set to 0 output PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_ClearOutput (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg output to be cleared
+{
+ pPio->PIO_CODR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_ForceOutput
+//* \brief Force output when Direct drive option is enabled
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_ForceOutput (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg output to be forced
+{
+ pPio->PIO_ODSR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_Enable
+//* \brief Enable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_Enable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio to be enabled
+{
+ pPio->PIO_PER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_Disable
+//* \brief Disable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_Disable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio to be disabled
+{
+ pPio->PIO_PDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetStatus
+//* \brief Return PIO Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetStatus ( // \return PIO Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_PSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsSet
+//* \brief Test if PIO is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_OutputEnable
+//* \brief Output Enable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_OutputEnable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio output to be enabled
+{
+ pPio->PIO_OER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_OutputDisable
+//* \brief Output Enable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_OutputDisable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio output to be disabled
+{
+ pPio->PIO_ODR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetOutputStatus
+//* \brief Return PIO Output Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetOutputStatus ( // \return PIO Output Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_OSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsOuputSet
+//* \brief Test if PIO Output is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsOutputSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetOutputStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_InputFilterEnable
+//* \brief Input Filter Enable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_InputFilterEnable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio input filter to be enabled
+{
+ pPio->PIO_IFER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_InputFilterDisable
+//* \brief Input Filter Disable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_InputFilterDisable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio input filter to be disabled
+{
+ pPio->PIO_IFDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetInputFilterStatus
+//* \brief Return PIO Input Filter Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetInputFilterStatus ( // \return PIO Input Filter Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_IFSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsInputFilterSet
+//* \brief Test if PIO Input filter is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsInputFilterSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetInputFilterStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetOutputDataStatus
+//* \brief Return PIO Output Data Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetOutputDataStatus ( // \return PIO Output Data Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_ODSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_InterruptEnable
+//* \brief Enable PIO Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_InterruptEnable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio interrupt to be enabled
+{
+ pPio->PIO_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_InterruptDisable
+//* \brief Disable PIO Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_InterruptDisable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio interrupt to be disabled
+{
+ pPio->PIO_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetInterruptMaskStatus
+//* \brief Return PIO Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetInterruptMaskStatus ( // \return PIO Interrupt Mask Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetInterruptStatus
+//* \brief Return PIO Interrupt Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetInterruptStatus ( // \return PIO Interrupt Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_ISR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsInterruptMasked
+//* \brief Test if PIO Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsInterruptMasked (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetInterruptMaskStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsInterruptSet
+//* \brief Test if PIO Interrupt is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsInterruptSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetInterruptStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_MultiDriverEnable
+//* \brief Multi Driver Enable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_MultiDriverEnable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio to be enabled
+{
+ pPio->PIO_MDER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_MultiDriverDisable
+//* \brief Multi Driver Disable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_MultiDriverDisable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio to be disabled
+{
+ pPio->PIO_MDDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetMultiDriverStatus
+//* \brief Return PIO Multi Driver Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetMultiDriverStatus ( // \return PIO Multi Driver Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_MDSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsMultiDriverSet
+//* \brief Test if PIO MultiDriver is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsMultiDriverSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetMultiDriverStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_A_RegisterSelection
+//* \brief PIO A Register Selection
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_A_RegisterSelection (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio A register selection
+{
+ pPio->PIO_ASR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_B_RegisterSelection
+//* \brief PIO B Register Selection
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_B_RegisterSelection (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio B register selection
+{
+ pPio->PIO_BSR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_Get_AB_RegisterStatus
+//* \brief Return PIO Interrupt Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_Get_AB_RegisterStatus ( // \return PIO AB Register Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_ABSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsAB_RegisterSet
+//* \brief Test if PIO AB Register is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsAB_RegisterSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_Get_AB_RegisterStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_OutputWriteEnable
+//* \brief Output Write Enable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_OutputWriteEnable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio output write to be enabled
+{
+ pPio->PIO_OWER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_OutputWriteDisable
+//* \brief Output Write Disable PIO
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIO_OutputWriteDisable (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg pio output write to be disabled
+{
+ pPio->PIO_OWDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetOutputWriteStatus
+//* \brief Return PIO Output Write Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetOutputWriteStatus ( // \return PIO Output Write Status
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_OWSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsOutputWriteSet
+//* \brief Test if PIO OutputWrite is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsOutputWriteSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetOutputWriteStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_GetCfgPullup
+//* \brief Return PIO Configuration Pullup
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PIO_GetCfgPullup ( // \return PIO Configuration Pullup
+ AT91PS_PIO pPio) // \arg pointer to a PIO controller
+{
+ return pPio->PIO_PPUSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsOutputDataStatusSet
+//* \brief Test if PIO Output Data Status is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsOutputDataStatusSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PIO_GetOutputDataStatus (pPio) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIO_IsCfgPullupStatusSet
+//* \brief Test if PIO Configuration Pullup Status is Set
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_PIO_IsCfgPullupStatusSet (AT91PS_PIO pPio, // \arg pointer to a PIO controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (~AT91F_PIO_GetCfgPullup (pPio) & flag);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR PMC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_CfgSysClkEnableReg
+//* \brief Configure the System Clock Enable Register of the PMC controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_CfgSysClkEnableReg (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int mode)
+{
+ //* Write to the SCER register
+ pPMC->PMC_SCER = mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_CfgSysClkDisableReg
+//* \brief Configure the System Clock Disable Register of the PMC controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_CfgSysClkDisableReg (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int mode)
+{
+ //* Write to the SCDR register
+ pPMC->PMC_SCDR = mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_GetSysClkStatusReg
+//* \brief Return the System Clock Status Register of the PMC controller
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PMC_GetSysClkStatusReg (AT91PS_PMC pPMC // pointer to a CAN controller
+ )
+{
+ return pPMC->PMC_SCSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_EnablePeriphClock
+//* \brief Enable peripheral clock
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_EnablePeriphClock (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int periphIds) // \arg IDs of peripherals to enable
+{
+ pPMC->PMC_PCER = periphIds;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_DisablePeriphClock
+//* \brief Disable peripheral clock
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_DisablePeriphClock (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int periphIds) // \arg IDs of peripherals to enable
+{
+ pPMC->PMC_PCDR = periphIds;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_GetPeriphClock
+//* \brief Get peripheral clock status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PMC_GetPeriphClock (AT91PS_PMC pPMC) // \arg pointer to PMC controller
+{
+ return pPMC->PMC_PCSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_CKGR_CfgMainOscillatorReg
+//* \brief Cfg the main oscillator
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_CKGR_CfgMainOscillatorReg (AT91PS_CKGR pCKGR, // \arg pointer to CKGR controller
+ unsigned int mode)
+{
+ pCKGR->CKGR_MOR = mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_CKGR_GetMainOscillatorReg
+//* \brief Cfg the main oscillator
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_CKGR_GetMainOscillatorReg (AT91PS_CKGR pCKGR) // \arg pointer to CKGR controller
+{
+ return pCKGR->CKGR_MOR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_CKGR_EnableMainOscillator
+//* \brief Enable the main oscillator
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_CKGR_EnableMainOscillator (AT91PS_CKGR pCKGR) // \arg pointer to CKGR controller
+{
+ pCKGR->CKGR_MOR |= AT91C_CKGR_MOSCEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_CKGR_DisableMainOscillator
+//* \brief Disable the main oscillator
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_CKGR_DisableMainOscillator (AT91PS_CKGR pCKGR) // \arg pointer to CKGR controller
+{
+ pCKGR->CKGR_MOR &= ~AT91C_CKGR_MOSCEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_CKGR_CfgMainOscStartUpTime
+//* \brief Cfg MOR Register according to the main osc startup time
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_CKGR_CfgMainOscStartUpTime (AT91PS_CKGR pCKGR, // \arg pointer to CKGR controller
+ unsigned int startup_time, // \arg main osc startup time in microsecond (us)
+ unsigned int slowClock) // \arg slowClock in Hz
+{
+ pCKGR->CKGR_MOR &= ~AT91C_CKGR_OSCOUNT;
+ pCKGR->CKGR_MOR |= ((slowClock * startup_time) / (8 * 1000000)) << 8;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_CKGR_GetMainClockFreqReg
+//* \brief Cfg the main oscillator
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_CKGR_GetMainClockFreqReg (AT91PS_CKGR pCKGR) // \arg pointer to CKGR controller
+{
+ return pCKGR->CKGR_MCFR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_CKGR_GetMainClock
+//* \brief Return Main clock in Hz
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_CKGR_GetMainClock (AT91PS_CKGR pCKGR, // \arg pointer to CKGR controller
+ unsigned int slowClock) // \arg slowClock in Hz
+{
+ return ((pCKGR->CKGR_MCFR & AT91C_CKGR_MAINF) * slowClock) >> 4;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_CfgMCKReg
+//* \brief Cfg Master Clock Register
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_CfgMCKReg (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int mode)
+{
+ pPMC->PMC_MCKR = mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_GetMCKReg
+//* \brief Return Master Clock Register
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PMC_GetMCKReg (AT91PS_PMC pPMC) // \arg pointer to PMC controller
+{
+ return pPMC->PMC_MCKR;
+}
+
+//*------------------------------------------------------------------------------
+//* \fn AT91F_PMC_GetMasterClock
+//* \brief Return master clock in Hz which correponds to processor clock for ARM7
+//*------------------------------------------------------------------------------
+extern unsigned int AT91F_PMC_GetMasterClock (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ AT91PS_CKGR pCKGR, // \arg pointer to CKGR controller
+ unsigned int slowClock); // \arg slowClock in Hz
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_EnablePCK
+//* \brief Enable peripheral clock
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_EnablePCK (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int pck, // \arg Peripheral clock identifier 0 .. 7
+ unsigned int mode)
+{
+ pPMC->PMC_PCKR[pck] = mode;
+ pPMC->PMC_SCER = (1 << pck) << 8;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_DisablePCK
+//* \brief Enable peripheral clock
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_DisablePCK (AT91PS_PMC pPMC, // \arg pointer to PMC controller
+ unsigned int pck) // \arg Peripheral clock identifier 0 .. 7
+{
+ pPMC->PMC_SCDR = (1 << pck) << 8;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_EnableIt
+//* \brief Enable PMC interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_EnableIt (AT91PS_PMC pPMC, // pointer to a PMC controller
+ unsigned int flag) // IT to be enabled
+{
+ //* Write to the IER register
+ pPMC->PMC_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_DisableIt
+//* \brief Disable PMC interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_DisableIt (AT91PS_PMC pPMC, // pointer to a PMC controller
+ unsigned int flag) // IT to be disabled
+{
+ //* Write to the IDR register
+ pPMC->PMC_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_GetStatus
+//* \brief Return PMC Interrupt Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PMC_GetStatus ( // \return PMC Interrupt Status
+ AT91PS_PMC pPMC) // pointer to a PMC controller
+{
+ return pPMC->PMC_SR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_GetInterruptMaskStatus
+//* \brief Return PMC Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PMC_GetInterruptMaskStatus ( // \return PMC Interrupt Mask Status
+ AT91PS_PMC pPMC) // pointer to a PMC controller
+{
+ return pPMC->PMC_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_IsInterruptMasked
+//* \brief Test if PMC Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PMC_IsInterruptMasked (AT91PS_PMC pPMC, // \arg pointer to a PMC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PMC_GetInterruptMaskStatus (pPMC) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_IsStatusSet
+//* \brief Test if PMC Status is Set
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PMC_IsStatusSet (AT91PS_PMC pPMC, // \arg pointer to a PMC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PMC_GetStatus (pPMC) & flag);
+}
+
+// ----------------------------------------------------------------------------
+// \fn AT91F_CKGR_CfgPLLReg
+// \brief Cfg the PLL Register
+// ----------------------------------------------------------------------------
+static inline void
+AT91F_CKGR_CfgPLLReg (AT91PS_CKGR pCKGR, // \arg pointer to CKGR controller
+ unsigned int mode)
+{
+ pCKGR->CKGR_PLLR = mode;
+}
+
+// ----------------------------------------------------------------------------
+// \fn AT91F_CKGR_GetPLLReg
+// \brief Get the PLL Register
+// ----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_CKGR_GetPLLReg (AT91PS_CKGR pCKGR) // \arg pointer to CKGR controller
+{
+ return pCKGR->CKGR_PLLR;
+}
+
+
+
+/* *****************************************************************************
+ SOFTWARE API FOR RSTC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_RSTSoftReset
+//* \brief Start Software Reset
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_RSTSoftReset (AT91PS_RSTC pRSTC, unsigned int reset)
+{
+ pRSTC->RSTC_RCR = (0xA5000000 | reset);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_RSTSetMode
+//* \brief Set Reset Mode
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_RSTSetMode (AT91PS_RSTC pRSTC, unsigned int mode)
+{
+ pRSTC->RSTC_RMR = (0xA5000000 | mode);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_RSTGetMode
+//* \brief Get Reset Mode
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_RSTGetMode (AT91PS_RSTC pRSTC)
+{
+ return (pRSTC->RSTC_RMR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_RSTGetStatus
+//* \brief Get Reset Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_RSTGetStatus (AT91PS_RSTC pRSTC)
+{
+ return (pRSTC->RSTC_RSR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_RSTIsSoftRstActive
+//* \brief Return !=0 if software reset is still not completed
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_RSTIsSoftRstActive (AT91PS_RSTC pRSTC)
+{
+ return ((pRSTC->RSTC_RSR) & AT91C_RSTC_SRCMP);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR RTTC
+ ***************************************************************************** */
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_SetRTT_TimeBase()
+//* \brief Set the RTT prescaler according to the TimeBase in ms
+//*--------------------------------------------------------------------------------------
+static inline unsigned int
+AT91F_RTTSetTimeBase (AT91PS_RTTC pRTTC, unsigned int ms)
+{
+ if (ms > 2000)
+ return 1; // AT91C_TIME_OUT_OF_RANGE
+ pRTTC->RTTC_RTMR &= ~0xFFFF;
+ pRTTC->RTTC_RTMR |= (((ms << 15) / 1000) & 0xFFFF);
+ return 0;
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTTSetPrescaler()
+//* \brief Set the new prescaler value
+//*--------------------------------------------------------------------------------------
+static inline unsigned int
+AT91F_RTTSetPrescaler (AT91PS_RTTC pRTTC, unsigned int rtpres)
+{
+ pRTTC->RTTC_RTMR &= ~0xFFFF;
+ pRTTC->RTTC_RTMR |= (rtpres & 0xFFFF);
+ return (pRTTC->RTTC_RTMR);
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTTRestart()
+//* \brief Restart the RTT prescaler
+//*--------------------------------------------------------------------------------------
+static inline void
+AT91F_RTTRestart (AT91PS_RTTC pRTTC)
+{
+ pRTTC->RTTC_RTMR |= AT91C_RTTC_RTTRST;
+}
+
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_SetAlarmINT()
+//* \brief Enable RTT Alarm Interrupt
+//*--------------------------------------------------------------------------------------
+static inline void
+AT91F_RTTSetAlarmINT (AT91PS_RTTC pRTTC)
+{
+ pRTTC->RTTC_RTMR |= AT91C_RTTC_ALMIEN;
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_ClearAlarmINT()
+//* \brief Disable RTT Alarm Interrupt
+//*--------------------------------------------------------------------------------------
+static inline void
+AT91F_RTTClearAlarmINT (AT91PS_RTTC pRTTC)
+{
+ pRTTC->RTTC_RTMR &= ~AT91C_RTTC_ALMIEN;
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_SetRttIncINT()
+//* \brief Enable RTT INC Interrupt
+//*--------------------------------------------------------------------------------------
+static inline void
+AT91F_RTTSetRttIncINT (AT91PS_RTTC pRTTC)
+{
+ pRTTC->RTTC_RTMR |= AT91C_RTTC_RTTINCIEN;
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_ClearRttIncINT()
+//* \brief Disable RTT INC Interrupt
+//*--------------------------------------------------------------------------------------
+static inline void
+AT91F_RTTClearRttIncINT (AT91PS_RTTC pRTTC)
+{
+ pRTTC->RTTC_RTMR &= ~AT91C_RTTC_RTTINCIEN;
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_SetAlarmValue()
+//* \brief Set RTT Alarm Value
+//*--------------------------------------------------------------------------------------
+static inline void
+AT91F_RTTSetAlarmValue (AT91PS_RTTC pRTTC, unsigned int _alarm)
+{
+ pRTTC->RTTC_RTAR = _alarm;
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_GetAlarmValue()
+//* \brief Get RTT Alarm Value
+//*--------------------------------------------------------------------------------------
+static inline unsigned int
+AT91F_RTTGetAlarmValue (AT91PS_RTTC pRTTC)
+{
+ return (pRTTC->RTTC_RTAR);
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTTGetStatus()
+//* \brief Read the RTT status
+//*--------------------------------------------------------------------------------------
+static inline unsigned int
+AT91F_RTTGetStatus (AT91PS_RTTC pRTTC)
+{
+ return (pRTTC->RTTC_RTSR);
+}
+
+//*--------------------------------------------------------------------------------------
+//* \fn AT91F_RTT_ReadValue()
+//* \brief Read the RTT value
+//*--------------------------------------------------------------------------------------
+extern unsigned int AT91F_RTTReadValue (AT91PS_RTTC pRTTC);
+
+/* *****************************************************************************
+ SOFTWARE API FOR PITC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITInit
+//* \brief System timer init : period in ‘second, system clock freq in MHz
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PITInit (AT91PS_PITC pPITC,
+ unsigned int period, unsigned int pit_frequency)
+{
+ pPITC->PITC_PIMR = period ? (period * pit_frequency + 8) >> 4 : 0; // +8 to avoid %10 and /10
+ pPITC->PITC_PIMR |= AT91C_PITC_PITEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITSetPIV
+//* \brief Set the PIT Periodic Interval Value
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PITSetPIV (AT91PS_PITC pPITC, unsigned int piv)
+{
+ pPITC->PITC_PIMR =
+ piv | (pPITC->PITC_PIMR & (AT91C_PITC_PITEN | AT91C_PITC_PITIEN));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITEnableInt
+//* \brief Enable PIT periodic interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PITEnableInt (AT91PS_PITC pPITC)
+{
+ pPITC->PITC_PIMR |= AT91C_PITC_PITIEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITDisableInt
+//* \brief Disable PIT periodic interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PITDisableInt (AT91PS_PITC pPITC)
+{
+ pPITC->PITC_PIMR &= ~AT91C_PITC_PITIEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITGetMode
+//* \brief Read PIT mode register
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PITGetMode (AT91PS_PITC pPITC)
+{
+ return (pPITC->PITC_PIMR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITGetStatus
+//* \brief Read PIT status register
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PITGetStatus (AT91PS_PITC pPITC)
+{
+ return (pPITC->PITC_PISR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITGetPIIR
+//* \brief Read PIT CPIV and PICNT without ressetting the counters
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PITGetPIIR (AT91PS_PITC pPITC)
+{
+ return (pPITC->PITC_PIIR);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITGetPIVR
+//* \brief Read System timer CPIV and PICNT without ressetting the counters
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PITGetPIVR (AT91PS_PITC pPITC)
+{
+ return (pPITC->PITC_PIVR);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR WDTC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_WDTSetMode
+//* \brief Set Watchdog Mode Register
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_WDTSetMode (AT91PS_WDTC pWDTC, unsigned int Mode)
+{
+ pWDTC->WDTC_WDMR = Mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_WDTRestart
+//* \brief Restart Watchdog
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_WDTRestart (AT91PS_WDTC pWDTC)
+{
+ pWDTC->WDTC_WDCR = 0xA5000001;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_WDTSGettatus
+//* \brief Get Watchdog Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_WDTSGettatus (AT91PS_WDTC pWDTC)
+{
+ return (pWDTC->WDTC_WDSR & 0x3);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_WDTGetPeriod
+//* \brief Translate ms into Watchdog Compatible value
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_WDTGetPeriod (unsigned int ms)
+{
+ if ((ms < 4) || (ms > 16000))
+ return 0;
+ return ((ms << 8) / 1000);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR VREG
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_VREG_Enable_LowPowerMode
+//* \brief Enable VREG Low Power Mode
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_VREG_Enable_LowPowerMode (AT91PS_VREG pVREG)
+{
+ pVREG->VREG_MR |= AT91C_VREG_PSTDBY;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_VREG_Disable_LowPowerMode
+//* \brief Disable VREG Low Power Mode
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_VREG_Disable_LowPowerMode (AT91PS_VREG pVREG)
+{
+ pVREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
+} /* *****************************************************************************
+ SOFTWARE API FOR MC
+ ***************************************************************************** */
+
+#define AT91C_MC_CORRECT_KEY ((unsigned int) 0x5A << 24) // (MC) Correct Protect Key
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_Remap
+//* \brief Make Remap
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_MC_Remap (void) //
+{
+ AT91PS_MC pMC = (AT91PS_MC) AT91C_BASE_MC;
+
+ pMC->MC_RCR = AT91C_MC_RCB;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_EFC_CfgModeReg
+//* \brief Configure the EFC Mode Register of the MC controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_MC_EFC_CfgModeReg (AT91PS_MC pMC, // pointer to a MC controller
+ unsigned int mode) // mode register
+{
+ // Write to the FMR register
+ pMC->MC_FMR = mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_EFC_GetModeReg
+//* \brief Return MC EFC Mode Regsiter
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_MC_EFC_GetModeReg (AT91PS_MC pMC) // pointer to a MC controller
+{
+ return pMC->MC_FMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_EFC_ComputeFMCN
+//* \brief Return MC EFC Mode Regsiter
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_MC_EFC_ComputeFMCN (int master_clock) // master clock in Hz
+{
+ return (master_clock / 1000000 + 2);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_EFC_PerformCmd
+//* \brief Perform EFC Command
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_MC_EFC_PerformCmd (AT91PS_MC pMC, // pointer to a MC controller
+ unsigned int transfer_cmd)
+{
+ pMC->MC_FCR = transfer_cmd;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_EFC_GetStatus
+//* \brief Return MC EFC Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_MC_EFC_GetStatus (AT91PS_MC pMC) // pointer to a MC controller
+{
+ return pMC->MC_FSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_EFC_IsInterruptMasked
+//* \brief Test if EFC MC Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_MC_EFC_IsInterruptMasked (AT91PS_MC pMC, // \arg pointer to a MC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_MC_EFC_GetModeReg (pMC) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_EFC_IsInterruptSet
+//* \brief Test if EFC MC Interrupt is Set
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_MC_EFC_IsInterruptSet (AT91PS_MC pMC, // \arg pointer to a MC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_MC_EFC_GetStatus (pMC) & flag);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR SPI
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_CfgCs
+//* \brief Configure SPI chip select register
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_CfgCs (AT91PS_SPI pSPI, // pointer to a SPI controller
+ int cs, // SPI cs number (0 to 3)
+ int val) // chip select register
+{
+ //* Write to the CSR register
+ *(pSPI->SPI_CSR + cs) = val;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_EnableIt
+//* \brief Enable SPI interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_EnableIt (AT91PS_SPI pSPI, // pointer to a SPI controller
+ unsigned int flag) // IT to be enabled
+{
+ //* Write to the IER register
+ pSPI->SPI_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_DisableIt
+//* \brief Disable SPI interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_DisableIt (AT91PS_SPI pSPI, // pointer to a SPI controller
+ unsigned int flag) // IT to be disabled
+{
+ //* Write to the IDR register
+ pSPI->SPI_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_Reset
+//* \brief Reset the SPI controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_Reset (AT91PS_SPI pSPI // pointer to a SPI controller
+ )
+{
+ //* Write to the CR register
+ pSPI->SPI_CR = AT91C_SPI_SWRST;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_Enable
+//* \brief Enable the SPI controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_Enable (AT91PS_SPI pSPI // pointer to a SPI controller
+ )
+{
+ //* Write to the CR register
+ pSPI->SPI_CR = AT91C_SPI_SPIEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_Disable
+//* \brief Disable the SPI controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_Disable (AT91PS_SPI pSPI // pointer to a SPI controller
+ )
+{
+ //* Write to the CR register
+ pSPI->SPI_CR = AT91C_SPI_SPIDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_CfgMode
+//* \brief Enable the SPI controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_CfgMode (AT91PS_SPI pSPI, // pointer to a SPI controller
+ int mode) // mode register
+{
+ //* Write to the MR register
+ pSPI->SPI_MR = mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_CfgPCS
+//* \brief Switch to the correct PCS of SPI Mode Register : Fixed Peripheral Selected
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_CfgPCS (AT91PS_SPI pSPI, // pointer to a SPI controller
+ char PCS_Device) // PCS of the Device
+{
+ //* Write to the MR register
+ pSPI->SPI_MR &= 0xFFF0FFFF;
+ pSPI->SPI_MR |= ((PCS_Device << 16) & AT91C_SPI_PCS);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_ReceiveFrame
+//* \brief Return 2 if PDC has been initialized with Buffer and Next Buffer, 1 if PDC has been initializaed with Next Buffer, 0 if PDC is busy
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_SPI_ReceiveFrame (AT91PS_SPI pSPI,
+ unsigned char *pBuffer,
+ unsigned int szBuffer,
+ unsigned char *pNextBuffer, unsigned int szNextBuffer)
+{
+ return AT91F_PDC_ReceiveFrame ((AT91PS_PDC) & (pSPI->SPI_RPR),
+ pBuffer,
+ szBuffer, pNextBuffer, szNextBuffer);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_SendFrame
+//* \brief Return 2 if PDC has been initialized with Buffer and Next Buffer, 1 if PDC has been initializaed with Next Buffer, 0 if PDC is bSPIy
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_SPI_SendFrame (AT91PS_SPI pSPI,
+ const unsigned char *pBuffer,
+ unsigned int szBuffer,
+ const unsigned char *pNextBuffer,
+ unsigned int szNextBuffer)
+{
+ return AT91F_PDC_SendFrame ((AT91PS_PDC) & (pSPI->SPI_RPR),
+ pBuffer, szBuffer, pNextBuffer, szNextBuffer);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_Close
+//* \brief Close SPI: disable IT disable transfert, close PDC
+//*----------------------------------------------------------------------------
+extern void AT91F_SPI_Close (AT91PS_SPI pSPI); // \arg pointer to a SPI controller
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_PutChar
+//* \brief Send a character,does not check if ready to send
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_PutChar (AT91PS_SPI pSPI,
+ unsigned int character, unsigned int cs_number)
+{
+ unsigned int value_for_cs;
+ value_for_cs = (~(1 << cs_number)) & 0xF; //Place a zero among a 4 ONEs number
+ pSPI->SPI_TDR = (character & 0xFFFF) | (value_for_cs << 16);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_GetChar
+//* \brief Receive a character,does not check if a character is available
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_SPI_GetChar (const AT91PS_SPI pSPI)
+{
+ return ((pSPI->SPI_RDR) & 0xFFFF);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_GetInterruptMaskStatus
+//* \brief Return SPI Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_SPI_GetInterruptMaskStatus ( // \return SPI Interrupt Mask Status
+ AT91PS_SPI pSpi) // \arg pointer to a SPI controller
+{
+ return pSpi->SPI_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_IsInterruptMasked
+//* \brief Test if SPI Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_SPI_IsInterruptMasked (AT91PS_SPI pSpi, // \arg pointer to a SPI controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_SPI_GetInterruptMaskStatus (pSpi) & flag);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR ADC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_EnableIt
+//* \brief Enable ADC interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_EnableIt (AT91PS_ADC pADC, // pointer to a ADC controller
+ unsigned int flag) // IT to be enabled
+{
+ //* Write to the IER register
+ pADC->ADC_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_DisableIt
+//* \brief Disable ADC interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_DisableIt (AT91PS_ADC pADC, // pointer to a ADC controller
+ unsigned int flag) // IT to be disabled
+{
+ //* Write to the IDR register
+ pADC->ADC_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetStatus
+//* \brief Return ADC Interrupt Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetStatus ( // \return ADC Interrupt Status
+ AT91PS_ADC pADC) // pointer to a ADC controller
+{
+ return pADC->ADC_SR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetInterruptMaskStatus
+//* \brief Return ADC Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetInterruptMaskStatus ( // \return ADC Interrupt Mask Status
+ AT91PS_ADC pADC) // pointer to a ADC controller
+{
+ return pADC->ADC_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_IsInterruptMasked
+//* \brief Test if ADC Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_IsInterruptMasked (AT91PS_ADC pADC, // \arg pointer to a ADC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_ADC_GetInterruptMaskStatus (pADC) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_IsStatusSet
+//* \brief Test if ADC Status is Set
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_IsStatusSet (AT91PS_ADC pADC, // \arg pointer to a ADC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_ADC_GetStatus (pADC) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_CfgModeReg
+//* \brief Configure the Mode Register of the ADC controller
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_CfgModeReg (AT91PS_ADC pADC, // pointer to a ADC controller
+ unsigned int mode) // mode register
+{
+ //* Write to the MR register
+ pADC->ADC_MR = mode;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetModeReg
+//* \brief Return the Mode Register of the ADC controller value
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetModeReg (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_MR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_CfgTimings
+//* \brief Configure the different necessary timings of the ADC controller
+//*----------------------------------------------------------------------------
+extern void AT91F_ADC_CfgTimings (AT91PS_ADC pADC, // pointer to a ADC controller
+ unsigned int mck_clock, // in MHz
+ unsigned int adc_clock, // in MHz
+ unsigned int startup_time, // in us
+ unsigned int sample_and_hold_time); // in ns
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_EnableChannel
+//* \brief Return ADC Timer Register Value
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_EnableChannel (AT91PS_ADC pADC, // pointer to a ADC controller
+ unsigned int channel) // mode register
+{
+ //* Write to the CHER register
+ pADC->ADC_CHER = channel;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_DisableChannel
+//* \brief Return ADC Timer Register Value
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_DisableChannel (AT91PS_ADC pADC, // pointer to a ADC controller
+ unsigned int channel) // mode register
+{
+ //* Write to the CHDR register
+ pADC->ADC_CHDR = channel;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetChannelStatus
+//* \brief Return ADC Timer Register Value
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetChannelStatus (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CHSR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_StartConversion
+//* \brief Software request for a analog to digital conversion
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_StartConversion (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ pADC->ADC_CR = AT91C_ADC_START;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_SoftReset
+//* \brief Software reset
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_SoftReset (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ pADC->ADC_CR = AT91C_ADC_SWRST;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetLastConvertedData
+//* \brief Return the Last Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetLastConvertedData (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_LCDR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH0
+//* \brief Return the Channel 0 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH0 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH1
+//* \brief Return the Channel 1 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH1 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR1;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH2
+//* \brief Return the Channel 2 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH2 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR2;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH3
+//* \brief Return the Channel 3 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH3 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR3;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH4
+//* \brief Return the Channel 4 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH4 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR4;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH5
+//* \brief Return the Channel 5 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH5 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR5;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH6
+//* \brief Return the Channel 6 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH6 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR6;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_GetConvertedDataCH7
+//* \brief Return the Channel 7 Converted Data
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_ADC_GetConvertedDataCH7 (AT91PS_ADC pADC // pointer to a ADC controller
+ )
+{
+ return pADC->ADC_CDR7;
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR SSC
+ ***************************************************************************** */
+//* Define the standard I2S mode configuration
+
+//* Configuration to set in the SSC Transmit Clock Mode Register
+//* Parameters : nb_bit_by_slot : 8, 16 or 32 bits
+//* nb_slot_by_frame : number of channels
+#define AT91C_I2S_ASY_MASTER_TX_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\
+ AT91C_SSC_CKS_DIV +\
+ AT91C_SSC_CKO_CONTINOUS +\
+ AT91C_SSC_CKG_NONE +\
+ AT91C_SSC_START_FALL_RF +\
+ AT91C_SSC_STTOUT +\
+ ((1<<16) & AT91C_SSC_STTDLY) +\
+ ((((nb_bit_by_slot*nb_slot_by_frame)/2)-1) <<24))
+
+
+//* Configuration to set in the SSC Transmit Frame Mode Register
+//* Parameters : nb_bit_by_slot : 8, 16 or 32 bits
+//* nb_slot_by_frame : number of channels
+#define AT91C_I2S_ASY_TX_FRAME_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\
+ (nb_bit_by_slot-1) +\
+ AT91C_SSC_MSBF +\
+ (((nb_slot_by_frame-1)<<8) & AT91C_SSC_DATNB) +\
+ (((nb_bit_by_slot-1)<<16) & AT91C_SSC_FSLEN) +\
+ AT91C_SSC_FSOS_NEGATIVE)
+
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_SetBaudrate
+//* \brief Set the baudrate according to the CPU clock
+//*----------------------------------------------------------------------------
+extern void AT91F_SSC_SetBaudrate (AT91PS_SSC pSSC, // \arg pointer to a SSC controller
+ unsigned int mainClock, // \arg peripheral clock
+ unsigned int speed); // \arg SSC baudrate
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_Configure
+//* \brief Configure SSC
+//*----------------------------------------------------------------------------
+extern void AT91F_SSC_Configure (AT91PS_SSC pSSC, // \arg pointer to a SSC controller
+ unsigned int syst_clock, // \arg System Clock Frequency
+ unsigned int baud_rate, // \arg Expected Baud Rate Frequency
+ unsigned int clock_rx, // \arg Receiver Clock Parameters
+ unsigned int mode_rx, // \arg mode Register to be programmed
+ unsigned int clock_tx, // \arg Transmitter Clock Parameters
+ unsigned int mode_tx); // \arg mode Register to be programmed
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_EnableRx
+//* \brief Enable receiving datas
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_EnableRx (AT91PS_SSC pSSC) // \arg pointer to a SSC controller
+{
+ //* Enable receiver
+ pSSC->SSC_CR = AT91C_SSC_RXEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_DisableRx
+//* \brief Disable receiving datas
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_DisableRx (AT91PS_SSC pSSC) // \arg pointer to a SSC controller
+{
+ //* Disable receiver
+ pSSC->SSC_CR = AT91C_SSC_RXDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_EnableTx
+//* \brief Enable sending datas
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_EnableTx (AT91PS_SSC pSSC) // \arg pointer to a SSC controller
+{
+ //* Enable transmitter
+ pSSC->SSC_CR = AT91C_SSC_TXEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_DisableTx
+//* \brief Disable sending datas
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_DisableTx (AT91PS_SSC pSSC) // \arg pointer to a SSC controller
+{
+ //* Disable transmitter
+ pSSC->SSC_CR = AT91C_SSC_TXDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_EnableIt
+//* \brief Enable SSC IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_EnableIt (AT91PS_SSC pSSC, // \arg pointer to a SSC controller
+ unsigned int flag) // \arg IT to be enabled
+{
+ //* Write to the IER register
+ pSSC->SSC_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_DisableIt
+//* \brief Disable SSC IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_DisableIt (AT91PS_SSC pSSC, // \arg pointer to a SSC controller
+ unsigned int flag) // \arg IT to be disabled
+{
+ //* Write to the IDR register
+ pSSC->SSC_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_ReceiveFrame
+//* \brief Return 2 if PDC has been initialized with Buffer and Next Buffer, 1 if PDC has been initialized with Next Buffer, 0 if PDC is busy
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_SSC_ReceiveFrame (AT91PS_SSC pSSC,
+ unsigned char *pBuffer,
+ unsigned int szBuffer,
+ unsigned char *pNextBuffer, unsigned int szNextBuffer)
+{
+ return AT91F_PDC_ReceiveFrame ((AT91PS_PDC) & (pSSC->SSC_RPR),
+ pBuffer,
+ szBuffer, pNextBuffer, szNextBuffer);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_SendFrame
+//* \brief Return 2 if PDC has been initialized with Buffer and Next Buffer, 1 if PDC has been initialized with Next Buffer, 0 if PDC is busy
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_SSC_SendFrame (AT91PS_SSC pSSC,
+ const unsigned char *pBuffer,
+ unsigned int szBuffer,
+ const unsigned char *pNextBuffer,
+ unsigned int szNextBuffer)
+{
+ return AT91F_PDC_SendFrame ((AT91PS_PDC) & (pSSC->SSC_RPR),
+ pBuffer, szBuffer, pNextBuffer, szNextBuffer);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_GetInterruptMaskStatus
+//* \brief Return SSC Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_SSC_GetInterruptMaskStatus ( // \return SSC Interrupt Mask Status
+ AT91PS_SSC pSsc) // \arg pointer to a SSC controller
+{
+ return pSsc->SSC_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_IsInterruptMasked
+//* \brief Test if SSC Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_SSC_IsInterruptMasked (AT91PS_SSC pSsc, // \arg pointer to a SSC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_SSC_GetInterruptMaskStatus (pSsc) & flag);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR USART
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_Baudrate
+//* \brief Calculate the baudrate
+//* Standard Asynchronous Mode : 8 bits , 1 stop , no parity
+#define AT91C_US_ASYNC_MODE ( AT91C_US_USMODE_NORMAL + \
+ AT91C_US_NBSTOP_1_BIT + \
+ AT91C_US_PAR_NONE + \
+ AT91C_US_CHRL_8_BITS + \
+ AT91C_US_CLKS_CLOCK )
+
+//* Standard External Asynchronous Mode : 8 bits , 1 stop , no parity
+#define AT91C_US_ASYNC_SCK_MODE ( AT91C_US_USMODE_NORMAL + \
+ AT91C_US_NBSTOP_1_BIT + \
+ AT91C_US_PAR_NONE + \
+ AT91C_US_CHRL_8_BITS + \
+ AT91C_US_CLKS_EXT )
+
+//* Standard Synchronous Mode : 8 bits , 1 stop , no parity
+#define AT91C_US_SYNC_MODE ( AT91C_US_SYNC + \
+ AT91C_US_USMODE_NORMAL + \
+ AT91C_US_NBSTOP_1_BIT + \
+ AT91C_US_PAR_NONE + \
+ AT91C_US_CHRL_8_BITS + \
+ AT91C_US_CLKS_CLOCK )
+
+//* SCK used Label
+#define AT91C_US_SCK_USED (AT91C_US_CKLO | AT91C_US_CLKS_EXT)
+
+//* Standard ISO T=0 Mode : 8 bits , 1 stop , parity
+#define AT91C_US_ISO_READER_MODE ( AT91C_US_USMODE_ISO7816_0 + \
+ AT91C_US_CLKS_CLOCK +\
+ AT91C_US_NBSTOP_1_BIT + \
+ AT91C_US_PAR_EVEN + \
+ AT91C_US_CHRL_8_BITS + \
+ AT91C_US_CKLO +\
+ AT91C_US_OVER)
+
+//* Standard IRDA mode
+#define AT91C_US_ASYNC_IRDA_MODE ( AT91C_US_USMODE_IRDA + \
+ AT91C_US_NBSTOP_1_BIT + \
+ AT91C_US_PAR_NONE + \
+ AT91C_US_CHRL_8_BITS + \
+ AT91C_US_CLKS_CLOCK )
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_Baudrate
+//* \brief Caluculate baud_value according to the main clock and the baud rate
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_US_Baudrate (const unsigned int main_clock, // \arg peripheral clock
+ const unsigned int baud_rate) // \arg UART baudrate
+{
+ unsigned int baud_value = ((main_clock * 10) / (baud_rate * 16));
+ if ((baud_value % 10) >= 5)
+ baud_value = (baud_value / 10) + 1;
+ else
+ baud_value /= 10;
+ return baud_value;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_SetBaudrate
+//* \brief Set the baudrate according to the CPU clock
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_SetBaudrate (AT91PS_USART pUSART, // \arg pointer to a USART controller
+ unsigned int mainClock, // \arg peripheral clock
+ unsigned int speed) // \arg UART baudrate
+{
+ //* Define the baud rate divisor register
+ pUSART->US_BRGR = AT91F_US_Baudrate (mainClock, speed);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_SetTimeguard
+//* \brief Set USART timeguard
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_SetTimeguard (AT91PS_USART pUSART, // \arg pointer to a USART controller
+ unsigned int timeguard) // \arg timeguard value
+{
+ //* Write the Timeguard Register
+ pUSART->US_TTGR = timeguard;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_EnableIt
+//* \brief Enable USART IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_EnableIt (AT91PS_USART pUSART, // \arg pointer to a USART controller
+ unsigned int flag) // \arg IT to be enabled
+{
+ //* Write to the IER register
+ pUSART->US_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_DisableIt
+//* \brief Disable USART IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_DisableIt (AT91PS_USART pUSART, // \arg pointer to a USART controller
+ unsigned int flag) // \arg IT to be disabled
+{
+ //* Write to the IER register
+ pUSART->US_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_Configure
+//* \brief Configure USART
+//*----------------------------------------------------------------------------
+extern void AT91F_US_Configure (AT91PS_USART pUSART, // \arg pointer to a USART controller
+ unsigned int mainClock, // \arg peripheral clock
+ unsigned int mode, // \arg mode Register to be programmed
+ unsigned int baudRate, // \arg baudrate to be programmed
+ unsigned int timeguard); // \arg timeguard to be programmed
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_EnableRx
+//* \brief Enable receiving characters
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_EnableRx (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ //* Enable receiver
+ pUSART->US_CR = AT91C_US_RXEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_EnableTx
+//* \brief Enable sending characters
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_EnableTx (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ //* Enable transmitter
+ pUSART->US_CR = AT91C_US_TXEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_ResetRx
+//* \brief Reset Receiver and re-enable it
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_ResetRx (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ //* Reset receiver
+ pUSART->US_CR = AT91C_US_RSTRX;
+ //* Re-Enable receiver
+ pUSART->US_CR = AT91C_US_RXEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_ResetTx
+//* \brief Reset Transmitter and re-enable it
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_ResetTx (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ //* Reset transmitter
+ pUSART->US_CR = AT91C_US_RSTTX;
+ //* Enable transmitter
+ pUSART->US_CR = AT91C_US_TXEN;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_DisableRx
+//* \brief Disable Receiver
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_DisableRx (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ //* Disable receiver
+ pUSART->US_CR = AT91C_US_RXDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_DisableTx
+//* \brief Disable Transmitter
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_DisableTx (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ //* Disable transmitter
+ pUSART->US_CR = AT91C_US_TXDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_Close
+//* \brief Close USART: disable IT disable receiver and transmitter, close PDC
+//*----------------------------------------------------------------------------
+extern void AT91F_US_Close (AT91PS_USART pUSART); // \arg pointer to a USART controller
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_TxReady
+//* \brief Return 1 if a character can be written in US_THR
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_US_TxReady (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ return (pUSART->US_CSR & AT91C_US_TXRDY);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_RxReady
+//* \brief Return 1 if a character can be read in US_RHR
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_US_RxReady (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ return (pUSART->US_CSR & AT91C_US_RXRDY);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_Error
+//* \brief Return the error flag
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_US_Error (AT91PS_USART pUSART) // \arg pointer to a USART controller
+{
+ return (pUSART->US_CSR & (AT91C_US_OVRE | // Overrun error
+ AT91C_US_FRAME | // Framing error
+ AT91C_US_PARE)); // Parity error
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_PutChar
+//* \brief Send a character,does not check if ready to send
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_PutChar (AT91PS_USART pUSART, int character)
+{
+ pUSART->US_THR = (character & 0x1FF);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_GetChar
+//* \brief Receive a character,does not check if a character is available
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_US_GetChar (const AT91PS_USART pUSART)
+{
+ return ((pUSART->US_RHR) & 0x1FF);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_SendFrame
+//* \brief Return 2 if PDC has been initialized with Buffer and Next Buffer, 1 if PDC has been initializaed with Next Buffer, 0 if PDC is busy
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_US_SendFrame (AT91PS_USART pUSART,
+ const unsigned char *pBuffer,
+ unsigned int szBuffer,
+ const unsigned char *pNextBuffer,
+ unsigned int szNextBuffer)
+{
+ return AT91F_PDC_SendFrame ((AT91PS_PDC) & (pUSART->US_RPR),
+ pBuffer, szBuffer, pNextBuffer, szNextBuffer);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_ReceiveFrame
+//* \brief Return 2 if PDC has been initialized with Buffer and Next Buffer, 1 if PDC has been initializaed with Next Buffer, 0 if PDC is busy
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_US_ReceiveFrame (AT91PS_USART pUSART,
+ unsigned char *pBuffer,
+ unsigned int szBuffer,
+ unsigned char *pNextBuffer, unsigned int szNextBuffer)
+{
+ return AT91F_PDC_ReceiveFrame ((AT91PS_PDC) & (pUSART->US_RPR),
+ pBuffer,
+ szBuffer, pNextBuffer, szNextBuffer);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US_SetIrdaFilter
+//* \brief Set the value of IrDa filter tregister
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US_SetIrdaFilter (AT91PS_USART pUSART, unsigned char value)
+{
+ pUSART->US_IF = value;
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR TWI
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TWI_EnableIt
+//* \brief Enable TWI IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TWI_EnableIt (AT91PS_TWI pTWI, // \arg pointer to a TWI controller
+ unsigned int flag) // \arg IT to be enabled
+{
+ //* Write to the IER register
+ pTWI->TWI_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TWI_DisableIt
+//* \brief Disable TWI IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TWI_DisableIt (AT91PS_TWI pTWI, // \arg pointer to a TWI controller
+ unsigned int flag) // \arg IT to be disabled
+{
+ //* Write to the IDR register
+ pTWI->TWI_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TWI_Configure
+//* \brief Configure TWI in master mode
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TWI_Configure (AT91PS_TWI pTWI) // \arg pointer to a TWI controller
+{
+ //* Disable interrupts
+ pTWI->TWI_IDR = (unsigned int) -1;
+
+ //* Reset peripheral
+ pTWI->TWI_CR = AT91C_TWI_SWRST;
+
+ //* Set Master mode
+ pTWI->TWI_CR = AT91C_TWI_MSEN;
+
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TWI_GetInterruptMaskStatus
+//* \brief Return TWI Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_TWI_GetInterruptMaskStatus ( // \return TWI Interrupt Mask Status
+ AT91PS_TWI pTwi) // \arg pointer to a TWI controller
+{
+ return pTwi->TWI_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TWI_IsInterruptMasked
+//* \brief Test if TWI Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_TWI_IsInterruptMasked (AT91PS_TWI pTwi, // \arg pointer to a TWI controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_TWI_GetInterruptMaskStatus (pTwi) & flag);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR TC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC_InterruptEnable
+//* \brief Enable TC Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC_InterruptEnable (AT91PS_TC pTc, // \arg pointer to a TC controller
+ unsigned int flag) // \arg TC interrupt to be enabled
+{
+ pTc->TC_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC_InterruptDisable
+//* \brief Disable TC Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC_InterruptDisable (AT91PS_TC pTc, // \arg pointer to a TC controller
+ unsigned int flag) // \arg TC interrupt to be disabled
+{
+ pTc->TC_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC_GetInterruptMaskStatus
+//* \brief Return TC Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_TC_GetInterruptMaskStatus ( // \return TC Interrupt Mask Status
+ AT91PS_TC pTc) // \arg pointer to a TC controller
+{
+ return pTc->TC_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC_IsInterruptMasked
+//* \brief Test if TC Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_TC_IsInterruptMasked (AT91PS_TC pTc, // \arg pointer to a TC controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_TC_GetInterruptMaskStatus (pTc) & flag);
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR PWMC
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_GetStatus
+//* \brief Return PWM Interrupt Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PWMC_GetStatus ( // \return PWM Interrupt Status
+ AT91PS_PWMC pPWM) // pointer to a PWM controller
+{
+ return pPWM->PWMC_SR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_InterruptEnable
+//* \brief Enable PWM Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_InterruptEnable (AT91PS_PWMC pPwm, // \arg pointer to a PWM controller
+ unsigned int flag) // \arg PWM interrupt to be enabled
+{
+ pPwm->PWMC_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_InterruptDisable
+//* \brief Disable PWM Interrupt
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_InterruptDisable (AT91PS_PWMC pPwm, // \arg pointer to a PWM controller
+ unsigned int flag) // \arg PWM interrupt to be disabled
+{
+ pPwm->PWMC_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_GetInterruptMaskStatus
+//* \brief Return PWM Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PWMC_GetInterruptMaskStatus ( // \return PWM Interrupt Mask Status
+ AT91PS_PWMC pPwm) // \arg pointer to a PWM controller
+{
+ return pPwm->PWMC_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_IsInterruptMasked
+//* \brief Test if PWM Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PWMC_IsInterruptMasked (AT91PS_PWMC pPWM, // \arg pointer to a PWM controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PWMC_GetInterruptMaskStatus (pPWM) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_IsStatusSet
+//* \brief Test if PWM Interrupt is Set
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_PWMC_IsStatusSet (AT91PS_PWMC pPWM, // \arg pointer to a PWM controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_PWMC_GetStatus (pPWM) & flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_CfgChannel
+//* \brief Test if PWM Interrupt is Set
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_CfgChannel (AT91PS_PWMC pPWM, // \arg pointer to a PWM controller
+ unsigned int channelId, // \arg PWM channel ID
+ unsigned int mode, // \arg PWM mode
+ unsigned int period, // \arg PWM period
+ unsigned int duty) // \arg PWM duty cycle
+{
+ pPWM->PWMC_CH[channelId].PWMC_CMR = mode;
+ pPWM->PWMC_CH[channelId].PWMC_CDTYR = duty;
+ pPWM->PWMC_CH[channelId].PWMC_CPRDR = period;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_StartChannel
+//* \brief Enable channel
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_StartChannel (AT91PS_PWMC pPWM, // \arg pointer to a PWM controller
+ unsigned int flag) // \arg Channels IDs to be enabled
+{
+ pPWM->PWMC_ENA = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_StopChannel
+//* \brief Disable channel
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_StopChannel (AT91PS_PWMC pPWM, // \arg pointer to a PWM controller
+ unsigned int flag) // \arg Channels IDs to be enabled
+{
+ pPWM->PWMC_DIS = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWM_UpdateChannel
+//* \brief Update Period or Duty Cycle
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_UpdateChannel (AT91PS_PWMC pPWM, // \arg pointer to a PWM controller
+ unsigned int channelId, // \arg PWM channel ID
+ unsigned int update) // \arg Channels IDs to be enabled
+{
+ pPWM->PWMC_CH[channelId].PWMC_CUPDR = update;
+}
+
+/* *****************************************************************************
+ SOFTWARE API FOR UDP
+ ***************************************************************************** */
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EnableIt
+//* \brief Enable UDP IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EnableIt (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned int flag) // \arg IT to be enabled
+{
+ //* Write to the IER register
+ pUDP->UDP_IER = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_DisableIt
+//* \brief Disable UDP IT
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_DisableIt (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned int flag) // \arg IT to be disabled
+{
+ //* Write to the IDR register
+ pUDP->UDP_IDR = flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_SetAddress
+//* \brief Set UDP functional address
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_SetAddress (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char address) // \arg new UDP address
+{
+ pUDP->UDP_FADDR = (AT91C_UDP_FEN | address);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EnableEp
+//* \brief Enable Endpoint
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EnableEp (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint) // \arg endpoint number
+{
+ pUDP->UDP_CSR[endpoint] |= AT91C_UDP_EPEDS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_DisableEp
+//* \brief Enable Endpoint
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_DisableEp (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint) // \arg endpoint number
+{
+ pUDP->UDP_CSR[endpoint] &= ~AT91C_UDP_EPEDS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_SetState
+//* \brief Set UDP Device state
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_SetState (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned int flag) // \arg new UDP address
+{
+ pUDP->UDP_GLBSTATE &= ~(AT91C_UDP_FADDEN | AT91C_UDP_CONFG);
+ pUDP->UDP_GLBSTATE |= flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_GetState
+//* \brief return UDP Device state
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_UDP_GetState ( // \return the UDP device state
+ AT91PS_UDP pUDP) // \arg pointer to a UDP controller
+{
+ return (pUDP->UDP_GLBSTATE & (AT91C_UDP_FADDEN | AT91C_UDP_CONFG));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_ResetEp
+//* \brief Reset UDP endpoint
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_ResetEp ( // \return the UDP device state
+ AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned int flag) // \arg Endpoints to be reset
+{
+ pUDP->UDP_RSTEP = flag;
+ pUDP->UDP_RSTEP = 0;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EpStall
+//* \brief Endpoint will STALL requests
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EpStall (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint) // \arg endpoint number
+{
+ pUDP->UDP_CSR[endpoint] |= AT91C_UDP_FORCESTALL;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EpWrite
+//* \brief Write value in the DPR
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EpWrite (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint, // \arg endpoint number
+ unsigned char value) // \arg value to be written in the DPR
+{
+ pUDP->UDP_FDR[endpoint] = value;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EpRead
+//* \brief Return value from the DPR
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_UDP_EpRead (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint) // \arg endpoint number
+{
+ return pUDP->UDP_FDR[endpoint];
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EpEndOfWr
+//* \brief Notify the UDP that values in DPR are ready to be sent
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EpEndOfWr (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint) // \arg endpoint number
+{
+ pUDP->UDP_CSR[endpoint] |= AT91C_UDP_TXPKTRDY;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EpClear
+//* \brief Clear flag in the endpoint CSR register
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EpClear (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint, // \arg endpoint number
+ unsigned int flag) // \arg flag to be cleared
+{
+ pUDP->UDP_CSR[endpoint] &= ~(flag);
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EpSet
+//* \brief Set flag in the endpoint CSR register
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EpSet (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint, // \arg endpoint number
+ unsigned int flag) // \arg flag to be cleared
+{
+ pUDP->UDP_CSR[endpoint] |= flag;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_EpStatus
+//* \brief Return the endpoint CSR register
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_UDP_EpStatus (AT91PS_UDP pUDP, // \arg pointer to a UDP controller
+ unsigned char endpoint) // \arg endpoint number
+{
+ return pUDP->UDP_CSR[endpoint];
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_GetInterruptMaskStatus
+//* \brief Return UDP Interrupt Mask Status
+//*----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_UDP_GetInterruptMaskStatus (AT91PS_UDP pUdp) // \arg pointer to a UDP controller
+{
+ return pUdp->UDP_IMR;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_IsInterruptMasked
+//* \brief Test if UDP Interrupt is Masked
+//*----------------------------------------------------------------------------
+static inline int
+AT91F_UDP_IsInterruptMasked (AT91PS_UDP pUdp, // \arg pointer to a UDP controller
+ unsigned int flag) // \arg flag to be tested
+{
+ return (AT91F_UDP_GetInterruptMaskStatus (pUdp) & flag);
+}
+
+// ----------------------------------------------------------------------------
+// \fn AT91F_UDP_InterruptStatusRegister
+// \brief Return the Interrupt Status Register
+// ----------------------------------------------------------------------------
+static inline unsigned int
+AT91F_UDP_InterruptStatusRegister (AT91PS_UDP pUDP) // \arg pointer to a UDP controller
+{
+ return pUDP->UDP_ISR;
+}
+
+// ----------------------------------------------------------------------------
+// \fn AT91F_UDP_InterruptClearRegister
+// \brief Clear Interrupt Register
+// ----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_InterruptClearRegister (AT91PS_UDP pUDP, // \arg pointer to UDP controller
+ unsigned int flag) // \arg IT to be cleat
+{
+ pUDP->UDP_ICR = flag;
+}
+
+// ----------------------------------------------------------------------------
+// \fn AT91F_UDP_EnableTransceiver
+// \brief Enable transceiver
+// ----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_EnableTransceiver (AT91PS_UDP pUDP) // \arg pointer to a UDP controller
+{
+ pUDP->UDP_TXVC &= ~AT91C_UDP_TXVDIS;
+}
+
+// ----------------------------------------------------------------------------
+// \fn AT91F_UDP_DisableTransceiver
+// \brief Disable transceiver
+// ----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_DisableTransceiver (AT91PS_UDP pUDP) // \arg pointer to a UDP controller
+{
+ pUDP->UDP_TXVC = AT91C_UDP_TXVDIS;
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_DBGU_CfgPMC
+//* \brief Enable Peripheral clock in PMC for DBGU
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_DBGU_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_DBGU_CfgPIO
+//* \brief Configure PIO controllers to drive DBGU signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_DBGU_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA9_DRXD) | ((unsigned int) AT91C_PA10_DTXD), // Peripheral A
+ 0); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for PMC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PMC_CfgPIO
+//* \brief Configure PIO controllers to drive PMC signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PMC_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ 0, // Peripheral A
+ ((unsigned int) AT91C_PA6_PCK0) | ((unsigned int) AT91C_PA18_PCK2) | ((unsigned int) AT91C_PA31_PCK2) | ((unsigned int) AT91C_PA21_PCK1) | ((unsigned int) AT91C_PA17_PCK1)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_VREG_CfgPMC
+//* \brief Enable Peripheral clock in PMC for VREG
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_VREG_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_RSTC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for RSTC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_RSTC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for SSC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SSC));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SSC_CfgPIO
+//* \brief Configure PIO controllers to drive SSC signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SSC_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA19_RK) | ((unsigned int) AT91C_PA16_TK) | ((unsigned int) AT91C_PA15_TF) | ((unsigned int) AT91C_PA18_RD) | ((unsigned int) AT91C_PA20_RF) | ((unsigned int) AT91C_PA17_TD), // Peripheral A
+ 0); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_WDTC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for WDTC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_WDTC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US1_CfgPMC
+//* \brief Enable Peripheral clock in PMC for US1
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US1_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_US1));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US1_CfgPIO
+//* \brief Configure PIO controllers to drive US1 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US1_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA29_RI1) | ((unsigned int) AT91C_PA26_DCD1) | ((unsigned int) AT91C_PA28_DSR1) | ((unsigned int) AT91C_PA27_DTR1) | ((unsigned int) AT91C_PA23_SCK1) | ((unsigned int) AT91C_PA24_RTS1) | ((unsigned int) AT91C_PA22_TXD1) | ((unsigned int) AT91C_PA21_RXD1) | ((unsigned int) AT91C_PA25_CTS1), // Peripheral A
+ 0); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US0_CfgPMC
+//* \brief Enable Peripheral clock in PMC for US0
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US0_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_US0));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_US0_CfgPIO
+//* \brief Configure PIO controllers to drive US0 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_US0_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA5_RXD0) | ((unsigned int) AT91C_PA8_CTS0) | ((unsigned int) AT91C_PA7_RTS0) | ((unsigned int) AT91C_PA6_TXD0), // Peripheral A
+ ((unsigned int) AT91C_PA2_SCK0)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_CfgPMC
+//* \brief Enable Peripheral clock in PMC for SPI
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SPI));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_SPI_CfgPIO
+//* \brief Configure PIO controllers to drive SPI signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_SPI_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA13_MOSI) | ((unsigned int) AT91C_PA31_NPCS1) | ((unsigned int) AT91C_PA14_SPCK) | ((unsigned int) AT91C_PA11_NPCS0) | ((unsigned int) AT91C_PA12_MISO), // Peripheral A
+ ((unsigned int) AT91C_PA9_NPCS1) | ((unsigned int) AT91C_PA22_NPCS3) | ((unsigned int) AT91C_PA3_NPCS3) | ((unsigned int) AT91C_PA5_NPCS3) | ((unsigned int) AT91C_PA10_NPCS2) | ((unsigned int) AT91C_PA30_NPCS2)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PITC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for PITC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PITC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for AIC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_AIC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_FIQ) |
+ ((unsigned int) 1 << AT91C_ID_IRQ0) |
+ ((unsigned int) 1 << AT91C_ID_IRQ1));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_AIC_CfgPIO
+//* \brief Configure PIO controllers to drive AIC signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_AIC_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA30_IRQ1), // Peripheral A
+ ((unsigned int) AT91C_PA20_IRQ0) | ((unsigned int) AT91C_PA19_FIQ)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TWI_CfgPMC
+//* \brief Enable Peripheral clock in PMC for TWI
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TWI_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_TWI));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TWI_CfgPIO
+//* \brief Configure PIO controllers to drive TWI signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TWI_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA4_TWCK) | ((unsigned int) AT91C_PA3_TWD), // Peripheral A
+ 0); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWMC_CH3_CfgPIO
+//* \brief Configure PIO controllers to drive PWMC_CH3 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_CH3_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ 0, // Peripheral A
+ ((unsigned int) AT91C_PA7_PWM3) | ((unsigned int) AT91C_PA14_PWM3)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWMC_CH2_CfgPIO
+//* \brief Configure PIO controllers to drive PWMC_CH2 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_CH2_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA2_PWM2), // Peripheral A
+ ((unsigned int) AT91C_PA13_PWM2) | ((unsigned int) AT91C_PA25_PWM2)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWMC_CH1_CfgPIO
+//* \brief Configure PIO controllers to drive PWMC_CH1 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_CH1_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA1_PWM1), // Peripheral A
+ ((unsigned int) AT91C_PA24_PWM1) | ((unsigned int) AT91C_PA12_PWM1)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWMC_CH0_CfgPIO
+//* \brief Configure PIO controllers to drive PWMC_CH0 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_CH0_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ ((unsigned int) AT91C_PA0_PWM0), // Peripheral A
+ ((unsigned int) AT91C_PA23_PWM0) | ((unsigned int) AT91C_PA11_PWM0)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for ADC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_ADC));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_ADC_CfgPIO
+//* \brief Configure PIO controllers to drive ADC signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_ADC_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ 0, // Peripheral A
+ ((unsigned int) AT91C_PA8_ADTRG)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_RTTC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for RTTC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_RTTC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_UDP_CfgPMC
+//* \brief Enable Peripheral clock in PMC for UDP
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_UDP_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_UDP));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC0_CfgPMC
+//* \brief Enable Peripheral clock in PMC for TC0
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC0_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_TC0));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC0_CfgPIO
+//* \brief Configure PIO controllers to drive TC0 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC0_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ 0, // Peripheral A
+ ((unsigned int) AT91C_PA0_TIOA0) | ((unsigned int) AT91C_PA4_TCLK0) | ((unsigned int) AT91C_PA1_TIOB0)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC1_CfgPMC
+//* \brief Enable Peripheral clock in PMC for TC1
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC1_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_TC1));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC1_CfgPIO
+//* \brief Configure PIO controllers to drive TC1 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC1_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ 0, // Peripheral A
+ ((unsigned int) AT91C_PA15_TIOA1) | ((unsigned int) AT91C_PA28_TCLK1) | ((unsigned int) AT91C_PA16_TIOB1)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC2_CfgPMC
+//* \brief Enable Peripheral clock in PMC for TC2
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC2_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_TC2));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_TC2_CfgPIO
+//* \brief Configure PIO controllers to drive TC2 signals
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_TC2_CfgPIO (void)
+{
+ // Configure PIO controllers to periph mode
+ AT91F_PIO_CfgPeriph (AT91C_BASE_PIOA, // PIO controller base address
+ 0, // Peripheral A
+ ((unsigned int) AT91C_PA27_TIOB2) | ((unsigned int) AT91C_PA26_TIOA2) | ((unsigned int) AT91C_PA29_TCLK2)); // Peripheral B
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_MC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for MC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_MC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_SYS));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PIOA_CfgPMC
+//* \brief Enable Peripheral clock in PMC for PIOA
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PIOA_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_PIOA));
+}
+
+//*----------------------------------------------------------------------------
+//* \fn AT91F_PWMC_CfgPMC
+//* \brief Enable Peripheral clock in PMC for PWMC
+//*----------------------------------------------------------------------------
+static inline void
+AT91F_PWMC_CfgPMC (void)
+{
+ AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, // PIO controller base address
+ ((unsigned int) 1 << AT91C_ID_PWMC));
+}
+
+#define __ramfunc __attribute__ ((long_call, section (".fastrun")))
+
+#endif // lib_AT91SAM7
diff --git a/openpicc/os/core/ARM7_AT91SAM7S/port.c b/openpicc/os/core/ARM7_AT91SAM7S/port.c
new file mode 100644
index 0000000..75bb567
--- /dev/null
+++ b/openpicc/os/core/ARM7_AT91SAM7S/port.c
@@ -0,0 +1,237 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+
+/*-----------------------------------------------------------
+ * Implementation of functions defined in portable.h for the ARM7 port.
+ *
+ * Components that can be compiled to either ARM or THUMB mode are
+ * contained in this file. The ISR routines, which can only be compiled
+ * to ARM mode are contained in portISR.c.
+ *----------------------------------------------------------*/
+
+/*
+ Changes from V2.5.2
+
+ + ulCriticalNesting is now saved as part of the task context, as is
+ therefore added to the initial task stack during pxPortInitialiseStack.
+*/
+
+
+/* Standard includes. */
+#include <stdlib.h>
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Processor constants. */
+#include "AT91SAM7.h"
+#include "lib_AT91SAM7.h"
+
+/* Constants required to setup the task context. */
+#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
+#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
+#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
+#define portNO_CRITICAL_SECTION_NESTING ( ( portSTACK_TYPE ) 0 )
+
+/* Constants required to setup the tick ISR. */
+#define portENABLE_TIMER ( ( unsigned portCHAR ) 0x01 )
+#define portPRESCALE_VALUE 0x00
+#define portINTERRUPT_ON_MATCH ( ( unsigned portLONG ) 0x01 )
+#define portRESET_COUNT_ON_MATCH ( ( unsigned portLONG ) 0x02 )
+
+/* Constants required to setup the PIT. */
+#define portPIT_CLOCK_DIVISOR ( ( unsigned portLONG ) 16 )
+#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
+
+#define portINT_LEVEL_SENSITIVE 0
+#define portPIT_ENABLE ( ( unsigned portSHORT ) 0x1 << 24 )
+#define portPIT_INT_ENABLE ( ( unsigned portSHORT ) 0x1 << 25 )
+/*-----------------------------------------------------------*/
+
+/* Setup the timer to generate the tick interrupts. */
+static void prvSetupTimerInterrupt (void);
+
+/*
+ * The scheduler can only be started from ARM mode, so
+ * vPortISRStartFirstSTask() is defined in portISR.c.
+ */
+extern void vPortISRStartFirstTask (void);
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Initialise the stack of a task to look exactly as if a call to
+ * portSAVE_CONTEXT had been called.
+ *
+ * See header file for description.
+ */
+portSTACK_TYPE *
+pxPortInitialiseStack (portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode,
+ void *pvParameters)
+{
+ portSTACK_TYPE *pxOriginalTOS;
+
+ pxOriginalTOS = pxTopOfStack;
+
+ /* Setup the initial stack of the task. The stack is set exactly as
+ expected by the portRESTORE_CONTEXT() macro. */
+
+ /* First on the stack is the return address - which in this case is the
+ start of the task. The offset is added to make the return address appear
+ as it would within an IRQ ISR. */
+ *pxTopOfStack = (portSTACK_TYPE) pxCode + portINSTRUCTION_SIZE;
+ pxTopOfStack--;
+
+ *pxTopOfStack = (portSTACK_TYPE) 0xaaaaaaaa; /* R14 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) pxOriginalTOS; /* Stack used when task starts goes in R13. */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x12121212; /* R12 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x11111111; /* R11 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x10101010; /* R10 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x09090909; /* R9 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x08080808; /* R8 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x07070707; /* R7 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x06060606; /* R6 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x05050505; /* R5 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x04040404; /* R4 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x03030303; /* R3 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x02020202; /* R2 */
+ pxTopOfStack--;
+ *pxTopOfStack = (portSTACK_TYPE) 0x01010101; /* R1 */
+ pxTopOfStack--;
+
+ /* When the task starts is will expect to find the function parameter in
+ R0. */
+ *pxTopOfStack = (portSTACK_TYPE) pvParameters; /* R0 */
+ pxTopOfStack--;
+
+ /* The last thing onto the stack is the status register, which is set for
+ system mode, with interrupts enabled. */
+ *pxTopOfStack = (portSTACK_TYPE) portINITIAL_SPSR;
+
+#ifdef THUMB_INTERWORK
+ {
+ /* We want the task to start in thumb mode. */
+ *pxTopOfStack |= portTHUMB_MODE_BIT;
+ }
+#endif
+
+ pxTopOfStack--;
+
+ /* Some optimisation levels use the stack differently to others. This
+ means the interrupt flags cannot always be stored on the stack and will
+ instead be stored in a variable, which is then saved as part of the
+ tasks context. */
+ *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
+
+ return pxTopOfStack;
+}
+
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE
+xPortStartScheduler (void)
+{
+ /* Start the timer that generates the tick ISR. Interrupts are disabled
+ here already. */
+ prvSetupTimerInterrupt ();
+
+ /* Start the first task. */
+ vPortISRStartFirstTask ();
+
+ /* Should not get here! */
+ return 0;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vPortEndScheduler (void)
+{
+ /* It is unlikely that the ARM port will require this function as there
+ is nothing to return to. */
+}
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Setup the timer 0 to generate the tick interrupts at the required frequency.
+ */
+static void
+prvSetupTimerInterrupt (void)
+{
+ AT91PS_PITC pxPIT = AT91C_BASE_PITC;
+
+ /* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
+ on whether the preemptive or cooperative scheduler is being used. */
+#if configUSE_PREEMPTION == 0
+
+ extern void (vNonPreemptiveTick) (void);
+ AT91F_AIC_ConfigureIt (AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST,
+ portINT_LEVEL_SENSITIVE,
+ (void (*)(void)) vNonPreemptiveTick);
+
+#else
+
+ extern void (vPreemptiveTick) (void);
+ AT91F_AIC_ConfigureIt (AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST,
+ portINT_LEVEL_SENSITIVE,
+ (void (*)(void)) vPreemptiveTick);
+
+#endif
+
+ /* Configure the PIT period. */
+ pxPIT->PITC_PIMR =
+ portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
+
+ /* Enable the interrupt. Global interrupts are disables at this point so
+ this is safe. */
+ AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
+}
+
+/*-----------------------------------------------------------*/
diff --git a/openpicc/os/core/ARM7_AT91SAM7S/portISR.c b/openpicc/os/core/ARM7_AT91SAM7S/portISR.c
new file mode 100644
index 0000000..507712e
--- /dev/null
+++ b/openpicc/os/core/ARM7_AT91SAM7S/portISR.c
@@ -0,0 +1,239 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+
+/*-----------------------------------------------------------
+ * Components that can be compiled to either ARM or THUMB mode are
+ * contained in port.c The ISR routines, which can only be compiled
+ * to ARM mode, are contained in this file.
+ *----------------------------------------------------------*/
+
+/*
+ Changes from V3.2.4
+
+ + The assembler statements are now included in a single asm block rather
+ than each line having its own asm block.
+*/
+
+/* Scheduler includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "AT91SAM7.h"
+
+/* Constants required to handle interrupts. */
+#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
+#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
+
+/* Constants required to handle critical sections. */
+#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
+volatile unsigned portLONG ulCriticalNesting = 9999UL;
+
+/*-----------------------------------------------------------*/
+
+/* ISR to handle manual context switches (from a call to taskYIELD()). */
+void vPortYieldProcessor (void) __attribute__ ((interrupt ("SWI"), naked));
+
+/*
+ * The scheduler can only be started from ARM mode, hence the inclusion of this
+ * function here.
+ */
+void vPortISRStartFirstTask (void);
+/*-----------------------------------------------------------*/
+
+void
+vPortISRStartFirstTask (void)
+{
+ /* Simply start the scheduler. This is included here as it can only be
+ called from ARM mode. */
+ portRESTORE_CONTEXT ();
+}
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Called by portYIELD() or taskYIELD() to manually force a context switch.
+ *
+ * When a context switch is performed from the task level the saved task
+ * context is made to look as if it occurred from within the tick ISR. This
+ * way the same restore context function can be used when restoring the context
+ * saved from the ISR or that saved from a call to vPortYieldProcessor.
+ */
+void
+vPortYieldProcessor (void)
+{
+ /* Within an IRQ ISR the link register has an offset from the true return
+ address, but an SWI ISR does not. Add the offset manually so the same
+ ISR return code can be used in both cases. */
+ asm volatile ("ADD LR, LR, #4");
+
+ /* Perform the context switch. First save the context of the current task. */
+ portSAVE_CONTEXT ();
+
+ /* Find the highest priority task that is ready to run. */
+ vTaskSwitchContext ();
+
+ /* Restore the context of the new task. */
+ portRESTORE_CONTEXT ();
+}
+
+/*-----------------------------------------------------------*/
+
+/*
+ * The ISR used for the scheduler tick depends on whether the cooperative or
+ * the preemptive scheduler is being used.
+ */
+
+#if configUSE_PREEMPTION == 0
+
+ /* The cooperative scheduler requires a normal IRQ service routine to
+ simply increment the system tick. */
+void vNonPreemptiveTick (void) __attribute__ ((interrupt ("IRQ")));
+void
+vNonPreemptiveTick (void)
+{
+ unsigned portLONG ulDummy;
+
+ /* Increment the tick count - which may wake some tasks but as the
+ preemptive scheduler is not being used any woken task is not given
+ processor time no matter what its priority. */
+ vTaskIncrementTick ();
+
+ /* Clear the PIT interrupt. */
+ ulDummy = AT91C_BASE_PITC->PITC_PIVR;
+
+ /* End the interrupt in the AIC. */
+ AT91C_BASE_AIC->AIC_EOICR = ulDummy;
+}
+
+#else
+
+ /* The preemptive scheduler is defined as "naked" as the full context is
+ saved on entry as part of the context switch. */
+void vPreemptiveTick (void) __attribute__ ((naked));
+void
+vPreemptiveTick (void)
+{
+ /* Save the context of the current task. */
+ portSAVE_CONTEXT ();
+
+ /* Increment the tick count - this may wake a task. */
+ vTaskIncrementTick ();
+
+ /* Find the highest priority task that is ready to run. */
+ vTaskSwitchContext ();
+
+ /* End the interrupt in the AIC. */
+ AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;;
+
+ portRESTORE_CONTEXT ();
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+/*
+ * The interrupt management utilities can only be called from ARM mode. When
+ * THUMB_INTERWORK is defined the utilities are defined as functions here to
+ * ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
+ * the utilities are defined as macros in portmacro.h - as per other ports.
+ */
+void vPortDisableInterruptsFromThumb (void) __attribute__ ((naked));
+void vPortEnableInterruptsFromThumb (void) __attribute__ ((naked));
+
+void
+vPortDisableInterruptsFromThumb (void)
+{
+ asm volatile ("STMDB SP!, {R0} \n\t" /* Push R0. */
+ "MRS R0, CPSR \n\t" /* Get CPSR. */
+ "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
+ "MSR CPSR, R0 \n\t" /* Write back modified value. */
+ "LDMIA SP!, {R0} \n\t" /* Pop R0. */
+ "BX R14"); /* Return back to thumb. */
+}
+
+void
+vPortEnableInterruptsFromThumb (void)
+{
+ asm volatile ("STMDB SP!, {R0} \n\t" /* Push R0. */
+ "MRS R0, CPSR \n\t" /* Get CPSR. */
+ "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
+ "MSR CPSR, R0 \n\t" /* Write back modified value. */
+ "LDMIA SP!, {R0} \n\t" /* Pop R0. */
+ "BX R14"); /* Return back to thumb. */
+}
+
+
+/* The code generated by the GCC compiler uses the stack in different ways at
+different optimisation levels. The interrupt flags can therefore not always
+be saved to the stack. Instead the critical section nesting level is stored
+in a variable, which is then saved as part of the stack context. */
+void
+vPortEnterCritical (void)
+{
+ /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
+ asm volatile ("STMDB SP!, {R0} \n\t" /* Push R0. */
+ "MRS R0, CPSR \n\t" /* Get CPSR. */
+ "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
+ "MSR CPSR, R0 \n\t" /* Write back modified value. */
+ "LDMIA SP!, {R0}"); /* Pop R0. */
+
+ /* Now interrupts are disabled ulCriticalNesting can be accessed
+ directly. Increment ulCriticalNesting to keep a count of how many times
+ portENTER_CRITICAL() has been called. */
+ ulCriticalNesting++;
+}
+
+void
+vPortExitCritical (void)
+{
+ if (ulCriticalNesting > portNO_CRITICAL_NESTING)
+ {
+ /* Decrement the nesting count as we are leaving a critical section. */
+ ulCriticalNesting--;
+
+ /* If the nesting level has reached zero then interrupts should be
+ re-enabled. */
+ if (ulCriticalNesting == portNO_CRITICAL_NESTING)
+ {
+ /* Enable interrupts as per portEXIT_CRITICAL(). */
+ asm volatile ("STMDB SP!, {R0} \n\t" /* Push R0. */
+ "MRS R0, CPSR \n\t" /* Get CPSR. */
+ "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
+ "MSR CPSR, R0 \n\t" /* Write back modified value. */
+ "LDMIA SP!, {R0}"); /* Pop R0. */
+ }
+ }
+}
diff --git a/openpicc/os/core/ARM7_AT91SAM7S/portmacro.h b/openpicc/os/core/ARM7_AT91SAM7S/portmacro.h
new file mode 100644
index 0000000..6b25ec5
--- /dev/null
+++ b/openpicc/os/core/ARM7_AT91SAM7S/portmacro.h
@@ -0,0 +1,266 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+ Changes from V3.2.3
+
+ + Modified portENTER_SWITCHING_ISR() to allow use with GCC V4.0.1.
+
+ Changes from V3.2.4
+
+ + Removed the use of the %0 parameter within the assembler macros and
+ replaced them with hard coded registers. This will ensure the
+ assembler does not select the link register as the temp register as
+ was occasionally happening previously.
+
+ + The assembler statements are now included in a single asm block rather
+ than each line having its own asm block.
+*/
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+/*-----------------------------------------------------------
+ * Port specific definitions.
+ *
+ * The settings in this file configure FreeRTOS correctly for the
+ * given hardware and compiler.
+ *
+ * These settings should not be altered.
+ *-----------------------------------------------------------
+ */
+
+/* Type definitions. */
+#define portCHAR char
+#define portFLOAT float
+#define portDOUBLE double
+#define portLONG long
+#define portSHORT short
+#define portSTACK_TYPE unsigned portLONG
+#define portBASE_TYPE portLONG
+
+#if( configUSE_16_BIT_TICKS == 1 )
+typedef unsigned portSHORT portTickType;
+#define portMAX_DELAY ( portTickType ) 0xffff
+#else
+typedef unsigned portLONG portTickType;
+#define portMAX_DELAY ( portTickType ) 0xffffffff
+#endif
+/*-----------------------------------------------------------*/
+
+/* Architecture specifics. */
+#define portSTACK_GROWTH ( -1 )
+#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
+#define portBYTE_ALIGNMENT 4
+#define portNOP() asm volatile ( "NOP" );
+/*-----------------------------------------------------------*/
+
+
+/* Scheduler utilities. */
+
+/*
+ * portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
+ * and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
+ * are included here for efficiency. An attempt to call one from
+ * THUMB mode code will result in a compile time error.
+ */
+
+#define portRESTORE_CONTEXT() \
+{ \
+extern volatile void * volatile pxCurrentTCB; \
+extern volatile unsigned portLONG ulCriticalNesting; \
+ \
+ /* Set the LR to the task stack. */ \
+ asm volatile ( \
+ "LDR R0, =pxCurrentTCB \n\t" \
+ "LDR R0, [R0] \n\t" \
+ "LDR LR, [R0] \n\t" \
+ \
+ /* The critical nesting depth is the first item on the stack. */ \
+ /* Load it into the ulCriticalNesting variable. */ \
+ "LDR R0, =ulCriticalNesting \n\t" \
+ "LDMFD LR!, {R1} \n\t" \
+ "STR R1, [R0] \n\t" \
+ \
+ /* Get the SPSR from the stack. */ \
+ "LDMFD LR!, {R0} \n\t" \
+ "MSR SPSR, R0 \n\t" \
+ \
+ /* Restore all system mode registers for the task. */ \
+ "LDMFD LR, {R0-R14}^ \n\t" \
+ "NOP \n\t" \
+ \
+ /* Restore the return address. */ \
+ "LDR LR, [LR, #+60] \n\t" \
+ \
+ /* And return - correcting the offset in the LR to obtain the */ \
+ /* correct address. */ \
+ "SUBS PC, LR, #4 \n\t" \
+ ); \
+ ( void ) ulCriticalNesting; \
+ ( void ) pxCurrentTCB; \
+}
+/*-----------------------------------------------------------*/
+
+#define portSAVE_CONTEXT() \
+{ \
+extern volatile void * volatile pxCurrentTCB; \
+extern volatile unsigned portLONG ulCriticalNesting; \
+ \
+ /* Push R0 as we are going to use the register. */ \
+ asm volatile ( \
+ "STMDB SP!, {R0} \n\t" \
+ \
+ /* Set R0 to point to the task stack pointer. */ \
+ "STMDB SP,{SP}^ \n\t" \
+ "NOP \n\t" \
+ "SUB SP, SP, #4 \n\t" \
+ "LDMIA SP!,{R0} \n\t" \
+ \
+ /* Push the return address onto the stack. */ \
+ "STMDB R0!, {LR} \n\t" \
+ \
+ /* Now we have saved LR we can use it instead of R0. */ \
+ "MOV LR, R0 \n\t" \
+ \
+ /* Pop R0 so we can save it onto the system mode stack. */ \
+ "LDMIA SP!, {R0} \n\t" \
+ \
+ /* Push all the system mode registers onto the task stack. */ \
+ "STMDB LR,{R0-LR}^ \n\t" \
+ "NOP \n\t" \
+ "SUB LR, LR, #60 \n\t" \
+ \
+ /* Push the SPSR onto the task stack. */ \
+ "MRS R0, SPSR \n\t" \
+ "STMDB LR!, {R0} \n\t" \
+ \
+ "LDR R0, =ulCriticalNesting \n\t" \
+ "LDR R0, [R0] \n\t" \
+ "STMDB LR!, {R0} \n\t" \
+ \
+ /* Store the new top of stack for the task. */ \
+ "LDR R0, =pxCurrentTCB \n\t" \
+ "LDR R0, [R0] \n\t" \
+ "STR LR, [R0] \n\t" \
+ ); \
+ ( void ) ulCriticalNesting; \
+ ( void ) pxCurrentTCB; \
+}
+
+
+/*-----------------------------------------------------------
+ * ISR entry and exit macros. These are only required if a task switch
+ * is required from the ISR.
+ *----------------------------------------------------------*/
+
+
+#define portENTER_SWITCHING_ISR() \
+ /* Save the context of the interrupted task. */ \
+ portSAVE_CONTEXT(); \
+ \
+ /* We don't know the stack requirements for the ISR, so the frame */\
+ /* pointer will be set to the top of the task stack, and the stack*/\
+ /* pointer left where it is. The IRQ stack will get used for any */\
+ /* functions calls made by this ISR. */ \
+ asm volatile ( "SUB R11, LR, #4" ); \
+ {
+
+#define portEXIT_SWITCHING_ISR( SwitchRequired ) \
+ /* If a switch is required then we just need to call */ \
+ /* vTaskSwitchContext() as the context has already been */ \
+ /* saved. */ \
+ if( SwitchRequired ) \
+ { \
+ vTaskSwitchContext(); \
+ } \
+ } \
+ /* Restore the context of which ever task is now the highest */ \
+ /* priority that is ready to run. */ \
+ portRESTORE_CONTEXT();
+
+#define portYIELD() asm volatile ( "SWI" );
+/*-----------------------------------------------------------*/
+
+
+/* Critical section management. */
+
+/*
+ * The interrupt management utilities can only be called from ARM mode. When
+ * THUMB_INTERWORK is defined the utilities are defined as functions in
+ * portISR.c to ensure a switch to ARM mode. When THUMB_INTERWORK is not
+ * defined then the utilities are defined as macros here - as per other ports.
+ */
+
+#ifdef THUMB_INTERWORK
+
+extern void vPortDisableInterruptsFromThumb (void) __attribute__ ((naked));
+extern void vPortEnableInterruptsFromThumb (void) __attribute__ ((naked));
+
+#define portDISABLE_INTERRUPTS() vPortDisableInterruptsFromThumb()
+#define portENABLE_INTERRUPTS() vPortEnableInterruptsFromThumb()
+
+#else
+
+#define portDISABLE_INTERRUPTS() \
+ asm volatile ( \
+ "STMDB SP!, {R0} \n\t" /* Push R0. */ \
+ "MRS R0, CPSR \n\t" /* Get CPSR. */ \
+ "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */ \
+ "MSR CPSR, R0 \n\t" /* Write back modified value. */ \
+ "LDMIA SP!, {R0} " ) /* Pop R0. */
+
+#define portENABLE_INTERRUPTS() \
+ asm volatile ( \
+ "STMDB SP!, {R0} \n\t" /* Push R0. */ \
+ "MRS R0, CPSR \n\t" /* Get CPSR. */ \
+ "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */ \
+ "MSR CPSR, R0 \n\t" /* Write back modified value. */ \
+ "LDMIA SP!, {R0} " ) /* Pop R0. */
+
+#endif /* THUMB_INTERWORK */
+
+extern void vPortEnterCritical (void);
+extern void vPortExitCritical (void);
+
+#define portENTER_CRITICAL() vPortEnterCritical();
+#define portEXIT_CRITICAL() vPortExitCritical();
+/*-----------------------------------------------------------*/
+
+/* Task function macros as described on the FreeRTOS.org WEB site. */
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
+
+#endif /* PORTMACRO_H */
diff --git a/openpicc/os/core/MemMang/heap_1.c b/openpicc/os/core/MemMang/heap_1.c
new file mode 100644
index 0000000..8370479
--- /dev/null
+++ b/openpicc/os/core/MemMang/heap_1.c
@@ -0,0 +1,143 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+
+Changes between V2.5.1 and V2.5.1
+
+ + The memory pool has been defined within a struct to ensure correct memory
+ alignment on 32bit systems.
+
+Changes between V2.6.1 and V3.0.0
+
+ + An overflow check has been added to ensure the next free byte variable
+ does not wrap around.
+*/
+
+
+/*
+ * The simplest possible implementation of pvPortMalloc(). Note that this
+ * implementation does NOT allow allocated memory to be freed again.
+ *
+ * See heap_2.c and heap_3.c for alternative implementations, and the memory
+ * management pages of http://www.FreeRTOS.org for more information.
+ */
+#include <stdlib.h>
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Setup the correct byte alignment mask for the defined byte alignment. */
+
+#if portBYTE_ALIGNMENT == 8
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0007 )
+#endif
+
+#if portBYTE_ALIGNMENT == 4
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0003 )
+#endif
+
+#if portBYTE_ALIGNMENT == 2
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0001 )
+#endif
+
+#if portBYTE_ALIGNMENT == 1
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0000 )
+#endif
+
+#ifndef heapBYTE_ALIGNMENT_MASK
+#error "Invalid portBYTE_ALIGNMENT definition"
+#endif
+
+/* Allocate the memory for the heap. The struct is used to force byte
+alignment without using any non-portable code. */
+static struct xRTOS_HEAP
+{
+ unsigned portLONG ulDummy;
+ unsigned portCHAR ucHeap[configTOTAL_HEAP_SIZE];
+} xHeap;
+
+static size_t xNextFreeByte = (size_t) 0;
+/*-----------------------------------------------------------*/
+
+void *
+pvPortMalloc (size_t xWantedSize)
+{
+ void *pvReturn = NULL;
+
+ /* Ensure that blocks are always aligned to the required number of bytes. */
+#if portBYTE_ALIGNMENT != 1
+ if (xWantedSize & heapBYTE_ALIGNMENT_MASK)
+ {
+ /* Byte alignment required. */
+ xWantedSize +=
+ (portBYTE_ALIGNMENT - (xWantedSize & heapBYTE_ALIGNMENT_MASK));
+ }
+#endif
+
+ vTaskSuspendAll ();
+ {
+ /* Check there is enough room left for the allocation. */
+ if (((xNextFreeByte + xWantedSize) < configTOTAL_HEAP_SIZE) && ((xNextFreeByte + xWantedSize) > xNextFreeByte)) /* Check for overflow. */
+ {
+ /* Return the next free byte then increment the index past this
+ block. */
+ pvReturn = &(xHeap.ucHeap[xNextFreeByte]);
+ xNextFreeByte += xWantedSize;
+ }
+ }
+ xTaskResumeAll ();
+
+ return pvReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vPortFree (void *pv)
+{
+ /* Memory cannot be freed using this scheme. See heap_2.c and heap_3.c
+ for alternative implementations, and the memory management pages of
+ http://www.FreeRTOS.org for more information. */
+ (void) pv;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vPortInitialiseBlocks (void)
+{
+ /* Only required when static memory is not cleared. */
+ xNextFreeByte = (size_t) 0;
+}
diff --git a/openpicc/os/core/MemMang/heap_2.c b/openpicc/os/core/MemMang/heap_2.c
new file mode 100644
index 0000000..0b74d44
--- /dev/null
+++ b/openpicc/os/core/MemMang/heap_2.c
@@ -0,0 +1,255 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+ * A sample implementation of pvPortMalloc() and vPortFree() that permits
+ * allocated blocks to be freed, but does not combine adjacent free blocks
+ * into a single larger block.
+ *
+ * See heap_1.c and heap_3.c for alternative implementations, and the memory
+ * management pages of http://www.FreeRTOS.org for more information.
+ */
+#include <stdlib.h>
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Setup the correct byte alignment mask for the defined byte alignment. */
+
+#if portBYTE_ALIGNMENT == 8
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0007 )
+#endif
+
+#if portBYTE_ALIGNMENT == 4
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0003 )
+#endif
+
+#if portBYTE_ALIGNMENT == 2
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0001 )
+#endif
+
+#if portBYTE_ALIGNMENT == 1
+#define heapBYTE_ALIGNMENT_MASK ( ( size_t ) 0x0000 )
+#endif
+
+#ifndef heapBYTE_ALIGNMENT_MASK
+#error "Invalid portBYTE_ALIGNMENT definition"
+#endif
+
+/* Allocate the memory for the heap. The struct is used to force byte
+alignment without using any non-portable code. */
+static struct xRTOS_HEAP
+{
+ unsigned portLONG ulDummy;
+ unsigned portCHAR ucHeap[configTOTAL_HEAP_SIZE];
+} xHeap;
+
+/* Define the linked list structure. This is used to link free blocks in order
+of their size. */
+typedef struct A_BLOCK_LINK
+{
+ struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
+ size_t xBlockSize; /*<< The size of the free block. */
+} xBlockLink;
+
+
+static const unsigned portSHORT heapSTRUCT_SIZE =
+ (sizeof (xBlockLink) + (sizeof (xBlockLink) % portBYTE_ALIGNMENT));
+#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) )
+
+/* Create a couple of list links to mark the start and end of the list. */
+static xBlockLink xStart, xEnd;
+
+/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
+
+/*
+ * Insert a block into the list of free blocks - which is ordered by size of
+ * the block. Small blocks at the start of the list and large blocks at the end
+ * of the list.
+ */
+#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \
+{ \
+xBlockLink *pxIterator; \
+size_t xBlockSize; \
+ \
+ xBlockSize = pxBlockToInsert->xBlockSize; \
+ \
+ /* Iterate through the list until a block is found that has a larger size */ \
+ /* than the block we are inserting. */ \
+ for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
+ { \
+ /* There is nothing to do here - just iterate to the correct position. */ \
+ } \
+ \
+ /* Update the list to include the block being inserted in the correct */ \
+ /* position. */ \
+ pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \
+ pxIterator->pxNextFreeBlock = pxBlockToInsert; \
+}
+/*-----------------------------------------------------------*/
+
+#define prvHeapInit() \
+{ \
+xBlockLink *pxFirstFreeBlock; \
+ \
+ /* xStart is used to hold a pointer to the first item in the list of free */ \
+ /* blocks. The void cast is used to prevent compiler warnings. */ \
+ xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; \
+ xStart.xBlockSize = ( size_t ) 0; \
+ \
+ /* xEnd is used to mark the end of the list of free blocks. */ \
+ xEnd.xBlockSize = configTOTAL_HEAP_SIZE; \
+ xEnd.pxNextFreeBlock = NULL; \
+ \
+ /* To start with there is a single free block that is sized to take up the \
+ entire heap space. */ \
+ pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \
+ pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \
+ pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \
+}
+/*-----------------------------------------------------------*/
+
+void *
+pvPortMalloc (size_t xWantedSize)
+{
+ xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
+ static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE;
+ void *pvReturn = NULL;
+
+ vTaskSuspendAll ();
+ {
+ /* If this is the first call to malloc then the heap will require
+ initialisation to setup the list of free blocks. */
+ if (xHeapHasBeenInitialised == pdFALSE)
+ {
+ prvHeapInit ();
+ xHeapHasBeenInitialised = pdTRUE;
+ }
+
+ /* The wanted size is increased so it can contain a xBlockLink
+ structure in addition to the requested amount of bytes. */
+ if (xWantedSize > 0)
+ {
+ xWantedSize += heapSTRUCT_SIZE;
+
+ /* Ensure that blocks are always aligned to the required number of bytes. */
+ if (xWantedSize & heapBYTE_ALIGNMENT_MASK)
+ {
+ /* Byte alignment required. */
+ xWantedSize +=
+ (portBYTE_ALIGNMENT - (xWantedSize & heapBYTE_ALIGNMENT_MASK));
+ }
+ }
+
+ if ((xWantedSize > 0) && (xWantedSize < configTOTAL_HEAP_SIZE))
+ {
+ /* Blocks are stored in byte order - traverse the list from the start
+ (smallest) block until one of adequate size is found. */
+ pxPreviousBlock = &xStart;
+ pxBlock = xStart.pxNextFreeBlock;
+ while ((pxBlock->xBlockSize < xWantedSize)
+ && (pxBlock->pxNextFreeBlock))
+ {
+ pxPreviousBlock = pxBlock;
+ pxBlock = pxBlock->pxNextFreeBlock;
+ }
+
+ /* If we found the end marker then a block of adequate size was not found. */
+ if (pxBlock != &xEnd)
+ {
+ /* Return the memory space - jumping over the xBlockLink structure
+ at its start. */
+ pvReturn =
+ (void
+ *) (((unsigned portCHAR *) pxPreviousBlock->pxNextFreeBlock) +
+ heapSTRUCT_SIZE);
+
+ /* This block is being returned for use so must be taken our of the
+ list of free blocks. */
+ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
+
+ /* If the block is larger than required it can be split into two. */
+ if ((pxBlock->xBlockSize - xWantedSize) > heapMINIMUM_BLOCK_SIZE)
+ {
+ /* This block is to be split into two. Create a new block
+ following the number of bytes requested. The void cast is
+ used to prevent byte alignment warnings from the compiler. */
+ pxNewBlockLink =
+ (void *) (((unsigned portCHAR *) pxBlock) + xWantedSize);
+
+ /* Calculate the sizes of two blocks split from the single
+ block. */
+ pxNewBlockLink->xBlockSize =
+ pxBlock->xBlockSize - xWantedSize;
+ pxBlock->xBlockSize = xWantedSize;
+
+ /* Insert the new block into the list of free blocks. */
+ prvInsertBlockIntoFreeList ((pxNewBlockLink));
+ }
+ }
+ }
+ }
+ xTaskResumeAll ();
+
+ return pvReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vPortFree (void *pv)
+{
+ unsigned portCHAR *puc = (unsigned portCHAR *) pv;
+ xBlockLink *pxLink;
+
+ if (pv)
+ {
+ /* The memory being freed will have an xBlockLink structure immediately
+ before it. */
+ puc -= heapSTRUCT_SIZE;
+
+ /* This casting is to keep the compiler from issuing warnings. */
+ pxLink = (void *) puc;
+
+ vTaskSuspendAll ();
+ {
+ /* Add this block to the list of free blocks. */
+ prvInsertBlockIntoFreeList (((xBlockLink *) pxLink));
+ }
+ xTaskResumeAll ();
+ }
+}
+
+/*-----------------------------------------------------------*/
diff --git a/openpicc/os/core/MemMang/heap_3.c b/openpicc/os/core/MemMang/heap_3.c
new file mode 100644
index 0000000..ca1311e
--- /dev/null
+++ b/openpicc/os/core/MemMang/heap_3.c
@@ -0,0 +1,82 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+
+/*
+ * Implementation of pvPortMalloc() and vPortFree() that relies on the
+ * compilers own malloc() and free() implementations.
+ *
+ * This file can only be used if the linker is configured to to generate
+ * a heap memory area.
+ *
+ * See heap_2.c and heap_1.c for alternative implementations, and the memory
+ * management pages of http://www.FreeRTOS.org for more information.
+ */
+
+#include <stdlib.h>
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+/*-----------------------------------------------------------*/
+
+void *
+pvPortMalloc (size_t xWantedSize)
+{
+ void *pvReturn;
+
+ vTaskSuspendAll ();
+ {
+ pvReturn = malloc (xWantedSize);
+ }
+ xTaskResumeAll ();
+
+ return pvReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vPortFree (void *pv)
+{
+ if (pv)
+ {
+ vTaskSuspendAll ();
+ {
+ free (pv);
+ }
+ xTaskResumeAll ();
+ }
+}
diff --git a/openpicc/os/core/include/FreeRTOS.h b/openpicc/os/core/include/FreeRTOS.h
new file mode 100644
index 0000000..7afc084
--- /dev/null
+++ b/openpicc/os/core/include/FreeRTOS.h
@@ -0,0 +1,114 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef INC_FREERTOS_H
+#define INC_FREERTOS_H
+
+
+/*
+ * Include the generic headers required for the FreeRTOS port being used.
+ */
+#include <stddef.h>
+
+/* Basic FreeRTOS definitions. */
+#include "projdefs.h"
+
+/* Application specific configuration options. */
+#include "FreeRTOSConfig.h"
+
+/* Definitions specific to the port being used. */
+#include "portable.h"
+
+
+
+
+
+
+
+/*
+ * Check all the required application specific macros have been defined.
+ * These macros are application specific and (as downloaded) are defined
+ * within FreeRTOSConfig.h.
+ */
+
+#ifndef configUSE_PREEMPTION
+#error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_IDLE_HOOK
+#error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_TICK_HOOK
+#error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_CO_ROUTINES
+#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskPrioritySet
+#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_uxTaskPriorityGet
+#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelete
+#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskCleanUpResources
+#error Missing definition: INCLUDE_vTaskCleanUpResources should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskSuspend
+#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelayUntil
+#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef INCLUDE_vTaskDelay
+#error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#ifndef configUSE_16_BIT_TICKS
+#error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
+#endif
+
+#endif
diff --git a/openpicc/os/core/include/blocktim.h b/openpicc/os/core/include/blocktim.h
new file mode 100644
index 0000000..a60605a
--- /dev/null
+++ b/openpicc/os/core/include/blocktim.h
@@ -0,0 +1,42 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef BLOCK_TIME_TEST_H
+#define BLOCK_TIME_TEST_H
+
+void vCreateBlockTimeTasks (void);
+portBASE_TYPE xAreBlockTimeTestTasksStillRunning (void);
+
+#endif
diff --git a/openpicc/os/core/include/comtest.h b/openpicc/os/core/include/comtest.h
new file mode 100644
index 0000000..472e138
--- /dev/null
+++ b/openpicc/os/core/include/comtest.h
@@ -0,0 +1,46 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef COMTEST_H
+#define COMTEST_H
+
+void vAltStartComTestTasks (unsigned portBASE_TYPE uxPriority,
+ unsigned portLONG ulBaudRate,
+ unsigned portBASE_TYPE uxLED);
+void vStartComTestTasks (unsigned portBASE_TYPE uxPriority, eCOMPort ePort,
+ eBaud eBaudRate);
+portBASE_TYPE xAreComTestTasksStillRunning (void);
+
+#endif
diff --git a/openpicc/os/core/include/comtest2.h b/openpicc/os/core/include/comtest2.h
new file mode 100644
index 0000000..1dd155d
--- /dev/null
+++ b/openpicc/os/core/include/comtest2.h
@@ -0,0 +1,44 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef COMTEST_H
+#define COMTEST_H
+
+void vAltStartComTestTasks (unsigned portBASE_TYPE uxPriority,
+ unsigned portLONG ulBaudRate,
+ unsigned portBASE_TYPE uxLED);
+portBASE_TYPE xAreComTestTasksStillRunning (void);
+
+#endif
diff --git a/openpicc/os/core/include/crhook.h b/openpicc/os/core/include/crhook.h
new file mode 100644
index 0000000..de16883
--- /dev/null
+++ b/openpicc/os/core/include/crhook.h
@@ -0,0 +1,50 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef CRHOOK_H
+#define CRHOOK_H
+
+/*
+ * Create the co-routines used to communicate wit the tick hook.
+ */
+void vStartHookCoRoutines (void);
+
+/*
+ * Return pdPASS or pdFAIL depending on whether an error has been detected
+ * or not.
+ */
+portBASE_TYPE xAreHookCoRoutinesStillRunning (void);
+
+#endif
diff --git a/openpicc/os/core/include/croutine.h b/openpicc/os/core/include/croutine.h
new file mode 100644
index 0000000..0394240
--- /dev/null
+++ b/openpicc/os/core/include/croutine.h
@@ -0,0 +1,720 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+#ifndef CO_ROUTINE_H
+#define CO_ROUTINE_H
+
+#include "list.h"
+
+/* Used to hide the implementation of the co-routine control block. The
+control block structure however has to be included in the header due to
+the macro implementation of the co-routine functionality. */
+typedef void *xCoRoutineHandle;
+
+/* Defines the prototype to which co-routine functions must conform. */
+typedef void (*crCOROUTINE_CODE) (xCoRoutineHandle, unsigned portBASE_TYPE);
+
+typedef struct corCoRoutineControlBlock
+{
+ crCOROUTINE_CODE pxCoRoutineFunction;
+ xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
+ xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */
+ unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
+ unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
+ unsigned portSHORT uxState; /*< Used internally by the co-routine implementation. */
+} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
+
+/**
+ * croutine. h
+ *<pre>
+ portBASE_TYPE xCoRoutineCreate(
+ crCOROUTINE_CODE pxCoRoutineCode,
+ unsigned portBASE_TYPE uxPriority,
+ unsigned portBASE_TYPE uxIndex
+ );</pre>
+ *
+ * Create a new co-routine and add it to the list of co-routines that are
+ * ready to run.
+ *
+ * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
+ * functions require special syntax - see the co-routine section of the WEB
+ * documentation for more information.
+ *
+ * @param uxPriority The priority with respect to other co-routines at which
+ * the co-routine will run.
+ *
+ * @param uxIndex Used to distinguish between different co-routines that
+ * execute the same function. See the example below and the co-routine section
+ * of the WEB documentation for further information.
+ *
+ * @return pdPASS if the co-routine was successfully created and added to a ready
+ * list, otherwise an error code defined with ProjDefs.h.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const portTickType xTimeToDelay[ 2 ] = { 200, 400 };
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // This co-routine just delays for a fixed period, then toggles
+ // an LED. Two co-routines are created using this function, so
+ // the uxIndex parameter is used to tell the co-routine which
+ // LED to flash and how long to delay. This assumes xQueue has
+ // already been created.
+ vParTestToggleLED( cLedToFlash[ uxIndex ] );
+ crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+ // Create two co-routines at priority 0. The first is given index 0
+ // so (from the code above) toggles LED 5 every 200 ticks. The second
+ // is given index 1 so toggles LED 6 every 400 ticks.
+ for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+ {
+ xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+ }
+ }
+ </pre>
+ * \defgroup xCoRoutineCreate xCoRoutineCreate
+ * \ingroup Tasks
+ */
+signed portBASE_TYPE xCoRoutineCreate (crCOROUTINE_CODE pxCoRoutineCode,
+ unsigned portBASE_TYPE uxPriority,
+ unsigned portBASE_TYPE uxIndex);
+
+
+/**
+ * croutine. h
+ *<pre>
+ void vCoRoutineSchedule( void );</pre>
+ *
+ * Run a co-routine.
+ *
+ * vCoRoutineSchedule() executes the highest priority co-routine that is able
+ * to run. The co-routine will execute until it either blocks, yields or is
+ * preempted by a task. Co-routines execute cooperatively so one
+ * co-routine cannot be preempted by another, but can be preempted by a task.
+ *
+ * If an application comprises of both tasks and co-routines then
+ * vCoRoutineSchedule should be called from the idle task (in an idle task
+ * hook).
+ *
+ * Example usage:
+ <pre>
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+ vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+ for( ;; )
+ {
+ vCoRoutineSchedule();
+ }
+ }
+ </pre>
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule
+ * \ingroup Tasks
+ */
+void vCoRoutineSchedule (void);
+
+/**
+ * croutine. h
+ * <pre>
+ crSTART( xCoRoutineHandle xHandle );</pre>
+ *
+ * This macro MUST always be called at the start of a co-routine function.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portLONG ulAVariable;
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Co-routine functionality goes here.
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }</pre>
+ * \defgroup crSTART crSTART
+ * \ingroup Tasks
+ */
+#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
+
+/**
+ * croutine. h
+ * <pre>
+ crEND();</pre>
+ *
+ * This macro MUST always be called at the end of a co-routine function.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portLONG ulAVariable;
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Co-routine functionality goes here.
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }</pre>
+ * \defgroup crSTART crSTART
+ * \ingroup Tasks
+ */
+#define crEND() }
+
+/*
+ * These macros are intended for internal use by the co-routine implementation
+ * only. The macros should not be used directly by application writers.
+ */
+#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
+#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
+
+/**
+ * croutine. h
+ *<pre>
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
+ *
+ * Delay a co-routine for a fixed period of time.
+ *
+ * crDELAY can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function. This is because
+ * co-routines do not maintain their own stack.
+ *
+ * @param xHandle The handle of the co-routine to delay. This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should delay
+ * for. The actual amount of time this equates to is defined by
+ * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
+ * can be used to convert ticks to milliseconds.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
+
+ // Must start every co-routine with a call to crSTART();
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Delay for 200ms.
+ crDELAY( xHandle, xDelayTime );
+
+ // Do something here.
+ }
+
+ // Must end every co-routine with a call to crEND();
+ crEND();
+ }</pre>
+ * \defgroup crDELAY crDELAY
+ * \ingroup Tasks
+ */
+#define crDELAY( xHandle, xTicksToDelay ) \
+ if( xTicksToDelay > 0 ) \
+ { \
+ vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \
+ } \
+ crSET_STATE0( xHandle );
+
+/**
+ * <pre>
+ crQUEUE_SEND(
+ xCoRoutineHandle xHandle,
+ xQueueHandle pxQueue,
+ void *pvItemToQueue,
+ portTickType xTicksToWait,
+ portBASE_TYPE *pxResult
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
+ *
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
+ * xQueueSend() and xQueueReceive() can only be used from tasks.
+ *
+ * crQUEUE_SEND can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function. This is because
+ * co-routines do not maintain their own stack.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xHandle The handle of the calling co-routine. This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param pxQueue The handle of the queue on which the data will be posted.
+ * The handle is obtained as the return value when the queue is created using
+ * the xQueueCreate() API function.
+ *
+ * @param pvItemToQueue A pointer to the data being posted onto the queue.
+ * The number of bytes of each queued item is specified when the queue is
+ * created. This number of bytes is copied from pvItemToQueue into the queue
+ * itself.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should block
+ * to wait for space to become available on the queue, should space not be
+ * available immediately. The actual amount of time this equates to is defined
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
+ * below).
+ *
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
+ * data was successfully posted onto the queue, otherwise it will be set to an
+ * error defined within ProjDefs.h.
+ *
+ * Example usage:
+ <pre>
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xNumberToPost = 0;
+ static portBASE_TYPE xResult;
+
+ // Co-routines must begin with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // This assumes the queue has already been created.
+ crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+ if( xResult != pdPASS )
+ {
+ // The message was not posted!
+ }
+
+ // Increment the number to be posted onto the queue.
+ xNumberToPost++;
+
+ // Delay for 100 ticks.
+ crDELAY( xHandle, 100 );
+ }
+
+ // Co-routines must end with a call to crEND().
+ crEND();
+ }</pre>
+ * \defgroup crQUEUE_SEND crQUEUE_SEND
+ * \ingroup Tasks
+ */
+#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
+{ \
+ *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait ); \
+ if( *pxResult == errQUEUE_BLOCKED ) \
+ { \
+ crSET_STATE0( xHandle ); \
+ *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 ); \
+ } \
+ if( *pxResult == errQUEUE_YIELD ) \
+ { \
+ crSET_STATE1( xHandle ); \
+ *pxResult = pdPASS; \
+ } \
+}
+
+/**
+ * croutine. h
+ * <pre>
+ crQUEUE_RECEIVE(
+ xCoRoutineHandle xHandle,
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait,
+ portBASE_TYPE *pxResult
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
+ * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
+ *
+ * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
+ * xQueueSend() and xQueueReceive() can only be used from tasks.
+ *
+ * crQUEUE_RECEIVE can only be called from the co-routine function itself - not
+ * from within a function called by the co-routine function. This is because
+ * co-routines do not maintain their own stack.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xHandle The handle of the calling co-routine. This is the xHandle
+ * parameter of the co-routine function.
+ *
+ * @param pxQueue The handle of the queue from which the data will be received.
+ * The handle is obtained as the return value when the queue is created using
+ * the xQueueCreate() API function.
+ *
+ * @param pvBuffer The buffer into which the received item is to be copied.
+ * The number of bytes of each queued item is specified when the queue is
+ * created. This number of bytes is copied into pvBuffer.
+ *
+ * @param xTickToDelay The number of ticks that the co-routine should block
+ * to wait for data to become available from the queue, should data not be
+ * available immediately. The actual amount of time this equates to is defined
+ * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
+ * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
+ * crQUEUE_SEND example).
+ *
+ * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
+ * data was successfully retrieved from the queue, otherwise it will be set to
+ * an error code as defined within ProjDefs.h.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine receives the number of an LED to flash from a queue. It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xResult;
+ static unsigned portBASE_TYPE uxLEDToFlash;
+
+ // All co-routines must start with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Wait for data to become available on the queue.
+ crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+ if( xResult == pdPASS )
+ {
+ // We received the LED to flash - flash it!
+ vParTestToggleLED( uxLEDToFlash );
+ }
+ }
+
+ crEND();
+ }</pre>
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
+ * \ingroup Tasks
+ */
+#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
+{ \
+ *pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait ); \
+ if( *pxResult == errQUEUE_BLOCKED ) \
+ { \
+ crSET_STATE0( xHandle ); \
+ *pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 ); \
+ } \
+ if( *pxResult == errQUEUE_YIELD ) \
+ { \
+ crSET_STATE1( xHandle ); \
+ *pxResult = pdPASS; \
+ } \
+}
+
+/**
+ * croutine. h
+ * <pre>
+ crQUEUE_SEND_FROM_ISR(
+ xQueueHandle pxQueue,
+ void *pvItemToQueue,
+ portBASE_TYPE xCoRoutinePreviouslyWoken
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
+ * functions used by tasks.
+ *
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and
+ * ISR.
+ *
+ * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
+ * that is being used from within a co-routine.
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
+ * the same queue multiple times from a single interrupt. The first call
+ * should always pass in pdFALSE. Subsequent calls should pass in
+ * the value returned from the previous call.
+ *
+ * @return pdTRUE if a co-routine was woken by posting onto the queue. This is
+ * used by the ISR to determine if a context switch may be required following
+ * the ISR.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ portCHAR cRxedChar;
+ portBASE_TYPE xResult;
+
+ // All co-routines must start with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Wait for data to become available on the queue. This assumes the
+ // queue xCommsRxQueue has already been created!
+ crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+ // Was a character received?
+ if( xResult == pdPASS )
+ {
+ // Process the character here.
+ }
+ }
+
+ // All co-routines must end with a call to crEND().
+ crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ portCHAR cRxedChar;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+ // We loop around reading characters until there are none left in the UART.
+ while( UART_RX_REG_NOT_EMPTY() )
+ {
+ // Obtain the character from the UART.
+ cRxedChar = UART_RX_REG;
+
+ // Post the character onto a queue. xCRWokenByPost will be pdFALSE
+ // the first time around the loop. If the post causes a co-routine
+ // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+ // In this manner we can ensure that if more than one co-routine is
+ // blocked on the queue only one is woken by this ISR no matter how
+ // many characters are posted to the queue.
+ xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+ }
+ }</pre>
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
+ * \ingroup Tasks
+ */
+#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
+
+
+/**
+ * croutine. h
+ * <pre>
+ crQUEUE_SEND_FROM_ISR(
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portBASE_TYPE * pxCoRoutineWoken
+ )</pre>
+ *
+ * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
+ * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
+ * functions used by tasks.
+ *
+ * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
+ * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
+ * xQueueReceiveFromISR() can only be used to pass data between a task and and
+ * ISR.
+ *
+ * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
+ * from a queue that is being used from within a co-routine (a co-routine
+ * posted to the queue).
+ *
+ * See the co-routine section of the WEB documentation for information on
+ * passing data between tasks and co-routines and between ISR's and
+ * co-routines.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvBuffer A pointer to a buffer into which the received item will be
+ * placed. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from the queue into
+ * pvBuffer.
+ *
+ * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
+ * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
+ * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
+ * *pxCoRoutineWoken will remain unchanged.
+ *
+ * @return pdTRUE an item was successfully received from the queue, otherwise
+ * pdFALSE.
+ *
+ * Example usage:
+ <pre>
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period. The character is incremented each time.
+ static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static portCHAR cCharToTx = 'a';
+ portBASE_TYPE xResult;
+
+ // All co-routines must start with a call to crSTART().
+ crSTART( xHandle );
+
+ for( ;; )
+ {
+ // Send the next character to the queue.
+ crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+ if( xResult == pdPASS )
+ {
+ // The character was successfully posted to the queue.
+ }
+ else
+ {
+ // Could not post the character to the queue.
+ }
+
+ // Enable the UART Tx interrupt to cause an interrupt in this
+ // hypothetical UART. The interrupt will obtain the character
+ // from the queue and send it.
+ ENABLE_RX_INTERRUPT();
+
+ // Increment to the next character then block for a fixed period.
+ // cCharToTx will maintain its value across the delay as it is
+ // declared static.
+ cCharToTx++;
+ if( cCharToTx > 'x' )
+ {
+ cCharToTx = 'a';
+ }
+ crDELAY( 100 );
+ }
+
+ // All co-routines must end with a call to crEND().
+ crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ portCHAR cCharToTx;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+ while( UART_TX_REG_EMPTY() )
+ {
+ // Are there any characters in the queue waiting to be sent?
+ // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+ // is woken by the post - ensuring that only a single co-routine is
+ // woken no matter how many times we go around this loop.
+ if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+ {
+ SEND_CHARACTER( cCharToTx );
+ }
+ }
+ }</pre>
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
+ * \ingroup Tasks
+ */
+#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
+
+/*
+ * This function is intended for internal use by the co-routine macros only.
+ * The macro nature of the co-routine implementation requires that the
+ * prototype appears here. The function should not be used by application
+ * writers.
+ *
+ * Removes the current co-routine from its ready list and places it in the
+ * appropriate delayed list.
+ */
+void vCoRoutineAddToDelayedList (portTickType xTicksToDelay,
+ xList * pxEventList);
+
+/*
+ * This function is intended for internal use by the queue implementation only.
+ * The function should not be used by application writers.
+ *
+ * Removes the highest priority co-routine from the event list and places it in
+ * the pending ready list.
+ */
+signed portBASE_TYPE xCoRoutineRemoveFromEventList (const xList *
+ pxEventList);
+
+
+#endif /* CO_ROUTINE_H */
diff --git a/openpicc/os/core/include/death.h b/openpicc/os/core/include/death.h
new file mode 100644
index 0000000..d5f20e0
--- /dev/null
+++ b/openpicc/os/core/include/death.h
@@ -0,0 +1,42 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef SUICIDE_TASK_H
+#define SUICIDE_TASK_H
+
+void vCreateSuicidalTasks (unsigned portBASE_TYPE uxPriority);
+portBASE_TYPE xIsCreateTaskStillRunning (void);
+
+#endif
diff --git a/openpicc/os/core/include/dynamic.h b/openpicc/os/core/include/dynamic.h
new file mode 100644
index 0000000..5a77c07
--- /dev/null
+++ b/openpicc/os/core/include/dynamic.h
@@ -0,0 +1,42 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef DYNAMIC_MANIPULATION_H
+#define DYNAMIC_MANIPULATION_H
+
+void vStartDynamicPriorityTasks (void);
+portBASE_TYPE xAreDynamicPriorityTasksStillRunning (void);
+
+#endif
diff --git a/openpicc/os/core/include/fileIO.h b/openpicc/os/core/include/fileIO.h
new file mode 100644
index 0000000..d1b336b
--- /dev/null
+++ b/openpicc/os/core/include/fileIO.h
@@ -0,0 +1,44 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef FILE_IO_H
+#define FILE_OI_H
+
+void vDisplayMessage (const portCHAR * const pcMessageToPrint);
+void vWriteMessageToDisk (const portCHAR * const pcMessage);
+void vWriteBufferToDisk (const portCHAR * const pcBuffer,
+ unsigned portLONG ulBufferLength);
+
+#endif
diff --git a/openpicc/os/core/include/list.h b/openpicc/os/core/include/list.h
new file mode 100644
index 0000000..cdd6a75
--- /dev/null
+++ b/openpicc/os/core/include/list.h
@@ -0,0 +1,272 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+ * This is the list implementation used by the scheduler. While it is tailored
+ * heavily for the schedulers needs, it is also available for use by
+ * application code.
+ *
+ * xLists can only store pointers to xListItems. Each xListItem contains a
+ * numeric value (xItemValue). Most of the time the lists are sorted in
+ * descending item value order.
+ *
+ * Lists are created already containing one list item. The value of this
+ * item is the maximum possible that can be stored, it is therefore always at
+ * the end of the list and acts as a marker. The list member pxHead always
+ * points to this marker - even though it is at the tail of the list. This
+ * is because the tail contains a wrap back pointer to the true head of
+ * the list.
+ *
+ * In addition to it's value, each list item contains a pointer to the next
+ * item in the list (pxNext), a pointer to the list it is in (pxContainer)
+ * and a pointer to back to the object that contains it. These later two
+ * pointers are included for efficiency of list manipulation. There is
+ * effectively a two way link between the object containing the list item and
+ * the list item itself.
+ *
+ *
+ * \page ListIntroduction List Implementation
+ * \ingroup FreeRTOSIntro
+ */
+
+
+#ifndef LIST_H
+#define LIST_H
+
+/*
+ * Definition of the only type of object that a list can contain.
+ */
+struct xLIST_ITEM
+{
+ portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
+ volatile struct xLIST_ITEM *pxNext; /*< Pointer to the next xListItem in the list. */
+ volatile struct xLIST_ITEM *pxPrevious; /*< Pointer to the previous xListItem in the list. */
+ void *pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
+ void *pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
+};
+typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
+
+struct xMINI_LIST_ITEM
+{
+ portTickType xItemValue;
+ volatile struct xLIST_ITEM *pxNext;
+ volatile struct xLIST_ITEM *pxPrevious;
+};
+typedef struct xMINI_LIST_ITEM xMiniListItem;
+
+/*
+ * Definition of the type of queue used by the scheduler.
+ */
+typedef struct xLIST
+{
+ volatile unsigned portBASE_TYPE uxNumberOfItems;
+ volatile xListItem *pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
+ volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
+} xList;
+
+/*
+ * Access macro to set the owner of a list item. The owner of a list item
+ * is the object (usually a TCB) that contains the list item.
+ *
+ * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) pxOwner
+
+/*
+ * Access macro to set the value of the list item. In most cases the value is
+ * used to sort the list in descending order.
+ *
+ * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = xValue
+
+/*
+ * Access macro the retrieve the value of the list item. The value can
+ * represent anything - for example a the priority of a task, or the time at
+ * which a task should be unblocked.
+ *
+ * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
+ * \ingroup LinkedList
+ */
+#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
+
+/*
+ * Access macro to determine if a list contains any items. The macro will
+ * only have the value true if the list is empty.
+ *
+ * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
+ * \ingroup LinkedList
+ */
+#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
+
+/*
+ * Access macro to return the number of items in the list.
+ */
+#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
+
+/*
+ * Access function to obtain the owner of the next entry in a list.
+ *
+ * The list member pxIndex is used to walk through a list. Calling
+ * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
+ * and returns that entries pxOwner parameter. Using multiple calls to this
+ * function it is therefore possible to move through every item contained in
+ * a list.
+ *
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item. In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxList The list from which the next item owner is to be returned.
+ *
+ * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
+ /* Increment the index to the next item and return the item, ensuring */ \
+ /* we don't return the marker used at the end of the list. */ \
+ ( pxList )->pxIndex = ( pxList )->pxIndex->pxNext; \
+ if( ( pxList )->pxIndex == ( xListItem * ) &( ( pxList )->xListEnd ) ) \
+ { \
+ ( pxList )->pxIndex = ( pxList )->pxIndex->pxNext; \
+ } \
+ pxTCB = ( pxList )->pxIndex->pvOwner
+
+
+/*
+ * Access function to obtain the owner of the first entry in a list. Lists
+ * are normally sorted in ascending item value order.
+ *
+ * This function returns the pxOwner member of the first item in the list.
+ * The pxOwner parameter of a list item is a pointer to the object that owns
+ * the list item. In the scheduler this is normally a task control block.
+ * The pxOwner parameter effectively creates a two way link between the list
+ * item and its owner.
+ *
+ * @param pxList The list from which the owner of the head item is to be
+ * returned.
+ *
+ * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
+ * \ingroup LinkedList
+ */
+#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( ( pxList->uxNumberOfItems != ( unsigned portBASE_TYPE ) 0 ) ? ( (&( pxList->xListEnd ))->pxNext->pvOwner ) : ( NULL ) )
+
+/*
+ * Check to see if a list item is within a list. The list item maintains a
+ * "container" pointer that points to the list it is in. All this macro does
+ * is check to see if the container and the list match.
+ *
+ * @param pxList The list we want to know if the list item is within.
+ * @param pxListItem The list item we want to know if is in the list.
+ * @return pdTRUE is the list item is in the list, otherwise pdFALSE.
+ * pointer against
+ */
+#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) pxList )
+
+/*
+ * Must be called before a list is used! This initialises all the members
+ * of the list structure and inserts the xListEnd item into the list as a
+ * marker to the back of the list.
+ *
+ * @param pxList Pointer to the list being initialised.
+ *
+ * \page vListInitialise vListInitialise
+ * \ingroup LinkedList
+ */
+void vListInitialise (xList * pxList);
+
+/*
+ * Must be called before a list item is used. This sets the list container to
+ * null so the item does not think that it is already contained in a list.
+ *
+ * @param pxItem Pointer to the list item being initialised.
+ *
+ * \page vListInitialiseItem vListInitialiseItem
+ * \ingroup LinkedList
+ */
+void vListInitialiseItem (xListItem * pxItem);
+
+/*
+ * Insert a list item into a list. The item will be inserted into the list in
+ * a position determined by its item value (descending item value order).
+ *
+ * @param pxList The list into which the item is to be inserted.
+ *
+ * @param pxNewListItem The item to that is to be placed in the list.
+ *
+ * \page vListInsert vListInsert
+ * \ingroup LinkedList
+ */
+void vListInsert (xList * pxList, xListItem * pxNewListItem);
+
+/*
+ * Insert a list item into a list. The item will be inserted in a position
+ * such that it will be the last item within the list returned by multiple
+ * calls to listGET_OWNER_OF_NEXT_ENTRY.
+ *
+ * The list member pvIndex is used to walk through a list. Calling
+ * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
+ * Placing an item in a list using vListInsertEnd effectively places the item
+ * in the list position pointed to by pvIndex. This means that every other
+ * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
+ * the pvIndex parameter again points to the item being inserted.
+ *
+ * @param pxList The list into which the item is to be inserted.
+ *
+ * @param pxNewListItem The list item to be inserted into the list.
+ *
+ * \page vListInsertEnd vListInsertEnd
+ * \ingroup LinkedList
+ */
+void vListInsertEnd (xList * pxList, xListItem * pxNewListItem);
+
+/*
+ * Remove an item from a list. The list item has a pointer to the list that
+ * it is in, so only the list item need be passed into the function.
+ *
+ * @param vListRemove The item to be removed. The item will remove itself from
+ * the list pointed to by it's pxContainer parameter.
+ *
+ * \page vListRemove vListRemove
+ * \ingroup LinkedList
+ */
+void vListRemove (xListItem * pxItemToRemove);
+
+
+
+#endif
diff --git a/openpicc/os/core/include/mevents.h b/openpicc/os/core/include/mevents.h
new file mode 100644
index 0000000..a4580a8
--- /dev/null
+++ b/openpicc/os/core/include/mevents.h
@@ -0,0 +1,42 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef EVENTS_TEST_H
+#define EVENTS_TEST_H
+
+void vStartMultiEventTasks (void);
+portBASE_TYPE xAreMultiEventTasksStillRunning (void);
+
+#endif
diff --git a/openpicc/os/core/include/portable.h b/openpicc/os/core/include/portable.h
new file mode 100644
index 0000000..49d11b0
--- /dev/null
+++ b/openpicc/os/core/include/portable.h
@@ -0,0 +1,233 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http:www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http:www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*-----------------------------------------------------------
+ * Portable layer API. Each function must be defined for each port.
+ *----------------------------------------------------------*/
+
+#ifndef PORTABLE_H
+#define PORTABLE_H
+
+/* Include the macro file relevant to the port being used. */
+
+#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
+#include "..\..\source\portable\owatcom\16bitdos\pc\portmacro.h"
+typedef void (__interrupt __far * pxISR) ();
+#endif
+
+#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
+#include "..\..\source\portable\owatcom\16bitdos\flsh186\portmacro.h"
+typedef void (__interrupt __far * pxISR) ();
+#endif
+
+#ifdef GCC_MEGA_AVR
+#include "../portable/GCC/ATMega323/portmacro.h"
+#endif
+
+#ifdef IAR_MEGA_AVR
+#include "../portable/IAR/ATMega323/portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC24_PORT
+#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
+#endif
+
+#ifdef MPLAB_DSPIC_PORT
+#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
+#endif
+
+#ifdef MPLAB_PIC18F_PORT
+#include "..\..\source\portable\MPLAB\PIC18F\portmacro.h"
+#endif
+
+#ifdef _FEDPICC
+#include "libFreeRTOS/Include/portmacro.h"
+#endif
+
+#ifdef SDCC_CYGNAL
+#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
+#endif
+
+#ifdef GCC_ARM7
+#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
+#endif
+
+#ifdef ROWLEY_LPC23xx
+#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
+#endif
+
+#ifdef GCC_MSP430
+#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
+#endif
+
+#ifdef ROWLEY_MSP430
+#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
+#endif
+
+#ifdef KEIL_ARM7
+#include "..\..\Source\portable\Keil\ARM7\portmacro.h"
+#endif
+
+#ifdef SAM7_GCC
+#include "../ARM7_AT91SAM7S/portmacro.h"
+#endif
+
+#ifdef SAM7_IAR
+#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
+#endif
+
+#ifdef LPC2000_IAR
+#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
+#endif
+
+#ifdef STR71X_IAR
+#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
+#endif
+
+#ifdef STR75X_IAR
+#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
+#endif
+
+#ifdef STR75X_GCC
+#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
+#endif
+
+#ifdef STR91X_IAR
+#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
+#endif
+
+#ifdef GCC_H8S
+#include "../../Source/portable/GCC/H8S2329/portmacro.h"
+#endif
+
+#ifdef GCC_AT91FR40008
+#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
+#endif
+
+#ifdef RVDS_ARMCM3_LM3S102
+#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef GCC_ARMCM3_LM3S102
+#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef IAR_ARMCM3_LM
+#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
+#endif
+
+#ifdef HCS12_CODE_WARRIOR
+#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
+#endif
+
+#ifdef MICROBLAZE_GCC
+#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
+#endif
+
+#ifdef TERN_EE
+#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
+#endif
+
+#ifdef GCC_HCS12
+#include "../../Source/portable/GCC/HCS12/portmacro.h"
+#endif
+
+#ifdef GCC_MCF5235
+#include "../../Source/portable/GCC/MCF5235/portmacro.h"
+#endif
+
+#ifdef BCC_INDUSTRIAL_PC_PORT
+ /* A short file name has to be used in place of the normal
+ FreeRTOSConfig.h when using the Borland compiler. */
+#include "frconfig.h"
+#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
+typedef void (__interrupt __far * pxISR) ();
+#endif
+
+#ifdef BCC_FLASH_LITE_186_PORT
+ /* A short file name has to be used in place of the normal
+ FreeRTOSConfig.h when using the Borland compiler. */
+#include "frconfig.h"
+#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
+typedef void (__interrupt __far * pxISR) ();
+#endif
+
+#if __GNUC__ && (__AVR32_UC3A0256__ || \
+ __AVR32_UC3A0512__ || \
+ __AVR32_UC3A1128__ || \
+ __AVR32_UC3A1256__ || \
+ __AVR32_UC3A1512__)
+#include "portmacro.h"
+#endif
+
+#if __ICCAVR32__ && (__AT32UC3A0256__ || \
+ __AT32UC3A0512__ || \
+ __AT32UC3A1128__ || \
+ __AT32UC3A1256__ || \
+ __AT32UC3A1512__)
+#include "portmacro.h"
+#endif
+
+/*
+ * Setup the stack of a new task so it is ready to be placed under the
+ * scheduler control. The registers have to be placed on the stack in
+ * the order that the port expects to find them.
+ */
+portSTACK_TYPE *pxPortInitialiseStack (portSTACK_TYPE * pxTopOfStack,
+ pdTASK_CODE pxCode,
+ void *pvParameters);
+
+/*
+ * Map to the memory management routines required for the port.
+ */
+void *pvPortMalloc (size_t xSize);
+void vPortFree (void *pv);
+void vPortInitialiseBlocks (void);
+
+/*
+ * Setup the hardware ready for the scheduler to take control. This generally
+ * sets up a tick interrupt and sets timers for the correct tick frequency.
+ */
+portBASE_TYPE xPortStartScheduler (void);
+
+/*
+ * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
+ * the hardware is left in its original condition after the scheduler stops
+ * executing.
+ */
+void vPortEndScheduler (void);
+
+
+#endif /* PORTABLE_H */
diff --git a/openpicc/os/core/include/print.h b/openpicc/os/core/include/print.h
new file mode 100644
index 0000000..d219bc4
--- /dev/null
+++ b/openpicc/os/core/include/print.h
@@ -0,0 +1,43 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef PRINT_H
+#define PRINT_H
+
+void vPrintInitialise (void);
+void vPrintDisplayMessage (const portCHAR * const *pcMessageToSend);
+const portCHAR *pcPrintGetNextMessage (portTickType xPrintRate);
+
+#endif
diff --git a/openpicc/os/core/include/projdefs.h b/openpicc/os/core/include/projdefs.h
new file mode 100644
index 0000000..3b2f1b7
--- /dev/null
+++ b/openpicc/os/core/include/projdefs.h
@@ -0,0 +1,56 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef PROJDEFS_H
+#define PROJDEFS_H
+
+/* Defines to prototype to which task functions must conform. */
+typedef void (*pdTASK_CODE) (void *);
+
+#define pdTRUE ( 1 )
+#define pdFALSE ( 0 )
+
+#define pdPASS ( 1 )
+#define pdFAIL ( 0 )
+#define errQUEUE_EMPTY ( 0 )
+#define errQUEUE_FULL ( 0 )
+
+/* Error definitions. */
+#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
+#define errNO_TASK_TO_RUN ( -2 )
+#define errQUEUE_BLOCKED ( -4 )
+#define errQUEUE_YIELD ( -5 )
+
+#endif /* PROJDEFS_H */
diff --git a/openpicc/os/core/include/queue.h b/openpicc/os/core/include/queue.h
new file mode 100644
index 0000000..e95d7b0
--- /dev/null
+++ b/openpicc/os/core/include/queue.h
@@ -0,0 +1,492 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef QUEUE_H
+#define QUEUE_H
+
+typedef void *xQueueHandle;
+
+/**
+ * queue. h
+ * <pre>
+ xQueueHandle xQueueCreate(
+ unsigned portBASE_TYPE uxQueueLength,
+ unsigned portBASE_TYPE uxItemSize
+ );
+ * </pre>
+ *
+ * Creates a new queue instance. This allocates the storage required by the
+ * new queue and returns a handle for the queue.
+ *
+ * @param uxQueueLength The maximum number of items that the queue can contain.
+ *
+ * @param uxItemSize The number of bytes each item in the queue will require.
+ * Items are queued by copy, not by reference, so this is the number of bytes
+ * that will be copied for each posted item. Each item on the queue must be
+ * the same size.
+ *
+ * @return If the queue is successfully create then a handle to the newly
+ * created queue is returned. If the queue cannot be created then 0 is
+ * returned.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ portCHAR ucMessageID;
+ portCHAR ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+
+ // Create a queue capable of containing 10 unsigned long values.
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );
+ if( xQueue1 == 0 )
+ {
+ // Queue was not created and must not be used.
+ }
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue2 == 0 )
+ {
+ // Queue was not created and must not be used.
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueCreate xQueueCreate
+ * \ingroup QueueManagement
+ */
+xQueueHandle xQueueCreate (unsigned portBASE_TYPE uxQueueLength,
+ unsigned portBASE_TYPE uxItemSize);
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSend(
+ xQueueHandle xQueue,
+ const void * pvItemToQueue,
+ portTickType xTicksToWait
+ );
+ * </pre>
+ *
+ * Post an item on a queue. The item is queued by copy, not by reference.
+ * This function must not be called from an interrupt service routine.
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for space to become available on the queue, should it already
+ * be full. The call will return immediately if this is set to 0. The
+ * time is defined in tick periods so the constant portTICK_RATE_MS
+ * should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ portCHAR ucMessageID;
+ portCHAR ucData[ 20 ];
+ } xMessage;
+
+ unsigned portLONG ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 unsigned long values.
+ xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+ // ...
+
+ if( xQueue1 != 0 )
+ {
+ // Send an unsigned long. Wait for 10 ticks for space to become
+ // available if necessary.
+ if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+ {
+ // Failed to post the message, even after 10 ticks.
+ }
+ }
+
+ if( xQueue2 != 0 )
+ {
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueSend xQueueSend
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueSend (xQueueHandle xQueue,
+ const void *pvItemToQueue,
+ portTickType xTicksToWait);
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueReceive(
+ xQueueHandle xQueue,
+ void *pvBuffer,
+ portTickType xTicksToWait
+ );</pre>
+ *
+ * Receive an item from a queue. The item is received by copy so a buffer of
+ * adequate size must be provided. The number of bytes copied into the buffer
+ * was defined when the queue was created.
+ *
+ * This function must not be used in an interrupt service routine. See
+ * xQueueReceiveFromISR for an alternative that can.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param xTicksToWait The maximum amount of time the task should block
+ * waiting for an item to receive should the queue be empty at the time
+ * of the call. The time is defined in tick periods so the constant
+ * portTICK_RATE_MS should be used to convert to real time if this is required.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+ <pre>
+ struct AMessage
+ {
+ portCHAR ucMessageID;
+ portCHAR ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+ // Create a queue capable of containing 10 pointers to AMessage structures.
+ // These should be passed by pointer as they contain a lot of data.
+ xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Send a pointer to a struct AMessage object. Don't block if the
+ // queue is already full.
+ pxMessage = & xMessage;
+ xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+ // ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+ if( xQueue != 0 )
+ {
+ // Receive a message on the created queue. Block for 10 ticks if a
+ // message is not immediately available.
+ if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+ {
+ // pcRxedMessage now points to the struct AMessage variable posted
+ // by vATask.
+ }
+ }
+
+ // ... Rest of task code.
+ }
+ </pre>
+ * \defgroup xQueueReceive xQueueReceive
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueReceive (xQueueHandle xQueue, void *pvBuffer,
+ portTickType xTicksToWait);
+
+/**
+ * queue. h
+ * <pre>unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );</pre>
+ *
+ * Return the number of messages stored in a queue.
+ *
+ * @param xQueue A handle to the queue being queried.
+ *
+ * @return The number of messages available in the queue.
+ *
+ * \page uxQueueMessagesWaiting uxQueueMessagesWaiting
+ * \ingroup QueueManagement
+ */
+unsigned portBASE_TYPE uxQueueMessagesWaiting (xQueueHandle xQueue);
+
+/**
+ * queue. h
+ * <pre>void vQueueDelete( xQueueHandle xQueue );</pre>
+ *
+ * Delete a queue - freeing all the memory allocated for storing of items
+ * placed on the queue.
+ *
+ * @param xQueue A handle to the queue to be deleted.
+ *
+ * \page vQueueDelete vQueueDelete
+ * \ingroup QueueManagement
+ */
+void vQueueDelete (xQueueHandle xQueue);
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueSendFromISR(
+ xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portBASE_TYPE xTaskPreviouslyWoken
+ );
+ </pre>
+ *
+ * Post an item on a queue. It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * Items are queued by copy not reference so it is preferable to only
+ * queue small items, especially when called from an ISR. In most cases
+ * it would be preferable to store a pointer to the item being queued.
+ *
+ * @param xQueue The handle to the queue on which the item is to be posted.
+ *
+ * @param pvItemToQueue A pointer to the item that is to be placed on the
+ * queue. The size of the items the queue will hold was defined when the
+ * queue was created, so this many bytes will be copied from pvItemToQueue
+ * into the queue storage area.
+ *
+ * @param cTaskPreviouslyWoken This is included so an ISR can post onto
+ * the same queue multiple times from a single interrupt. The first call
+ * should always pass in pdFALSE. Subsequent calls should pass in
+ * the value returned from the previous call. See the file serial .c in the
+ * PC port for a good example of this mechanism.
+ *
+ * @return pdTRUE if a task was woken by posting onto the queue. This is
+ * used by the ISR to determine if a context switch may be required following
+ * the ISR.
+ *
+ * Example usage for buffered IO (where the ISR can obtain more than one value
+ * per call):
+ <pre>
+ void vBufferISR( void )
+ {
+ portCHAR cIn;
+ portBASE_TYPE xTaskWokenByPost;
+
+ // We have not woken a task at the start of the ISR.
+ cTaskWokenByPost = pdFALSE;
+
+ // Loop until the buffer is empty.
+ do
+ {
+ // Obtain a byte from the buffer.
+ cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+ // Post the byte. The first time round the loop cTaskWokenByPost
+ // will be pdFALSE. If the queue send causes a task to wake we do
+ // not want the task to run until we have finished the ISR, so
+ // xQueueSendFromISR does not cause a context switch. Also we
+ // don't want subsequent posts to wake any other tasks, so we store
+ // the return value back into cTaskWokenByPost so xQueueSendFromISR
+ // knows not to wake any task the next iteration of the loop.
+ xTaskWokenByPost = xQueueSendFromISR( xRxQueue, &cIn, cTaskWokenByPost );
+
+ } while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+ // Now the buffer is empty we can switch context if necessary.
+ if( cTaskWokenByPost )
+ {
+ taskYIELD ();
+ }
+ }
+ </pre>
+ *
+ * \defgroup xQueueSendFromISR xQueueSendFromISR
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueSendFromISR (xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ signed portBASE_TYPE
+ xTaskPreviouslyWoken);
+
+/**
+ * queue. h
+ * <pre>
+ portBASE_TYPE xQueueReceiveFromISR(
+ xQueueHandle pxQueue,
+ void *pvBuffer,
+ portBASE_TYPE *pxTaskWoken
+ );
+ * </pre>
+ *
+ * Receive an item from a queue. It is safe to use this function from within an
+ * interrupt service routine.
+ *
+ * @param pxQueue The handle to the queue from which the item is to be
+ * received.
+ *
+ * @param pvBuffer Pointer to the buffer into which the received item will
+ * be copied.
+ *
+ * @param pxTaskWoken A task may be blocked waiting for space to become
+ * available on the queue. If xQueueReceiveFromISR causes such a task to
+ * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will
+ * remain unchanged.
+ *
+ * @return pdTRUE if an item was successfully received from the queue,
+ * otherwise pdFALSE.
+ *
+ * Example usage:
+ <pre>
+
+ xQueueHandle xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ portCHAR cValueToPost;
+ const portTickType xBlockTime = ( portTickType )0xff;
+
+ // Create a queue capable of containing 10 characters.
+ xQueue = xQueueCreate( 10, sizeof( portCHAR ) );
+ if( xQueue == 0 )
+ {
+ // Failed to create the queue.
+ }
+
+ // ...
+
+ // Post some characters that will be used within an ISR. If the queue
+ // is full then this task will block for xBlockTime ticks.
+ cValueToPost = 'a';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ cValueToPost = 'b';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+
+ // ... keep posting characters ... this task may block when the queue
+ // becomes full.
+
+ cValueToPost = 'c';
+ xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ portBASE_TYPE xTaskWokenByReceive = pdFALSE;
+ portCHAR cRxedChar;
+
+ while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+ {
+ // A character was received. Output the character now.
+ vOutputCharacter( cRxedChar );
+
+ // If removing the character from the queue woke the task that was
+ // posting onto the queue cTaskWokenByReceive will have been set to
+ // pdTRUE. No matter how many times this loop iterates only one
+ // task will be woken.
+ }
+
+ if( cTaskWokenByPost != ( portCHAR ) pdFALSE;
+ {
+ taskYIELD ();
+ }
+ }
+ </pre>
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR
+ * \ingroup QueueManagement
+ */
+signed portBASE_TYPE xQueueReceiveFromISR (xQueueHandle pxQueue,
+ void *pvBuffer,
+ signed portBASE_TYPE *
+ pxTaskWoken);
+
+
+/*
+ * The functions defined above are for passing data to and from tasks. The
+ * functions below are the equivalents for passing data to and from
+ * co-rtoutines.
+ *
+ * These functions are called from the co-routine macro implementation and
+ * should not be called directly from application code. Instead use the macro
+ * wrappers defined within croutine.h.
+ */
+signed portBASE_TYPE xQueueCRSendFromISR (xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ signed portBASE_TYPE
+ xCoRoutinePreviouslyWoken);
+signed portBASE_TYPE xQueueCRReceiveFromISR (xQueueHandle pxQueue,
+ void *pvBuffer,
+ signed portBASE_TYPE *
+ pxTaskWoken);
+signed portBASE_TYPE xQueueCRSend (xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portTickType xTicksToWait);
+signed portBASE_TYPE xQueueCRReceive (xQueueHandle pxQueue, void *pvBuffer,
+ portTickType xTicksToWait);
+
+#endif
diff --git a/openpicc/os/core/include/semphr.h b/openpicc/os/core/include/semphr.h
new file mode 100644
index 0000000..acdd022
--- /dev/null
+++ b/openpicc/os/core/include/semphr.h
@@ -0,0 +1,291 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#include "queue.h"
+
+#ifndef SEMAPHORE_H
+#define SEMAPHORE_H
+
+typedef xQueueHandle xSemaphoreHandle;
+
+#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned portCHAR ) 1 )
+#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portCHAR ) 0 )
+#define semGIVE_BLOCK_TIME ( ( portTickType ) 0 )
+
+
+/**
+ * semphr. h
+ * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
+ *
+ * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
+ * The queue length is 1 as this is a binary semaphore. The data size is 0
+ * as we don't want to actually store any data - we just want to know if the
+ * queue is empty or full.
+ *
+ * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+ // This is a macro so pass the variable in directly.
+ vSemaphoreCreateBinary( xSemaphore );
+
+ if( xSemaphore != NULL )
+ {
+ // The semaphore was created successfully.
+ // The semaphore can now be used.
+ }
+ }
+ </pre>
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
+ * \ingroup Semaphores
+ */
+#define vSemaphoreCreateBinary( xSemaphore ) { \
+ xSemaphore = xQueueCreate( ( unsigned portCHAR ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
+ if( xSemaphore != NULL ) \
+ { \
+ xSemaphoreGive( xSemaphore ); \
+ } \
+ }
+
+/**
+ * semphr. h
+ * xSemaphoreTake(
+ * xSemaphoreHandle xSemaphore,
+ * portTickType xBlockTime
+ * )</pre>
+ *
+ * <i>Macro</i> to obtain a semaphore. The semaphore must of been created using
+ * vSemaphoreCreateBinary ().
+ *
+ * @param xSemaphore A handle to the semaphore being obtained. This is the
+ * handle returned by vSemaphoreCreateBinary ();
+ *
+ * @param xBlockTime The time in ticks to wait for the semaphore to become
+ * available. The macro portTICK_RATE_MS can be used to convert this to a
+ * real time. A block time of zero can be used to poll the semaphore.
+ *
+ * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
+ * expired without the semaphore becoming available.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+ // Create the semaphore to guard a shared resource.
+ vSemaphoreCreateBinary( xSemaphore );
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+ // ... Do other things.
+
+ if( xSemaphore != NULL )
+ {
+ // See if we can obtain the semaphore. If the semaphore is not available
+ // wait 10 ticks to see if it becomes free.
+ if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+ {
+ // We were able to obtain the semaphore and can now access the
+ // shared resource.
+
+ // ...
+
+ // We have finished accessing the shared resource. Release the
+ // semaphore.
+ xSemaphoreGive( xSemaphore );
+ }
+ else
+ {
+ // We could not obtain the semaphore and can therefore not access
+ // the shared resource safely.
+ }
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreTake xSemaphoreTake
+ * \ingroup Semaphores
+ */
+#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime )
+
+/**
+ * semphr. h
+ * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
+ *
+ * <i>Macro</i> to release a semaphore. The semaphore must of been created using
+ * vSemaphoreCreateBinary (), and obtained using sSemaphoreTake ().
+ *
+ * This must not be used from an ISR. See xSemaphoreGiveFromISR () for
+ * an alternative which can be used from an ISR.
+ *
+ * @param xSemaphore A handle to the semaphore being released. This is the
+ * handle returned by vSemaphoreCreateBinary ();
+ *
+ * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
+ * Semaphores are implemented using queues. An error can occur if there is
+ * no space on the queue to post a message - indicating that the
+ * semaphore was not first obtained correctly.
+ *
+ * Example usage:
+ <pre>
+ xSemaphoreHandle xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+ // Create the semaphore to guard a shared resource.
+ vSemaphoreCreateBinary( xSemaphore );
+
+ if( xSemaphore != NULL )
+ {
+ if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+ {
+ // We would expect this call to fail because we cannot give
+ // a semaphore without first "taking" it!
+ }
+
+ // Obtain the semaphore - don't block if the semaphore is not
+ // immediately available.
+ if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
+ {
+ // We now have the semaphore and can access the shared resource.
+
+ // ...
+
+ // We have finished accessing the shared resource so can free the
+ // semaphore.
+ if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+ {
+ // We would not expect this call to fail because we must have
+ // obtained the semaphore to get here.
+ }
+ }
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreGive xSemaphoreGive
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGive( xSemaphore ) xQueueSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME )
+
+/**
+ * semphr. h
+ * <pre>
+ xSemaphoreGiveFromISR(
+ xSemaphoreHandle xSemaphore,
+ portSHORT sTaskPreviouslyWoken
+ )</pre>
+ *
+ * <i>Macro</i> to release a semaphore. The semaphore must of been created using
+ * vSemaphoreCreateBinary (), and obtained using xSemaphoreTake ().
+ *
+ * This macro can be used from an ISR.
+ *
+ * @param xSemaphore A handle to the semaphore being released. This is the
+ * handle returned by vSemaphoreCreateBinary ();
+ *
+ * @param sTaskPreviouslyWoken This is included so an ISR can make multiple calls
+ * to xSemaphoreGiveFromISR () from a single interrupt. The first call
+ * should always pass in pdFALSE. Subsequent calls should pass in
+ * the value returned from the previous call. See the file serial .c in the
+ * PC port for a good example of using xSemaphoreGiveFromISR ().
+ *
+ * @return pdTRUE if a task was woken by releasing the semaphore. This is
+ * used by the ISR to determine if a context switch may be required following
+ * the ISR.
+ *
+ * Example usage:
+ <pre>
+ #define LONG_TIME 0xffff
+ #define TICKS_TO_WAIT 10
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // We want this task to run every 10 ticks or a timer. The semaphore
+ // was created before this task was started
+
+ // Block waiting for the semaphore to become available.
+ if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+ {
+ // It is time to execute.
+
+ // ...
+
+ // We have finished our task. Return to the top of the loop where
+ // we will block on the semaphore until it is time to execute
+ // again.
+ }
+ }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static unsigned portCHAR ucLocalTickCount = 0;
+
+ // A timer tick has occurred.
+
+ // ... Do other time functions.
+
+ // Is it time for vATask () to run?
+ ucLocalTickCount++;
+ if( ucLocalTickCount >= TICKS_TO_WAIT )
+ {
+ // Unblock the task by releasing the semaphore.
+ xSemaphoreGive( xSemaphore );
+
+ // Reset the count so we release the semaphore again in 10 ticks time.
+ ucLocalTickCount = 0;
+ }
+ }
+ </pre>
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
+ * \ingroup Semaphores
+ */
+#define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken ) xQueueSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken )
+
+
+#endif
diff --git a/openpicc/os/core/include/serial.h b/openpicc/os/core/include/serial.h
new file mode 100644
index 0000000..58c7a5f
--- /dev/null
+++ b/openpicc/os/core/include/serial.h
@@ -0,0 +1,116 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef SERIAL_COMMS_H
+#define SERIAL_COMMS_H
+
+typedef void *xComPortHandle;
+
+typedef enum
+{
+ serCOM1,
+ serCOM2,
+ serCOM3,
+ serCOM4,
+ serCOM5,
+ serCOM6,
+ serCOM7,
+ serCOM8
+} eCOMPort;
+
+typedef enum
+{
+ serNO_PARITY,
+ serODD_PARITY,
+ serEVEN_PARITY,
+ serMARK_PARITY,
+ serSPACE_PARITY
+} eParity;
+
+typedef enum
+{
+ serSTOP_1,
+ serSTOP_2
+} eStopBits;
+
+typedef enum
+{
+ serBITS_5,
+ serBITS_6,
+ serBITS_7,
+ serBITS_8
+} eDataBits;
+
+typedef enum
+{
+ ser50,
+ ser75,
+ ser110,
+ ser134,
+ ser150,
+ ser200,
+ ser300,
+ ser600,
+ ser1200,
+ ser1800,
+ ser2400,
+ ser4800,
+ ser9600,
+ ser19200,
+ ser38400,
+ ser57600,
+ ser115200
+} eBaud;
+
+xComPortHandle xSerialPortInitMinimal (unsigned portLONG ulWantedBaud,
+ unsigned portBASE_TYPE uxQueueLength);
+xComPortHandle xSerialPortInit (eCOMPort ePort, eBaud eWantedBaud,
+ eParity eWantedParity,
+ eDataBits eWantedDataBits,
+ eStopBits eWantedStopBits,
+ unsigned portBASE_TYPE uxBufferLength);
+void vSerialPutString (xComPortHandle pxPort,
+ const signed portCHAR * const pcString,
+ unsigned portSHORT usStringLength);
+signed portBASE_TYPE xSerialGetChar (xComPortHandle pxPort,
+ signed portCHAR * pcRxedChar,
+ portTickType xBlockTime);
+signed portBASE_TYPE xSerialPutChar (xComPortHandle pxPort,
+ signed portCHAR cOutChar,
+ portTickType xBlockTime);
+portBASE_TYPE xSerialWaitForSemaphore (xComPortHandle xPort);
+void vSerialClose (xComPortHandle xPort);
+
+#endif
diff --git a/openpicc/os/core/include/task.h b/openpicc/os/core/include/task.h
new file mode 100644
index 0000000..3d01c53
--- /dev/null
+++ b/openpicc/os/core/include/task.h
@@ -0,0 +1,960 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef TASK_H
+#define TASK_H
+
+#include "portable.h"
+#include "list.h"
+
+/*-----------------------------------------------------------
+ * MACROS AND DEFINITIONS
+ *----------------------------------------------------------*/
+
+#define tskKERNEL_VERSION_NUMBER "V4.2.1"
+
+/**
+ * task. h
+ *
+ * Type by which tasks are referenced. For example, a call to xTaskCreate
+ * returns (via a pointer parameter) an xTaskHandle variable that can then
+ * be used as a parameter to vTaskDelete to delete the task.
+ *
+ * \page xTaskHandle xTaskHandle
+ * \ingroup Tasks
+ */
+typedef void *xTaskHandle;
+
+/*
+ * Used internally only.
+ */
+typedef struct xTIME_OUT
+{
+ portBASE_TYPE xOverflowCount;
+ portTickType xTimeOnEntering;
+} xTimeOutType;
+
+/*
+ * Defines the priority used by the idle task. This must not be modified.
+ *
+ * \ingroup TaskUtils
+ */
+#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0 )
+
+/**
+ * task. h
+ *
+ * Macro for forcing a context switch.
+ *
+ * \page taskYIELD taskYIELD
+ * \ingroup SchedulerControl
+ */
+#define taskYIELD() portYIELD()
+
+/**
+ * task. h
+ *
+ * Macro to mark the start of a critical code region. Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \page taskENTER_CRITICAL taskENTER_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskENTER_CRITICAL() portENTER_CRITICAL()
+
+/**
+ * task. h
+ *
+ * Macro to mark the end of a critical code region. Preemptive context
+ * switches cannot occur when in a critical region.
+ *
+ * NOTE: This may alter the stack (depending on the portable implementation)
+ * so must be used with care!
+ *
+ * \page taskEXIT_CRITICAL taskEXIT_CRITICAL
+ * \ingroup SchedulerControl
+ */
+#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
+
+/**
+ * task. h
+ *
+ * Macro to disable all maskable interrupts.
+ *
+ * \page taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()
+
+/**
+ * task. h
+ *
+ * Macro to enable microcontroller interrupts.
+ *
+ * \page taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS
+ * \ingroup SchedulerControl
+ */
+#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
+
+
+/*-----------------------------------------------------------
+ * TASK CREATION API
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ *<pre>
+ portBASE_TYPE xTaskCreate(
+ pdTASK_CODE pvTaskCode,
+ const portCHAR * const pcName,
+ unsigned portSHORT usStackDepth,
+ void *pvParameters,
+ unsigned portBASE_TYPE uxPriority,
+ xTaskHandle *pvCreatedTask
+ );</pre>
+ *
+ * Create a new task and add it to the list of tasks that are ready to run.
+ *
+ * @param pvTaskCode Pointer to the task entry function. Tasks
+ * must be implemented to never return (i.e. continuous loop).
+ *
+ * @param pcName A descriptive name for the task. This is mainly used to
+ * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default
+ * is 16.
+ *
+ * @param usStackDepth The size of the task stack specified as the number of
+ * variables the stack can hold - not the number of bytes. For example, if
+ * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes
+ * will be allocated for stack storage.
+ *
+ * @param pvParameters Pointer that will be used as the parameter for the task
+ * being created.
+ *
+ * @param uxPriority The priority at which the task should run.
+ *
+ * @param pvCreatedTask Used to pass back a handle by which the created task
+ * can be referenced.
+ *
+ * @return pdPASS if the task was successfully created and added to a ready
+ * list, otherwise an error code defined in the file errors. h
+ *
+ * Example usage:
+ <pre>
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+ }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+ // Create the task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+
+ // Use the handle to delete the task.
+ vTaskDelete( xHandle );
+ }
+ </pre>
+ * \defgroup xTaskCreate xTaskCreate
+ * \ingroup Tasks
+ */
+signed portBASE_TYPE xTaskCreate (pdTASK_CODE pvTaskCode,
+ const signed portCHAR * const pcName,
+ unsigned portSHORT usStackDepth,
+ void *pvParameters,
+ unsigned portBASE_TYPE uxPriority,
+ xTaskHandle * pvCreatedTask);
+
+/**
+ * task. h
+ * <pre>void vTaskDelete( xTaskHandle pxTask );</pre>
+ *
+ * INCLUDE_vTaskDelete must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Remove a task from the RTOS real time kernels management. The task being
+ * deleted will be removed from all ready, blocked, suspended and event lists.
+ *
+ * NOTE: The idle task is responsible for freeing the kernel allocated
+ * memory from tasks that have been deleted. It is therefore important that
+ * the idle task is not starved of microcontroller processing time if your
+ * application makes any calls to vTaskDelete (). Memory allocated by the
+ * task code is not automatically freed, and should be freed before the task
+ * is deleted.
+ *
+ * See the demo application file death.c for sample code that utilises
+ * vTaskDelete ().
+ *
+ * @param pxTask The handle of the task to be deleted. Passing NULL will
+ * cause the calling task to be deleted.
+ *
+ * Example usage:
+ <pre>
+ void vOtherFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create the task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // Use the handle to delete the task.
+ vTaskDelete( xHandle );
+ }
+ </pre>
+ * \defgroup vTaskDelete vTaskDelete
+ * \ingroup Tasks
+ */
+void vTaskDelete (xTaskHandle pxTask);
+
+
+/*-----------------------------------------------------------
+ * TASK CONTROL API
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * <pre>void vTaskDelay( portTickType xTicksToDelay );</pre>
+ *
+ * Delay a task for a given number of ticks. The actual time that the
+ * task remains blocked depends on the tick rate. The constant
+ * portTICK_RATE_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * INCLUDE_vTaskDelay must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * @param xTicksToDelay The amount of time, in tick periods, that
+ * the calling task should block.
+ *
+ * Example usage:
+ <pre>
+ // Wait 10 ticks before performing an action.
+ // NOTE:
+ // This is for demonstration only and would be better achieved
+ // using vTaskDelayUntil ().
+ void vTaskFunction( void * pvParameters )
+ {
+ portTickType xDelay, xNextTime;
+
+ // Calc the time at which we want to perform the action
+ // next.
+ xNextTime = xTaskGetTickCount () + ( portTickType ) 10;
+
+ for( ;; )
+ {
+ xDelay = xNextTime - xTaskGetTickCount ();
+ xNextTime += ( portTickType ) 10;
+
+ // Guard against overflow
+ if( xDelay <= ( portTickType ) 10 )
+ {
+ vTaskDelay( xDelay );
+ }
+
+ // Perform action here.
+ }
+ }
+ </pre>
+ * \defgroup vTaskDelay vTaskDelay
+ * \ingroup TaskCtrl
+ */
+void vTaskDelay (portTickType xTicksToDelay);
+
+/**
+ * task. h
+ * <pre>void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );</pre>
+ *
+ * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Delay a task until a specified time. This function can be used by cyclical
+ * tasks to ensure a constant execution frequency.
+ *
+ * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will
+ * cause a task to block for the specified number of ticks from the time vTaskDelay () is
+ * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed
+ * execution frequency as the time between a task starting to execute and that task
+ * calling vTaskDelay () may not be fixed [the task may take a different path though the
+ * code between calls, or may get interrupted or preempted a different number of times
+ * each time it executes].
+ *
+ * Whereas vTaskDelay () specifies a wake time relative to the time at which the function
+ * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to
+ * unblock.
+ *
+ * The constant portTICK_RATE_MS can be used to calculate real time from the tick
+ * rate - with the resolution of one tick period.
+ *
+ * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the
+ * task was last unblocked. The variable must be initialised with the current time
+ * prior to its first use (see the example below). Following this the variable is
+ * automatically updated within vTaskDelayUntil ().
+ *
+ * @param xTimeIncrement The cycle time period. The task will be unblocked at
+ * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the
+ * same xTimeIncrement parameter value will cause the task to execute with
+ * a fixed interface period.
+ *
+ * Example usage:
+ <pre>
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ portTickType xLastWakeTime;
+ const portTickType xFrequency = 10;
+
+ // Initialise the xLastWakeTime variable with the current time.
+ xLastWakeTime = xTaskGetTickCount ();
+ for( ;; )
+ {
+ // Wait for the next cycle.
+ vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+ // Perform action here.
+ }
+ }
+ </pre>
+ * \defgroup vTaskDelayUntil vTaskDelayUntil
+ * \ingroup TaskCtrl
+ */
+void vTaskDelayUntil (portTickType * pxPreviousWakeTime,
+ portTickType xTimeIncrement);
+
+/**
+ * task. h
+ * <pre>unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );</pre>
+ *
+ * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Obtain the priority of any task.
+ *
+ * @param pxTask Handle of the task to be queried. Passing a NULL
+ * handle results in the priority of the calling task being returned.
+ *
+ * @return The priority of pxTask.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to obtain the priority of the created task.
+ // It was created with tskIDLE_PRIORITY, but may have changed
+ // it itself.
+ if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+ {
+ // The task has changed it's priority.
+ }
+
+ // ...
+
+ // Is our priority higher than the created task?
+ if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+ {
+ // Our priority (obtained using NULL handle) is higher.
+ }
+ }
+ </pre>
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet
+ * \ingroup TaskCtrl
+ */
+unsigned portBASE_TYPE uxTaskPriorityGet (xTaskHandle pxTask);
+
+/**
+ * task. h
+ * <pre>void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );</pre>
+ *
+ * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Set the priority of any task.
+ *
+ * A context switch will occur before the function returns if the priority
+ * being set is higher than the currently executing task.
+ *
+ * @param pxTask Handle to the task for which the priority is being set.
+ * Passing a NULL handle results in the priority of the calling task being set.
+ *
+ * @param uxNewPriority The priority to which the task will be set.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to raise the priority of the created task.
+ vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+ // ...
+
+ // Use a NULL handle to raise our priority to the same value.
+ vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+ </pre>
+ * \defgroup vTaskPrioritySet vTaskPrioritySet
+ * \ingroup TaskCtrl
+ */
+void vTaskPrioritySet (xTaskHandle pxTask,
+ unsigned portBASE_TYPE uxNewPriority);
+
+/**
+ * task. h
+ * <pre>void vTaskSuspend( xTaskHandle pxTaskToSuspend );</pre>
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Suspend any task. When suspended a task will never get any microcontroller
+ * processing time, no matter what its priority.
+ *
+ * Calls to vTaskSuspend are not accumulative -
+ * i.e. calling vTaskSuspend () twice on the same task still only requires one
+ * call to vTaskResume () to ready the suspended task.
+ *
+ * @param pxTaskToSuspend Handle to the task being suspended. Passing a NULL
+ * handle will cause the calling task to be suspended.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to suspend the created task.
+ vTaskSuspend( xHandle );
+
+ // ...
+
+ // The created task will not run during this period, unless
+ // another task calls vTaskResume( xHandle ).
+
+ //...
+
+
+ // Suspend ourselves.
+ vTaskSuspend( NULL );
+
+ // We cannot get here unless another task calls vTaskResume
+ // with our handle as the parameter.
+ }
+ </pre>
+ * \defgroup vTaskSuspend vTaskSuspend
+ * \ingroup TaskCtrl
+ */
+void vTaskSuspend (xTaskHandle pxTaskToSuspend);
+
+/**
+ * task. h
+ * <pre>void vTaskResume( xTaskHandle pxTaskToResume );</pre>
+ *
+ * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Resumes a suspended task.
+ *
+ * A task that has been suspended by one of more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * vTaskResume ().
+ *
+ * @param pxTaskToResume Handle to the task being readied.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+ // Create a task, storing the handle.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+ // ...
+
+ // Use the handle to suspend the created task.
+ vTaskSuspend( xHandle );
+
+ // ...
+
+ // The created task will not run during this period, unless
+ // another task calls vTaskResume( xHandle ).
+
+ //...
+
+
+ // Resume the suspended task ourselves.
+ vTaskResume( xHandle );
+
+ // The created task will once again get microcontroller processing
+ // time in accordance with it priority within the system.
+ }
+ </pre>
+ * \defgroup vTaskResume vTaskResume
+ * \ingroup TaskCtrl
+ */
+void vTaskResume (xTaskHandle pxTaskToResume);
+
+/**
+ * task. h
+ * <pre>void xTaskResumeFromISR( xTaskHandle pxTaskToResume );</pre>
+ *
+ * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be
+ * available. See the configuration section for more information.
+ *
+ * An implementation of vTaskResume() that can be called from within an ISR.
+ *
+ * A task that has been suspended by one of more calls to vTaskSuspend ()
+ * will be made available for running again by a single call to
+ * xTaskResumeFromISR ().
+ *
+ * @param pxTaskToResume Handle to the task being readied.
+ *
+ * \defgroup vTaskResumeFromISR vTaskResumeFromISR
+ * \ingroup TaskCtrl
+ */
+portBASE_TYPE xTaskResumeFromISR (xTaskHandle pxTaskToResume);
+
+/*-----------------------------------------------------------
+ * SCHEDULER CONTROL
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * <pre>void vTaskStartScheduler( void );</pre>
+ *
+ * Starts the real time kernel tick processing. After calling the kernel
+ * has control over which tasks are executed and when. This function
+ * does not return until an executing task calls vTaskEndScheduler ().
+ *
+ * At least one task should be created via a call to xTaskCreate ()
+ * before calling vTaskStartScheduler (). The idle task is created
+ * automatically when the first application task is created.
+ *
+ * See the demo application file main.c for an example of creating
+ * tasks and starting the kernel.
+ *
+ * Example usage:
+ <pre>
+ void vAFunction( void )
+ {
+ // Create at least one task before starting the kernel.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+ // Start the real time kernel with preemption.
+ vTaskStartScheduler ();
+
+ // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+ </pre>
+ *
+ * \defgroup vTaskStartScheduler vTaskStartScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskStartScheduler (void);
+
+/**
+ * task. h
+ * <pre>void vTaskEndScheduler( void );</pre>
+ *
+ * Stops the real time kernel tick. All created tasks will be automatically
+ * deleted and multitasking (either preemptive or cooperative) will
+ * stop. Execution then resumes from the point where vTaskStartScheduler ()
+ * was called, as if vTaskStartScheduler () had just returned.
+ *
+ * See the demo application file main. c in the demo/PC directory for an
+ * example that uses vTaskEndScheduler ().
+ *
+ * vTaskEndScheduler () requires an exit function to be defined within the
+ * portable layer (see vPortEndScheduler () in port. c for the PC port). This
+ * performs hardware specific operations such as stopping the kernel tick.
+ *
+ * vTaskEndScheduler () will cause all of the resources allocated by the
+ * kernel to be freed - but will not free resources allocated by application
+ * tasks.
+ *
+ * Example usage:
+ <pre>
+ void vTaskCode( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // At some point we want to end the real time kernel processing
+ // so call ...
+ vTaskEndScheduler ();
+ }
+ }
+
+ void vAFunction( void )
+ {
+ // Create at least one task before starting the kernel.
+ xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+ // Start the real time kernel with preemption.
+ vTaskStartScheduler ();
+
+ // Will only get here when the vTaskCode () task has called
+ // vTaskEndScheduler (). When we get here we are back to single task
+ // execution.
+ }
+ </pre>
+ *
+ * \defgroup vTaskEndScheduler vTaskEndScheduler
+ * \ingroup SchedulerControl
+ */
+void vTaskEndScheduler (void);
+
+/**
+ * task. h
+ * <pre>void vTaskSuspendAll( void );</pre>
+ *
+ * Suspends all real time kernel activity while keeping interrupts (including the
+ * kernel tick) enabled.
+ *
+ * After calling vTaskSuspendAll () the calling task will continue to execute
+ * without risk of being swapped out until a call to xTaskResumeAll () has been
+ * made.
+ *
+ * Example usage:
+ <pre>
+ void vTask1( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // ...
+
+ // At some point the task wants to perform a long operation during
+ // which it does not want to get swapped out. It cannot use
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+ // operation may cause interrupts to be missed - including the
+ // ticks.
+
+ // Prevent the real time kernel swapping out the task.
+ vTaskSuspendAll ();
+
+ // Perform the operation here. There is no need to use critical
+ // sections as we have all the microcontroller processing time.
+ // During this time interrupts will still operate and the kernel
+ // tick count will be maintained.
+
+ // ...
+
+ // The operation is complete. Restart the kernel.
+ xTaskResumeAll ();
+ }
+ }
+ </pre>
+ * \defgroup vTaskSuspendAll vTaskSuspendAll
+ * \ingroup SchedulerControl
+ */
+void vTaskSuspendAll (void);
+
+/**
+ * task. h
+ * <pre>portCHAR xTaskResumeAll( void );</pre>
+ *
+ * Resumes real time kernel activity following a call to vTaskSuspendAll ().
+ * After a call to vTaskSuspendAll () the kernel will take control of which
+ * task is executing at any time.
+ *
+ * @return If resuming the scheduler caused a context switch then pdTRUE is
+ * returned, otherwise pdFALSE is returned.
+ *
+ * Example usage:
+ <pre>
+ void vTask1( void * pvParameters )
+ {
+ for( ;; )
+ {
+ // Task code goes here.
+
+ // ...
+
+ // At some point the task wants to perform a long operation during
+ // which it does not want to get swapped out. It cannot use
+ // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+ // operation may cause interrupts to be missed - including the
+ // ticks.
+
+ // Prevent the real time kernel swapping out the task.
+ vTaskSuspendAll ();
+
+ // Perform the operation here. There is no need to use critical
+ // sections as we have all the microcontroller processing time.
+ // During this time interrupts will still operate and the real
+ // time kernel tick count will be maintained.
+
+ // ...
+
+ // The operation is complete. Restart the kernel. We want to force
+ // a context switch - but there is no point if resuming the scheduler
+ // caused a context switch already.
+ if( !xTaskResumeAll () )
+ {
+ taskYIELD ();
+ }
+ }
+ }
+ </pre>
+ * \defgroup xTaskResumeAll xTaskResumeAll
+ * \ingroup SchedulerControl
+ */
+signed portBASE_TYPE xTaskResumeAll (void);
+
+
+/*-----------------------------------------------------------
+ * TASK UTILITIES
+ *----------------------------------------------------------*/
+
+/**
+ * task. h
+ * <PRE>volatile portTickType xTaskGetTickCount( void );</PRE>
+ *
+ * @return The count of ticks since vTaskStartScheduler was called.
+ *
+ * \page xTaskGetTickCount xTaskGetTickCount
+ * \ingroup TaskUtils
+ */
+portTickType xTaskGetTickCount (void);
+
+/**
+ * task. h
+ * <PRE>unsigned portSHORT uxTaskGetNumberOfTasks( void );</PRE>
+ *
+ * @return The number of tasks that the real time kernel is currently managing.
+ * This includes all ready, blocked and suspended tasks. A task that
+ * has been deleted but not yet freed by the idle task will also be
+ * included in the count.
+ *
+ * \page uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks
+ * \ingroup TaskUtils
+ */
+unsigned portBASE_TYPE uxTaskGetNumberOfTasks (void);
+
+/**
+ * task. h
+ * <PRE>void vTaskList( portCHAR *pcWriteBuffer );</PRE>
+ *
+ * configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and INCLUDE_vTaskSuspend
+ * must all be defined as 1 for this function to be available.
+ * See the configuration section for more information.
+ *
+ * NOTE: This function will disable interrupts for its duration. It is
+ * not intended for normal application runtime use but as a debug aid.
+ *
+ * Lists all the current tasks, along with their current state and stack
+ * usage high water mark.
+ *
+ * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or
+ * suspended ('S').
+ *
+ * @param pcWriteBuffer A buffer into which the above mentioned details
+ * will be written, in ascii form. This buffer is assumed to be large
+ * enough to contain the generated report. Approximately 40 bytes per
+ * task should be sufficient.
+ *
+ * \page vTaskList vTaskList
+ * \ingroup TaskUtils
+ */
+void vTaskList (signed portCHAR * pcWriteBuffer);
+
+/**
+ * task. h
+ * <PRE>void vTaskStartTrace( portCHAR * pcBuffer, unsigned portBASE_TYPE uxBufferSize );</PRE>
+ *
+ * Starts a real time kernel activity trace. The trace logs the identity of
+ * which task is running when.
+ *
+ * The trace file is stored in binary format. A separate DOS utility called
+ * convtrce.exe is used to convert this into a tab delimited text file which
+ * can be viewed and plotted in a spread sheet.
+ *
+ * @param pcBuffer The buffer into which the trace will be written.
+ *
+ * @param ulBufferSize The size of pcBuffer in bytes. The trace will continue
+ * until either the buffer in full, or ulTaskEndTrace () is called.
+ *
+ * \page vTaskStartTrace vTaskStartTrace
+ * \ingroup TaskUtils
+ */
+void vTaskStartTrace (signed portCHAR * pcBuffer,
+ unsigned portLONG ulBufferSize);
+
+/**
+ * task. h
+ * <PRE>unsigned portLONG ulTaskEndTrace( void );</PRE>
+ *
+ * Stops a kernel activity trace. See vTaskStartTrace ().
+ *
+ * @return The number of bytes that have been written into the trace buffer.
+ *
+ * \page usTaskEndTrace usTaskEndTrace
+ * \ingroup TaskUtils
+ */
+unsigned portLONG ulTaskEndTrace (void);
+
+
+/*-----------------------------------------------------------
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
+ *----------------------------------------------------------*/
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Called from the real time kernel tick (either preemptive or cooperative),
+ * this increments the tick count and checks if any tasks that are blocked
+ * for a finite period required removing from a blocked list and placing on
+ * a ready list.
+ */
+inline void vTaskIncrementTick (void);
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes the calling task from the ready list and places it both
+ * on the list of tasks waiting for a particular event, and the
+ * list of delayed tasks. The task will be removed from both lists
+ * and replaced on the ready list should either the event occur (and
+ * there be no higher priority tasks waiting on the same event) or
+ * the delay period expires.
+ *
+ * @param pxEventList The list containing tasks that are blocked waiting
+ * for the event to occur.
+ *
+ * @param xTicksToWait The maximum amount of time that the task should wait
+ * for the event to occur. This is specified in kernel ticks,the constant
+ * portTICK_RATE_MS can be used to convert kernel ticks into a real time
+ * period.
+ */
+void vTaskPlaceOnEventList (xList * pxEventList, portTickType xTicksToWait);
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
+ *
+ * Removes a task from both the specified event list and the list of blocked
+ * tasks, and places it on a ready queue.
+ *
+ * xTaskRemoveFromEventList () will be called if either an event occurs to
+ * unblock a task, or the block timeout period expires.
+ *
+ * @return pdTRUE if the task being removed has a higher priority than the task
+ * making the call, otherwise pdFALSE.
+ */
+signed portBASE_TYPE xTaskRemoveFromEventList (const xList * pxEventList);
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN
+ * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * INCLUDE_vTaskCleanUpResources and INCLUDE_vTaskSuspend must be defined as 1
+ * for this function to be available.
+ * See the configuration section for more information.
+ *
+ * Empties the ready and delayed queues of task control blocks, freeing the
+ * memory allocated for the task control block and task stacks as it goes.
+ */
+void vTaskCleanUpResources (void);
+
+/*
+ * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
+ * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
+ * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
+ *
+ * Sets the pointer to the current TCB to the TCB of the highest priority task
+ * that is ready to run.
+ */
+inline void vTaskSwitchContext (void);
+
+/*
+ * Return the handle of the calling task.
+ */
+xTaskHandle xTaskGetCurrentTaskHandle (void);
+
+/*
+ * Capture the current time status for future reference.
+ */
+void vTaskSetTimeOutState (xTimeOutType * pxTimeOut);
+
+/*
+ * Compare the time status now with that previously captured to see if the
+ * timeout has expired.
+ */
+portBASE_TYPE xTaskCheckForTimeOut (xTimeOutType * pxTimeOut,
+ portTickType * pxTicksToWait);
+
+/*
+ * Shortcut used by the queue implementation to prevent unnecessary call to
+ * taskYIELD();
+ */
+void vTaskMissedYield (void);
+
+#endif /* TASK_H */
diff --git a/openpicc/os/core/list.c b/openpicc/os/core/list.c
new file mode 100644
index 0000000..e6db76a
--- /dev/null
+++ b/openpicc/os/core/list.c
@@ -0,0 +1,215 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+Changes from V1.2.0
+
+ + Removed the volatile modifier from the function parameters. This was
+ only ever included to prevent compiler warnings. Now warnings are
+ removed by casting parameters where the calls are made.
+
+ + prvListGetOwnerOfNextEntry() and prvListGetOwnerOfHeadEntry() have been
+ removed from the c file and added as macros to the h file.
+
+ + uxNumberOfItems has been added to the list structure. This removes the
+ need for a pointer comparison when checking if a list is empty, and so
+ is slightly faster.
+
+ + Removed the NULL check in vListRemove(). This makes the call faster but
+ necessitates any application code utilising the list implementation to
+ ensure NULL pointers are not passed.
+
+Changes from V2.0.0
+
+ + Double linked the lists to allow faster removal item removal.
+
+Changes from V2.6.1
+
+ + Make use of the new portBASE_TYPE definition where ever appropriate.
+
+Changes from V3.0.0
+
+ + API changes as described on the FreeRTOS.org WEB site.
+
+Changes from V3.2.4
+
+ + Removed the pxHead member of the xList structure. This always pointed
+ to the same place so has been removed to free a few bytes of RAM.
+
+ + Introduced the xMiniListItem structure that does not include the
+ xListItem members that are not required by the xListEnd member of a list.
+ Again this was done to reduce RAM usage.
+
+ + Changed the volatile definitions of some structure members to clean up
+ the code where the list structures are used.
+
+Changes from V4.0.4
+
+ + Optimised vListInsert() in the case when the wake time is the maximum
+ tick count value.
+*/
+
+#include <stdlib.h>
+#include "FreeRTOS.h"
+#include "list.h"
+
+/*-----------------------------------------------------------
+ * PUBLIC LIST API documented in list.h
+ *----------------------------------------------------------*/
+
+void
+vListInitialise (xList * pxList)
+{
+ /* The list structure contains a list item which is used to mark the
+ end of the list. To initialise the list the list end is inserted
+ as the only list entry. */
+ pxList->pxIndex = (xListItem *) & (pxList->xListEnd);
+
+ /* The list end value is the highest possible value in the list to
+ ensure it remains at the end of the list. */
+ pxList->xListEnd.xItemValue = portMAX_DELAY;
+
+ /* The list end next and previous pointers point to itself so we know
+ when the list is empty. */
+ pxList->xListEnd.pxNext = (xListItem *) & (pxList->xListEnd);
+ pxList->xListEnd.pxPrevious = (xListItem *) & (pxList->xListEnd);
+
+ pxList->uxNumberOfItems = 0;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vListInitialiseItem (xListItem * pxItem)
+{
+ /* Make sure the list item is not recorded as being on a list. */
+ pxItem->pvContainer = NULL;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vListInsertEnd (xList * pxList, xListItem * pxNewListItem)
+{
+ volatile xListItem *pxIndex;
+
+ /* Insert a new list item into pxList, but rather than sort the list,
+ makes the new list item the last item to be removed by a call to
+ pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by
+ the pxIndex member. */
+ pxIndex = pxList->pxIndex;
+
+ pxNewListItem->pxNext = pxIndex->pxNext;
+ pxNewListItem->pxPrevious = pxList->pxIndex;
+ pxIndex->pxNext->pxPrevious = (volatile xListItem *) pxNewListItem;
+ pxIndex->pxNext = (volatile xListItem *) pxNewListItem;
+ pxList->pxIndex = (volatile xListItem *) pxNewListItem;
+
+ /* Remember which list the item is in. */
+ pxNewListItem->pvContainer = (void *) pxList;
+
+ (pxList->uxNumberOfItems)++;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vListInsert (xList * pxList, xListItem * pxNewListItem)
+{
+ volatile xListItem *pxIterator;
+ portTickType xValueOfInsertion;
+
+ /* Insert the new list item into the list, sorted in ulListItem order. */
+ xValueOfInsertion = pxNewListItem->xItemValue;
+
+ /* If the list already contains a list item with the same item value then
+ the new list item should be placed after it. This ensures that TCB's which
+ are stored in ready lists (all of which have the same ulListItem value)
+ get an equal share of the CPU. However, if the xItemValue is the same as
+ the back marker the iteration loop below will not end. This means we need
+ to guard against this by checking the value first and modifying the
+ algorithm slightly if necessary. */
+ if (xValueOfInsertion == portMAX_DELAY)
+ {
+ pxIterator = pxList->xListEnd.pxPrevious;
+ }
+ else
+ {
+ for (pxIterator = (xListItem *) & (pxList->xListEnd);
+ pxIterator->pxNext->xItemValue <= xValueOfInsertion;
+ pxIterator = pxIterator->pxNext)
+ {
+ /* There is nothing to do here, we are just iterating to the
+ wanted insertion position. */
+ }
+ }
+
+ pxNewListItem->pxNext = pxIterator->pxNext;
+ pxNewListItem->pxNext->pxPrevious = (volatile xListItem *) pxNewListItem;
+ pxNewListItem->pxPrevious = pxIterator;
+ pxIterator->pxNext = (volatile xListItem *) pxNewListItem;
+
+ /* Remember which list the item is in. This allows fast removal of the
+ item later. */
+ pxNewListItem->pvContainer = (void *) pxList;
+
+ (pxList->uxNumberOfItems)++;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vListRemove (xListItem * pxItemToRemove)
+{
+ xList *pxList;
+
+ pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
+ pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
+
+ /* The list item knows which list it is in. Obtain the list from the list
+ item. */
+ pxList = (xList *) pxItemToRemove->pvContainer;
+
+ /* Make sure the index is left pointing to a valid item. */
+ if (pxList->pxIndex == pxItemToRemove)
+ {
+ pxList->pxIndex = pxItemToRemove->pxPrevious;
+ }
+
+ pxItemToRemove->pvContainer = NULL;
+ (pxList->uxNumberOfItems)--;
+}
+
+/*-----------------------------------------------------------*/
diff --git a/openpicc/os/core/queue.c b/openpicc/os/core/queue.c
new file mode 100644
index 0000000..c2f08cb
--- /dev/null
+++ b/openpicc/os/core/queue.c
@@ -0,0 +1,1002 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+Changes from V1.01
+
+ + More use of 8bit data types.
+ + Function name prefixes changed where the data type returned has changed.
+
+Changed from V2.0.0
+
+ + Added the queue locking mechanism and make more use of the scheduler
+ suspension feature to minimise the time interrupts have to be disabled
+ when accessing a queue.
+
+Changed from V2.2.0
+
+ + Explicit use of 'signed' qualifier on portCHAR types added.
+
+Changes from V3.0.0
+
+ + API changes as described on the FreeRTOS.org WEB site.
+
+Changes from V3.2.3
+
+ + Added the queue functions that can be used from co-routines.
+
+Changes from V4.0.5
+
+ + Added a loop within xQueueSend() and xQueueReceive() to prevent the
+ functions exiting when a block time remains and the function has
+ not completed.
+
+Changes from V4.1.2:
+
+ + BUG FIX: Removed the call to prvIsQueueEmpty from within xQueueCRReceive
+ as it exited with interrupts enabled. Thanks Paul Katz.
+
+Changes from V4.1.3:
+
+ + Modified xQueueSend() and xQueueReceive() to handle the (very unlikely)
+ case whereby a task unblocking due to a temporal event can remove/send an
+ item from/to a queue when a higher priority task is still blocked on the
+ queue. This modification is a result of the SafeRTOS testing.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include "task.h"
+#include "croutine.h"
+
+/*-----------------------------------------------------------
+ * PUBLIC LIST API documented in list.h
+ *----------------------------------------------------------*/
+
+/* Constants used with the cRxLock and cTxLock structure members. */
+#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
+#define queueERRONEOUS_UNBLOCK ( -1 )
+
+/*
+ * Definition of the queue used by the scheduler.
+ * Items are queued by copy, not reference.
+ */
+typedef struct QueueDefinition
+{
+ signed portCHAR *pcHead; /*< Points to the beginning of the queue storage area. */
+ signed portCHAR *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
+
+ signed portCHAR *pcWriteTo; /*< Points to the free next place in the storage area. */
+ signed portCHAR *pcReadFrom; /*< Points to the last place that a queued item was read from. */
+
+ xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
+ xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
+
+ unsigned portBASE_TYPE uxMessagesWaiting; /*< The number of items currently in the queue. */
+ unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
+ unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */
+
+ signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
+ signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
+} xQUEUE;
+/*-----------------------------------------------------------*/
+
+/*
+ * Inside this file xQueueHandle is a pointer to a xQUEUE structure.
+ * To keep the definition private the API header file defines it as a
+ * pointer to void.
+ */
+typedef xQUEUE *xQueueHandle;
+
+/*
+ * Prototypes for public functions are included here so we don't have to
+ * include the API header file (as it defines xQueueHandle differently). These
+ * functions are documented in the API header file.
+ */
+xQueueHandle xQueueCreate (unsigned portBASE_TYPE uxQueueLength,
+ unsigned portBASE_TYPE uxItemSize);
+signed portBASE_TYPE xQueueSend (xQueueHandle xQueue,
+ const void *pvItemToQueue,
+ portTickType xTicksToWait);
+unsigned portBASE_TYPE uxQueueMessagesWaiting (xQueueHandle pxQueue);
+void vQueueDelete (xQueueHandle xQueue);
+signed portBASE_TYPE xQueueSendFromISR (xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ signed portBASE_TYPE
+ xTaskPreviouslyWoken);
+signed portBASE_TYPE xQueueReceive (xQueueHandle pxQueue, void *pvBuffer,
+ portTickType xTicksToWait);
+signed portBASE_TYPE xQueueReceiveFromISR (xQueueHandle pxQueue,
+ void *pvBuffer,
+ signed portBASE_TYPE *
+ pxTaskWoken);
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE xQueueCRSendFromISR (xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ signed portBASE_TYPE
+ xCoRoutinePreviouslyWoken);
+signed portBASE_TYPE xQueueCRReceiveFromISR (xQueueHandle pxQueue,
+ void *pvBuffer,
+ signed portBASE_TYPE *
+ pxTaskWoken);
+signed portBASE_TYPE xQueueCRSend (xQueueHandle pxQueue,
+ const void *pvItemToQueue,
+ portTickType xTicksToWait);
+signed portBASE_TYPE xQueueCRReceive (xQueueHandle pxQueue, void *pvBuffer,
+ portTickType xTicksToWait);
+#endif
+
+/*
+ * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
+ * prevent an ISR from adding or removing items to the queue, but does prevent
+ * an ISR from removing tasks from the queue event lists. If an ISR finds a
+ * queue is locked it will instead increment the appropriate queue lock count
+ * to indicate that a task may require unblocking. When the queue in unlocked
+ * these lock counts are inspected, and the appropriate action taken.
+ */
+static void prvUnlockQueue (xQueueHandle pxQueue);
+
+/*
+ * Uses a critical section to determine if there is any data in a queue.
+ *
+ * @return pdTRUE if the queue contains no items, otherwise pdFALSE.
+ */
+static signed portBASE_TYPE prvIsQueueEmpty (const xQueueHandle pxQueue);
+
+/*
+ * Uses a critical section to determine if there is any space in a queue.
+ *
+ * @return pdTRUE if there is no space, otherwise pdFALSE;
+ */
+static signed portBASE_TYPE prvIsQueueFull (const xQueueHandle pxQueue);
+
+/*
+ * Macro that copies an item into the queue. This is done by copying the item
+ * byte for byte, not by reference. Updates the queue state to ensure it's
+ * integrity after the copy.
+ */
+#define prvCopyQueueData( pxQueue, pvItemToQueue ) \
+{ \
+ memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); \
+ ++( pxQueue->uxMessagesWaiting ); \
+ pxQueue->pcWriteTo += pxQueue->uxItemSize; \
+ if( pxQueue->pcWriteTo >= pxQueue->pcTail ) \
+ { \
+ pxQueue->pcWriteTo = pxQueue->pcHead; \
+ } \
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro to mark a queue as locked. Locking a queue prevents an ISR from
+ * accessing the queue event lists.
+ */
+#define prvLockQueue( pxQueue ) \
+{ \
+ taskENTER_CRITICAL(); \
+ ++( pxQueue->xRxLock ); \
+ ++( pxQueue->xTxLock ); \
+ taskEXIT_CRITICAL(); \
+}
+/*-----------------------------------------------------------*/
+
+
+/*-----------------------------------------------------------
+ * PUBLIC QUEUE MANAGEMENT API documented in queue.h
+ *----------------------------------------------------------*/
+
+xQueueHandle
+xQueueCreate (unsigned portBASE_TYPE uxQueueLength,
+ unsigned portBASE_TYPE uxItemSize)
+{
+ xQUEUE *pxNewQueue;
+ size_t xQueueSizeInBytes;
+
+ /* Allocate the new queue structure. */
+ if (uxQueueLength > (unsigned portBASE_TYPE) 0)
+ {
+ pxNewQueue = (xQUEUE *) pvPortMalloc (sizeof (xQUEUE));
+ if (pxNewQueue != NULL)
+ {
+ /* Create the list of pointers to queue items. The queue is one byte
+ longer than asked for to make wrap checking easier/faster. */
+ xQueueSizeInBytes =
+ (size_t) (uxQueueLength * uxItemSize) + (size_t) 1;
+
+ pxNewQueue->pcHead =
+ (signed portCHAR *) pvPortMalloc (xQueueSizeInBytes);
+ if (pxNewQueue->pcHead != NULL)
+ {
+ /* Initialise the queue members as described above where the
+ queue type is defined. */
+ pxNewQueue->pcTail =
+ pxNewQueue->pcHead + (uxQueueLength * uxItemSize);
+ pxNewQueue->uxMessagesWaiting = 0;
+ pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
+ pxNewQueue->pcReadFrom =
+ pxNewQueue->pcHead + ((uxQueueLength - 1) * uxItemSize);
+ pxNewQueue->uxLength = uxQueueLength;
+ pxNewQueue->uxItemSize = uxItemSize;
+ pxNewQueue->xRxLock = queueUNLOCKED;
+ pxNewQueue->xTxLock = queueUNLOCKED;
+
+ /* Likewise ensure the event queues start with the correct state. */
+ vListInitialise (&(pxNewQueue->xTasksWaitingToSend));
+ vListInitialise (&(pxNewQueue->xTasksWaitingToReceive));
+
+ return pxNewQueue;
+ }
+ else
+ {
+ vPortFree (pxNewQueue);
+ }
+ }
+ }
+
+ /* Will only reach here if we could not allocate enough memory or no memory
+ was required. */
+ return NULL;
+}
+
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE
+xQueueSend (xQueueHandle pxQueue, const void *pvItemToQueue,
+ portTickType xTicksToWait)
+{
+ signed portBASE_TYPE xReturn = pdPASS;
+ xTimeOutType xTimeOut;
+
+ /* Make sure other tasks do not access the queue. */
+ vTaskSuspendAll ();
+
+ /* Capture the current time status for future reference. */
+ vTaskSetTimeOutState (&xTimeOut);
+
+ /* It is important that this is the only thread/ISR that modifies the
+ ready or delayed lists until xTaskResumeAll() is called. Places where
+ the ready/delayed lists are modified include:
+
+ + vTaskDelay() - Nothing can call vTaskDelay as the scheduler is
+ suspended, vTaskDelay() cannot be called from an ISR.
+ + vTaskPrioritySet() - Has a critical section around the access.
+ + vTaskSwitchContext() - This will not get executed while the scheduler
+ is suspended.
+ + prvCheckDelayedTasks() - This will not get executed while the
+ scheduler is suspended.
+ + xTaskCreate() - Has a critical section around the access.
+ + vTaskResume() - Has a critical section around the access.
+ + xTaskResumeAll() - Has a critical section around the access.
+ + xTaskRemoveFromEventList - Checks to see if the scheduler is
+ suspended. If so then the TCB being removed from the event is
+ removed from the event and added to the xPendingReadyList.
+ */
+
+ /* Make sure interrupts do not access the queue event list. */
+ prvLockQueue (pxQueue);
+
+ /* It is important that interrupts to not access the event list of the
+ queue being modified here. Places where the event list is modified
+ include:
+
+ + xQueueSendFromISR(). This checks the lock on the queue to see if
+ it has access. If the queue is locked then the Tx lock count is
+ incremented to signify that a task waiting for data can be made ready
+ once the queue lock is removed. If the queue is not locked then
+ a task can be moved from the event list, but will not be removed
+ from the delayed list or placed in the ready list until the scheduler
+ is unlocked.
+
+ + xQueueReceiveFromISR(). As per xQueueSendFromISR().
+ */
+
+ /* If the queue is already full we may have to block. */
+ do
+ {
+ if (prvIsQueueFull (pxQueue))
+ {
+ /* The queue is full - do we want to block or just leave without
+ posting? */
+ if (xTicksToWait > (portTickType) 0)
+ {
+ /* We are going to place ourselves on the xTasksWaitingToSend event
+ list, and will get woken should the delay expire, or space become
+ available on the queue.
+
+ As detailed above we do not require mutual exclusion on the event
+ list as nothing else can modify it or the ready lists while we
+ have the scheduler suspended and queue locked.
+
+ It is possible that an ISR has removed data from the queue since we
+ checked if any was available. If this is the case then the data
+ will have been copied from the queue, and the queue variables
+ updated, but the event list will not yet have been checked to see if
+ anything is waiting as the queue is locked. */
+ vTaskPlaceOnEventList (&(pxQueue->xTasksWaitingToSend),
+ xTicksToWait);
+
+ /* Force a context switch now as we are blocked. We can do
+ this from within a critical section as the task we are
+ switching to has its own context. When we return here (i.e. we
+ unblock) we will leave the critical section as normal.
+
+ It is possible that an ISR has caused an event on an unrelated and
+ unlocked queue. If this was the case then the event list for that
+ queue will have been updated but the ready lists left unchanged -
+ instead the readied task will have been added to the pending ready
+ list. */
+ taskENTER_CRITICAL ();
+ {
+ /* We can safely unlock the queue and scheduler here as
+ interrupts are disabled. We must not yield with anything
+ locked, but we can yield from within a critical section.
+
+ Tasks that have been placed on the pending ready list cannot
+ be tasks that are waiting for events on this queue. See
+ in comment xTaskRemoveFromEventList(). */
+ prvUnlockQueue (pxQueue);
+
+ /* Resuming the scheduler may cause a yield. If so then there
+ is no point yielding again here. */
+ if (!xTaskResumeAll ())
+ {
+ taskYIELD ();
+ }
+
+ /* We want to check to see if the queue is still full
+ before leaving the critical section. This is to prevent
+ this task placing an item into the queue due to an
+ interrupt making space on the queue between critical
+ sections (when there might be a higher priority task
+ blocked on the queue that cannot run yet because the
+ scheduler gets suspended). */
+ if (pxQueue->uxMessagesWaiting == pxQueue->uxLength)
+ {
+ /* We unblocked but there is no space in the queue,
+ we probably timed out. */
+ xReturn = errQUEUE_FULL;
+ }
+
+ /* Before leaving the critical section we have to ensure
+ exclusive access again. */
+ vTaskSuspendAll ();
+ prvLockQueue (pxQueue);
+ }
+ taskEXIT_CRITICAL ();
+ }
+ }
+
+ /* If xReturn is errQUEUE_FULL then we unblocked when the queue
+ was still full. Don't check it again now as it is possible that
+ an interrupt has removed an item from the queue since we left the
+ critical section and we don't want to write to the queue in case
+ there is a task of higher priority blocked waiting for space to
+ be available on the queue. If this is the case the higher priority
+ task will execute when the scheduler is unsupended. */
+ if (xReturn != errQUEUE_FULL)
+ {
+ /* When we are here it is possible that we unblocked as space became
+ available on the queue. It is also possible that an ISR posted to the
+ queue since we left the critical section, so it may be that again there
+ is no space. This would only happen if a task and ISR post onto the
+ same queue. */
+ taskENTER_CRITICAL ();
+ {
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength)
+ {
+ /* There is room in the queue, copy the data into the queue. */
+ prvCopyQueueData (pxQueue, pvItemToQueue);
+ xReturn = pdPASS;
+
+ /* Update the TxLock count so prvUnlockQueue knows to check for
+ tasks waiting for data to become available in the queue. */
+ ++(pxQueue->xTxLock);
+ }
+ else
+ {
+ xReturn = errQUEUE_FULL;
+ }
+ }
+ taskEXIT_CRITICAL ();
+ }
+
+ if (xReturn == errQUEUE_FULL)
+ {
+ if (xTicksToWait > 0)
+ {
+ if (xTaskCheckForTimeOut (&xTimeOut, &xTicksToWait) == pdFALSE)
+ {
+ xReturn = queueERRONEOUS_UNBLOCK;
+ }
+ }
+ }
+ }
+ while (xReturn == queueERRONEOUS_UNBLOCK);
+
+ prvUnlockQueue (pxQueue);
+ xTaskResumeAll ();
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE
+xQueueSendFromISR (xQueueHandle pxQueue, const void *pvItemToQueue,
+ signed portBASE_TYPE xTaskPreviouslyWoken)
+{
+ /* Similar to xQueueSend, except we don't block if there is no room in the
+ queue. Also we don't directly wake a task that was blocked on a queue
+ read, instead we return a flag to say whether a context switch is required
+ or not (i.e. has a task with a higher priority than us been woken by this
+ post). */
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength)
+ {
+ prvCopyQueueData (pxQueue, pvItemToQueue);
+
+ /* If the queue is locked we do not alter the event list. This will
+ be done when the queue is unlocked later. */
+ if (pxQueue->xTxLock == queueUNLOCKED)
+ {
+ /* We only want to wake one task per ISR, so check that a task has
+ not already been woken. */
+ if (!xTaskPreviouslyWoken)
+ {
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive)))
+ {
+ if (xTaskRemoveFromEventList
+ (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE)
+ {
+ /* The task waiting has a higher priority so record that a
+ context switch is required. */
+ return pdTRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Increment the lock count so the task that unlocks the queue
+ knows that data was posted while it was locked. */
+ ++(pxQueue->xTxLock);
+ }
+ }
+
+ return xTaskPreviouslyWoken;
+}
+
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE
+xQueueReceive (xQueueHandle pxQueue, void *pvBuffer,
+ portTickType xTicksToWait)
+{
+ signed portBASE_TYPE xReturn = pdTRUE;
+ xTimeOutType xTimeOut;
+
+ /* This function is very similar to xQueueSend(). See comments within
+ xQueueSend() for a more detailed explanation.
+
+ Make sure other tasks do not access the queue. */
+ vTaskSuspendAll ();
+
+ /* Capture the current time status for future reference. */
+ vTaskSetTimeOutState (&xTimeOut);
+
+ /* Make sure interrupts do not access the queue. */
+ prvLockQueue (pxQueue);
+
+ do
+ {
+ /* If there are no messages in the queue we may have to block. */
+ if (prvIsQueueEmpty (pxQueue))
+ {
+ /* There are no messages in the queue, do we want to block or just
+ leave with nothing? */
+ if (xTicksToWait > (portTickType) 0)
+ {
+ vTaskPlaceOnEventList (&(pxQueue->xTasksWaitingToReceive),
+ xTicksToWait);
+ taskENTER_CRITICAL ();
+ {
+ prvUnlockQueue (pxQueue);
+ if (!xTaskResumeAll ())
+ {
+ taskYIELD ();
+ }
+
+ if (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0)
+ {
+ /* We unblocked but the queue is empty. We probably
+ timed out. */
+ xReturn = errQUEUE_EMPTY;
+ }
+
+ vTaskSuspendAll ();
+ prvLockQueue (pxQueue);
+ }
+ taskEXIT_CRITICAL ();
+ }
+ }
+
+ if (xReturn != errQUEUE_EMPTY)
+ {
+ taskENTER_CRITICAL ();
+ {
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0)
+ {
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom >= pxQueue->pcTail)
+ {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --(pxQueue->uxMessagesWaiting);
+ memcpy ((void *) pvBuffer, (void *) pxQueue->pcReadFrom,
+ (unsigned) pxQueue->uxItemSize);
+
+ /* Increment the lock count so prvUnlockQueue knows to check for
+ tasks waiting for space to become available on the queue. */
+ ++(pxQueue->xRxLock);
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = errQUEUE_EMPTY;
+ }
+ }
+ taskEXIT_CRITICAL ();
+ }
+
+ if (xReturn == errQUEUE_EMPTY)
+ {
+ if (xTicksToWait > 0)
+ {
+ if (xTaskCheckForTimeOut (&xTimeOut, &xTicksToWait) == pdFALSE)
+ {
+ xReturn = queueERRONEOUS_UNBLOCK;
+ }
+ }
+ }
+ }
+ while (xReturn == queueERRONEOUS_UNBLOCK);
+
+ /* We no longer require exclusive access to the queue. */
+ prvUnlockQueue (pxQueue);
+ xTaskResumeAll ();
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE
+xQueueReceiveFromISR (xQueueHandle pxQueue, void *pvBuffer,
+ signed portBASE_TYPE * pxTaskWoken)
+{
+ signed portBASE_TYPE xReturn;
+
+ /* We cannot block from an ISR, so check there is data available. */
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0)
+ {
+ /* Copy the data from the queue. */
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom >= pxQueue->pcTail)
+ {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --(pxQueue->uxMessagesWaiting);
+ memcpy ((void *) pvBuffer, (void *) pxQueue->pcReadFrom,
+ (unsigned) pxQueue->uxItemSize);
+
+ /* If the queue is locked we will not modify the event list. Instead
+ we update the lock count so the task that unlocks the queue will know
+ that an ISR has removed data while the queue was locked. */
+ if (pxQueue->xRxLock == queueUNLOCKED)
+ {
+ /* We only want to wake one task per ISR, so check that a task has
+ not already been woken. */
+ if (!(*pxTaskWoken))
+ {
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend)))
+ {
+ if (xTaskRemoveFromEventList
+ (&(pxQueue->xTasksWaitingToSend)) != pdFALSE)
+ {
+ /* The task waiting has a higher priority than us so
+ force a context switch. */
+ *pxTaskWoken = pdTRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Increment the lock count so the task that unlocks the queue
+ knows that data was removed while it was locked. */
+ ++(pxQueue->xRxLock);
+ }
+
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE
+uxQueueMessagesWaiting (xQueueHandle pxQueue)
+{
+ unsigned portBASE_TYPE uxReturn;
+
+ taskENTER_CRITICAL ();
+ uxReturn = pxQueue->uxMessagesWaiting;
+ taskEXIT_CRITICAL ();
+
+ return uxReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vQueueDelete (xQueueHandle pxQueue)
+{
+ vPortFree (pxQueue->pcHead);
+ vPortFree (pxQueue);
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvUnlockQueue (xQueueHandle pxQueue)
+{
+ /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
+
+ /* The lock counts contains the number of extra data items placed or
+ removed from the queue while the queue was locked. When a queue is
+ locked items can be added or removed, but the event lists cannot be
+ updated. */
+ taskENTER_CRITICAL ();
+ {
+ --(pxQueue->xTxLock);
+
+ /* See if data was added to the queue while it was locked. */
+ if (pxQueue->xTxLock > queueUNLOCKED)
+ {
+ pxQueue->xTxLock = queueUNLOCKED;
+
+ /* Data was posted while the queue was locked. Are any tasks
+ blocked waiting for data to become available? */
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive)))
+ {
+ /* Tasks that are removed from the event list will get added to
+ the pending ready list as the scheduler is still suspended. */
+ if (xTaskRemoveFromEventList (&(pxQueue->xTasksWaitingToReceive))
+ != pdFALSE)
+ {
+ /* The task waiting has a higher priority so record that a
+ context switch is required. */
+ vTaskMissedYield ();
+ }
+ }
+ }
+ }
+ taskEXIT_CRITICAL ();
+
+ /* Do the same for the Rx lock. */
+ taskENTER_CRITICAL ();
+ {
+ --(pxQueue->xRxLock);
+
+ if (pxQueue->xRxLock > queueUNLOCKED)
+ {
+ pxQueue->xRxLock = queueUNLOCKED;
+
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend)))
+ {
+ if (xTaskRemoveFromEventList (&(pxQueue->xTasksWaitingToSend)) !=
+ pdFALSE)
+ {
+ vTaskMissedYield ();
+ }
+ }
+ }
+ }
+ taskEXIT_CRITICAL ();
+}
+
+/*-----------------------------------------------------------*/
+
+static signed portBASE_TYPE
+prvIsQueueEmpty (const xQueueHandle pxQueue)
+{
+ signed portBASE_TYPE xReturn;
+
+ taskENTER_CRITICAL ();
+ xReturn = (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0);
+ taskEXIT_CRITICAL ();
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+static signed portBASE_TYPE
+prvIsQueueFull (const xQueueHandle pxQueue)
+{
+ signed portBASE_TYPE xReturn;
+
+ taskENTER_CRITICAL ();
+ xReturn = (pxQueue->uxMessagesWaiting == pxQueue->uxLength);
+ taskEXIT_CRITICAL ();
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE
+xQueueCRSend (xQueueHandle pxQueue, const void *pvItemToQueue,
+ portTickType xTicksToWait)
+{
+ signed portBASE_TYPE xReturn;
+
+ /* If the queue is already full we may have to block. A critical section
+ is required to prevent an interrupt removing something from the queue
+ between the check to see if the queue is full and blocking on the queue. */
+ portDISABLE_INTERRUPTS ();
+ {
+ if (prvIsQueueFull (pxQueue))
+ {
+ /* The queue is full - do we want to block or just leave without
+ posting? */
+ if (xTicksToWait > (portTickType) 0)
+ {
+ /* As this is called from a coroutine we cannot block directly, but
+ return indicating that we need to block. */
+ vCoRoutineAddToDelayedList (xTicksToWait,
+ &(pxQueue->xTasksWaitingToSend));
+ portENABLE_INTERRUPTS ();
+ return errQUEUE_BLOCKED;
+ }
+ else
+ {
+ portENABLE_INTERRUPTS ();
+ return errQUEUE_FULL;
+ }
+ }
+ }
+ portENABLE_INTERRUPTS ();
+
+ portNOP ();
+
+ portDISABLE_INTERRUPTS ();
+ {
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength)
+ {
+ /* There is room in the queue, copy the data into the queue. */
+ prvCopyQueueData (pxQueue, pvItemToQueue);
+ xReturn = pdPASS;
+
+ /* Were any co-routines waiting for data to become available? */
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive)))
+ {
+ /* In this instance the co-routine could be placed directly
+ into the ready list as we are within a critical section.
+ Instead the same pending ready list mechansim is used as if
+ the event were caused from within an interrupt. */
+ if (xCoRoutineRemoveFromEventList
+ (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE)
+ {
+ /* The co-routine waiting has a higher priority so record
+ that a yield might be appropriate. */
+ xReturn = errQUEUE_YIELD;
+ }
+ }
+ }
+ else
+ {
+ xReturn = errQUEUE_FULL;
+ }
+ }
+ portENABLE_INTERRUPTS ();
+
+ return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE
+xQueueCRReceive (xQueueHandle pxQueue, void *pvBuffer,
+ portTickType xTicksToWait)
+{
+ signed portBASE_TYPE xReturn;
+
+ /* If the queue is already empty we may have to block. A critical section
+ is required to prevent an interrupt adding something to the queue
+ between the check to see if the queue is empty and blocking on the queue. */
+ portDISABLE_INTERRUPTS ();
+ {
+ if (pxQueue->uxMessagesWaiting == (unsigned portBASE_TYPE) 0)
+ {
+ /* There are no messages in the queue, do we want to block or just
+ leave with nothing? */
+ if (xTicksToWait > (portTickType) 0)
+ {
+ /* As this is a co-routine we cannot block directly, but return
+ indicating that we need to block. */
+ vCoRoutineAddToDelayedList (xTicksToWait,
+ &(pxQueue->xTasksWaitingToReceive));
+ portENABLE_INTERRUPTS ();
+ return errQUEUE_BLOCKED;
+ }
+ else
+ {
+ portENABLE_INTERRUPTS ();
+ return errQUEUE_FULL;
+ }
+ }
+ }
+ portENABLE_INTERRUPTS ();
+
+ portNOP ();
+
+ portDISABLE_INTERRUPTS ();
+ {
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0)
+ {
+ /* Data is available from the queue. */
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom >= pxQueue->pcTail)
+ {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --(pxQueue->uxMessagesWaiting);
+ memcpy ((void *) pvBuffer, (void *) pxQueue->pcReadFrom,
+ (unsigned) pxQueue->uxItemSize);
+
+ xReturn = pdPASS;
+
+ /* Were any co-routines waiting for space to become available? */
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend)))
+ {
+ /* In this instance the co-routine could be placed directly
+ into the ready list as we are within a critical section.
+ Instead the same pending ready list mechansim is used as if
+ the event were caused from within an interrupt. */
+ if (xCoRoutineRemoveFromEventList
+ (&(pxQueue->xTasksWaitingToSend)) != pdFALSE)
+ {
+ xReturn = errQUEUE_YIELD;
+ }
+ }
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+ }
+ portENABLE_INTERRUPTS ();
+
+ return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE
+xQueueCRSendFromISR (xQueueHandle pxQueue, const void *pvItemToQueue,
+ signed portBASE_TYPE xCoRoutinePreviouslyWoken)
+{
+ /* Cannot block within an ISR so if there is no space on the queue then
+ exit without doing anything. */
+ if (pxQueue->uxMessagesWaiting < pxQueue->uxLength)
+ {
+ prvCopyQueueData (pxQueue, pvItemToQueue);
+
+ /* We only want to wake one co-routine per ISR, so check that a
+ co-routine has not already been woken. */
+ if (!xCoRoutinePreviouslyWoken)
+ {
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToReceive)))
+ {
+ if (xCoRoutineRemoveFromEventList
+ (&(pxQueue->xTasksWaitingToReceive)) != pdFALSE)
+ {
+ return pdTRUE;
+ }
+ }
+ }
+ }
+
+ return xCoRoutinePreviouslyWoken;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+#if configUSE_CO_ROUTINES == 1
+signed portBASE_TYPE
+xQueueCRReceiveFromISR (xQueueHandle pxQueue, void *pvBuffer,
+ signed portBASE_TYPE * pxCoRoutineWoken)
+{
+ signed portBASE_TYPE xReturn;
+
+ /* We cannot block from an ISR, so check there is data available. If
+ not then just leave without doing anything. */
+ if (pxQueue->uxMessagesWaiting > (unsigned portBASE_TYPE) 0)
+ {
+ /* Copy the data from the queue. */
+ pxQueue->pcReadFrom += pxQueue->uxItemSize;
+ if (pxQueue->pcReadFrom >= pxQueue->pcTail)
+ {
+ pxQueue->pcReadFrom = pxQueue->pcHead;
+ }
+ --(pxQueue->uxMessagesWaiting);
+ memcpy ((void *) pvBuffer, (void *) pxQueue->pcReadFrom,
+ (unsigned) pxQueue->uxItemSize);
+
+ if (!(*pxCoRoutineWoken))
+ {
+ if (!listLIST_IS_EMPTY (&(pxQueue->xTasksWaitingToSend)))
+ {
+ if (xCoRoutineRemoveFromEventList
+ (&(pxQueue->xTasksWaitingToSend)) != pdFALSE)
+ {
+ *pxCoRoutineWoken = pdTRUE;
+ }
+ }
+ }
+
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+}
+#endif
+/*-----------------------------------------------------------*/
diff --git a/openpicc/os/core/tasks.c b/openpicc/os/core/tasks.c
new file mode 100644
index 0000000..68a0dd9
--- /dev/null
+++ b/openpicc/os/core/tasks.c
@@ -0,0 +1,1988 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version, along
+ with development and support options.
+ ***************************************************************************
+*/
+
+/*
+Changes from V1.00:
+
+ + Call to portRESTORE_CONTEXT has been removed. The first context
+ switch is now performed within sPortStartScheduler().
+
+Changes from V1.01:
+
+ + More use of 8bit data types.
+ + Function name prefixes changed where the data type returned has changed.
+ + configUSE_TRACE_FACILITY is no longer defined by default.
+
+Changes from V1.2.0
+
+ + Introduced ucTopReadyPriority. This tracks the highest priority ready
+ queue that contains a valid TCB and thus makes the context switch
+ slightly faster.
+
+ + prvAddTaskToReadyQueue() has been made a macro.
+
+Changes from V1.2.6
+
+ + Added conditional compilation directives.
+ + Extended API.
+ + Rearranged function order.
+ + Creating a task now causes a context switch if the task being created
+ has a higher priority than the calling task - assuming the kernel is
+ running.
+ + vTaskDelete() now only causes a context switch if the calling task is
+ the task being deleted.
+
+Changes from V2.0.0
+
+ + Allow the type of the tick count to be 16 or 32 bits.
+ + Introduce xPendingReadyList feature to allow the time interrupts have to
+ be disabled to be minimised.
+ + Remove the #if( INCLUDE_vTaskSuspendAll ) statements. vTaskSuspendAll()
+ is now always included as it is used by the scheduler itself.
+
+Changes from V2.1.0
+
+ + Bug fix - pxCurrentTCB is now initialised before the call to
+ prvInitializeTaskLists(). Previously pxCurrentTCB could be accessed
+ while null.
+
+Changed from V2.1.1
+
+ + Change to where lStackSize is declared within sTaskCreate() to prevent
+ compiler warnings with 8051 port.
+
+Changes from V2.2.0
+
+ + Explicit use of 'signed' qualifier on portCHAR types added.
+ + Changed odd calculation of initial pxTopOfStack value when
+ portSTACK_GROWTH < 0.
+ + Removed pcVersionNumber definition.
+
+Changes from V2.5.3
+
+ + cTaskResumeAll() modified to ensure it can be called prior to the task
+ lists being initialised.
+
+Changes from V2.5.5
+
+ + Added API function vTaskDelayUntil().
+ + Added INCLUDE_vTaskDelay conditional compilation.
+
+Changes from V2.6.0
+
+ + Updated the vWriteTraceToBuffer macro to always be 4 byte aligned so it
+ can be used on ARM architectures.
+ + tskMAX_TASK_NAME_LEN definition replaced with the port specific
+ configMAX_TASK_NAME_LEN definition.
+ + Removed the call to strcpy when copying across the task name into the
+ TCB.
+ + Added ucTasksDeleted variable to prevent vTaskSuspendAll() being called
+ too often in the idle task.
+
+Changes between V3.0.0 and V2.6.1
+
+ + When resuming the scheduler a yield is performed if either a tick has
+ been missed, or a task is moved from the pending ready list into a ready
+ list. Previously a yield was not performed on this second condition.
+ + Introduced the type portBASE_TYPE. This necessitates several API
+ changes.
+ + Removed the sUsingPreemption variable. The constant defined in
+ portmacro.h is now used directly.
+ + The idle task can now include an optional hook function - and no longer
+ completes its time slice if other tasks with equal priority to it are
+ ready to run.
+ + See the FreeRTOS.org documentation for more information on V2.x.x to
+ V3.x.x modifications.
+
+Changes from V3.1.1
+
+ + Modified vTaskPrioritySet() and vTaskResume() to allow these functions to
+ be called while the scheduler is suspended.
+ + Corrected the task ordering within event lists.
+
+Changes from V3.2.0
+
+ + Added function xTaskGetCurrentTaskHandle().
+
+Changes from V3.2.4
+
+ + Changed the volatile declarations on some variables to reflect the
+ changes to the list definitions.
+ + Changed the order of the TCB definition so there is commonality between
+ the task control block and a co-routine control block.
+ + Allow the scheduler to be started even if no tasks other than the idle
+ task has been created. This allows co-routines to run even when no tasks
+ have been created.
+ + The need for a context switch is now signalled if a task woken by an
+ event has a priority greater or equal to the currently running task.
+ Previously this was only greater than.
+
+Changes from V4.0.0
+
+ + Added the xMissedYield handling.
+
+Changes from V4.0.1
+
+ + The function vTaskList() now suspends the scheduler rather than disabling
+ interrupts during the creation of the task list.
+ + Allow a task to delete itself by passing in its own handle. Previously
+ this could only be done by passing in NULL.
+ + The tick hook function is now called only within a tick isr. Previously
+ it was also called when the tick function was called during the scheduler
+ unlocking process.
+
+Changes from V4.0.3
+
+ + Extra checks have been placed in vTaskPrioritySet() to avoid unnecessary
+ yields.
+
+Changed from V4.0.4
+
+ + Bug fix: The 'value' of the event list item is updated when the priority
+ of a task is changed. Previously only the priority of the TCB itself was
+ changed.
+ + When resuming a task a check is first made to see if the task is actually
+ suspended.
+ + vTaskPrioritySet() and vTaskResume() no longer use the event list item.
+ This has not been necessary since V4.0.1 when the xMissedYield handling
+ was added.
+ + Implement xTaskResumeFromISR().
+
+Changes from V4.0.5
+
+ + Added utility functions and xOverflowCount variable to facilitate the
+ queue.c changes.
+
+Changes from V4.1.2
+
+ + Tasks that block on events with a timeout of portMAX_DELAY are now
+ blocked indefinitely if configINCLUDE_vTaskSuspend is defined.
+ Previously portMAX_DELAY was just the longest block time possible.
+
+Changes from V4.1.3
+
+ + Very small change made to xTaskCheckForTimeout() as a result of the
+ SafeRTOS testing. This corrects the case where the function can return an
+ invalid value - but only in an extremely unlikely scenario.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+/*
+ * Macro to define the amount of stack available to the idle task.
+ */
+#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE
+
+
+/*
+ * Default a definitions for backwards compatibility with old
+ * portmacro.h files.
+ */
+#ifndef configMAX_TASK_NAME_LEN
+#define configMAX_TASK_NAME_LEN 16
+#endif
+
+#ifndef INCLUDE_xTaskGetCurrentTaskHandle
+#define INCLUDE_xTaskGetCurrentTaskHandle 0
+#endif
+
+#ifndef configIDLE_SHOULD_YIELD
+#define configIDLE_SHOULD_YIELD 1
+#endif
+
+#if configMAX_TASK_NAME_LEN < 1
+#undef configMAX_TASK_NAME_LEN
+#define configMAX_TASK_NAME_LEN 1
+#endif
+
+#ifndef INCLUDE_xTaskResumeFromISR
+#define INCLUDE_xTaskResumeFromISR 1
+#endif
+
+/*
+ * Task control block. A task control block (TCB) is allocated to each task,
+ * and stores the context of the task.
+ */
+typedef struct tskTaskControlBlock
+{
+ volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */
+ xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */
+ xListItem xEventListItem; /*< List item used to place the TCB in event lists. */
+ unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */
+ portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */
+ unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */
+ signed portCHAR pcTaskName[configMAX_TASK_NAME_LEN]; /*< Descriptive name given to the task when created. Facilitates debugging only. */
+ unsigned portSHORT usStackDepth; /*< Total depth of the stack (when empty). This is defined as the number of variables the stack can hold, not the number of bytes. */
+} tskTCB;
+
+/*lint -e956 */
+
+tskTCB *volatile pxCurrentTCB = NULL;
+
+/* Lists for ready and blocked tasks. --------------------*/
+
+static xList pxReadyTasksLists[configMAX_PRIORITIES]; /*< Prioritised ready tasks. */
+static xList xDelayedTaskList1; /*< Delayed tasks. */
+static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
+static xList *volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */
+static xList *volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
+static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready queue when the scheduler is resumed. */
+
+#if ( INCLUDE_vTaskDelete == 1 )
+
+static volatile xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */
+static volatile unsigned portBASE_TYPE uxTasksDeleted =
+ (unsigned portBASE_TYPE) 0;
+
+#endif
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */
+
+#endif
+
+/* File private variables. --------------------------------*/
+static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks =
+ (unsigned portBASE_TYPE) 0;
+static volatile portTickType xTickCount = (portTickType) 0;
+static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
+static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY;
+static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE;
+static volatile unsigned portBASE_TYPE uxSchedulerSuspended =
+ (unsigned portBASE_TYPE) pdFALSE;
+static volatile unsigned portBASE_TYPE uxMissedTicks =
+ (unsigned portBASE_TYPE) 0;
+static volatile portBASE_TYPE xMissedYield = (portBASE_TYPE) pdFALSE;
+static volatile portBASE_TYPE xNumOfOverflows = (portBASE_TYPE) 0;
+/* Debugging and trace facilities private variables and macros. ------------*/
+
+/*
+ * The value used to fill the stack of a task when the task is created. This
+ * is used purely for checking the high water mark for tasks.
+ */
+#define tskSTACK_FILL_BYTE ( 0xa5 )
+
+/*
+ * Macros used by vListTask to indicate which state a task is in.
+ */
+#define tskBLOCKED_CHAR ( ( signed portCHAR ) 'B' )
+#define tskREADY_CHAR ( ( signed portCHAR ) 'R' )
+#define tskDELETED_CHAR ( ( signed portCHAR ) 'D' )
+#define tskSUSPENDED_CHAR ( ( signed portCHAR ) 'S' )
+
+/*
+ * Macros and private variables used by the trace facility.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+#define tskSIZE_OF_EACH_TRACE_LINE ( ( unsigned portLONG ) ( sizeof( unsigned portLONG ) + sizeof( unsigned portLONG ) ) )
+static volatile signed portCHAR *volatile pcTraceBuffer;
+static signed portCHAR *pcTraceBufferStart;
+static signed portCHAR *pcTraceBufferEnd;
+static signed portBASE_TYPE xTracing = pdFALSE;
+
+#endif
+
+/*
+ * Macro that writes a trace of scheduler activity to a buffer. This trace
+ * shows which task is running when and is very useful as a debugging tool.
+ * As this macro is called each context switch it is a good idea to undefine
+ * it if not using the facility.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+#define vWriteTraceToBuffer() \
+ { \
+ if( xTracing ) \
+ { \
+ static unsigned portBASE_TYPE uxPreviousTask = 255; \
+ \
+ if( uxPreviousTask != pxCurrentTCB->uxTCBNumber ) \
+ { \
+ if( ( pcTraceBuffer + tskSIZE_OF_EACH_TRACE_LINE ) < pcTraceBufferEnd ) \
+ { \
+ uxPreviousTask = pxCurrentTCB->uxTCBNumber; \
+ *( unsigned portLONG * ) pcTraceBuffer = ( unsigned portLONG ) xTickCount; \
+ pcTraceBuffer += sizeof( unsigned portLONG ); \
+ *( unsigned portLONG * ) pcTraceBuffer = ( unsigned portLONG ) uxPreviousTask; \
+ pcTraceBuffer += sizeof( unsigned portLONG ); \
+ } \
+ else \
+ { \
+ xTracing = pdFALSE; \
+ } \
+ } \
+ } \
+ }
+
+#else
+
+#define vWriteTraceToBuffer()
+
+#endif
+
+
+/*
+ * Place the task represented by pxTCB into the appropriate ready queue for
+ * the task. It is inserted at the end of the list. One quirk of this is
+ * that if the task being inserted is at the same priority as the currently
+ * executing task, then it will only be rescheduled after the currently
+ * executing task has been rescheduled.
+ */
+#define prvAddTaskToReadyQueue( pxTCB ) \
+{ \
+ if( pxTCB->uxPriority > uxTopReadyPriority ) \
+ { \
+ uxTopReadyPriority = pxTCB->uxPriority; \
+ } \
+ vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \
+}
+
+/*
+ * Macro that looks at the list of tasks that are currently delayed to see if
+ * any require waking.
+ *
+ * Tasks are stored in the queue in the order of their wake time - meaning
+ * once one tasks has been found whose timer has not expired we need not look
+ * any further down the list.
+ */
+#define prvCheckDelayedTasks() \
+{ \
+register tskTCB *pxTCB; \
+ \
+ while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL ) \
+ { \
+ if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) ) \
+ { \
+ break; \
+ } \
+ vListRemove( &( pxTCB->xGenericListItem ) ); \
+ /* Is the task waiting on an event also? */ \
+ if( pxTCB->xEventListItem.pvContainer ) \
+ { \
+ vListRemove( &( pxTCB->xEventListItem ) ); \
+ } \
+ prvAddTaskToReadyQueue( pxTCB ); \
+ } \
+}
+
+/*
+ * Several functions take an xTaskHandle parameter that can optionally be NULL,
+ * where NULL is used to indicate that the handle of the currently executing
+ * task should be used in place of the parameter. This macro simply checks to
+ * see if the parameter is NULL and returns a pointer to the appropriate TCB.
+ */
+#define prvGetTCBFromHandle( pxHandle ) ( ( pxHandle == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) pxHandle )
+
+
+/* File private functions. --------------------------------*/
+
+/*
+ * Utility to ready a TCB for a given task. Mainly just copies the parameters
+ * into the TCB structure.
+ */
+static void prvInitialiseTCBVariables (tskTCB * pxTCB,
+ unsigned portSHORT usStackDepth,
+ const signed portCHAR * const pcName,
+ unsigned portBASE_TYPE uxPriority);
+
+/*
+ * Utility to ready all the lists used by the scheduler. This is called
+ * automatically upon the creation of the first task.
+ */
+static void prvInitialiseTaskLists (void);
+
+/*
+ * The idle task, which as all tasks is implemented as a never ending loop.
+ * The idle task is automatically created and added to the ready lists upon
+ * creation of the first user task.
+ *
+ * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific
+ * language extensions. The equivalent prototype for this function is:
+ *
+ * void prvIdleTask( void *pvParameters );
+ *
+ */
+static portTASK_FUNCTION_PROTO (prvIdleTask, pvParameters);
+
+/*
+ * Utility to free all memory allocated by the scheduler to hold a TCB,
+ * including the stack pointed to by the TCB.
+ *
+ * This does not free memory allocated by the task itself (i.e. memory
+ * allocated by calls to pvPortMalloc from within the tasks application code).
+ */
+#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
+static void prvDeleteTCB (tskTCB * pxTCB);
+#endif
+
+/*
+ * Used only by the idle task. This checks to see if anything has been placed
+ * in the list of tasks waiting to be deleted. If so the task is cleaned up
+ * and its TCB deleted.
+ */
+static void prvCheckTasksWaitingTermination (void);
+
+/*
+ * Allocates memory from the heap for a TCB and associated stack. Checks the
+ * allocation was successful.
+ */
+static tskTCB *prvAllocateTCBAndStack (unsigned portSHORT usStackDepth);
+
+/*
+ * Called from vTaskList. vListTasks details all the tasks currently under
+ * control of the scheduler. The tasks may be in one of a number of lists.
+ * prvListTaskWithinSingleList accepts a list and details the tasks from
+ * within just that list.
+ *
+ * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM
+ * NORMAL APPLICATION CODE.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+static void prvListTaskWithinSingleList (signed portCHAR * pcWriteBuffer,
+ xList * pxList,
+ signed portCHAR cStatus);
+
+#endif
+
+/*
+ * When a task is created, the stack of the task is filled with a known value.
+ * This function determines the 'high water mark' of the task stack by
+ * determining how much of the stack remains at the original preset value.
+ */
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+unsigned portSHORT usTaskCheckFreeStackSpace (const unsigned portCHAR *
+ pucStackByte);
+
+#endif
+
+/*lint +e956 */
+
+
+
+
+
+/*-----------------------------------------------------------
+ * TASK CREATION API documented in task.h
+ *----------------------------------------------------------*/
+
+signed portBASE_TYPE
+xTaskCreate (pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName,
+ unsigned portSHORT usStackDepth, void *pvParameters,
+ unsigned portBASE_TYPE uxPriority, xTaskHandle * pxCreatedTask)
+{
+ signed portBASE_TYPE xReturn;
+ tskTCB *pxNewTCB;
+ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */
+
+ /* Allocate the memory required by the TCB and stack for the new task.
+ checking that the allocation was successful. */
+ pxNewTCB = prvAllocateTCBAndStack (usStackDepth);
+
+ if (pxNewTCB != NULL)
+ {
+ portSTACK_TYPE *pxTopOfStack;
+
+ /* Setup the newly allocated TCB with the initial state of the task. */
+ prvInitialiseTCBVariables (pxNewTCB, usStackDepth, pcName, uxPriority);
+
+ /* Calculate the top of stack address. This depends on whether the
+ stack grows from high memory to low (as per the 80x86) or visa versa.
+ portSTACK_GROWTH is used to make the result positive or negative as
+ required by the port. */
+#if portSTACK_GROWTH < 0
+ {
+ pxTopOfStack = pxNewTCB->pxStack + (pxNewTCB->usStackDepth - 1);
+ }
+#else
+ {
+ pxTopOfStack = pxNewTCB->pxStack;
+ }
+#endif
+
+ /* Initialize the TCB stack to look as if the task was already running,
+ but had been interrupted by the scheduler. The return address is set
+ to the start of the task function. Once the stack has been initialised
+ the top of stack variable is updated. */
+ pxNewTCB->pxTopOfStack =
+ pxPortInitialiseStack (pxTopOfStack, pvTaskCode, pvParameters);
+
+ /* We are going to manipulate the task queues to add this task to a
+ ready list, so must make sure no interrupts occur. */
+ portENTER_CRITICAL ();
+ {
+ uxCurrentNumberOfTasks++;
+ if (uxCurrentNumberOfTasks == (unsigned portBASE_TYPE) 1)
+ {
+ /* As this is the first task it must also be the current task. */
+ pxCurrentTCB = pxNewTCB;
+
+ /* This is the first task to be created so do the preliminary
+ initialisation required. We will not recover if this call
+ fails, but we will report the failure. */
+ prvInitialiseTaskLists ();
+ }
+ else
+ {
+ /* If the scheduler is not already running, make this task the
+ current task if it is the highest priority task to be created
+ so far. */
+ if (xSchedulerRunning == pdFALSE)
+ {
+ if (pxCurrentTCB->uxPriority <= uxPriority)
+ {
+ pxCurrentTCB = pxNewTCB;
+ }
+ }
+ }
+
+ /* Remember the top priority to make context switching faster. Use
+ the priority in pxNewTCB as this has been capped to a valid value. */
+ if (pxNewTCB->uxPriority > uxTopUsedPriority)
+ {
+ uxTopUsedPriority = pxNewTCB->uxPriority;
+ }
+
+ /* Add a counter into the TCB for tracing only. */
+ pxNewTCB->uxTCBNumber = uxTaskNumber;
+ uxTaskNumber++;
+
+ prvAddTaskToReadyQueue (pxNewTCB);
+
+ xReturn = pdPASS;
+ }
+ portEXIT_CRITICAL ();
+ }
+ else
+ {
+ xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
+ }
+
+ if (xReturn == pdPASS)
+ {
+ if ((void *) pxCreatedTask != NULL)
+ {
+ /* Pass the TCB out - in an anonymous way. The calling function/
+ task can use this as a handle to delete the task later if
+ required. */
+ *pxCreatedTask = (xTaskHandle) pxNewTCB;
+ }
+
+ if (xSchedulerRunning != pdFALSE)
+ {
+ /* If the created task is of a higher priority than the current task
+ then it should run now. */
+ if (pxCurrentTCB->uxPriority < uxPriority)
+ {
+ taskYIELD ();
+ }
+ }
+ }
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelete == 1 )
+
+void
+vTaskDelete (xTaskHandle pxTaskToDelete)
+{
+ tskTCB *pxTCB;
+
+ taskENTER_CRITICAL ();
+ {
+ /* Ensure a yield is performed if the current task is being
+ deleted. */
+ if (pxTaskToDelete == pxCurrentTCB)
+ {
+ pxTaskToDelete = NULL;
+ }
+
+ /* If null is passed in here then we are deleting ourselves. */
+ pxTCB = prvGetTCBFromHandle (pxTaskToDelete);
+
+ /* Remove task from the ready list and place in the termination list.
+ This will stop the task from be scheduled. The idle task will check
+ the termination list and free up any memory allocated by the
+ scheduler for the TCB and stack. */
+ vListRemove (&(pxTCB->xGenericListItem));
+
+ /* Is the task waiting on an event also? */
+ if (pxTCB->xEventListItem.pvContainer)
+ {
+ vListRemove (&(pxTCB->xEventListItem));
+ }
+
+ vListInsertEnd ((xList *) & xTasksWaitingTermination,
+ &(pxTCB->xGenericListItem));
+
+ /* Increment the ucTasksDeleted variable so the idle task knows
+ there is a task that has been deleted and that it should therefore
+ check the xTasksWaitingTermination list. */
+ ++uxTasksDeleted;
+ }
+ taskEXIT_CRITICAL ();
+
+ /* Force a reschedule if we have just deleted the current task. */
+ if (xSchedulerRunning != pdFALSE)
+ {
+ if ((void *) pxTaskToDelete == NULL)
+ {
+ taskYIELD ();
+ }
+ }
+}
+
+#endif
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * TASK CONTROL API documented in task.h
+ *----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelayUntil == 1 )
+
+void
+vTaskDelayUntil (portTickType * pxPreviousWakeTime,
+ portTickType xTimeIncrement)
+{
+ portTickType xTimeToWake;
+ portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;
+
+ vTaskSuspendAll ();
+ {
+ /* Generate the tick time at which the task wants to wake. */
+ xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
+
+ if (xTickCount < *pxPreviousWakeTime)
+ {
+ /* The tick count has overflowed since this function was
+ lasted called. In this case the only time we should ever
+ actually delay is if the wake time has also overflowed,
+ and the wake time is greater than the tick time. When this
+ is the case it is as if neither time had overflowed. */
+ if ((xTimeToWake < *pxPreviousWakeTime) && (xTimeToWake > xTickCount))
+ {
+ xShouldDelay = pdTRUE;
+ }
+ }
+ else
+ {
+ /* The tick time has not overflowed. In this case we will
+ delay if either the wake time has overflowed, and/or the
+ tick time is less than the wake time. */
+ if ((xTimeToWake < *pxPreviousWakeTime) || (xTimeToWake > xTickCount))
+ {
+ xShouldDelay = pdTRUE;
+ }
+ }
+
+ /* Update the wake time ready for the next call. */
+ *pxPreviousWakeTime = xTimeToWake;
+
+ if (xShouldDelay)
+ {
+ /* We must remove ourselves from the ready list before adding
+ ourselves to the blocked list as the same list item is used for
+ both lists. */
+ vListRemove ((xListItem *) & (pxCurrentTCB->xGenericListItem));
+
+ /* The list item will be inserted in wake time order. */
+ listSET_LIST_ITEM_VALUE (&(pxCurrentTCB->xGenericListItem),
+ xTimeToWake);
+
+ if (xTimeToWake < xTickCount)
+ {
+ /* Wake time has overflowed. Place this item in the
+ overflow list. */
+ vListInsert ((xList *) pxOverflowDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ else
+ {
+ /* The wake time has not overflowed, so we can use the
+ current block list. */
+ vListInsert ((xList *) pxDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ }
+ }
+ xAlreadyYielded = xTaskResumeAll ();
+
+ /* Force a reschedule if xTaskResumeAll has not already done so, we may
+ have put ourselves to sleep. */
+ if (!xAlreadyYielded)
+ {
+ taskYIELD ();
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskDelay == 1 )
+
+void
+vTaskDelay (portTickType xTicksToDelay)
+{
+ portTickType xTimeToWake;
+ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
+
+ /* A delay time of zero just forces a reschedule. */
+ if (xTicksToDelay > (portTickType) 0)
+ {
+ vTaskSuspendAll ();
+ {
+ /* A task that is removed from the event list while the
+ scheduler is suspended will not get placed in the ready
+ list or removed from the blocked list until the scheduler
+ is resumed.
+
+ This task cannot be in an event list as it is the currently
+ executing task. */
+
+ /* Calculate the time to wake - this may overflow but this is
+ not a problem. */
+ xTimeToWake = xTickCount + xTicksToDelay;
+
+ /* We must remove ourselves from the ready list before adding
+ ourselves to the blocked list as the same list item is used for
+ both lists. */
+ vListRemove ((xListItem *) & (pxCurrentTCB->xGenericListItem));
+
+ /* The list item will be inserted in wake time order. */
+ listSET_LIST_ITEM_VALUE (&(pxCurrentTCB->xGenericListItem),
+ xTimeToWake);
+
+ if (xTimeToWake < xTickCount)
+ {
+ /* Wake time has overflowed. Place this item in the
+ overflow list. */
+ vListInsert ((xList *) pxOverflowDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ else
+ {
+ /* The wake time has not overflowed, so we can use the
+ current block list. */
+ vListInsert ((xList *) pxDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ }
+ xAlreadyYielded = xTaskResumeAll ();
+ }
+
+ /* Force a reschedule if xTaskResumeAll has not already done so, we may
+ have put ourselves to sleep. */
+ if (!xAlreadyYielded)
+ {
+ taskYIELD ();
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_uxTaskPriorityGet == 1 )
+
+unsigned portBASE_TYPE
+uxTaskPriorityGet (xTaskHandle pxTask)
+{
+ tskTCB *pxTCB;
+ unsigned portBASE_TYPE uxReturn;
+
+ taskENTER_CRITICAL ();
+ {
+ /* If null is passed in here then we are changing the
+ priority of the calling function. */
+ pxTCB = prvGetTCBFromHandle (pxTask);
+ uxReturn = pxTCB->uxPriority;
+ }
+ taskEXIT_CRITICAL ();
+
+ return uxReturn;
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskPrioritySet == 1 )
+
+void
+vTaskPrioritySet (xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority)
+{
+ tskTCB *pxTCB;
+ unsigned portBASE_TYPE uxCurrentPriority, xYieldRequired = pdFALSE;
+
+ /* Ensure the new priority is valid. */
+ if (uxNewPriority >= configMAX_PRIORITIES)
+ {
+ uxNewPriority = configMAX_PRIORITIES - 1;
+ }
+
+ taskENTER_CRITICAL ();
+ {
+ /* If null is passed in here then we are changing the
+ priority of the calling function. */
+ pxTCB = prvGetTCBFromHandle (pxTask);
+ uxCurrentPriority = pxTCB->uxPriority;
+
+ if (uxCurrentPriority != uxNewPriority)
+ {
+ /* The priority change may have readied a task of higher
+ priority than the calling task. */
+ if (uxNewPriority > pxCurrentTCB->uxPriority)
+ {
+ if (pxTask != NULL)
+ {
+ /* The priority of another task is being raised. If we
+ were raising the priority of the currently running task
+ there would be no need to switch as it must have already
+ been the highest priority task. */
+ xYieldRequired = pdTRUE;
+ }
+ }
+ else if (pxTask == NULL)
+ {
+ /* Setting our own priority down means there may now be another
+ task of higher priority that is ready to execute. */
+ xYieldRequired = pdTRUE;
+ }
+
+ pxTCB->uxPriority = uxNewPriority;
+ listSET_LIST_ITEM_VALUE (&(pxTCB->xEventListItem),
+ configMAX_PRIORITIES -
+ (portTickType) uxNewPriority);
+
+ /* If the task is in the blocked or suspended list we need do
+ nothing more than change it's priority variable. However, if
+ the task is in a ready list it needs to be removed and placed
+ in the queue appropriate to its new priority. */
+ if (listIS_CONTAINED_WITHIN
+ (&(pxReadyTasksLists[uxCurrentPriority]),
+ &(pxTCB->xGenericListItem)))
+ {
+ /* The task is currently in its ready list - remove before adding
+ it to it's new ready list. As we are in a critical section we
+ can do this even if the scheduler is suspended. */
+ vListRemove (&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue (pxTCB);
+ }
+
+ if (xYieldRequired == pdTRUE)
+ {
+ taskYIELD ();
+ }
+ }
+ }
+ taskEXIT_CRITICAL ();
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+void
+vTaskSuspend (xTaskHandle pxTaskToSuspend)
+{
+ tskTCB *pxTCB;
+
+ taskENTER_CRITICAL ();
+ {
+ /* Ensure a yield is performed if the current task is being
+ suspended. */
+ if (pxTaskToSuspend == pxCurrentTCB)
+ {
+ pxTaskToSuspend = NULL;
+ }
+
+ /* If null is passed in here then we are suspending ourselves. */
+ pxTCB = prvGetTCBFromHandle (pxTaskToSuspend);
+
+ /* Remove task from the ready/delayed list and place in the suspended list. */
+ vListRemove (&(pxTCB->xGenericListItem));
+
+ /* Is the task waiting on an event also? */
+ if (pxTCB->xEventListItem.pvContainer)
+ {
+ vListRemove (&(pxTCB->xEventListItem));
+ }
+
+ vListInsertEnd ((xList *) & xSuspendedTaskList,
+ &(pxTCB->xGenericListItem));
+ }
+ taskEXIT_CRITICAL ();
+
+ /* We may have just suspended the current task. */
+ if ((void *) pxTaskToSuspend == NULL)
+ {
+ taskYIELD ();
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+
+void
+vTaskResume (xTaskHandle pxTaskToResume)
+{
+ tskTCB *pxTCB;
+
+ /* Remove the task from whichever list it is currently in, and place
+ it in the ready list. */
+ pxTCB = (tskTCB *) pxTaskToResume;
+
+ /* The parameter cannot be NULL as it is impossible to resume the
+ currently executing task. */
+ if (pxTCB != NULL)
+ {
+ taskENTER_CRITICAL ();
+ {
+ /* Is the task we are attempting to resume actually suspended? */
+ if (listIS_CONTAINED_WITHIN
+ (&xSuspendedTaskList, &(pxTCB->xGenericListItem)) != pdFALSE)
+ {
+ /* Has the task already been resumed from within an ISR? */
+ if (listIS_CONTAINED_WITHIN
+ (&xPendingReadyList, &(pxTCB->xEventListItem)) != pdTRUE)
+ {
+ /* As we are in a critical section we can access the ready
+ lists even if the scheduler is suspended. */
+ vListRemove (&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue (pxTCB);
+
+ /* We may have just resumed a higher priority task. */
+ if (pxTCB->uxPriority >= pxCurrentTCB->uxPriority)
+ {
+ /* This yield may not cause the task just resumed to run, but
+ will leave the lists in the correct state for the next yield. */
+ taskYIELD ();
+ }
+ }
+ }
+ }
+ taskEXIT_CRITICAL ();
+ }
+}
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
+
+portBASE_TYPE
+xTaskResumeFromISR (xTaskHandle pxTaskToResume)
+{
+ portBASE_TYPE xYieldRequired = pdFALSE;
+ tskTCB *pxTCB;
+
+ pxTCB = (tskTCB *) pxTaskToResume;
+
+ /* Is the task we are attempting to resume actually suspended? */
+ if (listIS_CONTAINED_WITHIN
+ (&xSuspendedTaskList, &(pxTCB->xGenericListItem)) != pdFALSE)
+ {
+ /* Has the task already been resumed from within an ISR? */
+ if (listIS_CONTAINED_WITHIN
+ (&xPendingReadyList, &(pxTCB->xEventListItem)) != pdTRUE)
+ {
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE)
+ {
+ xYieldRequired =
+ (pxTCB->uxPriority >= pxCurrentTCB->uxPriority);
+ vListRemove (&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue (pxTCB);
+ }
+ else
+ {
+ /* We cannot access the delayed or ready lists, so will hold this
+ task pending until the scheduler is resumed, at which point a
+ yield will be preformed if necessary. */
+ vListInsertEnd ((xList *) & (xPendingReadyList),
+ &(pxTCB->xEventListItem));
+ }
+ }
+ }
+
+ return xYieldRequired;
+}
+
+#endif
+
+
+
+
+/*-----------------------------------------------------------
+ * PUBLIC SCHEDULER CONTROL documented in task.h
+ *----------------------------------------------------------*/
+
+
+void
+vTaskStartScheduler (void)
+{
+ portBASE_TYPE xReturn;
+
+ /* Add the idle task at the lowest priority. */
+ xReturn =
+ xTaskCreate (prvIdleTask, (signed portCHAR *) "IDLE", tskIDLE_STACK_SIZE,
+ (void *) NULL, tskIDLE_PRIORITY, (xTaskHandle *) NULL);
+
+ if (xReturn == pdPASS)
+ {
+ /* Interrupts are turned off here, to ensure a tick does not occur
+ before or during the call to xPortStartScheduler(). The stacks of
+ the created tasks contain a status word with interrupts switched on
+ so interrupts will automatically get re-enabled when the first task
+ starts to run.
+
+ STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE
+ DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */
+ portDISABLE_INTERRUPTS ();
+
+ xSchedulerRunning = pdTRUE;
+ xTickCount = (portTickType) 0;
+
+ /* Setting up the timer tick is hardware specific and thus in the
+ portable interface. */
+ if (xPortStartScheduler ())
+ {
+ /* Should not reach here as if the scheduler is running the
+ function will not return. */
+ }
+ else
+ {
+ /* Should only reach here if a task calls xTaskEndScheduler(). */
+ }
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vTaskEndScheduler (void)
+{
+ /* Stop the scheduler interrupts and call the portable scheduler end
+ routine so the original ISRs can be restored if necessary. The port
+ layer must ensure interrupts enable bit is left in the correct state. */
+ portDISABLE_INTERRUPTS ();
+ xSchedulerRunning = pdFALSE;
+ vPortEndScheduler ();
+}
+
+/*----------------------------------------------------------*/
+
+void
+vTaskSuspendAll (void)
+{
+ portENTER_CRITICAL ();
+ ++uxSchedulerSuspended;
+ portEXIT_CRITICAL ();
+}
+
+/*----------------------------------------------------------*/
+
+signed portBASE_TYPE
+xTaskResumeAll (void)
+{
+ register tskTCB *pxTCB;
+ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
+
+ /* It is possible that an ISR caused a task to be removed from an event
+ list while the scheduler was suspended. If this was the case then the
+ removed task will have been added to the xPendingReadyList. Once the
+ scheduler has been resumed it is safe to move all the pending ready
+ tasks from this list into their appropriate ready list. */
+ portENTER_CRITICAL ();
+ {
+ --uxSchedulerSuspended;
+
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE)
+ {
+ if (uxCurrentNumberOfTasks > (unsigned portBASE_TYPE) 0)
+ {
+ portBASE_TYPE xYieldRequired = pdFALSE;
+
+ /* Move any readied tasks from the pending list into the
+ appropriate ready list. */
+ while ((pxTCB =
+ (tskTCB *)
+ listGET_OWNER_OF_HEAD_ENTRY (((xList *) &
+ xPendingReadyList))) !=
+ NULL)
+ {
+ vListRemove (&(pxTCB->xEventListItem));
+ vListRemove (&(pxTCB->xGenericListItem));
+ prvAddTaskToReadyQueue (pxTCB);
+
+ /* If we have moved a task that has a priority higher than
+ the current task then we should yield. */
+ if (pxTCB->uxPriority >= pxCurrentTCB->uxPriority)
+ {
+ xYieldRequired = pdTRUE;
+ }
+ }
+
+ /* If any ticks occurred while the scheduler was suspended then
+ they should be processed now. This ensures the tick count does not
+ slip, and that any delayed tasks are resumed at the correct time. */
+ if (uxMissedTicks > (unsigned portBASE_TYPE) 0)
+ {
+ while (uxMissedTicks > (unsigned portBASE_TYPE) 0)
+ {
+ vTaskIncrementTick ();
+ --uxMissedTicks;
+ }
+
+ /* As we have processed some ticks it is appropriate to yield
+ to ensure the highest priority task that is ready to run is
+ the task actually running. */
+ xYieldRequired = pdTRUE;
+ }
+
+ if ((xYieldRequired == pdTRUE) || (xMissedYield == pdTRUE))
+ {
+ xAlreadyYielded = pdTRUE;
+ xMissedYield = pdFALSE;
+ taskYIELD ();
+ }
+ }
+ }
+ }
+ portEXIT_CRITICAL ();
+
+ return xAlreadyYielded;
+}
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * PUBLIC TASK UTILITIES documented in task.h
+ *----------------------------------------------------------*/
+
+
+
+portTickType
+xTaskGetTickCount (void)
+{
+ portTickType xTicks;
+
+ /* Critical section required if running on a 16 bit processor. */
+ taskENTER_CRITICAL ();
+ {
+ xTicks = xTickCount;
+ }
+ taskEXIT_CRITICAL ();
+
+ return xTicks;
+}
+
+/*-----------------------------------------------------------*/
+
+unsigned portBASE_TYPE
+uxTaskGetNumberOfTasks (void)
+{
+ unsigned portBASE_TYPE uxNumberOfTasks;
+
+ taskENTER_CRITICAL ();
+ uxNumberOfTasks = uxCurrentNumberOfTasks;
+ taskEXIT_CRITICAL ();
+
+ return uxNumberOfTasks;
+}
+
+/*-----------------------------------------------------------*/
+
+#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_vTaskDelete == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
+
+void
+vTaskList (signed portCHAR * pcWriteBuffer)
+{
+ unsigned portBASE_TYPE uxQueue;
+
+ /* This is a VERY costly function that should be used for debug only.
+ It leaves interrupts disabled for a LONG time. */
+
+ vTaskSuspendAll ();
+ {
+ /* Run through all the lists that could potentially contain a TCB and
+ report the task name, state and stack high water mark. */
+
+ pcWriteBuffer[0] = (signed portCHAR) 0x00;
+ strcat ((portCHAR *) pcWriteBuffer, (const portCHAR *) "\r\n");
+
+ uxQueue = uxTopUsedPriority + 1;
+
+ do
+ {
+ uxQueue--;
+
+ if (!listLIST_IS_EMPTY (&(pxReadyTasksLists[uxQueue])))
+ {
+ prvListTaskWithinSingleList (pcWriteBuffer,
+ (xList *) &
+ (pxReadyTasksLists[uxQueue]),
+ tskREADY_CHAR);
+ }
+ }
+ while (uxQueue > (unsigned portSHORT) tskIDLE_PRIORITY);
+
+ if (!listLIST_IS_EMPTY (pxDelayedTaskList))
+ {
+ prvListTaskWithinSingleList (pcWriteBuffer,
+ (xList *) pxDelayedTaskList,
+ tskBLOCKED_CHAR);
+ }
+
+ if (!listLIST_IS_EMPTY (pxOverflowDelayedTaskList))
+ {
+ prvListTaskWithinSingleList (pcWriteBuffer,
+ (xList *) pxOverflowDelayedTaskList,
+ tskBLOCKED_CHAR);
+ }
+
+ if (!listLIST_IS_EMPTY (&xTasksWaitingTermination))
+ {
+ prvListTaskWithinSingleList (pcWriteBuffer,
+ (xList *) & xTasksWaitingTermination,
+ tskDELETED_CHAR);
+ }
+
+ if (!listLIST_IS_EMPTY (&xSuspendedTaskList))
+ {
+ prvListTaskWithinSingleList (pcWriteBuffer,
+ (xList *) & xSuspendedTaskList,
+ tskSUSPENDED_CHAR);
+ }
+ }
+ xTaskResumeAll ();
+}
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+void
+vTaskStartTrace (signed portCHAR * pcBuffer, unsigned portLONG ulBufferSize)
+{
+ portENTER_CRITICAL ();
+ {
+ pcTraceBuffer = (volatile signed portCHAR * volatile) pcBuffer;
+ pcTraceBufferStart = pcBuffer;
+ pcTraceBufferEnd = pcBuffer + (ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE);
+ xTracing = pdTRUE;
+ }
+ portEXIT_CRITICAL ();
+}
+
+#endif
+/*----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+unsigned portLONG
+ulTaskEndTrace (void)
+{
+ unsigned portLONG ulBufferLength;
+
+ portENTER_CRITICAL ();
+ xTracing = pdFALSE;
+ portEXIT_CRITICAL ();
+
+ ulBufferLength = (unsigned portLONG) (pcTraceBuffer - pcTraceBufferStart);
+
+ return ulBufferLength;
+}
+
+#endif
+
+
+
+/*-----------------------------------------------------------
+ * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES
+ * documented in task.h
+ *----------------------------------------------------------*/
+
+
+inline void
+vTaskIncrementTick (void)
+{
+ /* Called by the portable layer each time a tick interrupt occurs.
+ Increments the tick then checks to see if the new tick value will cause any
+ tasks to be unblocked. */
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE)
+ {
+ ++xTickCount;
+ if (xTickCount == (portTickType) 0)
+ {
+ xList *pxTemp;
+
+ /* Tick count has overflowed so we need to swap the delay lists.
+ If there are any items in pxDelayedTaskList here then there is
+ an error! */
+ pxTemp = pxDelayedTaskList;
+ pxDelayedTaskList = pxOverflowDelayedTaskList;
+ pxOverflowDelayedTaskList = pxTemp;
+ xNumOfOverflows++;
+ }
+
+ /* See if this tick has made a timeout expire. */
+ prvCheckDelayedTasks ();
+ }
+ else
+ {
+ ++uxMissedTicks;
+
+ /* The tick hook gets called at regular intervals, even if the
+ scheduler is locked. */
+#if ( configUSE_TICK_HOOK == 1 )
+ {
+ extern void vApplicationTickHook (void);
+
+ vApplicationTickHook ();
+ }
+#endif
+ }
+
+#if ( configUSE_TICK_HOOK == 1 )
+ {
+ extern void vApplicationTickHook (void);
+
+ /* Guard against the tick hook being called when the missed tick
+ count is being unwound (when the scheduler is being unlocked. */
+ if (uxMissedTicks == 0)
+ {
+ vApplicationTickHook ();
+ }
+ }
+#endif
+}
+
+/*-----------------------------------------------------------*/
+
+#if ( ( INCLUDE_vTaskCleanUpResources == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) )
+
+void
+vTaskCleanUpResources (void)
+{
+ unsigned portSHORT usQueue;
+ volatile tskTCB *pxTCB;
+
+ usQueue = (unsigned portSHORT) uxTopUsedPriority + (unsigned portSHORT) 1;
+
+ /* Remove any TCB's from the ready queues. */
+ do
+ {
+ usQueue--;
+
+ while (!listLIST_IS_EMPTY (&(pxReadyTasksLists[usQueue])))
+ {
+ listGET_OWNER_OF_NEXT_ENTRY (pxTCB, &(pxReadyTasksLists[usQueue]));
+ vListRemove ((xListItem *) & (pxTCB->xGenericListItem));
+
+ prvDeleteTCB ((tskTCB *) pxTCB);
+ }
+ }
+ while (usQueue > (unsigned portSHORT) tskIDLE_PRIORITY);
+
+ /* Remove any TCB's from the delayed queue. */
+ while (!listLIST_IS_EMPTY (&xDelayedTaskList1))
+ {
+ listGET_OWNER_OF_NEXT_ENTRY (pxTCB, &xDelayedTaskList1);
+ vListRemove ((xListItem *) & (pxTCB->xGenericListItem));
+
+ prvDeleteTCB ((tskTCB *) pxTCB);
+ }
+
+ /* Remove any TCB's from the overflow delayed queue. */
+ while (!listLIST_IS_EMPTY (&xDelayedTaskList2))
+ {
+ listGET_OWNER_OF_NEXT_ENTRY (pxTCB, &xDelayedTaskList2);
+ vListRemove ((xListItem *) & (pxTCB->xGenericListItem));
+
+ prvDeleteTCB ((tskTCB *) pxTCB);
+ }
+
+ while (!listLIST_IS_EMPTY (&xSuspendedTaskList))
+ {
+ listGET_OWNER_OF_NEXT_ENTRY (pxTCB, &xSuspendedTaskList);
+ vListRemove ((xListItem *) & (pxTCB->xGenericListItem));
+
+ prvDeleteTCB ((tskTCB *) pxTCB);
+ }
+
+ while (!listLIST_IS_EMPTY (&xPendingReadyList))
+ {
+ listGET_OWNER_OF_NEXT_ENTRY (pxTCB, &xPendingReadyList);
+ vListRemove ((xListItem *) & (pxTCB->xGenericListItem));
+
+ prvDeleteTCB ((tskTCB *) pxTCB);
+ }
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+void
+vTaskSwitchContext (void)
+{
+ if (uxSchedulerSuspended != (unsigned portBASE_TYPE) pdFALSE)
+ {
+ /* The scheduler is currently suspended - do not allow a context
+ switch. */
+ xMissedYield = pdTRUE;
+ return;
+ }
+
+ /* Find the highest priority queue that contains ready tasks. */
+ while (listLIST_IS_EMPTY (&(pxReadyTasksLists[uxTopReadyPriority])))
+ {
+ --uxTopReadyPriority;
+ }
+
+ /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the
+ same priority get an equal share of the processor time. */
+ listGET_OWNER_OF_NEXT_ENTRY (pxCurrentTCB,
+ &(pxReadyTasksLists[uxTopReadyPriority]));
+ vWriteTraceToBuffer ();
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vTaskPlaceOnEventList (xList * pxEventList, portTickType xTicksToWait)
+{
+ portTickType xTimeToWake;
+
+ /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
+ SCHEDULER SUSPENDED. */
+
+ /* Place the event list item of the TCB in the appropriate event list.
+ This is placed in the list in priority order so the highest priority task
+ is the first to be woken by the event. */
+ vListInsert ((xList *) pxEventList,
+ (xListItem *) & (pxCurrentTCB->xEventListItem));
+
+ /* We must remove ourselves from the ready list before adding ourselves
+ to the blocked list as the same list item is used for both lists. We have
+ exclusive access to the ready lists as the scheduler is locked. */
+ vListRemove ((xListItem *) & (pxCurrentTCB->xGenericListItem));
+
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+ {
+ if (xTicksToWait == portMAX_DELAY)
+ {
+ /* Add ourselves to the suspended task list instead of a delayed task
+ list to ensure we are not woken by a timing event. We will block
+ indefinitely. */
+ vListInsertEnd ((xList *) & xSuspendedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ else
+ {
+ /* Calculate the time at which the task should be woken if the event does
+ not occur. This may overflow but this doesn't matter. */
+ xTimeToWake = xTickCount + xTicksToWait;
+
+ listSET_LIST_ITEM_VALUE (&(pxCurrentTCB->xGenericListItem),
+ xTimeToWake);
+
+ if (xTimeToWake < xTickCount)
+ {
+ /* Wake time has overflowed. Place this item in the overflow list. */
+ vListInsert ((xList *) pxOverflowDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ else
+ {
+ /* The wake time has not overflowed, so we can use the current block list. */
+ vListInsert ((xList *) pxDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ }
+ }
+#else
+ {
+ /* Calculate the time at which the task should be woken if the event does
+ not occur. This may overflow but this doesn't matter. */
+ xTimeToWake = xTickCount + xTicksToWait;
+
+ listSET_LIST_ITEM_VALUE (&(pxCurrentTCB->xGenericListItem), xTimeToWake);
+
+ if (xTimeToWake < xTickCount)
+ {
+ /* Wake time has overflowed. Place this item in the overflow list. */
+ vListInsert ((xList *) pxOverflowDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ else
+ {
+ /* The wake time has not overflowed, so we can use the current block list. */
+ vListInsert ((xList *) pxDelayedTaskList,
+ (xListItem *) & (pxCurrentTCB->xGenericListItem));
+ }
+ }
+#endif
+}
+
+/*-----------------------------------------------------------*/
+
+signed portBASE_TYPE
+xTaskRemoveFromEventList (const xList * pxEventList)
+{
+ tskTCB *pxUnblockedTCB;
+ portBASE_TYPE xReturn;
+
+ /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE
+ SCHEDULER SUSPENDED. It can also be called from within an ISR. */
+
+ /* The event list is sorted in priority order, so we can remove the
+ first in the list, remove the TCB from the delayed list, and add
+ it to the ready list.
+
+ If an event is for a queue that is locked then this function will never
+ get called - the lock count on the queue will get modified instead. This
+ means we can always expect exclusive access to the event list here. */
+ pxUnblockedTCB = (tskTCB *) listGET_OWNER_OF_HEAD_ENTRY (pxEventList);
+ vListRemove (&(pxUnblockedTCB->xEventListItem));
+
+ if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE)
+ {
+ vListRemove (&(pxUnblockedTCB->xGenericListItem));
+ prvAddTaskToReadyQueue (pxUnblockedTCB);
+ }
+ else
+ {
+ /* We cannot access the delayed or ready lists, so will hold this
+ task pending until the scheduler is resumed. */
+ vListInsertEnd ((xList *) & (xPendingReadyList),
+ &(pxUnblockedTCB->xEventListItem));
+ }
+
+ if (pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority)
+ {
+ /* Return true if the task removed from the event list has
+ a higher priority than the calling task. This allows
+ the calling task to know if it should force a context
+ switch now. */
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vTaskSetTimeOutState (xTimeOutType * pxTimeOut)
+{
+ pxTimeOut->xOverflowCount = xNumOfOverflows;
+ pxTimeOut->xTimeOnEntering = xTickCount;
+}
+
+/*-----------------------------------------------------------*/
+
+portBASE_TYPE
+xTaskCheckForTimeOut (xTimeOutType * pxTimeOut, portTickType * pxTicksToWait)
+{
+ portBASE_TYPE xReturn;
+
+ if ((xNumOfOverflows != pxTimeOut->xOverflowCount)
+ && (xTickCount >= pxTimeOut->xTimeOnEntering))
+ {
+ /* The tick count is greater than the time at which vTaskSetTimeout()
+ was called, but has also overflowed since vTaskSetTimeOut() was called.
+ It must have wrapped all the way around and gone past us again. This
+ passed since vTaskSetTimeout() was called. */
+ xReturn = pdTRUE;
+ }
+ else if ((xTickCount - pxTimeOut->xTimeOnEntering) < *pxTicksToWait)
+ {
+ /* Not a genuine timeout. Adjust parameters for time remaining. */
+ *pxTicksToWait -= (xTickCount - pxTimeOut->xTimeOnEntering);
+ vTaskSetTimeOutState (pxTimeOut);
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ xReturn = pdTRUE;
+ }
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+void
+vTaskMissedYield (void)
+{
+ xMissedYield = pdTRUE;
+}
+
+/*
+ * -----------------------------------------------------------
+ * The Idle task.
+ * ----------------------------------------------------------
+ *
+ * The portTASK_FUNCTION() macro is used to allow port/compiler specific
+ * language extensions. The equivalent prototype for this function is:
+ *
+ * void prvIdleTask( void *pvParameters );
+ *
+ */
+static
+portTASK_FUNCTION (prvIdleTask, pvParameters)
+{
+ /* Stop warnings. */
+ (void) pvParameters;
+
+ for (;;)
+ {
+ /* See if any tasks have been deleted. */
+ prvCheckTasksWaitingTermination ();
+
+#if ( configUSE_PREEMPTION == 0 )
+ {
+ /* If we are not using preemption we keep forcing a task switch to
+ see if any other task has become available. If we are using
+ preemption we don't need to do this as any task becoming available
+ will automatically get the processor anyway. */
+ taskYIELD ();
+ }
+#endif
+
+#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
+ {
+ /* When using preemption tasks of equal priority will be
+ timesliced. If a task that is sharing the idle priority is ready
+ to run then the idle task should yield before the end of the
+ timeslice.
+
+ A critical region is not required here as we are just reading from
+ the list, and an occasional incorrect value will not matter. If
+ the ready list at the idle priority contains more than one task
+ then a task other than the idle task is ready to execute. */
+ if (listCURRENT_LIST_LENGTH (&(pxReadyTasksLists[tskIDLE_PRIORITY])) >
+ (unsigned portBASE_TYPE) 1)
+ {
+ taskYIELD ();
+ }
+ }
+#endif
+
+#if ( configUSE_IDLE_HOOK == 1 )
+ {
+ extern void vApplicationIdleHook (void);
+
+ /* Call the user defined function from within the idle task. This
+ allows the application designer to add background functionality
+ without the overhead of a separate task.
+ NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
+ CALL A FUNCTION THAT MIGHT BLOCK. */
+ vApplicationIdleHook ();
+ }
+#endif
+ }
+} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */
+
+
+
+
+
+
+
+/*-----------------------------------------------------------
+ * File private functions documented at the top of the file.
+ *----------------------------------------------------------*/
+
+
+
+static void
+prvInitialiseTCBVariables (tskTCB * pxTCB, unsigned portSHORT usStackDepth,
+ const signed portCHAR * const pcName,
+ unsigned portBASE_TYPE uxPriority)
+{
+ pxTCB->usStackDepth = usStackDepth;
+
+ /* Store the function name in the TCB. */
+ strncpy ((char *) pxTCB->pcTaskName, (const char *) pcName,
+ (unsigned portSHORT) configMAX_TASK_NAME_LEN);
+ pxTCB->pcTaskName[(unsigned portSHORT) configMAX_TASK_NAME_LEN -
+ (unsigned portSHORT) 1] = '\0';
+
+ /* This is used as an array index so must ensure it's not too large. */
+ if (uxPriority >= configMAX_PRIORITIES)
+ {
+ uxPriority = configMAX_PRIORITIES - 1;
+ }
+
+ pxTCB->uxPriority = uxPriority;
+
+ vListInitialiseItem (&(pxTCB->xGenericListItem));
+ vListInitialiseItem (&(pxTCB->xEventListItem));
+
+ /* Set the pxTCB as a link back from the xListItem. This is so we can get
+ back to the containing TCB from a generic item in a list. */
+ listSET_LIST_ITEM_OWNER (&(pxTCB->xGenericListItem), pxTCB);
+
+ /* Event lists are always in priority order. */
+ listSET_LIST_ITEM_VALUE (&(pxTCB->xEventListItem),
+ configMAX_PRIORITIES - (portTickType) uxPriority);
+ listSET_LIST_ITEM_OWNER (&(pxTCB->xEventListItem), pxTCB);
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvInitialiseTaskLists (void)
+{
+ unsigned portBASE_TYPE uxPriority;
+
+ for (uxPriority = 0; uxPriority < configMAX_PRIORITIES; uxPriority++)
+ {
+ vListInitialise ((xList *) & (pxReadyTasksLists[uxPriority]));
+ }
+
+ vListInitialise ((xList *) & xDelayedTaskList1);
+ vListInitialise ((xList *) & xDelayedTaskList2);
+ vListInitialise ((xList *) & xPendingReadyList);
+
+#if ( INCLUDE_vTaskDelete == 1 )
+ {
+ vListInitialise ((xList *) & xTasksWaitingTermination);
+ }
+#endif
+
+#if ( INCLUDE_vTaskSuspend == 1 )
+ {
+ vListInitialise ((xList *) & xSuspendedTaskList);
+ }
+#endif
+
+ /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList
+ using list2. */
+ pxDelayedTaskList = &xDelayedTaskList1;
+ pxOverflowDelayedTaskList = &xDelayedTaskList2;
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvCheckTasksWaitingTermination (void)
+{
+#if ( INCLUDE_vTaskDelete == 1 )
+ {
+ portBASE_TYPE xListIsEmpty;
+
+ /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
+ too often in the idle task. */
+ if (uxTasksDeleted > (unsigned portBASE_TYPE) 0)
+ {
+ vTaskSuspendAll ();
+ xListIsEmpty = listLIST_IS_EMPTY (&xTasksWaitingTermination);
+ xTaskResumeAll ();
+
+ if (!xListIsEmpty)
+ {
+ tskTCB *pxTCB;
+
+ portENTER_CRITICAL ();
+ {
+ pxTCB =
+ (tskTCB *)
+ listGET_OWNER_OF_HEAD_ENTRY (((xList *) &
+ xTasksWaitingTermination));
+ vListRemove (&(pxTCB->xGenericListItem));
+ --uxCurrentNumberOfTasks;
+ --uxTasksDeleted;
+ }
+ portEXIT_CRITICAL ();
+
+ prvDeleteTCB (pxTCB);
+ }
+ }
+ }
+#endif
+}
+
+/*-----------------------------------------------------------*/
+
+static tskTCB *
+prvAllocateTCBAndStack (unsigned portSHORT usStackDepth)
+{
+ tskTCB *pxNewTCB;
+
+ /* Allocate space for the TCB. Where the memory comes from depends on
+ the implementation of the port malloc function. */
+ pxNewTCB = (tskTCB *) pvPortMalloc (sizeof (tskTCB));
+
+ if (pxNewTCB != NULL)
+ {
+ /* Allocate space for the stack used by the task being created.
+ The base of the stack memory stored in the TCB so the task can
+ be deleted later if required. */
+ pxNewTCB->pxStack =
+ (portSTACK_TYPE *) pvPortMalloc (((size_t) usStackDepth) *
+ sizeof (portSTACK_TYPE));
+
+ if (pxNewTCB->pxStack == NULL)
+ {
+ /* Could not allocate the stack. Delete the allocated TCB. */
+ vPortFree (pxNewTCB);
+ pxNewTCB = NULL;
+ }
+ else
+ {
+ /* Just to help debugging. */
+ memset (pxNewTCB->pxStack, tskSTACK_FILL_BYTE,
+ usStackDepth * sizeof (portSTACK_TYPE));
+ }
+ }
+
+ return pxNewTCB;
+}
+
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+
+static void
+prvListTaskWithinSingleList (signed portCHAR * pcWriteBuffer, xList * pxList,
+ signed portCHAR cStatus)
+{
+ volatile tskTCB *pxNextTCB, *pxFirstTCB;
+ static portCHAR pcStatusString[50];
+ unsigned portSHORT usStackRemaining;
+
+ /* Write the details of all the TCB's in pxList into the buffer. */
+ listGET_OWNER_OF_NEXT_ENTRY (pxFirstTCB, pxList);
+ do
+ {
+ listGET_OWNER_OF_NEXT_ENTRY (pxNextTCB, pxList);
+ usStackRemaining =
+ usTaskCheckFreeStackSpace ((unsigned portCHAR *) pxNextTCB->pxStack);
+ sprintf (pcStatusString, (portCHAR *) "%s\t\t%c\t%u\t%u\t%u\r\n",
+ pxNextTCB->pcTaskName, cStatus,
+ (unsigned int) pxNextTCB->uxPriority, usStackRemaining,
+ (unsigned int) pxNextTCB->uxTCBNumber);
+ strcat ((portCHAR *) pcWriteBuffer, (portCHAR *) pcStatusString);
+
+ }
+ while (pxNextTCB != pxFirstTCB);
+}
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( configUSE_TRACE_FACILITY == 1 )
+unsigned portSHORT
+usTaskCheckFreeStackSpace (const unsigned portCHAR * pucStackByte)
+{
+ register unsigned portSHORT usCount = 0;
+
+ while (*pucStackByte == tskSTACK_FILL_BYTE)
+ {
+ pucStackByte -= portSTACK_GROWTH;
+ usCount++;
+ }
+
+ usCount /= sizeof (portSTACK_TYPE);
+
+ return usCount;
+}
+#endif
+/*-----------------------------------------------------------*/
+
+
+
+#if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )
+
+static void
+prvDeleteTCB (tskTCB * pxTCB)
+{
+ /* Free up the memory allocated by the scheduler for the task. It is up to
+ the task to free any memory allocated at the application level. */
+ vPortFree (pxTCB->pxStack);
+ vPortFree (pxTCB);
+}
+
+#endif
+
+
+/*-----------------------------------------------------------*/
+
+#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 )
+
+xTaskHandle
+xTaskGetCurrentTaskHandle (void)
+{
+ xTaskHandle xReturn;
+
+ portENTER_CRITICAL ();
+ {
+ xReturn = (xTaskHandle) pxCurrentTCB;
+ }
+ portEXIT_CRITICAL ();
+
+ return xReturn;
+}
+
+#endif
diff --git a/openpicc/os/license.txt b/openpicc/os/license.txt
new file mode 100644
index 0000000..1f24fa7
--- /dev/null
+++ b/openpicc/os/license.txt
@@ -0,0 +1,399 @@
+The FreeRTOS.org source code is licensed by the modified GNU General Public
+License (GPL) text provided below. The FreeRTOS download also includes
+demo application source code, some of which is provided by third parties
+AND IS LICENSED SEPARATELY FROM FREERTOS.ORG.
+
+For the avoidance of any doubt refer to the comment included at the top
+of each source and header file for license and copyright information.
+
+This is a list of files for which Richard Barry is not the copyright owner
+and are NOT COVERED BY THE GPL.
+
+
+1) Various header files provided by silicon manufacturers and tool vendors
+ that define processor specific memory addresses and utility macros.
+ Permission has been granted by the various copyright holders for these
+ files to be included in the FreeRTOS download. Users must ensure license
+ conditions are adhered to for any use other than compilation of the
+ FreeRTOS demo application.
+
+2) The uIP TCP/IP stack the copyright of which is held by Adam Dunkels.
+ Users must ensure the open source license conditions stated at the top
+ of each uIP source file is understood and adhered to.
+
+3) The lwIP TCP/IP stack the copyright of which is held by the Swedish
+ Institute of Computer Science. Users must ensure the open source license
+ conditions stated at the top of each lwIP source file is understood and
+ adhered to.
+
+4) All files contained within the FreeRTOS\Demo\CORTEX_LM3S102_GCC\hw_include
+ and FreeRTOS\Demo\CORTEX_LM3S316_IAR\hw_include directories. The
+ copyright of these files is owned by Luminary Micro. Permission has been
+ granted by Luminary Micro for these files to be included in the FreeRTOS
+ download. Users must ensure the license conditions stated in the EULA.txt
+ file located in the same directories is understood and adhered at all
+ times for all files in those directories.
+
+5) The files contained within FreeRTOS\Demo\WizNET_DEMO_TERN_186\tern_code,
+ which are slightly modified versions of code provided by and copyright to
+ Tern Inc.
+
+Errors and omissions should be reported to Richard Barry, contact details for
+whom can be obtained from http://www.FreeRTOS.org.
+
+
+
+
+
+The GPL license text follows.
+
+An exception to this license exists that can be applied should you
+wish to use FreeRTOS in a work that includes commercial or
+proprietary code without being obliged to provide source code for the
+proprietary components. See the licensing section of
+http://www.FreeRTOS.org for full details.
+--------------------------------------------------------------------
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
diff --git a/openpicc/os/usb/USB-CDC.c b/openpicc/os/usb/USB-CDC.c
new file mode 100644
index 0000000..4496c55
--- /dev/null
+++ b/openpicc/os/usb/USB-CDC.c
@@ -0,0 +1,953 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+ USB Communications Device Class driver.
+ Implements task vUSBCDCTask and provides an Abstract Control Model serial
+ interface. Control is through endpoint 0, device-to-host notification is
+ provided by interrupt-in endpoint 3, and raw data is transferred through
+ bulk endpoints 1 and 2.
+
+ - developed from original FreeRTOS HID example by Scott Miller
+ - modified to support 3.2 GCC by najay
+*/
+
+/* Standard includes. */
+#include <string.h>
+#include <stdio.h>
+
+/* Demo board includes. */
+#include <board.h>
+
+/* Scheduler includes. */
+#include <FreeRTOS.h>
+#include <task.h>
+#include <queue.h>
+
+/* Demo app includes. */
+#include <USB-CDC.h>
+#include <descriptors.h>
+
+#define usbNO_BLOCK ( ( portTickType ) 0 )
+
+/* Reset all endpoints */
+static void prvResetEndPoints (void);
+
+/* Clear pull up resistor to detach device from host */
+static void vDetachUSBInterface (void);
+
+/* Set up interface and initialize variables */
+static void vInitUSBInterface (void);
+
+/* Handle control endpoint events. */
+static void prvProcessEndPoint0Interrupt (xISRStatus * pxMessage);
+
+/* Handle standard device requests. */
+static void prvHandleStandardDeviceRequest (xUSB_REQUEST * pxRequest);
+
+/* Handle standard interface requests. */
+static void prvHandleStandardInterfaceRequest (xUSB_REQUEST * pxRequest);
+
+/* Handle endpoint requests. */
+static void prvHandleStandardEndPointRequest (xUSB_REQUEST * pxRequest);
+
+/* Handle class interface requests. */
+static void prvHandleClassInterfaceRequest (xUSB_REQUEST * pxRequest);
+
+/* Prepare control data transfer. prvSendNextSegment starts transfer. */
+static void prvSendControlData (unsigned portCHAR * pucData,
+ unsigned portSHORT usRequestedLength,
+ unsigned portLONG ulLengthLeftToSend,
+ portLONG lSendingDescriptor);
+
+/* Send next segment of data for the control transfer */
+static void prvSendNextSegment (void);
+
+/* Send stall - used to respond to unsupported requests */
+static void prvSendStall (void);
+
+/* Send a zero-length (null) packet */
+static void prvSendZLP (void);
+
+/* Handle requests for standard interface descriptors */
+static void prvGetStandardInterfaceDescriptor (xUSB_REQUEST * pxRequest);
+
+/*------------------------------------------------------------*/
+
+/* File scope static variables */
+static unsigned portCHAR ucUSBConfig = (unsigned portCHAR) 0;
+static unsigned portLONG ulReceivedAddress = (unsigned portLONG) 0;
+static eDRIVER_STATE eDriverState = eNOTHING;
+
+/* Incoming and outgoing control data structures */
+static xCONTROL_MESSAGE pxControlTx;
+static xCONTROL_MESSAGE pxControlRx;
+
+/* Queue holding pointers to pending messages */
+xQueueHandle xUSBInterruptQueue;
+
+/* Queues used to hold received characters, and characters waiting to be
+transmitted. Rx queue must be larger than FIFO size. */
+static xQueueHandle xRxCDC;
+static xQueueHandle xTxCDC;
+
+/* Line coding - 115,200 baud, N-8-1 */
+static const unsigned portCHAR pxLineCoding[] =
+ { 0x00, 0xC2, 0x01, 0x00, 0x00, 0x00, 0x08 };
+
+/* Status variables. */
+static unsigned portCHAR ucControlState;
+static unsigned int uiCurrentBank;
+
+
+/*------------------------------------------------------------*/
+
+
+void
+vUSBCDCTask (void *pvParameters)
+{
+ xISRStatus *pxMessage;
+ unsigned portLONG ulStatus;
+ unsigned portLONG ulRxBytes;
+ unsigned portCHAR ucByte;
+ portBASE_TYPE xByte;
+
+ (void) pvParameters;
+
+ /* Disconnect USB device from hub. For debugging - causes host to register reset */
+ portENTER_CRITICAL ();
+ vDetachUSBInterface ();
+ portEXIT_CRITICAL ();
+
+ vTaskDelay (portTICK_RATE_MS * 60);
+
+ /* Init USB interface */
+ portENTER_CRITICAL ();
+ vInitUSBInterface ();
+ portEXIT_CRITICAL ();
+
+ /* Main task loop. Process incoming endpoint 0 interrupts, handle data transfers. */
+
+ for (;;)
+ {
+ /* Look for data coming from the ISR. */
+ if (xQueueReceive (xUSBInterruptQueue, &pxMessage, usbSHORTEST_DELAY))
+ {
+ if (pxMessage->ulISR & AT91C_UDP_EPINT0)
+ {
+ /* All endpoint 0 interrupts are handled here. */
+ prvProcessEndPoint0Interrupt (pxMessage);
+ }
+
+ if (pxMessage->ulISR & AT91C_UDP_ENDBUSRES)
+ {
+ /* End of bus reset - reset the endpoints and de-configure. */
+ prvResetEndPoints ();
+ }
+ }
+
+ /* See if we're ready to send and receive data. */
+ if (eDriverState == eREADY_TO_SEND && ucControlState)
+ {
+ if ((!
+ (AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] & AT91C_UDP_TXPKTRDY))
+ && uxQueueMessagesWaiting (xTxCDC))
+ {
+ for (xByte = 0; xByte < 64; xByte++)
+ {
+ if (!xQueueReceive (xTxCDC, &ucByte, 0))
+ {
+ /* No data buffered to transmit. */
+ break;
+ }
+
+ /* Got a byte to transmit. */
+ AT91C_BASE_UDP->UDP_FDR[usbEND_POINT_2] = ucByte;
+ }
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] |= AT91C_UDP_TXPKTRDY;
+ }
+
+ /* Check for incoming data (host-to-device) on endpoint 1. */
+ while (AT91C_BASE_UDP->
+ UDP_CSR[usbEND_POINT_1] & (AT91C_UDP_RX_DATA_BK0 |
+ AT91C_UDP_RX_DATA_BK1))
+ {
+ ulRxBytes =
+ (AT91C_BASE_UDP->
+ UDP_CSR[usbEND_POINT_1] >> 16) & usbRX_COUNT_MASK;
+
+ /* Only process FIFO if there's room to store it in the queue */
+ if (ulRxBytes <
+ (USB_CDC_QUEUE_SIZE - uxQueueMessagesWaiting (xRxCDC)))
+ {
+ while (ulRxBytes--)
+ {
+ ucByte = AT91C_BASE_UDP->UDP_FDR[usbEND_POINT_1];
+ xQueueSend (xRxCDC, &ucByte, 0);
+ }
+
+ /* Release the FIFO */
+ portENTER_CRITICAL ();
+ {
+ ulStatus = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_1];
+ usbCSR_CLEAR_BIT (&ulStatus, uiCurrentBank);
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_1] = ulStatus;
+ }
+ portEXIT_CRITICAL ();
+
+ /* Re-enable endpoint 1's interrupts */
+ AT91C_BASE_UDP->UDP_IER = AT91C_UDP_EPINT1;
+
+ /* Update the current bank in use */
+ if (uiCurrentBank == AT91C_UDP_RX_DATA_BK0)
+ {
+ uiCurrentBank = AT91C_UDP_RX_DATA_BK1;
+ }
+ else
+ {
+ uiCurrentBank = AT91C_UDP_RX_DATA_BK0;
+ }
+
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+}
+
+/*------------------------------------------------------------*/
+
+void
+vUSBSendByte (portCHAR cByte)
+{
+ /* Queue the byte to be sent. The USB task will send it. */
+ xQueueSend (xTxCDC, &cByte, usbNO_BLOCK);
+}
+
+/*------------------------------------------------------------*/
+
+portLONG
+vUSBRecvByte (portCHAR *cByte, portLONG size, portTickType xTicksToWait)
+{
+ portLONG res;
+ if(size<=0 || !cByte || !xRxCDC)
+ return 0;
+
+ res=0;
+ while(size-- && xQueueReceive(xRxCDC, cByte++, xTicksToWait))
+ res++;
+
+ return res;
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvSendZLP (void)
+{
+ unsigned portLONG ulStatus;
+
+ /* Wait until the FIFO is free - even though we are not going to use it.
+ THERE IS NO TIMEOUT HERE! */
+ while (AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] & AT91C_UDP_TXPKTRDY)
+ {
+ vTaskDelay (usbSHORTEST_DELAY);
+ }
+
+ portENTER_CRITICAL ();
+ {
+ /* Cancel any further pending data */
+ pxControlTx.ulTotalDataLength = pxControlTx.ulNextCharIndex;
+
+ /* Set the TXPKTRDY bit to cause a transmission with no data. */
+ ulStatus = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0];
+ usbCSR_SET_BIT (&ulStatus, AT91C_UDP_TXPKTRDY);
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] = ulStatus;
+ }
+ portEXIT_CRITICAL ();
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvSendStall (void)
+{
+ unsigned portLONG ulStatus;
+
+ portENTER_CRITICAL ();
+ {
+ /* Force a stall by simply setting the FORCESTALL bit in the CSR. */
+ ulStatus = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0];
+ usbCSR_SET_BIT (&ulStatus, AT91C_UDP_FORCESTALL);
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] = ulStatus;
+ }
+ portEXIT_CRITICAL ();
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvResetEndPoints (void)
+{
+ unsigned portLONG ulTemp;
+
+ eDriverState = eJUST_RESET;
+ ucControlState = 0;
+
+ /* Reset all the end points. */
+ AT91C_BASE_UDP->UDP_RSTEP = usbEND_POINT_RESET_MASK;
+ AT91C_BASE_UDP->UDP_RSTEP = (unsigned portLONG) 0x00;
+
+ /* Enable data to be sent and received. */
+ AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;
+
+ /* Repair the configuration end point. */
+ portENTER_CRITICAL ();
+ {
+ ulTemp = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0];
+ usbCSR_SET_BIT (&ulTemp,
+ ((unsigned portLONG) (AT91C_UDP_EPEDS |
+ AT91C_UDP_EPTYPE_CTRL)));
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] = ulTemp;
+ AT91C_BASE_UDP->UDP_IER = AT91C_UDP_EPINT0;
+ }
+ portEXIT_CRITICAL ();
+ uiCurrentBank = AT91C_UDP_RX_DATA_BK0;
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvProcessEndPoint0Interrupt (xISRStatus * pxMessage)
+{
+ static xUSB_REQUEST xRequest;
+ unsigned portLONG ulRxBytes;
+
+ /* Get number of bytes received, if any */
+ ulRxBytes = pxMessage->ulCSR0 >> 16;
+ ulRxBytes &= usbRX_COUNT_MASK;
+
+ if (pxMessage->ulCSR0 & AT91C_UDP_TXCOMP)
+ {
+ /* We received a TX complete interrupt. What we do depends on
+ what we sent to get this interrupt. */
+
+ if (eDriverState == eJUST_GOT_CONFIG)
+ {
+ /* We sent an acknowledgement of a SET_CONFIG request. We
+ are now at the end of the enumeration.
+
+ TODO: Config 0 sets unconfigured state, should enter Address state.
+ Request for unsupported config should stall. */
+ AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_CONFG;
+
+ /* Set up endpoints */
+ portENTER_CRITICAL ();
+ {
+ unsigned portLONG ulTemp;
+
+ /* Set endpoint 1 to bulk-out */
+ ulTemp = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_1];
+ usbCSR_SET_BIT (&ulTemp,
+ AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_1] = ulTemp;
+ AT91C_BASE_UDP->UDP_IER = AT91C_UDP_EPINT1;
+ /* Set endpoint 2 to bulk-in */
+ ulTemp = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2];
+ usbCSR_SET_BIT (&ulTemp,
+ AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] = ulTemp;
+ AT91C_BASE_UDP->UDP_IER = AT91C_UDP_EPINT2;
+ /* Set endpoint 3 to interrupt-in, enable it, and enable interrupts */
+ ulTemp = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_3];
+ usbCSR_SET_BIT (&ulTemp,
+ AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_3] = ulTemp;
+ /*AT91F_UDP_EnableIt( AT91C_BASE_UDP, AT91C_UDP_EPINT3 ); */
+ }
+ portEXIT_CRITICAL ();
+
+ eDriverState = eREADY_TO_SEND;
+ }
+ else if (eDriverState == eJUST_GOT_ADDRESS)
+ {
+ /* We sent an acknowledgement of a SET_ADDRESS request. Move
+ to the addressed state. */
+ if (ulReceivedAddress != (unsigned portLONG) 0)
+ {
+ AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
+ }
+ else
+ {
+ AT91C_BASE_UDP->UDP_GLBSTATE = 0;
+ }
+
+ AT91C_BASE_UDP->UDP_FADDR = (AT91C_UDP_FEN | ulReceivedAddress);
+ eDriverState = eNOTHING;
+ }
+ else
+ {
+ /* The TXCOMP was not for any special type of transmission. See
+ if there is any more data to send. */
+ prvSendNextSegment ();
+ }
+ }
+
+ if (pxMessage->ulCSR0 & AT91C_UDP_RX_DATA_BK0)
+ {
+ /* Received a control data packet. May be a 0-length ACK or a data stage. */
+ unsigned portCHAR ucBytesToGet;
+
+ /* Got data. Cancel any outgoing data. */
+ pxControlTx.ulNextCharIndex = pxControlTx.ulTotalDataLength;
+
+ /* Determine how many bytes we need to receive. */
+ ucBytesToGet =
+ pxControlRx.ulTotalDataLength - pxControlRx.ulNextCharIndex;
+ if (ucBytesToGet > ulRxBytes)
+ {
+ ucBytesToGet = ulRxBytes;
+ }
+
+ /* If we're not expecting any data, it's an ack - just quit now. */
+ if (!ucBytesToGet)
+ {
+ return;
+ }
+
+ /* Get the required data and update the index. */
+ memcpy (pxControlRx.ucBuffer, pxMessage->ucFifoData, ucBytesToGet);
+ pxControlRx.ulNextCharIndex += ucBytesToGet;
+ }
+
+ if (pxMessage->ulCSR0 & AT91C_UDP_RXSETUP)
+ {
+ /* Received a SETUP packet. May be followed by data packets. */
+
+ if (ulRxBytes >= usbEXPECTED_NUMBER_OF_BYTES)
+ {
+ /* Create an xUSB_REQUEST variable from the raw bytes array. */
+
+ xRequest.ucReqType = pxMessage->ucFifoData[usbREQUEST_TYPE_INDEX];
+ xRequest.ucRequest = pxMessage->ucFifoData[usbREQUEST_INDEX];
+
+ xRequest.usValue = pxMessage->ucFifoData[usbVALUE_HIGH_BYTE];
+ xRequest.usValue <<= 8;
+ xRequest.usValue |= pxMessage->ucFifoData[usbVALUE_LOW_BYTE];
+
+ xRequest.usIndex = pxMessage->ucFifoData[usbINDEX_HIGH_BYTE];
+ xRequest.usIndex <<= 8;
+ xRequest.usIndex |= pxMessage->ucFifoData[usbINDEX_LOW_BYTE];
+
+ xRequest.usLength = pxMessage->ucFifoData[usbLENGTH_HIGH_BYTE];
+ xRequest.usLength <<= 8;
+ xRequest.usLength |= pxMessage->ucFifoData[usbLENGTH_LOW_BYTE];
+
+ pxControlRx.ulNextCharIndex = 0;
+ if (!(xRequest.ucReqType & 0x80)) /* Host-to-Device transfer, may need to get data first */
+ {
+ if (xRequest.usLength > usbMAX_CONTROL_MESSAGE_SIZE)
+ {
+ /* Too big! No space for control data, stall and abort. */
+ prvSendStall ();
+ return;
+ }
+
+ pxControlRx.ulTotalDataLength = xRequest.usLength;
+ }
+ else
+ {
+ /* We're sending the data, don't wait for any. */
+ pxControlRx.ulTotalDataLength = 0;
+ }
+ }
+ }
+
+ /* See if we've got a pending request and all its associated data ready */
+ if ((pxMessage->ulCSR0 & (AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RXSETUP))
+ && (pxControlRx.ulNextCharIndex >= pxControlRx.ulTotalDataLength))
+ {
+ unsigned portCHAR ucRequest;
+
+ /* Manipulate the ucRequestType and the ucRequest parameters to
+ generate a zero based request selection. This is just done to
+ break up the requests into subsections for clarity. The
+ alternative would be to have more huge switch statement that would
+ be difficult to optimise. */
+ ucRequest = ((xRequest.ucReqType & 0x60) >> 3);
+ ucRequest |= (xRequest.ucReqType & 0x03);
+
+ switch (ucRequest)
+ {
+ case usbSTANDARD_DEVICE_REQUEST:
+ /* Standard Device request */
+ prvHandleStandardDeviceRequest (&xRequest);
+ break;
+
+ case usbSTANDARD_INTERFACE_REQUEST:
+ /* Standard Interface request */
+ prvHandleStandardInterfaceRequest (&xRequest);
+ break;
+
+ case usbSTANDARD_END_POINT_REQUEST:
+ /* Standard Endpoint request */
+ prvHandleStandardEndPointRequest (&xRequest);
+ break;
+
+ case usbCLASS_INTERFACE_REQUEST:
+ /* Class Interface request */
+ prvHandleClassInterfaceRequest (&xRequest);
+ break;
+
+ default: /* This is not something we want to respond to. */
+ prvSendStall ();
+ }
+ }
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvGetStandardDeviceDescriptor (xUSB_REQUEST * pxRequest)
+{
+ /* The type is in the high byte. Return whatever has been requested. */
+ switch ((pxRequest->usValue & 0xff00) >> 8)
+ {
+ case usbDESCRIPTOR_TYPE_DEVICE:
+ prvSendControlData ((unsigned portCHAR *) &pxDeviceDescriptor,
+ pxRequest->usLength, sizeof (pxDeviceDescriptor),
+ pdTRUE);
+ break;
+
+ case usbDESCRIPTOR_TYPE_CONFIGURATION:
+ prvSendControlData ((unsigned portCHAR *) &(pxConfigDescriptor),
+ pxRequest->usLength, sizeof (pxConfigDescriptor),
+ pdTRUE);
+ break;
+
+ case usbDESCRIPTOR_TYPE_STRING:
+
+ /* The index to the string descriptor is the lower byte. */
+ switch (pxRequest->usValue & 0xff)
+ {
+ case usbLANGUAGE_STRING:
+ prvSendControlData ((unsigned portCHAR *)
+ &pxLanguageStringDescriptor,
+ pxRequest->usLength,
+ sizeof (pxLanguageStringDescriptor), pdTRUE);
+ break;
+
+ case usbMANUFACTURER_STRING:
+ prvSendControlData ((unsigned portCHAR *)
+ &pxManufacturerStringDescriptor,
+ pxRequest->usLength,
+ sizeof (pxManufacturerStringDescriptor),
+ pdTRUE);
+ break;
+
+ case usbPRODUCT_STRING:
+ prvSendControlData ((unsigned portCHAR *)
+ &pxProductStringDescriptor, pxRequest->usLength,
+ sizeof (pxProductStringDescriptor), pdTRUE);
+ break;
+
+ default:
+ prvSendStall ();
+ break;
+ }
+ break;
+
+ default:
+ prvSendStall ();
+ break;
+ }
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvHandleStandardDeviceRequest (xUSB_REQUEST * pxRequest)
+{
+ unsigned portSHORT usStatus = 0;
+
+ switch (pxRequest->ucRequest)
+ {
+ case usbGET_STATUS_REQUEST:
+ /* Just send two byte dummy status. */
+ prvSendControlData ((unsigned portCHAR *) &usStatus, sizeof (usStatus),
+ sizeof (usStatus), pdFALSE);
+ break;
+
+ case usbGET_DESCRIPTOR_REQUEST:
+ /* Send device descriptor */
+ prvGetStandardDeviceDescriptor (pxRequest);
+ break;
+
+ case usbGET_CONFIGURATION_REQUEST:
+ /* Send selected device configuration */
+ prvSendControlData ((unsigned portCHAR *) &ucUSBConfig,
+ sizeof (ucUSBConfig), sizeof (ucUSBConfig),
+ pdFALSE);
+ break;
+
+ case usbSET_FEATURE_REQUEST:
+ prvSendZLP ();
+ break;
+
+ case usbSET_ADDRESS_REQUEST:
+ /* Get assigned address and send ack, but don't implement new address until we get a TXCOMP */
+ prvSendZLP ();
+ eDriverState = eJUST_GOT_ADDRESS;
+ ulReceivedAddress = (unsigned portLONG) pxRequest->usValue;
+ break;
+
+ case usbSET_CONFIGURATION_REQUEST:
+ /* Ack SET_CONFIGURATION request, but don't implement until TXCOMP */
+ ucUSBConfig = (unsigned portCHAR) (pxRequest->usValue & 0xff);
+ eDriverState = eJUST_GOT_CONFIG;
+ prvSendZLP ();
+ break;
+
+ default:
+ /* Any unsupported request results in a STALL response. */
+ prvSendStall ();
+ break;
+ }
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvHandleClassInterfaceRequest (xUSB_REQUEST * pxRequest)
+{
+ switch (pxRequest->ucRequest)
+ {
+ case usbSEND_ENCAPSULATED_COMMAND:
+ prvSendStall ();
+ break;
+
+ case usbGET_ENCAPSULATED_RESPONSE:
+ prvSendStall ();
+ break;
+
+ case usbSET_LINE_CODING:
+ /* Set line coding - baud rate, data bits, parity, stop bits */
+ prvSendZLP ();
+ memcpy ((void *) pxLineCoding, pxControlRx.ucBuffer,
+ sizeof (pxLineCoding));
+ break;
+
+ case usbGET_LINE_CODING:
+ /* Get line coding */
+ prvSendControlData ((unsigned portCHAR *) &pxLineCoding,
+ pxRequest->usLength, sizeof (pxLineCoding),
+ pdFALSE);
+ break;
+
+ case usbSET_CONTROL_LINE_STATE:
+ /* D0: 1=DTR, 0=No DTR, D1: 1=Activate Carrier, 0=Deactivate carrier (RTS, half-duplex) */
+ prvSendZLP ();
+ ucControlState = pxRequest->usValue;
+ break;
+
+ default:
+ prvSendStall ();
+ break;
+ }
+}
+
+/*------------------------------------------------------------*/
+
+static void
+prvGetStandardInterfaceDescriptor (xUSB_REQUEST * pxRequest)
+{
+ switch ((pxRequest->usValue & (unsigned portSHORT) 0xff00) >> 8)
+ {
+ default:
+ prvSendStall ();
+ break;
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvHandleStandardInterfaceRequest (xUSB_REQUEST * pxRequest)
+{
+ unsigned portSHORT usStatus = 0;
+
+ switch (pxRequest->ucRequest)
+ {
+ case usbGET_STATUS_REQUEST:
+ /* Send dummy 2 bytes. */
+ prvSendControlData ((unsigned portCHAR *) &usStatus, sizeof (usStatus),
+ sizeof (usStatus), pdFALSE);
+ break;
+
+ case usbGET_DESCRIPTOR_REQUEST:
+ prvGetStandardInterfaceDescriptor (pxRequest);
+ break;
+
+ /* This minimal implementation does not respond to these. */
+ case usbGET_INTERFACE_REQUEST:
+ case usbSET_FEATURE_REQUEST:
+ case usbSET_INTERFACE_REQUEST:
+
+ default:
+ prvSendStall ();
+ break;
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvHandleStandardEndPointRequest (xUSB_REQUEST * pxRequest)
+{
+ switch (pxRequest->ucRequest)
+ {
+ /* This minimal implementation does not expect to respond to these. */
+ case usbGET_STATUS_REQUEST:
+ case usbCLEAR_FEATURE_REQUEST:
+ case usbSET_FEATURE_REQUEST:
+
+ default:
+ prvSendStall ();
+ break;
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+vDetachUSBInterface (void)
+{
+ /* Setup the PIO for the USB pull up resistor. */
+ AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA16;
+ AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16;
+
+
+ /* Disable pull up */
+ AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA16;
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+vInitUSBInterface (void)
+{
+ extern void (vUSB_ISR) (void);
+
+ /* Create the queue used to communicate between the USB ISR and task. */
+ xUSBInterruptQueue =
+ xQueueCreate (usbQUEUE_LENGTH + 1, sizeof (xISRStatus *));
+
+ /* Create the queues used to hold Rx and Tx characters. */
+ xRxCDC =
+ xQueueCreate (USB_CDC_QUEUE_SIZE,
+ (unsigned portCHAR) sizeof (signed portCHAR));
+ xTxCDC =
+ xQueueCreate (USB_CDC_QUEUE_SIZE + 1,
+ (unsigned portCHAR) sizeof (signed portCHAR));
+
+ if ((!xUSBInterruptQueue) || (!xRxCDC) || (!xTxCDC))
+ {
+ /* Not enough RAM to create queues!. */
+ return;
+ }
+
+ /* Initialise a few state variables. */
+ pxControlTx.ulNextCharIndex = (unsigned portLONG) 0;
+ pxControlRx.ulNextCharIndex = (unsigned portLONG) 0;
+ ucUSBConfig = (unsigned portCHAR) 0;
+ eDriverState = eNOTHING;
+ ucControlState = 0;
+ uiCurrentBank = AT91C_UDP_RX_DATA_BK0;
+
+
+ /* HARDWARE SETUP */
+
+ /* Set the PLL USB Divider */
+ AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1;
+
+ /* Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock. */
+ AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
+
+ /* Setup the PIO for the USB pull up resistor. */
+ AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA16;
+ AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16;
+
+
+ /* Start without the pullup - this will get set at the end of this
+ function. */
+ AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA16;
+
+
+ /* When using the USB debugger the peripheral registers do not always get
+ set to the correct default values. To make sure set the relevant registers
+ manually here. */
+ AT91C_BASE_UDP->UDP_IDR = (unsigned portLONG) 0xffffffff;
+ AT91C_BASE_UDP->UDP_ICR = (unsigned portLONG) 0xffffffff;
+ AT91C_BASE_UDP->UDP_CSR[0] = (unsigned portLONG) 0x00;
+ AT91C_BASE_UDP->UDP_CSR[1] = (unsigned portLONG) 0x00;
+ AT91C_BASE_UDP->UDP_CSR[2] = (unsigned portLONG) 0x00;
+ AT91C_BASE_UDP->UDP_CSR[3] = (unsigned portLONG) 0x00;
+ AT91C_BASE_UDP->UDP_GLBSTATE = 0;
+ AT91C_BASE_UDP->UDP_FADDR = 0;
+
+ /* Enable the transceiver. */
+ AT91C_UDP_TRANSCEIVER_ENABLE = 0;
+
+ /* Enable the USB interrupts - other interrupts get enabled as the
+ enumeration process progresses. */
+ AT91F_AIC_ConfigureIt (AT91C_ID_UDP, usbINTERRUPT_PRIORITY,
+ AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
+ (void (*)(void)) vUSB_ISR);
+ AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_UDP;
+
+
+ /* Wait a short while before making our presence known. */
+ vTaskDelay (usbINIT_DELAY);
+ AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA16;
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvSendControlData (unsigned portCHAR * pucData,
+ unsigned portSHORT usRequestedLength,
+ unsigned portLONG ulLengthToSend,
+ portLONG lSendingDescriptor)
+{
+ if (((unsigned portLONG) usRequestedLength < ulLengthToSend))
+ {
+ /* Cap the data length to that requested. */
+ ulLengthToSend = (unsigned portSHORT) usRequestedLength;
+ }
+ else if ((ulLengthToSend < (unsigned portLONG) usRequestedLength)
+ && lSendingDescriptor)
+ {
+ /* We are sending a descriptor. If the descriptor is an exact
+ multiple of the FIFO length then it will have to be terminated
+ with a NULL packet. Set the state to indicate this if
+ necessary. */
+ if ((ulLengthToSend % usbFIFO_LENGTH) == 0)
+ {
+ eDriverState = eSENDING_EVEN_DESCRIPTOR;
+ }
+ }
+
+ /* Here we assume that the previous message has been sent. THERE IS NO
+ BUFFER OVERFLOW PROTECTION HERE.
+
+ Copy the data to send into the buffer as we cannot send it all at once
+ (if it is greater than 8 bytes in length). */
+ memcpy (pxControlTx.ucBuffer, pucData, ulLengthToSend);
+
+ /* Reinitialise the buffer index so we start sending from the start of
+ the data. */
+ pxControlTx.ulTotalDataLength = ulLengthToSend;
+ pxControlTx.ulNextCharIndex = (unsigned portLONG) 0;
+
+ /* Send the first 8 bytes now. The rest will get sent in response to
+ TXCOMP interrupts. */
+ prvSendNextSegment ();
+}
+
+/*-----------------------------------------------------------*/
+
+static void
+prvSendNextSegment (void)
+{
+ volatile unsigned portLONG ulNextLength, ulStatus, ulLengthLeftToSend;
+
+ /* Is there any data to send? */
+ if (pxControlTx.ulTotalDataLength > pxControlTx.ulNextCharIndex)
+ {
+ ulLengthLeftToSend =
+ pxControlTx.ulTotalDataLength - pxControlTx.ulNextCharIndex;
+
+ /* We can only send 8 bytes to the fifo at a time. */
+ if (ulLengthLeftToSend > usbFIFO_LENGTH)
+ {
+ ulNextLength = usbFIFO_LENGTH;
+ }
+ else
+ {
+ ulNextLength = ulLengthLeftToSend;
+ }
+
+ /* Wait until we can place data in the fifo. THERE IS NO TIMEOUT
+ HERE! */
+ while (AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] & AT91C_UDP_TXPKTRDY)
+ {
+ vTaskDelay (usbSHORTEST_DELAY);
+ }
+
+ /* Write the data to the FIFO. */
+ while (ulNextLength > (unsigned portLONG) 0)
+ {
+ AT91C_BASE_UDP->UDP_FDR[usbEND_POINT_0] =
+ pxControlTx.ucBuffer[pxControlTx.ulNextCharIndex];
+
+ ulNextLength--;
+ pxControlTx.ulNextCharIndex++;
+ }
+
+ /* Start the transmission. */
+ portENTER_CRITICAL ();
+ {
+ ulStatus = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0];
+ usbCSR_SET_BIT (&ulStatus, ((unsigned portLONG) 0x10));
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] = ulStatus;
+ }
+ portEXIT_CRITICAL ();
+ }
+ else
+ {
+ /* There is no data to send. If we were sending a descriptor and the
+ descriptor was an exact multiple of the max packet size then we need
+ to send a null to terminate the transmission. */
+ if (eDriverState == eSENDING_EVEN_DESCRIPTOR)
+ {
+ prvSendZLP ();
+ eDriverState = eNOTHING;
+ }
+ }
+}
diff --git a/openpicc/os/usb/USB-CDC.h b/openpicc/os/usb/USB-CDC.h
new file mode 100644
index 0000000..894ebfb
--- /dev/null
+++ b/openpicc/os/usb/USB-CDC.h
@@ -0,0 +1,87 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+#ifndef USB_CDC_H
+#define USB_CDC_H
+
+#include "usb.h"
+
+#define USB_CDC_QUEUE_SIZE 1024
+
+/* Structure used to take a snapshot of the USB status from within the ISR. */
+typedef struct X_ISR_STATUS
+{
+ unsigned portLONG ulISR;
+ unsigned portLONG ulCSR0;
+ unsigned portCHAR ucFifoData[8];
+} xISRStatus;
+
+/* Structure used to hold the received requests. */
+typedef struct
+{
+ unsigned portCHAR ucReqType;
+ unsigned portCHAR ucRequest;
+ unsigned portSHORT usValue;
+ unsigned portSHORT usIndex;
+ unsigned portSHORT usLength;
+} xUSB_REQUEST;
+
+typedef enum
+{
+ eNOTHING,
+ eJUST_RESET,
+ eJUST_GOT_CONFIG,
+ eJUST_GOT_ADDRESS,
+ eSENDING_EVEN_DESCRIPTOR,
+ eREADY_TO_SEND
+} eDRIVER_STATE;
+
+/* Structure used to control the data being sent to the host. */
+typedef struct
+{
+ unsigned portCHAR ucBuffer[usbMAX_CONTROL_MESSAGE_SIZE];
+ unsigned portLONG ulNextCharIndex;
+ unsigned portLONG ulTotalDataLength;
+} xCONTROL_MESSAGE;
+
+/*-----------------------------------------------------------*/
+void vUSBCDCTask (void *pvParameters);
+
+/* Send cByte down the USB port. Characters are simply buffered and not
+sent unless the port is connected. */
+void vUSBSendByte (portCHAR cByte);
+portLONG vUSBRecvByte (portCHAR *cByte,portLONG size, portTickType xTicksToWait);
+
+#endif
diff --git a/openpicc/os/usb/USBIsr.c b/openpicc/os/usb/USBIsr.c
new file mode 100644
index 0000000..cbc5f85
--- /dev/null
+++ b/openpicc/os/usb/USBIsr.c
@@ -0,0 +1,169 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+ ***************************************************************************
+*/
+
+
+/*
+ BASIC INTERRUPT DRIVEN DRIVER FOR USB.
+
+ This file contains all the usb components that must be compiled
+ to ARM mode. The components that can be compiled to either ARM or THUMB
+ mode are contained in USB-CDC.c.
+
+*/
+
+/* Scheduler includes. */
+#include <FreeRTOS.h>
+#include <task.h>
+#include <queue.h>
+
+/* Demo application includes. */
+#include <board.h>
+#include <usb.h>
+#include <USB-CDC.h>
+
+#define usbINT_CLEAR_MASK (AT91C_UDP_TXCOMP | AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP | AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 )
+/*-----------------------------------------------------------*/
+
+/* Messages and queue used to communicate between the ISR and the USB task. */
+static xISRStatus xISRMessages[usbQUEUE_LENGTH + 1];
+extern xQueueHandle xUSBInterruptQueue;
+/*-----------------------------------------------------------*/
+
+/* The ISR can cause a context switch so is declared naked. */
+void vUSB_ISR (void) __attribute__ ((naked));
+
+/*-----------------------------------------------------------*/
+
+
+void
+vUSB_ISR (void)
+{
+ /* This ISR can cause a context switch. Therefore a call to the
+ portENTER_SWITCHING_ISR() macro is made. This must come BEFORE any
+ stack variable declarations. */
+ portENTER_SWITCHING_ISR ();
+
+ /* Now variables can be declared. */
+ portCHAR cTaskWokenByPost = pdFALSE;
+ static volatile unsigned portLONG ulNextMessage = 0;
+ xISRStatus *pxMessage;
+ unsigned portLONG ulRxBytes;
+ unsigned portCHAR ucFifoIndex;
+
+ /* Use the next message from the array. */
+ pxMessage = &(xISRMessages[(ulNextMessage & usbQUEUE_LENGTH)]);
+ ulNextMessage++;
+
+ /* Save UDP ISR state for task-level processing. */
+ pxMessage->ulISR = AT91C_BASE_UDP->UDP_ISR;
+ pxMessage->ulCSR0 = AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0];
+
+ /* Clear interrupts from ICR. */
+ AT91C_BASE_UDP->UDP_ICR = AT91C_BASE_UDP->UDP_IMR | AT91C_UDP_ENDBUSRES;
+
+
+ /* Process incoming FIFO data. Must set DIR (if needed) and clear RXSETUP
+ before exit. */
+
+ /* Read CSR and get incoming byte count. */
+ ulRxBytes = (pxMessage->ulCSR0 >> 16) & usbRX_COUNT_MASK;
+
+ /* Receive control transfers on endpoint 0. */
+ if (pxMessage->ulCSR0 & (AT91C_UDP_RXSETUP | AT91C_UDP_RX_DATA_BK0))
+ {
+ /* Save FIFO data buffer for either a SETUP or DATA stage */
+ for (ucFifoIndex = 0; ucFifoIndex < ulRxBytes; ucFifoIndex++)
+ {
+ pxMessage->ucFifoData[ucFifoIndex] =
+ AT91C_BASE_UDP->UDP_FDR[usbEND_POINT_0];
+ }
+
+ /* Set direction for data stage. Must be done before RXSETUP is
+ cleared. */
+ if ((AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] & AT91C_UDP_RXSETUP))
+ {
+ if (ulRxBytes
+ && (pxMessage->ucFifoData[usbREQUEST_TYPE_INDEX] & 0x80))
+ {
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] |= AT91C_UDP_DIR;
+
+ /* Might not be wise in an ISR! */
+ while (!
+ (AT91C_BASE_UDP->
+ UDP_CSR[usbEND_POINT_0] & AT91C_UDP_DIR));
+ }
+
+ /* Clear RXSETUP */
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] &= ~AT91C_UDP_RXSETUP;
+
+ /* Might not be wise in an ISR! */
+ while (AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] & AT91C_UDP_RXSETUP);
+ }
+ else
+ {
+ /* Clear RX_DATA_BK0 */
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] &= ~AT91C_UDP_RX_DATA_BK0;
+
+ /* Might not be wise in an ISR! */
+ while (AT91C_BASE_UDP->
+ UDP_CSR[usbEND_POINT_0] & AT91C_UDP_RX_DATA_BK0);
+ }
+ }
+
+ /* If we received data on endpoint 1, disable its interrupts until it is
+ processed in the main loop */
+ if (AT91C_BASE_UDP->
+ UDP_CSR[usbEND_POINT_1] & (AT91C_UDP_RX_DATA_BK0 |
+ AT91C_UDP_RX_DATA_BK1))
+ {
+ AT91C_BASE_UDP->UDP_IDR = AT91C_UDP_EPINT1;
+ }
+
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_0] &=
+ ~(AT91C_UDP_TXCOMP | AT91C_UDP_STALLSENT);
+
+ /* Clear interrupts for the other endpoints, retain data flags for endpoint
+ 1. */
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_1] &=
+ ~(AT91C_UDP_TXCOMP | AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP);
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] &= ~usbINT_CLEAR_MASK;
+ AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_3] &= ~usbINT_CLEAR_MASK;
+
+ /* Post ISR data to queue for task-level processing */
+ cTaskWokenByPost =
+ xQueueSendFromISR (xUSBInterruptQueue, &pxMessage, cTaskWokenByPost);
+
+ /* Clear AIC to complete ISR processing */
+ AT91C_BASE_AIC->AIC_EOICR = 0;
+
+ /* Do a task switch if needed */
+portEXIT_SWITCHING_ISR (cTaskWokenByPost)}
diff --git a/openpicc/os/usb/descriptors.h b/openpicc/os/usb/descriptors.h
new file mode 100644
index 0000000..230122f
--- /dev/null
+++ b/openpicc/os/usb/descriptors.h
@@ -0,0 +1,190 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/*
+ - DESCRIPTOR DEFINITIONS -
+*/
+
+/* String descriptors used during the enumeration process.
+These take the form:
+
+{
+ Length of descriptor,
+ Descriptor type,
+ Data
+}
+*/
+
+const portCHAR pxLanguageStringDescriptor[] = {
+ 4,
+ usbDESCRIPTOR_TYPE_STRING,
+ 0x09, 0x04
+};
+
+const portCHAR pxManufacturerStringDescriptor[] = {
+ 28,
+ usbDESCRIPTOR_TYPE_STRING,
+
+ 'b', 0x00, 'i', 0x00, 't', 0x00, 'm', 0x00,
+ 'a', 0x00, 'n', 0x00, 'u', 0x00, 'f', 0x00,
+ 'a', 0x00, 'k', 0x00, 't', 0x00, 'u', 0x00,
+ 'r', 0x00
+};
+
+const portCHAR pxProductStringDescriptor[] = {
+ 44,
+ usbDESCRIPTOR_TYPE_STRING,
+
+ 'O', 0x00, 'p', 0x00, 'e', 0x00, 'n', 0x00,
+ 'B', 0x00, 'e', 0x00, 'a', 0x00, 'c', 0x00,
+ 'o', 0x00, 'n', 0x00, ' ', 0x00, 'U', 0x00,
+ 'S', 0x00, 'B', 0x00, ' ', 0x00, '2', 0x00,
+ '.', 0x00, '4', 0x00, 'G', 0x00, 'H', 0x00,
+ 'z', 0x00
+};
+
+/* Device should properly be 0x134A:0x9001, using 0x05F9:0xFFFF for Linux testing */
+const char pxDeviceDescriptor[] = {
+ /* Device descriptor */
+ 0x12, /* bLength */
+ 0x01, /* bDescriptorType */
+ 0x10, 0x01, /* bcdUSBL */
+ 0x02, /* bDeviceClass: */
+ 0x00, /* bDeviceSubclass: */
+ 0x00, /* bDeviceProtocol: */
+ 0x08, /* bMaxPacketSize0 */
+ 0xC0, 0x16, /* idVendorL */
+ 0xAC, 0x08, /* idProductL */
+ 0x10, 0x01, /* bcdDeviceL */
+ usbMANUFACTURER_STRING, /* iManufacturer */
+ usbPRODUCT_STRING, /* iProduct */
+ 0x00, /* SerialNumber */
+ 0x01 /* bNumConfigs */
+};
+
+const char pxConfigDescriptor[] = {
+
+ /* Configuration 1 descriptor
+ Here we define two interfaces (0 and 1) and a total of 3 endpoints.
+ Interface 0 is a CDC Abstract Control Model interface with one interrupt-in endpoint.
+ Interface 1 is a CDC Data Interface class, with a bulk-in and bulk-out endpoint.
+ Endpoint 0 gets used as the CDC management element.
+ */
+ 0x09, /* CbLength */
+ 0x02, /* CbDescriptorType */
+ 0x43, 0x00, /* CwTotalLength 2 EP + Control ? */
+ 0x02, /* CbNumInterfaces */
+ 0x01, /* CbConfigurationValue */
+ 0x00, /* CiConfiguration */
+ usbBUS_POWERED, /* CbmAttributes Bus powered + Remote Wakeup */
+ 0x32, /* CMaxPower: 100mA */
+
+ /* Communication Class Interface Descriptor Requirement */
+ 0x09, /* bLength */
+ 0x04, /* bDescriptorType */
+ 0x00, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x01, /* bNumEndpoints */
+ 0x02, /* bInterfaceClass: Comm Interface Class */
+ 0x02, /* bInterfaceSubclass: Abstract Control Model */
+ 0x01, /* bInterfaceProtocol */
+ usbINTERFACE_STRING, /* iInterface */
+
+ /* Header Functional Descriptor */
+ 0x05, /* bLength */
+ 0x24, /* bDescriptor type: CS_INTERFACE */
+ 0x00, /* bDescriptor subtype: Header Func Desc */
+ 0x10, 0x01, /* bcdCDC:1.1 */
+
+ /* ACM Functional Descriptor */
+ 0x04, /* bFunctionLength */
+ 0x24, /* bDescriptor type: CS_INTERFACE */
+ 0x02, /* bDescriptor subtype: ACM Func Desc */
+ 0x00, /* bmCapabilities: We don't support squat */
+
+ /* Union Functional Descriptor */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptor type: CS_INTERFACE */
+ 0x06, /* bDescriptor subtype: Union Func Desc */
+ 0x00, /* bMasterInterface: CDC Interface */
+ 0x01, /* bSlaveInterface0: Data Class Interface */
+
+ /* Call Management Functional Descriptor
+ 0 in D1 and D0 indicates that device does not handle call management */
+ 0x05, /* bFunctionLength */
+ 0x24, /* bDescriptor type: CS_INTERFACE */
+ 0x01, /* bDescriptor subtype: Call Management Func */
+ 0x00, /* bmCapabilities: D1 + D0 */
+ 0x01, /* bDataInterface: Data Class Interface 1 */
+
+ /* CDC Control - Endpoint 3 descriptor
+ This endpoint serves as a notification element. */
+
+ 0x07, /* bLength */
+ 0x05, /* bDescriptorType */
+ 0x83, /* bEndpointAddress, Endpoint 03 - IN */
+ 0x03, /* bmAttributes INT */
+ 0x08, 0x00, /* wMaxPacketSize: 8 bytes */
+ 0xFF, /* bInterval */
+
+ /* Data Class Interface Descriptor Requirement */
+ 0x09, /* bLength */
+ 0x04, /* bDescriptorType */
+ 0x01, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x02, /* bNumEndPoints */
+ 0x0A, /* bInterfaceClass */
+ 0x00, /* bInterfaceSubclass */
+ 0x00, /* bInterfaceProtocol */
+ 0x00, /* iInterface */
+
+ /* CDC Data - Endpoint 1 descriptor */
+ 0x07, /* bLenght */
+ 0x05, /* bDescriptorType */
+ 0x01, /* bEndPointAddress, Endpoint 01 - OUT */
+ 0x02, /* bmAttributes BULK */
+ 64, /* wMaxPacketSize */
+ 0x00,
+ 0x00, /* bInterval */
+
+ /* CDC Data - Endpoint 2 descriptor */
+ 0x07, /* bLength */
+ 0x05, /* bDescriptorType */
+ 0x82, /* bEndPointAddress, Endpoint 02 - IN */
+ 0x02, /* bmAttributes BULK */
+ 64, /* wMaxPacketSize */
+ 0x00,
+ 0x00 /* bInterval */
+};
diff --git a/openpicc/os/usb/usb.h b/openpicc/os/usb/usb.h
new file mode 100644
index 0000000..86d98f9
--- /dev/null
+++ b/openpicc/os/usb/usb.h
@@ -0,0 +1,146 @@
+/*
+ FreeRTOS.org V4.2.1 - Copyright (C) 2003-2007 Richard Barry.
+
+ This file is part of the FreeRTOS.org distribution.
+
+ FreeRTOS.org is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ FreeRTOS.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with FreeRTOS.org; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes FreeRTOS.org, without being obliged to provide
+ the source code for any proprietary components. See the licensing section
+ of http://www.FreeRTOS.org for full details of how and when the exception
+ can be applied.
+
+ ***************************************************************************
+ See http://www.FreeRTOS.org for documentation, latest information, license
+ and contact details. Please ensure to read the configuration and relevant
+ port sections of the online documentation.
+
+ Also see http://www.SafeRTOS.com for an IEC 61508 compliant version along
+ with commercial development and support options.
+ ***************************************************************************
+*/
+
+/* Descriptor type definitions. */
+#define usbDESCRIPTOR_TYPE_DEVICE ( 0x01 )
+#define usbDESCRIPTOR_TYPE_CONFIGURATION ( 0x02 )
+#define usbDESCRIPTOR_TYPE_STRING ( 0x03 )
+
+/* USB request type definitions. */
+#define usbGET_REPORT_REQUEST ( 0x01 )
+#define usbGET_IDLE_REQUEST ( 0x02 )
+#define usbGET_PROTOCOL_REQUEST ( 0x03 )
+#define usbSET_REPORT_REQUEST ( 0x09 )
+#define usbSET_IDLE_REQUEST ( 0x0A )
+#define usbSET_PROTOCOL_REQUEST ( 0x0B )
+#define usbGET_CONFIGURATION_REQUEST ( 0x08 )
+#define usbGET_STATUS_REQUEST ( 0x00 )
+#define usbCLEAR_FEATURE_REQUEST ( 0x01 )
+#define usbSET_FEATURE_REQUEST ( 0x03 )
+#define usbSET_ADDRESS_REQUEST ( 0x05 )
+#define usbGET_DESCRIPTOR_REQUEST ( 0x06 )
+#define usbSET_CONFIGURATION_REQUEST ( 0x09 )
+#define usbGET_INTERFACE_REQUEST ( 0x0A )
+#define usbSET_INTERFACE_REQUEST ( 0x0B )
+
+/* ACM Requests */
+#define usbSEND_ENCAPSULATED_COMMAND ( 0x00 )
+#define usbGET_ENCAPSULATED_RESPONSE ( 0x01 )
+#define usbSET_LINE_CODING ( 0x20 )
+#define usbGET_LINE_CODING ( 0x21 )
+#define usbSET_CONTROL_LINE_STATE ( 0x22 )
+
+/* Misc USB definitions. */
+#define usbDEVICE_CLASS_VENDOR_SPECIFIC ( 0xFF )
+#define usbBUS_POWERED ( 0x80 )
+#define usbHID_REPORT_DESCRIPTOR ( 0x22 )
+#define AT91C_UDP_TRANSCEIVER_ENABLE ( *( ( unsigned long * ) 0xfffb0074 ) )
+
+/* Index to the various string. */
+#define usbLANGUAGE_STRING ( 0 )
+#define usbMANUFACTURER_STRING ( 1 )
+#define usbPRODUCT_STRING ( 2 )
+#define usbCONFIGURATION_STRING ( 3 )
+#define usbINTERFACE_STRING ( 4 )
+
+/* Defines fields of standard SETUP request. Now in normal order. */
+#define usbREQUEST_TYPE_INDEX ( 0 )
+#define usbREQUEST_INDEX ( 1 )
+#define usbVALUE_HIGH_BYTE ( 3 )
+#define usbVALUE_LOW_BYTE ( 2 )
+#define usbINDEX_HIGH_BYTE ( 5 )
+#define usbINDEX_LOW_BYTE ( 4 )
+#define usbLENGTH_HIGH_BYTE ( 7 )
+#define usbLENGTH_LOW_BYTE ( 6 )
+
+/* Misc application definitions. */
+#define usbINTERRUPT_PRIORITY ( 3 )
+#define usbQUEUE_LENGTH ( 0x3 ) /* Must have all bits set! */
+#define usbFIFO_LENGTH ( ( unsigned portLONG ) 8 )
+#define usbEND_POINT_0 ( 0 )
+#define usbEND_POINT_1 ( 1 )
+#define usbEND_POINT_2 ( 2 )
+#define usbEND_POINT_3 ( 3 )
+#define usbMAX_CONTROL_MESSAGE_SIZE ( 128 )
+#define usbRX_COUNT_MASK ( ( unsigned portLONG ) 0x7ff )
+#define usbSHORTEST_DELAY ( ( portTickType ) 1 )
+#define usbINIT_DELAY ( ( portTickType ) 1000 / portTICK_RATE_MS )
+#define usbSHORT_DELAY ( ( portTickType ) 50 / portTICK_RATE_MS )
+#define usbEND_POINT_RESET_MASK ( ( unsigned portLONG ) 0x0f )
+#define usbDATA_INC ( ( portCHAR ) 5 )
+#define usbEXPECTED_NUMBER_OF_BYTES ( ( unsigned portLONG ) 8 )
+
+/* Control request types. */
+#define usbSTANDARD_DEVICE_REQUEST ( 0 )
+#define usbSTANDARD_INTERFACE_REQUEST ( 1 )
+#define usbSTANDARD_END_POINT_REQUEST ( 2 )
+#define usbCLASS_INTERFACE_REQUEST ( 5 )
+
+
+/* Macros to manipulate the control and status registers. These registers
+cannot be accessed using a direct read modify write operation outside of the
+ISR as some bits are left unchanged by writing with a 0, and some are left
+unchanged by writing with a 1. */
+
+
+#define usbCSR_SET_BIT( pulValueNow, ulBit ) \
+{ \
+ /* Set TXCOMP, RX_DATA_BK0, RXSETUP, */ \
+ /* STALLSENT and RX_DATA_BK1 to 1 so the */ \
+ /* write has no effect. */ \
+ ( * ( ( unsigned portLONG * ) pulValueNow ) ) |= ( unsigned portLONG ) 0x4f; \
+ \
+ /* Clear the FORCE_STALL and TXPKTRDY bits */ \
+ /* so the write has no effect. */ \
+ ( * ( ( unsigned portLONG * ) pulValueNow ) ) &= ( unsigned portLONG ) 0xffffffcf; \
+ \
+ /* Set whichever bit we want set. */ \
+ ( * ( ( unsigned portLONG * ) pulValueNow ) ) |= ( ulBit ); \
+}
+
+#define usbCSR_CLEAR_BIT( pulValueNow, ulBit ) \
+{ \
+ /* Set TXCOMP, RX_DATA_BK0, RXSETUP, */ \
+ /* STALLSENT and RX_DATA_BK1 to 1 so the */ \
+ /* write has no effect. */ \
+ ( * ( ( unsigned portLONG * ) pulValueNow ) ) |= ( unsigned portLONG ) 0x4f; \
+ \
+ /* Clear the FORCE_STALL and TXPKTRDY bits */ \
+ /* so the write has no effect. */ \
+ ( * ( ( unsigned portLONG * ) pulValueNow ) ) &= ( unsigned portLONG ) 0xffffffcf; \
+ \
+ /* Clear whichever bit we want clear. */ \
+ ( * ( ( unsigned portLONG * ) pulValueNow ) ) &= ( ~ulBit ); \
+}
personal git repositories of Harald Welte. Your mileage may vary