From 10477061970655e8ae9c01a28ac9734aff7cfd41 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Sun, 3 Feb 2008 21:41:39 +0100 Subject: [PATCH] first commit --- .gitignore | 1 + Makefile | 75 ++ at91_init0.s | 244 +++++ at91_init1.c | 81 ++ include/AT91SAM7S256.h | 1918 ++++++++++++++++++++++++++++++++++++++++ include/at91_dbgu.h | 12 + include/at91_pio.h | 20 + include/at91_pitc.h | 25 + include/at91_sysc.h | 22 + include/at91_tc1.h | 14 + include/at91_tests.h | 9 + include/at91_twi.h | 57 ++ include/at91_udp.h | 6 + include/atomic.h | 26 + include/board.h | 43 + include/fifo.h | 28 + include/list.h | 268 ++++++ include/static_alloc.h | 9 + include/usb_cdc.h | 240 +++++ include/usb_ch9.h | 553 ++++++++++++ include/usb_dfu.h | 73 ++ ldscript.ld | 81 ++ main.c | 98 ++ scripts/download.sh | 19 + scripts/gdb-thumb.cfg | 23 + scripts/gdb.cfg | 23 + scripts/openocd.cfg | 16 + src/at91_adc.c | 99 +++ src/at91_dbgu.c | 90 ++ src/at91_exceptions.c | 162 ++++ src/at91_pio.c | 69 ++ src/at91_pitc.c | 90 ++ src/at91_rttc_test.c | 34 + src/at91_sysc.c | 154 ++++ src/at91_tc1.c | 110 +++ src/at91_twi.c | 241 +++++ src/at91_udp.c | 520 +++++++++++ src/fifo.c | 192 ++++ src/static_alloc.c | 60 ++ src/stdio/_putf.c | 286 ++++++ src/stdio/_putf.h | 6 + src/stdio/printf.c | 61 ++ 42 files changed, 6158 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 at91_init0.s create mode 100644 at91_init1.c create mode 100644 include/AT91SAM7S256.h create mode 100644 include/at91_dbgu.h create mode 100644 include/at91_pio.h create mode 100644 include/at91_pitc.h create mode 100644 include/at91_sysc.h create mode 100644 include/at91_tc1.h create mode 100644 include/at91_tests.h create mode 100644 include/at91_twi.h create mode 100644 include/at91_udp.h create mode 100644 include/atomic.h create mode 100644 include/board.h create mode 100644 include/fifo.h create mode 100644 include/list.h create mode 100644 include/static_alloc.h create mode 100644 include/usb_cdc.h create mode 100644 include/usb_ch9.h create mode 100644 include/usb_dfu.h create mode 100644 ldscript.ld create mode 100644 main.c create mode 100755 scripts/download.sh create mode 100644 scripts/gdb-thumb.cfg create mode 100644 scripts/gdb.cfg create mode 100644 scripts/openocd.cfg create mode 100644 src/at91_adc.c create mode 100644 src/at91_dbgu.c create mode 100644 src/at91_exceptions.c create mode 100644 src/at91_pio.c create mode 100644 src/at91_pitc.c create mode 100644 src/at91_rttc_test.c create mode 100644 src/at91_sysc.c create mode 100644 src/at91_tc1.c create mode 100644 src/at91_twi.c create mode 100644 src/at91_udp.c create mode 100644 src/fifo.c create mode 100644 src/static_alloc.c create mode 100644 src/stdio/_putf.c create mode 100644 src/stdio/_putf.h create mode 100644 src/stdio/printf.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..76c9543 --- /dev/null +++ b/Makefile @@ -0,0 +1,75 @@ +TOOLCHAIN = /opt/arm-toolchain + +OPENOCD = /opt/arm-toolchain/openocd + +AS = $(TOOLCHAIN)/bin/arm-elf-as +CC = $(TOOLCHAIN)/bin/arm-elf-gcc +LD = $(TOOLCHAIN)/bin/arm-elf-ld +NM = $(TOOLCHAIN)/bin/arm-elf-nm +SIZE = $(TOOLCHAIN)/bin/arm-elf-size +OBJCOPY = $(TOOLCHAIN)/bin/arm-elf-objcopy +OBJDUMP = $(TOOLCHAIN)/bin/arm-elf-objdump + +INCDIRS = include $(TOOLCHAIN)/lib/gcc/arm-elf/4.1.1/include $(TOOLCHAIN)/arm-elf/include +LIBDIRS = $(TOOLCHAIN)/arm-elf/lib $(TOOLCHAIN)/lib/gcc/arm-elf/4.1.1 + +# ------ + +BUILD = build +TARGET = sam7fc + +ASFLAGS = -mcpu=arm7tdmi -Wa,-adhlns=$(BUILD)/$(*D)/$(*F).lst,--gdwarf-2 -Iinclude + +CFLAGS = -gdwarf-2 -mcpu=arm7tdmi -Os -std=gnu99 +CFLAGS += -Wa,-adhlns=$(BUILD)/$(*D)/$(*F).lst +CFLAGS += -nostdinc $(patsubst %,-I%,$(INCDIRS)) +CFLAGS += -MD -MP -MF $(BUILD)/.dep/$(*F).d + +CFLAGS += -Wall +#CFLAGS += -Wextra +#CFLAGS += -Wcast-align -Wimplicit -Wunused +#CFLAGS += -Wpointer-arith -Wswitch +#CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow +#CFLAGS += -Wbad-function-cast -Wsign-compare -Waggregate-return +#CFLAGS += -Wcast-qual -Wnested-externs +#CFLAGS += -Wmissing-prototypes +#CFLAGS += -Wstrict-prototypes -Wmissing-declarations + +LDFLAGS = -nostartfiles -t ldscript.ld -Wl,-Map=$@.map,--cref +LDFLAGS += $(patsubst %,-L%,$(LIBDIRS)) +LDFLAGS += -lc -lgcc + +# ------ + +SRC := $(wildcard *.c) $(wildcard src/*.c) $(wildcard src/*/*.c) +AS_SRC := $(wildcard *.s) $(wildcard src/*.s) + +all: $(BUILD)/$(TARGET).elf + @$(SIZE) -x $< + +$(BUILD)/$(TARGET).elf: $(patsubst %,$(BUILD)/%,$(AS_SRC:.s=.o) $(SRC:.c=.o)) + @echo " Linking file: $@" + @$(shell mkdir -p $(BUILD)/$(*D)) + @$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) + @$(OBJCOPY) -O binary $@ $@.bin + @$(OBJCOPY) -O ihex $@ $@.hex + @$(OBJDUMP) -h -S -C $@ > $@.lss + @$(NM) -n $@ > $@.sym + +$(BUILD)/%.o: %.c + @echo " Building file: $<" + @$(shell mkdir -p $(BUILD)/$(*D)) + @$(CC) -c $(CFLAGS) $< -o $@ + +$(BUILD)/%.o: %.s + @echo " Building file: $<" + @$(shell mkdir -p $(BUILD)/$(*D)) + @$(CC) -c $(ASFLAGS) $< -o $@ + +clean: + rm -rf $(BUILD) + +openocd: + $(shell $(OPENOCD) -f scripts/openocd.cfg) + +-include $(shell mkdir -p $(BUILD)/.dep 2> /dev/null) $(wildcard $(BUILD)/.dep/*.d) diff --git a/at91_init0.s b/at91_init0.s new file mode 100644 index 0000000..583bc28 --- /dev/null +++ b/at91_init0.s @@ -0,0 +1,244 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ + .equ AIC_IVR, (256) + .equ AIC_FVR, (260) + .equ AIC_EOICR, (304) + .equ AT91C_BASE_AIC, (0xFFFFF000) + + .equ IRQ_Stack_Size, (3 * 8 * 4) + .equ FIQ_Stack_Size, (3 * 8 * 4) + .equ ABT_Stack_Size, 192 + + .equ ARM_MODE_FIQ, 0x11 + .equ ARM_MODE_IRQ, 0x12 + .equ ARM_MODE_SVC, 0x13 + .equ ARM_MODE_ABT, 0x17 + + .equ I_BIT, 0x80 + .equ F_BIT, 0x40 + + .section .text + .global _start + .func _start + +_start: ldr pc, [pc, #24] /* 0x00 Reset handler */ +undefvec: ldr pc, [pc, #24] /* 0x04 Undefined Instruction */ +swivec: ldr pc, [pc, #24] /* 0x08 Software Interrupt */ +pabtvec: ldr pc, [pc, #24] /* 0x0C Prefetch Abort */ +dabtvec: ldr pc, [pc, #24] /* 0x10 Data Abort */ +rsvdvec: ldr pc, [pc, #24] /* 0x14 reserved */ +irqvec: ldr pc, [pc, #24] /* 0x18 IRQ */ +fiqvec: ldr pc, [pc, #24] /* 0x1c FIQ */ + + /* 0x80000000 will result in Prefetch Abort */ + .word InitReset + .word 0x80000000 + .word 0x80000000 + .word ABT_Handler_Entry + .word ABT_Handler_Entry + .word 0x80000000 + .word IRQ_Handler_Entry + .word FIQ_Handler_Entry + + .endfunc + + .global InitReset + .func InitReset + +InitReset: + .extern at91_init1 + /* Call Low level init function */ + ldr sp,=__stack_top__ + ldr r0,=at91_init1 + mov lr, pc + bx r0 + mov r0, sp + + /* Setup FIQ Mode Stack */ + msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT + mov sp, r0 + sub r0, r0, #FIQ_Stack_Size + + /* store AIC Base in ARM_MODE_FIQ:r8 for faster access */ + ldr r8, =AT91C_BASE_AIC + + /* Setup IRQ Mode Stack */ + msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT + mov sp, r0 + sub r0, r0, #IRQ_Stack_Size + + /* Setup Abort Mode Stack */ + msr CPSR_c, #ARM_MODE_ABT | I_BIT | F_BIT + mov sp, r0 + sub r0, r0, #ABT_Stack_Size + + /* Setup Supervisor Mode Stack (IRQ & NMI enabled) */ + msr CPSR_c, #ARM_MODE_SVC + mov sp, r0 + + /* Relocate .data section */ + ldr r1, =__text_end__ + ldr r2, =__data_start__ + ldr r3, =__data_end__ +LoopRel: cmp r2, r3 + ldrlo r0, [r1], #4 + strlo r0, [r2], #4 + blo LoopRel + + /* Clear .bss section */ + mov r0, #0 + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ +LoopZI: cmp r1, r2 + strlo r0, [r1], #4 + BLO LoopZI + + /* Start main() */ + ldr lr,=exit + ldr r0,=main + bx r0 + + .endfunc + + .global exit + .func exit + /* exit dummy for newlib */ +exit: b . + .endfunc + + .global ABT_Handler_Entry + .func ABT_Handler_Entry +ABT_Handler_Entry: + /* disable interrupts (F_BIT not set on entry) */ + msr CPSR_c, #ARM_MODE_ABT | I_BIT | F_BIT + + /* store all registers */ + stmfd sp!, { r0-r12 } + + /* saved cpsr (from aborted mode) */ + mrs r0, SPSR + + /* address of abort (pc) */ + mov r3, lr + + /* enter previous mode and get lr(r14), sp(r13) */ + /* TODO: interrupts might be enabled? */ + /* TODO: thumb mode enabled? */ + msr CPSR_c, r0 + mov r1, sp + mov r2, lr + + /* return to abort mode */ + msr CPSR_c, #ARM_MODE_ABT | I_BIT | F_BIT + + /* store remaining registers (r1-r3 == r13-r15) */ + stmfd sp!, { r1-r3 } + mov r1, sp + + /* execute C Handler (cpsr, registers) */ + ldr r5,=at91_abt_handler + mov lr, pc + bx r5 + b . + .endfunc + + .global FIQ_Handler_Entry + .func FIQ_Handler_Entry +FIQ_Handler_Entry: + /* Save r0 to ARM_MODE_FIQ:r9 */ + mov r9,r0 + + /* get FIQ Vector from AIC and thus clear FIQ */ + ldr r0 , [r8, #AIC_FVR] + + /* Switch to ARM_MODE_SVC and save registers there */ + msr CPSR_c,#ARM_MODE_SVC | I_BIT | F_BIT + stmfd sp!, { r1-r3, r12, lr} + + /* execute FIQ in SVC_MODE */ + mov r14, pc + bx r0 + + /* restore registers and switch back to ARM_MODE_FIQ */ + ldmia sp!, { r1-r3, r12, lr} + msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT + + /* restore the ARM_MODE_SVC:r0 */ + mov r0,r9 + + /* restore PC using the LR_fiq directly */ + subs pc,lr,#4 + + .endfunc + + + .global IRQ_Handler_Entry + .func IRQ_Handler_Entry +IRQ_Handler_Entry: +/*- Manage Exception Entry */ +/*- Adjust and save LR_irq in IRQ stack */ + sub lr, lr, #4 + stmfd sp!, {lr} + +/*- Save SPSR need to be saved for nested interrupt */ + mrs r14, SPSR + stmfd sp!, {r14} + +/*- Save and r0 in IRQ stack */ + stmfd sp!, {r0} + +/*- Write in the IVR to support Protect Mode */ +/*- No effect in Normal Mode */ +/*- De-assert the NIRQ and clear the source in Protect Mode */ + ldr r14, =AT91C_BASE_AIC + ldr r0 , [r14, #AIC_IVR] + str r14, [r14, #AIC_IVR] + +/*- Enable Interrupt and Switch in Supervisor Mode */ + msr CPSR_c, #ARM_MODE_SVC + +/*- Save scratch/used registers and LR in User Stack */ + stmfd sp!, { r1-r3, r12, r14} + +/*- Branch to the routine pointed by the AIC_IVR */ + mov r14, pc + bx r0 +/*- Restore scratch/used registers and LR from User Stack*/ + ldmia sp!, { r1-r3, r12, r14} + +/*- Disable Interrupt and switch back in IRQ mode */ + msr CPSR_c, #ARM_MODE_IRQ | I_BIT + +/*- Mark the End of Interrupt on the AIC */ + ldr r14, =AT91C_BASE_AIC + str r14, [r14, #AIC_EOICR] + +/*- Restore SPSR_irq and r0 from IRQ stack */ + ldmia sp!, {r0} + +/*- Restore SPSR_irq and r0 from IRQ stack */ + ldmia sp!, {r14} + msr SPSR_cxsf, r14 + +/*- Restore adjusted LR_irq from IRQ stack directly in the PC */ + ldmia sp!, {pc}^ + + .endfunc + + .end diff --git a/at91_init1.c b/at91_init1.c new file mode 100644 index 0000000..32e5f72 --- /dev/null +++ b/at91_init1.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include +#include "AT91SAM7S256.h" + +static void empty_isr(void) {} + +/* + * Init critical onchip hardware: + * - disable Watchdog + * - enable Oscillator and PLL, switch to 48MHz MCK + * - set empty Interrupt Handlers + */ +void at91_init1(void) +{ + /* disable watchdog */ + *AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS; + + /* enable user reset */ + *AT91C_RSTC_RMR = (AT91C_RSTC_KEY & 0xA5 << 24) | AT91C_RSTC_URSTEN; + + /* Set Flash Waitstates */ + *AT91C_MC_FMR = AT91C_MC_FWS_1FWS; + + /* + * Enable main oscillator (MAINCK) + * startup time: 8*6/32768 -> 1.46ms + */ + AT91S_PMC *pmc = AT91C_BASE_PMC; + pmc->PMC_MOR = (AT91C_CKGR_OSCOUNT & (6<<8)) | + AT91C_CKGR_MOSCEN; + while (!(pmc->PMC_SR & AT91C_PMC_MOSCS)); + + /* + * PLLCK = 18.432MHz / 24 * 125 = 96MHz -> div:24, mul:124 + * startup time: 32/32768 -> 976us + */ + pmc->PMC_PLLR = (AT91C_CKGR_DIV & 24) | + (AT91C_CKGR_MUL & (124<<16)) | + (AT91C_CKGR_PLLCOUNT & (32<<8)) ; + while (!(pmc->PMC_SR & AT91C_PMC_LOCK)); + + /* MCK = PLLCK / 2 = 48MHz */ + pmc->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | + AT91C_PMC_PRES_CLK_2; + while (!(pmc->PMC_SR & AT91C_PMC_MCKRDY)); + + /* enable protected mode (let AIC work with debugger) */ + AT91S_AIC *aic = AT91C_BASE_AIC; + aic->AIC_DCR = AT91C_AIC_DCR_PROT; + + /* Disable & clear all Interrupts */ + aic->AIC_IDCR = ~0; + aic->AIC_ICCR = ~0; + + /* default Interrupt Handlers just return */ + aic->AIC_FVR = (uint32_t)empty_isr; + aic->AIC_IVR = (uint32_t)empty_isr; + uint32_t i; + for (i = 0; i < 32; i++) { + aic->AIC_SMR[i] = 0; + aic->AIC_SVR[i] = (uint32_t)empty_isr; + } + aic->AIC_SPU = (uint32_t)empty_isr; +} diff --git a/include/AT91SAM7S256.h b/include/AT91SAM7S256.h new file mode 100644 index 0000000..8949920 --- /dev/null +++ b/include/AT91SAM7S256.h @@ -0,0 +1,1918 @@ +// ---------------------------------------------------------------------------- +// 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 : AT91SAM7S256.h +// Object : AT91SAM7S256 definitions +// Generated : AT91 SW Application Group 08/18/2006 (15:29:25) +// +// CVS Reference : /AT91SAM7S256.pl/1.11/Tue Aug 30 12:14:57 2005// +// CVS Reference : /SYS_SAM7S.pl/1.2/Thu Feb 3 10:47:39 2005// +// CVS Reference : /MC_SAM7S.pl/1.4/Thu Feb 16 16:45:50 2006// +// CVS Reference : /PMC_SAM7S_USB.pl/1.4/Tue Feb 8 14:00:19 2005// +// CVS Reference : /RSTC_SAM7S.pl/1.2/Wed Jul 13 15:25:17 2005// +// CVS Reference : /UDP_SAM7S.pl/1.3/Thu Aug 3 12:26:00 2006// +// CVS Reference : /PWM_SAM7S.pl/1.1/Tue May 10 12:38:54 2005// +// CVS Reference : /RTTC_6081A.pl/1.2/Thu Nov 4 13:57:22 2004// +// CVS Reference : /PITC_6079A.pl/1.2/Thu Nov 4 13:56:22 2004// +// CVS Reference : /WDTC_6080A.pl/1.3/Thu Nov 4 13:58:52 2004// +// CVS Reference : /VREG_6085B.pl/1.1/Tue Feb 1 16:40:38 2005// +// CVS Reference : /AIC_6075B.pl/1.3/Fri May 20 14:21:42 2005// +// CVS Reference : /PIO_6057A.pl/1.2/Thu Feb 3 10:29:42 2005// +// CVS Reference : /DBGU_6059D.pl/1.1/Mon Jan 31 13:54:41 2005// +// CVS Reference : /US_6089C.pl/1.1/Mon Jan 31 13:56:02 2005// +// CVS Reference : /SPI_6088D.pl/1.3/Fri May 20 14:23:02 2005// +// CVS Reference : /SSC_6078A.pl/1.1/Tue Jul 13 07:10:41 2004// +// CVS Reference : /TC_6082A.pl/1.7/Wed Mar 9 16:31:51 2005// +// CVS Reference : /TWI_6061A.pl/1.1/Tue Jul 13 06:38:23 2004// +// CVS Reference : /PDC_6074C.pl/1.2/Thu Feb 3 09:02:11 2005// +// CVS Reference : /ADC_6051C.pl/1.1/Mon Jan 31 13:12:40 2005// +// ---------------------------------------------------------------------------- + +#ifndef AT91SAM7S256_H +#define AT91SAM7S256_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 Reserved2[2]; // + 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_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_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 0 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, bulk, interrupt 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 AT91SAM7S256 +// ***************************************************************************** +// ========== 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 AT91SAM7S256 +// ***************************************************************************** +#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 AT91SAM7S256 +// ***************************************************************************** +#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_3_Reserved ((unsigned int) 3) // Reserved +#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 AT91SAM7S256 +// ***************************************************************************** +#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 AT91SAM7S256 +// ***************************************************************************** +// ISRAM +#define AT91C_ISRAM ((char *) 0x00200000) // Internal SRAM base address +#define AT91C_ISRAM_SIZE ((unsigned int) 0x00010000) // Internal SRAM size in byte (64 Kbytes) +// IFLASH +#define AT91C_IFLASH ((char *) 0x00100000) // Internal FLASH base address +#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_LOCK_REGION_SIZE ((unsigned int) 16384) // Internal FLASH Lock Region Size: 16 Kbytes +#define AT91C_IFLASH_NB_OF_PAGES ((unsigned int) 1024) // Internal FLASH Number of Pages: 1024 bytes +#define AT91C_IFLASH_NB_OF_LOCK_BITS ((unsigned int) 16) // Internal FLASH Number of Lock Bits: 16 bytes + +#endif diff --git a/include/at91_dbgu.h b/include/at91_dbgu.h new file mode 100644 index 0000000..985f366 --- /dev/null +++ b/include/at91_dbgu.h @@ -0,0 +1,12 @@ +#ifndef AT91_DBGU_H_ +#define AT91_DBGU_H_ + +#include + +void at91_dbgu_init(void); + +void at91_dbgu_putc(char c); +void at91_dbgu_puts(const char *p); +int at91_dbgu_write(void *base, const char *buf, size_t len); + +#endif /*AT91_DBGU_H_*/ diff --git a/include/at91_pio.h b/include/at91_pio.h new file mode 100644 index 0000000..d7c405f --- /dev/null +++ b/include/at91_pio.h @@ -0,0 +1,20 @@ +#ifndef AT91_PIO_H_ +#define AT91_PIO_H_ + +#include + +struct pio_pinchange_isr { + uint32_t mask; + void (*func)(uint32_t status, uint32_t input); +}; + +#define PIO_PINCHANGE_ISR(mask, func) \ + static struct pio_pinchange_isr \ + __attribute__((used, section(".pio_isr"))) \ + pio_isr_##func = { mask, &func }; + + +void pio_trigger_isr(uint32_t mask); +void at91_pio_init(void); + +#endif /*AT91_PIO_H_*/ diff --git a/include/at91_pitc.h b/include/at91_pitc.h new file mode 100644 index 0000000..2763d3f --- /dev/null +++ b/include/at91_pitc.h @@ -0,0 +1,25 @@ +#ifndef AT91_PITC_H_ +#define AT91_PITC_H_ + +#include +#include +#include "list.h" + +#define PITC_RESTART_TIMER 0 +#define PITC_REMOVE_TIMER 1 + +struct pitc_timer { + struct list_head list; + uint32_t interval; + uint32_t nextrun; + uint32_t (*func)(struct pitc_timer *); + void *privdata; +}; + +void pitc_schedule_timer(struct pitc_timer *timer); +struct pitc_timer * alloc_pitc_timer(uint32_t interval, uint32_t (*func)(struct pitc_timer *), void *privdata); + +uint32_t pitc_get_ticks(void); +void at91_pitc_init(void); + +#endif /*AT91_PITC_H_*/ diff --git a/include/at91_sysc.h b/include/at91_sysc.h new file mode 100644 index 0000000..af08156 --- /dev/null +++ b/include/at91_sysc.h @@ -0,0 +1,22 @@ +#ifndef AT91_SYSC_H_ +#define AT91_SYSC_H_ + +#include + +enum syscirqs { + AT91_SYSIRQ_PIT = 0, + AT91_SYSIRQ_DBGU = 1, + AT91_SYSIRQ_EFC = 2, + AT91_SYSIRQ_WDT = 3, + AT91_SYSIRQ_RTT = 4, + AT91_SYSIRQ_RSTC = 5, + AT91_SYSIRQ_PMC = 6, + AT91_SYSIRQ_COUNT +}; + +typedef void SYSCISR(uint32_t status); + +void at91_sysc_init(void); +void sysc_register_isr(enum syscirqs irq, SYSCISR *isr); + +#endif /*AT91_SYSC_H_*/ diff --git a/include/at91_tc1.h b/include/at91_tc1.h new file mode 100644 index 0000000..ed5388c --- /dev/null +++ b/include/at91_tc1.h @@ -0,0 +1,14 @@ +#ifndef RC_PPM_H_ +#define RC_PPM_H_ + +#define MAX_CHANNELS 8 + +struct rc_values { + int16_t ch[MAX_CHANNELS]; + uint32_t count; +}; + +void at91_tc1_init(void); +uint32_t rc_ppm_getvalues(struct rc_values *rc); + +#endif /*RC_PPM_H_*/ diff --git a/include/at91_tests.h b/include/at91_tests.h new file mode 100644 index 0000000..fad3d49 --- /dev/null +++ b/include/at91_tests.h @@ -0,0 +1,9 @@ +#ifndef AT91_TESTS_H_ +#define AT91_TESTS_H_ + +void at91_rttc_test_init(void); + +void at91_adc_test_init(void); +void at91_adc_printresults(void); + +#endif /*AT91_TESTS_H_*/ diff --git a/include/at91_twi.h b/include/at91_twi.h new file mode 100644 index 0000000..0e23314 --- /dev/null +++ b/include/at91_twi.h @@ -0,0 +1,57 @@ +#ifndef AT91TWI_H_ +#define AT91TWI_H_ + +#include + +/* TWI slave addresses */ +#define TWI_ADDR_BL1 0x21 +#define TWI_ADDR_BL2 0x22 +#define TWI_ADDR_BL3 0x23 +#define TWI_ADDR_BL4 0x24 +#define TWI_ADDR_EEPROM 0x40 + +/* TWIBOOT commands */ +#define CMD_WAIT 0x00 +#define CMD_GET_INFO 0x10 +#define CMD_GET_SIGNATURE 0x11 +#define CMD_WRITE_FLASH 0x12 +#define CMD_READ_FLASH 0x13 +#define CMD_WRITE_EEPROM 0x14 +#define CMD_READ_EEPROM 0x15 +#define CMD_BOOT_APPLICATION 0x1F + +/* blctrl commands */ +//#define CMD_WAIT 0x00 +//#define CMD_GET_INFO 0x10 +#define CMD_SET_PWM 0x21 +#define CMD_GET_STATUS 0x22 +//#define CMD_SET_PARAM 0x23 +//#define CMD_GET_PARAM 0x24 +#define CMD_BOOT_LOADER 0x2F + + +struct blmc_cmd { + uint32_t cmd; /* cmd byte(s) */ + uint8_t mode; /* read/write, cmdlen (1-3 bytes) */ + uint8_t size; /* data size */ + uint8_t *data; /* read/write data */ +}; + +/* same bits as TWI_MMR[8..15] */ +#define BLMC_CMD_READ 0x10 +#define BLMC_CMD_WRITE 0x00 +#define BLMC_CMD_0_ARG 0x01 +#define BLMC_CMD_1_ARG 0x02 +#define BLMC_CMD_2_ARG 0x03 + +uint32_t twi_read_eeprom(uint32_t addr, uint8_t *buf, uint32_t size); +uint32_t twi_write_eeprom(uint32_t addr, uint8_t *buf, uint32_t size); + +uint32_t twi_setpwm(uint8_t *values); + +uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd); + +void at91_twi_init(void); +void at91_twi_test(void); + +#endif /*AT91TWI_H_*/ diff --git a/include/at91_udp.h b/include/at91_udp.h new file mode 100644 index 0000000..e667f91 --- /dev/null +++ b/include/at91_udp.h @@ -0,0 +1,6 @@ +#ifndef AT91_UDP_H_ +#define AT91_UDP_H_ + +void at91_udp_init(void); + +#endif /*AT91_UDP_H_*/ diff --git a/include/atomic.h b/include/atomic.h new file mode 100644 index 0000000..2b82ead --- /dev/null +++ b/include/atomic.h @@ -0,0 +1,26 @@ +#ifndef ATOMIC_H_ +#define ATOMIC_H_ + +//TODO: not for thumbcode?! + +#define disable_irqs() \ +{ \ + int temp_; \ + asm volatile ( \ + "mrs %0, cpsr" "\n\t" \ + "stmfd sp!, {%0}" "\n\t" \ + "orr %0, %0, #0xC0" "\n\t" \ + "msr cpsr, %0" "\n\t" \ + : "=r" (temp_) : ); \ +} + +#define restore_irqs() \ +{ \ + int temp_; \ + asm volatile ( \ + "ldmfd sp!, {%0}" "\n\t" \ + "msr cpsr, %0" "\n\t" \ + : "=r" (temp_) : ); \ +} + +#endif /*ATOMIC_H_*/ diff --git a/include/board.h b/include/board.h new file mode 100644 index 0000000..2a51cc4 --- /dev/null +++ b/include/board.h @@ -0,0 +1,43 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "AT91SAM7S256.h" + +/* keep in sync with at91_init1.c */ +#define MAINCK 18432000 +#define PLLCK (MAINCK / 24 * 125) /* 96MHz */ +#define MCK (PLLCK / 2) /* 48MHz */ + +/* DBGU UART Baudrate calculation */ +#define BAUD_TO_DIV(BAUD) (MCK / (16 * BAUD)) + +/* LED PIOs */ +#define LED_ORANGE AT91C_PIO_PA17 +#define LED_GREEN AT91C_PIO_PA18 + +/* Taster PIOs */ +#define TAST1 AT91C_PIO_PA19 +#define TAST2 AT91C_PIO_PA20 + +/* USB PIOs */ +#define UDP_VBUS_MON AT91C_PIO_PA24 +#define UDP_PULLUP AT91C_PIO_PA25 + +/* ATMEL IDs */ +#define USB_VENDOR_ID 0x03EB +#define USB_PRODUCT_ID 0x6124 + +/* Interrupt Priorities (7 = highest) */ +#define IRQPRIO_SYSC 6 /* pitc */ +#define IRQPRIO_PIOA 1 /* pinchange interrupts */ +#define IRQPRIO_ADC 2 +#define IRQPRIO_TWI 7 /* twi must be fast! */ +#define IRQPRIO_UDP 4 /* usb */ +#define IRQPRIO_TC1 5 /* ppm capturing */ + +/* TODO: find better place */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +#endif /*BOARD_H_*/ diff --git a/include/fifo.h b/include/fifo.h new file mode 100644 index 0000000..42a90a5 --- /dev/null +++ b/include/fifo.h @@ -0,0 +1,28 @@ +#ifndef FIFO_H_ +#define FIFO_H_ + +#include + +struct fifo { + uint32_t in; + uint32_t out; + + uint16_t pdc_tx; + uint16_t pdc_rx; + + uint32_t size; + char buf[0]; +}; + +uint32_t fifo_put(struct fifo *fifo, const char *buf, uint32_t len); +uint32_t fifo_get(struct fifo *fifo, char *buf, uint32_t len); + +uint32_t fifo_rxpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize); +uint32_t fifo_txpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize); + +uint32_t fifo_putbyte(struct fifo *fifo, char c); +uint32_t fifo_getbyte(struct fifo *fifo, char *p); + +struct fifo * fifo_alloc(uint32_t size); + +#endif /*FIFO_H_*/ diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000..c1d5519 --- /dev/null +++ b/include/list.h @@ -0,0 +1,268 @@ +#ifndef _LIST_H_ +#define _LIST_H_ + +/* + * stolen from linux kernel 2.6.11 (http://kernel.org/) + * linux/include/linux/stddef.h (offsetoff) + * linux/include/linux/kernel.h (container_of) + * linux/include/linux/list.h (*list*) + * linux/include/linux/netfilter_ipv4/listhelp.h (LIST_FIND) + * + * modified by Olaf Rempel + */ +//#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/* + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/* + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/* + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = NULL; + entry->prev = NULL; +} + +/* + * list_del_init - deletes entry from list and reinitialize it. + * entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/* + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +/* + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/* + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +/* + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(struct list_head *list, struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head); +} + +/* + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +} + +/* + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/* + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/* + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + +/* + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/* + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/* + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_reverse(pos, head, member) \ + for (pos = list_entry((head)->prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member)) + +/* + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + + +/* Return pointer to first true entry, if any, or NULL. A macro + required to allow inlining of cmpfn. */ +#define LIST_FIND(head, cmpfn, type, args...) \ +({ \ + const struct list_head *__i, *__j = NULL; \ + \ + list_for_each(__i, (head)) \ + if (cmpfn((const type)__i , ## args)) { \ + __j = __i; \ + break; \ + } \ + (type)__j; \ +}) + +#endif /* _LIST_H_ */ diff --git a/include/static_alloc.h b/include/static_alloc.h new file mode 100644 index 0000000..39b1f64 --- /dev/null +++ b/include/static_alloc.h @@ -0,0 +1,9 @@ +#ifndef STATIC_ALLOC_H_ +#define STATIC_ALLOC_H_ + +void * static_alloc(uint32_t size); +uint32_t static_alloc_used(void); + +uint32_t next_powerof2(uint32_t value); + +#endif /*STATIC_ALLOC_H_*/ diff --git a/include/usb_cdc.h b/include/usb_cdc.h new file mode 100644 index 0000000..4c6191c --- /dev/null +++ b/include/usb_cdc.h @@ -0,0 +1,240 @@ +#ifndef USB_CDC_H_ +#define USB_CDC_H_ + +#include + +/* + * the content of this file comes from + * - linux/include/linux/usb/cdc.h + * with minor modifications: + * - type conversion (e.g. __u8 -> uint8_t) + */ + +/*-------------------------------------------------------------------------*/ + +/* + * USB Communications Device Class (CDC) definitions + * + * CDC says how to talk to lots of different types of network adapters, + * notably ethernet adapters and various modems. It's used mostly with + * firmware based USB peripherals. + */ + +#define USB_CDC_SUBCLASS_ACM 0x02 +#define USB_CDC_SUBCLASS_ETHERNET 0x06 +#define USB_CDC_SUBCLASS_WHCM 0x08 +#define USB_CDC_SUBCLASS_DMM 0x09 +#define USB_CDC_SUBCLASS_MDLM 0x0a +#define USB_CDC_SUBCLASS_OBEX 0x0b + +#define USB_CDC_PROTO_NONE 0 + +#define USB_CDC_ACM_PROTO_AT_V25TER 1 +#define USB_CDC_ACM_PROTO_AT_PCCA101 2 +#define USB_CDC_ACM_PROTO_AT_PCCA101_WAKE 3 +#define USB_CDC_ACM_PROTO_AT_GSM 4 +#define USB_CDC_ACM_PROTO_AT_3G 5 +#define USB_CDC_ACM_PROTO_AT_CDMA 6 +#define USB_CDC_ACM_PROTO_VENDOR 0xff + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific descriptors ... there are a couple dozen of them + */ + +#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ +#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ +#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ +#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ +#define USB_CDC_COUNTRY_TYPE 0x07 +#define USB_CDC_NETWORK_TERMINAL_TYPE 0x0a /* network_terminal_desc */ +#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ +#define USB_CDC_WHCM_TYPE 0x11 +#define USB_CDC_MDLM_TYPE 0x12 /* mdlm_desc */ +#define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */ +#define USB_CDC_DMM_TYPE 0x14 +#define USB_CDC_OBEX_TYPE 0x15 + +/* "Header Functional Descriptor" from CDC spec 5.2.3.1 */ +struct usb_cdc_header_desc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint16_t bcdCDC; +} __attribute__ ((packed)); + +/* "Call Management Descriptor" from CDC spec 5.2.3.2 */ +struct usb_cdc_call_mgmt_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint8_t bmCapabilities; +#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT 0x01 +#define USB_CDC_CALL_MGMT_CAP_DATA_INTF 0x02 + + uint8_t bDataInterface; +} __attribute__ ((packed)); + +/* "Abstract Control Management Descriptor" from CDC spec 5.2.3.3 */ +struct usb_cdc_acm_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint8_t bmCapabilities; +} __attribute__ ((packed)); + +/* capabilities from 5.2.3.3 */ + +#define USB_CDC_COMM_FEATURE 0x01 +#define USB_CDC_CAP_LINE 0x02 +#define USB_CDC_CAP_BRK 0x04 +#define USB_CDC_CAP_NOTIFY 0x08 + +/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ +struct usb_cdc_union_desc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint8_t bMasterInterface0; + uint8_t bSlaveInterface0; + /* ... and there could be other slave interfaces */ +} __attribute__ ((packed)); + +/* "Country Selection Functional Descriptor" from CDC spec 5.2.3.9 */ +struct usb_cdc_country_functional_desc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint8_t iCountryCodeRelDate; + uint16_t wCountyCode0; + /* ... and there can be a lot of country codes */ +} __attribute__ ((packed)); + +/* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */ +struct usb_cdc_network_terminal_desc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint8_t bEntityId; + uint8_t iName; + uint8_t bChannelIndex; + uint8_t bPhysicalInterface; +} __attribute__ ((packed)); + +/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */ +struct usb_cdc_ether_desc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint8_t iMACAddress; + uint32_t bmEthernetStatistics; + uint16_t wMaxSegmentSize; + uint16_t wNumberMCFilters; + uint8_t bNumberPowerFilters; +} __attribute__ ((packed)); + +/* "MDLM Functional Descriptor" from CDC WMC spec 6.7.2.3 */ +struct usb_cdc_mdlm_desc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + uint16_t bcdVersion; + uint8_t bGUID[16]; +} __attribute__ ((packed)); + +/* "MDLM Detail Functional Descriptor" from CDC WMC spec 6.7.2.4 */ +struct usb_cdc_mdlm_detail_desc { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + + /* type is associated with mdlm_desc.bGUID */ + uint8_t bGuidDescriptorType; + uint8_t bDetailData[0]; +} __attribute__ ((packed)); + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific Control Requests (6.2) + * + * section 3.6.2.1 table 4 has the ACM profile, for modems. + * section 3.8.2 table 10 has the ethernet profile. + * + * Microsoft's RNDIS stack for Ethernet is a vendor-specific CDC ACM variant, + * heavily dependent on the encapsulated (proprietary) command mechanism. + */ + +#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_CDC_REQ_SET_LINE_CODING 0x20 +#define USB_CDC_REQ_GET_LINE_CODING 0x21 +#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 +#define USB_CDC_REQ_SEND_BREAK 0x23 +#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 +#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 +#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 + +/* Line Coding Structure from CDC spec 6.2.13 */ +struct usb_cdc_line_coding { + uint32_t dwDTERate; + uint8_t bCharFormat; +#define USB_CDC_1_STOP_BITS 0 +#define USB_CDC_1_5_STOP_BITS 1 +#define USB_CDC_2_STOP_BITS 2 + + uint8_t bParityType; +#define USB_CDC_NO_PARITY 0 +#define USB_CDC_ODD_PARITY 1 +#define USB_CDC_EVEN_PARITY 2 +#define USB_CDC_MARK_PARITY 3 +#define USB_CDC_SPACE_PARITY 4 + + uint8_t bDataBits; +} __attribute__ ((packed)); + +/* table 62; bits in multicast filter */ +#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0) +#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */ +#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2) +#define USB_CDC_PACKET_TYPE_BROADCAST (1 << 3) +#define USB_CDC_PACKET_TYPE_MULTICAST (1 << 4) /* filtered */ + + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific Notifications (6.3) sent by interrupt transfers + * + * section 3.8.2 table 11 of the CDC spec lists Ethernet notifications + * section 3.6.2.1 table 5 specifies ACM notifications, accepted by RNDIS + * RNDIS also defines its own bit-incompatible notifications + */ + +#define USB_CDC_NOTIFY_NETWORK_CONNECTION 0x00 +#define USB_CDC_NOTIFY_RESPONSE_AVAILABLE 0x01 +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_CDC_NOTIFY_SPEED_CHANGE 0x2a + +struct usb_cdc_notification { + uint8_t bmRequestType; + uint8_t bNotificationType; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__ ((packed)); + +/*-------------------------------------------------------------------------*/ + +#endif /*USB_CDC_H_*/ diff --git a/include/usb_ch9.h b/include/usb_ch9.h new file mode 100644 index 0000000..533d7d0 --- /dev/null +++ b/include/usb_ch9.h @@ -0,0 +1,553 @@ +#ifndef USB_CH9_H_ +#define USB_CH9_H_ + +#include + +/* + * the content of this file comes from + * - linux/include/linux/usb/ch9.h + * with minor modifications: + * - type conversion (e.g. __u8 -> uint8_t) + * - usb_endpoint_descriptor: removed last 2 bytes + */ + +/*-------------------------------------------------------------------------*/ + +/* CONTROL REQUEST SUPPORT */ + +/* + * USB directions + * + * This bit flag is used in endpoint descriptors' bEndpointAddress field. + * It's also one of three fields in control requests bRequestType. + */ +#define USB_DIR_OUT 0 /* to device */ +#define USB_DIR_IN 0x80 /* to host */ + +/* + * USB types, the second of three bRequestType fields + */ +#define USB_TYPE_MASK (0x03 << 5) +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +/* + * USB recipients, the third of three bRequestType fields + */ +#define USB_RECIP_MASK 0x1f +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 +/* From Wireless USB 1.0 */ +#define USB_RECIP_PORT 0x04 +#define USB_RECIP_RPIPE 0x05 + +/* + * Standard requests, for the bRequest field of a SETUP packet. + * + * These are qualified by the bRequestType field, so that for example + * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved + * by a GET_STATUS request. + */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */ +#define USB_REQ_GET_ENCRYPTION 0x0E +#define USB_REQ_RPIPE_ABORT 0x0E +#define USB_REQ_SET_HANDSHAKE 0x0F +#define USB_REQ_RPIPE_RESET 0x0F +#define USB_REQ_GET_HANDSHAKE 0x10 +#define USB_REQ_SET_CONNECTION 0x11 +#define USB_REQ_SET_SECURITY_DATA 0x12 +#define USB_REQ_GET_SECURITY_DATA 0x13 +#define USB_REQ_SET_WUSB_DATA 0x14 +#define USB_REQ_LOOPBACK_DATA_WRITE 0x15 +#define USB_REQ_LOOPBACK_DATA_READ 0x16 +#define USB_REQ_SET_INTERFACE_DS 0x17 + +/* + * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and + * are read as a bit array returned by USB_REQ_GET_STATUS. (So there + * are at most sixteen features of each type.) + */ +#define USB_DEVICE_SELF_POWERED 0 /* (read only) */ +#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */ +#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */ +#define USB_DEVICE_BATTERY 2 /* (wireless) */ +#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */ +#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/ +#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */ +#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */ +#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */ + +#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ + + +/** + * struct usb_ctrlrequest - SETUP data for a USB device control request + * @bRequestType: matches the USB bmRequestType field + * @bRequest: matches the USB bRequest field + * @wValue: matches the USB wValue field (le16 byte order) + * @wIndex: matches the USB wIndex field (le16 byte order) + * @wLength: matches the USB wLength field (le16 byte order) + * + * This structure is used to send control requests to a USB device. It matches + * the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the + * USB spec for a fuller description of the different fields, and what they are + * used for. + * + * Note that the driver for any interface can issue control requests. + * For most devices, interfaces don't coordinate with each other, so + * such requests may be made at any time. + */ +struct usb_ctrlrequest { + uint8_t bRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__ ((packed)); + +/*-------------------------------------------------------------------------*/ + +/* + * STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or + * (rarely) accepted by SET_DESCRIPTOR. + * + * Note that all multi-byte values here are encoded in little endian + * byte order "on the wire". But when exposed through Linux-USB APIs, + * they've been converted to cpu byte order. + */ + +/* + * Descriptor types ... USB 2.0 spec table 9.5 + */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 +#define USB_DT_DEVICE_QUALIFIER 0x06 +#define USB_DT_OTHER_SPEED_CONFIG 0x07 +#define USB_DT_INTERFACE_POWER 0x08 +/* these are from a minor usb 2.0 revision (ECN) */ +#define USB_DT_OTG 0x09 +#define USB_DT_DEBUG 0x0a +#define USB_DT_INTERFACE_ASSOCIATION 0x0b +/* these are from the Wireless USB spec */ +#define USB_DT_SECURITY 0x0c +#define USB_DT_KEY 0x0d +#define USB_DT_ENCRYPTION_TYPE 0x0e +#define USB_DT_BOS 0x0f +#define USB_DT_DEVICE_CAPABILITY 0x10 +#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11 +#define USB_DT_WIRE_ADAPTER 0x21 +#define USB_DT_RPIPE 0x22 + +/* Conventional codes for class-specific descriptors. The convention is + * defined in the USB "Common Class" Spec (3.11). Individual class specs + * are authoritative for their usage, not the "common class" writeup. + */ +#define USB_DT_CS_DEVICE (USB_TYPE_CLASS | USB_DT_DEVICE) +#define USB_DT_CS_CONFIG (USB_TYPE_CLASS | USB_DT_CONFIG) +#define USB_DT_CS_STRING (USB_TYPE_CLASS | USB_DT_STRING) +#define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE) +#define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT) + +/* All standard descriptors have these 2 fields at the beginning */ +struct usb_descriptor_header { + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__ ((packed)); + + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEVICE: Device descriptor */ +struct usb_device_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)); + +#define USB_DT_DEVICE_SIZE 18 + + +/* + * Device and/or Interface Class codes + * as found in bDeviceClass or bInterfaceClass + * and defined by www.usb.org documents + */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PHYSICAL 5 +#define USB_CLASS_STILL_IMAGE 6 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_CDC_DATA 0x0a +#define USB_CLASS_CSCID 0x0b /* chip+ smart card */ +#define USB_CLASS_CONTENT_SEC 0x0d /* content security */ +#define USB_CLASS_VIDEO 0x0e +#define USB_CLASS_WIRELESS_CONTROLLER 0xe0 +#define USB_CLASS_MISC 0xef +#define USB_CLASS_APP_SPEC 0xfe +#define USB_CLASS_VENDOR_SPEC 0xff + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_CONFIG: Configuration descriptor information. + * + * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the + * descriptor type is different. Highspeed-capable devices can look + * different depending on what speed they're currently running. Only + * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG + * descriptors. + */ +struct usb_config_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __attribute__ ((packed)); + +#define USB_DT_CONFIG_SIZE 9 + +/* from config descriptor bmAttributes */ +#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */ +#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */ +#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */ +#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */ + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_STRING: String descriptor */ +struct usb_string_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint16_t wData[1]; /* UTF-16LE encoded */ +} __attribute__ ((packed)); + +/* note that "string" zero is special, it holds language codes that + * the device supports, not Unicode characters. + */ + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_INTERFACE: Interface descriptor */ +struct usb_interface_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __attribute__ ((packed)); + +#define USB_DT_INTERFACE_SIZE 9 + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_ENDPOINT: Endpoint descriptor */ +struct usb_endpoint_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + + /* NOTE: these two are _only_ in audio endpoints. */ + /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ +// uint8_t bRefresh; +// uint8_t bSynchAddress; +} __attribute__ ((packed)); + +#define USB_DT_ENDPOINT_SIZE 7 +//#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ + + +/* + * Endpoints + */ +#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_XFER_CONTROL 0 +#define USB_ENDPOINT_XFER_ISOC 1 +#define USB_ENDPOINT_XFER_BULK 2 +#define USB_ENDPOINT_XFER_INT 3 +#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ +struct usb_qualifier_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bRESERVED; +} __attribute__ ((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_OTG (from OTG 1.0a supplement) */ +struct usb_otg_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint8_t bmAttributes; /* support for HNP, SRP, etc */ +} __attribute__ ((packed)); + +/* from usb_otg_descriptor.bmAttributes */ +#define USB_OTG_SRP (1 << 0) +#define USB_OTG_HNP (1 << 1) /* swap host/device roles */ + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */ +struct usb_debug_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + /* bulk endpoints with 8 byte maxpacket */ + uint8_t bDebugInEndpoint; + uint8_t bDebugOutEndpoint; +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */ +struct usb_interface_assoc_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} __attribute__ ((packed)); + + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_SECURITY: group of wireless security descriptors, including + * encryption types available for setting up a CC/association. + */ +struct usb_security_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint16_t wTotalLength; + uint8_t bNumEncryptionTypes; +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys + * may be retrieved. + */ +struct usb_key_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint8_t tTKID[3]; + uint8_t bReserved; + uint8_t bKeyData[0]; +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */ +struct usb_encryption_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint8_t bEncryptionType; +#define USB_ENC_TYPE_UNSECURE 0 +#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */ +#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */ +#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */ + uint8_t bEncryptionValue; /* use in SET_ENCRYPTION */ + uint8_t bAuthKeyIndex; +} __attribute__((packed)); + + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_BOS: group of wireless capabilities */ +struct usb_bos_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */ +struct usb_dev_cap_header { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; +} __attribute__((packed)); + +#define USB_CAP_TYPE_WIRELESS_USB 1 + +struct usb_wireless_cap_descriptor { /* Ultra Wide Band */ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + + uint8_t bmAttributes; +#define USB_WIRELESS_P2P_DRD (1 << 1) +#define USB_WIRELESS_BEACON_MASK (3 << 2) +#define USB_WIRELESS_BEACON_SELF (1 << 2) +#define USB_WIRELESS_BEACON_DIRECTED (2 << 2) +#define USB_WIRELESS_BEACON_NONE (3 << 2) + uint16_t wPHYRates; /* bit rates, Mbps */ +#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */ +#define USB_WIRELESS_PHY_80 (1 << 1) +#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */ +#define USB_WIRELESS_PHY_160 (1 << 3) +#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */ +#define USB_WIRELESS_PHY_320 (1 << 5) +#define USB_WIRELESS_PHY_400 (1 << 6) +#define USB_WIRELESS_PHY_480 (1 << 7) + uint8_t bmTFITXPowerInfo; /* TFI power levels */ + uint8_t bmFFITXPowerInfo; /* FFI power levels */ + uint16_t bmBandGroup; + uint8_t bReserved; +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with + * each endpoint descriptor for a wireless device + */ +struct usb_wireless_ep_comp_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + + uint8_t bMaxBurst; + uint8_t bMaxSequence; + uint16_t wMaxStreamDelay; + uint16_t wOverTheAirPacketSize; + uint8_t bOverTheAirInterval; + uint8_t bmCompAttributes; +#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */ +#define USB_ENDPOINT_SWITCH_NO 0 +#define USB_ENDPOINT_SWITCH_SWITCH 1 +#define USB_ENDPOINT_SWITCH_SCALE 2 +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless + * host and a device for connection set up, mutual authentication, and + * exchanging short lived session keys. The handshake depends on a CC. + */ +struct usb_handshake { + uint8_t bMessageNumber; + uint8_t bStatus; + uint8_t tTKID[3]; + uint8_t bReserved; + uint8_t CDID[16]; + uint8_t nonce[16]; + uint8_t MIC[8]; +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC). + * A CC may also be set up using non-wireless secure channels (including + * wired USB!), and some devices may support CCs with multiple hosts. + */ +struct usb_connection_context { + uint8_t CHID[16]; /* persistent host id */ + uint8_t CDID[16]; /* device id (unique w/in host context) */ + uint8_t CK[16]; /* connection key */ +} __attribute__((packed)); + +/*-------------------------------------------------------------------------*/ + +/* USB 2.0 defines three speeds, here's how Linux identifies them */ + +enum usb_device_speed { + USB_SPEED_UNKNOWN = 0, /* enumerating */ + USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ + USB_SPEED_HIGH, /* usb 2.0 */ + USB_SPEED_VARIABLE, /* wireless (usb 2.5) */ +}; + +enum usb_device_state { + /* NOTATTACHED isn't in the USB spec, and this state acts + * the same as ATTACHED ... but it's clearer this way. + */ + USB_STATE_NOTATTACHED = 0, + + /* chapter 9 and authentication (wireless) device states */ + USB_STATE_ATTACHED, + USB_STATE_POWERED, /* wired */ + USB_STATE_UNAUTHENTICATED, /* auth */ + USB_STATE_RECONNECTING, /* auth */ + USB_STATE_DEFAULT, /* limited function */ + USB_STATE_ADDRESS, + USB_STATE_CONFIGURED, /* most functions */ + + USB_STATE_SUSPENDED + + /* NOTE: there are actually four different SUSPENDED + * states, returning to POWERED, DEFAULT, ADDRESS, or + * CONFIGURED respectively when SOF tokens flow again. + */ +}; + +#endif /*USB_CH9_H_*/ diff --git a/include/usb_dfu.h b/include/usb_dfu.h new file mode 100644 index 0000000..fbb2b4f --- /dev/null +++ b/include/usb_dfu.h @@ -0,0 +1,73 @@ +#ifndef USB_DFU_H_ +#define USB_DFU_H_ + +#include +#include "usb_ch9.h" + +#define USB_DT_DFU USB_DT_CS_DEVICE + +/* DFU Descriptor Type */ +#define USB_TYPE_DFU (USB_TYPE_CLASS | USB_RECIP_INTERFACE) + +struct usb_dfu_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bmAttributes; + uint16_t wDetachTimeOut; + uint16_t wTransferSize; + uint16_t bcdDFUVersion; +} __attribute__ ((packed)); + +#define USB_DFU_CAN_DOWNLOAD 0x01 +#define USB_DFU_CAN_UPLOAD 0x02 +#define USB_DFU_MANIFEST_TOL 0x04 +#define USB_DFU_WILL_DETACH 0x08 + +/* DFU class-specific requests (Section 3, DFU Rev 1.1) */ +#define USB_REQ_DFU_DETACH 0x00 +#define USB_REQ_DFU_DNLOAD 0x01 +#define USB_REQ_DFU_UPLOAD 0x02 +#define USB_REQ_DFU_GETSTATUS 0x03 +#define USB_REQ_DFU_CLRSTATUS 0x04 +#define USB_REQ_DFU_GETSTATE 0x05 +#define USB_REQ_DFU_ABORT 0x06 + +struct dfu_status { + uint8_t bStatus; + uint8_t bwPollTimeout[3]; + uint8_t bState; + uint8_t iString; +} __attribute__((packed)); + +#define DFU_STATUS_OK 0x00 +#define DFU_STATUS_errTARGET 0x01 +#define DFU_STATUS_errFILE 0x02 +#define DFU_STATUS_errWRITE 0x03 +#define DFU_STATUS_errERASE 0x04 +#define DFU_STATUS_errCHECK_ERASED 0x05 +#define DFU_STATUS_errPROG 0x06 +#define DFU_STATUS_errVERIFY 0x07 +#define DFU_STATUS_errADDRESS 0x08 +#define DFU_STATUS_errNOTDONE 0x09 +#define DFU_STATUS_errFIRMWARE 0x0a +#define DFU_STATUS_errVENDOR 0x0b +#define DFU_STATUS_errUSBR 0x0c +#define DFU_STATUS_errPOR 0x0d +#define DFU_STATUS_errUNKNOWN 0x0e +#define DFU_STATUS_errSTALLEDPKT 0x0f + +enum dfu_state { + DFU_STATE_appIDLE = 0, + DFU_STATE_appDETACH = 1, + DFU_STATE_dfuIDLE = 2, + DFU_STATE_dfuDNLOAD_SYNC = 3, + DFU_STATE_dfuDNBUSY = 4, + DFU_STATE_dfuDNLOAD_IDLE = 5, + DFU_STATE_dfuMANIFEST_SYNC = 6, + DFU_STATE_dfuMANIFEST = 7, + DFU_STATE_dfuMANIFEST_WAIT_RST = 8, + DFU_STATE_dfuUPLOAD_IDLE = 9, + DFU_STATE_dfuERROR = 10, +}; + +#endif /*USB_DFU_H_*/ diff --git a/ldscript.ld b/ldscript.ld new file mode 100644 index 0000000..225c407 --- /dev/null +++ b/ldscript.ld @@ -0,0 +1,81 @@ +MEMORY +{ + CODE (rx) : ORIGIN = 0x00100000, LENGTH = 256k + DATA (rwx) : ORIGIN = 0x00200000, LENGTH = 64k +} + +SECTIONS +{ + . = ORIGIN(CODE); + .text : { + *at91_init0.o (.text) + *at91_init1.o (.text) + *(.text) + *(.glue_7t) + *(.glue_7) + + . = ALIGN(4); + _pio_isr_table = .; + *(.pio_isr) + _pio_isr_table_end = .; + + . = ALIGN(4); + *(.rodata) + *(.rodata.*) + + __text_end__ = .; + } >CODE =0 + + .data : AT (ADDR(.text) + SIZEOF(.text)) { + *(.data) + } >DATA =0 + + __data_start__ = ADDR(.data); + __data_end__ = ADDR(.data) + SIZEOF(.data); + + .bss : { + *(.bss) + *(COMMON) + } + + __bss_start__ = ADDR(.bss); + __bss_end__ = ADDR(.bss) + SIZEOF(.bss); + + __stack_top__ = ORIGIN(DATA) + LENGTH(DATA); + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..23ab055 --- /dev/null +++ b/main.c @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include "AT91SAM7S256.h" +#include "at91_sysc.h" +#include "at91_dbgu.h" +#include "at91_pitc.h" +#include "at91_tests.h" +#include "at91_udp.h" +#include "at91_pio.h" +#include "at91_twi.h" + +#include "at91_tc1.h" +#include "static_alloc.h" + +#include "board.h" +#include +#include + +AT91S_AIC *aic = AT91C_BASE_AIC; +AT91S_TWI *twi = AT91C_BASE_TWI; +AT91S_UDP *udp = AT91C_BASE_UDP; + +static uint32_t pitc_test(struct pitc_timer *timer) +{ + static uint32_t i; + *AT91C_PIOA_SODR = i; + i = i ^ LED_GREEN; + *AT91C_PIOA_CODR = i; +/* + struct rc_values rc; + uint32_t valid = rc_ppm_getvalues(&rc); + if (!valid) + rc.count = 0; + + printf("%d channels: ", rc.count); + uint32_t j; + for (j = 0; j < rc.count; j++) + printf("%+3d ", rc.ch[j]); + + printf("\n\r"); +*/ + return 0; +} + +int main(void) +{ + /* trigger pinchange-isrs */ + at91_pio_init(); + + /* LED outputs */ + *AT91C_PIOA_PER = LED_GREEN | LED_ORANGE; + *AT91C_PIOA_OER = LED_GREEN | LED_ORANGE; + + /* needed for dbgu */ + at91_sysc_init(); + + at91_dbgu_init(); + at91_dbgu_puts("==========================================================\n\rGood morning Dave\n\r"); + + /* timer */ + at91_pitc_init(); + at91_rttc_test_init(); + at91_tc1_init(); + + /* adc, need timer */ + at91_adc_test_init(); + + /* twi */ + at91_twi_init(); + + /* usb */ + at91_udp_init(); + + struct pitc_timer *pitc_test_timer = alloc_pitc_timer(10, &pitc_test, NULL); + pitc_schedule_timer(pitc_test_timer); + + printf("static alloc: %5ld bytes\n\r", static_alloc_used()); + + at91_twi_test(); + + while (1); +} diff --git a/scripts/download.sh b/scripts/download.sh new file mode 100755 index 0000000..ec479f2 --- /dev/null +++ b/scripts/download.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +echo -e " +sleep 10 +reset halt +wait_halt +mww 0xfffffd08 0xa5000001 +sleep 10 +arm7_9 sw_bkpts disable +arm7_9 force_hw_bkpts enable +arm7_9 dcc_downloads enable +sleep 10 +flash probe 0 +flash info 0 +flash auto_erase on +flash write_image build/sam7fc.elf +sleep 10 +reset run +exit" | nc localhost 4444 diff --git a/scripts/gdb-thumb.cfg b/scripts/gdb-thumb.cfg new file mode 100644 index 0000000..177e845 --- /dev/null +++ b/scripts/gdb-thumb.cfg @@ -0,0 +1,23 @@ +target remote localhost:3333 + +# Peripheral reset (also resets memory map) +#monitor mww 0xfffffd00 0xa5000002 +#monitor sleep 10 + +# Enable User reset (via jtag trst) +monitor mww 0xfffffd08 0xa5000001 +monitor sleep 10 + +monitor reset halt +monitor wait_halt + +monitor arm7_9 sw_bkpts disable +monitor arm7_9 force_hw_bkpts enable + +#monitor arm7_9 fast_memory_access enable +monitor arm7_9 dcc_downloads enable + +monitor flash probe 0 +monitor flash info 0 +monitor flash auto_erase on +monitor flash write_image Debug_thumb/FlightCtrl_arm7.elf diff --git a/scripts/gdb.cfg b/scripts/gdb.cfg new file mode 100644 index 0000000..f838bc5 --- /dev/null +++ b/scripts/gdb.cfg @@ -0,0 +1,23 @@ +target remote localhost:3333 + +# Peripheral reset (also resets memory map) +#monitor mww 0xfffffd00 0xa5000002 +#monitor sleep 10 + +# Enable User reset (via jtag trst) +monitor mww 0xfffffd08 0xa5000001 +monitor sleep 10 + +monitor reset halt +monitor wait_halt + +monitor arm7_9 sw_bkpts disable +monitor arm7_9 force_hw_bkpts enable + +#monitor arm7_9 fast_memory_access enable +monitor arm7_9 dcc_downloads enable + +monitor flash probe 0 +monitor flash info 0 +monitor flash auto_erase on +monitor flash write_image Debug/FlightCtrl_arm7.elf diff --git a/scripts/openocd.cfg b/scripts/openocd.cfg new file mode 100644 index 0000000..1e3d1c9 --- /dev/null +++ b/scripts/openocd.cfg @@ -0,0 +1,16 @@ +telnet_port 4444 +gdb_port 3333 +daemon_startup reset + +interface parport +parport_port 0 +parport_cable wiggler +jtag_speed 0 + +reset_config srst_only +jtag_device 4 0x1 0xf 0xe +#jtag_nsrst_delay 500 +#jtag_ntrst_delay 100 + +target arm7tdmi little reset_halt 0 arm7tdmi +flash bank at91sam7 0 0 0 0 0 diff --git a/src/at91_adc.c b/src/at91_adc.c new file mode 100644 index 0000000..a9c5f9b --- /dev/null +++ b/src/at91_adc.c @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include +#include + +#include "AT91SAM7S256.h" +#include "board.h" +#include "at91_pitc.h" +#include "static_alloc.h" + +static uint16_t adc_result[4]; + +static void at91_adc_isr(void) +{ + AT91S_PDC *pdc = AT91C_BASE_PDC_ADC; + pdc->PDC_RPR = (uint32_t) &adc_result; + pdc->PDC_RCR = ARRAY_SIZE(adc_result); + pdc->PDC_PTCR = AT91C_PDC_RXTEN; + + /* clear interrupts */ + AT91S_ADC *adc = AT91C_BASE_ADC; + uint32_t status = adc->ADC_SR; + status = status; +} + +static uint32_t adc_trigger(struct pitc_timer *timer) +{ + *AT91C_ADC_CR = AT91C_ADC_START; + return PITC_RESTART_TIMER; +} + +void at91_adc_test_init(void) +{ + /* enable ADC clock */ + *AT91C_PMC_PCER = (1 << AT91C_ID_ADC); + + /* ADC Software reset */ + AT91S_ADC *adc = AT91C_BASE_ADC; + adc->ADC_CR = AT91C_ADC_SWRST; + + /* + * ADC config: 10bit, no sleep + * 4.8MHz (48MHz / ((4 +1) * 2) = 4.8MHz) + * 96 cycles Startup ((11 +1) * 8 / 4.8MHz = 20us) + * 3 cycles SH ((2 +1) / 4.8MHz = 625ns) + * Conversion time per channel @5MHz ~2us + */ + adc->ADC_MR = AT91C_ADC_TRGEN_DIS | + AT91C_ADC_LOWRES_10_BIT | + AT91C_ADC_SLEEP_NORMAL_MODE | + (AT91C_ADC_PRESCAL & (4 << 8)) | + (AT91C_ADC_STARTUP & (11 << 16)) | + (AT91C_ADC_SHTIM & (2 << 24)); + + /* setup PDC */ + AT91S_PDC *pdc = AT91C_BASE_PDC_ADC; + pdc->PDC_RPR = (uint32_t) &adc_result; + pdc->PDC_RCR = ARRAY_SIZE(adc_result); + pdc->PDC_PTCR = AT91C_PDC_RXTEN; + + /* enable 4 channels, PDC Interrupt */ + adc->ADC_CHER = 0xF0; + adc->ADC_IER = AT91C_ADC_ENDRX; + + /* low priority, level triggered, own vector */ + AT91S_AIC *aic = AT91C_BASE_AIC; + aic->AIC_SMR[AT91C_ID_ADC] = IRQPRIO_ADC | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; + aic->AIC_SVR[AT91C_ID_ADC] = (uint32_t)at91_adc_isr; + aic->AIC_IECR = (1< +#include +#include "AT91SAM7S256.h" +#include "board.h" +#include "at91_dbgu.h" +#include "at91_sysc.h" +#include "fifo.h" + +static struct fifo *txfifo; + +static void dbgu_isr(uint32_t status) +{ + /* only enabled interrupts */ + status &= *AT91C_DBGU_IMR; +/* + if (status & AT91C_US_TXEMPTY) { + static char c; + if (c == '\n') { + *AT91C_DBGU_THR = '\r'; + c = 0; + + } else if (fifo_getbyte(&txfifo, &c) == 1) + *AT91C_DBGU_THR = c; + else + *AT91C_DBGU_IDR = AT91C_US_TXEMPTY; + } +*/ + if (status & AT91C_US_TXBUFE) + if (fifo_txpdc(txfifo, AT91C_BASE_PDC_DBGU, 16) == 0) + *AT91C_DBGU_IDR = AT91C_US_TXBUFE; +} + +void at91_dbgu_init(void) +{ + /* switch pins to UART */ + *AT91C_PIOA_PDR = AT91C_PA9_DRXD | AT91C_PA10_DTXD; + + /* enable Debug Port with 115200 Baud (+0.16%) */ + AT91S_DBGU *dbgu = AT91C_BASE_DBGU; + dbgu->DBGU_BRGR = BAUD_TO_DIV(115200); + dbgu->DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL; + dbgu->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN | AT91C_US_RSTSTA; + + txfifo = fifo_alloc(1024); + + /* enable TX PDC */ + dbgu->DBGU_PTCR = AT91C_PDC_TXTEN; + + sysc_register_isr(AT91_SYSIRQ_DBGU, dbgu_isr); +} + +void at91_dbgu_putc(char c) +{ + fifo_putbyte(txfifo, c); +// *AT91C_DBGU_IER = AT91C_US_TXEMPTY; + *AT91C_DBGU_IER = AT91C_US_TXBUFE; +} + +void at91_dbgu_puts(const char *p) +{ + fifo_put(txfifo, p, strlen(p)); +// *AT91C_DBGU_IER = AT91C_US_TXEMPTY; + *AT91C_DBGU_IER = AT91C_US_TXBUFE; +} + +int at91_dbgu_write(void *base, const char *buf, size_t len) +{ + int retval = fifo_put(txfifo, buf, len); +// *AT91C_DBGU_IER = AT91C_US_TXEMPTY; + *AT91C_DBGU_IER = AT91C_US_TXBUFE; + return retval; +} diff --git a/src/at91_exceptions.c b/src/at91_exceptions.c new file mode 100644 index 0000000..4b7517f --- /dev/null +++ b/src/at91_exceptions.c @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include +#include "AT91SAM7S256.h" +#include "board.h" + +static void dbgu_putchar(char c) +{ + while (!(*AT91C_DBGU_CSR & AT91C_US_TXEMPTY)); + *AT91C_DBGU_THR = c; + if (c == '\n') { + while (!(*AT91C_DBGU_CSR & AT91C_US_TXEMPTY)); + *AT91C_DBGU_THR = '\r'; + } +} + +static void dbgu_puts(const char *p) +{ + while (*p != '\0') + dbgu_putchar(*p++); +} + +static void dbgu_hexvar(const char *name, uint32_t var) +{ + dbgu_puts(name); + + char buf[11]; + buf[0] = '0'; + buf[1] = 'x'; + uint32_t i; + for (i = 9; i > 1; i--) { + buf[i] = (var & 0x0F); + buf[i] += (buf[i] < 0xa) ? '0' : ('a' - 0x0a); + var >>= 4; + } + buf[10] = '\0'; + dbgu_puts(buf); +} + +/* +ARM7TDMI 32bit Undefined Address Instruction Fetch Abort +(ASR:0x02020a01 AASR:0x80000008) +--- Registerdump (cpsr:0xa0000013 - SVC): + r0:0x00000002 r1:0x0000000c r2:0x00200038 r3:0x80000000 + r4:0x0020fffc r5:0x00101788 r6:0x00000180 r7:0x41000000 + r8:0x00008400 r9:0x00100004 r10:0x03000294 fp:0x0020fe84 +r12:0x0020fe10 sp:0x0020fe70 lr:0x00102174 pc:0x80000004 +--- Stackdump: +0x0020fe70: 0x0020fe7c 0x00101648 0x001015a8 0x0020feaf +0x0020fe80: 0x0020fec0 0x0020fe90 0x00101780 0x00101620 +0x0020fe90: 0x00000002 0x00000000 0x00000030 0x00000000 +0x0020fea0: 0x001029a8 0x307830b0 0x33383730 0x00303337 +*/ +void at91_abt_handler(uint32_t cpsr, uint32_t *registers) +{ + /* enable Debug Port with 115200 Baud (+0.16%) */ + AT91S_DBGU *dbgu = AT91C_BASE_DBGU; + dbgu->DBGU_BRGR = BAUD_TO_DIV(115200); + dbgu->DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL; + dbgu->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN | AT91C_US_RSTSTA; + + /* switch pins to UART */ + *AT91C_PIOA_PDR = AT91C_PA9_DRXD | AT91C_PA10_DTXD; + + + AT91_REG asr = *AT91C_MC_ASR; + if (asr & AT91C_MC_MST0) + dbgu_puts("PDC "); + else if (asr & AT91C_MC_MST1) + dbgu_puts("ARM7TDMI "); + + switch (asr & AT91C_MC_ABTSZ) { + case AT91C_MC_ABTSZ_BYTE: + dbgu_puts("8bit "); + break; + case AT91C_MC_ABTSZ_HWORD: + dbgu_puts("16bit "); + break; + case AT91C_MC_ABTSZ_WORD: + dbgu_puts("32bit "); + break; + } + + if (asr & AT91C_MC_UNDADD) + dbgu_puts("Undefined Address "); + else if (asr & AT91C_MC_MISADD) + dbgu_puts("Misaliged Address "); + + switch (asr & AT91C_MC_ABTTYP) { + case AT91C_MC_ABTTYP_DATAR: + dbgu_puts("Data Read "); + break; + + case AT91C_MC_ABTTYP_DATAW: + dbgu_puts("Data Write "); + break; + + case AT91C_MC_ABTTYP_FETCH: + dbgu_puts("Prefetch "); + break; + } + + dbgu_hexvar("Abort\n(ASR:", asr); + dbgu_hexvar(" AASR:", *AT91C_MC_AASR); + dbgu_puts(")\n"); + + dbgu_hexvar("--- Registerdump (cpsr:", cpsr); + dbgu_puts(" - "); + switch (cpsr & 0x1F) { + case 0x10: dbgu_puts("USR"); break; + case 0x11: dbgu_puts("FIQ"); break; + case 0x12: dbgu_puts("IRQ"); break; + case 0x13: dbgu_puts("SVC"); break; + case 0x17: dbgu_puts("ABT"); break; + case 0x1B: dbgu_puts("UND"); break; + case 0x1F: dbgu_puts("SYS"); break; + } + + dbgu_hexvar("):\n r0:", registers[3]); + dbgu_hexvar(" r1:", registers[4]); + dbgu_hexvar(" r2:", registers[5]); + dbgu_hexvar(" r3:", registers[6]); + dbgu_hexvar("\n r4:", registers[7]); + dbgu_hexvar(" r5:", registers[8]); + dbgu_hexvar(" r6:", registers[9]); + dbgu_hexvar(" r7:", registers[10]); + dbgu_hexvar("\n r8:", registers[11]); + dbgu_hexvar(" r9:", registers[12]); + dbgu_hexvar(" r10:", registers[13]); + dbgu_hexvar(" fp:", registers[14]); + dbgu_hexvar("\nr12:", registers[15]); + dbgu_hexvar(" sp:", registers[0]); + dbgu_hexvar(" lr:", registers[1]); + dbgu_hexvar(" pc:", registers[2]); + + dbgu_puts("\n--- Stackdump:"); + uint32_t *val = (uint32_t *)(registers[0] & ~0x0F); + for ( ; val < (uint32_t *)(registers[0] & ~0x0F) +16; val++) { + if (!((uint32_t)val & 0x0F)) { + dbgu_hexvar("\n", (uint32_t)val); + dbgu_putchar(':'); + } + dbgu_hexvar(" ", *val); + } + dbgu_putchar('\n'); +} diff --git a/src/at91_pio.c b/src/at91_pio.c new file mode 100644 index 0000000..6a990d4 --- /dev/null +++ b/src/at91_pio.c @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include +#include +#include "AT91SAM7S256.h" +#include "board.h" +#include "at91_pio.h" + +/* extern symbols, defined in ldscript */ +extern struct pio_pinchange_isr _pio_isr_table; +extern struct pio_pinchange_isr _pio_isr_table_end; + +static void pio_isr(void) +{ + uint32_t status = *AT91C_PIOA_ISR; + uint32_t input = *AT91C_PIOA_PDSR; + + struct pio_pinchange_isr *isr; + for (isr = &_pio_isr_table; isr < &_pio_isr_table_end; isr++) + if (isr->mask & status) + isr->func(status, input); +} + +void pio_trigger_isr(uint32_t mask) +{ + uint32_t input = *AT91C_PIOA_PDSR; + + struct pio_pinchange_isr *isr; + for (isr = &_pio_isr_table; isr < &_pio_isr_table_end; isr++) + if (isr->mask & mask) + isr->func(mask, input); +} + +void at91_pio_init(void) +{ + /* enable PIO clock */ + *AT91C_PMC_PCER = (1 << AT91C_ID_PIOA); + + /* enable pinchange interrupts */ + struct pio_pinchange_isr *isr; + for (isr = &_pio_isr_table; isr < &_pio_isr_table_end; isr++) + *AT91C_PIOA_IER = isr->mask; + + /* dummy read to clear interrupts */ + uint32_t dummy = *AT91C_PIOA_ISR; + dummy = dummy; + + /* low priority, level triggered, own vector */ + AT91S_AIC *aic = AT91C_BASE_AIC; + aic->AIC_SMR[AT91C_ID_PIOA] = IRQPRIO_PIOA | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; + aic->AIC_SVR[AT91C_ID_PIOA] = (uint32_t)pio_isr; + aic->AIC_IECR = (1 << AT91C_ID_PIOA); +} diff --git a/src/at91_pitc.c b/src/at91_pitc.c new file mode 100644 index 0000000..12f703a --- /dev/null +++ b/src/at91_pitc.c @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include "AT91SAM7S256.h" +#include "at91_pitc.h" +#include "at91_sysc.h" +#include "board.h" +#include "static_alloc.h" + +/* PIV is 20bit -> min. 3Hz @48MHz MCK */ +#define HZ_TO_PIV(HZ) (MCK / (16 * HZ)) + +static LIST_HEAD(timer_list); +volatile static uint32_t pitc_ticks; + +struct pitc_timer * alloc_pitc_timer(uint32_t interval, uint32_t (*func)(struct pitc_timer *), void *privdata) +{ + struct pitc_timer *timer = static_alloc(sizeof(struct pitc_timer)); + timer->interval = interval; + timer->func = func; + timer->privdata = privdata; + + return timer; +} + +void pitc_schedule_timer(struct pitc_timer *timer) +{ + timer->nextrun = timer->interval + pitc_ticks; + + struct pitc_timer *search; + list_for_each_entry(search, &timer_list, list) + if (search->nextrun > timer->nextrun) + break; + + list_add_tail(&timer->list, &search->list); +} + +static void pitc_isr(uint32_t status) +{ + /* get Ticks and clear interrupt */ + pitc_ticks += (*AT91C_PITC_PIVR & AT91C_PITC_PICNT) >> 20; + + struct pitc_timer *search, *tmp; + list_for_each_entry_safe(search, tmp, &timer_list, list) { + /* if this entry not scheduled yet, abort search */ + if (pitc_ticks < search->nextrun) + break; + + /* remove from list */ + list_del(&search->list); + + /* exec handler */ + if (search->func(search) == PITC_REMOVE_TIMER) { + /* one-shot timer, mark as completed */ + search->nextrun = 0x00; + continue; + } + /* interval timer, reschedule it */ + pitc_schedule_timer(search); + } +} + +uint32_t pitc_get_ticks(void) +{ + return pitc_ticks; +} + +void at91_pitc_init(void) +{ + sysc_register_isr(AT91_SYSIRQ_PIT, &pitc_isr); + + *AT91C_PITC_PIMR = (AT91C_PITC_PIV & HZ_TO_PIV(100)) | + AT91C_PITC_PITEN | + AT91C_PITC_PITIEN; +} diff --git a/src/at91_rttc_test.c b/src/at91_rttc_test.c new file mode 100644 index 0000000..ce6d9c2 --- /dev/null +++ b/src/at91_rttc_test.c @@ -0,0 +1,34 @@ +#include +#include "AT91SAM7S256.h" +#include "at91_sysc.h" +#include "board.h" + +static void rtt_isr(uint32_t status) +{ + *AT91C_RTTC_RTAR = *AT91C_RTTC_RTVR +1; +/* + static uint32_t i; + *AT91C_PIOA_SODR = i; + i = i ^ LED_ORANGE; + *AT91C_PIOA_CODR = i; +*/ +} + +void at91_rttc_test_init(void) +{ + /* calculate SLOWCK from MAINCK and measured MAINF */ + uint32_t prescaler = MAINCK * 16 / (*AT91C_CKGR_MCFR & AT91C_CKGR_MAINF); + + sysc_register_isr(AT91_SYSIRQ_RTT, &rtt_isr); + + /* + * AT91C_RTTC_RTTINCIEN doesn't work + * use AT91C_RTTC_ALMIEN and increment RTAR in isr + */ + *AT91C_RTTC_RTAR = *AT91C_RTTC_RTVR +1; + *AT91C_RTTC_RTMR = (AT91C_RTTC_RTPRES & prescaler) | + AT91C_RTTC_ALMIEN | + AT91C_RTTC_RTTRST; + + printf("rttc running at %ld Hz\n\r", prescaler); +} diff --git a/src/at91_sysc.c b/src/at91_sysc.c new file mode 100644 index 0000000..2789d6f --- /dev/null +++ b/src/at91_sysc.c @@ -0,0 +1,154 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include "AT91SAM7S256.h" +#include "at91_sysc.h" +#include "board.h" + +static SYSCISR *sysc_isrs[AT91_SYSIRQ_COUNT]; + +struct _irq_regs { + AT91_REG *mask_register; + uint32_t mask; + AT91_REG *status_register; + uint32_t status; +}; + +/* same IDs as sysc_isrs enum! */ +static const struct _irq_regs irq_regs[] = { + /* + * PIT (Periodic Intervall Timer) + * ISR must read AT91C_PITC_PIVR to clear interrupt + * - PITIEN (Periodic Intervall Timer Interrupt Enable) + */ + { AT91C_PITC_PIMR, AT91C_PITC_PITIEN, + AT91C_PITC_PISR, AT91C_PITC_PITS + }, + + /* + * DBGU (Debug Unit) + * TODO: must use AT91C_DBGU_IDR to fault disable interrupt + * - 12 Interrupt sources + */ + { AT91C_DBGU_IMR, (AT91C_US_RXRDY | AT91C_US_TXRDY | + AT91C_US_ENDRX | AT91C_US_ENDTX | + AT91C_US_OVRE | AT91C_US_FRAME | + AT91C_US_PARE | AT91C_US_TXEMPTY | + AT91C_US_TXBUFE | AT91C_US_RXBUFF | + AT91C_US_COMM_TX | AT91C_US_COMM_RX), + AT91C_DBGU_CSR, (AT91C_US_RXRDY | AT91C_US_TXRDY | + AT91C_US_ENDRX | AT91C_US_ENDTX | + AT91C_US_OVRE | AT91C_US_FRAME | + AT91C_US_PARE | AT91C_US_TXEMPTY | + AT91C_US_TXBUFE | AT91C_US_RXBUFF | + AT91C_US_COMM_TX | AT91C_US_COMM_RX) + }, + + /* + * EFC (Embedded Flash Controller / Memory Controller) + */ + { AT91C_MC_FMR, (AT91C_MC_FRDY | AT91C_MC_LOCKE | AT91C_MC_PROGE), + AT91C_MC_FSR, (AT91C_MC_FRDY | AT91C_MC_LOCKE | AT91C_MC_PROGE) + }, + + /* + * WDT (Watchdog Timer) + * WDMR can be written only once (no fault disable) + * - WDFIEN (Watchdog Fault Interrupt Enable) + */ + { AT91C_WDTC_WDMR, AT91C_WDTC_WDFIEN, + AT91C_WDTC_WDSR, (AT91C_WDTC_WDUNF | AT91C_WDTC_WDERR) + }, + + /* + * RTT (Real-Time Timer) + * Interrupts must be disabled during ISR?! + * - ALMIEN (Alarm Interrupt Enable) + * - RTTCINCIEN (Real-Time Timer Increment Interrupt Enable) + */ + { AT91C_RTTC_RTMR, (AT91C_RTTC_ALMIEN | AT91C_RTTC_RTTINCIEN), + AT91C_RTTC_RTSR, (AT91C_RTTC_ALMS | AT91C_RTTC_RTTINC) + }, + + /* + * RSTC (Reset Controller) + * - AT91C_RSTC_URSTIEN (User Reset Interrupt Enable) + * - AT91C_RSTC_BODIEN (Brownout Detection Interrupt Enable) + */ + { AT91C_RSTC_RMR, (AT91C_RSTC_URSTIEN | AT91C_RSTC_BODIEN), + AT91C_RSTC_RSR, (AT91C_RSTC_URSTS | AT91C_RSTC_BODSTS) + }, + + /* + * PMC (Power Managment Controller) + * TODO: must use AT91C_PMC_IDR to fault disable interrupt + * - 6 Interrupt sources + */ + { AT91C_PMC_IMR, (AT91C_PMC_MOSCS | AT91C_PMC_LOCK | + AT91C_PMC_MCKRDY | AT91C_PMC_PCK0RDY | + AT91C_PMC_PCK1RDY | AT91C_PMC_PCK2RDY), + AT91C_PMC_SR, (AT91C_PMC_MOSCS | AT91C_PMC_LOCK | + AT91C_PMC_MCKRDY | AT91C_PMC_PCK0RDY | + AT91C_PMC_PCK1RDY | AT91C_PMC_PCK2RDY) + }, +}; + +/* check Interrupts from internal hardware */ +static void at91_sysc_isr(void) +{ + uint32_t id; + for (id = 0; id < AT91_SYSIRQ_COUNT; id++) { + + /* check if interrups are enabled */ + if (*(irq_regs[id].mask_register) & irq_regs[id].mask) { + + /* check if interrupts are active */ + uint32_t status = *(irq_regs[id].status_register); + if (status & irq_regs[id].status) { + + /* execute handler */ + if (sysc_isrs[id]) { + sysc_isrs[id](status); + + } else { + /* disable interrupts */ + *(irq_regs[id].mask_register) &= ~irq_regs[id].mask; + } + } + } + } +} + +void at91_sysc_init(void) +{ + /* high priority, level triggered, own vector */ + AT91S_AIC *aic = AT91C_BASE_AIC; + aic->AIC_SMR[AT91C_ID_SYS] = IRQPRIO_SYSC | + AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; + + aic->AIC_SVR[AT91C_ID_SYS] = (uint32_t)at91_sysc_isr; + aic->AIC_IECR = (1<= AT91_SYSIRQ_COUNT) + return; + + sysc_isrs[irq] = isr; +} diff --git a/src/at91_tc1.c b/src/at91_tc1.c new file mode 100644 index 0000000..bb50109 --- /dev/null +++ b/src/at91_tc1.c @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include +#include +#include "AT91SAM7S256.h" +#include "board.h" +#include "at91_tc1.h" + +#define ROUND_DIV256(x) ((x >> 8) + ((x & 0x80) ? 1 : 0)) + +static uint32_t ppm_arr[MAX_CHANNELS]; +static uint32_t ch, cnt, valid; + +static void ppm_isr(void) +{ + /* RC Compare -> no TIOA1 edge for 2.5ms */ + uint32_t status = *AT91C_TC1_SR; + if (status & AT91C_TC_CPCS) { + + /* average channel count */ + cnt = ((cnt * 7) + (ch << 8)) / 8; + + /* at least 4 channels and a stable channel count */ + valid = (ROUND_DIV256(cnt) == ch) && (ch >= 4); + + /* reset index */ + ch = 0; + } + + /* edge on TIOA1 */ + if (status & AT91C_TC_LDRAS) { + /* get impulse width */ + uint16_t ra = *AT91C_TC1_RA; + + /* valid range: 1 - 2ms */ + if (ra > 0x0500 && ra < 0x0D00) { + if (ch < ARRAY_SIZE(ppm_arr)) + ppm_arr[ch] = ((ppm_arr[ch] * 3) + ra) / 4; + + ch++; + } + } +} + +/* +struct cal_data { + uint16_t min; + uint16_t mid; + uint16_t max; +}; + +int16_t getval(struct cal_data *cal, uint16_t input) +{ + int32_t x = (input - cal->mid) * 1024; + uint32_t y = (x > 0) ? (cal->max - cal->mid) : (cal->mid - cal->min); + + return x / y; +} +*/ + +uint32_t rc_ppm_getvalues(struct rc_values *rc) +{ + uint32_t i; + rc->count = MIN(ROUND_DIV256(cnt), ARRAY_SIZE(ppm_arr)); + for (i = 0; i < rc->count; i++) + rc->ch[i] = (ppm_arr[i] - 0x8C0); + + return valid; +} + +void at91_tc1_init(void) +{ + /* enable TC1 clock */ + *AT91C_PMC_PCER = (1 << AT91C_ID_TC1); + + /* MCK /32, trigger & capture on falling TIOA1 edge */ + *AT91C_TC1_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | AT91C_TC_LDRA_FALLING | + AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG; + + /* enable RA load and RC compare interrupt */ + *AT91C_TC1_IER = AT91C_TC_LDRAS | AT91C_TC_CPCS; + + /* RC Compare Interrupt if no rising Edge on TIOA1 for 2.56ms */ + *AT91C_TC1_RC = 0x0F00; + + /* enable & trigger the clock */ + *AT91C_TC1_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + + /* level triggered, own vector */ + AT91S_AIC *aic = AT91C_BASE_AIC; + aic->AIC_SMR[AT91C_ID_TC1] = IRQPRIO_TC1 | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; + aic->AIC_SVR[AT91C_ID_TC1] = (uint32_t)ppm_isr; + aic->AIC_IECR = (1 << AT91C_ID_TC1); +} diff --git a/src/at91_twi.c b/src/at91_twi.c new file mode 100644 index 0000000..0d55310 --- /dev/null +++ b/src/at91_twi.c @@ -0,0 +1,241 @@ +/*************************************************************************** + * Copyright (C) 02/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include +#include + +#include "AT91SAM7S256.h" +#include "board.h" +#include "at91_twi.h" +#include "at91_pio.h" + +/* + * undocumented TWI_SR flags, at least OVRE seems to be present on a sam7s256 + * taken from linux-2.6.24/include/asm-arm/arch-at91/at91_twi.h + */ +#define AT91_TWI_OVRE (1<<6) /* Overrun */ +#define AT91_TWI_UNRE (1<<7) /* Underrun */ + +/* + * while ((cldiv = ((MCK / (2 * TWI)) -3) / (1 << ckdiv)) > 255) + * ckdiv++ ; + * + * works for TWI >= 100kHz + */ +#define TWI_CLK(x) (((MCK / (2 * (x))) -3)<<8 | ((MCK / (2 * (x))) -3)) + +enum twi_states { + TWI_IDLE = 0x00, + TWI_ERROR, + TWI_GENERIC_CMD = 0x10, + TWI_BLMC_UPDATE = 0x20, +}; + +static volatile uint32_t twi_state = TWI_IDLE; +static uint8_t *twi_data; +static uint32_t twi_size; +static uint32_t twi_count; + +static void twi_isr(void) +{ + /* get status */ + uint32_t status = *AT91C_TWI_SR; + status &= *AT91C_TWI_IMR; + + /* NACK - disable all interrupts and go to state TWI_ERROR */ + if (status & AT91C_TWI_NACK) { + *AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK; + twi_state = TWI_ERROR; + + // TODO: TWI_BLMC_UPDATE? + return; + } + + /* tx register ready for new data */ + if (status & AT91C_TWI_TXRDY) { + if (twi_count != twi_size) { + /* feed next byte */ + *AT91C_TWI_THR = twi_data[twi_count++]; + + } else { + /* wait for TXCOMP */ + *AT91C_TWI_IDR = AT91C_TWI_RXRDY | AT91C_TWI_TXRDY; + *AT91C_TWI_IER = AT91C_TWI_TXCOMP | AT91C_TWI_NACK; + } + } + + /* rx register has data */ + if (status & AT91C_TWI_RXRDY) { + /* get data */ + twi_data[twi_count++] = *AT91C_TWI_RHR; + + /* transfer complete? */ + if (twi_count == twi_size) { + /* send STOP and wait for TXCOMP */ + *AT91C_TWI_CR = AT91C_TWI_STOP; + *AT91C_TWI_IDR = AT91C_TWI_TXRDY; + *AT91C_TWI_IER = AT91C_TWI_TXCOMP | AT91C_TWI_NACK; + } + } + + /* transfer really complete? */ + if (status & AT91C_TWI_TXCOMP) { + + /* are we doing a blmc update? */ + if (twi_state == TWI_BLMC_UPDATE) { + uint32_t addr = (*AT91C_TWI_MMR >> 16) & 0x7F; + if (addr != TWI_ADDR_BL4) { + /* increase address */ + *AT91C_TWI_MMR += (1<<16); + + /* send next value to next blmc */ + *AT91C_TWI_THR = *twi_data++; + } else { + // TODO: + } + + } else { + *AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK; + twi_state = TWI_IDLE; + } + } +} + +uint32_t twi_setpwm(uint8_t *values) +{ + if (twi_state != TWI_IDLE) + return 1; + + twi_state = TWI_BLMC_UPDATE; + twi_data = values; /* data is not copied! */ + twi_size = 0; + twi_count = 0; + + *AT91C_TWI_MMR = (TWI_ADDR_BL1 << 16) | AT91C_TWI_IADRSZ_1_BYTE; + *AT91C_TWI_IADR = CMD_SET_PWM; + + *AT91C_TWI_THR = *twi_data++; + *AT91C_TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK; + + return 0; +} + +uint32_t twi_cmd(uint8_t addr, struct blmc_cmd *cmd) +{ + if (twi_state != TWI_IDLE) + return 1; + + /* TODO: locking needed? */ + twi_state = TWI_GENERIC_CMD; + + /* read transfer, or write transfer with payload */ + if (cmd->mode & BLMC_CMD_READ || cmd->size != 0) { + /* set address, direction, argument count and command bytes */ + *AT91C_TWI_MMR = (addr << 16) | (cmd->mode & 0xFF) << 8; + *AT91C_TWI_IADR = cmd->cmd; + + /* write transfer without payload */ + } else { + /* use one cmd byte as payload (needed to start transfer) */ + cmd->mode--; + *AT91C_TWI_MMR = (addr << 16) | (cmd->mode & 0xFF) << 8; + *AT91C_TWI_IADR = (cmd->cmd) >> 8; + } + + /* isr needs data & size parameters */ + twi_data = cmd->data; + twi_size = cmd->size; + twi_count = 0; + + if (cmd->mode & BLMC_CMD_READ) { + *AT91C_TWI_CR = AT91C_TWI_START; + *AT91C_TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK; + + } else { + *AT91C_TWI_THR = (twi_size != 0) ? cmd->data[twi_count++] : (cmd->cmd & 0xFF); + *AT91C_TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK; + } + + /* + * wait for end + * TODO: locking needed? + * TODO: timeout? + */ + while (twi_state != TWI_IDLE && twi_state != TWI_ERROR); + if (twi_state != TWI_IDLE) { + twi_state = TWI_IDLE; + return 1; + } + + return 0; +} + +void at91_twi_test(void) +{ + uint32_t i; + for (i = TWI_ADDR_BL1; i <= TWI_ADDR_BL4; i++) { + uint8_t buf[16]; + struct blmc_cmd cmd = { + .cmd = CMD_GET_INFO, + .mode = BLMC_CMD_READ | BLMC_CMD_0_ARG, + .size = sizeof(buf), + .data = buf, + }; + + uint32_t retval = twi_cmd(i, &cmd); + printf("twi(0x%02lx): %ld '%s' ", i, retval, buf); + + cmd.cmd = CMD_GET_SIGNATURE; + cmd.size = 4; + twi_cmd(i, &cmd); + printf("(sig: 0x%02x%02x%02x)\n\r", buf[0], buf[1], buf[2]); + + cmd.cmd = CMD_BOOT_APPLICATION; + cmd.mode = BLMC_CMD_WRITE | BLMC_CMD_0_ARG; + cmd.size = 0; + twi_cmd(i, &cmd); + } +} + +void at91_twi_init(void) +{ + /* enable Clock */ + *AT91C_PMC_PCER = (1 << AT91C_ID_TWI); + + /* SDA & SCL from Peripheral A, Open Drain, no Pullup */ + AT91S_PIO *pio = AT91C_BASE_PIOA; + pio->PIO_ASR = AT91C_PA3_TWD | AT91C_PA4_TWCK; + pio->PIO_PDR = AT91C_PA3_TWD | AT91C_PA4_TWCK; + pio->PIO_MDER = AT91C_PA3_TWD | AT91C_PA4_TWCK; + pio->PIO_PPUDR = AT91C_PA3_TWD | AT91C_PA4_TWCK; + + /* set TWI Clock */ + *AT91C_TWI_CWGR = TWI_CLK(200000) | (5<<16); + + /* disable all (known) interrupts */ + *AT91C_TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY | AT91C_TWI_TXRDY | AT91C_TWI_NACK; + + /* level triggered, own vector */ + AT91S_AIC *aic = AT91C_BASE_AIC; + aic->AIC_SMR[AT91C_ID_TWI] = IRQPRIO_TWI | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; + aic->AIC_SVR[AT91C_ID_TWI] = (uint32_t)twi_isr; + aic->AIC_IECR = (1 << AT91C_ID_TWI); + + /* enable teh monster */ + *AT91C_TWI_CR = AT91C_TWI_MSEN; +} diff --git a/src/at91_udp.c b/src/at91_udp.c new file mode 100644 index 0000000..5647bbc --- /dev/null +++ b/src/at91_udp.c @@ -0,0 +1,520 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include + +#include "AT91SAM7S256.h" +#include "at91_pio.h" +#include "board.h" + +#include "usb_ch9.h" +#include "usb_cdc.h" +#include "usb_dfu.h" + +#define csr_clear_flags(csr, flags) \ + while ((csr) & (flags)) \ + (csr) &= ~(flags); + +#define csr_set_flags(csr, flags) \ + while (((csr) & (flags)) != (flags)) \ + (csr) |= (flags); + +// TODO: name? +struct udp_transfer { + uint16_t address; + uint16_t maxpkt; + // TODO: last bank used / ping pong + + // TODO: direction (IN/OUT) + uint16_t length; + uint16_t curpos; + + char *data; + void (*complete_cb)(void); + // TODO: privdata? +}; + +static uint16_t current_address; +static uint16_t current_config; +static uint16_t current_interface; +static struct udp_transfer ep_transfer[4]; + +static const struct usb_device_descriptor dev_descriptor = { + .bLength = sizeof(struct usb_device_descriptor), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0110, + .bMaxPacketSize0 = 8, + .idVendor = USB_VENDOR_ID, + .idProduct = USB_PRODUCT_ID +1, + .bcdDevice = 0x0001, + .bNumConfigurations = 1, +}; + +struct my_config { + struct usb_config_descriptor cfg; + struct usb_interface_descriptor ctrl_iface; + struct usb_cdc_header_desc cdc_header; + struct usb_cdc_call_mgmt_descriptor cdc_call_mgmt; + struct usb_cdc_acm_descriptor cdc_acm; + struct usb_cdc_union_desc cdc_union; + struct usb_endpoint_descriptor notify_ep; + struct usb_interface_descriptor data_iface; + struct usb_endpoint_descriptor dataout_ep; + struct usb_endpoint_descriptor datain_ep; + struct usb_interface_descriptor dfu_iface; + struct usb_dfu_descriptor dfu; +} __attribute__ ((packed)); + +static const struct my_config cfg_descriptor = { +.cfg = { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DT_CONFIG, + .wTotalLength = sizeof(struct my_config), + .bNumInterfaces = 3, + .bConfigurationValue = 1, + .bmAttributes = USB_CONFIG_ATT_SELFPOWER | USB_CONFIG_ATT_WAKEUP, + .bMaxPower = 50, +}, +.ctrl_iface = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = 1, +}, +.cdc_header = { + .bLength = sizeof(struct usb_cdc_header_desc), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_HEADER_TYPE, + .bcdCDC = 0x0110, +}, +.cdc_call_mgmt = { + .bLength = sizeof(struct usb_cdc_call_mgmt_descriptor), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, + .bmCapabilities = USB_CDC_CALL_MGMT_CAP_CALL_MGMT, + .bDataInterface = 1, +}, +.cdc_acm = { + .bLength = sizeof(struct usb_cdc_acm_descriptor), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_ACM_TYPE, + .bmCapabilities = (USB_CDC_CAP_BRK | USB_CDC_CAP_LINE | USB_CDC_COMM_FEATURE), +}, +.cdc_union = { + .bLength = sizeof(struct usb_cdc_union_desc), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = USB_CDC_UNION_TYPE, + .bMasterInterface0 = 0, + .bSlaveInterface0 = 1, +}, +.notify_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN | 0x03, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = 64, + .bInterval = 10, +}, +.data_iface = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 1, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, +}, +.dataout_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT | 0x01, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = 64, +}, +.datain_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN | 0x02, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = 64, +}, +.dfu_iface = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 2, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_APP_SPEC, + .bInterfaceSubClass = 0x01, /* DFU */ +}, +.dfu = { + .bLength = sizeof(struct usb_dfu_descriptor), + .bDescriptorType = USB_TYPE_DFU, + .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD, + .wDetachTimeOut = 0xff00, + .wTransferSize = AT91C_IFLASH_PAGE_SIZE, + .bcdDFUVersion = 0x0100, +}, +}; + +static struct dfu_status dfu_status = { + .bStatus = DFU_STATUS_OK, + .bwPollTimeout = {0x00, 0x04, 0x00}, + .bState = DFU_STATE_appIDLE, +}; + +static void udp_configure_ep(const struct usb_endpoint_descriptor *desc) +{ + /* get endpoint type (ctrl, iso, bulb, int) */ + uint32_t eptype = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + eptype |= 0x04; + + /* get endpoint address, set Max Packet Size */ + uint32_t address = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_transfer[address].maxpkt = desc->wMaxPacketSize; + + /* configure UDP endpoint and enable interrupt */ + AT91C_UDP_CSR[address] = AT91C_UDP_EPEDS | (eptype << 8); + *AT91C_UDP_IER = (1 << address); +} + +static void udp_fill_fifo(struct udp_transfer *trans) +{ + uint16_t ep = trans->address; + + if (AT91C_UDP_CSR[ep] & AT91C_UDP_TXPKTRDY) { + printf("TX!RDY\n\r"); + return; + } + + /* fill fifo */ + uint16_t max = trans->maxpkt; + while (trans->curpos < trans->length && max--) + AT91C_UDP_FDR[ep] = trans->data[trans->curpos++]; + + /* trigger transmission */ + AT91C_UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY; +} + +static void udp_send_data(struct udp_transfer *trans, const char *data, + uint32_t length, void (*complete_cb)(void)) +{ + if (trans->length != trans->curpos) { + printf("TXOVF\n\r"); + return; + } + + /* setup data transmission */ + trans->length = length; + trans->curpos = 0; + trans->data = (char *)data; + trans->complete_cb = complete_cb; + + udp_fill_fifo(trans); +} + +/* stalls the endpoint */ +static void udp_send_stall(uint32_t ep) +{ + printf("stall\n\r"); + AT91C_UDP_CSR[ep] |= AT91C_UDP_FORCESTALL; +} + +/* + * set local address + * (USB_REQ_SET_ADDRESS callback) + */ +static void udp_txcb_setaddress(void) +{ + *AT91C_UDP_FADDR = (AT91C_UDP_FEN | current_address); + *AT91C_UDP_GLBSTATE = AT91C_UDP_FADDEN; +} + +/* + * configure endpoints + * (USB_REQ_SET_CONFIGURATION callback) + */ +static void udp_txcb_setconfig(void) +{ + udp_configure_ep(&cfg_descriptor.notify_ep); + udp_configure_ep(&cfg_descriptor.datain_ep); + udp_configure_ep(&cfg_descriptor.dataout_ep); + + /* set UDP to "configured" */ + *AT91C_UDP_GLBSTATE = AT91C_UDP_CONFG; +} + +static void udp_txcb_setinterface(void) +{ + printf("claim interface %d\n\r", current_interface); +} + +static void udp_handle_ctrlrequest(struct usb_ctrlrequest *req) +{ + printf("typ:0x%02x req:0x%02x val:0x%04x idx:0x%04x len:0x%04x\n\r", + req->bRequestType, req->bRequest, req->wValue, req->wIndex, req->wLength); + + switch (req->bRequestType & (USB_TYPE_MASK | USB_RECIP_MASK)) { + case (USB_TYPE_STANDARD | USB_RECIP_DEVICE): /* 0x00/0x80 */ + switch (req->bRequest) { + case USB_REQ_SET_ADDRESS: /* 0x05 */ + current_address = req->wValue; + udp_send_data(&ep_transfer[0], NULL, 0, udp_txcb_setaddress); + break; + + case USB_REQ_GET_DESCRIPTOR: /* 0x06 */ + switch (req->wValue >> 8) { + case USB_DT_DEVICE: /* 0x01 */ + udp_send_data(&ep_transfer[0], (const char *)&dev_descriptor, + MIN(sizeof(dev_descriptor), req->wLength), NULL); + break; + + case USB_DT_CONFIG: /* 0x02 */ + udp_send_data(&ep_transfer[0], (const char *)&cfg_descriptor, + MIN(sizeof(cfg_descriptor), req->wLength), NULL); + break; + + default: + udp_send_stall(0); + break; + } + break; + + case USB_REQ_SET_CONFIGURATION: /* 0x09 */ + current_config = req->wValue; + udp_send_data(&ep_transfer[0], NULL, 0, udp_txcb_setconfig); + break; + + default: + udp_send_stall(0); + break; + } + break; + + case (USB_TYPE_STANDARD | USB_RECIP_INTERFACE): /* 0x01/0x81 */ + // TODO: follow current_interface + switch (req->bRequest) { + case USB_REQ_SET_INTERFACE: /* 0x0b */ + current_interface = req->wIndex; + udp_send_data(&ep_transfer[0], NULL, 0, udp_txcb_setinterface); + break; + + default: + udp_send_stall(0); + break; + } + break; + + case (USB_TYPE_CLASS | USB_RECIP_INTERFACE): /* 0x21/0xA1 */ + // TODO: follow current_interface + switch (req->bRequest) { + case USB_REQ_DFU_DETACH: /* 0x00 */ + udp_send_data(&ep_transfer[0], NULL, 0, NULL); + break; + + case USB_REQ_DFU_GETSTATUS: /* 0x03 */ + udp_send_data(&ep_transfer[0], (const char *)&dfu_status, + MIN(sizeof(struct dfu_status), req->wLength), NULL); + break; + + case USB_CDC_REQ_SET_LINE_CODING: /* 0x20 */ + // TODO: read 7 data bytes + udp_send_data(&ep_transfer[0], NULL, 0, NULL); + break; + + case USB_CDC_REQ_SET_CONTROL_LINE_STATE: /* 0x22 */ + udp_send_data(&ep_transfer[0], NULL, 0, NULL); + break; + + default: + udp_send_stall(0); + break; + } + break; + + default: + udp_send_stall(0); + break; + } +} + +static void udp_handle_ep(uint32_t ep) +{ + AT91_REG *csr = &AT91C_UDP_CSR[ep]; + + /* endpoint enabled? */ + if (!(*csr & AT91C_UDP_EPEDS)) + return; + + /* ctrl request packet? */ + if (*csr & AT91C_UDP_RXSETUP) { + struct usb_ctrlrequest req; + uint8_t *p; + for (p = (uint8_t *)&req; p < (uint8_t *)(&req +1); p++) + *p = AT91C_UDP_FDR[ep]; + + /* set data phase transfer direction */ + if (req.bRequestType & USB_DIR_IN) + *csr |= AT91C_UDP_DIR; + + /* clear interrupt (THIS MUST USE csr_clear_flags()!) */ + csr_clear_flags(*csr, AT91C_UDP_RXSETUP); + + udp_handle_ctrlrequest(&req); + } + + /* transmit complete? */ + if (*csr & AT91C_UDP_TXCOMP) { + struct udp_transfer *trans = &ep_transfer[ep]; + + /* refill fifo, if transfer is incomplete */ + if (trans->length != trans->curpos) + udp_fill_fifo(trans); + + /* execute callback when transfer is complete */ + else if (trans->complete_cb) + trans->complete_cb(); + + /* clear interrupt */ + *csr &= ~(AT91C_UDP_TXCOMP); + } + + /* clear STALLSENT interrupt */ + if (*csr & AT91C_UDP_STALLSENT) + csr_clear_flags(*csr, (AT91C_UDP_STALLSENT | AT91C_UDP_FORCESTALL)); + + /* data ready to read? */ + if (*csr & (AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1)) { + uint16_t len = (*csr & AT91C_UDP_RXBYTECNT) >> 16; + if (len) { + printf("rx: "); + while (len--) + printf("0x%02x ", AT91C_UDP_FDR[ep]); + + printf("\n\r"); + + } else { + /* clear a pending transfer! */ + ep_transfer[ep].length = 0; + ep_transfer[ep].curpos = 0; + } + + /* TODO: ping pong FIFOs */ + if (*csr & AT91C_UDP_RX_DATA_BK0) + csr_clear_flags(*csr, AT91C_UDP_RX_DATA_BK0); + + if (*csr & AT91C_UDP_RX_DATA_BK1) + csr_clear_flags(*csr, AT91C_UDP_RX_DATA_BK1); + } +} + +static void udp_isr(void) +{ + uint32_t isr = *AT91C_UDP_ISR; + + if (isr & AT91C_UDP_ENDBUSRES) { + printf("usb reset\n\r"); + + AT91S_UDP *udp = AT91C_BASE_UDP; + + /* reset all endpoints */ + udp->UDP_RSTEP = (AT91C_UDP_EP0 | AT91C_UDP_EP1 | + AT91C_UDP_EP2 | AT91C_UDP_EP3) ; + udp->UDP_RSTEP = 0; + + /* clear all transfers, set default values */ + uint32_t i; + for (i = 0; i < 4; i++) { + ep_transfer[i].address = i; + ep_transfer[i].maxpkt = 64; + ep_transfer[i].length = 0; + ep_transfer[i].curpos = 0; + } + ep_transfer[0].maxpkt = 8; + + /* Configure endpoint0 as Control EP */ + udp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL); + + /* enable ep0 Interrupt, disable all others */ + udp->UDP_IER = AT91C_UDP_EPINT0; + udp->UDP_IDR = AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2 | AT91C_UDP_EPINT3 | + AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM | AT91C_UDP_SOFINT | + AT91C_UDP_WAKEUP; + } + + /* Handle Endpoint Interrupts */ + uint32_t i; + for (i = 0; i < 4; i++) { + if (isr & (1<PIO_CODR = UDP_PULLUP; + pio->PIO_PER = UDP_PULLUP; + pio->PIO_OER = UDP_PULLUP; + // TODO: needed? + pio->PIO_PPUDR = UDP_VBUS_MON; + + /* UDPCK (48MHz) = PLLCK / 2 */ + *AT91C_CKGR_PLLR |= AT91C_CKGR_USBDIV_1; + + /* enable UDP clocks */ + *AT91C_PMC_SCER = AT91C_PMC_UDP; + *AT91C_PMC_PCER = (1 << AT91C_ID_UDP); + + /* enable transmitter */ + *AT91C_UDP_TXVC &= ~AT91C_UDP_TXVDIS; + + /* clear & disable all UDP interrupts */ + *AT91C_UDP_IDR = AT91C_UDP_EPINT0 | AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2 | + AT91C_UDP_EPINT3 | AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM | + AT91C_UDP_SOFINT | AT91C_UDP_WAKEUP; + + *AT91C_UDP_ICR = AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM | AT91C_UDP_SOFINT | + AT91C_UDP_ENDBUSRES | AT91C_UDP_WAKEUP ; + + /* level triggered, own vector */ + AT91S_AIC *aic = AT91C_BASE_AIC; + aic->AIC_SMR[AT91C_ID_UDP] = IRQPRIO_UDP | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL; + aic->AIC_SVR[AT91C_ID_UDP] = (uint32_t)udp_isr; + aic->AIC_IECR = (1 << AT91C_ID_UDP); + + pio_trigger_isr(UDP_VBUS_MON); +} + +static void udp_vbus_monitor(uint32_t status, uint32_t input) +{ + if (input & UDP_VBUS_MON) + /* usb connected -> enable pullup */ + *AT91C_PIOA_SODR = UDP_PULLUP; + else + /* usb got diconnected -> disable pullup */ + *AT91C_PIOA_CODR = UDP_PULLUP; +} + +PIO_PINCHANGE_ISR(UDP_VBUS_MON, udp_vbus_monitor); diff --git a/src/fifo.c b/src/fifo.c new file mode 100644 index 0000000..0f150a0 --- /dev/null +++ b/src/fifo.c @@ -0,0 +1,192 @@ +/*************************************************************************** + * Copyright (C) 01/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include "AT91SAM7S256.h" +#include "atomic.h" +#include "fifo.h" +#include "static_alloc.h" + +#define FIFO_MASK(x) ((x)->size -1) + +/* + * get used bytes (under lock) + * all other operations don't need locks: + * - only fifo_put/fifo_rxpdc are allowed to increment fifo->in + * - only fifo_get/fifo_txpdc are allowed to increment fifo->out + * a integer overflow (4gb) of fifo->in / fifo->out could cause trouble + */ +static uint32_t fifo_used(struct fifo *fifo) +{ + disable_irqs(); + uint32_t used = fifo->in - fifo->out; + restore_irqs(); + return used; +} + +/* + * append data to fifo + * returns number of bytes copied + */ +uint32_t fifo_put(struct fifo *fifo, const char *buf, uint32_t len) +{ + uint32_t left = fifo->size - fifo_used(fifo); + if (len > left) + len = left; + + uint32_t count = len; + while (count--) + fifo->buf[fifo->in++ & FIFO_MASK(fifo)] = *buf++; + + return len; +} + +/* + * get data from fifo + * returns number of bytes copied + */ +uint32_t fifo_get(struct fifo *fifo, char *buf, uint32_t len) +{ + uint32_t used = fifo_used(fifo); + if (len > used) + len = used; + + uint32_t count = len; + while (count--) + *buf++ = fifo->buf[fifo->out++ & FIFO_MASK(fifo)]; + + return len; +} + +/* + * receive data via PDC and put it into fifo + */ +uint32_t fifo_rxpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize) +{ + /* account previous PDC transfer */ + fifo->in += fifo->pdc_rx; + + uint32_t free = fifo->size - fifo_used(fifo); + if (free) { + /* calc pointer for next transfer */ + uint32_t first_idx = (fifo->in & FIFO_MASK(fifo)); + pdc->PDC_RPR = (uint32_t)(fifo->buf + first_idx); + + /* check for buffer end -> split transfer */ + if (first_idx + free <= (fifo->size -1)) { + fifo->pdc_rx = free; + } else { + fifo->pdc_rx = fifo->size - first_idx; + } + + /* split in maxsize chunks */ + if (maxsize && fifo->pdc_rx > maxsize) + fifo->pdc_rx = maxsize; + + /* start transfer */ + pdc->PDC_RCR = fifo->pdc_rx; + + } else { + /* no data in buffer */ + fifo->pdc_rx = 0; + } + + return fifo->pdc_rx; +} + +/* + * transmit fifo via PDC + * returns 0 if no transfer was started + */ +uint32_t fifo_txpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize) +{ + /* account previous PDC transfer */ + fifo->out += fifo->pdc_tx; + + uint32_t used = fifo_used(fifo); + if (used) { + /* calc pointer for next transfer */ + uint32_t first_idx = (fifo->out & FIFO_MASK(fifo)); + pdc->PDC_TPR = (uint32_t)(fifo->buf + first_idx); + + /* check for buffer end -> split transfer */ + if (first_idx + used <= (fifo->size -1)) { + fifo->pdc_tx = used; + } else { + fifo->pdc_tx = fifo->size - first_idx; + } + + /* split in maxsize chunks */ + if (maxsize && fifo->pdc_tx > maxsize) + fifo->pdc_tx = maxsize; + + /* start transfer */ + pdc->PDC_TCR = fifo->pdc_tx; + + } else { + /* no data in buffer */ + fifo->pdc_tx = 0; + } + + return fifo->pdc_tx; +} + +/* + * put one byte into the fifo + * returns 0 if fifo was full + */ +uint32_t fifo_putbyte(struct fifo *fifo, char c) +{ + uint32_t left = fifo->size - fifo_used(fifo); + if (left) { + fifo->buf[fifo->in++ & FIFO_MASK(fifo)] = c; + return 1; + } + return 0; +} + +/* + * gets one byte from fifo + * returns 0 if fifo was empty + */ +uint32_t fifo_getbyte(struct fifo *fifo, char *p) +{ + uint32_t used = fifo_used(fifo); + if (used) { + *p = fifo->buf[fifo->out++ & FIFO_MASK(fifo)]; + return 1; + } + return 0; +} + +/* + * allocs a fifo from static_alloc space + */ +struct fifo * fifo_alloc(uint32_t size) +{ + size = next_powerof2(size); + + struct fifo *fifo = static_alloc(sizeof(struct fifo) + size); + fifo->size = size; + + fifo->in = 0; + fifo->out = 0; + fifo->pdc_tx = 0; + fifo->pdc_rx = 0; + + return fifo; +} diff --git a/src/static_alloc.c b/src/static_alloc.c new file mode 100644 index 0000000..0251421 --- /dev/null +++ b/src/static_alloc.c @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 02/2008 by Olaf Rempel * + * razzor@kopf-tisch.de * + * * + * 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; version 2 of the License * + * * + * 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. * + ***************************************************************************/ +#include +#include "AT91SAM7S256.h" +#include "board.h" +//#include "static_alloc.h" + +#define ALIGN(x) (((x) +3) & ~3) + +/* extern symbols, defined in ldscript */ +extern void * __bss_end__; +extern void * __stack_top__; + +static uint32_t static_alloc_pos; + +void * static_alloc(uint32_t size) +{ + if (static_alloc_pos == 0) + static_alloc_pos = ALIGN((uint32_t)&__bss_end__); + + uint32_t retval = static_alloc_pos; + + size = ALIGN(size); + static_alloc_pos += size; + + return (void *)retval; +} + +uint32_t static_alloc_used(void) +{ + return static_alloc_pos - (uint32_t)&__bss_end__; +} + +// TODO: find a better place +uint32_t next_powerof2(uint32_t value) +{ + uint32_t i; + + value--; + for (i = 1; i < 32; i = i * 2) + value |= value >> i; + + return value +1; +} diff --git a/src/stdio/_putf.c b/src/stdio/_putf.c new file mode 100644 index 0000000..991b912 --- /dev/null +++ b/src/stdio/_putf.c @@ -0,0 +1,286 @@ +#include /* size_t */ +#include /* va_list */ + +#include +#include +#include "_putf.h" + +#define BUF 16 +#define PADSIZE 16 + +static const char blanks[PADSIZE] = { + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' +}; +static const char zeroes[PADSIZE] = { + '0', '0', '0', '0', '0', '0', '0', '0', + '0', '0', '0', '0', '0', '0', '0', '0' +}; + +static void _putpad(int _putb(void *, const char *, size_t), void *base, const char *padch, int count) +{ + while (count > PADSIZE) { + _putb(base, padch, PADSIZE); + count -= PADSIZE; + } + + if (count > 0) + _putb(base, padch, count); +} + +/* + * Flags used during conversion. + */ +#define ALT 0x01 /* alternate form */ +#define LADJUST 0x04 /* left adjustment */ +#define LONGINT 0x08 /* long integer */ +#define ZEROPAD 0x10 /* zero (as opposed to blank) pad */ + +int _putf(int _putb(void *, const char *, size_t), void *base, const char *fmt, va_list ap) +{ + int rc = 0; /* return value accumulator */ + for (;;) { + unsigned char ch; /* character from fmt */ + int size; /* size of converted field or string */ + + char *cp = (char *)fmt; + while ((ch = *fmt) && (ch != '%')) + fmt++; + + int n = fmt - cp; + if (n) { + _putb(base, cp, n); + rc += n; + } + + if (ch == 0) + break; + + fmt++; + + char flags = 0; /* flags as above */ + char sign = 0; /* sign prefix (' ', '+', '-', or \0) */ + int width = 0; /* width from format (%8d), or 0 */ + int prec = -1; /* precision from format (%.3d), or -1 */ + int dprec = 0; /* a copy of prec if [diouxX], 0 otherwise */ + + for (;;) { + ch = *fmt++; + if (ch == ' ') { + if (!sign) + sign = ' '; + + } else if (ch == '+') { + sign = '+'; + + } else if (ch == '-') { + flags |= LADJUST; + + } else if (ch == '#') { + flags |= ALT; + + } else if (ch == '0') { + flags |= ZEROPAD; + + } else if (ch == 'l') { + flags |= LONGINT; + + } else if (ch == 'z') { + if (sizeof(size_t) > sizeof(int)) + flags |= LONGINT; + + } else if (ch == '*') { + width = va_arg(ap, int); + if (width < 0) { + flags |= LADJUST; + width = -width; + } + + } else if (ch == '.') { + if (*fmt == '*') { + fmt++; + prec = va_arg(ap, int); + + } else { + prec = 0; + while (*fmt >= '0' && *fmt <= '9') + prec = 10 * prec + (*fmt++ - '0'); + } + if (prec < 0) + prec = -1; + + } else if (ch >= '1' && ch <= '9') { + width = ch - '0'; + while (*fmt >= '0' && *fmt <= '9') + width = 10 * width + (*fmt++ - '0'); + + } else { + break; + } + } + + unsigned long ulval; /* integer arguments %[diouxX] */ + char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ + + switch (ch) { + case 'c': + *(cp = buf) = va_arg(ap, int); + size = 1; + sign = 0; + break; + + case 'P': + case 's': + cp = va_arg(ap, char *); + if (cp == 0) + cp = "(null)"; + + if (prec >= 0) { + char *p = memchr(cp, 0, (size_t) prec); + + if (p) { + size = p - cp; + if (size > prec) + size = prec; + + } else { + size = prec; + } + + } else { + size = strlen(cp); + sign = 0; + } + break; + + case 'u': + sign = 0; + case 'd': + case 'i': + if (flags & LONGINT) { + ulval = va_arg(ap, unsigned long); + + } else if (ch == 'u') { + ulval = va_arg(ap, unsigned int); + + } else { + ulval = va_arg(ap, int); + } + + if (ch != 'u' && (long) ulval < 0) { + ulval = (unsigned long) (-((long) ulval)); + sign = '-'; + } + + if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + cp = buf + BUF; + if (ulval || prec) { + if (ulval < 10) { + *--cp = (char) ulval + '0'; + + } else { + do { + *--cp = (char) (ulval % 10) + '0'; + ulval /= 10; + } while (ulval); + } + } + size = buf + BUF - cp; + break; + + case 'o': + ulval = (flags & LONGINT) ? va_arg(ap, unsigned long) : va_arg(ap, unsigned int); + sign = 0; + if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + cp = buf + BUF; + if (ulval || prec) { + do { + *--cp = (char) (ulval & 7) + '0'; + ulval >>= 3; + } while (ulval); + + if ((flags & ALT) != 0 && *cp != '0') + *--cp = '0'; + } + size = buf + BUF - cp; + break; + + case 'p': + case 'X': + case 'x': + if (ch == 'p') { + ulval = (unsigned long) va_arg(ap, void *); + flags |= ALT; + ch = 'x'; + + } else { + ulval = (flags & LONGINT) ? va_arg(ap, unsigned long) : va_arg(ap, unsigned int); + } + + sign = 0; + if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + char *xdigs = (ch == 'X') ? "0123456789ABCDEF" : "0123456789abcdef"; + cp = buf + BUF; + + do { + *--cp = xdigs[ulval & 0x0f]; + ulval >>= 4; + } while (ulval); + + if (flags & ALT) { + *--cp = ch; + *--cp = '0'; + } + + size = buf + BUF - cp; + break; + + case 'g': + case 'G': + case 'e': + case 'E': + case 'f': + (void) va_arg(ap, long); + + default: + if (ch == 0) + return rc; + + cp = buf; + *cp = ch; + size = 1; + sign = '\0'; + break; + } + + int realsz = dprec > size ? dprec : size; + if (sign) + realsz++; + + if ((flags & (LADJUST | ZEROPAD)) == 0) + _putpad(_putb, base, blanks, width - realsz); + + if (sign) + _putb(base, &sign, 1); + + if ((flags & (LADJUST | ZEROPAD)) == ZEROPAD) + _putpad(_putb, base, zeroes, width - realsz); + + _putpad(_putb, base, zeroes, dprec - size); + + if (size) + _putb(base, cp, size); + + if (flags & LADJUST) + _putpad(_putb, base, blanks, width - realsz); + + rc += (width >= realsz) ? width : realsz; + } + return rc; +} diff --git a/src/stdio/_putf.h b/src/stdio/_putf.h new file mode 100644 index 0000000..8883191 --- /dev/null +++ b/src/stdio/_putf.h @@ -0,0 +1,6 @@ +#ifndef _PUTF_H_ +#define _PUTF_H_ + +int _putf(int _putb(void *, const char *, size_t), void *base, const char *fmt, va_list ap); + +#endif /* _PUTF_H_ */ diff --git a/src/stdio/printf.c b/src/stdio/printf.c new file mode 100644 index 0000000..13674d6 --- /dev/null +++ b/src/stdio/printf.c @@ -0,0 +1,61 @@ +#include /* size_t */ +#include /* va_list */ + +#include "_putf.h" +#include "at91_dbgu.h" + +int printf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int rc = _putf(at91_dbgu_write, NULL, fmt, ap); + va_end(ap); + + return rc; +} + +int inline puts(const char *p) +{ + at91_dbgu_puts(p); + return 0; +} + +int inline putchar(int c) +{ + at91_dbgu_putc(c); + return 0; +} + +struct snprintf_data { + char *bufstart; + size_t buflen; + int pos; +}; + +int snprintf_helper(void *base, const char *buf, size_t len) +{ + struct snprintf_data *data = (struct snprintf_data *)base; + + int count = 0; + while (len-- && (data->pos < data->buflen)) + data->bufstart[data->pos++] = *buf++; + + return count; +} + +int snprintf(char *buf, size_t len, const char *fmt, ...) +{ + struct snprintf_data data = { + .bufstart = buf, + .buflen = len, + .pos = 0, + }; + + va_list ap; + va_start(ap, fmt); + int rc = _putf(snprintf_helper, (void *)&data, fmt, ap); + va_end(ap); + + buf[data.pos] = '\0'; + return rc; +}