diff options
author | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2008-02-09 17:49:39 +0000 |
---|---|---|
committer | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2008-02-09 17:49:39 +0000 |
commit | 6be69f0de0c5455758c7ab3a6a3c7d37a061e5fa (patch) | |
tree | 54bc5f77817fd3e0f578ccc1b551363a6a193f70 /openpicc/application/iso14443_layer2a.c | |
parent | f44e839dcc1ce0269c0608d76ee3d6fd222ba778 (diff) |
Commit a first version of an iso 14443 layer 2 and a passive sniffer. Works for short frames, and sometimes even for long frames. Pending some major cleanup
git-svn-id: https://svn.openpcd.org:2342/trunk@408 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpicc/application/iso14443_layer2a.c')
-rw-r--r-- | openpicc/application/iso14443_layer2a.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c new file mode 100644 index 0000000..b91b67c --- /dev/null +++ b/openpicc/application/iso14443_layer2a.c @@ -0,0 +1,172 @@ +/*************************************************************** + * + * OpenPICC - ISO 14443 Layer 2 Type A PICC transceiver code + * Manages receiving, sending and parts of framing + * + * This does not fully implement layer 2 in that it won't + * automatically call the Miller decoder or Manchester encoder + * for you. Instead you'll be given ssc rx buffer pointers and + * are expected to hand in ssc tx buffer pointers. You've got + * to call iso14443a_manchester and iso14443a_miller yourself. + * The reason is that this makes it possible for the layer 3 + * implementation to work on raw samples without en/de-coding + * time to enable fast responses during anticollision. + * + * Copyright 2008 Henryk Plötz <henryk@ploetzli.ch> + * + *************************************************************** + + 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. + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +*/ + +#include <FreeRTOS.h> +#include <board.h> +#include <task.h> +#include <errno.h> + +#include "openpicc.h" +#include "iso14443_layer2a.h" +#include "ssc_picc.h" +#include "pll.h" +#include "tc_fdt.h" +#include "tc_cdiv.h" +#include "tc_cdiv_sync.h" +#include "load_modulation.h" + +static u_int8_t fast_receive; +static volatile u_int8_t receiving = 0; + +#ifdef FOUR_TIMES_OVERSAMPLING +#define RX_DIVIDER 32 +#else +#define RX_DIVIDER 64 +#endif + +int iso14443_receive(iso14443_receive_callback_t callback, ssc_dma_rx_buffer_t **buffer, unsigned int timeout) +{ + int was_receiving = receiving; + (void)callback; + ssc_dma_rx_buffer_t* _buffer = NULL; + int len; + + + if(!was_receiving) { + iso14443_l2a_rx_start(); + } else { + /* + * handled by _iso14443_ssc_irq_ext below + tc_fdt_set(0xff00); + tc_cdiv_set_divider(RX_DIVIDER); + tc_cdiv_sync_reset(); + */ + } + + + if(xQueueReceive(ssc_rx_queue, &_buffer, timeout)) { + if(!was_receiving) { + iso14443_l2a_rx_stop(); + } + + if(_buffer == NULL) { + /* Can this happen? */ + return -ETIMEDOUT; + } + + portENTER_CRITICAL(); + _buffer->state = PROCESSING; + portEXIT_CRITICAL(); + + len = _buffer->len_transfers; + + if(buffer != NULL) *buffer = _buffer; + else { + portENTER_CRITICAL(); + _buffer->state = FREE; + portEXIT_CRITICAL(); + } + + return len; + } + + if(!was_receiving) + iso14443_l2a_rx_stop(); + + return -ETIMEDOUT; +} + +int iso14443_wait_for_carrier(unsigned int timeout) +{ + (void)timeout; + return 0; +} + +int iso14443_l2a_rx_start(void) +{ + receiving = 1; + tc_fdt_set(0xff00); + tc_cdiv_set_divider(RX_DIVIDER); + ssc_rx_start(); + return 0; +} + +int iso14443_l2a_rx_stop(void) +{ + ssc_rx_stop(); + receiving = 0; + return 0; +} + + +u_int8_t iso14443_set_fast_receive(u_int8_t enable_fast_receive) +{ + u_int8_t old_value = fast_receive; + fast_receive = enable_fast_receive; + return old_value; +} + +u_int8_t iso14443_get_fast_receive(void) +{ + return fast_receive; +} + +void _iso14443_ssc_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode, u_int8_t* samples) +{ + (void) ssc_mode; (void) samples; + if( (ssc_sr & AT91C_SSC_CP1) && receiving) { + tc_fdt_set(0xff00); + tc_cdiv_set_divider(RX_DIVIDER); + tc_cdiv_sync_reset(); + } +} + +int iso14443_layer2a_init(u_int8_t enable_fast_receive) +{ + pll_init(); + + tc_cdiv_init(); + tc_fdt_init(); + //ssc_set_irq_extension((ssc_irq_ext_t)iso14443_layer3a_irq_ext); + ssc_rx_init(); + ssc_tx_init(); + + load_mod_init(); + load_mod_level(3); + + ssc_rx_mode_set(SSC_MODE_14443A); + ssc_set_irq_extension(_iso14443_ssc_irq_ext); + + iso14443_set_fast_receive(enable_fast_receive); + return 0; +} |