Project

General

Profile

Download (14.7 KB) Statistics
| Branch: | Tag: | Revision:
1 32985a29 laforge
/* AT91SAM7 SSC controller routines for OpenPICC
2 7907a108 (no author)
 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
3
 *
4 32985a29 laforge
 *  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 7907a108 (no author)
 * We use SSC for both TX and RX side.
19
 *
20 f71a643e (no author)
 * RX side is interconnected with demodulated carrier 
21 7907a108 (no author)
 *
22 f71a643e (no author)
 * TX side is interconnected with load modulation circuitry
23 7907a108 (no author)
 */
24
25 28eb4a57 laforge
//#undef DEBUG
26
27 7907a108 (no author)
#include <errno.h>
28 2c41370a (no author)
#include <string.h>
29 7907a108 (no author)
#include <sys/types.h>
30 2c41370a (no author)
#include <AT91SAM7.h>
31 7907a108 (no author)
#include <lib_AT91SAM7.h>
32 81416e6a (no author)
#include <openpcd.h>
33 7907a108 (no author)
34 5bf2bacd (no author)
#include <os/usb_handler.h>
35
#include <os/dbgu.h>
36 28eb4a57 laforge
#include <os/led.h>
37 5bf2bacd (no author)
#include "../openpcd.h"
38 7907a108 (no author)
39 2b28edee laforge
#include <picc/tc_cdiv_sync.h>
40
41 28eb4a57 laforge
//#define DEBUG_SSC_REFILL
42
43 2c41370a (no author)
/* definitions for four-times oversampling */
44
#define REQA	0x10410441
45
#define WUPA	0x04041041
46
47
static const AT91PS_SSC ssc = AT91C_BASE_SSC;
48 7907a108 (no author)
static AT91PS_PDC rx_pdc;
49
50 2c41370a (no author)
enum ssc_mode {
51 5bf2bacd (no author)
	SSC_MODE_NONE,
52 2c41370a (no author)
	SSC_MODE_14443A_SHORT,
53
	SSC_MODE_14443A_STANDARD,
54
	SSC_MODE_14443B,
55 5bf2bacd (no author)
	SSC_MODE_EDGE_ONE_SHOT,
56 28eb4a57 laforge
	SSC_MODE_CONTINUOUS,
57 2c41370a (no author)
};
58
59 7907a108 (no author)
struct ssc_state {
60
	struct req_ctx *rx_ctx[2];
61 2c41370a (no author)
	enum ssc_mode mode;
62 7907a108 (no author)
};
63
static struct ssc_state ssc_state;
64
65 373c172a Harald Welte
static const uint16_t ssc_dmasize[] = {
66 28eb4a57 laforge
	[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 2c41370a (no author)
/* This is for four-times oversampling */
75 28eb4a57 laforge
#define ISO14443A_SOF_SAMPLE	0x01
76 2c41370a (no author)
#define ISO14443A_SOF_LEN	4
77
78 28eb4a57 laforge
#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 f71a643e (no author)
void ssc_rx_mode_set(enum ssc_mode ssc_mode)
93 2c41370a (no author)
{
94 373c172a Harald Welte
	uint8_t data_len, num_data, sync_len;
95
	uint32_t start_cond;
96 2c41370a (no author)
97 28eb4a57 laforge
	/* disable Rx and all Rx interrupt sources */
98
	AT91F_SSC_DisableRx(AT91C_BASE_SSC);
99
	AT91F_SSC_DisableIt(ssc, SSC_RX_IRQ_MASK);
100 2c41370a (no author)
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 28eb4a57 laforge
		num_data = 16;
108 2c41370a (no author)
		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 28eb4a57 laforge
		data_len = 32;
114
		num_data = 16;	/* FIXME */
115 2c41370a (no author)
		break;
116
	case SSC_MODE_14443B:
117
		/* start sampling at first falling data edge */
118
		//start_cond = 
119
		break;
120 5bf2bacd (no author)
	case SSC_MODE_EDGE_ONE_SHOT:
121 28eb4a57 laforge
	case SSC_MODE_CONTINUOUS:
122
		/* unfortunately we don't have RD and RF interconnected
123
		 * (at least not yet in the current hardware) */
124 f71a643e (no author)
		//start_cond = AT91C_SSC_START_EDGE_RF;
125
		start_cond = AT91C_SSC_START_CONTINOUS;
126 6c6b1878 laforge
				//AT91C_SSC_START_RISE_RF;
127 5bf2bacd (no author)
		sync_len = 0;
128 28eb4a57 laforge
		data_len = 32;
129
		num_data = 16;
130
		break;
131
	case SSC_MODE_NONE:
132
		goto out_set_mode;
133 5bf2bacd (no author)
		break;
134 2c41370a (no author)
	}
135 28eb4a57 laforge
	//ssc->SSC_RFMR = AT91C_SSC_MSBF | (data_len-1) & 0x1f |
136 2c41370a (no author)
	ssc->SSC_RFMR = (data_len-1) & 0x1f |
137
			(((num_data-1) & 0x0f) << 8) | 
138
			(((sync_len-1) & 0x0f) << 16);
139 28eb4a57 laforge
	ssc->SSC_RCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE | 
140 6c6b1878 laforge
			(0x2 << 6) | AT91C_SSC_CKI | start_cond;
141 2c41370a (no author)
142 28eb4a57 laforge
	/* Enable Rx DMA */
143 f71a643e (no author)
	AT91F_PDC_EnableRx(rx_pdc);
144 28eb4a57 laforge
145 2c41370a (no author)
	/* Enable RX interrupts */
146 28eb4a57 laforge
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN | AT91C_SSC_CP0 |
147 f71a643e (no author)
			   AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF);
148 28eb4a57 laforge
out_set_mode:
149 2c41370a (no author)
	ssc_state.mode = ssc_mode;
150
}
151
152
static void ssc_tx_mode_set(enum ssc_mode ssc_mode)
153
{
154 373c172a Harald Welte
	uint8_t data_len, num_data, sync_len;
155
	uint32_t start_cond;
156 2c41370a (no author)
157
	/* disable Tx */
158 28eb4a57 laforge
	AT91F_SSC_DisableTx(AT91C_BASE_SSC);
159 2c41370a (no author)
160
	/* disable all Tx related interrupt sources */
161 28eb4a57 laforge
	AT91F_SSC_DisableIt(ssc, SSC_TX_IRQ_MASK);
162 2c41370a (no author)
163
	switch (ssc_mode) {
164
	case SSC_MODE_14443A_SHORT:
165
		start_cond = AT91C_SSC_START_RISE_RF;
166 28eb4a57 laforge
		sync_len = 0;
167 2c41370a (no author)
		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 28eb4a57 laforge
		data_len = 32;
175 2c41370a (no author)
		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 28eb4a57 laforge
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_TXSYN);
184
	AT91F_SSC_EnableTx(AT91C_BASE_SSC);
185 2c41370a (no author)
#if 0
186
	/* Enable RX interrupts */
187
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN |
188 28eb4a57 laforge
			   AT91C_SSC_ENDTX | AT91C_SSC_TXBUFE);
