paths changed
[kk_librfid.git] / firmware / src / picc / ssc_picc.c
blob8ec6f791562c1edff25132b6e668016b455161f4
1 /* AT91SAM7 SSC controller routines for OpenPICC
2 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
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.
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.
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
18 * We use SSC for both TX and RX side.
20 * RX side is interconnected with demodulated carrier
22 * TX side is interconnected with load modulation circuitry
25 //#undef DEBUG
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>
34 #include <os/usb_handler.h>
35 #include <os/dbgu.h>
36 #include <os/led.h>
37 #include "../openpcd.h"
39 #include <picc/tc_cdiv_sync.h>
41 //#define DEBUG_SSC_REFILL
43 /* definitions for four-times oversampling */
44 #define REQA 0x10410441
45 #define WUPA 0x04041041
47 static const AT91PS_SSC ssc = AT91C_BASE_SSC;
48 static AT91PS_PDC rx_pdc;
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,
59 struct ssc_state {
60 struct req_ctx *rx_ctx[2];
61 enum ssc_mode mode;
63 static struct ssc_state ssc_state;
65 static const u_int16_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 */
74 /* This is for four-times oversampling */
75 #define ISO14443A_SOF_SAMPLE 0x01
76 #define ISO14443A_SOF_LEN 4
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)
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)
92 void ssc_rx_mode_set(enum ssc_mode ssc_mode)
94 u_int8_t data_len, num_data, sync_len;
95 u_int32_t start_cond;
97 /* disable Rx and all Rx interrupt sources */
98 AT91F_SSC_DisableRx(AT91C_BASE_SSC);
99 AT91F_SSC_DisableIt(ssc, SSC_RX_IRQ_MASK);
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;
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;
142 /* Enable Rx DMA */
143 AT91F_PDC_EnableRx(rx_pdc);
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;
152 static void ssc_tx_mode_set(enum ssc_mode ssc_mode)
154 u_int8_t data_len, num_data, sync_len;
155 u_int32_t start_cond;
157 /* disable Tx */
158 AT91F_SSC_DisableTx(AT91C_BASE_SSC);
160 /* disable all Tx related interrupt sources */
161 AT91F_SSC_DisableIt(ssc, SSC_TX_IRQ_MASK);
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;
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;
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);
191 ssc_state.mode = ssc_mode;
192 #endif
198 static struct openpcd_hdr opcd_ssc_hdr = {
199 .cmd = OPENPCD_CMD_SSC_READ,
202 static inline void init_opcdhdr(struct req_ctx *rctx)
204 memcpy(rctx->data, &opcd_ssc_hdr, sizeof(opcd_ssc_hdr));
205 rctx->tot_len = sizeof(opcd_ssc_hdr);
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
215 static int __ramfunc __ssc_rx_refill(int secondary)
217 struct req_ctx *rctx;
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;
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;
239 tc_cdiv_sync_reset();
241 return 0;
244 #if 0
245 static char dmabuf1[512];
246 static char dmabuf2[512];
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
255 static int8_t ssc_rx_refill(void)
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;
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;
277 init_opcdhdr(rctx);
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;
294 #else
295 if (AT91F_PDC_IsRxEmpty(rx_pdc))
296 AT91F_PDC_SetRx(rx_pdc, dmabuf1, sizeof(dmabuf1)>>2);
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
304 #endif
306 #define ISO14443A_FDT_SHORT_1 1236
307 #define ISO14443A_FDT_SHORT_0 1172
309 static void __ramfunc ssc_irq(void)
311 u_int32_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);
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();
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 = (u_int32_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;
345 #endif
346 /* Ignore empty frames */
347 if (ssc_state.mode == SSC_MODE_CONTINUOUS) {
348 tmp = (u_int32_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]);
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]);
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);
383 if (__ssc_rx_refill(0) == -1)
384 AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |
385 AT91C_SSC_RXBUFF |
386 AT91C_SSC_OVRUN);
389 if (__ssc_rx_refill(1) == -1)
390 AT91F_SSC_DisableIt(ssc, AT91C_SSC_ENDRX |
391 AT91C_SSC_RXBUFF |
392 AT91C_SSC_OVRUN);
394 udp_refill_ep(2);
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
404 if (ssc_sr & AT91C_SSC_OVRUN)
405 DEBUGP("RX_OVERRUN ");
407 if (ssc_sr & AT91C_SSC_CP0)
408 DEBUGP("CP0 ");
410 if (ssc_sr & AT91C_SSC_TXSYN)
411 DEBUGP("TXSYN ");
412 #if 0
413 led_toggle(1);
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 u_int32_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 ");
432 break;
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;
443 #endif
444 DEBUGPCR("I");
445 AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SSC);
448 void ssc_print(void)
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);
457 void ssc_rx_unthrottle(void)
459 AT91F_SSC_EnableIt(ssc, AT91C_SSC_ENDRX | AT91C_SSC_CP0 |
460 AT91C_SSC_RXBUFF | AT91C_SSC_OVRUN);
463 void ssc_rx_start(void)
465 volatile int i;
466 //DEBUGPCRF("starting SSC RX\n");
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);
473 /* Clear the flipflop */
474 tc_cdiv_sync_reset();
477 void ssc_rx_stop(void)
479 /* Disable reception */
480 AT91F_SSC_DisableRx(AT91C_BASE_SSC);
483 void ssc_tx_init(void)
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);
492 ssc_tx_mode_set(SSC_MODE_14443A_SHORT);
495 static int ssc_usb_in(struct req_ctx *rctx)
497 struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data;
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;
516 return (poh->flags & OPENPCD_FLAG_RESPOND) ? USB_RET_RESPOND : 0;
519 void ssc_rx_init(void)
521 tc_cdiv_sync_init();
522 tc_cdiv_sync_enable();
524 rx_pdc = (AT91PS_PDC) &(ssc->SSC_RPR);
526 AT91F_SSC_CfgPMC();
528 AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,
529 OPENPCD_PIO_MFOUT_SSC_RX | OPENPCD_PIO_SSP_CKIN |
530 OPENPICC_PIO_FRAME,
533 AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL);
534 AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPICC_PIO_SSC_DATA_CONTROL);
536 AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SSC,
537 OPENPCD_IRQ_PRIO_SSC,
538 AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &ssc_irq);
540 /* don't divide clock inside SSC, we do that in tc_cdiv */
541 ssc->SSC_CMR = 0;
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
551 __ssc_rx_refill(0);
552 __ssc_rx_refill(1);
554 ssc_rx_mode_set(SSC_MODE_NONE);
555 #if 0
556 AT91F_PDC_EnableRx(rx_pdc);
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);
565 AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SSC);
567 //usb_hdlr_register(&ssc_usb_in, OPENPCD_CMD_CLS_SSC);
569 DEBUGP("\r\n");
572 void ssc_fini(void)
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));