diff options
-rw-r--r-- | openpcd/firmware/src/picc/adc.c | 57 | ||||
-rw-r--r-- | openpcd/firmware/src/picc/ssc_picc.c | 46 |
2 files changed, 75 insertions, 28 deletions
diff --git a/openpcd/firmware/src/picc/adc.c b/openpcd/firmware/src/picc/adc.c index 1438a08..31b3469 100644 --- a/openpcd/firmware/src/picc/adc.c +++ b/openpcd/firmware/src/picc/adc.c @@ -17,6 +17,14 @@ #define OPENPICC_ADC_CH_FIELDSTR AT91C_ADC_CH4 #define OPENPICC_ADC_CH_PLL_DEM AT91C_ADC_CH5 +#define DEBUG_ADC + +#ifdef DEBUG_ADC +#define DEBUGADC DEBUGP +#else +#define DEBUGADC do { } while (0) +#endif + static const AT91PS_ADC adc = AT91C_BASE_ADC; enum adc_states { @@ -33,35 +41,50 @@ struct adc_state { static struct adc_state adc_state; -static void adc_int(void) +static void adc_irq(void) { u_int32_t sr = adc->ADC_SR; struct req_ctx *rctx = adc_state.rctx; - u_int16_t *val = (u_int16_t *) &(rctx->tx.data[rctx->tx.tot_len]); + + DEBUGADC("adc_irq(SR=0x%08x, IMR=0x%08x, state=%u): ", + sr, adc->ADC_IMR, adc_state.state); switch (adc_state.state) { case ADC_NONE: - break; + //break; case ADC_READ_CONTINUOUS_USB: + if (sr & AT91C_ADC_EOC4) + DEBUGADC("CDR4=0x%4x ", adc->ADC_CDR4); + if (sr & AT91C_ADC_EOC5) + DEBUGADC("CDR5=0x%4x ", adc->ADC_CDR5); if (sr & AT91C_ADC_ENDRX) { /* rctx full, get rid of it */ + DEBUGADC("sending rctx (val=%s) ", + hexdump(rctx->tx.data[4], 2)); + req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING); adc_state.state = ADC_NONE; adc_state.rctx = NULL; + + //AT91F_PDC_SetRx(AT91C_BASE_PDC_ADC, NULL, 0); /* Disable EOC interrupts since we don't want to * re-start conversion any further*/ - AT91F_ADC_DisableIt(AT91C_BASE_ADC, - AT91C_ADC_EOC4|AT91C_ADC_EOC5); + AT91F_ADC_DisableIt(AT91C_BASE_ADC, AT91C_ADC_ENDRX); + //AT91C_ADC_EOC4|AT91C_ADC_EOC5|AT91C_ADC_ENDRX); AT91F_PDC_DisableRx(AT91C_BASE_PDC_ADC); - } - - if (sr & (AT91C_ADC_EOC4|AT91C_ADC_EOC5)) { - /* re-start conversion, since we need more values */ - AT91F_ADC_StartConversion(adc); + DEBUGADC("disabled IT/RX "); + } else { + if (sr & (AT91C_ADC_EOC4|AT91C_ADC_EOC5)) { + /* re-start conversion, since we need more values */ + AT91F_ADC_StartConversion(adc); + } } break; } + + AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_ADC); + DEBUGADC("cleeared ADC IRQ in AIC\r\n"); } #if 0 @@ -83,6 +106,7 @@ static int adc_usb_in(struct req_ctx *rctx) switch (poh->cmd) { case OPENPCD_CMD_ADC_READ: + DEBUGADC("ADC_READ(chan=%u, len=%u) ", poh->reg, poh->val); //channel = poh->reg; if (adc_state.rctx) { /* FIXME: do something */ @@ -91,11 +115,14 @@ static int adc_usb_in(struct req_ctx *rctx) adc_state.state = ADC_READ_CONTINUOUS_USB; adc_state.rctx = rctx; + memcpy(pih, poh, sizeof(*pih)); + rctx->tx.tot_len = sizeof(*pih) + poh->val * 2; + AT91F_PDC_SetRx(AT91C_BASE_PDC_ADC, rctx->rx.data, poh->val); + AT91F_PDC_EnableRx(AT91C_BASE_PDC_ADC); AT91F_ADC_EnableChannel(AT91C_BASE_ADC, OPENPICC_ADC_CH_FIELDSTR); AT91F_ADC_EnableIt(AT91C_BASE_ADC, AT91C_ADC_ENDRX | OPENPICC_ADC_CH_FIELDSTR); - AT91F_PDC_SetRx(AT91C_BASE_PDC_ADC, rctx->rx.data, 60 /*FIXME*/); - AT91F_PDC_EnableRx(AT91C_BASE_PDC_ADC); + AT91F_ADC_StartConversion(adc); break; } } @@ -105,8 +132,14 @@ int adc_init(void) AT91F_ADC_CfgPMC(); AT91F_ADC_CfgTimings(AT91C_BASE_ADC, 48 /*MHz*/, 5 /*MHz*/, 20/*uSec*/, 700/*nSec*/); +#if 0 AT91F_ADC_EnableChannel(AT91C_BASE_ADC, OPENPICC_ADC_CH_FIELDSTR | OPENPICC_ADC_CH_PLL_DEM); +#endif + AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_ADC, + AT91C_AIC_PRIOR_LOWEST, + AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &adc_irq); + AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC); usb_hdlr_register(&adc_usb_in, OPENPCD_CMD_CLS_ADC); } diff --git a/openpcd/firmware/src/picc/ssc_picc.c b/openpcd/firmware/src/picc/ssc_picc.c index 2949da6..fac2c62 100644 --- a/openpcd/firmware/src/picc/ssc_picc.c +++ b/openpcd/firmware/src/picc/ssc_picc.c @@ -3,9 +3,9 @@ * * We use SSC for both TX and RX side. * - * RX side is interconnected with MFOUT of RC632 + * RX side is interconnected with demodulated carrier * - * TX side is interconnected with MFIN of RC632 + * TX side is interconnected with load modulation circuitry */ #include <errno.h> @@ -44,7 +44,7 @@ static struct ssc_state ssc_state; #define ISO14443A_SOF_SAMPLE 0x08 #define ISO14443A_SOF_LEN 4 -static void ssc_rx_mode_set(enum ssc_mode ssc_mode) +void ssc_rx_mode_set(enum ssc_mode ssc_mode) { u_int8_t data_len, num_data, sync_len; u_int32_t start_cond; @@ -53,7 +53,7 @@ static void ssc_rx_mode_set(enum ssc_mode ssc_mode) ssc->SSC_CR = AT91C_SSC_RXDIS; /* disable all Rx related interrupt sources */ - AT91F_SSC_DisableIt(ssc, ssc->SSC_IDR = AT91C_SSC_RXRDY | + AT91F_SSC_DisableIt(ssc, AT91C_SSC_RXRDY | AT91C_SSC_OVRUN | AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF | AT91C_SSC_RXSYN | AT91C_SSC_CP0 | AT91C_SSC_CP1); @@ -78,7 +78,8 @@ static void ssc_rx_mode_set(enum ssc_mode ssc_mode) //start_cond = break; case SSC_MODE_EDGE_ONE_SHOT: - start_cond = AT91C_SSC_START_EDGE_RF; + //start_cond = AT91C_SSC_START_EDGE_RF; + start_cond = AT91C_SSC_START_CONTINOUS; sync_len = 0; data_len = 8; num_data = 50; @@ -91,13 +92,13 @@ static void ssc_rx_mode_set(enum ssc_mode ssc_mode) (((sync_len-1) & 0x0f) << 16); ssc->SSC_RCMR = AT91C_SSC_CKS_RK | AT91C_SSC_CKO_NONE | start_cond; + AT91F_PDC_EnableRx(rx_pdc); /* Enable RX interrupts */ - AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN); - //AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF); + AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN | + AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF); ssc_state.mode = ssc_mode; - AT91F_PDC_EnableRx(rx_pdc); } static void ssc_tx_mode_set(enum ssc_mode ssc_mode) @@ -228,7 +229,7 @@ static int8_t ssc_rx_refill(void) static void ssc_irq(void) { u_int32_t ssc_sr = ssc->SSC_SR; - DEBUGP("ssc_sr=0x%08x: ", ssc_sr); + DEBUGP("ssc_sr=0x%08x, mode=%u: ", ssc_sr, ssc_state.mode); if (ssc_sr & AT91C_SSC_OVRUN) DEBUGP("RX OVERRUN "); @@ -253,6 +254,7 @@ static void ssc_irq(void) break; case SSC_MODE_14443A_STANDARD: + case SSC_MODE_EDGE_ONE_SHOT: if (ssc_sr & (AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF)) { #if 1 @@ -265,7 +267,7 @@ static void ssc_irq(void) #endif if (ssc_sr & AT91C_SSC_RXBUFF) { - DEBUGPCRF("RXBUFF, shouldn't happen!"); + DEBUGP("RXBUFF, shouldn't happen! "); #if 0 req_ctx_set_state(ssc_state.rx_ctx[0], RCTX_STATE_UDP_EP2_PENDING); @@ -278,6 +280,8 @@ static void ssc_irq(void) } break; } + DEBUGPCR(""); + AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_SSC); } @@ -316,12 +320,15 @@ static int ssc_usb_in(struct req_ctx *rctx) struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->rx.data[0]; struct openpcd_hdr *pih = (struct openpcd_hdr *) &rctx->tx.data[0]; - /* FIXME: implement this */ switch (poh->cmd) { case OPENPCD_CMD_SSC_READ: - + /* FIXME: allow host to specify mode */ + ssc_rx_mode_set(SSC_MODE_EDGE_ONE_SHOT); + ssc_rx_start(); break; case OPENPCD_CMD_SSC_WRITE: + /* FIXME: implement this */ + //ssc_tx_start() break; } @@ -334,13 +341,16 @@ void ssc_rx_init(void) rx_pdc = (AT91PS_PDC) &(ssc->SSC_RPR); AT91F_SSC_CfgPMC(); + + AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, + OPENPCD_PIO_MFOUT_SSC_RX | OPENPCD_PIO_SSP_CKIN, + 0); + AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SSC, OPENPCD_IRQ_PRIO_SSC, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &ssc_irq); - AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SSC); - /* Reset */ - ssc->SSC_CR = AT91C_SSC_SWRST; + //ssc->SSC_CR = AT91C_SSC_SWRST; /* don't divide clock */ ssc->SSC_CMR = 0; @@ -349,11 +359,15 @@ void ssc_rx_init(void) AT91C_SSC_START_CONTINOUS; /* Data bits per Data N = 32-1, Data words per Frame = 15-1 (=60 byte)*/ ssc->SSC_RFMR = 31 | AT91C_SSC_MSBF | (14 << 8); + + ssc_rx_mode_set(SSC_MODE_EDGE_ONE_SHOT); + + AT91F_PDC_EnableRx(rx_pdc); /* Enable RX interrupts */ AT91F_SSC_EnableIt(ssc, AT91C_SSC_OVRUN | AT91C_SSC_ENDRX | AT91C_SSC_RXBUFF); - AT91F_PDC_EnableRx(rx_pdc); + AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SSC); usb_hdlr_register(&ssc_usb_in, OPENPCD_CMD_CLS_SSC); } |