Project

General

Profile

Download (15.8 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Philips CL RC632 driver (via SPI) for OpenPCD firmware
2
 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
3
 *
4
 * This is heavily based on the librfid RC632 driver. All primitive access
5
 * functions such as rc632_{reg,fifo}_{read,write}() are API compatible to
6
 * librfid in order to be able to leverage higher-level code from librfid
7
 * to this OpenPCD firmware.
8
 *
9
 * AT91SAM7 PWM routines for OpenPCD / OpenPICC
10
 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
11
 *
12
 *  This program is free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by 
14
 *  the Free Software Foundation; either version 2 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  This program is distributed in the hope that it will be useful,
18
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 *  GNU General Public License for more details.
21
 *
22
 *  You should have received a copy of the GNU General Public License
23
 *  along with this program; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 *
26
 */
27

    
28
#include <string.h>
29
#include <errno.h>
30
#include <lib_AT91SAM7.h>
31
#include <cl_rc632.h>
32
#include <openpcd.h>
33
#include "../openpcd.h"
34
#include <os/fifo.h>
35
#include <os/dbgu.h>
36
#include <os/pcd_enumerate.h>
37
#include <os/usb_handler.h>
38
#include <os/req_ctx.h>
39
#include "rc632.h"
40

    
41
#include <librfid/rfid_asic.h>
42

    
43
#define NOTHING  do {} while(0)
44

    
45
#if 0
46
#define DEBUGPSPI DEBUGP
47
#define DEBUGPSPIIRQ DEBUGP
48
#else
49
#define	DEBUGPSPI(x, args ...)  NOTHING
50
#define DEBUGPSPIIRQ(x, args...) NOTHING
51
#endif
52

    
53
#if 0
54
#define DEBUG632 DEBUGPCRF
55
#else
56
#define DEBUG632(x, args ...)	NOTHING
57
#endif
58

    
59

    
60
/* SPI driver */
61

    
62
#ifdef OLIMEX
63
#define SPI_DEBUG_LOOPBACK
64
#endif
65

    
66
#define SPI_USES_DMA
67

    
68
#define SPI_MAX_XFER_LEN	65
69

    
70
static const AT91PS_SPI pSPI = AT91C_BASE_SPI;
71

    
72
/* SPI irq handler */
73
static void spi_irq(void)
74
{
75
	uint32_t status = pSPI->SPI_SR;
76

    
77
	DEBUGPSPIIRQ("spi_irq: 0x%08x ", status);
78

    
79
	if (status & AT91C_SPI_OVRES)
80
		DEBUGPSPIIRQ("Overrun ");
81
	if (status & AT91C_SPI_MODF)
82
		DEBUGPSPIIRQ("ModeFault ");
83
	if (status & AT91C_SPI_ENDRX) {
84
		pSPI->SPI_IDR = AT91C_SPI_ENDRX;
85
		DEBUGPSPIIRQ("ENDRX ");
86
	}
87
	if (status & AT91C_SPI_ENDTX) {
88
		pSPI->SPI_IDR = AT91C_SPI_ENDTX;
89
		DEBUGPSPIIRQ("ENDTX ");
90
	}
91

    
92
	DEBUGPSPIIRQ("\r\n");
93

    
94
	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SPI);
95
}
96

    
97
#ifdef SPI_USES_DMA
98
static int spi_transceive(const uint8_t *tx_data, uint16_t tx_len, 
99
			  uint8_t *rx_data, uint16_t *rx_len)
100
{
101
	DEBUGPSPI("DMA Xfer tx=%s\r\n", hexdump(tx_data, tx_len));
102
	if (*rx_len < tx_len) {
103
		DEBUGPCRF("rx_len=%u smaller tx_len=%u\n", *rx_len, tx_len);
104
		return -1;
105
	}
106

    
107
	/* disable RC632 interrupt because it wants to do SPI transactions */
108
	AT91F_AIC_DisableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
109

    
110
	AT91F_SPI_ReceiveFrame(pSPI, rx_data, tx_len, NULL, 0);
111
	AT91F_SPI_SendFrame(pSPI, tx_data, tx_len, NULL, 0);
112

    
113
	AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI);
114
	AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI);
115

    
116
	pSPI->SPI_IER = AT91C_SPI_ENDTX|AT91C_SPI_ENDRX;
117

    
118

    
119
	while (! (pSPI->SPI_SR & AT91C_SPI_ENDRX)) ;
120

    
121
	/* Re-enable RC632 interrupts */
