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
29 #include <sys/types.h>
31 #include <lib_AT91SAM7.h>
34 #include <os/usb_handler.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
;
52 SSC_MODE_14443A_SHORT
,
53 SSC_MODE_14443A_STANDARD
,
55 SSC_MODE_EDGE_ONE_SHOT
,
60 struct req_ctx
*rx_ctx
[2];
63 static struct ssc_state ssc_state
;
65 static const u_int16_t ssc_dmasize
[] = {
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 | \
86 #define SSC_TX_IRQ_MASK (AT91C_SSC_TXRDY | \
92 void ssc_rx_mode_set(enum ssc_mode ssc_mode
)
94 u_int8_t data_len
, num_data
, sync_len
;
97 /* disable Rx and all Rx interrupt sources */
98 AT91F_SSC_DisableRx(AT91C_BASE_SSC
);
99 AT91F_SSC_DisableIt(ssc
, SSC_RX_IRQ_MASK
);
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
;
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
;
114 num_data
= 16; /* FIXME */
116 case SSC_MODE_14443B
:
117 /* start sampling at first falling data edge */
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;
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
;
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
);
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
;
158 AT91F_SSC_DisableTx(AT91C_BASE_SSC
);
160 /* disable all Tx related interrupt sources */
161 AT91F_SSC_DisableIt(ssc
, SSC_TX_IRQ_MASK
);
164 case SSC_MODE_14443A_SHORT
:
165 start_cond
= AT91C_SSC_START_RISE_RF
;
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
;
175 num_data
= 1; /* FIXME */
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
);
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
;
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)
212 #define DEBUGR(x, args ...)
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
);
221 DEBUGP("no_rctx_for_refill! ");
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
);
230 AT91F_PDC_SetNextRx(rx_pdc
, rctx
->data
+MAX_HDRSIZE
,
231 ssc_dmasize
[ssc_state
.mode
]);
232 ssc_state
.rx_ctx
[1] = rctx
;
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();
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
;
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
);
274 DEBUGPCRF("no rctx for secondary refill!");
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
;
289 /* we were unable to fill*/
290 DEBUGPCRF("prim/secnd DMA busy, can't refill");
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);
301 DEBUGPCRF("prim/secnd DMA busy, can't refill");
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
) {
317 /* in a one-shot sample, we don't want to keep
318 * sampling further after having received the first
320 if (ssc_state
.mode
== SSC_MODE_EDGE_ONE_SHOT
) {
321 DEBUGP("DISABLE_RX ");
324 //AT91F_SSC_DisableIt(AT91C_BASE_SSC, SSC_RX_IRQ_MASK);
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 ");
338 ssc_rx_mode_set(ssc_state
.mode
);
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
;
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));
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 */
364 req_ctx_set_state(ssc_state
.rx_ctx
[0],
365 RCTX_STATE_UDP_EP2_PENDING
);
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
) {
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
);
383 if (__ssc_rx_refill(0) == -1)
384 AT91F_SSC_DisableIt(ssc
, AT91C_SSC_ENDRX
|
389 if (__ssc_rx_refill(1) == -1)
390 AT91F_SSC_DisableIt(ssc
, AT91C_SSC_ENDRX
|
397 if (__ssc_rx_refill(1) == -1)
398 AT91F_SSC_DisableIt(ssc
, AT91C_SSC_ENDRX
|
404 if (ssc_sr
& AT91C_SSC_OVRUN
)
405 DEBUGP("RX_OVERRUN ");
407 if (ssc_sr
& AT91C_SSC_CP0
)
410 if (ssc_sr
& AT91C_SSC_TXSYN
)
415 switch (ssc_state
.mode
) {
416 case SSC_MODE_14443A_SHORT
:
417 if (ssc_sr
& AT91C_SSC_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 */
430 DEBUGP("<== unknown ");
434 case SSC_MODE_14443A_STANDARD
:
435 case SSC_MODE_EDGE_ONE_SHOT
:
439 DEBUGP("UNKNOWN_MODE ");
445 AT91F_AIC_ClearIt(AT91C_BASE_AIC
, AT91C_ID_SSC
);
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)
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
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
|
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
;
500 case OPENPCD_CMD_SSC_READ
:
501 /* FIXME: allow host to specify mode */
502 ssc_rx_mode_set(SSC_MODE_EDGE_ONE_SHOT
);
507 case OPENPCD_CMD_SSC_WRITE
:
508 /* FIXME: implement this */
512 return USB_ERR(USB_ERR_CMD_UNKNOWN
);
516 return (poh
->flags
& OPENPCD_FLAG_RESPOND
) ? USB_RET_RESPOND
: 0;
519 void ssc_rx_init(void)
522 tc_cdiv_sync_enable();
524 rx_pdc
= (AT91PS_PDC
) &(ssc
->SSC_RPR
);
528 AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA
,
529 OPENPCD_PIO_MFOUT_SSC_RX
| OPENPCD_PIO_SSP_CKIN
|
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 */
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);
554 ssc_rx_mode_set(SSC_MODE_NONE
);
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
);
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);
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
));