Project

General

Profile

Download (14.7 KB) Statistics
| Branch: | Tag: | Revision:
1
/* AT91SAM7 SSC controller routines for OpenPICC
2
 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
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
 * We use SSC for both TX and RX side.
19
 *
20
 * RX side is interconnected with demodulated carrier 
21
 *
22
 * TX side is interconnected with load modulation circuitry
23
 */
24

    
25
//#undef DEBUG
26

    
27
#include <errno.h>
28
#include <string.h>
29
#include <sys/types.h>
30
#include <AT91SAM7.h>
31
#include <lib_AT91SAM7.h>
32
#include <openpcd.h>
33

    
34
#include <os/usb_handler.h>
35
#include <os/dbgu.h>
36
#include <os/led.h>
37
#include "../openpcd.h"
38

    
39
#include <picc/tc_cdiv_sync.h>
40

    
41
//#define DEBUG_SSC_REFILL
42

    
43
/* definitions for four-times oversampling */
44
#define REQA	0x10410441
45
#define WUPA	0x04041041
46

    
47
static const AT91PS_SSC ssc = AT91C_BASE_SSC;
48
static AT91PS_PDC rx_pdc;
49

    
50
enum ssc_mode {
51
	SSC_MODE_NONE,
52
	SSC_MODE_14443A_SHORT,
53
	SSC_MODE_14443A_STANDARD,
54
	SSC_MODE_14443B,
55
	SSC_MODE_EDGE_ONE_SHOT,
56
	SSC_MODE_CONTINUOUS,
57
};
58

    
59
struct ssc_state {
60
	struct req_ctx *rx_ctx[2];
61
	enum ssc_mode mode;
62
};
63
static struct ssc_state ssc_state;
64

    
65
static const uint16_t ssc_dmasize[] = {
66
	[SSC_MODE_NONE]			= 16,
67
	[SSC_MODE_14443A_SHORT]		= 16,	/* 64 bytes */
68
	[SSC_MODE_14443A_STANDARD]	= 16,	/* 64 bytes */
69
	[SSC_MODE_14443B]		= 16,	/* 64 bytes */
70
	[SSC_MODE_EDGE_ONE_SHOT] 	= 16,	/* 64 bytes */
71
	[SSC_MODE_CONTINUOUS]		= 511,	/* 2044 bytes */
72
};
73

    
74
/* This is for four-times oversampling */
75
#define ISO14443A_SOF_SAMPLE	0x01
76
#define ISO14443A_SOF_LEN	4
77

    
78
#define SSC_RX_IRQ_MASK	(AT91C_SSC_RXRDY | 	\
79
			 AT91C_SSC_OVRUN | 	\
80
			 AT91C_SSC_ENDRX |	\
81
			 AT91C_SSC_RXBUFF |	\
82
			 AT91C_SSC_RXSYN |	\
83
			 AT91C_SSC_CP0 |	\
84
			 AT91C_SSC_CP1)
85

    
86
#define SSC_TX_IRQ_MASK (AT91C_SSC_TXRDY |	\
87
			 AT91C_SSC_TXEMPTY | 	\
88
			 AT91C_SSC_ENDTX |	\
89
			 AT91C_SSC_TXBUFE |	\
90
			 AT91C_SSC_TXSYN)