122
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
123

    
124
	DEBUGPSPI("DMA Xfer finished rx=%s\r\n", hexdump(rx_data, tx_len));
125

    
126
	*rx_len = tx_len;
127

    
128
	return 0;
129
}
130
#else
131
/* stupid polling transceiver routine */
132
static int spi_transceive(const uint8_t *tx_data, uint16_t tx_len, 
133
		   uint8_t *rx_data, uint16_t *rx_len)
134
{
135
	uint16_t tx_cur = 0;
136
	uint16_t rx_len_max = 0;
137
	uint16_t rx_cnt = 0;
138

    
139
	/* disable RC632 interrupt because it wants to do SPI transactions */
140
	AT91F_AIC_DisableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
141

    
142
	DEBUGPSPI("spi_transceive: enter(tx_len=%u) ", tx_len);
143

    
144
	if (rx_len) {
145
		rx_len_max = *rx_len;
146
		*rx_len = 0;
147
	}
148

    
149
	//AT91F_SPI_Enable(pSPI);
150
	while (1) { 
151
		uint32_t sr = pSPI->SPI_SR;
152
		uint8_t tmp;
153
		if (sr & AT91C_SPI_RDRF) {
154
			tmp = pSPI->SPI_RDR;
155
			rx_cnt++;
156
			if (rx_len && *rx_len < rx_len_max)
157
				rx_data[(*rx_len)++] = tmp;
158
		}
159
	 	if (sr & AT91C_SPI_TDRE) {
160
			if (tx_len > tx_cur)
161
				pSPI->SPI_TDR = tx_data[tx_cur++];
162
		}
163
		if (tx_cur >= tx_len && rx_cnt >= tx_len)
164
			break;
165
	}
166
	//AT91F_SPI_Disable(pSPI);
167
	if (rx_data)
168
		DEBUGPSPI("leave(%02x %02x)\r\n", rx_data[0], rx_data[1]);
169
	else
170
		DEBUGPSPI("leave()\r\n");
171

    
172
	/* Re-enable RC632 interrupts */
173
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
174

    
175
	return 0;
176
}
177
#endif
178

    
179
/* RC632 driver */
180

    
181
/* static buffers used by RC632 access primitives below. 
182
 * Since we only have one */
183

    
184
static uint8_t spi_outbuf[SPI_MAX_XFER_LEN];
185
static uint8_t spi_inbuf[SPI_MAX_XFER_LEN];
186

    
187
#define FIFO_ADDR (RC632_REG_FIFO_DATA << 1)
188

    
189
#define RC632_WRITE_ADDR(x)	((x << 1) & 0x7e)
190

    
191
/* RC632 access primitives */
192

    
193
int opcd_rc632_reg_write(struct rfid_asic_handle *hdl,
194
			 uint8_t addr, uint8_t data)
195
{
196
	uint16_t rx_len = 2;
197

    
198
	DEBUG632("[0x%02x] <= 0x%02x", addr, data);
199

    
200
	addr = RC632_WRITE_ADDR(addr);
201

    
202
	spi_outbuf[0] = addr;
203
	spi_outbuf[1] = data;
204

    
205
	return spi_transceive(spi_outbuf, 2, spi_inbuf, &rx_len);
206
}
207

    
208
#define RC632_REGSET_START	0x10
209
#define RC632_REGSET_END	0x3f
210
#define RC632_REGSET_MAXSIZE	(RC632_REGSET_END-RC632_REGSET_START)
211
static uint8_t regset_buf[RC632_REGSET_MAXSIZE * 2];
212

    
213
int opcd_rc632_reg_write_set(struct rfid_asic_handle *hdl,
214
			     uint8_t *regs, int len)
215
{
216
	uint8_t i, j = 0;
217
	uint16_t rx_len;
218

    
219
	if (len > RC632_REGSET_MAXSIZE)
220
		return -E2BIG;
221
	
222
	for (i = RC632_REGSET_START; i <= RC632_REGSET_END; i++) {
223
		/* skip bank registers */
224
		if (i % 8 == 0)
225
			continue;
226
		regset_buf[j++] = RC632_WRITE_ADDR(i);
227
		regset_buf[j++] = regs[i - RC632_REGSET_START];
228
	}
229
	
230
	rx_len = j;
231
	return spi_transceive(regset_buf, j, spi_inbuf, &rx_len);
232
}
233

    
234
int opcd_rc632_fifo_write(struct rfid_asic_handle *hdl,
235
			  uint8_t len, uint8_t *data, uint8_t flags)
