1 /* $Id: rfm12.c,v 1.2 2010/07/24 20:55:48 simimeie Exp $
2 * Functions for communicating with the rfm12(b) module
8 /* Unfortunately, the manufacturer documentation for chip and module is
9 * almost unreadable crap.
10 * This one is better: http://www.mikrocontroller.net/articles/RFM12
12 /* Note: the signal is inverted, thus pulling this high DEselects the chip */
13 #define spi_ss_hi() { PORTC |= _BV(0); }
14 /* Consequently, this SELECTS the chip */
15 #define spi_ss_lo() { PORTC &= (uint8_t)~_BV(0); }
17 /* write and (at the same time) read a word from RFM12.
18 * The module uses 16 bit commands and replies that are
19 * synchronous to the command - except for the status read.
20 * Note: This does not handle chip select! */
21 static uint16_t rfm12_spi_wrword(uint16_t v) {
23 /* Start transmission */
25 /* Wait for transmission complete */
26 while ((SPSR & _BV(SPIF)) == 0) {
28 res = (uint16_t)(SPDR) << 8;
30 /* Wait for transmission complete */
31 while ((SPSR & _BV(SPIF)) == 0) {
37 void rfm12_sendcommand(uint16_t cmd) {
39 rfm12_spi_wrword(cmd);
43 uint32_t rfm12_readstatus(void) {
46 res = (uint32_t)rfm12_spi_wrword(0x0000) << 16;
47 res |= rfm12_spi_wrword(0x0000);
52 void rfm12_init(void) {
53 /* Set MOSI, SCK and SS output, MISO input */
54 /* Frickel Alert: Also set PB2 output. It is not used, but noise on the
55 * pin could reset our SPI mode to slave (!!!) if it is left as input. */
56 DDRB |= _BV(3) | _BV(5) | _BV(2);
58 DDRB &= (uint8_t)~_BV(4);
60 #if (CPUFREQ <= 10000000UL)
61 /* Enable SPI, Master, set clock rate fck/4.
62 * This works as long as our own clockrate is below 10 MHz - because
63 * 2.5 MHz is the maximum the rfm12b can do. */
64 SPCR |= _BV(SPE) | _BV(MSTR);
66 /* For higher clock rates set fck/16. */
67 SPCR |= _BV(SPE) | _BV(MSTR) | _BV(SPR0);
69 /* Now send some initialization commands. */
70 /* Mostly taken over from http://www.joachim-neu.de/post/70/rfm12b-868/
71 * Seems to be mostly black magic anyways. */
72 rfm12_sendcommand(0x80E7); /* EL, EF, 868band, 12.0pF */
73 rfm12_sendcommand(0x8219); /* !er, !ebb, !ET, ES, EX, !eb, !ew, DC */
74 /* Frequency setting: 0xAnnn; the 12 nnn-bits of value are
75 * calculated like this: v = ((freq / 20) - 43) * 4000
77 rfm12_sendcommand(0xA7BC); /* 869,900 MHz */
78 rfm12_sendcommand(0xC647); /* 4.8kbps FIXME? */
79 rfm12_sendcommand(0x94C0); /* VDI, FAST, 67kHz, 0dBm, -103dBm */
80 rfm12_sendcommand(0xC2AC); /* AL, !ml, DIG, DQD4 */
81 rfm12_sendcommand(0xCA81);//FIFO8,SYNC,!ff,DR
82 rfm12_sendcommand(0xCED4);//SYNC=2DD4;
83 rfm12_sendcommand(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN
84 rfm12_sendcommand(0x9820);// !mp,45kHz,MAX OUT*/
85 rfm12_sendcommand(0xCC77);//OB1,OB0, LPX,!ddy,DDIT,BW0
86 rfm12_sendcommand(0xE000);//NOT USE
87 rfm12_sendcommand(0xC800);//NOT USE
88 rfm12_sendcommand(0xC040);//1.66MHz,2.2V