91

    
92
void ssc_rx_mode_set(enum ssc_mode ssc_mode)
93
{
94
	uint8_t data_len, num_data, sync_len;
95
	uint32_t start_cond;
96

    
97
	/* disable Rx and all Rx interrupt sources */
98
	AT91F_SSC_DisableRx(AT91C_BASE_SSC);
99
	AT91F_SSC_DisableIt(ssc, SSC_RX_IRQ_MASK);
100

    
101
	switch (ssc_mode) {
102
	case SSC_MODE_14443A_SHORT:
103
		start_cond = AT91C_SSC_START_0;
104
		sync_len = ISO14443A_SOF_LEN;
105
		ssc->SSC_RC0R = ISO14443A_SOF_SAMPLE;
106
		data_len = 32;
107
		num_data = 16;
108
		break;
109
	case SSC_MODE_14443A_STANDARD:
110
		start_cond = AT91C_SSC_START_0;
111
		sync_len = ISO14443A_SOF_LEN;
112
		ssc->SSC_RC0R = ISO14443A_SOF_SAMPLE;
113
		data_len = 32;
114
		num_data = 16;	/* FIXME */
115
		break;
116
	case SSC_MODE_14443B:
117
		/* start sampling at first falling data edge */
118
		//start_cond = 
119
		break;
120
	case SSC_MODE_EDGE_ONE_SHOT:
121
	case SSC_MODE_CONTINUOUS:
122
		/* unfortunately we don't have RD and RF interconnected
123
		 * (at least not yet in the current hardware) */
124
		//start_cond = AT91C_SSC_START_EDGE_RF;
125
		start_cond = AT91C_SSC_START_CONTINOUS;
126
				//AT91C_SSC_START_RISE_RF;
127
		sync_len = 0;
128
		data_len = 32;
129
		num_data = 16;
130
		break;
131
	case SSC_MODE_NONE:
132
		goto out_set_mode;
133
		break;
134
	}
135
	//ssc->SSC_RFMR = AT91C_SSC_MSBF | (data_len-1) & 0x1f |
136
	ssc->SSC_RFMR = (data_len-1) & 0x1f |
137
			(((num_data-1) & 0x0f) << 8) | 
138
			(((sync_len-1) & 0x0f) << 16);
139
	ssc->SSC_RCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE | 
140
			(0x2 << 6) | AT91C_SSC_CKI | start_cond;
141

    
142
	/* Enable Rx DMA */
143
	AT91F_PDC_EnableRx(rx_pdc);
144

    
145
	/* Enable RX interrupts */
146
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN | AT91C_SSC_CP0 |
147
			   AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF);
148
out_set_mode:
149
	ssc_state.mode = ssc_mode;
150
}
151

    
152
static void ssc_tx_mode_set(enum ssc_mode ssc_mode)
153
{
154
	uint8_t data_len, num_data, sync_len;
155
	uint32_t start_cond;
156

    
157
	/* disable Tx */
158
	AT91F_SSC_DisableTx(AT91C_BASE_SSC);
159

    
160
	/* disable all Tx related interrupt sources */
161
	AT91F_SSC_DisableIt(ssc, SSC_TX_IRQ_MASK);
162

    
163
	switch (ssc_mode) {
164
	case SSC_MODE_14443A_SHORT:
165
		start_cond = AT91C_SSC_START_RISE_RF;
166
		sync_len = 0;
167
		data_len = 32;
168
		num_data = 1;
169
		break;
170
	case SSC_MODE_14443A_STANDARD:
171
		start_cond = AT91C_SSC_START_0;
172
		sync_len = ISO14443A_SOF_LEN;
173
		ssc->SSC_RC0R = ISO14443A_SOF_SAMPLE;
174
		data_len = 32;
175
		num_data = 1;	/* FIXME */
176
		break;
177
	}
178
	ssc->SSC_TFMR = (data_len-1) & 0x1f |
179
			(((num_data-1) & 0x0f) << 8) | 
180
			(((sync_len-1) & 0x0f) << 16);
181
	ssc->SSC_TCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE | start_cond;
182

    
183
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_TXSYN);
184
	AT91F_SSC_EnableTx(AT91C_BASE_SSC);
185
#if 0
186
	/* Enable RX interrupts */
187
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN |
188
			   AT91C_SSC_ENDTX | AT91C_SSC_TXBUFE);
189
	AT91F_PDC_EnableTx(tx_pdc);
190

    
191
	ssc_state.mode = ssc_mode;