236
{
237
	uint16_t rx_len = sizeof(spi_inbuf);
238
	if (len > sizeof(spi_outbuf)-1)
239
		len = sizeof(spi_outbuf)-1;
240

    
241
	spi_outbuf[0] = FIFO_ADDR;
242
	memcpy(&spi_outbuf[1], data, len);
243

    
244
	DEBUG632("[FIFO] <= %s", hexdump(data, len));
245

    
246
	return spi_transceive(spi_outbuf, len+1, spi_inbuf, &rx_len);
247
}
248

    
249
int opcd_rc632_reg_read(struct rfid_asic_handle *hdl, 
250
			uint8_t addr, uint8_t *val)
251
{
252
	uint16_t rx_len = 2;
253

    
254
	addr = (addr << 1) & 0x7e;
255

    
256
	spi_outbuf[0] = addr | 0x80;
257
	spi_outbuf[1] = 0x00;
258

    
259
	spi_transceive(spi_outbuf, 2, spi_inbuf, &rx_len);
260
	*val = spi_inbuf[1];
261

    
262
	DEBUG632("[0x%02x] => 0x%02x", addr>>1, *val);
263

    
264
	return 0;
265
}
266

    
267
int opcd_rc632_fifo_read(struct rfid_asic_handle *hdl,
268
			 uint8_t max_len, uint8_t *data)
269
{
270
	int ret;
271
	uint8_t fifo_length;
272
	uint8_t i;
273
	uint16_t rx_len;
274

    
275
 	ret = opcd_rc632_reg_read(hdl, RC632_REG_FIFO_LENGTH, &fifo_length);
276
	if (ret < 0)
277
		return ret;
278

    
279
	rx_len = fifo_length+1;
280

    
281
	if (max_len < fifo_length)
282
		fifo_length = max_len;
283

    
284
	for (i = 0; i < fifo_length; i++)
285
		spi_outbuf[i] = FIFO_ADDR;
286

    
287
	spi_outbuf[0] |= 0x80;
288
	spi_outbuf[fifo_length] = 0x00;
289

    
290
	spi_transceive(spi_outbuf, fifo_length+1, spi_inbuf, &rx_len);
291
	memcpy(data, spi_inbuf+1, rx_len-1);
292

    
293
	DEBUG632("[FIFO] => %s", hexdump(data, rx_len-1));
294

    
295
	return rx_len-1;
296
}
297

    
298
int opcd_rc632_set_bits(struct rfid_asic_handle *hdl,
299
		   uint8_t reg, uint8_t bits)
300
{
301
	uint8_t val;
302
	int ret;
303
	
304
	ret = opcd_rc632_reg_read(hdl, reg, &val);
305
	if (ret < 0)
306
		return ret;
307

    
308
	val |= bits;
309

    
310
	return opcd_rc632_reg_write(hdl, reg, val);
311
}
312

    
313
int opcd_rc632_clear_bits(struct rfid_asic_handle *hdl,
314
		     uint8_t reg, uint8_t bits)
