X-Git-Url: http://git.rrze.uni-erlangen.de/gitweb/?p=moodlight.git;a=blobdiff_plain;f=rfm12.c;h=30a2a0e0292fcdcfe870222fad96bf76427628f3;hp=01297e492425a23d99313d1a6ab3a275ccffc78f;hb=ff29bc2b3dbad7885497cfd9aa2b3aa98cc4ebb0;hpb=dfbc0cefbdd8cdc0aecbad960c804cb1128d5b32 diff --git a/rfm12.c b/rfm12.c index 01297e4..30a2a0e 100644 --- a/rfm12.c +++ b/rfm12.c @@ -1,4 +1,4 @@ -/* $Id: rfm12.c,v 1.1 2010/07/11 09:09:26 simimeie Exp $ +/* $Id: rfm12.c,v 1.2 2010/07/24 20:55:48 simimeie Exp $ * Functions for communicating with the rfm12(b) module */ @@ -14,30 +14,76 @@ /* Consequently, this SELECTS the chip */ #define spi_ss_lo() { PORTC &= (uint8_t)~_BV(0); } -static void spi_sendbyte(uint8_t v) { +/* write and (at the same time) read a word from RFM12. + * The module uses 16 bit commands and replies that are + * synchronous to the command - except for the status read. + * Note: This does not handle chip select! */ +static uint16_t rfm12_spi_wrword(uint16_t v) { + uint16_t res; /* Start transmission */ - SPDR = v; + SPDR = v >> 8; /* Wait for transmission complete */ while ((SPSR & _BV(SPIF)) == 0) { } -} - -static uint8_t spi_readbyte() { - SPDR = 0x00; /* Dummy write */ + res = (uint16_t)(SPDR) << 8; + SPDR = v & 0xff; + /* Wait for transmission complete */ while ((SPSR & _BV(SPIF)) == 0) { } - /* Return Data Register */ - return SPDR; + res |= SPDR & 0xff; + return res; +} + +void rfm12_sendcommand(uint16_t cmd) { + spi_ss_lo(); + rfm12_spi_wrword(cmd); + spi_ss_hi(); +} + +uint32_t rfm12_readstatus(void) { + uint32_t res; + spi_ss_lo(); + res = (uint32_t)rfm12_spi_wrword(0x0000) << 16; + res |= rfm12_spi_wrword(0x0000); + spi_ss_hi(); + return res; } void rfm12_init(void) { /* Set MOSI, SCK and SS output, MISO input */ - DDRB |= _BV(3) | _BV(5); + /* Frickel Alert: Also set PB2 output. It is not used, but noise on the + * pin could reset our SPI mode to slave (!!!) if it is left as input. */ + DDRB |= _BV(3) | _BV(5) | _BV(2); DDRC |= _BV(0); DDRB &= (uint8_t)~_BV(4); spi_ss_hi(); +#if (CPUFREQ <= 10000000UL) /* Enable SPI, Master, set clock rate fck/4. * This works as long as our own clockrate is below 10 MHz - because * 2.5 MHz is the maximum the rfm12b can do. */ SPCR |= _BV(SPE) | _BV(MSTR); +#else + /* For higher clock rates set fck/16. */ + SPCR |= _BV(SPE) | _BV(MSTR) | _BV(SPR0); +#endif /* CPUFREQ */ + /* Now send some initialization commands. */ + /* Mostly taken over from http://www.joachim-neu.de/post/70/rfm12b-868/ + * Seems to be mostly black magic anyways. */ + rfm12_sendcommand(0x80E7); /* EL, EF, 868band, 12.0pF */ + rfm12_sendcommand(0x8219); /* !er, !ebb, !ET, ES, EX, !eb, !ew, DC */ + /* Frequency setting: 0xAnnn; the 12 nnn-bits of value are + * calculated like this: v = ((freq / 20) - 43) * 4000 + */ + rfm12_sendcommand(0xA7BC); /* 869,900 MHz */ + rfm12_sendcommand(0xC647); /* 4.8kbps FIXME? */ + rfm12_sendcommand(0x94C0); /* VDI, FAST, 67kHz, 0dBm, -103dBm */ + rfm12_sendcommand(0xC2AC); /* AL, !ml, DIG, DQD4 */ + rfm12_sendcommand(0xCA81);//FIFO8,SYNC,!ff,DR + rfm12_sendcommand(0xCED4);//SYNC=2DD4; + rfm12_sendcommand(0xC483);//@PWR,NO RSTRIC,!st,!fi,OE,EN + rfm12_sendcommand(0x9820);// !mp,45kHz,MAX OUT*/ + rfm12_sendcommand(0xCC77);//OB1,OB0, LPX,!ddy,DDIT,BW0 + rfm12_sendcommand(0xE000);//NOT USE + rfm12_sendcommand(0xC800);//NOT USE + rfm12_sendcommand(0xC040);//1.66MHz,2.2V }