192
#endif
193
}
194

    
195

    
196

    
197

    
198
static struct openpcd_hdr opcd_ssc_hdr = {
199
	.cmd	= OPENPCD_CMD_SSC_READ,
200
};
201

    
202
static inline void init_opcdhdr(struct req_ctx *rctx)
203
{
204
	memcpy(rctx->data, &opcd_ssc_hdr, sizeof(opcd_ssc_hdr));
205
	rctx->tot_len = sizeof(opcd_ssc_hdr);
206
}
207

    
208
#define DEBUG_SSC_REFILL 1
209
#ifdef DEBUG_SSC_REFILL
210
#define DEBUGR(x, args ...) DEBUGPCRF(x, ## args)
211
#else
212
#define DEBUGR(x, args ...)
213
#endif
214

    
215
static int __ramfunc __ssc_rx_refill(int secondary)
216
{
217
	struct req_ctx *rctx;
218

    
219
	rctx = req_ctx_find_get(1, RCTX_STATE_FREE, RCTX_STATE_SSC_RX_BUSY);
220
	if (!rctx) {
221
		DEBUGP("no_rctx_for_refill! ");
222
		return -1;
223
	}
224
	init_opcdhdr(rctx);
225
	DEBUGR("filling SSC RX%u dma ctx: %u (len=%u) ", secondary,
226
		req_ctx_num(rctx), rctx->size);
227
	rctx->tot_len = ssc_dmasize[ssc_state.mode]*4 + 
228
			sizeof(struct openpcd_hdr);
229
	if (secondary) {
230
		AT91F_PDC_SetNextRx(rx_pdc, rctx->data+MAX_HDRSIZE,
231
				    ssc_dmasize[ssc_state.mode]);
232
		ssc_state.rx_ctx[1] = rctx;
233
	} else {
234
		AT91F_PDC_SetRx(rx_pdc, rctx->data+MAX_HDRSIZE,
235
				ssc_dmasize[ssc_state.mode]);
236
		ssc_state.rx_ctx[0] = rctx;
237
	}
238

    
239
	tc_cdiv_sync_reset();
240
	
241
	return 0;
242
}
243

    
244
#if 0
245
static char dmabuf1[512];
246
static char dmabuf2[512];
247

    
248
/* Try to refill RX dma descriptors. Return values:
249
 *  0) no dma descriptors empty
250
 *  1) filled next/secondary descriptor
251
 *  2) filled both primary and secondary descriptor
252
 * -1) no free request contexts to use
253
 * -2) only one free request context, but two free descriptors
254
 */
