Initial commit
[kk_librfid.git] / firmware / src / picc / adc.c
blobf350a495eb7ba9cdb77ad39274976633c56121a8
1 /* AT91SAM7 ADC 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
20 #include <errno.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <AT91SAM7.h>
24 #include <lib_AT91SAM7.h>
25 #include <openpcd.h>
27 #include <os/usb_handler.h>
28 #include "../openpcd.h"
29 #include <os/dbgu.h>
31 #define OPENPICC_ADC_CH_FIELDSTR AT91C_ADC_CH4
32 #define OPENPICC_ADC_CH_PLL_DEM AT91C_ADC_CH5
34 #define DEBUG_ADC
36 #ifdef DEBUG_ADC
37 #define DEBUGADC DEBUGP
38 #else
39 #define DEBUGADC do { } while (0)
40 #endif
42 static const AT91PS_ADC adc = AT91C_BASE_ADC;
44 enum adc_states {
45 ADC_NONE,
46 ADC_READ_CONTINUOUS,
47 ADC_READ_CONTINUOUS_USB,
48 ADC_READ_SINGLE,
51 struct adc_state {
52 enum adc_states state;
53 struct req_ctx *rctx;
56 static struct adc_state adc_state;
58 static void adc_irq(void)
60 u_int32_t sr = adc->ADC_SR;
61 struct req_ctx *rctx = adc_state.rctx;
63 DEBUGADC("adc_irq(SR=0x%08x, IMR=0x%08x, state=%u): ",
64 sr, adc->ADC_IMR, adc_state.state);
66 switch (adc_state.state) {
67 case ADC_NONE:
68 //break;
69 case ADC_READ_CONTINUOUS_USB:
70 if (sr & AT91C_ADC_EOC4)
71 DEBUGADC("CDR4=0x%4x ", adc->ADC_CDR4);
72 if (sr & AT91C_ADC_EOC5)
73 DEBUGADC("CDR5=0x%4x ", adc->ADC_CDR5);
74 if (sr & AT91C_ADC_ENDRX) {
75 /* rctx full, get rid of it */
76 DEBUGADC("sending rctx (val=%s) ",
77 hexdump(rctx->data[4], 2));
79 req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING);
80 adc_state.state = ADC_NONE;
81 adc_state.rctx = NULL;
83 //AT91F_PDC_SetRx(AT91C_BASE_PDC_ADC, NULL, 0);
85 /* Disable EOC interrupts since we don't want to
86 * re-start conversion any further*/
87 AT91F_ADC_DisableIt(AT91C_BASE_ADC, AT91C_ADC_ENDRX);
88 //AT91C_ADC_EOC4|AT91C_ADC_EOC5|AT91C_ADC_ENDRX);
89 AT91F_PDC_DisableRx(AT91C_BASE_PDC_ADC);
90 DEBUGADC("disabled IT/RX ");
91 } else {
92 if (sr & (AT91C_ADC_EOC4|AT91C_ADC_EOC5)) {
93 /* re-start conversion, since we need more values */
94 AT91F_ADC_StartConversion(adc);
97 break;
100 AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_ADC);
101 DEBUGADC("cleeared ADC IRQ in AIC\r\n");
104 #if 0
105 u_int16_t adc_read_fieldstr(void)
107 return adc->ADC_CDR4;
110 u_int16_T adc_read_pll_dem(void)
112 return adc
114 #endif
116 static int adc_usb_in(struct req_ctx *rctx)
118 struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->data[0];
120 switch (poh->cmd) {
121 case OPENPCD_CMD_ADC_READ:
122 DEBUGADC("ADC_READ(chan=%u, len=%u) ", poh->reg, poh->val);
123 //channel = poh->reg;
124 if (adc_state.rctx) {
125 /* FIXME: do something */
126 req_ctx_put(rctx);
129 adc_state.state = ADC_READ_CONTINUOUS_USB;
130 adc_state.rctx = rctx;
131 rctx->tot_len = sizeof(*poh) + poh->val * 2;
132 AT91F_PDC_SetRx(AT91C_BASE_PDC_ADC, rctx->data, poh->val);
133 AT91F_PDC_EnableRx(AT91C_BASE_PDC_ADC);
134 AT91F_ADC_EnableChannel(AT91C_BASE_ADC, OPENPICC_ADC_CH_FIELDSTR);
135 AT91F_ADC_EnableIt(AT91C_BASE_ADC, AT91C_ADC_ENDRX |
136 OPENPICC_ADC_CH_FIELDSTR);
137 AT91F_ADC_StartConversion(adc);
138 break;
142 int adc_init(void)
144 AT91F_ADC_CfgPMC();
145 AT91F_ADC_CfgTimings(AT91C_BASE_ADC, 48 /*MHz*/, 5 /*MHz*/,
146 20/*uSec*/, 700/*nSec*/);
147 #if 0
148 AT91F_ADC_EnableChannel(AT91C_BASE_ADC, OPENPICC_ADC_CH_FIELDSTR |
149 OPENPICC_ADC_CH_PLL_DEM);
150 #endif
151 AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_ADC,
152 AT91C_AIC_PRIOR_LOWEST,
153 AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &adc_irq);
154 AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_ADC);
156 usb_hdlr_register(&adc_usb_in, OPENPCD_CMD_CLS_ADC);