Add simple test program to light up the transmitter at 434.550MHz
[fw/altos] / target / radio / radio.c
1 /*
2  * Copyright © 2008 Keith Packard <keithp@keithp.com>
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, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <stdint.h>
20
21 sfr at 0x80 P0;
22 sfr at 0x90 P1;
23 sfr at 0xA0 P2;
24 sfr at 0xC6 CLKCON;
25
26 sfr at 0xF1 PERCFG;
27 sfr at 0xF2 ADCCFG;
28 sfr at 0xF3 P0SEL;
29 sfr at 0xF4 P1SEL;
30 sfr at 0xF5 P2SEL;
31
32 sfr at 0xFD P0DIR;
33 sfr at 0xFE P1DIR;
34 sfr at 0xFF P2DIR;
35 sfr at 0x8F P0INP;
36 sfr at 0xF6 P1INP;
37 sfr at 0xF7 P2INP;
38
39 sfr at 0x89 P0IFG;
40 sfr at 0x8A P1IFG;
41 sfr at 0x8B P2IFG;
42
43 sfr at 0xD9 RFD;
44 sfr at 0xE9 RFIF;
45 sfr at 0xE1 RFST;
46
47 sfr at 0x88 TCON;
48
49 sbit at 0x89 RFTXRXIF;
50
51 #define TCON_RFTXRXIF   (1 << 1)
52
53 #define RFST_SFSTXON    0x00
54 #define RFST_SCAL       0x01
55 #define RFST_SRX        0x02
56 #define RFST_STX        0x03
57 #define RFST_SIDLE      0x04
58
59 __xdata __at (0xdf00) uint8_t RF[0x3c];
60
61 __xdata __at (0xdf2f) uint8_t RF_IOCFG2;
62 #define RF_IOCFG2_OFF   0x2f
63
64 __xdata __at (0xdf30) uint8_t RF_IOCFG1;
65 #define RF_IOCFG1_OFF   0x30
66
67 __xdata __at (0xdf31) uint8_t RF_IOCFG0;
68 #define RF_IOCFG0_OFF   0x31
69
70 __xdata __at (0xdf00) uint8_t RF_SYNC1;
71 #define RF_SYNC1_OFF    0x00
72
73 __xdata __at (0xdf01) uint8_t RF_SYNC0;
74 #define RF_SYNC0_OFF    0x01
75
76 __xdata __at (0xdf02) uint8_t RF_PKTLEN;
77 #define RF_PKTLEN_OFF   0x02
78
79 __xdata __at (0xdf03) uint8_t RF_PKTCTRL1;
80 #define RF_PKTCTRL1_OFF 0x03
81
82 __xdata __at (0xdf04) uint8_t RF_PKTCTRL0;
83 #define RF_PKTCTRL0_OFF 0x04
84
85 __xdata __at (0xdf05) uint8_t RF_ADDR;
86 #define RF_ADDR_OFF     0x05
87
88 __xdata __at (0xdf06) uint8_t RF_CHANNR;
89 #define RF_CHANNR_OFF   0x06
90
91 __xdata __at (0xdf07) uint8_t RF_FSCTRL1;
92 #define RF_FSCTRL1_OFF  0x07
93
94 #define RF_FSCTRL1_FREQ_IF_SHIFT        (0)
95
96 __xdata __at (0xdf08) uint8_t RF_FSCTRL0;
97 #define RF_FSCTRL0_OFF  0x08
98
99 #define RF_FSCTRL0_FREQOFF_SHIFT        (0)
100
101 __xdata __at (0xdf09) uint8_t RF_FREQ2;
102 #define RF_FREQ2_OFF    0x09
103
104 __xdata __at (0xdf0a) uint8_t RF_FREQ1;
105 #define RF_FREQ1_OFF    0x0a
106
107 __xdata __at (0xdf0b) uint8_t RF_FREQ0;
108 #define RF_FREQ0_OFF    0x0b
109
110 __xdata __at (0xdf0c) uint8_t RF_MDMCFG4;
111 #define RF_MDMCFG4_OFF  0x0c
112
113 #define RF_MDMCFG4_CHANBW_E_SHIFT       6
114 #define RF_MDMCFG4_CHANBW_M_SHIFT       4
115 #define RF_MDMCFG4_DRATE_E_SHIFT        0
116
117 __xdata __at (0xdf0d) uint8_t RF_MDMCFG3;
118 #define RF_MDMCFG3_OFF  0x0d
119
120 #define RF_MDMCFG3_DRATE_M_SHIFT        0
121
122 __xdata __at (0xdf0e) uint8_t RF_MDMCFG2;
123 #define RF_MDMCFG2_OFF  0x0e
124
125 #define RF_MDMCFG2_DEM_DCFILT_OFF       (1 << 7)
126
127 #define RF_MDMCFG2_MOD_FORMAT_MASK      (7 << 4)
128 #define RF_MDMCFG2_MOD_FORMAT_2_FSK     (0 << 4)
129 #define RF_MDMCFG2_MOD_FORMAT_GFSK      (1 << 4)
130 #define RF_MDMCFG2_MOD_FORMAT_ASK_OOK   (3 << 4)
131 #define RF_MDMCFG2_MOD_FORMAT_MSK       (7 << 4)
132
133 #define RF_MDMCFG2_MANCHESTER_EN        (1 << 3)
134
135 #define RF_MDMCFG2_SYNC_MODE_MASK               (0x7 << 0)
136 #define RF_MDMCFG2_SYNC_MODE_NONE               (0x0 << 0)
137 #define RF_MDMCFG2_SYNC_MODE_15_16              (0x1 << 0)
138 #define RF_MDMCFG2_SYNC_MODE_16_16              (0x2 << 0)
139 #define RF_MDMCFG2_SYNC_MODE_30_32              (0x3 << 0)
140 #define RF_MDMCFG2_SYNC_MODE_NONE_THRES         (0x4 << 0)
141 #define RF_MDMCFG2_SYNC_MODE_15_16_THRES        (0x5 << 0)
142 #define RF_MDMCFG2_SYNC_MODE_16_16_THRES        (0x6 << 0)
143 #define RF_MDMCFG2_SYNC_MODE_30_32_THRES        (0x7 << 0)
144
145 __xdata __at (0xdf0f) uint8_t RF_MDMCFG1;
146 #define RF_MDMCFG1_OFF  0x0f
147
148 #define RF_MDMCFG1_FEC_EN                       (1 << 7)
149
150 #define RF_MDMCFG1_NUM_PREAMBLE_MASK            (7 << 4)
151 #define RF_MDMCFG1_NUM_PREAMBLE_2               (0 << 4)
152 #define RF_MDMCFG1_NUM_PREAMBLE_3               (1 << 4)
153 #define RF_MDMCFG1_NUM_PREAMBLE_4               (2 << 4)
154 #define RF_MDMCFG1_NUM_PREAMBLE_6               (3 << 4)
155 #define RF_MDMCFG1_NUM_PREAMBLE_8               (4 << 4)
156 #define RF_MDMCFG1_NUM_PREAMBLE_12              (5 << 4)
157 #define RF_MDMCFG1_NUM_PREAMBLE_16              (6 << 4)
158 #define RF_MDMCFG1_NUM_PREAMBLE_24              (7 << 4)
159
160 #define RF_MDMCFG1_CHANSPC_E_MASK               (3 << 0)
161 #define RF_MDMCFG1_CHANSPC_E_SHIFT              (0)
162
163 __xdata __at (0xdf10) uint8_t RF_MDMCFG0;
164 #define RF_MDMCFG0_OFF  0x10
165
166 #define RF_MDMCFG0_CHANSPC_M_SHIFT              (0)
167
168 __xdata __at (0xdf11) uint8_t RF_DEVIATN;
169 #define RF_DEVIATN_OFF  0x11
170
171 #define RF_DEVIATN_DEVIATION_E_SHIFT            4
172 #define RF_DEVIATN_DEVIATION_M_SHIFT            0
173
174 __xdata __at (0xdf12) uint8_t RF_MCSM2;
175 #define RF_MCSM2_OFF    0x12
176
177 __xdata __at (0xdf13) uint8_t RF_MCSM1;
178 #define RF_MCSM1_OFF    0x13
179
180 __xdata __at (0xdf14) uint8_t RF_MCSM0;
181 #define RF_MCSM0_OFF    0x14
182
183 __xdata __at (0xdf15) uint8_t RF_FOCCFG;
184 #define RF_FOCCFG_OFF   0x15
185
186 __xdata __at (0xdf16) uint8_t RF_BSCFG;
187 #define RF_BSCFG_OFF    0x16
188
189 __xdata __at (0xdf17) uint8_t RF_AGCCTRL2;
190 #define RF_AGCCTRL2_OFF 0x17
191
192 __xdata __at (0xdf18) uint8_t RF_AGCCTRL1;
193 #define RF_AGCCTRL1_OFF 0x18
194
195 __xdata __at (0xdf19) uint8_t RF_AGCCTRL0;
196 #define RF_AGCCTRL0_OFF 0x19
197
198 __xdata __at (0xdf1a) uint8_t RF_FREND1;
199 #define RF_FREND1_OFF   0x1a
200
201 #define RF_FREND1_LNA_CURRENT_SHIFT             6
202 #define RF_FREND1_LNA2MIX_CURRENT_SHIFT         4
203 #define RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT    2
204 #define RF_FREND1_MIX_CURRENT_SHIFT             0
205
206 __xdata __at (0xdf1b) uint8_t RF_FREND0;
207 #define RF_FREND0_OFF   0x1b
208
209 #define RF_FREND0_LODIV_BUF_CURRENT_TX_MASK     (0x3 << 4)
210 #define RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT    4
211 #define RF_FREND0_PA_POWER_MASK                 (0x7)
212 #define RF_FREND0_PA_POWER_SHIFT                0
213
214 __xdata __at (0xdf1c) uint8_t RF_FSCAL3;
215 #define RF_FSCAL3_OFF   0x1c
216
217 __xdata __at (0xdf1d) uint8_t RF_FSCAL2;
218 #define RF_FSCAL2_OFF   0x1d
219
220 __xdata __at (0xdf1e) uint8_t RF_FSCAL1;
221 #define RF_FSCAL1_OFF   0x1e
222
223 __xdata __at (0xdf1f) uint8_t RF_FSCAL0;
224 #define RF_FSCAL0_OFF   0x1f
225
226 __xdata __at (0xdf23) uint8_t RF_TEST2;
227 #define RF_TEST2_OFF    0x23
228
229 #define RF_TEST2_NORMAL_MAGIC           0x88
230 #define RF_TEST2_RX_LOW_DATA_RATE_MAGIC 0x81
231
232 __xdata __at (0xdf24) uint8_t RF_TEST1;
233 #define RF_TEST1_OFF    0x24
234
235 #define RF_TEST1_TX_MAGIC               0x31
236 #define RF_TEST1_RX_LOW_DATA_RATE_MAGIC 0x35
237
238 __xdata __at (0xdf25) uint8_t RF_TEST0;
239 #define RF_TEST0_OFF    0x25
240
241 #define RF_TEST0_7_2_MASK               (0xfc)
242 #define RF_TEST0_VCO_SEL_CAL_EN         (1 << 1)
243 #define RF_TEST0_0_MASK                 (1)
244
245 /* These are undocumented, and must be computed
246  * using the provided tool.
247  */
248 __xdata __at (0xdf27) uint8_t RF_PA_TABLE7;
249 #define RF_PA_TABLE7_OFF        0x27
250
251 __xdata __at (0xdf28) uint8_t RF_PA_TABLE6;
252 #define RF_PA_TABLE6_OFF        0x28
253
254 __xdata __at (0xdf29) uint8_t RF_PA_TABLE5;
255 #define RF_PA_TABLE5_OFF        0x29
256
257 __xdata __at (0xdf2a) uint8_t RF_PA_TABLE4;
258 #define RF_PA_TABLE4_OFF        0x2a
259
260 __xdata __at (0xdf2b) uint8_t RF_PA_TABLE3;
261 #define RF_PA_TABLE3_OFF        0x2b
262
263 __xdata __at (0xdf2c) uint8_t RF_PA_TABLE2;
264 #define RF_PA_TABLE2_OFF        0x2c
265
266 __xdata __at (0xdf2d) uint8_t RF_PA_TABLE1;
267 #define RF_PA_TABLE1_OFF        0x2d
268
269 __xdata __at (0xdf2e) uint8_t RF_PA_TABLE0;
270 #define RF_PA_TABLE0_OFF        0x2e
271
272 __xdata __at (0xdf36) uint8_t RF_PARTNUM;
273 #define RF_PARTNUM_OFF  0x36
274
275 __xdata __at (0xdf37) uint8_t RF_VERSION;
276 #define RF_VERSION_OFF  0x37
277
278 __xdata __at (0xdf38) uint8_t RF_FREQEST;
279 #define RF_FREQEST_OFF  0x38
280
281 __xdata __at (0xdf39) uint8_t RF_LQI;
282 #define RF_LQI_OFF      0x39
283
284 #define RF_LQI_CRC_OK                   (1 << 7)
285 #define RF_LQI_LQI_EST_MASK             (0x7f)
286
287 __xdata __at (0xdf3a) uint8_t RF_RSSI;
288 #define RF_RSSI_OFF     0x3a
289
290 __xdata __at (0xdf3b) uint8_t RF_MARCSTATE;
291 #define RF_MARCSTATE_OFF        0x3b
292
293 #define RF_MARCSTATE_MASK               0x0f
294 #define RF_MARCSTATE_SLEEP              0x00
295 #define RF_MARCSTATE_IDLE               0x01
296 #define RF_MARCSTATE_VCOON_MC           0x03
297 #define RF_MARCSTATE_REGON_MC           0x04
298 #define RF_MARCSTATE_MANCAL             0x05
299 #define RF_MARCSTATE_VCOON              0x06
300 #define RF_MARCSTATE_REGON              0x07
301 #define RF_MARCSTATE_STARTCAL           0x08
302 #define RF_MARCSTATE_BWBOOST            0x09
303 #define RF_MARCSTATE_FS_LOCK            0x0a
304 #define RF_MARCSTATE_IFADCON            0x0b
305 #define RF_MARCSTATE_ENDCAL             0x0c
306 #define RF_MARCSTATE_RX                 0x0d
307 #define RF_MARCSTATE_RX_END             0x0e
308 #define RF_MARCSTATE_RX_RST             0x0f
309 #define RF_MARCSTATE_TXRX_SWITCH        0x10
310 #define RF_MARCSTATE_RX_OVERFLOW        0x11
311 #define RF_MARCSTATE_FSTXON             0x12
312 #define RF_MARCSTATE_TX                 0x13
313 #define RF_MARCSTATE_TX_END             0x14
314 #define RF_MARCSTATE_RXTX_SWITCH        0x15
315 #define RF_MARCSTATE_TX_UNDERFLOW       0x16
316
317
318 __xdata __at (0xdf3c) uint8_t RF_PKTSTATUS;
319 #define RF_PKTSTATUS_OFF        0x3c
320
321 #define RF_PKTSTATUS_CRC_OK             (1 << 7)
322 #define RF_PKTSTATUS_CS                 (1 << 6)
323 #define RF_PKTSTATUS_PQT_REACHED        (1 << 5)
324 #define RF_PKTSTATUS_CCA                (1 << 4)
325 #define RF_PKTSTATUS_SFD                (1 << 3)
326
327 __xdata __at (0xdf3d) uint8_t RF_VCO_VC_DAC;
328 #define RF_VCO_VC_DAC_OFF       0x3d
329
330 #define nop()   _asm nop _endasm;
331
332 void
333 delay (unsigned char n)
334 {
335         unsigned char i = 0;
336
337         n <<= 1;
338         while (--n != 0)
339                 while (--i != 0)
340                         nop();
341 }
342
343 void
344 tone (unsigned char n, unsigned char m)
345 {
346         unsigned char   i = 0;
347         while (--m != 0) {
348                 i = 128;
349                 while (--i != 0) {
350                         P2 = 0xff;
351                         delay(n);
352                         P2 = 0xfe;
353                         delay(n);
354                 }
355         }
356 }
357
358 void
359 high() {
360         tone(1, 2);
361 }
362
363 void
364 low() {
365         tone(2, 1);
366 }
367
368 /* Values from SmartRF® Studio for:
369  *
370  * Deviation:   20.507812 kHz
371  * Datarate:    38.360596 kBaud
372  * Modulation:  GFSK
373  * RF Freq:     434.549927 MHz
374  * Channel:     99.975586 kHz
375  * Channel:     0
376  * RX filter:   93.75 kHz
377  */
378
379 /*
380  * For 434.550MHz, the frequency value is:
381  *
382  * 434.550e6 / (24e6 / 2**16) = 1186611.2
383  */
384
385 #define FREQ_CONTROL    1186611
386
387 /*
388  * For IF freq of 140.62kHz, the IF value is:
389  *
390  * 140.62e3 / (24e6 / 2**10) = 6
391  */
392
393 #define IF_FREQ_CONTROL 6
394
395 /*
396  * For channel bandwidth of 93.75 kHz, the CHANBW_E and CHANBW_M values are
397  *
398  * BW = 24e6 / (8 * (4 + M) * 2 ** E)
399  *
400  * So, M = 0 and E = 3
401  */
402
403 #define CHANBW_M        0
404 #define CHANBW_E        3
405
406 /*
407  * For a symbol rate of 38360kBaud, the DRATE_E and DRATE_M values are:
408  *
409  * R = (256 + M) * 2** E * 24e6 / 2**28
410  *
411  * So M is 163 and E is 10
412  */
413
414 #define DRATE_E         10
415 #define DRATE_M         163
416
417 #define PACKET_LEN      128
418
419 static __code uint8_t radio_setup[] = {
420         RF_PA_TABLE7_OFF,       0x60,
421         RF_PA_TABLE6_OFF,       0x60,
422         RF_PA_TABLE5_OFF,       0x60,
423         RF_PA_TABLE4_OFF,       0x60,
424         RF_PA_TABLE3_OFF,       0x60,
425         RF_PA_TABLE2_OFF,       0x60,
426         RF_PA_TABLE1_OFF,       0x60,
427         RF_PA_TABLE0_OFF,       0x60,
428
429         RF_FREQ2_OFF,           FREQ_CONTROL >> 16,
430         RF_FREQ1_OFF,           FREQ_CONTROL >> 8,
431         RF_FREQ0_OFF,           FREQ_CONTROL >> 0,
432         
433         RF_FSCTRL1_OFF,         (IF_FREQ_CONTROL << RF_FSCTRL1_FREQ_IF_SHIFT),
434         RF_FSCTRL0_OFF,         (0 << RF_FSCTRL0_FREQOFF_SHIFT),
435
436         RF_MDMCFG4_OFF,         ((CHANBW_E << RF_MDMCFG4_CHANBW_E_SHIFT) |
437                                  (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
438                                  (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
439         RF_MDMCFG3_OFF,         (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
440         RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
441                                  RF_MDMCFG2_MOD_FORMAT_GFSK |
442                                  RF_MDMCFG2_SYNC_MODE_NONE),
443         RF_MDMCFG1_OFF,         (RF_MDMCFG1_NUM_PREAMBLE_4 |
444                                  (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
445         RF_MDMCFG0_OFF,         (17 << RF_MDMCFG0_CHANSPC_M_SHIFT),
446
447         RF_CHANNR_OFF,          0,
448
449         RF_DEVIATN_OFF,         ((3 << RF_DEVIATN_DEVIATION_E_SHIFT) |
450                                  (6 << RF_DEVIATN_DEVIATION_M_SHIFT)),
451
452         /* SmartRF says set LODIV_BUF_CURRENT_TX to 0
453          * And, we're not using power ramping, so use PA_POWER 0
454          */
455         RF_FREND0_OFF,          ((1 << RF_FREND0_LODIV_BUF_CURRENT_TX_SHIFT) |
456                                  (0 << RF_FREND0_PA_POWER_SHIFT)),
457
458         RF_FREND1_OFF,          ((1 << RF_FREND1_LNA_CURRENT_SHIFT) |
459                                  (1 << RF_FREND1_LNA2MIX_CURRENT_SHIFT) |
460                                  (1 << RF_FREND1_LODIV_BUF_CURRENT_RX_SHIFT) |
461                                  (2 << RF_FREND1_MIX_CURRENT_SHIFT)),
462         RF_MCSM0_OFF,           0x18,
463         RF_FOCCFG_OFF,          0x16,
464         RF_BSCFG_OFF,           0x6C,
465
466         RF_AGCCTRL2_OFF,        0x43,
467         RF_AGCCTRL1_OFF,        0x40,
468         RF_AGCCTRL0_OFF,        0x91,
469
470         RF_FSCAL3_OFF,          0xE9,
471         RF_FSCAL2_OFF,          0x0A,
472         RF_FSCAL1_OFF,          0x00,
473         RF_FSCAL0_OFF,          0x1F,
474
475         RF_TEST2_OFF,           0x88,
476         RF_TEST1_OFF,           0x31,
477         RF_TEST0_OFF,           0x09,
478
479         /* default sync values */
480         RF_SYNC1_OFF,           0xD3,
481         RF_SYNC0_OFF,           0x91,
482         
483         /* max packet length */
484         RF_PKTLEN_OFF,          PACKET_LEN,
485
486         RF_PKTCTRL1_OFF,        0x04,
487         RF_PKTCTRL0_OFF,        0x00,
488         RF_ADDR_OFF,            0x00,
489         RF_MCSM2_OFF,           0x07,
490         RF_MCSM1_OFF,           0x30,
491         
492         RF_IOCFG2_OFF,          0x00,
493         RF_IOCFG1_OFF,          0x00,
494         RF_IOCFG0_OFF,          0x00,
495 };
496
497 void
498 radio_init() {
499         uint8_t i;
500         for (i = 0; i < sizeof (radio_setup); i += 2)
501                 RF[radio_setup[i]] = radio_setup[i+1];
502 }
503
504 main ()
505 {
506         CLKCON = 0;
507         /* Set P2_0 to output */
508         radio_init ();
509         delay(100);
510         RFST = RFST_SIDLE;
511         delay(100);
512         RFST = RFST_STX;
513         delay(100);
514         for (;;);
515 #if 0
516         for (;;) {
517                 uint8_t i;
518                 for (i = 0; i < PACKET_LEN; i++) {
519                         while (!RFTXRXIF);
520                         RFTXRXIF = 0;
521                         RFD = 0x55;
522                 }
523         }
524 #endif
525 }