255
static int8_t ssc_rx_refill(void)
256
{
257
	struct req_ctx *rctx;
258
	DEBUGR("refill ");
259
#if 1
260
	rctx = req_ctx_find_get(1, RCTX_STATE_FREE, RCTX_STATE_SSC_RX_BUSY);
261
	DEBUGP("SSC_SR=0x%08x ", ssc->SSC_SR);
262
	if (AT91F_PDC_IsRxEmpty(rx_pdc)) {
263
		DEBUGR("filling primary SSC RX dma ctx: %u (len=%u) ",
264
			req_ctx_num(rctx), rctx->size);
265
		rctx->tot_len = rctx->size;
266
		AT91F_PDC_SetRx(rx_pdc, rctx->data+MAX_HDRSIZE,
267
				(rctx->size-MAX_HDRSIZE)>>2);
268
		ssc_state.rx_ctx[0] = rctx;
269

    
270
		/* If primary is empty, secondary must be empty, too */
271
		rctx = req_ctx_find_get(1, RCTX_STATE_FREE, 
272
					RCTX_STATE_SSC_RX_BUSY);
273
		if (!rctx) {
274
			DEBUGPCRF("no rctx for secondary refill!");
275
			return -2;
276
		}
277
		init_opcdhdr(rctx);
278
	}
279

    
280
	if (AT91F_PDC_IsNextRxEmpty(rx_pdc)) {
281
		DEBUGR("filling secondary SSC RX dma ctx: %u (len=%u) ",
282
			req_ctx_num(rctx), rctx->size);
283
		rctx->tot_len = rctx->size;
284
		AT91F_PDC_SetNextRx(rx_pdc, rctx->data+MAX_HDRSIZE,
285
				    (rctx->size-MAX_HDRSIZE)>2);
286
		ssc_state.rx_ctx[1] = rctx;
287
		return 2;
288
	} else {
289
		/* we were unable to fill*/
290
		DEBUGPCRF("prim/secnd DMA busy, can't refill");
291
		req_ctx_put(rctx);	
292
		return 0;
293
	}
294
#else
295
	if (AT91F_PDC_IsRxEmpty(rx_pdc))
296
		AT91F_PDC_SetRx(rx_pdc, dmabuf1, sizeof(dmabuf1)>>2);
297
	
298
	if (AT91F_PDC_IsNextRxEmpty(rx_pdc))
299
		AT91F_PDC_SetNextRx(rx_pdc, dmabuf2, sizeof(dmabuf2)>>2);
300
	else
301
		DEBUGPCRF("prim/secnd DMA busy, can't refill");
302
#endif
303
}
304
#endif
305

    
306
#define ISO14443A_FDT_SHORT_1	1236
307
#define ISO14443A_FDT_SHORT_0	1172
308

    
309
static void __ramfunc ssc_irq(void)
310
{
311
	uint32_t ssc_sr = ssc->SSC_SR;
312
	int i, *tmp, emptyframe = 0;
313
	DEBUGP("ssc_sr=0x%08x, mode=%u: ", ssc_sr, ssc_state.mode);
314

    
315
	if (ssc_sr & AT91C_SSC_ENDRX) {
316
#if 1
317
		/* in a one-shot sample, we don't want to keep
318
		 * sampling further after having received the first
319
		 * packet.  */
320
		if (ssc_state.mode == SSC_MODE_EDGE_ONE_SHOT) {
321
			DEBUGP("DISABLE_RX ");
322
			ssc_rx_stop();
323
		}
324
		//AT91F_SSC_DisableIt(AT91C_BASE_SSC, SSC_RX_IRQ_MASK);
325
#endif
326
#if 0
327
/* Experimental start SSC on frame, stop on FFFFFFFF */
328
		if (ssc_state.mode == SSC_MODE_CONTINUOUS) {
329
			//ssc->SSC_RCMR = (ssc->SSC_RCMR & ~AT91C_SSC_START) | AT91C_SSC_START_CONTINOUS;
330
			tmp = (uint32_t*)ssc_state.rx_ctx[0]->data;
331
			for(i = ssc_state.rx_ctx[0]->size / 4; i >= 0 ; i--) {
332
				if( *tmp++ == 0xFFFFFFFF ) {
333
					*(tmp-1) = 0xAAAAAAAA; // debug marker
334
					/* No modulation for a long time, stop sampling 
335
					 * and prepare for next frame */
336
					DEBUGP("RESTART RX ");
337
					ssc_rx_stop();
338
					ssc_rx_mode_set(ssc_state.mode);
339
					ssc_rx_start();
340
					led_toggle(1);
341
					break;
342
				}
343
			}
344
		}
345
#endif
346
		/* Ignore empty frames */
347
		if (ssc_state.mode == SSC_MODE_CONTINUOUS) {
348
			tmp = (uint32_t*)ssc_state.rx_ctx[0]->data + MAX_HDRSIZE;
349
			emptyframe = 1;
350
			for(i = (ssc_state.rx_ctx[0]->size-MAX_HDRSIZE) / 4 - 8/*WTF?*/; i > 0; i--) {
351
				if( *tmp++ != 0xFFFFFFFF ) {
352
					DEBUGPCR("NONEMPTY(%08x, %i): %08x", tmp, i, *(tmp-1));
353
					emptyframe = 0;
354
					break;
355
				} else {
356
					//DEBUGPCR("DUNNO(%08x, %i): %08x", tmp, i, tmp[i]);
357
				}
358
			}
359
		}
360
		//DEBUGP("Sending primary RCTX(%u, len=%u) ", req_ctx_num(ssc_state.rx_ctx[0]), ssc_state.rx_ctx[0]->tot_len);
361
		/* Mark primary RCTX as ready to send for usb */
362
		if(!emptyframe) {
363
			DEBUGP("NONEMPTY");
364
			req_ctx_set_state(ssc_state.rx_ctx[0], 
365
					  RCTX_STATE_UDP_EP2_PENDING);
366
					  //RCTX_STATE_FREE);
367
		} else {
368
			DEBUGP("EMPTY");
369
			req_ctx_put(ssc_state.rx_ctx[0]);
370
		}
371

    
372
		/* second buffer gets propagated to primary */
373
		ssc_state.rx_ctx[0] = ssc_state.rx_ctx[1];
374
		ssc_state.rx_ctx[1] = NULL;
375
		if (ssc_sr & AT91C_SSC_RXBUFF) {
376
			DEBUGP("RXBUFF! ");
377
			if (ssc_state.rx_ctx[0]) {
378
				//DEBUGP("Sending secondary RCTX(%u, len=%u) ", req_ctx_num(ssc_state.rx_ctx[0]), ssc_state.rx_ctx[0]->tot_len);
379
				req_ctx_set_state(ssc_state.rx_ctx[0],
380
						  RCTX_STATE_UDP_EP2_PENDING);
381
						  //RCTX_STATE_FREE);
382
			}
383
			if (__ssc_rx_refill(0) == -1)
384
				AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |
385
						    AT91C_SSC_RXBUFF |
386
						    AT91C_SSC_OVRUN);
387
		}
388

    
389
		if (__ssc_rx_refill(1) == -1)
390
			AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |
391
					    AT91C_SSC_RXBUFF |
392
					    AT91C_SSC_OVRUN);