315
{
316
	uint8_t val;
317
	int ret;
318
	
319
	ret = opcd_rc632_reg_read(hdl, reg, &val);
320
	if (ret < 0)
321
		return ret;
322

    
323
	val &= ~bits;
324

    
325
	return opcd_rc632_reg_write(hdl, reg, val);
326
}
327

    
328
/* RC632 interrupt handling */
329

    
330
static void rc632_irq(void)
331
{
332
	struct req_ctx *irq_rctx;
333
	struct openpcd_hdr *irq_opcdh;
334
	uint8_t cause;
335

    
336
	/* CL RC632 has interrupted us */
337
	opcd_rc632_reg_read(NULL, RC632_REG_INTERRUPT_RQ, &cause);
338

    
339
	/* ACK all interrupts */
340
	//rc632_reg_write(NULL, RC632_REG_INTERRUPT_RQ, cause);
341
	opcd_rc632_reg_write(NULL, RC632_REG_INTERRUPT_RQ, RC632_INT_TIMER);
342
	DEBUGP("rc632_irq: ");
343

    
344
	if (cause & RC632_INT_LOALERT) {
345
		/* FIFO is getting low, refill from virtual FIFO */
346
		DEBUGP("FIFO_low ");
347
		#if 0
348
		if (!fifo_available(&rc632.fifo))
349
			return;
350
		#endif
351
		/* FIXME */
352
	}
353
	if (cause & RC632_INT_HIALERT) {
354
		/* FIFO is getting full, empty into virtual FIFO */
355
		DEBUGP("FIFO_high ");
356
		/* FIXME */
357
	}
358
	/* All interrupts below can be reported directly to the host */
359
	if (cause & RC632_INT_TIMER)
360
		DEBUGP("Timer ");
361
	if (cause & RC632_INT_IDLE)
362
		DEBUGP("Idle ");
363
	if (cause & RC632_INT_RX)
364
		DEBUGP("RxComplete ");
365
	if (cause & RC632_INT_TX)
366
		DEBUGP("TxComplete ");
367
	
368

    
369
	irq_rctx = req_ctx_find_get(0, RCTX_STATE_FREE,
370
				    RCTX_STATE_RC632IRQ_BUSY);
371
	if (!irq_rctx) {
372
		DEBUGPCRF("NO RCTX!");
373
		/* disable rc632 interrupt until RCTX is free */
374
		AT91F_AIC_DisableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
375
		return;
376
	}
377

    
378
	irq_opcdh = (struct openpcd_hdr *) irq_rctx->data;
379

    
380
	/* initialize static part of openpcd_hdr for USB IRQ reporting */
381
	irq_opcdh->cmd = OPENPCD_CMD_IRQ;
382
	irq_opcdh->flags = 0x00;
383
	irq_opcdh->reg = 0x07;
384
	irq_opcdh->val = cause;
385
	
386
	req_ctx_set_state(irq_rctx, RCTX_STATE_UDP_EP3_PENDING);
387
	DEBUGPCR("");
388
}
389

    
390
void rc632_unthrottle(void)
391
{
392
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
393
}
394

    
395
void rc632_power(uint8_t up)
396
{
397
        DEBUGPCRF("powering %s RC632", up ? "up" : "down");
398
	if (up)
399
		AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,
400
				      OPENPCD_PIO_RC632_RESET);
401
	else
402
		AT91F_PIO_SetOutput(AT91C_BASE_PIOA,
403
				    OPENPCD_PIO_RC632_RESET);
