Project

General

Profile

Download (6.63 KB) Statistics
| Branch: | Tag: | Revision:
1 b7e19ea8 (no author)
/* main_pwm - OpenPCD firmware for generating a PWM-modulated 13.56MHz
2
 *	      carrier
3
 *
4
 * To use this, you need to connect PIOA P0 with MFIN of the reader.
5 32985a29 laforge
 *
6
 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by 
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, write to the Free Software
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 *
22 b7e19ea8 (no author)
 */
23
24
#include <errno.h>
25
#include <string.h>
26
#include <lib_AT91SAM7.h>
27 520784c7 (no author)
#include "../openpcd.h"
28 c0a3cda1 (no author)
#include <pcd/rc632.h>
29 520784c7 (no author)
#include <os/dbgu.h>
30
#include <os/led.h>
31 c0a3cda1 (no author)
#include <os/pwm.h>
32
#include <os/tc_cdiv.h>
33 520784c7 (no author)
#include <os/pcd_enumerate.h>
34
#include <os/usb_handler.h>
35 b7e19ea8 (no author)
36 c0a3cda1 (no author)
#ifdef SSC
37
#include <pcd/ssc.h>
38
#endif
39
40 28eb4a57 laforge
#define RAH NULL
41
42 373c172a Harald Welte
static uint8_t force_100ask = 1;
43
static uint8_t mod_conductance = 0x3f;
44
static uint8_t cw_conductance = 0x3f;
45
static uint16_t duty_percent = 22;
46 b7e19ea8 (no author)
47
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
48 373c172a Harald Welte
static uint32_t pwm_freq[] = { 105937, 211875, 423750, 847500 };
49
static uint8_t pwm_freq_idx = 0;
50 b7e19ea8 (no author)
51
static void rc632_modulate_mfin()
52
{
53 28eb4a57 laforge
	opcd_rc632_reg_write(RAH, RC632_REG_TX_CONTROL, 
54 b7e19ea8 (no author)
			RC632_TXCTRL_MOD_SRC_MFIN|RC632_TXCTRL_TX2_INV|
55
			RC632_TXCTRL_TX1_RF_EN|RC632_TXCTRL_TX2_RF_EN);
56
}
57
58
/* (77/40) ^ EXPcsCfgCW */
59
/* 1, 1.925, 3.705625, 7.13332812 */
60
61
#define COND_MANT(x)	(x & 0x0f)
62
#define COND_EXP(x)	((x & 0x30) >> 4)
63
64 373c172a Harald Welte
static const uint16_t rsrel_expfact[] = { 1000, 1925, 3706, 7133 };
65 b7e19ea8 (no author)
66 373c172a Harald Welte
static uint32_t calc_conduct_rel(uint8_t inp)
67 b7e19ea8 (no author)
{
68 373c172a Harald Welte
	uint32_t cond_rel;
69 b7e19ea8 (no author)
70
	cond_rel = COND_MANT(inp) * rsrel_expfact[COND_EXP(inp)];
71
	cond_rel = cond_rel / 1000;
72
73
	return cond_rel;
74
}
75
76 373c172a Harald Welte
static const uint8_t rsrel_table[] = {
77 b7e19ea8 (no author)
	0, 16, 32, 48, 1, 17, 2, 3, 33, 18, 4, 5, 19, 6, 7, 49, 34, 20,
78
	8, 9, 21, 10, 11, 35, 22, 12, 13, 23, 14, 50, 36, 15, 24, 25,
79
	37, 26, 27, 51, 38, 28, 29, 39, 30, 52, 31, 40, 41, 53, 42, 43,
80
	54, 44, 45, 55, 46, 47, 56, 57, 58, 59, 60, 61, 62, 63 };
