Project

General

Profile

Download (12.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/***************************************************************
2
 *
3
 * OpenPICC - ISO 14443 Layer 3 Type A state machine
4
 * Handles initialization and anticollision
5
 *
6
 * Copyright 2007 Henryk Plötz <henryk@ploetzli.ch>
7
 *
8
 ***************************************************************
9

    
10
    This program is free software; you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation; version 2.
13

    
14
    This program is distributed in the hope that it will be useful,
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
    GNU General Public License for more details.
18

    
19
    You should have received a copy of the GNU General Public License along
20
    with this program; if not, write to the Free Software Foundation, Inc.,
21
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22

    
23
*/
24

    
25
#include <FreeRTOS.h>
26
#include <board.h>
27
#include <task.h>
28

    
29
#include "openpicc.h"
30
#include "iso14443_layer3a.h"
31
#include "ssc_picc.h"
32
#include "pll.h"
33
#include "tc_fdt.h"
34
#include "tc_cdiv.h"
35
#include "tc_cdiv_sync.h"
36
#include "usb_print.h"
37
#include "cmd.h"
38
#include "load_modulation.h"
39
#include "decoder.h"
40
#include "iso14443a_manchester.h"
41
#include "iso14443a_miller.h"
42
#include "led.h"
43

    
44
static enum ISO14443_STATES state = STARTING_UP;
45
const iso14443_frame ATQA_FRAME = {
46
	TYPE_A,
47
	{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE}},
48
	2,
49
	0, 0,
50
	{4, 0},
51
	{}
52
};
53

    
54
const iso14443_frame NULL_FRAME = {
55
	TYPE_A,
56
	{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE}},
57
	4, 
58
	0, 0,
59
	//{0xF3, 0xFB, 0xAE, 0xED},
60
	{0xFF, 0xFF, 0xFF, 0xFF},
61
	//{0, 0, 0, 0},
62
	{}
63
};
64

    
65
const u_int8_t ISO14443A_SHORT_FRAME_REQA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH] = _ISO14443A_SHORT_FRAME_REQA;
66
const u_int8_t ISO14443A_SHORT_FRAME_WUPA[ISO14443A_SHORT_FRAME_COMPARE_LENGTH] = _ISO14443A_SHORT_FRAME_WUPA;
67

    
68
#define PLL_LOCK_HYSTERESIS portTICK_RATE_MS*5
69

    
70
#define LAYER3_DEBUG usb_print_string
71

    
72
#define INITIAL_STATE IDLE
73
//#define INITIAL_STATE ACTIVE
74

    
75
#if INITIAL_STATE == IDLE
76
#define INITIAL_FRAME ATQA_FRAME
77
#else
78
#define INITIAL_FRAME NULL_FRAME
79
#endif
80

    
81
#if 1
82
#define SHORT_MODE SSC_MODE_14443A_SHORT
83
#define STANDARD_MODE SSC_MODE_14443A_STANDARD
84
#else
85
#define SHORT_MODE SSC_MODE_14443A
86
#define STANDARD_MODE SSC_MODE_14443A
87
#endif
88

    
89
#define ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 -1
90
#define ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1 -2
91

    
92
/* Transmit a frame in ISO14443A mode from buffer buf at fdt carrier cycles
93
 * after the end of the last modulation pause from the PCD with a clock divisor
94
 * of div. Set fdt to ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 or _1 to have the 
95
 * transmission start at the next possible interval. Use _0 when the last bit
96
 * from the PCD was a 0 and _1 when it was a 1. */ 
