Source file: /~heha/mb-iwp/FlyStick/Firmware.zip/AccessPoint/rfm12.c

/*******************
 * Funktransceiver *
 *******************/
#include "rfm12.h"
#include <avr/io.h>
#include <avr/pgmspace.h>

/* Empirisches Kanalraster (12 Kanäle im Abstand 145 kHz, ∆F = 58)
Kanal	F	Anfang	Ende
1	1237	433,05	433,195
2	1295	433,195	433,34
3	1353	433,34	433,485
4	1411	433,485	433.63
5	1469	433.63	433.775
6	1527	433.775	433.92
7	1585	433.92	434.065
8	1643	434.065	434.21
9	1701	434.21	434.355
10	1759	434.355	434.5
11	1817	434.5	434.645
12	1991	434.645	434.79

SPI __    (CPOL=CPHA=0)                        ___
!SS   \__________________________   __________/
            ___     ___     ___        ___
SCK _______/   \___/   \___/   \_   __/   \_______
    ___ _______ _______ _______ _   ______________
MOSI___X_______X_______X_______X_   ______________
    ____ _______ _______ _______    ______________
MISO____X__↑____X__↑____X__↑____X   __↑___________
*/

// Daten-WORD „austauschen“. Blockiert 2,6 µs
WORD rf_xfer(WORD data) {
 PORTB&=~0x04;		// !SS aktivieren
 asm volatile("out %0,%B1" :: "I" (_SFR_IO_ADDR(SPDR)), "r" (data));
 while (!(SPSR&1<<SPIF));	// warten bis High-Byte fertig
 asm volatile("in %B0,%2" : "=r" (data): "0"(data), "I" (_SFR_IO_ADDR(SPDR)));
 asm volatile("out %0,%A1" :: "I" (_SFR_IO_ADDR(SPDR)), "r" (data));
 while (!(SPSR&1<<SPIF));	// warten bis Low-Byte fertig
 asm volatile("in %A0,%2" : "=r" (data): "0"(data), "I" (_SFR_IO_ADDR(SPDR)));
 PORTB|=0x04;		// !SS deaktivieren
 return data;
}

BYTE txch=1;	// Sende-Kanal (1..12), 0 = keine Belegung
BYTE rxch=1;	// Empfangs-Kanal (unterschiedlich während Frequenz-Hopping)

PROGMEM static const WORD rf_inittab[]={
 0x8208,	// (2) Quarz reaktivieren
 0x80D7,	// (1) FIFO benutzen, 433-MHz-Band, 12 pF Ballastkapazität
 0xC2AC,	// (6) Datenfilter: Auto-Lock setzen (??)
 0xCA81,	// (7) FIFO-Modus: Reset-Modus (??)
 0x94C0,	// (5) VDI-Ausgang, Bandbreite 67 kHz, maximale Empfindlichkeit
 0x9820,	// (10) Hub ∆f = ± 45 kHz, Ausgangsleistung = 0 dB (maximal)
 0xC611,	// (4) Datenrate ≈ 19,2 kbit/s (keine Orthogonalität mit η = 4,68)
// 0xE000,	// (12) kein WakeUpTimer (ist sowieso aus!)
// 0xC800,	// (13) kein LowDutyCycle (ist sowieso aus!)
// 0xC4F7,	// (9) AFC
};

// Kanal (Mittenfrequenz) setzen
void rf_setch(BYTE ch) {
 rf_xfer(0xA000|1237+(ch-1)*58);	// (3) Mittenfrequenz setzen
}

// Initialisierungssequenz
void rf_init() {
 int i;
 for (i=0; i<elemof(rf_inittab); i++) {
  rf_xfer(pgm_read_word(rf_inittab+i));
 }
 rf_setch(txch);
}

// Modusumschaltung. Bit 0 = Sender EIN, Bit 1 = Empfänger EIN
void rf_mode(BYTE sw) {
 rf_xfer(0xCA81);	// (7) Rahmensynchronwort(rest) löschen
 if (sw&2) {
  rf_xfer(sw&1 ? 0x82F9 : 0x82C9);	// (2)
  rf_xfer(0xCA83);	// FIFO freigeben für Rahmensynchronwort (2DD4h)
 }else{
  rf_xfer(sw&1 ? 0x8239 : 0x8209);	// (2)
 }
}

BYTE rf_tx(BYTE b) {
 while (PINB&1);	// warte bis !IRQ = low
 return rf_xfer(0xB800|b);	// (11)
}


Detected encoding: UTF-80