Project

General

Profile

Download (4.06 KB) Statistics
| Branch: | Tag: | Revision:
1
/* AT91SAM7 ADC controller routines for OpenPICC
2
 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
3
 *
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.
8
 *
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.
13
 *
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
17
 *
18
 */
19

    
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>
26

    
27
#include <os/usb_handler.h>
28
#include "../openpcd.h"
29
#include <os/dbgu.h>
30

    
31
#define OPENPICC_ADC_CH_FIELDSTR	AT91C_ADC_CH4
32
#define OPENPICC_ADC_CH_PLL_DEM		AT91C_ADC_CH5
33

    
34
#define DEBUG_ADC
35

    
36
#ifdef DEBUG_ADC
37
#define DEBUGADC	DEBUGP
38
#else
39
#define DEBUGADC	do { } while (0)
40
#endif
41

    
42
static const AT91PS_ADC adc = AT91C_BASE_ADC;
43

    
44
enum adc_states {
45
	ADC_NONE,
46
	ADC_READ_CONTINUOUS,
47
	ADC_READ_CONTINUOUS_USB,
48
	ADC_READ_SINGLE,
49
};
50

    
51
struct adc_state {
52
	enum adc_states state;
53
	struct req_ctx *rctx;
54
};
55

    
56
static struct adc_state adc_state;
57

    
58
static void adc_irq(void)
59
{
60
	uint32_t sr = adc->ADC_SR;
61
	struct req_ctx *rctx = adc_state.rctx;
62

    
63
	DEBUGADC("adc_irq(SR=0x%08x, IMR=0x%08x, state=%u): ",
64
		 sr, adc->ADC_IMR, adc_state.state);
65

    
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));
78
				 
79
			req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING);
80
			adc_state.state = ADC_NONE;
81
			adc_state.rctx = NULL;
82
		
83
			//AT91F_PDC_SetRx(AT91C_BASE_PDC_ADC, NULL, 0);
84

    
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);
95
			}
96
		}
97
		break;
98
	}
99

    
100
	AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_ADC);
101
	DEBUGADC("cleeared ADC IRQ in AIC\r\n");
102
}
103

    
104
#if 0
105
uint16_t adc_read_fieldstr(void)
106
{
107
	return adc->ADC_CDR4;
108
}
109

    
110
uint16_T adc_read_pll_dem(void)
111
{
112
	return adc
113
}
114
#endif
115

    
116
static int adc_usb_in(struct req_ctx *rctx)
117
{
118
	struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->data[0];
119

    
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);
127
		}
128

    
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;
139
	}
140
}
141

    
142
int adc_init(void)
143
{
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);
155

    
156
	usb_hdlr_register(&adc_usb_in, OPENPCD_CMD_CLS_ADC);
157
}
(1-1/26)
Add picture from clipboard (Maximum size: 48.8 MB)