97
void iso14443_transmit(ssc_dma_tx_buffer_t *buf, int fdt, int div)
98
{
99
	tc_cdiv_set_divider(div);
100
	if(fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0) {
101
		fdt = tc_fdt_get_next_slot(ISO14443A_FDT_SHORT_0, ISO14443A_FDT_SLOTLEN);
102
	} else if (fdt == ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1) {
103
		fdt = tc_fdt_get_next_slot(ISO14443A_FDT_SHORT_1, ISO14443A_FDT_SLOTLEN);
104
	}
105
	if(0) {
106
		ssc_tx_fiq_fdt_cdiv = fdt -3*div -1;
107
		tc_fdt_set(ssc_tx_fiq_fdt_cdiv -MAX_TF_FIQ_ENTRY_DELAY -MAX_TF_FIQ_OVERHEAD);
108
		ssc_tx_fiq_fdt_ssc  = fdt -div +1;
109
		*AT91C_TC0_CCR = AT91C_TC_CLKDIS;
110
	} else {
111
		tc_fdt_set(fdt);
112
	}
113
	ssc_tx_start(buf);
114
}
115

    
116
static void _is_reqa_or_wupa(enum ssc_mode ssc_mode, u_int8_t* samples, int *is_reqa, int *is_wupa)
117
{
118
	if(ssc_mode == SSC_MODE_14443A_SHORT) {
119
		*is_reqa = *is_wupa = 0;
120
		ISO14443A_SHORT_TYPE sample =  *(ISO14443A_SHORT_TYPE*)samples;
121
		if(sample == REQA) {
122
			*is_reqa = 1;
123
		} else if(sample == WUPA) {
124
			*is_wupa = 1;
125
		}
126
	} else if(ssc_mode == SSC_MODE_14443A) {
127
		int i;
128
		*is_reqa = *is_wupa = 1;
129
		for(i=0; i<ISO14443A_SHORT_FRAME_COMPARE_LENGTH; i++) {
130
			if(samples[i] !=  ISO14443A_SHORT_FRAME_REQA[i]) is_reqa = 0;
131
			if(samples[i] !=  ISO14443A_SHORT_FRAME_WUPA[i]) is_wupa = 0;
132
		}
133
	} else {
134
		*is_reqa = *is_wupa = 0;
135
	}
136
}
137

    
138
static int atqa_sent = 0;
139
/* Running in ISR mode */
140
void __ramfunc iso14443_layer3a_irq_ext(u_int32_t ssc_sr, enum ssc_mode ssc_mode, u_int8_t* samples)
141
{
142
	(void)ssc_sr;
143
	int fdt;
144
	if((ssc_mode == SSC_MODE_14443A_SHORT || ssc_mode == SSC_MODE_14443A) && samples) {
145
		int is_reqa, is_wupa;
146
		_is_reqa_or_wupa(ssc_mode, samples, &is_reqa, &is_wupa);
147
		portBASE_TYPE send_atqa = is_reqa || is_wupa; 
148
		
149
		if(is_reqa) {
150
			fdt = ISO14443A_FDT_SHORT_0;
151
			if(state == IDLE)
152
				send_atqa = 1;
153
		} else if(is_wupa) {
154
			fdt = ISO14443A_FDT_SHORT_1;
155
			if(state == IDLE || state == HALT)
156
				send_atqa = 1;
157
		}
158
		
159
		if(send_atqa) {
160
		vLedSetGreen(0);
161
			if(ssc_tx_buffer.state == SSC_PREFILLED && ssc_tx_buffer.source == &ATQA_FRAME) {
162
				ssc_tx_buffer.state = SSC_PROCESSING;
163
				vLedSetGreen(1);
164
				iso14443_transmit(&ssc_tx_buffer, fdt, 8);
165
				atqa_sent = 1;
166
				vLedSetGreen(0);
167
			}
168
		vLedSetGreen(1);
169
		}
170
		vLedSetGreen(0);
171
	}
172
}
173

    
174
#define FALSE (0!=0)
175
static int prefill_buffer(ssc_dma_tx_buffer_t *dest, const iso14443_frame *src) {
176
	portENTER_CRITICAL();
177
	if(dest->state == SSC_FREE) {
178
		dest->state = SSC_PROCESSING;
179
		portEXIT_CRITICAL();
180
		dest->source = (void*)src;
181
		dest->len = sizeof(ssc_tx_buffer.data);
182
		int ret = manchester_encode(dest->data,
183
				dest->len,
184
				src);
185
		if(ret>0) {
186
			dest->len = ret;
187
			portENTER_CRITICAL();
188
			dest->state = SSC_PREFILLED;
189
			portEXIT_CRITICAL();
190
		} else {
191
			portENTER_CRITICAL();
192
			dest->state = SSC_FREE;
193
			portEXIT_CRITICAL();
194
		}
195
		return ret > 0;
196
	} else if(dest->state == SSC_PREFILLED) {
197
		portEXIT_CRITICAL();
198
		return dest->source == src;
199
	} else {
200
		portEXIT_CRITICAL();
201
		return FALSE;
202
	}
203
	
204
}
205

    
206
static iso14443_frame received_frame;
207

    
208
static void enable_reception(enum ssc_mode mode) {
209
	tc_fdt_set(0xff00);
210
	ssc_rx_mode_set(mode);
211
#ifdef FOUR_TIMES_OVERSAMPLING
212
	tc_cdiv_set_divider(32);
213
#else
214
	tc_cdiv_set_divider(64);
215
#endif
216
	ssc_rx_start();
217
}
218

    
219
extern void main_help_print_buffer(ssc_dma_rx_buffer_t *buffer, int *pktcount);
220
void iso14443_layer3a_state_machine (void *pvParameters)
221
{
222
	unsigned long int last_pll_lock_change = 0;
223
	int pktcount=0, locked, last_was_locked=0;
224
	(void)pvParameters;
225
	while(1) {
226
		ssc_dma_rx_buffer_t* buffer = NULL;
227
		portBASE_TYPE need_receive = 0, switch_on = 0;
228
		
229
		if(ssc_get_metric(SSC_ERRORS) > 0 && state != ERROR) {
230
			LAYER3_DEBUG("SSC overflow error, please debug\n\r");
231
			state = ERROR;
232
		}
233
		
234
		/* First let's see whether there is a reader */
235
		locked = pll_is_locked();
236
		unsigned long int now = xTaskGetTickCount();
237
		switch(state) {
238
			case STARTING_UP: /* Fall through */
239
			case ERROR:
240
				// do nothing here
241
				break;
242
			case POWERED_OFF:
243
				if(locked && now - last_pll_lock_change > PLL_LOCK_HYSTERESIS) { 
244
					/* Go to idle when in POWERED_OFF and pll 
245
					 * was locked for at least 
246
					 * PLL_LOCK_HYSTERESIS ticks */
247
					switch_on = 1;
248
					LAYER3_DEBUG("PLL locked, switching on \n\r");
249
				}
250
				break;
251
			default:
252
				if(!locked && now - last_pll_lock_change > PLL_LOCK_HYSTERESIS) {
253
					/* Power off when not powered off and pll
254
					 * was unlocked for at least  PLL_LOCK_HYSTERESIS
255
					 * ticks */
256
					state = POWERED_OFF;
257
					ssc_rx_stop();
258
					LAYER3_DEBUG("PLL lost lock, switching off \n\r");
259
					continue;
260
				} 
261
				break;
262
		}
263
		if( (!locked && last_was_locked) || (locked && !last_was_locked) ) 
264
			last_pll_lock_change = now;
265
		last_was_locked = locked;
266
		
267
		switch(state) {
268
			case STARTING_UP:
269
				pll_init();
270
			    
271
				tc_cdiv_init();
272
				tc_fdt_init();
273
				ssc_set_irq_extension((ssc_irq_ext_t)iso14443_layer3a_irq_ext);
274
				ssc_rx_init();
275
				ssc_tx_init();
276
				
277
				load_mod_init();
278
				load_mod_level(3);
279
				
280
				
281
				state = POWERED_OFF;
282
				last_was_locked = 0;
283
				vTaskDelay(200*portTICK_RATE_MS);
284
				break;
285
			case POWERED_OFF:
286
				if(switch_on == 1) {
287
					if(prefill_buffer(&ssc_tx_buffer, &INITIAL_FRAME)) {
288
						LAYER3_DEBUG("Buffer prefilled\n\r");
289
						DumpUIntToUSB(ssc_tx_buffer.state);
290
						DumpStringToUSB(" ");
291
						DumpUIntToUSB((unsigned int)ssc_tx_buffer.source);
292
						DumpStringToUSB(" ");
293
						DumpUIntToUSB((unsigned int)&INITIAL_FRAME);
294
						DumpStringToUSB(" ");
295
                                                DumpUIntToUSB(ssc_tx_buffer.len);
296
                                                DumpStringToUSB(" ");
297
                                                DumpBufferToUSB((char*)ssc_tx_buffer.data, ssc_tx_buffer.len);
298
						DumpStringToUSB("\n\r");
299
						state=INITIAL_STATE;
300
						if(INITIAL_STATE == IDLE)
301
							enable_reception(SHORT_MODE);
302
						else if(INITIAL_STATE == ACTIVE)
303
							enable_reception(STANDARD_MODE);
304
						else enable_reception(SSC_MODE_NONE);
305
					} else {
306
						LAYER3_DEBUG("SSC TX overflow error, please debug");
307
						state=ERROR;
308
					}
309
					continue;
310
				}
311
				break;
312
			case IDLE:
313
			case HALT:
314
				/* Wait for REQA or WUPA (HALT: only WUPA) */
315
				need_receive = 1;
316
			case ACTIVE:
317
			case ACTIVE_STAR:
318
				need_receive = 1;
319
			default:
320
				break;
321
		}
322
		
323
		if(need_receive) {
324
			if(xQueueReceive(ssc_rx_queue, &buffer, portTICK_RATE_MS) && buffer != NULL) {
325
				vLedSetGreen(0);
326
				vLedBlinkGreen();
327
				portENTER_CRITICAL();
328
				buffer->state = SSC_PROCESSING;
329
				portEXIT_CRITICAL();
330
				u_int32_t first_sample = *(u_int32_t*)buffer->data;
331
				
332
				if(0) {
333
					DumpStringToUSB("Frame: ");
334
					DumpUIntToUSB(first_sample);
335
					DumpStringToUSB(" ");
336
					main_help_print_buffer(buffer, &pktcount);
337
				}
338
				vLedBlinkGreen();
339
				if(1) {
340
					int i = usb_print_set_default_flush(0);
341
					DumpStringToUSB("[");
342
					DumpUIntToUSB((unsigned int)buffer);
343
					DumpStringToUSB(":");
344
					DumpUIntToUSB(buffer->len_transfers);
345
					DumpStringToUSB(" ");
346
					DumpUIntToUSB((unsigned int)buffer->data);
347
					DumpStringToUSB("] ");
348
					DumpBufferToUSB((char*)buffer->data, (buffer->len_transfers * buffer->reception_mode->transfersize_pdc)/8);
349
					DumpStringToUSB(" Decoded: ");
350
					vLedBlinkGreen();
351
					vLedSetGreen(1);
352
					iso14443a_decode_miller(&received_frame, buffer);
353
					vLedBlinkGreen();
354
					vLedSetGreen(0);
355
					DumpBufferToUSB((char*)received_frame.data, received_frame.numbytes + (received_frame.numbits+7)/8);
356
					DumpStringToUSB(" ");
357
					DumpUIntToUSB(received_frame.parameters.a.last_bit);
358
					DumpStringToUSB("\n\r");
359
					usb_print_set_default_flush(i);
360
				}
361
				
362
				int is_reqa=0, is_wupa=0;
363
				switch(state) {
364
					case IDLE:
365
					case HALT:
366
						if(buffer->data) _is_reqa_or_wupa(buffer->reception_mode->mode, buffer->data, &is_reqa, &is_wupa);
367
						
368
						if(is_wupa || (state==IDLE && is_reqa)) {
369
							/* Need to transmit ATQA */
370
							LAYER3_DEBUG("Received ");
371
							LAYER3_DEBUG(is_wupa ? "WUPA" : "REQA");
372
							if(atqa_sent) {
373
								LAYER3_DEBUG(", woke up to send ATQA\n\r");
374
								atqa_sent = 0;
375
							}
376
							/* For debugging, wait 1ms, then wait for another frame 
377
							 * Normally we'd go to anticol from here*/
378
							vTaskDelay(portTICK_RATE_MS);
379
							if(prefill_buffer(&ssc_tx_buffer, &ATQA_FRAME)) {
380
								enable_reception(SHORT_MODE);
381
							}
382
						} else {
383
							/* Wait for another frame */
384
							enable_reception(SHORT_MODE);
385
						}
386
						break;
387
					case ACTIVE:
388
					case ACTIVE_STAR:
389
							/* Wait for another frame */
390
							if(0) {
391
								ssc_rx_mode_set(STANDARD_MODE);
392
								ssc_rx_start();
393
							} else {
394
								//vTaskDelay(portTICK_RATE_MS);
395
								if(ssc_tx_buffer.source == &ATQA_FRAME) ssc_tx_buffer.state = SSC_FREE;
396
								if(prefill_buffer(&ssc_tx_buffer, &NULL_FRAME)) {
397
									usb_print_string_f("Sending response ...",0);
398
									ssc_tx_buffer.state = SSC_PROCESSING;
399
									iso14443_transmit(&ssc_tx_buffer,
400
										received_frame.parameters.a.last_bit==ISO14443A_LAST_BIT_0 ?
401
										ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_0 :
402
										ISO14443A_TRANSMIT_AT_NEXT_INTERVAL_1, 
403
									8);
404
									while( ssc_tx_buffer.state != SSC_FREE ) {
405
										vTaskDelay(portTICK_RATE_MS);
406
									}
407
									usb_print_string("done\n\r");
408
									usb_print_flush();
409
								}
410
							/* Wait for another frame */
411
							enable_reception(STANDARD_MODE);
412
							}
413
					default:
414
						break;
415
				}
416
				
417
				portENTER_CRITICAL();
418
				buffer->state = SSC_FREE;
419
				portEXIT_CRITICAL();
420
			}
421
		} else vTaskDelay(portTICK_RATE_MS);
422
	}
423
}
(21-21/59)
Add picture from clipboard (Maximum size: 48.8 MB)