81
82 8e4fab42 (no author)
83 373c172a Harald Welte
static const uint16_t cdivs[] = { 128, 64, 32, 16 };
84 8e4fab42 (no author)
static int cdiv_idx = 0;
85
86 b7e19ea8 (no author)
static void help(void)
87
{
88 b6989b35 (no author)
	DEBUGPCR("o: decrease duty     p: increase duty\r\n"
89
		 "k: stop pwm          l: start pwn\r\n"
90
		 "n: decrease freq     m: incresae freq\r\n"
91
		 "v: decrease mod_cond b: increase mod_cond\r\n"
92 8e4fab42 (no author)
		 "g: decrease cw_cond  h: increase cw_cond");
93
	DEBUGPCR("u: PA23 const 1      y: PA23 const 0\r\n"
94 db8fe52b (no author)
		 "t: PA23 PWM0         f: toggle Force100ASK\r\n"
95
		 "{: decrease cdiv_idx }: increse cdiv idx");
96 b7e19ea8 (no author)
}
97
98
void _init_func(void)
99
{
100 b6989b35 (no author)
	DEBUGPCR("\r\n===> main_pwm <===\r\n");
101 b7e19ea8 (no author)
	help();
102
103
	rc632_init();
104
	DEBUGPCRF("turning on RF");
105
	rc632_turn_on_rf(RAH);
106
107
	/* switch PA17 (connected to MFIN on board) to input */
108
	AT91F_PIO_CfgInput(AT91C_BASE_PIOA, AT91C_PIO_PA17);
109
110 8e4fab42 (no author)
	DEBUGPCRF("Initializing carrier divider");
111
	tc_cdiv_init();
112 06d2a987 (no author)
113 8e4fab42 (no author)
	DEBUGPCRF("Initializing PWM");
114
	pwm_init();
115 b7e19ea8 (no author)
	pwm_freq_set(0, 105937);
116
	pwm_start(0);
117 06d2a987 (no author)
	pwm_duty_set_percent(0, 22);	/* 22% of 9.43uS = 2.07uS */
118 8e4fab42 (no author)
	rc632_modulate_mfin();
119
120 c0a3cda1 (no author)
#ifdef SSC
121 8e4fab42 (no author)
	DEBUGPCRF("Initializing SSC RX");
122
	ssc_rx_init();
123 c0a3cda1 (no author)
#endif
124 b7e19ea8 (no author)
}
125
126
int _main_dbgu(char key)
127
{
128
	switch (key) {
129
	case 'o':
130
		if (duty_percent >= 1)
131
			duty_percent--;
132
		pwm_duty_set_percent(0, duty_percent);
133
		break;
134
	case 'p':
135
		if (duty_percent <= 99)
136
			duty_percent++;
137
		pwm_duty_set_percent(0, duty_percent);
138
		break;
139
	case 'k':
140
		pwm_stop(0);
141
		break;
142
	case 'l':
143
		pwm_start(0);
144
		break;
145
	case 'n':
146
		if (pwm_freq_idx > 0) {
147
			pwm_freq_idx--;
148
			pwm_stop(0);
149
			pwm_freq_set(0, pwm_freq[pwm_freq_idx]);
150
			pwm_start(0);
151
			pwm_duty_set_percent(0, 22);	/* 22% of 9.43uS = 2.07uS */
152
		}
153
		break;
154
	case 'm':
155
		if (pwm_freq_idx < ARRAY_SIZE(pwm_freq)-1) {
156
			pwm_freq_idx++;
157
			pwm_stop(0);
158
			pwm_freq_set(0, pwm_freq[pwm_freq_idx]);
159
			pwm_start(0);
160
			pwm_duty_set_percent(0, 22);	/* 22% of 9.43uS = 2.07uS */
161
		}
162
		break;
163
	case 'u':
164 8e4fab42 (no author)
		DEBUGPCRF("PA23 output high");
165
		AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, AT91C_PIO_PA23);
166
		AT91F_PIO_SetOutput(AT91C_BASE_PIOA, AT91C_PIO_PA23);
167 b7e19ea8 (no author)
		break;
168
	case 'y':
169 8e4fab42 (no author)
		DEBUGPCRF("PA23 output low");
170
		AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, AT91C_PIO_PA23);
171
		AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, AT91C_PIO_PA23);
172 b7e19ea8 (no author)
		return 0;
173
		break;
174
	case 't':
175 8e4fab42 (no author)
		DEBUGPCRF("PA23 PeriphA (PWM)");
176
		AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, 0, AT91C_PA23_PWM0);
177 b7e19ea8 (no author)
		return 0;
178
		break;
179
	case 'f':
180
		DEBUGPCRF("%sabling Force100ASK", force_100ask ? "Dis":"En");
