diff options
author | (no author) <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2006-09-09 01:08:38 +0000 |
---|---|---|
committer | (no author) <(no author)@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2006-09-09 01:08:38 +0000 |
commit | 520784c7ba6a8325e413a293ab11840d982ba87d (patch) | |
tree | 44ee93d44102d47014c6ff696ebc93e8de402e01 /openpcd/firmware/src/picc | |
parent | b0317c72667378333e1008c49559e974f3e7c15d (diff) |
- major reorganization, split source tree in
- os: core "operating system"
- pcd: PCD (reader) side
- picc: PICC (transponder) side
- rewrite linker script almost from scratch (for correct DFU operation)
git-svn-id: https://svn.openpcd.org:2342/trunk@142 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpcd/firmware/src/picc')
-rw-r--r-- | openpcd/firmware/src/picc/load_modulation.c | 31 | ||||
-rw-r--r-- | openpcd/firmware/src/picc/load_modulation.h | 7 | ||||
-rw-r--r-- | openpcd/firmware/src/picc/piccsim.h | 2 | ||||
-rw-r--r-- | openpcd/firmware/src/picc/tc.c | 123 | ||||
-rw-r--r-- | openpcd/firmware/src/picc/tc.h | 28 |
5 files changed, 190 insertions, 1 deletions
diff --git a/openpcd/firmware/src/picc/load_modulation.c b/openpcd/firmware/src/picc/load_modulation.c new file mode 100644 index 0000000..d2af070 --- /dev/null +++ b/openpcd/firmware/src/picc/load_modulation.c @@ -0,0 +1,31 @@ + +#ifdef CONFIG_PICCSIM + +#include <sys/types.h> +#include <lib_AT91SAM7.h> + +#include "../openpcd.h" + +void load_mod_level(u_int8_t level) +{ + if (level > 3) + level = 3; + + if (level & 0x1) + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LOAD1); + else + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LOAD1); + + if (level & 0x2) + AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LOAD2); + else + AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LOAD2); +} + +void load_mod_init(void) +{ + AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LOAD1); + AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LOAD2); +} + +#endif /* CONFIG_PICCSIM */ diff --git a/openpcd/firmware/src/picc/load_modulation.h b/openpcd/firmware/src/picc/load_modulation.h new file mode 100644 index 0000000..71f9d6f --- /dev/null +++ b/openpcd/firmware/src/picc/load_modulation.h @@ -0,0 +1,7 @@ +#ifndef _LOAD_MODULATION_H +#define _LOAD_MODULATION_H + +extern void load_mod_level(u_int8_t level); +extern void load_mod_init(void); + +#endif diff --git a/openpcd/firmware/src/picc/piccsim.h b/openpcd/firmware/src/picc/piccsim.h index 34c7bf0..3cf6514 100644 --- a/openpcd/firmware/src/picc/piccsim.h +++ b/openpcd/firmware/src/picc/piccsim.h @@ -1,5 +1,5 @@ -#include <librfdi/rfid_layer2_iso14443a.h> +#include <librfid/rfid_layer2_iso14443a.h> struct piccsim_state { enum rfid_layer2_id l2prot; diff --git a/openpcd/firmware/src/picc/tc.c b/openpcd/firmware/src/picc/tc.c new file mode 100644 index 0000000..d23afa2 --- /dev/null +++ b/openpcd/firmware/src/picc/tc.c @@ -0,0 +1,123 @@ +/* OpenPC TC (Timer / Clock) support code + * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de> + * + * This idea of this code is to feed the 13.56MHz carrier clock of RC632 + * into TCLK1, which is routed to XC1. Then configure TC0 to divide this + * clock by a configurable divider. + * + * PICC Simulator Side: + * In order to support responding to synchronous frames (REQA/WUPA/ANTICOL), + * we need a second Timer/Counter (TC1). This unit is reset by an external + * event (rising edge of modulation pause PCD->PICC) connected to TIOB2, and + * counts up to a configurable number of carrier clock cycles (RA). Once the + * RA value is reached, TIOA2 will see a rising edge. This rising edge will + * be interconnected to TF (Tx Frame) of the SSC to start transmitting our + * synchronous response. + * + */ + +#include <lib_AT91SAM7.h> +#include <os/dbgu.h> + +#include "../openpcd.h" +#include "tc.h" + +static AT91PS_TCB tcb = AT91C_BASE_TCB; + +/* set carrier divider to a specific */ +void tc_cdiv_set_divider(u_int16_t div) +{ + tcb->TCB_TC0.TC_RC = div; + + /* set to 50% duty cycle */ + tcb->TCB_TC0.TC_RA = 1; + tcb->TCB_TC0.TC_RB = 1 + (div >> 1); +} + +void tc_cdiv_phase_add(int16_t inc) +{ + tcb->TCB_TC0.TC_RA = (tcb->TCB_TC0.TC_RA + inc) % tcb->TCB_TC0.TC_RC; + tcb->TCB_TC0.TC_RB = (tcb->TCB_TC0.TC_RB + inc) % tcb->TCB_TC0.TC_RC; + + /* FIXME: can this be done more elegantly? */ + if (tcb->TCB_TC0.TC_RA == 0) { + tcb->TCB_TC0.TC_RA += 1; + tcb->TCB_TC0.TC_RB += 1; + } +} + +#ifdef CONFIG_PICCSIM +void tc_fdt_set(u_int16_t count) +{ + tcb->TC_TC2.TC_RA = count; +} +#endif + +void tc_cdiv_init(void) +{ + /* Cfg PA28(TCLK1), PA0(TIOA0), PA1(TIOB0), PA20(TCLK2) as Periph B */ + AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, 0, + OPENPCD_PIO_CARRIER_IN | + OPENPCD_PIO_CARRIER_DIV_OUT | + OPENPCD_PIO_CDIV_HELP_OUT | + OPENPCD_PIO_CDIV_HELP_IN); + + AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, + ((unsigned int) 1 << AT91C_ID_TC0)); + + /* Enable Clock for TC0 */ + tcb->TCB_TC0.TC_CCR = AT91C_TC_CLKEN; + + /* Connect TCLK1 to XC1, TCLK2 to XC2 */ + tcb->TCB_BMR &= ~(AT91C_TCB_TC1XC1S | AT91C_TCB_TC2XC2S); + tcb->TCB_BMR |= (AT91C_TCB_TC1XC1S_TCLK1 | AT91C_TCB_TC2XC2S_TCLK2); + + /* Clock XC1, Wave mode, Reset on RC comp + * TIOA0 on RA comp = set, * TIOA0 on RC comp = clear, + * TIOB0 on EEVT = set, TIOB0 on RB comp = clear, + * EEVT = XC2 (TIOA0) */ + tcb->TCB_TC0.TC_CMR = AT91C_TC_CLKS_XC1 | AT91C_TC_WAVE | + AT91C_TC_WAVESEL_UP_AUTO | + AT91C_TC_ACPA_SET | AT91C_TC_ACPC_CLEAR | + AT91C_TC_BEEVT_SET | AT91C_TC_BCPB_CLEAR | + AT91C_TC_EEVT_XC2 | AT91C_TC_ETRGEDG_RISING; + + tc_cdiv_set_divider(128); + +#ifdef CONFIG_PICCSIM + AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, AT91C_PA15_TF, + AT91C_PA26_TIOA2, AT91C_PA17_TIOB2); + AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, + ((unsigned int) 1 << AT91C_ID_TC2)); + /* Clock XC1, Wave Mode, No automatic reset on RC comp + * TIOA2 in RA comp = set, TIOA2 on RC comp = clear, + * TIOB2 as input, EEVT = TIOB2, Reset/Trigger on EEVT */ + tcb->TCB_TC2.TC_CMR = AT91C_TC_CLKS_XC1 | AT91C_TC_WAVE | + AT91C_TC_WAVESEL_UP | + AT91C_TC_ACPA_SET | AT91C_ACPC_CLEAR | + AT91C_TC_BEEVT_NONE | AT91C_TC_BCPB_NONE | + AT91C_TC_EEVT_TIOB | AT91C_TC_ETRGEDG_RISING | + AT91C_TC_ENETRG ; +#endif + + /* Reset to start timers */ + tcb->TCB_BCR = 1; +} + +void tc_cdiv_print(void) +{ + DEBUGP("TCB_BMR=0x%08x ", tcb->TCB_BMR); + DEBUGP("TC0_CV=0x%08x ", tcb->TCB_TC0.TC_CV); + DEBUGP("TC0_CMR=0x%08x ", tcb->TCB_TC0.TC_CMR); + DEBUGPCR("TC0_SR=0x%08x", tcb->TCB_TC0.TC_SR); + + DEBUGPCR("TC0_RA=0x%04x, TC0_RB=0x%04x, TC0_RC=0x%04x", + tcb->TCB_TC0.TC_RA, tcb->TCB_TC0.TC_RB, tcb->TCB_TC0.TC_RC); +} + +void tc_cdiv_fini(void) +{ + tcb->TCB_TC0.TC_CCR = AT91C_TC_CLKDIS; + AT91F_PMC_DisablePeriphClock(AT91C_BASE_PMC, + ((unsigned int) 1 << AT91C_ID_TC0)); +} diff --git a/openpcd/firmware/src/picc/tc.h b/openpcd/firmware/src/picc/tc.h new file mode 100644 index 0000000..e7aa7e4 --- /dev/null +++ b/openpcd/firmware/src/picc/tc.h @@ -0,0 +1,28 @@ +#ifndef _TC_H +#define _TC_H + +#include <sys/types.h> + +extern void tc_cdiv_phase_add(int16_t inc); +extern void tc_cdiv_set_divider(u_int16_t div); + +static inline void tc_cdiv_phase_inc(void) +{ + tc_cdiv_phase_add(1); +} + +static inline void tc_cdiv_phase_dec(void) +{ + tc_cdiv_phase_add(-1); +} + + +extern void tc_cdiv_print(void); +extern void tc_cdiv_init(void); +extern void tc_cdiv_fini(void); + +#ifdef CONFIG_PICCSIM +extern void tc_fdt_set(u_int16_t count); +#endif + +#endif |