189
	AT91F_PDC_EnableTx(tx_pdc);
190 2c41370a (no author)
191
	ssc_state.mode = ssc_mode;
192
#endif
193
}
194
195
196
197
198 81416e6a (no author)
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 514b0f72 laforge
	memcpy(rctx->data, &opcd_ssc_hdr, sizeof(opcd_ssc_hdr));
205 28eb4a57 laforge
	rctx->tot_len = sizeof(opcd_ssc_hdr);
206 81416e6a (no author)
}
207
208 6c6b1878 laforge
#define DEBUG_SSC_REFILL 1
209 2c41370a (no author)
#ifdef DEBUG_SSC_REFILL
210
#define DEBUGR(x, args ...) DEBUGPCRF(x, ## args)
211
#else
212
#define DEBUGR(x, args ...)
213
#endif
214
215 28eb4a57 laforge
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 2c41370a (no author)
static char dmabuf1[512];
246
static char dmabuf2[512];
247
248 7907a108 (no author)
/* 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 28eb4a57 laforge
	DEBUGR("refill ");
259
#if 1
260 514b0f72 laforge
	rctx = req_ctx_find_get(1, RCTX_STATE_FREE, RCTX_STATE_SSC_RX_BUSY);
261 28eb4a57 laforge
	DEBUGP("SSC_SR=0x%08x ", ssc->SSC_SR);
262 7907a108 (no author)
	if (AT91F_PDC_IsRxEmpty(rx_pdc)) {
263 28eb4a57 laforge
		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 514b0f72 laforge
				(rctx->size-MAX_HDRSIZE)>>2);
268 7907a108 (no author)
		ssc_state.rx_ctx[0] = rctx;
269
270
		/* If primary is empty, secondary must be empty, too */
