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