181
		if (force_100ask) {
182
			force_100ask = 0;
183 28eb4a57 laforge
			opcd_rc632_clear_bits(RAH, RC632_REG_TX_CONTROL,
184
					      RC632_TXCTRL_FORCE_100_ASK);
185 b7e19ea8 (no author)
		} else {
186
			force_100ask = 1;
187 28eb4a57 laforge
			opcd_rc632_set_bits(RAH, RC632_REG_TX_CONTROL,
188
					    RC632_TXCTRL_FORCE_100_ASK);
189 b7e19ea8 (no author)
		}
190
		return 0;
191
		break;
192
	case 'v':
193
		if (mod_conductance > 0) {
194
			mod_conductance--;
195 28eb4a57 laforge
			opcd_rc632_reg_write(RAH, RC632_REG_MOD_CONDUCTANCE,
196
					     rsrel_table[mod_conductance]);
197 b7e19ea8 (no author)
		}
198
		break;
199
	case 'b':
200
		if (mod_conductance < 0x3f) {
201
			mod_conductance++;
202 28eb4a57 laforge
			opcd_rc632_reg_write(RAH, RC632_REG_MOD_CONDUCTANCE,
203
					     rsrel_table[mod_conductance]);
204 b7e19ea8 (no author)
		}
205
		break;
206
	case 'g':
207
		if (cw_conductance > 0) {
208
			cw_conductance--;
209 28eb4a57 laforge
			opcd_rc632_reg_write(RAH, RC632_REG_CW_CONDUCTANCE, 
210
					     rsrel_table[cw_conductance]);
211 b7e19ea8 (no author)
		}
212
		break;
213
	case 'h':
214
		if (cw_conductance < 0x3f) {
215
			cw_conductance++;
216 28eb4a57 laforge
			opcd_rc632_reg_write(RAH, RC632_REG_CW_CONDUCTANCE, 
217
					     rsrel_table[cw_conductance]);
218 b7e19ea8 (no author)
		}
219
		break;
220
	case '?':
221
		help();
222
		return 0;
223
		break;
224 8e4fab42 (no author)
	case '<':
225
		tc_cdiv_phase_inc();
226
		break;
227
	case '>':
228
		tc_cdiv_phase_dec();
229
		break;
230
	case '{':
231
		if (cdiv_idx > 0)
232
			cdiv_idx--;
233
		tc_cdiv_set_divider(cdivs[cdiv_idx]);
234
		break;
235
	case '}':
236
		if (cdiv_idx < ARRAY_SIZE(cdivs)-1)
237
			cdiv_idx++;
238
		tc_cdiv_set_divider(cdivs[cdiv_idx]);
239
		break;
240 c0a3cda1 (no author)
#ifdef SSC
241 8e4fab42 (no author)
	case 's':
242
		ssc_rx_start();
243
		break;
244 db8fe52b (no author)
	case 'S':
245
		ssc_rx_stop();
246
		break;
247 c0a3cda1 (no author)
#endif
248 b7e19ea8 (no author)
	default:
249
		return -EINVAL;
250
	}
251
252 db8fe52b (no author)
	DEBUGPCR("pwm_freq=%u, duty_percent=%u, mod_cond=%u, cw_cond=%u tc_cdiv=%u", 
253
		 pwm_freq[pwm_freq_idx], duty_percent, mod_conductance, cw_conductance,
254
		 cdivs[cdiv_idx]);
255 b7e19ea8 (no author)
	
256
	return 0;
257
}
258
259 8e4fab42 (no author)
260 b7e19ea8 (no author)
void _main_func(void)
261
{
262 8e4fab42 (no author)
	/* first we try to get rid of pending to-be-sent stuff */
263
	usb_out_process();
264
265 8ac31009 Holger Hans Peter Freyther
	/* next we deal with incoming requests from USB EP1 (OUT) */
266 8e4fab42 (no author)
	usb_in_process();
267
268 9f204d3d (no author)
	/* try unthrottling sources since we now are [more] likely to
269
	 * have empty request contexts */
270 8e4fab42 (no author)
	rc632_unthrottle();
271 c0a3cda1 (no author)
#ifdef SSC
272 9f204d3d (no author)
	ssc_rx_unthrottle();
273 c0a3cda1 (no author)
#endif
274 8e4fab42 (no author)
275 b7e19ea8 (no author)
	led_toggle(2);
276
}
Add picture from clipboard (Maximum size: 48.8 MB)