271 514b0f72 laforge
		rctx = req_ctx_find_get(1, RCTX_STATE_FREE, 
272 7907a108 (no author)
					RCTX_STATE_SSC_RX_BUSY);
273
		if (!rctx) {
274
			DEBUGPCRF("no rctx for secondary refill!");
275
			return -2;
276
		}
277 2c41370a (no author)
		init_opcdhdr(rctx);
278 7907a108 (no author)
	}
279
280
	if (AT91F_PDC_IsNextRxEmpty(rx_pdc)) {
281 28eb4a57 laforge
		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 514b0f72 laforge
				    (rctx->size-MAX_HDRSIZE)>2);
286 7907a108 (no author)
		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 2c41370a (no author)
#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 7907a108 (no author)
}
304 28eb4a57 laforge
#endif
305 7907a108 (no author)
306 2c41370a (no author)
#define ISO14443A_FDT_SHORT_1	1236
307
#define ISO14443A_FDT_SHORT_0	1172
308
309 28eb4a57 laforge
static void __ramfunc ssc_irq(void)
310 7907a108 (no author)
{
311 373c172a Harald Welte
	uint32_t ssc_sr = ssc->SSC_SR;
312 6c6b1878 laforge
	int i, *tmp, emptyframe = 0;
313 f71a643e (no author)
	DEBUGP("ssc_sr=0x%08x, mode=%u: ", ssc_sr, ssc_state.mode);
314 2c41370a (no author)
315 28eb4a57 laforge
	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 6c6b1878 laforge
			ssc_rx_stop();
323 28eb4a57 laforge
		}
324
		//AT91F_SSC_DisableIt(AT91C_BASE_SSC, SSC_RX_IRQ_MASK);
325
#endif
326 6c6b1878 laforge
#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 373c172a Harald Welte
			tmp = (uint32_t*)ssc_state.rx_ctx[0]->data;
331 6c6b1878 laforge
			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 373c172a Harald Welte
			tmp = (uint32_t*)ssc_state.rx_ctx[0]->data + MAX_HDRSIZE;
349 6c6b1878 laforge
			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 28eb4a57 laforge
		//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 6c6b1878 laforge
		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 28eb4a57 laforge
		/* 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 6c6b1878 laforge
	
404 2c41370a (no author)
	if (ssc_sr & AT91C_SSC_OVRUN)
405 28eb4a57 laforge
		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 2c41370a (no author)
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 373c172a Harald Welte
			uint32_t sample = ssc->SSC_RHR;	
421 2c41370a (no author)
			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 f71a643e (no author)
	case SSC_MODE_EDGE_ONE_SHOT:
436 28eb4a57 laforge
		DEBUGP("ONE_SHOT ");
437
		break;
438
	default:
439
		DEBUGP("UNKNOWN_MODE ");
440 2c41370a (no author)
		break;
441 7907a108 (no author)
	}
442 28eb4a57 laforge
443
#endif
444
	DEBUGPCR("I");
445 f71a643e (no author)
	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SSC);
446 7907a108 (no author)
}
447
448 6c6b1878 laforge
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 fda97c65 (no author)
457
void ssc_rx_unthrottle(void)
458
{
459 28eb4a57 laforge
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 |
460 2c41370a (no author)
			   AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN);
461 fda97c65 (no author)
}
462
463 7907a108 (no author)
void ssc_rx_start(void)
464
{
465 6c6b1878 laforge
	volatile int i;
466 28eb4a57 laforge
	//DEBUGPCRF("starting SSC RX\n");	
467 7907a108 (no author)
468
	/* Enable Reception */
469 28eb4a57 laforge
	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 6c6b1878 laforge
	
473 2b28edee laforge
	/* Clear the flipflop */