393

    
394
		udp_refill_ep(2);
395

    
396
#if 0
397
			if (__ssc_rx_refill(1) == -1)
398
				AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |
399
						    AT91C_SSC_RXBUFF |
400
						    AT91C_SSC_OVRUN);
401
#endif
402
	}
403
	
404
	if (ssc_sr & AT91C_SSC_OVRUN)
405
		DEBUGP("RX_OVERRUN ");
406

    
407
	if (ssc_sr & AT91C_SSC_CP0)
408
		DEBUGP("CP0 ");
409
	
410
	if (ssc_sr & AT91C_SSC_TXSYN)
411
		DEBUGP("TXSYN ");
412
#if 0
413
	led_toggle(1);
414

    
415
	switch (ssc_state.mode) {
416
	case SSC_MODE_14443A_SHORT:
417
		if (ssc_sr & AT91C_SSC_RXSYN)
418
			DEBUGP("RXSYN ");
419
		if (ssc_sr & AT91C_SSC_RXRDY) {
420
			uint32_t sample = ssc->SSC_RHR;	
421
			DEBUGP("RXRDY=0x%08x ", sample);
422
			/* Try to set FDT compare register ASAP */
423
			if (sample == REQA) {
424
				tc_fdt_set(ISO14443A_FDT_SHORT_0);
425
				/* FIXME: prepare and configure ATQA response */
426
			} else if (sample == WUPA) {
427
				tc_fdt_set(ISO14443A_FDT_SHORT_1);
428
				/* FIXME: prepare and configure ATQA response */
429
			} else 
430
				DEBUGP("<== unknown ");
431
		}	
432
		break;
433

    
434
	case SSC_MODE_14443A_STANDARD:
435
	case SSC_MODE_EDGE_ONE_SHOT:
436
		DEBUGP("ONE_SHOT ");
437
		break;
438
	default:
439
		DEBUGP("UNKNOWN_MODE ");
440
		break;
441
	}
442

    
443
#endif
444
	DEBUGPCR("I");
445
	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SSC);
446
}
447

    
448
void ssc_print(void)
449
{
450
	DEBUGP("PDC_RPR=0x%08x ", rx_pdc->PDC_RPR);
451
	DEBUGP("PDC_RCR=0x%08x ", rx_pdc->PDC_RCR);
452
	DEBUGP("PDC_RNPR=0x%08x ", rx_pdc->PDC_RNPR);
453
	DEBUGP("PDC_RNCR=0x%08x ", rx_pdc->PDC_RNCR);
454
}
455

    
456

    
457
void ssc_rx_unthrottle(void)
458
{
459
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 |
460
			   AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN);
461
}
462

    
463
void ssc_rx_start(void)
464
{
465
	volatile int i;
466
	//DEBUGPCRF("starting SSC RX\n");	
467

    
468
	/* Enable Reception */
469
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 |
470
			   AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN);
471
	AT91F_SSC_EnableRx(AT91C_BASE_SSC);
472
	
473
	/* Clear the flipflop */
474
	tc_cdiv_sync_reset();
