summaryrefslogtreecommitdiff
path: root/openpcd
diff options
context:
space:
mode:
author(no author) <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-07-24 16:34:55 +0000
committer(no author) <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-07-24 16:34:55 +0000
commitcaf5000333d37d2a772236bd6c3d539b0ee39c86 (patch)
tree2bf4d4da34282fdaa71dcfd55bc9207fc5c24c57 /openpcd
parent6556e87c2bb82e4a2002ceea08865236c4c996e7 (diff)
major rework
git-svn-id: https://svn.openpcd.org:2342/trunk@35 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpcd')
-rw-r--r--openpcd/firmware/Makefile18
-rw-r--r--openpcd/firmware/README6
-rw-r--r--openpcd/firmware/include/asm/assembler.h97
-rw-r--r--openpcd/firmware/include/asm/atomic.h105
-rw-r--r--openpcd/firmware/include/asm/bitops.h225
-rw-r--r--openpcd/firmware/include/asm/linkage.h18
-rw-r--r--openpcd/firmware/include/asm/ptrace.h128
-rw-r--r--openpcd/firmware/include/asm/system.h108
-rw-r--r--openpcd/firmware/include/lib_AT91SAM7.h40
-rw-r--r--openpcd/firmware/include/openpcd.h2
-rw-r--r--openpcd/firmware/include/sys/types.h (renamed from openpcd/firmware/include/types.h)0
-rw-r--r--openpcd/firmware/include/usb_ch9.h2
-rw-r--r--openpcd/firmware/lib/changebit.S21
-rw-r--r--openpcd/firmware/lib/clearbit.S22
-rw-r--r--openpcd/firmware/lib/lib_AT91SAM7.c25
-rw-r--r--openpcd/firmware/lib/setbit.S22
-rw-r--r--openpcd/firmware/lib/testchangebit.S18
-rw-r--r--openpcd/firmware/lib/testclearbit.S18
-rw-r--r--openpcd/firmware/lib/testsetbit.S18
-rw-r--r--openpcd/firmware/src/dbgu.c48
-rw-r--r--openpcd/firmware/src/fifo.c14
-rw-r--r--openpcd/firmware/src/fifo.h2
-rw-r--r--openpcd/firmware/src/led.c14
-rw-r--r--openpcd/firmware/src/main.c146
-rw-r--r--openpcd/firmware/src/main_dumbreader.c94
-rw-r--r--openpcd/firmware/src/main_reqa.c25
-rw-r--r--openpcd/firmware/src/openpcd.h28
-rw-r--r--openpcd/firmware/src/pcd_enumerate.c162
-rw-r--r--openpcd/firmware/src/pcd_enumerate.h8
-rw-r--r--openpcd/firmware/src/rc632.c61
-rw-r--r--openpcd/firmware/src/rc632.h10
-rw-r--r--openpcd/firmware/src/rc632_highlevel.c489
-rw-r--r--openpcd/firmware/src/req_ctx.c19
-rw-r--r--openpcd/firmware/src/trigger.c14
-rw-r--r--openpcd/firmware/src/trigger.h7
35 files changed, 1679 insertions, 355 deletions
diff --git a/openpcd/firmware/Makefile b/openpcd/firmware/Makefile
index 48f247e..78c9716 100644
--- a/openpcd/firmware/Makefile
+++ b/openpcd/firmware/Makefile
@@ -63,7 +63,7 @@ PATH_TO_LINKSCRIPTS=compil/SrcWinARM/
#VECTOR_LOCATION=VECTORS_IN_RAM
# Target file name (without extension).
-TARGET = main
+TARGET:= main_dumbreader
# List C source files here. (C dependencies are automatically generated.)
# use file-extension c for "c-only"-files
@@ -71,7 +71,9 @@ SRC =
# List C source files here which must be compiled in ARM-Mode.
# use file-extension c for "c-only"-files
-SRCARM = lib/lib_AT91SAM7.c src/pcd_enumerate.c src/fifo.c src/dbgu.c src/led.c src/rc632.c src/req_ctx.c src/$(TARGET).c compil/SrcWinARM/Cstartup_SAM7.c
+SRCARM = lib/lib_AT91SAM7.c src/pcd_enumerate.c src/fifo.c src/dbgu.c \
+ src/led.c src/rc632.c src/req_ctx.c src/trigger.c src/main.c \
+ src/$(TARGET).c compil/SrcWinARM/Cstartup_SAM7.c
# List C++ source files here.
# use file-extension cpp for C++-files (use extension .cpp)
@@ -91,8 +93,10 @@ CPPSRCARM =
# care about how the name is spelled on its command-line.
ASRC =
+ASRCLIB = lib/changebit.S lib/clearbit.S lib/setbit.S lib/testchangebit.S lib/testclearbit.S lib/testsetbit.S
+
# List Assembler source files here which must be assembled in ARM-Mode..
-ASRCARM = compil/SrcWinARM/Cstartup.S
+ASRCARM = compil/SrcWinARM/Cstartup.S $(ASRCLIB)
## Output format. (can be ihex or binary)
## (binary i.e. for openocd and SAM-BA, hex i.e. for lpc21isp and uVision)
@@ -135,11 +139,11 @@ AT91LIBNOWARN = yes
CSTANDARD = -std=gnu99
# Place -D or -U options for C here
-CDEFS = -D$(RUN_MODE) -DDEBUG
-#CDEFS += -DOLIMEX
+CDEFS = -D$(RUN_MODE) -D__MS_types__ -DDEBUG
+CDEFS += -DOLIMEX
# Place -I options here
-CINCS = -Ihelper -Isrc
+CINCS = -Iinclude -Isrc
# Place -D or -U options for ASM here
ADEFS = -D$(RUN_MODE)
@@ -192,7 +196,7 @@ CPPFLAGS =
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlns: create listing
# -g$(DEBUG): have the assembler create line number information
-ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:.S=.lst),--g$(DEBUG)
+ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:.S=.lst),--g$(DEBUG) -Iinclude/ -D__ASSEMBLY__
#Additional libraries.
diff --git a/openpcd/firmware/README b/openpcd/firmware/README
new file mode 100644
index 0000000..15d3573
--- /dev/null
+++ b/openpcd/firmware/README
@@ -0,0 +1,6 @@
+Different Targets can be built by implementing a _init_func() and _main_func()_
+function in src/main_foo.c
+
+The resulting binary main_foo.bin can be built by issuing
+ make TARGET=main_foo
+
diff --git a/openpcd/firmware/include/asm/assembler.h b/openpcd/firmware/include/asm/assembler.h
new file mode 100644
index 0000000..b43f9d1
--- /dev/null
+++ b/openpcd/firmware/include/asm/assembler.h
@@ -0,0 +1,97 @@
+/*
+ * linux/include/asm-arm/assembler.h
+ *
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains arm architecture specific defines
+ * for the different processors.
+ *
+ * Do not include any C declarations in this file - it is included by
+ * assembler source.
+ */
+#ifndef __ASSEMBLY__
+#error "Only include this from assembly code"
+#endif
+
+#include <asm/ptrace.h>
+
+#define pull lsl
+#define push lsr
+#define get_byte_0 lsr #24
+#define get_byte_1 lsr #16
+#define get_byte_2 lsr #8
+#define get_byte_3 lsl #0
+#define put_byte_0 lsl #24
+#define put_byte_1 lsl #16
+#define put_byte_2 lsl #8
+#define put_byte_3 lsl #0
+
+#define PLD(code...)
+
+#define MODE_USR USR_MODE
+#define MODE_FIQ FIQ_MODE
+#define MODE_IRQ IRQ_MODE
+#define MODE_SVC SVC_MODE
+
+#define DEFAULT_FIQ MODE_FIQ
+
+/*
+ * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc})
+ */
+#ifdef __STDC__
+#define LOADREGS(cond, base, reglist...)\
+ ldm##cond base,reglist
+#else
+#define LOADREGS(cond, base, reglist...)\
+ ldm/**/cond base,reglist
+#endif
+
+/*
+ * Build a return instruction for this processor type.
+ */
+#define RETINSTR(instr, regs...)\
+ instr regs
+
+/*
+ * Enable and disable interrupts
+ */
+ .macro disable_irq
+ msr cpsr_c, #PSR_I_BIT | SVC_MODE
+ .endm
+
+ .macro enable_irq
+ msr cpsr_c, #SVC_MODE
+ .endm
+
+/*
+ * Save the current IRQ state and disable IRQs. Note that this macro
+ * assumes FIQs are enabled, and that the processor is in SVC mode.
+ */
+ .macro save_and_disable_irqs, oldcpsr
+ mrs \oldcpsr, cpsr
+ disable_irq
+ .endm
+
+/*
+ * Restore interrupt state previously stored in a register. We don't
+ * guarantee that this will preserve the flags.
+ */
+ .macro restore_irqs, oldcpsr
+ msr cpsr_c, \oldcpsr
+ .endm
+
+/*
+ * These two are used to save LR/restore PC over a user-based access.
+ * The old 26-bit architecture requires that we do. On 32-bit
+ * architecture, we can safely ignore this requirement.
+ */
+ .macro save_lr
+ .endm
+
+ .macro restore_pc
+ mov pc, lr
+ .endm
diff --git a/openpcd/firmware/include/asm/atomic.h b/openpcd/firmware/include/asm/atomic.h
new file mode 100644
index 0000000..bb5a2b1
--- /dev/null
+++ b/openpcd/firmware/include/asm/atomic.h
@@ -0,0 +1,105 @@
+/*
+ * linux/include/asm-arm/atomic.h
+ *
+ * Copyright (C) 1996 Russell King.
+ * Copyright (C) 2002 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_ATOMIC_H
+#define __ASM_ARM_ATOMIC_H
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ((v)->counter)
+
+#include <asm/system.h>
+
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ local_irq_save(flags);
+ val = v->counter;
+ v->counter = val += i;
+ local_irq_restore(flags);
+
+ return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ local_irq_save(flags);
+ val = v->counter;
+ v->counter = val -= i;
+ local_irq_restore(flags);
+
+ return val;
+}
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ int ret;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ret = v->counter;
+ if (likely(ret == old))
+ v->counter = new;
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *addr &= ~mask;
+ local_irq_restore(flags);
+}
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+
+ c = atomic_read(v);
+ while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+ c = old;
+ return c != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#define atomic_add(i, v) (void) atomic_add_return(i, v)
+#define atomic_inc(v) (void) atomic_add_return(1, v)
+#define atomic_sub(i, v) (void) atomic_sub_return(i, v)
+#define atomic_dec(v) (void) atomic_sub_return(1, v)
+
+#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
+#define atomic_inc_return(v) (atomic_add_return(1, v))
+#define atomic_dec_return(v) (atomic_sub_return(1, v))
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
+
+/* Atomic operations are already serializing on ARM */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#endif
diff --git a/openpcd/firmware/include/asm/bitops.h b/openpcd/firmware/include/asm/bitops.h
new file mode 100644
index 0000000..337d800
--- /dev/null
+++ b/openpcd/firmware/include/asm/bitops.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright 1995, Russell King.
+ * Various bits and pieces copyrights include:
+ * Linus Torvalds (test_bit).
+ * Big endian support: Copyright 2001, Nicolas Pitre
+ * reworked by rmk.
+ *
+ * bit 0 is the LSB of an "unsigned long" quantity.
+ *
+ * Please note that the code in this file should never be included
+ * from user space. Many of these are not implemented in assembler
+ * since they would be too costly. Also, they require privileged
+ * instructions (which are not available from user mode) to ensure
+ * that they are atomic.
+ */
+
+#ifndef __ASM_ARM_BITOPS_H
+#define __ASM_ARM_BITOPS_H
+
+#include <asm/system.h>
+
+#define smp_mb__before_clear_bit() mb()
+#define smp_mb__after_clear_bit() mb()
+
+/*
+ * These functions are the basis of our bit ops.
+ *
+ * First, the atomic bitops. These use native endian.
+ */
+static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ local_irq_save(flags);
+ *p |= mask;
+ local_irq_restore(flags);
+}
+
+static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ local_irq_save(flags);
+ *p &= ~mask;
+ local_irq_restore(flags);
+}
+
+static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ local_irq_save(flags);
+ *p ^= mask;
+ local_irq_restore(flags);
+}
+
+static inline int
+____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ local_irq_save(flags);
+ res = *p;
+ *p = res | mask;
+ local_irq_restore(flags);
+
+ return res & mask;
+}
+
+static inline int
+____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ local_irq_save(flags);
+ res = *p;
+ *p = res & ~mask;
+ local_irq_restore(flags);
+
+ return res & mask;
+}
+
+static inline int
+____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ local_irq_save(flags);
+ res = *p;
+ *p = res ^ mask;
+ local_irq_restore(flags);
+
+ return res & mask;
+}
+
+//#include <asm-generic/bitops/non-atomic.h>
+
+/*
+ * A note about Endian-ness.
+ * -------------------------
+ *
+ * When the ARM is put into big endian mode via CR15, the processor
+ * merely swaps the order of bytes within words, thus:
+ *
+ * ------------ physical data bus bits -----------
+ * D31 ... D24 D23 ... D16 D15 ... D8 D7 ... D0
+ * little byte 3 byte 2 byte 1 byte 0
+ * big byte 0 byte 1 byte 2 byte 3
+ *
+ * This means that reading a 32-bit word at address 0 returns the same
+ * value irrespective of the endian mode bit.
+ *
+ * Peripheral devices should be connected with the data bus reversed in
+ * "Big Endian" mode. ARM Application Note 61 is applicable, and is
+ * available from http://www.arm.com/.
+ *
+ * The following assumes that the data bus connectivity for big endian
+ * mode has been followed.
+ *
+ * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
+ */
+
+/*
+ * Little endian assembly bitops. nr = 0 -> byte 0 bit 0.
+ */
+extern void _set_bit_le(int nr, volatile unsigned long * p);
+extern void _clear_bit_le(int nr, volatile unsigned long * p);
+extern void _change_bit_le(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
+extern int _find_first_zero_bit_le(const void * p, unsigned size);
+extern int _find_next_zero_bit_le(const void * p, int size, int offset);
+extern int _find_first_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
+
+/*
+ * Big endian assembly bitops. nr = 0 -> byte 3 bit 0.
+ */
+extern void _set_bit_be(int nr, volatile unsigned long * p);
+extern void _clear_bit_be(int nr, volatile unsigned long * p);
+extern void _change_bit_be(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
+extern int _find_first_zero_bit_be(const void * p, unsigned size);
+extern int _find_next_zero_bit_be(const void * p, int size, int offset);
+extern int _find_first_bit_be(const unsigned long *p, unsigned size);
+extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
+
+/*
+ * The __* form of bitops are non-atomic and may be reordered.
+ */
+#define ATOMIC_BITOP_LE(name,nr,p) \
+ (__builtin_constant_p(nr) ? \
+ ____atomic_##name(nr, p) : \
+ _##name##_le(nr,p))
+
+#define ATOMIC_BITOP_BE(name,nr,p) \
+ (__builtin_constant_p(nr) ? \
+ ____atomic_##name(nr, p) : \
+ _##name##_be(nr,p))
+
+#define NONATOMIC_BITOP(name,nr,p) \
+ (____nonatomic_##name(nr, p))
+
+/*
+ * These are the little endian, atomic definitions.
+ */
+#define set_bit(nr,p) ATOMIC_BITOP_LE(set_bit,nr,p)
+#define clear_bit(nr,p) ATOMIC_BITOP_LE(clear_bit,nr,p)
+#define change_bit(nr,p) ATOMIC_BITOP_LE(change_bit,nr,p)
+#define test_and_set_bit(nr,p) ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
+#define test_and_clear_bit(nr,p) ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
+#define test_and_change_bit(nr,p) ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
+#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz)
+#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off)
+#define find_first_bit(p,sz) _find_first_bit_le(p,sz)
+#define find_next_bit(p,sz,off) _find_next_bit_le(p,sz,off)
+
+#define WORD_BITOFF_TO_LE(x) ((x))
+
+#if 0
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/ffs.h>
+
+#include <asm-generic/bitops/fls64.h>
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#endif
+
+#define BITS_PER_LONG 32
+#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
+
+static inline int test_bit(int nr, const volatile unsigned long *addr)
+{
+ return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+#endif /* _ARM_BITOPS_H */
diff --git a/openpcd/firmware/include/asm/linkage.h b/openpcd/firmware/include/asm/linkage.h
new file mode 100644
index 0000000..ac1c900
--- /dev/null
+++ b/openpcd/firmware/include/asm/linkage.h
@@ -0,0 +1,18 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* asm-arm/linkage.h */
+
+#define __ALIGN .align 0
+#define __ALIGN_STR ".align 0"
+
+/* linux/linkage.h */
+
+#define ALIGN __ALIGN
+
+#define ENTRY(name) \
+ .globl name; \
+ ALIGN; \
+ name:
+
+#endif
diff --git a/openpcd/firmware/include/asm/ptrace.h b/openpcd/firmware/include/asm/ptrace.h
new file mode 100644
index 0000000..f3a654e
--- /dev/null
+++ b/openpcd/firmware/include/asm/ptrace.h
@@ -0,0 +1,128 @@
+/*
+ * linux/include/asm-arm/ptrace.h
+ *
+ * Copyright (C) 1996-2003 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_PTRACE_H
+#define __ASM_ARM_PTRACE_H
+
+/*
+ * PSR bits
+ */
+#define USR26_MODE 0x00000000
+#define FIQ26_MODE 0x00000001
+#define IRQ26_MODE 0x00000002
+#define SVC26_MODE 0x00000003
+#define USR_MODE 0x00000010
+#define FIQ_MODE 0x00000011
+#define IRQ_MODE 0x00000012
+#define SVC_MODE 0x00000013
+#define ABT_MODE 0x00000017
+#define UND_MODE 0x0000001b
+#define SYSTEM_MODE 0x0000001f
+#define MODE32_BIT 0x00000010
+#define MODE_MASK 0x0000001f
+#define PSR_T_BIT 0x00000020
+#define PSR_F_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_J_BIT 0x01000000
+#define PSR_Q_BIT 0x08000000
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_N_BIT 0x80000000
+#define PCMASK 0
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f 0xff000000 /* Flags */
+#define PSR_s 0x00ff0000 /* Status */
+#define PSR_x 0x0000ff00 /* Extension */
+#define PSR_c 0x000000ff /* Control */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call. Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
+struct pt_regs {
+ long uregs[18];
+};
+
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+#define user_mode(regs) \
+ (((regs)->ARM_cpsr & 0xf) == 0)
+
+#ifdef CONFIG_ARM_THUMB
+#define thumb_mode(regs) \
+ (((regs)->ARM_cpsr & PSR_T_BIT))
+#else
+#define thumb_mode(regs) (0)
+#endif
+
+#define processor_mode(regs) \
+ ((regs)->ARM_cpsr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & PSR_I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & PSR_F_BIT))
+
+#define condition_codes(regs) \
+ ((regs)->ARM_cpsr & (PSR_V_BIT|PSR_C_BIT|PSR_Z_BIT|PSR_N_BIT))
+
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+ if (user_mode(regs) &&
+ (regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0)
+ return 1;
+
+ /*
+ * Force CPSR to something logical...
+ */
+ regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
+
+ return 0;
+}
+
+#define pc_pointer(v) \
+ ((v) & ~PCMASK)
+
+#define instruction_pointer(regs) \
+ (pc_pointer((regs)->ARM_pc))
+
+#define profile_pc(regs) instruction_pointer(regs)
+
+#endif /* __ASSEMBLY__ */
+
+#endif
+
diff --git a/openpcd/firmware/include/asm/system.h b/openpcd/firmware/include/asm/system.h
new file mode 100644
index 0000000..07d4151
--- /dev/null
+++ b/openpcd/firmware/include/asm/system.h
@@ -0,0 +1,108 @@
+#ifndef __ASM_ARM_SYSTEM_H
+#define __ASM_ARM_SYSTEM_H
+
+/* Generic ARM7TDMI (ARMv4T) synchronisation primitives, mostly
+ * taken from Linux kernel source, licensed under GPL */
+
+#define local_irq_save(x) \
+ ({ \
+ unsigned long temp; \
+ (void) (&temp == &x); \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_irq_save\n" \
+" orr %1, %0, #128\n" \
+" msr cpsr_c, %1" \
+ : "=r" (x), "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Enable IRQs
+ */
+#define local_irq_enable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_irq_enable\n" \
+" bic %0, %0, #128\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Disable IRQs
+ */
+#define local_irq_disable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_irq_disable\n" \
+" orr %0, %0, #128\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Enable FIQs
+ */
+#define local_fiq_enable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ stf\n" \
+" bic %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Disable FIQs
+ */
+#define local_fiq_disable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ clf\n" \
+" orr %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Save the current interrupt enable state.
+ */
+#define local_save_flags(x) \
+ ({ \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ local_save_flags" \
+ : "=r" (x) : : "memory", "cc"); \
+ })
+
+/*
+ * restore saved IRQ & FIQ state
+ */
+#define local_irq_restore(x) \
+ __asm__ __volatile__( \
+ "msr cpsr_c, %0 @ local_irq_restore\n" \
+ : \
+ : "r" (x) \
+ : "memory", "cc")
+
+#define irqs_disabled() \
+({ \
+ unsigned long flags; \
+ local_save_flags(flags); \
+ (int)(flags & PSR_I_BIT); \
+})
+
+
+#endif
diff --git a/openpcd/firmware/include/lib_AT91SAM7.h b/openpcd/firmware/include/lib_AT91SAM7.h
index 49f00bd..f43aaec 100644
--- a/openpcd/firmware/include/lib_AT91SAM7.h
+++ b/openpcd/firmware/include/lib_AT91SAM7.h
@@ -169,7 +169,7 @@ extern void AT91F_AIC_Open(
//*----------------------------------------------------------------------------
static inline void AT91F_PDC_SetNextRx (
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
- char *address, // \arg address to the next bloc to be received
+ unsigned char *address,// \arg address to the next bloc to be received
unsigned int bytes) // \arg number of bytes to be received
{
pPDC->PDC_RNPR = (unsigned int) address;
@@ -182,7 +182,7 @@ static inline void AT91F_PDC_SetNextRx (
//*----------------------------------------------------------------------------
static inline void AT91F_PDC_SetNextTx (
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
- char *address, // \arg address to the next bloc to be transmitted
+ const unsigned char *address,// \arg address to the next bloc to be transmitted
unsigned int bytes) // \arg number of bytes to be transmitted
{
pPDC->PDC_TNPR = (unsigned int) address;
@@ -195,7 +195,7 @@ static inline void AT91F_PDC_SetNextTx (
//*----------------------------------------------------------------------------
static inline void AT91F_PDC_SetRx (
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
- char *address, // \arg address to the next bloc to be received
+ unsigned char *address,// \arg address to the next bloc to be received
unsigned int bytes) // \arg number of bytes to be received
{
pPDC->PDC_RPR = (unsigned int) address;
@@ -208,7 +208,7 @@ static inline void AT91F_PDC_SetRx (
//*----------------------------------------------------------------------------
static inline void AT91F_PDC_SetTx (
AT91PS_PDC pPDC, // \arg pointer to a PDC controller
- char *address, // \arg address to the next bloc to be transmitted
+ const unsigned char *address,// \arg address to the next bloc to be transmitted
unsigned int bytes) // \arg number of bytes to be transmitted
{
pPDC->PDC_TPR = (unsigned int) address;
@@ -313,9 +313,9 @@ extern void AT91F_PDC_Close(AT91PS_PDC pPDC); // \arg pointer to a PDC con
//*----------------------------------------------------------------------------
extern unsigned int AT91F_PDC_SendFrame(
AT91PS_PDC pPDC,
- char *pBuffer,
+ const unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ const unsigned char *pNextBuffer,
unsigned int szNextBuffer);
//*----------------------------------------------------------------------------
@@ -324,9 +324,9 @@ extern unsigned int AT91F_PDC_SendFrame(
//*----------------------------------------------------------------------------
extern unsigned int AT91F_PDC_ReceiveFrame (
AT91PS_PDC pPDC,
- char *pBuffer,
+ unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ unsigned char *pNextBuffer,
unsigned int szNextBuffer);
/* *****************************************************************************
@@ -1701,9 +1701,9 @@ static inline void AT91F_SPI_CfgPCS (
//*----------------------------------------------------------------------------
static inline unsigned int AT91F_SPI_ReceiveFrame (
AT91PS_SPI pSPI,
- char *pBuffer,
+ unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
return AT91F_PDC_ReceiveFrame(
@@ -1720,9 +1720,9 @@ static inline unsigned int AT91F_SPI_ReceiveFrame (
//*----------------------------------------------------------------------------
static inline unsigned int AT91F_SPI_SendFrame(
AT91PS_SPI pSPI,
- char *pBuffer,
+ const unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ const unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
return AT91F_PDC_SendFrame(
@@ -2168,9 +2168,9 @@ static inline void AT91F_SSC_DisableIt (
//*----------------------------------------------------------------------------
static inline unsigned int AT91F_SSC_ReceiveFrame (
AT91PS_SSC pSSC,
- char *pBuffer,
+ unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
return AT91F_PDC_ReceiveFrame(
@@ -2187,9 +2187,9 @@ static inline unsigned int AT91F_SSC_ReceiveFrame (
//*----------------------------------------------------------------------------
static inline unsigned int AT91F_SSC_SendFrame(
AT91PS_SSC pSSC,
- char *pBuffer,
+ const unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ const unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
return AT91F_PDC_SendFrame(
@@ -2480,9 +2480,9 @@ static inline int AT91F_US_GetChar (
//*----------------------------------------------------------------------------
static inline unsigned int AT91F_US_SendFrame(
AT91PS_USART pUSART,
- char *pBuffer,
+ const unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ const unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
return AT91F_PDC_SendFrame(
@@ -2499,9 +2499,9 @@ static inline unsigned int AT91F_US_SendFrame(
//*----------------------------------------------------------------------------
static inline unsigned int AT91F_US_ReceiveFrame (
AT91PS_USART pUSART,
- char *pBuffer,
+ unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
return AT91F_PDC_ReceiveFrame(
diff --git a/openpcd/firmware/include/openpcd.h b/openpcd/firmware/include/openpcd.h
index 81d2ad1..6596717 100644
--- a/openpcd/firmware/include/openpcd.h
+++ b/openpcd/firmware/include/openpcd.h
@@ -3,7 +3,7 @@
/* This header file describes the USB protocol of the OpenPCD RFID reader */
-#include <include/types.h>
+#include <sys/types.h>
struct openpcd_hdr {
u_int8_t cmd; /* command */
diff --git a/openpcd/firmware/include/types.h b/openpcd/firmware/include/sys/types.h
index f17ffe5..f17ffe5 100644
--- a/openpcd/firmware/include/types.h
+++ b/openpcd/firmware/include/sys/types.h
diff --git a/openpcd/firmware/include/usb_ch9.h b/openpcd/firmware/include/usb_ch9.h
index b10c8ae..82edf61 100644
--- a/openpcd/firmware/include/usb_ch9.h
+++ b/openpcd/firmware/include/usb_ch9.h
@@ -19,7 +19,7 @@
#ifndef __LINUX_USB_CH9_H
#define __LINUX_USB_CH9_H
-#include <include/types.h>
+#include <sys/types.h>
/*-------------------------------------------------------------------------*/
diff --git a/openpcd/firmware/lib/changebit.S b/openpcd/firmware/lib/changebit.S
new file mode 100644
index 0000000..7c709fb
--- /dev/null
+++ b/openpcd/firmware/lib/changebit.S
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/lib/changebit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+/* Purpose : Function to change a bit
+ * Prototype: int change_bit(int bit, void *addr)
+ */
+ENTRY(_change_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_change_bit_le)
+ bitop eor
diff --git a/openpcd/firmware/lib/clearbit.S b/openpcd/firmware/lib/clearbit.S
new file mode 100644
index 0000000..cb48f7a
--- /dev/null
+++ b/openpcd/firmware/lib/clearbit.S
@@ -0,0 +1,22 @@
+/*
+ * linux/arch/arm/lib/clearbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+/*
+ * Purpose : Function to clear a bit
+ * Prototype: int clear_bit(int bit, void *addr)
+ */
+ENTRY(_clear_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_clear_bit_le)
+ bitop bic
diff --git a/openpcd/firmware/lib/lib_AT91SAM7.c b/openpcd/firmware/lib/lib_AT91SAM7.c
index f3e49d4..950761f 100644
--- a/openpcd/firmware/lib/lib_AT91SAM7.c
+++ b/openpcd/firmware/lib/lib_AT91SAM7.c
@@ -17,6 +17,7 @@
//* Generated : AT91 SW Application Group 08/30/2005 (15:52:59)
//*
+#include <sys/types.h>
#include <include/AT91SAM7.h>
#include <include/lib_AT91SAM7.h>
@@ -107,10 +108,10 @@ void AT91F_PDC_Open(AT91PS_PDC pPDC) // \arg pointer to a PDC controller
AT91F_PDC_DisableTx(pPDC);
//* Reset all Counter register Next buffer first
- AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0);
- AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
- AT91F_PDC_SetTx(pPDC, (char *) 0, 0);
- AT91F_PDC_SetRx(pPDC, (char *) 0, 0);
+ AT91F_PDC_SetNextTx(pPDC, NULL, 0);
+ AT91F_PDC_SetNextRx(pPDC, NULL, 0);
+ AT91F_PDC_SetTx(pPDC, NULL, 0);
+ AT91F_PDC_SetRx(pPDC, NULL, 0);
//* Enable the RX and TX PDC transfer requests
AT91F_PDC_EnableRx(pPDC);
@@ -128,10 +129,10 @@ void AT91F_PDC_Close(AT91PS_PDC pPDC) // \arg pointer to a PDC controller
AT91F_PDC_DisableTx(pPDC);
//* Reset all Counter register Next buffer first
- AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0);
- AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
- AT91F_PDC_SetTx(pPDC, (char *) 0, 0);
- AT91F_PDC_SetRx(pPDC, (char *) 0, 0);
+ AT91F_PDC_SetNextTx(pPDC, NULL, 0);
+ AT91F_PDC_SetNextRx(pPDC, NULL, 0);
+ AT91F_PDC_SetTx(pPDC, NULL, 0);
+ AT91F_PDC_SetRx(pPDC, NULL, 0);
}
@@ -141,9 +142,9 @@ void AT91F_PDC_Close(AT91PS_PDC pPDC) // \arg pointer to a PDC controller
//*----------------------------------------------------------------------------
unsigned int AT91F_PDC_SendFrame(
AT91PS_PDC pPDC,
- char *pBuffer,
+ const unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ const unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
if (AT91F_PDC_IsTxEmpty(pPDC)) {
@@ -169,9 +170,9 @@ unsigned int AT91F_PDC_SendFrame(
//*----------------------------------------------------------------------------
unsigned int AT91F_PDC_ReceiveFrame (
AT91PS_PDC pPDC,
- char *pBuffer,
+ unsigned char *pBuffer,
unsigned int szBuffer,
- char *pNextBuffer,
+ unsigned char *pNextBuffer,
unsigned int szNextBuffer )
{
if (AT91F_PDC_IsRxEmpty(pPDC)) {
diff --git a/openpcd/firmware/lib/setbit.S b/openpcd/firmware/lib/setbit.S
new file mode 100644
index 0000000..9009bc1
--- /dev/null
+++ b/openpcd/firmware/lib/setbit.S
@@ -0,0 +1,22 @@
+/*
+ * linux/arch/arm/lib/setbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+/*
+ * Purpose : Function to set a bit
+ * Prototype: int set_bit(int bit, void *addr)
+ */
+ENTRY(_set_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_set_bit_le)
+ bitop orr
diff --git a/openpcd/firmware/lib/testchangebit.S b/openpcd/firmware/lib/testchangebit.S
new file mode 100644
index 0000000..37c303e
--- /dev/null
+++ b/openpcd/firmware/lib/testchangebit.S
@@ -0,0 +1,18 @@
+/*
+ * linux/arch/arm/lib/testchangebit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_test_and_change_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_test_and_change_bit_le)
+ testop eor, strb
diff --git a/openpcd/firmware/lib/testclearbit.S b/openpcd/firmware/lib/testclearbit.S
new file mode 100644
index 0000000..985c399
--- /dev/null
+++ b/openpcd/firmware/lib/testclearbit.S
@@ -0,0 +1,18 @@
+/*
+ * linux/arch/arm/lib/testclearbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_test_and_clear_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_test_and_clear_bit_le)
+ testop bicne, strneb
diff --git a/openpcd/firmware/lib/testsetbit.S b/openpcd/firmware/lib/testsetbit.S
new file mode 100644
index 0000000..4a8a164
--- /dev/null
+++ b/openpcd/firmware/lib/testsetbit.S
@@ -0,0 +1,18 @@
+/*
+ * linux/arch/arm/lib/testsetbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_test_and_set_bit_be)
+ eor r0, r0, #0x18 @ big endian byte ordering
+ENTRY(_test_and_set_bit_le)
+ testop orreq, streqb
diff --git a/openpcd/firmware/src/dbgu.c b/openpcd/firmware/src/dbgu.c
index 1624795..1d54b41 100644
--- a/openpcd/firmware/src/dbgu.c
+++ b/openpcd/firmware/src/dbgu.c
@@ -1,26 +1,24 @@
-//*----------------------------------------------------------------------------
-//* ATMEL Microcontroller Software Support - ROUSSET -
-//*----------------------------------------------------------------------------
-//* The software is delivered "AS IS" without warranty or condition of any
-//* kind, either express, implied or statutory. This includes without
-//* limitation any warranty or condition with respect to merchantability or
-//* fitness for any particular purpose, or against the infringements of
-//* intellectual property rights of others.
-//*----------------------------------------------------------------------------
-//* File Name : Debug.c
-//* Object : Debug menu
-//* Creation : JPP 14/Sep/2004
-//* 1.1 29/Aug/05 JPP : Update AIC definion
-//*----------------------------------------------------------------------------
-
-// modified for WinARM example (remove scanf-function)
-// by Martin Thomas
+/*----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support - ROUSSET -
+ *----------------------------------------------------------------------------
+ * The software is delivered "AS IS" without warranty or condition of any
+ * kind, either express, implied or statutory. This includes without
+ * limitation any warranty or condition with respect to merchantability or
+ * fitness for any particular purpose, or against the infringements of
+ * intellectual property rights of others.
+ *----------------------------------------------------------------------------
+ * File Name : Debug.c
+ * Object : Debug menu
+ * Creation : JPP 14/Sep/2004
+ * 1.1 29/Aug/05 JPP : Update AIC definion
+ *----------------------------------------------------------------------------*/
// Include Standard files
#include "Board.h"
#include "dbgu.h"
#include "rc632.h"
#include "openpcd.h"
+#include "led.h"
#define USART_SYS_LEVEL 4
/*---------------------------- Global Variable ------------------------------*/
//*--------------------------1--------------------------------------------------
@@ -62,10 +60,10 @@ static void DBGU_irq_handler(void)
case '0': //* info
AT91F_DBGU_Frame("Set Pull up\n\r");
// Set
- AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, AT91C_PIO_UDP_PUP);
+ AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
break;
case '1': //* info
- AT91F_PIO_SetOutput(AT91C_BASE_PIOA, AT91C_PIO_UDP_PUP);
+ AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
AT91F_DBGU_Printk("Clear Pull up\n\r");
// Reset Application
Send_reset();
@@ -92,8 +90,8 @@ static void DBGU_irq_handler(void)
break;
case '6':
- DEBUGPCR("Writing RC632 Reg RxWait: 0x%02x",
- rc632_reg_write(RC632_REG_RX_WAIT, 0x55));
+ DEBUGPCR("Writing RC632 Reg RxWait: 0x55");
+ rc632_reg_write(RC632_REG_RX_WAIT, 0x55);
break;
case '7':
rc632_dump();
@@ -162,7 +160,8 @@ void AT91F_DBGU_Frame(char *buffer)
for (len = 0; buffer[len] != '\0'; len++) {
}
- AT91F_US_SendFrame((AT91PS_USART) AT91C_BASE_DBGU, buffer, len, 0, 0);
+ AT91F_US_SendFrame((AT91PS_USART) AT91C_BASE_DBGU,
+ (unsigned char *)buffer, len, 0, 0);
}
@@ -233,8 +232,9 @@ void debugp(const char *format, ...)
vsnprintf(dbg_buf, sizeof(dbg_buf)-1, format, ap);
va_end(ap);
- dbg_buf[sizeof(dbg_buf)-1] = '\0'; \
- AT91F_DBGU_Printk(dbg_buf); \
+ dbg_buf[sizeof(dbg_buf)-1] = '\0';
+ //AT91F_DBGU_Frame(dbg_buf);
+ AT91F_DBGU_Printk(dbg_buf);
}
#endif
diff --git a/openpcd/firmware/src/fifo.c b/openpcd/firmware/src/fifo.c
index 5bb0015..b0ec152 100644
--- a/openpcd/firmware/src/fifo.c
+++ b/openpcd/firmware/src/fifo.c
@@ -42,8 +42,6 @@ void fifo_check_raise_int(struct fifo *fifo)
u_int16_t fifo_data_put(struct fifo *fifo, u_int16_t len, u_int8_t *data)
{
- u_int16_t old_producer = fifo->producer;
-
if (len > fifo_available(fifo)) {
len = fifo_available(fifo);
fifo->irq |= FIFO_IRQ_OFLOW;
@@ -51,16 +49,16 @@ u_int16_t fifo_data_put(struct fifo *fifo, u_int16_t len, u_int8_t *data)
if (len + fifo->producer <= fifo->size) {
/* easy case */
- memcpy(fifo->data[fifo->producer], data, len);
+ memcpy(&fifo->data[fifo->producer], data, len);
fifo->producer += len;
} else {
/* difficult: wrap around */
u_int16_t chunk_len;
chunk_len = fifo->size - fifo->producer;
- memcpy(fifo->data[fifo->producer], data, chunk_len);
+ memcpy(&fifo->data[fifo->producer], data, chunk_len);
- memcpy(fifo->data[0], data + chunk_len, len - chunk_len);
+ memcpy(&fifo->data[0], data + chunk_len, len - chunk_len);
fifo->producer = len - chunk_len;
}
@@ -79,12 +77,12 @@ u_int16_t fifo_data_get(struct fifo *fifo, u_int16_t len, u_int8_t *data)
if (fifo->producer > fifo->consumer) {
/* easy case */
- memcpy(data, fifo->data[fifo->consumer], len);
+ memcpy(data, &fifo->data[fifo->consumer], len);
} else {
/* difficult case: wrap */
u_int16_t chunk_len = fifo->size - fifo->consumer;
- memcpy(data, fifo->data[fifo->consumer], chunk_len);
- memcpy(data+chunk_len, fifo->data[0], len - chunk_len);
+ memcpy(data, &fifo->data[fifo->consumer], chunk_len);
+ memcpy(data+chunk_len, &fifo->data[0], len - chunk_len);
}
fifo_check_water(fifo);
diff --git a/openpcd/firmware/src/fifo.h b/openpcd/firmware/src/fifo.h
index 324dad6..d91c6c2 100644
--- a/openpcd/firmware/src/fifo.h
+++ b/openpcd/firmware/src/fifo.h
@@ -1,7 +1,7 @@
#ifndef _FIFO_H
#define _FIFO_H
-#include <include/types.h>
+#include <sys/types.h>
#define FIFO_SIZE 1024
diff --git a/openpcd/firmware/src/led.c b/openpcd/firmware/src/led.c
index 83e7ce7..b3dcfc7 100644
--- a/openpcd/firmware/src/led.c
+++ b/openpcd/firmware/src/led.c
@@ -1,5 +1,5 @@
-#include <include/types.h>
+#include <sys/types.h>
#include <include/lib_AT91SAM7.h>
#include "openpcd.h"
#include "dbgu.h"
@@ -7,11 +7,11 @@
static int led2port(int led)
{
if (led == 1)
- return OPENPCD_LED1;
+ return OPENPCD_PIO_LED1;
else if (led == 2)
- return OPENPCD_LED2;
+ return OPENPCD_PIO_LED2;
else
- return -1;
+ return 0;
}
void led_switch(int led, int on)
@@ -47,12 +47,14 @@ int led_toggle(int led)
led_switch(led, 0);
else
led_switch(led, 1);
+
+ return !on;
}
void led_init(void)
{
- AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_LED1);
- AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_LED2);
+ AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED1);
+ AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED2);
led_switch(1, 0);
led_switch(2, 0);
}
diff --git a/openpcd/firmware/src/main.c b/openpcd/firmware/src/main.c
index 9d53ed1..384bad9 100644
--- a/openpcd/firmware/src/main.c
+++ b/openpcd/firmware/src/main.c
@@ -1,170 +1,42 @@
-//*--------------------------------------------------------------------------------------
-//* ATMEL Microcontroller Software Support - ROUSSET -
-//*--------------------------------------------------------------------------------------
-//* The software is delivered "AS IS" without warranty or condition of any
-//* kind, either express, implied or statutory. This includes without
-//* limitation any warranty or condition with respect to merchantability or
-//* fitness for any particular purpose, or against the infringements of
-//* intellectual property rights of others.
-//*--------------------------------------------------------------------------------------
-//* File Name : main.c
-//* Object : Testr USB device
-//* Translator :
-//* 1.0 19/03/01 HI : Creation
-//* 1.1 02/10/02 FB : Add on Svc DataFlash
-//* 1.2 13/Sep/04 JPP : Add DBGU
-//* 1.3 16/Dec/04 JPP : Add USART and enable reset
-//* 1.4 27/Apr/05 JPP : Unset the USART_COM and suppress displaying data
-//*--------------------------------------------------------------------------------------
-
#include <errno.h>
#include <string.h>
#include <include/lib_AT91SAM7.h>
-#include <include/openpcd.h>
#include "dbgu.h"
-#include "rc632.h"
#include "led.h"
-#include "pcd_enumerate.h"
#include "openpcd.h"
-#define MSG_SIZE 1000
-#if 0
-#define USART_COM
-
-#if defined(__WinARM__) && !defined(UART_COM)
-#warning "make sure syscalls.c is added to the source-file list (see makefile)"
-#endif
-#endif
-
-//*----------------------------------------------------------------------------
-static void AT91F_USB_Open(void)
-{
- // Set the PLL USB Divider
- AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1;
-
- // Specific Chip USB Initialisation
- // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
- AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
- AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
-
- // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
- // Set in PIO mode and Configure in Output
- AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, AT91C_PIO_UDP_PUP);
- // Clear for set the Pul up resistor
- AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, AT91C_PIO_UDP_PUP);
-
- // CDC Open by structure initialization
- AT91F_CDC_Open(AT91C_BASE_UDP);
-}
-
-static int usb_in(struct req_ctx *rctx)
-{
- struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->rx.data[0];
- struct openpcd_hdr *pih = (struct openpcd_hdr *) &rctx->tx.data[0];
- u_int16_t len = rctx->rx.tot_len;
-
- DEBUGP("usb_in ");
-
- if (len < sizeof(*poh))
- return -EINVAL;
-
- //data_len = ntohs(poh->len);
-
- memcpy(pih, poh, sizeof(*poh));
- rctx->tx.tot_len = sizeof(*poh);
-
- switch (poh->cmd) {
- case OPENPCD_CMD_READ_REG:
- DEBUGP("READ REG(0x%02x) ", poh->reg);
- pih->val = rc632_reg_read(poh->reg);
- break;
- case OPENPCD_CMD_READ_FIFO:
- DEBUGP("READ FIFO(len=%u) ", poh->val);
- pih->len = rc632_fifo_read(poh->val, pih->data);
- rctx->tx.tot_len += pih->len;
- break;
- case OPENPCD_CMD_WRITE_REG:
- DEBUGP("WRITE_REG(0x%02x, 0x%02x) ", poh->reg, poh->val);
- rc632_reg_write(poh->reg, poh->val);
- break;
- case OPENPCD_CMD_WRITE_FIFO:
- DEBUGP("WRITE FIFO(len=%u) ", poh->len);
- if (len - sizeof(*poh) < poh->len)
- return -EINVAL;
- rc632_fifo_write(poh->len, poh->data);
- break;
- case OPENPCD_CMD_READ_VFIFO:
- DEBUGP("READ VFIFO ");
- DEBUGP("NOT IMPLEMENTED YET ");
- break;
- case OPENPCD_CMD_WRITE_VFIFO:
- DEBUGP("WRITE VFIFO ");
- DEBUGP("NOT IMPLEMENTED YET ");
- break;
- case OPENPCD_CMD_REG_BITS_CLEAR:
- DEBUGP("CLEAR BITS ");
- pih->val = rc632_clear_bits(poh->reg, poh->val);
- break;
- case OPENPCD_CMD_REG_BITS_SET:
- DEBUGP("SET BITS ");
- pih->val = rc632_set_bits(poh->reg, poh->val);
- break;
- case OPENPCD_CMD_SET_LED:
- DEBUGP("SET LED(%u,%u) ", poh->reg, poh->val);
- led_switch(poh->reg, poh->val);
- break;
- default:
- return -EINVAL;
- }
- DEBUGPCRF("calling UDP_Write");
- AT91F_UDP_Write(0, &rctx->tx.data[0], rctx->tx.tot_len);
- DEBUGPCRF("usb_in: returning to main");
-}
-
#define DEBUG_TOGGLE_LED
int main(void)
{
- int i;
-
+ /* initialize LED and debug unit */
led_init();
- // Init trace DBGU
AT91F_DBGU_Init();
- rc632_init();
-
+
+ /* call application specific init function */
+ _init_func();
+
// Enable User Reset and set its minimal assertion to 960 us
AT91C_BASE_RSTC->RSTC_RMR =
AT91C_RSTC_URSTEN | (0x4 << 8) | (unsigned int)(0xA5 << 24);
- // Init USB device
- AT91F_USB_Open();
-
#ifdef DEBUG_CLOCK_PA6
AT91F_PMC_EnablePCK(AT91C_BASE_PMC, 0, AT91C_PMC_CSS_PLL_CLK);
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, 0, AT91C_PA6_PCK0);
#endif
+ /* switch on first led */
led_switch(1, 1);
- // Init USB device
+ DEBUGPCRF("entering main (idle) loop");
while (1) {
- struct req_ctx *rctx;
-
#ifdef DEBUG_TOGGLE_LED
/* toggle LEDs */
led_toggle(1);
led_toggle(2);
#endif
- for (rctx = req_ctx_find_busy(); rctx;
- rctx = req_ctx_find_busy()) {
- DEBUGPCRF("found used ctx %u: len=%u",
- req_ctx_num(rctx), rctx->rx.tot_len);
- usb_in(rctx);
- req_ctx_put(rctx);
- }
-
- /* busy-wait for led toggle */
- for (i = 0; i < 0x2fffff; i++) {}
+ /* Call application specific main idle function */
+ _main_func();
}
}
diff --git a/openpcd/firmware/src/main_dumbreader.c b/openpcd/firmware/src/main_dumbreader.c
new file mode 100644
index 0000000..43801f6
--- /dev/null
+++ b/openpcd/firmware/src/main_dumbreader.c
@@ -0,0 +1,94 @@
+#include <errno.h>
+#include <string.h>
+#include <include/lib_AT91SAM7.h>
+#include <include/openpcd.h>
+#include "dbgu.h"
+#include "rc632.h"
+#include "led.h"
+#include "pcd_enumerate.h"
+#include "openpcd.h"
+
+static int usb_in(struct req_ctx *rctx)
+{
+ struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->rx.data[0];
+ struct openpcd_hdr *pih = (struct openpcd_hdr *) &rctx->tx.data[0];
+ u_int16_t len = rctx->rx.tot_len;
+
+ DEBUGP("usb_in ");
+
+ if (len < sizeof(*poh))
+ return -EINVAL;
+
+ //data_len = ntohs(poh->len);
+
+ memcpy(pih, poh, sizeof(*poh));
+ rctx->tx.tot_len = sizeof(*poh);
+
+ switch (poh->cmd) {
+ case OPENPCD_CMD_READ_REG:
+ DEBUGP("READ REG(0x%02x) ", poh->reg);
+ pih->val = rc632_reg_read(poh->reg);
+ break;
+ case OPENPCD_CMD_READ_FIFO:
+ DEBUGP("READ FIFO(len=%u) ", poh->val);
+ pih->len = rc632_fifo_read(poh->val, pih->data);
+ rctx->tx.tot_len += pih->len;
+ break;
+ case OPENPCD_CMD_WRITE_REG:
+ DEBUGP("WRITE_REG(0x%02x, 0x%02x) ", poh->reg, poh->val);
+ rc632_reg_write(poh->reg, poh->val);
+ break;
+ case OPENPCD_CMD_WRITE_FIFO:
+ DEBUGP("WRITE FIFO(len=%u) ", poh->len);
+ if (len - sizeof(*poh) < poh->len)
+ return -EINVAL;
+ rc632_fifo_write(poh->len, poh->data);
+ break;
+ case OPENPCD_CMD_READ_VFIFO:
+ DEBUGP("READ VFIFO ");
+ DEBUGP("NOT IMPLEMENTED YET ");
+ break;
+ case OPENPCD_CMD_WRITE_VFIFO:
+ DEBUGP("WRITE VFIFO ");
+ DEBUGP("NOT IMPLEMENTED YET ");
+ break;
+ case OPENPCD_CMD_REG_BITS_CLEAR:
+ DEBUGP("CLEAR BITS ");
+ pih->val = rc632_clear_bits(poh->reg, poh->val);
+ break;
+ case OPENPCD_CMD_REG_BITS_SET:
+ DEBUGP("SET BITS ");
+ pih->val = rc632_set_bits(poh->reg, poh->val);
+ break;
+ case OPENPCD_CMD_SET_LED:
+ DEBUGP("SET LED(%u,%u) ", poh->reg, poh->val);
+ led_switch(poh->reg, poh->val);
+ break;
+ default:
+ return -EINVAL;
+ }
+ DEBUGPCRF("calling UDP_Write");
+ AT91F_UDP_Write(0, &rctx->tx.data[0], rctx->tx.tot_len);
+ DEBUGPCRF("usb_in: returning to main");
+
+ return 0;
+}
+
+void _init_func(void)
+{
+ rc632_init();
+ udp_init();
+}
+
+void _main_func(void)
+{
+ struct req_ctx *rctx;
+
+ for (rctx = req_ctx_find_busy(); rctx;
+ rctx = req_ctx_find_busy()) {
+ DEBUGPCRF("found used ctx %u: len=%u",
+ req_ctx_num(rctx), rctx->rx.tot_len);
+ usb_in(rctx);
+ req_ctx_put(rctx);
+ }
+}
diff --git a/openpcd/firmware/src/main_reqa.c b/openpcd/firmware/src/main_reqa.c
new file mode 100644
index 0000000..8d0b170
--- /dev/null
+++ b/openpcd/firmware/src/main_reqa.c
@@ -0,0 +1,25 @@
+#include "rc632_highlevel.h"
+#include "rc632.h"
+#include "dbgu.h"
+#include "trigger.h"
+
+void _init_func(void)
+{
+ rc632_init();
+ udp_init();
+ trigger_init();
+}
+
+
+void _main_func(void)
+{
+ struct iso14443a_atqa atqa;
+
+ memset(&atqa, 0, sizeof(atqua));
+
+ trigger_pulse();
+
+ if (rc632_iso14443a_transceive_sf(ISO14443A_SF_CMD_WUPA, &atqa) < 0)
+ DEBUGPCRF("error during transceive_sf");
+
+}
diff --git a/openpcd/firmware/src/openpcd.h b/openpcd/firmware/src/openpcd.h
index ddd3370..3ba2477 100644
--- a/openpcd/firmware/src/openpcd.h
+++ b/openpcd/firmware/src/openpcd.h
@@ -2,18 +2,22 @@
#define _OPENPCD_H
#ifdef OLIMEX
-#define OPENPCD_LED1 AT91C_PIO_PA18
-#define OPENPCD_LED2 AT91C_PIO_PA17
-//#define AT91C_PIO_UDP_PUP AT91C_PIO_PA25
-#define AT91C_PIO_UDP_PUP AT91C_PIO_PA16
+#define OPENPCD_PIO_LED2 AT91C_PIO_PA17
+#define OPENPCD_PIO_LED1 AT91C_PIO_PA18
+#define OPENPCD_PIO_UDP_PUP AT91C_PIO_PA25
#else
-#define OPENPCD_LED1 AT91C_PIO_PA25
-#define OPENPCD_LED2 AT91C_PIO_PA26
-#define AT91C_PIO_UDP_PUP AT91C_PIO_PA16
+#define OPENPCD_PIO_UDP_CNX AT91C_PIO_PA15
+#define OPENPCD_PIO_UDP_PUP AT91C_PIO_PA16
+#define OPENPCD_PIO_LED1 AT91C_PIO_PA25
+#define OPENPCD_PIO_LED2 AT91C_PIO_PA26
#endif
-#define OPENPCD_RC632_IRQ AT91C_ID_IRQ1
-#define OPENPCD_RC632_RESET AT91C_PIO_PA29
+#define OPENPCD_IRQ_RC632 AT91C_ID_IRQ1
+
+#define OPENPCD_PIO_MFIN AT91C_PIO_PA9
+#define OPENPCD_PIO_MFOUT AT91C_PIO_PA10
+#define OPENPCD_PIO_RC632_RESET AT91C_PIO_PA29
+#define OPENPCD_PIO_TRIGGER AT91C_PIO_PA31
#define OPENPCD_IRQ_PRIO_SPI AT91C_AIC_PRIOR_HIGHEST
#define OPENPCD_IRQ_PRIO_UDP (AT91C_AIC_PRIOR_LOWEST+1)
@@ -25,7 +29,7 @@
#define req_buf_payload(x) (x->data[x->hdr_len])
#define req_buf_hdr(x) (x->data[0])
-#include <include/types.h>
+#include <sys/types.h>
struct req_buf {
u_int16_t hdr_len;
@@ -44,7 +48,11 @@ struct req_ctx {
#define NUM_REQ_CTX 8
extern struct req_ctx *req_ctx_find_get(void);
+extern struct req_ctx *req_ctx_find_busy(void);
extern void req_ctx_put(struct req_ctx *ctx);
extern u_int8_t req_ctx_num(struct req_ctx *ctx);
+extern void _init_func(void);
+extern void _main_func(void);
+
#endif /* _OPENPCD_H */
diff --git a/openpcd/firmware/src/pcd_enumerate.c b/openpcd/firmware/src/pcd_enumerate.c
index 64c915c..ad18e29 100644
--- a/openpcd/firmware/src/pcd_enumerate.c
+++ b/openpcd/firmware/src/pcd_enumerate.c
@@ -18,7 +18,7 @@
// 12. Apr. 2006: added modification found in the mikrocontroller.net gcc-Forum
// additional line marked with /* +++ */
-#include <include/types.h>
+#include <sys/types.h>
#include <include/usb_ch9.h>
#include <include/lib_AT91SAM7.h>
#include <include/openpcd.h>
@@ -127,12 +127,7 @@ const struct _desc cfgDescriptor = {
#define STD_SET_INTERFACE 0x0B01
#define STD_SYNCH_FRAME 0x0C82
-/// mt u_int32_t currentReceiveBank = AT91C_UDP_RX_DATA_BK0;
-
-static u_int32_t AT91F_UDP_Read(char *pData, u_int32_t length);
-static void AT91F_CDC_Enumerate(void);
-
-static char rcv_data[64];
+static void udp_ep0_handler(void);
static void udp_irq(void)
{
@@ -160,7 +155,7 @@ static void udp_irq(void)
if (isr & AT91C_UDP_EPINT0) {
DEBUGP("EP0INT(Control) ");
- AT91F_CDC_Enumerate();
+ udp_ep0_handler();
}
if (isr & AT91C_UDP_EPINT1) {
u_int32_t cur_rcv_bank = pCDC.currentRcvBank;
@@ -236,12 +231,10 @@ static void udp_irq(void)
DEBUGP("END\r\n");
}
-//*----------------------------------------------------------------------------
-//* \fn AT91F_CDC_Open
-//* \brief
-//*----------------------------------------------------------------------------
-AT91PS_CDC AT91F_CDC_Open(AT91PS_UDP pUdp)
+/* Open USB Device Port */
+static AT91PS_CDC AT91F_PCD_Open(AT91PS_UDP pUdp)
{
+ DEBUGPCRF("entering");
pCdc->pUdp = pUdp;
pCdc->currentConfiguration = 0;
pCdc->currentConnection = 0;
@@ -254,58 +247,38 @@ AT91PS_CDC AT91F_CDC_Open(AT91PS_UDP pUdp)
/* End-of-Bus-Reset is always enabled */
+ DEBUGPCRF("returning after enabling UDP irq");
+
return pCdc;
}
-//*----------------------------------------------------------------------------
-//* \fn AT91F_UDP_IsConfigured
-//* \brief Test if the device is configured and handle enumeration
-//*----------------------------------------------------------------------------
-u_int8_t AT91F_UDP_IsConfigured(void)
+void udp_init(void)
{
- return pCdc->currentConfiguration;
-}
+ /* Set the PLL USB Divider */
+ AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1;
-//*----------------------------------------------------------------------------
-//* \fn AT91F_UDP_Read
-//* \brief Read available data from Endpoint OUT
-//*----------------------------------------------------------------------------
-static u_int32_t AT91F_UDP_Read(char *pData, u_int32_t length)
-{
- AT91PS_UDP pUdp = pCdc->pUdp;
- u_int32_t packetSize, nbBytesRcv = 0, currentReceiveBank =
- pCdc->currentRcvBank;
+ /* Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock */
+ AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
- while (length) {
- if (!AT91F_UDP_IsConfigured())
- break;
- if (pUdp->UDP_CSR[AT91C_EP_OUT] & currentReceiveBank) {
- packetSize =
- MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, length);
- length -= packetSize;
- if (packetSize < AT91C_EP_OUT_SIZE)
- length = 0;
- while (packetSize--)
- pData[nbBytesRcv++] =
- pUdp->UDP_FDR[AT91C_EP_OUT];
- pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(currentReceiveBank);
- if (currentReceiveBank == AT91C_UDP_RX_DATA_BK0)
- currentReceiveBank = AT91C_UDP_RX_DATA_BK1;
- else
- currentReceiveBank = AT91C_UDP_RX_DATA_BK0;
+ /* Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
+ * Set in PIO mode and Configure in Output */
+ AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
+ /* Clear for set the Pul up resistor */
+ AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
- }
- }
- pCdc->currentRcvBank = currentReceiveBank;
- return nbBytesRcv;
+ /* CDC Open by structure initialization */
+ AT91F_PCD_Open(AT91C_BASE_UDP);
+}
+/* Test if the device is configured and handle enumeration */
+u_int8_t udp_is_configured(void)
+{
+ return pCdc->currentConfiguration;
}
-//*----------------------------------------------------------------------------
-//* \fn AT91F_CDC_Write
-//* \brief Send through endpoint 2/3
-//*----------------------------------------------------------------------------
-u_int32_t AT91F_UDP_Write(u_int8_t irq, const char *pData, u_int32_t length)
+/* Send data through endpoint 2/3 */
+u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t length)
{
AT91PS_UDP pUdp = pCdc->pUdp;
u_int32_t cpt = 0;
@@ -336,7 +309,7 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const char *pData, u_int32_t length)
DEBUGPCRF("waiting for end of further packet");
// Wait for the the first bank to be sent
while (!(pUdp->UDP_CSR[ep] & AT91C_UDP_TXCOMP))
- if (!AT91F_UDP_IsConfigured()) {
+ if (!udp_is_configured()) {
DEBUGPCRF("return(!configured)");
return length;
}
@@ -347,7 +320,7 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const char *pData, u_int32_t length)
// Wait for the end of transfer
DEBUGPCRF("waiting for end of transfer");
while (!(pUdp->UDP_CSR[ep] & AT91C_UDP_TXCOMP))
- if (!AT91F_UDP_IsConfigured()) {
+ if (!udp_is_configured()) {
DEBUGPCRF("return(!configured)");
return length;
}
@@ -358,14 +331,8 @@ u_int32_t AT91F_UDP_Write(u_int8_t irq, const char *pData, u_int32_t length)
return length;
}
-//*----------------------------------------------------------------------------
-//* \fn AT91F_USB_SendData
-//* \brief Send Data through the control endpoint
-//*----------------------------------------------------------------------------
-unsigned int csrTab[100];
-unsigned char csrIdx = 0;
-
-static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, u_int32_t length)
+/* Send Data through the control endpoint */
+static void udp_ep0_send_data(AT91PS_UDP pUdp, const char *pData, u_int32_t length)
{
u_int32_t cpt = 0;
AT91_REG csr;
@@ -404,11 +371,8 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, u_int32_t len
}
}
-//*----------------------------------------------------------------------------
-//* \fn AT91F_USB_SendZlp
-//* \brief Send zero length packet through the control endpoint
-//*----------------------------------------------------------------------------
-void AT91F_USB_SendZlp(AT91PS_UDP pUdp)
+/* Send zero length packet through the control endpoint */
+static void udp_ep0_send_zlp(AT91PS_UDP pUdp)
{
pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
while (!(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP)) ;
@@ -416,11 +380,8 @@ void AT91F_USB_SendZlp(AT91PS_UDP pUdp)
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) ;
}
-//*----------------------------------------------------------------------------
-//* \fn AT91F_USB_SendStall
-//* \brief Stall the control endpoint
-//*----------------------------------------------------------------------------
-void AT91F_USB_SendStall(AT91PS_UDP pUdp)
+/* Stall the control endpoint */
+static void udp_ep0_send_stall(AT91PS_UDP pUdp)
{
pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
while (!(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR)) ;
@@ -428,11 +389,8 @@ void AT91F_USB_SendStall(AT91PS_UDP pUdp)
while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)) ;
}
-//*----------------------------------------------------------------------------
-//* \fn AT91F_CDC_Enumerate
-//* \brief This function is a callback invoked when a SETUP packet is received
-//*----------------------------------------------------------------------------
-static void AT91F_CDC_Enumerate(void)
+/* Handle requests on the USB Control Endpoint */
+static void udp_ep0_handler(void)
{
AT91PS_UDP pUDP = pCdc->pUdp;
u_int8_t bmRequestType, bRequest;
@@ -464,17 +422,17 @@ static void AT91F_CDC_Enumerate(void)
case STD_GET_DESCRIPTOR:
DEBUGP("GET_DESCRIPTOR ");
if (wValue == 0x100) // Return Device Descriptor
- AT91F_USB_SendData(pUDP, (const char *) &devDescriptor,
+ udp_ep0_send_data(pUDP, (const char *) &devDescriptor,
MIN(sizeof(devDescriptor), wLength));
else if (wValue == 0x200) // Return Configuration Descriptor
- AT91F_USB_SendData(pUDP, (const char *) &cfgDescriptor,
+ udp_ep0_send_data(pUDP, (const char *) &cfgDescriptor,
MIN(sizeof(cfgDescriptor), wLength));
else
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
case STD_SET_ADDRESS:
DEBUGP("SET_ADDRESS ");
- AT91F_USB_SendZlp(pUDP);
+ udp_ep0_send_zlp(pUDP);
pUDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);
pUDP->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;
break;
@@ -483,7 +441,7 @@ static void AT91F_CDC_Enumerate(void)
if (wValue)
DEBUGP("VALUE!=0 ");
pCdc->currentConfiguration = wValue;
- AT91F_USB_SendZlp(pUDP);
+ udp_ep0_send_zlp(pUDP);
pUDP->UDP_GLBSTATE =
(wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
pUDP->UDP_CSR[1] =
@@ -498,18 +456,18 @@ static void AT91F_CDC_Enumerate(void)
break;
case STD_GET_CONFIGURATION:
DEBUGP("GET_CONFIG ");
- AT91F_USB_SendData(pUDP, (char *)&(pCdc->currentConfiguration),
+ udp_ep0_send_data(pUDP, (char *)&(pCdc->currentConfiguration),
sizeof(pCdc->currentConfiguration));
break;
case STD_GET_STATUS_ZERO:
DEBUGP("GET_STATUS_ZERO ");
wStatus = 0;
- AT91F_USB_SendData(pUDP, (char *)&wStatus, sizeof(wStatus));
+ udp_ep0_send_data(pUDP, (char *)&wStatus, sizeof(wStatus));
break;
case STD_GET_STATUS_INTERFACE:
DEBUGP("GET_STATUS_INTERFACE ");
wStatus = 0;
- AT91F_USB_SendData(pUDP, (char *)&wStatus, sizeof(wStatus));
+ udp_ep0_send_data(pUDP, (char *)&wStatus, sizeof(wStatus));
break;
case STD_GET_STATUS_ENDPOINT:
DEBUGP("GET_STATUS_ENDPOINT(EPidx=%u) ", wIndex&0x0f);
@@ -518,42 +476,42 @@ static void AT91F_CDC_Enumerate(void)
if ((pUDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
wStatus =
(pUDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
- AT91F_USB_SendData(pUDP, (char *)&wStatus,
+ udp_ep0_send_data(pUDP, (char *)&wStatus,
sizeof(wStatus));
} else if ((pUDP->UDP_GLBSTATE & AT91C_UDP_FADDEN)
&& (wIndex == 0)) {
wStatus =
(pUDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
- AT91F_USB_SendData(pUDP, (char *)&wStatus,
+ udp_ep0_send_data(pUDP, (char *)&wStatus,
sizeof(wStatus));
} else
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
case STD_SET_FEATURE_ZERO:
DEBUGP("SET_FEATURE_ZERO ");
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
case STD_SET_FEATURE_INTERFACE:
DEBUGP("SET_FEATURE_INTERFACE ");
- AT91F_USB_SendZlp(pUDP);
+ udp_ep0_send_zlp(pUDP);
break;
case STD_SET_FEATURE_ENDPOINT:
DEBUGP("SET_FEATURE_ENDPOINT ");
- AT91F_USB_SendZlp(pUDP);
+ udp_ep0_send_zlp(pUDP);
wIndex &= 0x0F;
if ((wValue == 0) && wIndex && (wIndex <= 3)) {
pUDP->UDP_CSR[wIndex] = 0;
- AT91F_USB_SendZlp(pUDP);
+ udp_ep0_send_zlp(pUDP);
} else
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
case STD_CLEAR_FEATURE_ZERO:
DEBUGP("CLEAR_FEATURE_ZERO ");
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
case STD_CLEAR_FEATURE_INTERFACE:
DEBUGP("CLEAR_FEATURE_INTERFACE ");
- AT91F_USB_SendZlp(pUDP);
+ udp_ep0_send_zlp(pUDP);
break;
case STD_CLEAR_FEATURE_ENDPOINT:
DEBUGP("CLEAR_FEATURE_ENDPOINT(EPidx=%u) ", wIndex & 0x0f);
@@ -580,17 +538,17 @@ static void AT91F_CDC_Enumerate(void)
pUDP->UDP_RSTEP |= AT91C_UDP_EP3;
pUDP->UDP_RSTEP &= ~AT91C_UDP_EP3;
}
- AT91F_USB_SendZlp(pUDP);
+ udp_ep0_send_zlp(pUDP);
} else
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
case STD_SET_INTERFACE:
DEBUGP("SET INTERFACE ");
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
default:
DEBUGP("DEFAULT(req=0x%02x, type=0x%02x) ", bRequest, bmRequestType);
- AT91F_USB_SendStall(pUDP);
+ udp_ep0_send_stall(pUDP);
break;
}
}
diff --git a/openpcd/firmware/src/pcd_enumerate.h b/openpcd/firmware/src/pcd_enumerate.h
index d51ffa3..31d8f28 100644
--- a/openpcd/firmware/src/pcd_enumerate.h
+++ b/openpcd/firmware/src/pcd_enumerate.h
@@ -15,8 +15,8 @@
#ifndef PCD_ENUMERATE_H
#define PCD_ENUMERATE_H
-#include <include/AT91SAM7.h>
-#include <include/types.h>
+#include <sys/types.h>
+#include <AT91SAM7.h>
#define AT91C_EP_OUT 1
#define AT91C_EP_OUT_SIZE 0x40
@@ -36,9 +36,9 @@ typedef struct _AT91S_CDC
//* external function description
-AT91PS_CDC AT91F_CDC_Open(AT91PS_UDP pUdp);
+extern void udp_init(void);
u_int8_t AT91F_UDP_IsConfigured(void);
-u_int32_t AT91F_UDP_Write(u_int8_t irq, const char *pData, u_int32_t length);
+u_int32_t AT91F_UDP_Write(u_int8_t irq, const unsigned char *pData, u_int32_t length);
#endif // CDC_ENUMERATE_H
diff --git a/openpcd/firmware/src/rc632.c b/openpcd/firmware/src/rc632.c
index c8aa093..b1e5a3c 100644
--- a/openpcd/firmware/src/rc632.c
+++ b/openpcd/firmware/src/rc632.c
@@ -11,6 +11,10 @@
#include "openpcd.h"
#include "fifo.h"
#include "dbgu.h"
+#include "pcd_enumerate.h"
+
+#define SPI_DEBUG_LOOPBACK
+#define SPI_USES_DMA
static AT91PS_SPI pSPI = AT91C_BASE_SPI;
@@ -19,18 +23,45 @@ static void spi_irq(void)
{
u_int32_t status = pSPI->SPI_SR;
- DEBUGP("spi_irq: 0x%08x", status);
+ DEBUGP("spi_irq: 0x%08x ", status);
AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SPI);
if (status & AT91C_SPI_OVRES)
- DEBUGP("Overrun detected ");
+ DEBUGP("Overrun ");
if (status & AT91C_SPI_MODF)
- DEBUGP("Mode Fault detected ");
+ DEBUGP("ModeFault ");
+ if (status & AT91C_SPI_ENDRX) {
+ pSPI->SPI_IDR = AT91C_SPI_ENDRX;
+ DEBUGP("ENDRX ");
+ }
+ if (status & AT91C_SPI_ENDTX) {
+ pSPI->SPI_IDR = AT91C_SPI_ENDTX;
+ DEBUGP("ENDTX ");
+ }
DEBUGP("\r\n");
}
+#ifdef SPI_USES_DMA
+int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len,
+ u_int8_t *rx_data, u_int16_t *rx_len)
+{
+ DEBUGP("Starting DMA Xfer: ");
+ AT91F_SPI_ReceiveFrame(pSPI, rx_data, *rx_len, NULL, 0);
+ AT91F_SPI_SendFrame(pSPI, tx_data, tx_len, NULL, 0);
+ AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI);
+ AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI);
+ pSPI->SPI_IER = AT91C_SPI_ENDTX|AT91C_SPI_ENDRX;
+ AT91F_SPI_Enable(pSPI);
+
+ while (!(pSPI->SPI_SR & (AT91C_SPI_ENDRX|AT91C_SPI_ENDTX))) ;
+
+ DEBUGPCR("DMA Xfer finished");
+
+ return 0;
+}
+#else
/* stupid polling transceiver routine */
int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len,
u_int8_t *rx_data, u_int16_t *rx_len)
@@ -77,6 +108,7 @@ int spi_transceive(const u_int8_t *tx_data, u_int16_t tx_len,
return 0;
}
+#endif
/* static buffers used by routines below */
static u_int8_t spi_outbuf[64+1];
@@ -209,16 +241,18 @@ static void rc632_irq(void)
irq_opcdh.val = cause;
- AT91F_UDP_Write(1, &irq_opcdh, sizeof(irq_opcdh));
+ AT91F_UDP_Write(1, (u_int8_t *) &irq_opcdh, sizeof(irq_opcdh));
DEBUGP("\n");
}
void rc632_power(u_int8_t up)
{
if (up)
- AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_RC632_RESET);
+ AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,
+ OPENPCD_PIO_RC632_RESET);
else
- AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_RC632_RESET);
+ AT91F_PIO_SetOutput(AT91C_BASE_PIOA,
+ OPENPCD_PIO_RC632_RESET);
}
void rc632_reset(void)
@@ -251,8 +285,17 @@ void rc632_init(void)
OPENPCD_IRQ_PRIO_SPI,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &spi_irq);
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI);
+
AT91F_SPI_EnableIt(pSPI, AT91C_SPI_MODF|AT91C_SPI_OVRES);
+#ifdef SPI_USES_DMA
+ AT91F_SPI_EnableIt(pSPI, AT91C_SPI_ENDRX|AT91C_SPI_ENDTX);
+#endif
+
+#ifdef SPI_DEBUG_LOOPBACK
+ AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED|AT91C_SPI_LLB);
+#else
AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED);
+#endif
/* CPOL = 0, NCPHA = 1, CSAAT = 0, BITS = 0000, SCBR = 10 (4.8MHz),
* DLYBS = 0, DLYBCT = 0 */
//AT91F_SPI_CfgCs(pSPI, 0, AT91C_SPI_BITS_8|AT91C_SPI_NCPHA|(10<<8));
@@ -261,12 +304,14 @@ void rc632_init(void)
//AT91F_SPI_Reset(pSPI);
/* Register rc632_irq */
- AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, OPENPCD_RC632_IRQ,
+ AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632,
OPENPCD_IRQ_PRIO_RC632,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &rc632_irq);
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_IRQ1);
- AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_RC632_RESET);
+ AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_RC632_RESET);
+ AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_MFIN);
+ AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPCD_PIO_MFOUT);
/* initialize static part of openpcd_hdr for USB IRQ reporting */
irq_opcdh.cmd = OPENPCD_CMD_IRQ;
diff --git a/openpcd/firmware/src/rc632.h b/openpcd/firmware/src/rc632.h
index 77f7c20..acede11 100644
--- a/openpcd/firmware/src/rc632.h
+++ b/openpcd/firmware/src/rc632.h
@@ -1,13 +1,13 @@
#ifndef _RC623_API_H
#define _RC632_API_H
-#include <include/types.h>
+#include <sys/types.h>
#include <include/cl_rc632.h>
-extern void rc632_write_reg(u_int8_t addr, u_int8_t data);
-extern void rc632_write_fifo(u_int8_t len, u_int8_t *data);
-extern u_int8_t rc632_read_reg(u_int8_t addr);
-extern u_int8_t rc632_read_fifo(u_int8_t max_len, u_int8_t *data);
+extern void rc632_reg_write(u_int8_t addr, u_int8_t data);
+extern void rc632_fifo_write(u_int8_t len, u_int8_t *data);
+extern u_int8_t rc632_reg_read(u_int8_t addr);
+extern u_int8_t rc632_fifo_read(u_int8_t max_len, u_int8_t *data);
extern u_int8_t rc632_clear_bits(u_int8_t reg, u_int8_t bits);
extern u_int8_t rc632_set_bits(u_int8_t reg, u_int8_t bits);
extern void rc632_init(void);
diff --git a/openpcd/firmware/src/rc632_highlevel.c b/openpcd/firmware/src/rc632_highlevel.c
new file mode 100644
index 0000000..9a50df1
--- /dev/null
+++ b/openpcd/firmware/src/rc632_highlevel.c
@@ -0,0 +1,489 @@
+/* ISO 14443 WUPA / SELECT anticollision implementation, part of OpenPCD
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ */
+
+static int
+rc632_iso14443a_init(void)
+{
+ int ret;
+
+ // FIXME: some fifo work (drain fifo?)
+
+ /* flush fifo (our way) */
+ ret = rc632_reg_write(RC632_REG_CONTROL, 0x01);
+
+ ret = rc632_reg_write(RC632_REG_TX_CONTROL,
+ (RC632_TXCTRL_TX1_RF_EN |
+ RC632_TXCTRL_TX2_RF_EN |
+ RC632_TXCTRL_TX2_INV |
+ RC632_TXCTRL_FORCE_100_ASK |
+ RC632_TXCTRL_MOD_SRC_INT));
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_CW_CONDUCTANCE,
+ CM5121_CW_CONDUCTANCE);
+ if (ret < 0)
+ return ret;
+
+ /* Since FORCE_100_ASK is set (cf mc073930.pdf), this line may be left out? */
+ ret = rc632_reg_write(RC632_REG_MOD_CONDUCTANCE,
+ CM5121_MOD_CONDUCTANCE);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_CODER_CONTROL,
+ (RC632_CDRCTRL_TXCD_14443A |
+ RC632_CDRCTRL_RATE_106K));
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_MOD_WIDTH, 0x13);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_MOD_WIDTH_SOF, 0x3f);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_TYPE_B_FRAMING, 0x00);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_RX_CONTROL1,
+ (RC632_RXCTRL1_GAIN_35DB |
+ RC632_RXCTRL1_ISO14443 |
+ RC632_RXCTRL1_SUBCP_8));
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_DECODER_CONTROL,
+ (RC632_DECCTRL_MANCHESTER |
+ RC632_DECCTRL_RXFR_14443A));
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_BIT_PHASE,
+ CM5121_14443A_BITPHASE);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_RX_THRESHOLD,
+ CM5121_14443A_THRESHOLD);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_BPSK_DEM_CONTROL, 0x00);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_RX_CONTROL2,
+ (RC632_RXCTRL2_DECSRC_INT |
+ RC632_RXCTRL2_CLK_Q));
+ if (ret < 0)
+ return ret;
+
+ /* Omnikey proprietary driver has 0x03, but 0x06 is the default reset
+ * value ?!? */
+ ret = rc632_reg_write(RC632_REG_RX_WAIT, 0x06);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_CHANNEL_REDUNDANCY,
+ (RC632_CR_PARITY_ENABLE |
+ RC632_CR_PARITY_ODD));
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_CRC_PRESET_LSB, 0x63);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_write(RC632_REG_CRC_PRESET_MSB, 0x63);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int
+rc632_transceive(const u_int8_t *tx_buf,
+ u_int8_t tx_len,
+ u_int8_t *rx_buf,
+ u_int8_t *rx_len,
+ u_int64_t timer,
+ unsigned int toggle)
+{
+ int ret, cur_tx_len;
+ const u_int8_t *cur_tx_buf = tx_buf;
+
+ DEBUGP("timer = %u\n", timer);
+
+ if (tx_len > 64)
+ cur_tx_len = 64;
+ else
+ cur_tx_len = tx_len;
+
+ ret = rc632_timer_set(timer);
+ if (ret < 0)
+ return ret;
+
+ /* clear all interrupts */
+ ret = rc632_reg_write(RC632_REG_INTERRUPT_RQ, 0x7f);
+
+ do {
+ ret = rc632_fifo_write(cur_tx_len, cur_tx_buf, 0x03);
+ if (ret < 0)
+ return ret;
+
+ if (cur_tx_buf == tx_buf) {
+ ret = rc632_reg_write(RC632_REG_COMMAND,
+ RC632_CMD_TRANSCEIVE);
+ if (ret < 0)
+ return ret;
+ }
+
+ cur_tx_buf += cur_tx_len;
+ if (cur_tx_buf < tx_buf + tx_len) {
+ u_int8_t fifo_fill;
+ ret = rc632_reg_read(RC632_REG_FIFO_LENGTH,
+ &fifo_fill);
+ if (ret < 0)
+ return ret;
+
+ cur_tx_len = 64 - fifo_fill;
+ printf("refilling tx fifo with %u bytes\n", cur_tx_len);
+ } else
+ cur_tx_len = 0;
+
+ } while (cur_tx_len);
+
+ if (toggle == 1)
+ tcl_toggle_pcb(handle);
+
+ ret = rc632_wait_idle_timer(handle);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_reg_read(RC632_REG_FIFO_LENGTH, rx_len);
+ if (ret < 0)
+ return ret;
+
+ if (*rx_len == 0) {
+ u_int8_t tmp;
+
+ DEBUGP("rx_len == 0\n");
+
+ rc632_reg_read(RC632_REG_ERROR_FLAG, &tmp);
+ rc632_reg_read(RC632_REG_CHANNEL_REDUNDANCY, &tmp);
+
+ return -1;
+ }
+
+ return rc632_fifo_read(*rx_len, rx_buf);
+}
+
+/* issue a 14443-3 A PCD -> PICC command in a short frame, such as REQA, WUPA */
+static int
+rc632_iso14443a_transceive_sf(u_int8_t cmd,
+ struct iso14443a_atqa *atqa)
+{
+ int ret;
+ u_int8_t tx_buf[1];
+ u_int8_t rx_len = 2;
+
+ memset(atqa, 0, sizeof(atqa));
+
+ tx_buf[0] = cmd;
+
+ /* transfer only 7 bits of last byte in frame */
+ ret = rc632_reg_write(RC632_REG_BIT_FRAMING, 0x07);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_clear_bits(RC632_REG_CONTROL,
+ RC632_CONTROL_CRYPTO1_ON);
+ if (ret < 0)
+ return ret;
+
+#if 0
+ ret = rc632_reg_write(RC632_REG_CHANNEL_REDUNDANCY,
+ (RC632_CR_PARITY_ENABLE |
+ RC632_CR_PARITY_ODD));
+#else
+ ret = rc632_clear_bits(RC632_REG_CHANNEL_REDUNDANCY,
+ RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE);
+
+#endif
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_transceive(tx_buf, sizeof(tx_buf),
+ (u_int8_t *)atqa, &rx_len,
+ ISO14443A_FDT_ANTICOL_LAST1, 0);
+ if (ret < 0) {
+ DEBUGP("error during rc632_transceive()\n");
+ return ret;
+ }
+
+ /* switch back to normal 8bit last byte */
+ ret = rc632_reg_write(RC632_REG_BIT_FRAMING, 0x00);
+ if (ret < 0)
+ return ret;
+
+ if (rx_len != 2) {
+ DEBUGP("rx_len(%d) != 2\n", rx_len);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* transceive regular frame */
+static int
+rc632_iso14443ab_transceive(struct rfid_asic_handle *handle,
+ unsigned int frametype,
+ const u_int8_t *tx_buf, unsigned int tx_len,
+ u_int8_t *rx_buf, unsigned int *rx_len,
+ u_int64_t timeout, unsigned int flags)
+{
+ int ret;
+ u_int8_t rxl = *rx_len & 0xff;
+ u_int8_t channel_red;
+
+ memset(rx_buf, 0, *rx_len);
+
+ switch (frametype) {
+ case RFID_14443A_FRAME_REGULAR:
+ case RFID_MIFARE_FRAME:
+ channel_red = RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE
+ |RC632_CR_PARITY_ENABLE|RC632_CR_PARITY_ODD;
+ break;
+ case RFID_14443B_FRAME_REGULAR:
+ channel_red = RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE
+ |RC632_CR_CRC3309;
+ break;
+#if 0
+ case RFID_MIFARE_FRAME:
+ channel_red = RC632_CR_PARITY_ENABLE|RC632_CR_PARITY_ODD;
+ break;
+#endif
+ default:
+ return -EINVAL;
+ break;
+ }
+ ret = rc632_reg_write(RC632_REG_CHANNEL_REDUNDANCY,
+ channel_red);
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_transceive(tx_buf, tx_len, rx_buf, &rxl, timeout, 0);
+ *rx_len = rxl;
+ if (ret < 0)
+ return ret;
+
+
+ return 0;
+}
+
+/* transceive anti collission bitframe */
+static int
+rc632_iso14443a_transceive_acf(struct iso14443a_anticol_cmd *acf,
+ unsigned int *bit_of_col)
+{
+ int ret;
+ u_int8_t rx_buf[64];
+ u_int8_t rx_len = sizeof(rx_buf);
+ u_int8_t rx_align = 0, tx_last_bits, tx_bytes;
+ u_int8_t boc;
+ u_int8_t error_flag;
+ *bit_of_col = ISO14443A_BITOFCOL_NONE;
+ memset(rx_buf, 0, sizeof(rx_buf));
+
+ /* disable mifare cryto */
+ ret = rc632_clear_bits(RC632_REG_CONTROL,
+ RC632_CONTROL_CRYPTO1_ON);
+ if (ret < 0)
+ return ret;
+
+ /* disable CRC summing */
+#if 0
+ ret = rc632_reg_write(RC632_REG_CHANNEL_REDUNDANCY,
+ (RC632_CR_PARITY_ENABLE |
+ RC632_CR_PARITY_ODD));
+#else
+ ret = rc632_clear_bits(RC632_REG_CHANNEL_REDUNDANCY,
+ RC632_CR_TX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE);
+#endif
+ if (ret < 0)
+ return ret;
+
+ tx_last_bits = acf->nvb & 0x0f; /* lower nibble indicates bits */
+ tx_bytes = acf->nvb >> 4;
+ if (tx_last_bits) {
+ tx_bytes++;
+ rx_align = (tx_last_bits+1) % 8;/* rx frame complements tx */
+ }
+
+ //rx_align = 8 - tx_last_bits;/* rx frame complements tx */
+
+ /* set RxAlign and TxLastBits*/
+ ret = rc632_reg_write(RC632_REG_BIT_FRAMING,
+ (rx_align << 4) | (tx_last_bits));
+ if (ret < 0)
+ return ret;
+
+ ret = rc632_transceive((u_int8_t *)acf, tx_bytes,
+ rx_buf, &rx_len, 0x32, 0);
+ if (ret < 0)
+ return ret;
+
+ /* bitwise-OR the two halves of the split byte */
+ acf->uid_bits[tx_bytes-2] = (
+ (acf->uid_bits[tx_bytes-2] & (0xff >> (8-tx_last_bits)))
+ | rx_buf[0]);
+ /* copy the rest */
+ memcpy(&acf->uid_bits[tx_bytes+1-2], &rx_buf[1], rx_len-1);
+
+ /* determine whether there was a collission */
+ ret = rc632_reg_read(RC632_REG_ERROR_FLAG, &error_flag);
+ if (ret < 0)
+ return ret;
+
+ if (error_flag & RC632_ERR_FLAG_COL_ERR) {
+ /* retrieve bit of collission */
+ ret = rc632_reg_read(RC632_REG_COLL_POS, &boc);
+ if (ret < 0)
+ return ret;
+
+ /* bit of collission relative to start of part 1 of
+ * anticollision frame (!) */
+ *bit_of_col = 2*8 + boc;
+ }
+
+ return 0;
+}
+
+#if 0
+enum rc632_rate {
+ RC632_RATE_106 = 0x00,
+ RC632_RATE_212 = 0x01,
+ RC632_RATE_424 = 0x02,
+ RC632_RATE_848 = 0x03,
+};
+
+struct rx_config {
+ u_int8_t subc_pulses;
+ u_int8_t rx_coding;
+ u_int8_t rx_threshold;
+ u_int8_t bpsk_dem_ctrl;
+};
+
+struct tx_config {
+ u_int8_t rate;
+ u_int8_t mod_width;
+};
+
+static struct rx_config rx_configs[] = {
+ {
+ .subc_pulses = RC632_RXCTRL1_SUBCP_8,
+ .rx_coding = RC632_DECCTRL_MANCHESTER,
+ .rx_threshold = 0x88,
+ .bpsk_dem_ctrl = 0x00,
+ },
+ {
+ .subc_pulses = RC632_RXCTRL1_SUBCP_4,
+ .rx_coding = RC632_DECCTRL_BPSK,
+ .rx_threshold = 0x50,
+ .bpsk_dem_ctrl = 0x0c,
+ },
+ {
+ .subc_pulses = RC632_RXCTRL1_SUBCP_2,
+ .rx_coding = RC632_DECCTRL_BPSK,
+ .rx_threshold = 0x50,
+ .bpsk_dem_ctrl = 0x0c,
+ },
+ {
+ .subc_pulses = RC632_RXCTRL1_SUBCP_1,
+ .rx_coding = RC632_DECCTRL_BPSK,
+ .rx_threshold = 0x50,
+ .bpsk_dem_ctrl = 0x0c,
+ },
+};
+
+static struct tx_config tx_configs[] = {
+ {
+ .rate = RC632_CDRCTRL_RATE_106K,
+ .mod_width = 0x13,
+ },
+ {
+ .rate = RC632_CDRCTRL_RATE_212K,
+ .mod_width = 0x07,
+ },
+ {
+ .rate = RC632_CDRCTRL_RATE_424K,
+ .mod_width = 0x03,
+ },
+ {
+ .rate = RC632_CDRCTRL_RATE_848K,
+ .mod_width = 0x01,
+ },
+};
+
+static int rc632_iso14443a_set_speed(struct rfid_asic_handle *handle,
+ unsigned int tx,
+ u_int8_t rate)
+{
+ int rc;
+ u_int8_t reg;
+
+
+ if (!tx) {
+ /* Rx */
+ if (rate > ARRAY_SIZE(rx_configs))
+ return -EINVAL;
+
+ rc = rc632_set_bit_mask(RC632_REG_RX_CONTROL1,
+ RC632_RXCTRL1_SUBCP_MASK,
+ rx_configs[rate].subc_pulses);
+ if (rc < 0)
+ return rc;
+
+ rc = rc632_set_bit_mask(RC632_REG_DECODER_CONTROL,
+ RC632_DECCTRL_BPSK,
+ rx_configs[rate].rx_coding);
+ if (rc < 0)
+ return rc;
+
+ rc = rc632_reg_write(RC632_REG_RX_THRESHOLD,
+ rx_configs[rate].rx_threshold);
+ if (rc < 0)
+ return rc;
+
+ if (rx_configs[rate].rx_coding == RC632_DECCTRL_BPSK) {
+ rc = rc632_reg_write(
+ RC632_REG_BPSK_DEM_CONTROL,
+ rx_configs[rate].bpsk_dem_ctrl);
+ if (rc < 0)
+ return rc;
+ }
+ } else {
+ /* Tx */
+ if (rate > ARRAY_SIZE(tx_configs))
+ return -EINVAL;
+
+ rc = rc632_set_bit_mask(RC632_REG_CODER_CONTROL,
+ RC632_CDRCTRL_RATE_MASK,
+ tx_configs[rate].rate);
+ if (rc < 0)
+ return rc;
+
+ rc = rc632_reg_write(RC632_REG_MOD_WIDTH,
+ tx_configs[rate].mod_width);
+ if (rc < 0)
+ return rc;
+ }
+
+ return 0;
+}
+#endif
diff --git a/openpcd/firmware/src/req_ctx.c b/openpcd/firmware/src/req_ctx.c
index 025bf5e..c0731fe 100644
--- a/openpcd/firmware/src/req_ctx.c
+++ b/openpcd/firmware/src/req_ctx.c
@@ -1,23 +1,22 @@
-
#include <unistd.h>
#include <stdlib.h>
-#include <include/types.h>
+#include <sys/types.h>
+#include <asm/bitops.h>
+
#include "openpcd.h"
#include "dbgu.h"
/* FIXME: locking, FIFO order processing */
static struct req_ctx req_ctx[8];
-static u_int8_t req_ctx_busy; /* bitmask of used request contexts */
+static unsigned long req_ctx_busy; /* bitmask of used request contexts */
struct req_ctx *req_ctx_find_get(void)
{
u_int8_t i;
for (i = 0; i < NUM_REQ_CTX; i++) {
- if (!(req_ctx_busy & (1 << i))) {
- req_ctx_busy |= (1 << i);
+ if (test_and_set_bit(i, &req_ctx_busy) == 1)
return &req_ctx[i];
- }
}
return NULL;
@@ -27,11 +26,12 @@ struct req_ctx *req_ctx_find_busy(void)
{
u_int8_t i;
for (i = 0; i < NUM_REQ_CTX; i++) {
- if (req_ctx_busy & (1 << i))
+ if (test_bit(i, &req_ctx_busy))
return &req_ctx[i];
}
-}
+ return NULL;
+}
u_int8_t req_ctx_num(struct req_ctx *ctx)
{
@@ -44,5 +44,6 @@ void req_ctx_put(struct req_ctx *ctx)
if (offset > NUM_REQ_CTX)
DEBUGPCR("Error in offset calculation req_ctx_put");
- req_ctx_busy &= ~(1 << offset);
+ clear_bit(offset, &req_ctx_busy);
+ //req_ctx_busy &= ~(1 << offset);
}
diff --git a/openpcd/firmware/src/trigger.c b/openpcd/firmware/src/trigger.c
new file mode 100644
index 0000000..1768b21
--- /dev/null
+++ b/openpcd/firmware/src/trigger.c
@@ -0,0 +1,14 @@
+#include "openpcd.h"
+#include "trigger.h"
+#include <lib_AT91SAM7.h>
+
+void trigger_init(void)
+{
+ AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_TRIGGER);
+}
+
+void trigger_pulse(void)
+{
+ AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_TRIGGER);
+ AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_TRIGGER);
+}
diff --git a/openpcd/firmware/src/trigger.h b/openpcd/firmware/src/trigger.h
new file mode 100644
index 0000000..597704b
--- /dev/null
+++ b/openpcd/firmware/src/trigger.h
@@ -0,0 +1,7 @@
+#ifndef _TRIGGER_H
+#define _TRIGGER_H
+
+extern void trigger_init(void);
+extern void trigger_pulse(void);
+
+#endif
personal git repositories of Harald Welte. Your mileage may vary