404
}
405

    
406
void rc632_reset(void)
407
{
408
	volatile int i;
409

    
410
	rc632_power(0);
411
	for (i = 0; i < 0xffff; i++)
412
		{}
413
	rc632_power(1);
414

    
415
	/* wait for startup phase to finish */
416
	while (1) {
417
		uint8_t val;
418
		opcd_rc632_reg_read(NULL, RC632_REG_COMMAND, &val);
419
		if (val == 0x00)
420
			break;
421
	}
422

    
423
	/* turn off register paging */
424
	opcd_rc632_reg_write(NULL, RC632_REG_PAGE0, 0x00);
425
}
426

    
427
static int rc632_usb_in(struct req_ctx *rctx)
428
{
429
	struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data;
430
	uint16_t len = rctx->tot_len-sizeof(*poh);
431

    
432
	/* initialize transmit length to header length */
433
	rctx->tot_len = sizeof(*poh);
434

    
435
	switch (poh->cmd) {
436
	case OPENPCD_CMD_READ_REG:
437
		opcd_rc632_reg_read(NULL, poh->reg, &poh->val);
438
		DEBUGP("READ REG(0x%02x)=0x%02x ", poh->reg, poh->val);
439
		/* register read always has to provoke a response */
440
		poh->flags &= OPENPCD_FLAG_RESPOND;
441
		break;
442
	case OPENPCD_CMD_READ_FIFO:
443
		/* FIFO read always has to provoke a response */
444
		poh->flags &= OPENPCD_FLAG_RESPOND;
445
		{
446
		uint16_t req_len = poh->val, remain_len = req_len, pih_len;
447
#if 0
448
		if (req_len > MAX_PAYLOAD_LEN) {
449
			pih_len = MAX_PAYLOAD_LEN;
450
			remain_len -= pih_len;
451
			opcd_rc632_fifo_read(NULL, pih_len, poh->data);
452
			rctx->tot_len += pih_len;
453
			DEBUGP("READ FIFO(len=%u)=%s ", req_len,
454
				hexdump(poh->data, pih_len));
455
			req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING);
456
			udp_refill_ep(2);
457

    
458
			/* get and initialize second rctx */
459
			rctx = req_ctx_find_get(0, RCTX_STATE_FREE,
460
						RCTX_STATE_MAIN_PROCESSING);
461
			if (!rctx) {
462
				DEBUGPCRF("FATAL_NO_RCTX!!!\n");
463
				break;
464
			}
465
			poh = (struct openpcd_hdr *) rctx->data;
466
			rctx->tot_len = sizeof(*poh);
467

    
468
			pih_len = remain_len;
469
			opcd_rc632_fifo_read(NULL, pih_len, poh->data);
470
			rctx->tot_len += pih_len;
471
			DEBUGP("READ FIFO(len=%u)=%s ", pih_len,
472
				hexdump(poh->data, pih_len));
473
			/* don't set state of second rctx, main function
474
			 * body will do this after switch statement */
475
		} else {
476
#endif
477
			poh->val = opcd_rc632_fifo_read(NULL, req_len, poh->data);
478
			rctx->tot_len += poh->val;
479
			DEBUGP("READ FIFO(len=%u)=%s ", poh->val,
480
				hexdump(poh->data, poh->val));
481
		//}
482
		}
483
		break;
484
	case OPENPCD_CMD_WRITE_REG:
485
		DEBUGP("WRITE_REG(0x%02x, 0x%02x) ", poh->reg, poh->val);
486
		opcd_rc632_reg_write(NULL, poh->reg, poh->val);
487
		break;
488
	case OPENPCD_CMD_WRITE_REG_SET:
489
		DEBUGP("WRITE_REG_SET(%s) ", hexdump(poh->data, len));
490
		opcd_rc632_reg_write_set(NULL, poh->data, len);
491
		break;
492
	case OPENPCD_CMD_WRITE_FIFO:
493
		DEBUGP("WRITE FIFO(len=%u): %s ", len,
494
			hexdump(poh->data, len));
495
		opcd_rc632_fifo_write(NULL, len, poh->data, 0);
496
		break;
497
	case OPENPCD_CMD_READ_VFIFO:
498
		DEBUGP("READ VFIFO ");
499
		goto not_impl;
500
		break;
501
	case OPENPCD_CMD_WRITE_VFIFO:
502
		DEBUGP("WRITE VFIFO ");
503
		goto not_impl;
504
		break;
505
	case OPENPCD_CMD_REG_BITS_CLEAR:
506
		DEBUGP("CLEAR BITS ");
507
		poh->val = opcd_rc632_clear_bits(NULL, poh->reg, poh->val);
508
		break;
509
	case OPENPCD_CMD_REG_BITS_SET:
510
		DEBUGP("SET BITS ");
511
		poh->val = opcd_rc632_set_bits(NULL, poh->reg, poh->val);
512
		break;
513
	case OPENPCD_CMD_DUMP_REGS:
514
		DEBUGP("DUMP REGS ");
515
		goto not_impl;
516
		break;
517
	default:
518
		DEBUGP("UNKNOWN ");
519
		return USB_ERR(USB_ERR_CMD_UNKNOWN);
520
	}
521

    
522
	return (poh->flags & OPENPCD_FLAG_RESPOND) ? USB_RET_RESPOND : 0;
523
not_impl:
524
	DEBUGP("NOT IMPLEMENTED YET ");
525
	return USB_ERR(USB_ERR_CMD_NOT_IMPL);
526
}
527

    
528
void rc632_init(void)
529
{
530
	//fifo_init(&rc632.fifo, 256, NULL, &rc632);
531

    
532
	DEBUGPCRF("entering");
533

    
534
	AT91F_SPI_CfgPMC();
535

    
536
	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,
537
				AT91C_PA11_NPCS0|AT91C_PA12_MISO|
538
				AT91C_PA13_MOSI |AT91C_PA14_SPCK, 0);
539

    
540
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SPI,
541
			      OPENPCD_IRQ_PRIO_SPI,
542
			      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &spi_irq);
543
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI);
544

    
545
	AT91F_SPI_EnableIt(pSPI, AT91C_SPI_MODF|AT91C_SPI_OVRES);
546
#ifdef SPI_USES_DMA
547
	AT91F_SPI_EnableIt(pSPI, AT91C_SPI_ENDRX|AT91C_SPI_ENDTX);
548
#endif
549

    
550
#ifdef SPI_DEBUG_LOOPBACK
551
	AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED|
552
				AT91C_SPI_MODFDIS|AT91C_SPI_LLB);
553
#else
554
	AT91F_SPI_CfgMode(pSPI, AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED|
555
				AT91C_SPI_MODFDIS);