474
	tc_cdiv_sync_reset();
475 7907a108 (no author)
}
476
477
void ssc_rx_stop(void)
478
{
479
	/* Disable reception */
480 28eb4a57 laforge
	AT91F_SSC_DisableRx(AT91C_BASE_SSC);
481 7907a108 (no author)
}
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 28eb4a57 laforge
			    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 7907a108 (no author)
}
494
495 81416e6a (no author)
static int ssc_usb_in(struct req_ctx *rctx)
496
{
497 514b0f72 laforge
	struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data;
498 81416e6a (no author)
499
	switch (poh->cmd) {
500
	case OPENPCD_CMD_SSC_READ:
501 f71a643e (no author)
		/* FIXME: allow host to specify mode */
502
		ssc_rx_mode_set(SSC_MODE_EDGE_ONE_SHOT);
503
		ssc_rx_start();
504 28eb4a57 laforge
		req_ctx_put(rctx);
505
		return 0;
506 81416e6a (no author)
		break;
507
	case OPENPCD_CMD_SSC_WRITE:
508 f71a643e (no author)
		/* FIXME: implement this */
509
		//ssc_tx_start()
510 81416e6a (no author)
		break;
511 28eb4a57 laforge
	default:
512
		return USB_ERR(USB_ERR_CMD_UNKNOWN);
513
		break;
514 81416e6a (no author)
	}
515
516 28eb4a57 laforge
	return (poh->flags & OPENPCD_FLAG_RESPOND) ? USB_RET_RESPOND : 0;
517 81416e6a (no author)
}
518
519 7907a108 (no author)
void ssc_rx_init(void)
520 28eb4a57 laforge
{ 
521 2b28edee laforge
	tc_cdiv_sync_init();
522
	tc_cdiv_sync_enable();
523
524 7907a108 (no author)
	rx_pdc = (AT91PS_PDC) &(ssc->SSC_RPR);
525
526
	AT91F_SSC_CfgPMC();
527 f71a643e (no author)
528
	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, 
529 6c6b1878 laforge
			    OPENPCD_PIO_MFOUT_SSC_RX | OPENPCD_PIO_SSP_CKIN |
530
			    OPENPICC_PIO_FRAME,
531 f71a643e (no author)
			    0);
532 6c6b1878 laforge
	
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 f71a643e (no author)
536 7907a108 (no author)
	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 514b0f72 laforge
	/* don't divide clock inside SSC, we do that in tc_cdiv */
541 7907a108 (no author)
	ssc->SSC_CMR = 0;
542
543 28eb4a57 laforge
#if 0
544 7907a108 (no author)
	ssc->SSC_RCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE |
545 28eb4a57 laforge
			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 2c41370a (no author)
	ssc->SSC_RFMR = 31 | AT91C_SSC_MSBF | (14 << 8);
549 28eb4a57 laforge
#endif
550 f71a643e (no author)
	
551 28eb4a57 laforge
	__ssc_rx_refill(0);
552
	__ssc_rx_refill(1);
553 f71a643e (no author)
554 28eb4a57 laforge
	ssc_rx_mode_set(SSC_MODE_NONE);
555
#if 0
556 f71a643e (no author)
	AT91F_PDC_EnableRx(rx_pdc);
557 7907a108 (no author)
558
	/* Enable RX interrupts */
559
	AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN |
560
			   AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF);
561 28eb4a57 laforge
#endif
562
	/* FIXME: This is hardcoded for REQA 0x26 */
563
	tc_fdt_set(ISO14443A_FDT_SHORT_0);
564
565 f71a643e (no author)
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SSC);
566 81416e6a (no author)
567 28eb4a57 laforge
	//usb_hdlr_register(&ssc_usb_in, OPENPCD_CMD_CLS_SSC);
568
569
	DEBUGP("\r\n");
570 7907a108 (no author)
}
571
572
void ssc_fini(void)
573
{
574 81416e6a (no author)
	usb_hdlr_unregister(OPENPCD_CMD_CLS_SSC);
575 de8cee9b (no author)
	AT91F_PDC_DisableRx(rx_pdc);
576 7907a108 (no author)
	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
}
Add picture from clipboard (Maximum size: 48.8 MB)