Project

General

Profile

Download (4.13 KB) Statistics
| Branch: | Tag: | Revision:
1
/* ISO14443A Miller decoder for OpenPICC
2
 * (C) 2007 by Henryk Plötz <henryk@ploetzli.ch>
3
 *
4
 *  This program is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by 
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 */
19

    
20
#include <openpicc.h>
21
#include <FreeRTOS.h>
22

    
23
#include <string.h>
24

    
25
#include "iso14443_layer3a.h"
26
#include "usb_print.h"
27
#include "ssc_buffer.h"
28
#include "cmd.h"
29

    
30
#if 0
31
// With debugging
32
#define MILLER_DEBUG_STRING DumpStringToUSB
33
#define MILLER_DEBUG_UINT DumpUIntToUSB 
34
#else
35
// Without debugging
36
#define MILLER_DEBUG_STRING(...) if(0){(void)__VA_ARGS__;}
37
#define MILLER_DEBUG_UINT(...) if(0){(void)__VA_ARGS__;} 
38
#endif
39

    
40
#ifdef FOUR_TIMES_OVERSAMPLING
41
#define OVERSAMPLING_RATE	4
42

    
43
/* definitions for four-times oversampling */
44
#define SEQ_X	0x4
45
#define SEQ_Y	0x0
46
#define SEQ_Z	0x1
47
#else
48
#define OVERSAMPLING_RATE	2
49
#define SEQ_X   0x2
50
#define SEQ_Y   0x0
51
#define SEQ_Z   0x1
52
#endif
53

    
54
enum miller_sequence {
55
	SEQUENCE_X,
56
	SEQUENCE_Y,
57
	SEQUENCE_Z,
58
};
59

    
60
#define BIT_ENDMARKER -1
61

    
62
static const int BITSAMPLE_MASK = ~(~0 << OVERSAMPLING_RATE);
63

    
64
int iso14443a_decode_miller(iso14443_frame *frame, 
65
	const ssc_dma_rx_buffer_t * const buffer)
66
{
67
	u_int32_t i,j;
68
	signed int bit = 0, last_bit = ISO14443A_LAST_BIT_NONE, next_to_last_bit = ISO14443A_LAST_BIT_NONE;
69
	enum miller_sequence current_seq;
70
	unsigned int bitpos = 0;
71
	
72
	memset(frame, 0, sizeof(*frame));
73
	frame->type = TYPE_A;
74
	frame->parameters.a.parity = GIVEN_PARITY;
75
	
76
	u_int32_t sample = 0;
77
	u_int8_t *sample_8=0;
78
	u_int16_t *sample_16=0;
79
	u_int32_t *sample_32=0;
80
	
81
	switch(buffer->reception_mode->transfersize_pdc) {
82
		case 8:  sample_8 =  ((u_int8_t*)buffer->data);  break;
83
		case 16: sample_16 = ((u_int16_t*)buffer->data); break;
84
		case 32: sample_32 = ((u_int32_t*)buffer->data); break;
85
	}
86
	
87
	for(i=0; i<buffer->len_transfers && bit != BIT_ENDMARKER; i++) {
88
		MILLER_DEBUG_STRING(" ");
89
		switch(buffer->reception_mode->transfersize_pdc) {
90
			case 8:  sample = *sample_8++;  break;
91
			case 16: sample = *sample_16++; break;
92
			case 32: sample = *sample_32++; break;
93
		}
94
		MILLER_DEBUG_UINT(sample);
95
		
96
		for(j=0; j<buffer->reception_mode->transfersize_ssc && bit != BIT_ENDMARKER; j+=OVERSAMPLING_RATE) {
97
			MILLER_DEBUG_STRING(".");
98
			int bitsample = (sample>>j) & BITSAMPLE_MASK;
99
			switch(bitsample) {
100
				case SEQ_X: current_seq = SEQUENCE_X; MILLER_DEBUG_STRING("X"); break;
101
				case SEQ_Y: current_seq = SEQUENCE_Y; MILLER_DEBUG_STRING("Y"); break;
102
				case SEQ_Z: current_seq = SEQUENCE_Z; MILLER_DEBUG_STRING("Z"); break;
103
				default: MILLER_DEBUG_UINT(bitsample); current_seq = SEQUENCE_Y;
104
			}
105
			
106
			switch(current_seq) {
107
				case SEQUENCE_X:
108
					bit = 1; break;
109
				case SEQUENCE_Y: /* Fall-through to SEQUENCE_Z */
110
					if(last_bit == 0) {
111
						bit = BIT_ENDMARKER;
112
						MILLER_DEBUG_STRING("!");
113
						break;
114
					}
115
				case SEQUENCE_Z:
116
					bit = 0; break;
117
			}
118
			
119
			switch(bit) {
120
				case BIT_ENDMARKER:
121
					bitpos-=2; /* Subtract this sequence and the previous sequence (which was a 0) */
122
					frame->parameters.a.last_bit = next_to_last_bit;
123
					break;
124
				case 0: /* Fall-through */
125
				case 1: {
126
					int bytepos = bitpos/9;
127
					if(bitpos % 9 == 8) { /* Parity bit */
128
						frame->parity[ bytepos/8 ] |= (bit<<(bytepos%8));
129
					} else {
130
						frame->data[ bytepos ] |= (bit<<(bitpos%9));
131
					}
132
				}
133
			}
134
			
135
			next_to_last_bit = last_bit;
136
			last_bit = bit;
137
			bitpos++;
138
		}
139
	}
140
	
141
	frame->numbytes = bitpos/9;
142
	frame->numbits = bitpos%9;
143
	MILLER_DEBUG_STRING(" ");
144
	MILLER_DEBUG_UINT(frame->numbytes);
145
	MILLER_DEBUG_STRING(" bytes, ");
146
	MILLER_DEBUG_UINT(frame->numbits);
147
	MILLER_DEBUG_STRING(" bits ");
148
	
149
	return 0;
150
}
(29-29/59)
Add picture from clipboard (Maximum size: 48.8 MB)