556
#endif
557
	/* CPOL = 0, NCPHA = 1, CSAAT = 0, BITS = 0000, SCBR = 10 (4.8MHz), 
558
	 * DLYBS = 0, DLYBCT = 0 */
559
#ifdef SPI_USES_DMA
560
	AT91F_SPI_CfgCs(pSPI, 0, AT91C_SPI_BITS_8|AT91C_SPI_NCPHA|(10<<8));
561
#else
562
	/* 320 kHz in case of I/O based SPI */
563
	AT91F_SPI_CfgCs(pSPI, 0, AT91C_SPI_BITS_8|AT91C_SPI_NCPHA|(0x7f<<8));
564
#endif
565
	AT91F_SPI_Enable(pSPI);
566

    
567
	/* Register rc632_irq */
568
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632,
569
			      OPENPCD_IRQ_PRIO_RC632,
570
			      AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &rc632_irq);
571
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
572

    
573
	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_RC632_RESET);
574

    
575
	rc632_reset();
576

    
577
	/* configure IRQ pin */
578
	opcd_rc632_reg_write(NULL, RC632_REG_IRQ_PIN_CONFIG,
579
			     RC632_IRQCFG_CMOS|RC632_IRQCFG_INV);
580
	/* enable interrupts */
581
	opcd_rc632_reg_write(NULL, RC632_REG_INTERRUPT_EN, RC632_INT_TIMER);
582
	
583
	/* configure AUX to test signal four */
584
	opcd_rc632_reg_write(NULL, RC632_REG_TEST_ANA_SELECT, 0x04);
585

    
586
	usb_hdlr_register(&rc632_usb_in, OPENPCD_CMD_CLS_RC632);
587
};
588

    
589
#if 0
590
void rc632_exit(void)
591
{
592
	usb_hdlr_unregister(OPENPCD_CMD_CLS_RC632);
593
	AT91F_AIC_DisableIt(AT91C_BASE_AIC, OPENPCD_IRQ_RC632);
594
	AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_SPI);
595
	AT91F_SPI_Disable(pSPI);
596
}
597
#endif
598

    
599
#ifdef DEBUG
600
static int rc632_reg_write_verify(struct rfid_asic_handle *hdl,
601
				  uint8_t reg, uint8_t val)
602
{
603
	uint8_t tmp;
604

    
605
	opcd_rc632_reg_write(hdl, reg, val);
606
	opcd_rc632_reg_read(hdl, reg, &tmp);
607

    
608
	DEBUGPCRF("reg=0x%02x, write=0x%02x, read=0x%02x ", reg, val, tmp);
609

    
610
	return (val == tmp);
611
}
612

    
613
int rc632_dump(void)
614
{
615
	uint8_t i;
616
	uint16_t rx_len = sizeof(spi_inbuf);
617

    
618
	for (i = 0; i <= 0x3f; i++) {
619
		uint8_t reg = i;
620
		if (reg == RC632_REG_FIFO_DATA)
621
			reg = 0x3e;
622
			
623
		spi_outbuf[i] = reg << 1;
624
		spi_inbuf[i] = 0x00;
625
	}
626

    
627
	/* MSB of first byte of read spi transfer is high */
628
	spi_outbuf[0] |= 0x80;
629

    
630
	/* last byte of read spi transfer is 0x00 */
631
	spi_outbuf[0x40] = 0x00;
632
	spi_inbuf[0x40] = 0x00;
633

    
634
	spi_transceive(spi_outbuf, 0x41, spi_inbuf, &rx_len);
635

    
636
	for (i = 0; i < 0x3f; i++) {
637
		if (i == RC632_REG_FIFO_DATA)
638
			DEBUGPCR("REG 0x02 = NOT READ");
639
		else
640
			DEBUGPCR("REG 0x%02x = 0x%02x", i, spi_inbuf[i+1]);
641
	}
642
	
643
	return 0;
644
}
645

    
646
int rc632_test(struct rfid_asic_handle *hdl)
647
{
648
	if (rc632_reg_write_verify(hdl, RC632_REG_RX_WAIT, 0x55) != 1)
649
		return -1;
650

    
651
	if (rc632_reg_write_verify(hdl, RC632_REG_RX_WAIT, 0xAA) != 1)
652
		return -1;
653

    
654
	return 0;
655
}
656
#else /* DEBUG */
657
int rc632_test(struct rfid_asic_handle *hdl) {}
658
int rc632_dump(void) {}
659
#endif /* DEBUG */
(10-10/15)
Add picture from clipboard (Maximum size: 48.8 MB)