- add eepromdata.h
[moodlight.git] / rfm12.c
diff --git a/rfm12.c b/rfm12.c
index 01297e492425a23d99313d1a6ab3a275ccffc78f..30a2a0e0292fcdcfe870222fad96bf76427628f3 100644 (file)
--- 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
  */
 
 /* 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
 }
This page took 0.054669 seconds and 4 git commands to generate.