475
}
476

    
477
void ssc_rx_stop(void)
478
{
479
	/* Disable reception */
480
	AT91F_SSC_DisableRx(AT91C_BASE_SSC);
481
}
482

    
483
void ssc_tx_init(void)
484
{
485
	/* IMPORTANT: Disable PA23 (PWM0) output, since it is connected to 
486
	 * PA17 !! */
487
	AT91F_PIO_CfgInput(AT91C_BASE_PIOA, OPENPCD_PIO_MFIN_PWM);
488
	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, OPENPCD_PIO_MFIN_SSC_TX | 
489
			    OPENPCD_PIO_MFOUT_SSC_RX | OPENPCD_PIO_SSP_CKIN |
490
			    AT91C_PIO_PA15, 0);
491
	
492
	ssc_tx_mode_set(SSC_MODE_14443A_SHORT);
493
}
494

    
495
static int ssc_usb_in(struct req_ctx *rctx)
496
{
497
	struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data;
498

    
499
	switch (poh->cmd) {
500
	case OPENPCD_CMD_SSC_READ:
501
		/* FIXME: allow host to specify mode */
502
		ssc_rx_mode_set(SSC_MODE_EDGE_ONE_SHOT);
503
		ssc_rx_start();
504
		req_ctx_put(rctx);
505
		return 0;
506
		break;
507
	case OPENPCD_CMD_SSC_WRITE:
508
		/* FIXME: implement this */
509
		//ssc_tx_start()
510
		break;
511
	default:
512
		return USB_ERR(USB_ERR_CMD_UNKNOWN);
513
		break;
514
	}
515

    
516
	return (poh->flags & OPENPCD_FLAG_RESPOND) ? USB_RET_RESPOND : 0;
517
}
518

    
519
void ssc_rx_init(void)
520
{ 
521
	tc_cdiv_sync_init();
522
	tc_cdiv_sync_enable();
523

    
524
	rx_pdc = (AT91PS_PDC) &(ssc->SSC_RPR);
525

    
526
	AT91F_SSC_CfgPMC();
527

    
528
	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, 
529
			    OPENPCD_PIO_MFOUT_SSC_RX | OPENPCD_PIO_SSP_CKIN |
530
			    OPENPICC_PIO_FRAME,
531
			    0);
532
	
533
	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL);
534
	AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL);
535

    
536
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SSC,
537
			      OPENPCD_IRQ_PRIO_SSC,
538
			      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &ssc_irq);
539

    
540
	/* don't divide clock inside SSC, we do that in tc_cdiv */
541
	ssc->SSC_CMR = 0;
542

    
543
#if 0
544
	ssc->SSC_RCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE |
545
			AT91C_SSC_CKI | AT91C_SSC_START_CONTINOUS;
546
	/* Data bits per Data N = 32-1
547
	 * Data words per Frame = 15-1 (=60 byte)*/
548
	ssc->SSC_RFMR = 31 | AT91C_SSC_MSBF | (14 << 8);
549
#endif
550
	
551
	__ssc_rx_refill(0);
552
	__ssc_rx_refill(1);
553

    
554
	ssc_rx_mode_set(SSC_MODE_NONE);
555
#if 0
556
	AT91F_PDC_EnableRx(rx_pdc);
557

    
558
	/* Enable RX interrupts */
559
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN |
560
			   AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF);
561
#endif
562
	/* FIXME: This is hardcoded for REQA 0x26 */
563
	tc_fdt_set(ISO14443A_FDT_SHORT_0);
564

    
565
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SSC);
566

    
567
	//usb_hdlr_register(&ssc_usb_in, OPENPCD_CMD_CLS_SSC);
568

    
569
	DEBUGP("\r\n");
570
}
571

    
572
void ssc_fini(void)
573
{
574
	usb_hdlr_unregister(OPENPCD_CMD_CLS_SSC);
575
	AT91F_PDC_DisableRx(rx_pdc);
576
	AT91F_SSC_DisableTx(ssc);
577
	AT91F_SSC_DisableRx(ssc);
578
	AT91F_SSC_DisableIt(ssc, 0xfff);
579
	AT91F_PMC_DisablePeriphClock(AT91C_BASE_PMC, 
580
				 ((unsigned int) 1 << AT91C_ID_SSC));
581
}
(19-19/26)
Add picture from clipboard (Maximum size: 48.8 MB)