- add eepromdata.h
authorsimimeie <simimeie>
Sat, 24 Jul 2010 20:55:48 +0000 (20:55 +0000)
committersimimeie <simimeie>
Sat, 24 Jul 2010 20:55:48 +0000 (20:55 +0000)
- add rfm12 module to makefile
- preliminary initialization for rfm12
- console command 'rfstatus'
- display of last reset reason moved to console (so it displays
  properly now).

Makefile
console.c
eepromdata.h [new file with mode: 0644]
main.c
rfm12.c
rfm12.h

index 5de17a8cd6dbfbaea39166d8778fbc9c288e0111..acb33a2aee1a954d7aaeece7872dfae9e26ca809 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3 2010/06/27 22:19:15 simimeie Exp $
+# $Id: Makefile,v 1.4 2010/07/24 20:56:28 simimeie Exp $
 # Makefile for HaWo Moodlight
 
 CC     = avr-gcc
@@ -27,7 +27,7 @@ CPUFREQ               = 8000000UL
 # desired baudrate of serial debug console
 BAUDRATE       = 9600UL
 
-SRCS   = console.c ledpwm.c ircontrol.c timers.c main.c
+SRCS   = console.c ledframing.c ledpwm.c ircontrol.c timers.c main.c rfm12.c
 PROG   = moodlight
 
 # compiler flags
index 87f20434bc2d8fcf998dd787dd49ed3ca98f0bf3..8dff9f4b72ecef5c2d034fd52f6e9bd6657f5a0e 100644 (file)
--- a/console.c
+++ b/console.c
@@ -1,4 +1,4 @@
-/* $Id: console.c,v 1.3 2010/06/30 19:40:49 simimeie Exp $
+/* $Id: console.c,v 1.4 2010/07/24 20:55:48 simimeie Exp $
  * Functions for a serial console.
  */
 
@@ -6,11 +6,13 @@
 #include <avr/interrupt.h>
 #include <avr/pgmspace.h>
 #include <avr/version.h>
+#include <avr/wdt.h>
 #include <util/delay.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "console.h"
 #include "ledpwm.h"
+#include "rfm12.h"
 
 /* PD0 is RXD, PD1 is TXD, but we don't need to address them manually */
 
@@ -38,6 +40,19 @@ static prog_uint8_t WELCOMEMSG[] = "\r\n"\
                                   "\r\nSoftware Version 0.1, Compiled " __DATE__ " " __TIME__;
 static prog_uint8_t PROMPT[] = "\r\nroot@moodlight# ";
 
+uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
+
+/* This is needed to recover from a watchdog reset, as the watchdog
+ * stays active after the reset.
+ * The variable is just to make the reason of the last reset accessible
+ * later. */
+void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init3")));
+void get_mcusr(void) {
+  mcusr_mirror = MCUSR;
+  MCUSR = 0;
+  wdt_disable();
+}
+
 /* Handler for TXC (TX Complete) IRQ */
 ISR(USART_TX_vect) {
        if (outputhead == outputtail) { /* Nothing more to send! */
@@ -177,6 +192,19 @@ void console_init(void) {
        /* Enable Send and Receive and IRQs */
        UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(TXCIE0) | _BV(RXCIE0);
        console_printpgm_noirq_P(WELCOMEMSG);
+        console_printpgm_noirq_P(PSTR("\r\nNOTE: last reset was from"));
+       if (mcusr_mirror & _BV(WDRF)) {
+               console_printpgm_noirq_P(PSTR(" WatchdogTimer"));
+       }
+       if (mcusr_mirror & _BV(BORF)) {
+               console_printpgm_noirq_P(PSTR(" Brownout"));
+       }
+       if (mcusr_mirror & _BV(EXTRF)) {
+               console_printpgm_noirq_P(PSTR(" ExternalReset"));
+       }
+       if (mcusr_mirror & _BV(PORF)) {
+               console_printpgm_noirq_P(PSTR(" PowerOn"));
+       }
        console_printpgm_noirq_P(PROMPT);
        return;
 }
@@ -263,6 +291,7 @@ ISR(USART_RX_vect) {
                        console_printpgm_noirq_P(PSTR("\r\n showpins [x]     shows the avrs inputpins"));
                        console_printpgm_noirq_P(PSTR("\r\n status           show status / counters"));
                        console_printpgm_noirq_P(PSTR("\r\n [rgb] n          sets the brightness of the red / green / blue LED to n"));
+                       console_printpgm_noirq_P(PSTR("\r\n rfstatus         show RFM12 status"));
                        /* console_printpgm_noirq_P(PSTR("\r\n save             saves settings to EEPROM")); */
                } else if (strcmp_P(inputbuf, PSTR("motd")) == 0) {
                        console_printpgm_noirq_P(WELCOMEMSG);
@@ -329,28 +358,27 @@ ISR(USART_RX_vect) {
                        console_printhex8_noirq(ledpwm_bl);
                        console_printpgm_noirq_P(PSTR(", brightness = "));
                        console_printhex8_noirq(ledpwm_bri);
-                       /*console_printpgm_noirq_P(CRLF);*/
                } else if (strncmp_P(inputbuf, PSTR("r "), 2) == 0) {
                        uint8_t v;
                        v = strtoul(&inputbuf[2], NULL, 0);
                        ledpwm_re = v;
                        ledpwm_setled(LEDPWM_REDLED, (((uint16_t)ledpwm_re * ledpwm_bri) / 255));
-                       console_printpgm_P(PSTR("RED value set to 0x"));
-                       console_printhex8(v);
+                       console_printpgm_noirq_P(PSTR("RED value set to 0x"));
+                       console_printhex8_noirq(v);
                } else if (strncmp_P(inputbuf, PSTR("g "), 2) == 0) {
                        uint8_t v;
                        v = strtoul(&inputbuf[2], NULL, 0);
                        ledpwm_gr = v;
                        ledpwm_setled(LEDPWM_GREENLED, (((uint16_t)ledpwm_gr * ledpwm_bri) / 255));
-                       console_printpgm_P(PSTR("GREEN value set to 0x"));
-                       console_printhex8(v);
+                       console_printpgm_noirq_P(PSTR("GREEN value set to 0x"));
+                       console_printhex8_noirq(v);
                } else if (strncmp_P(inputbuf, PSTR("b "), 2) == 0) {
                        uint8_t v;
                        v = strtoul(&inputbuf[2], NULL, 0);
                        ledpwm_bl = v;
                        ledpwm_setled(LEDPWM_BLUELED, (((uint16_t)ledpwm_bl * ledpwm_bri) / 255));
-                       console_printpgm_P(PSTR("BLUE value set to 0x"));
-                       console_printhex8(v);
+                       console_printpgm_noirq_P(PSTR("BLUE value set to 0x"));
+                       console_printhex8_noirq(v);
                } else if (strncmp_P(inputbuf, PSTR("bri "), 2) == 0) {
                        uint8_t v;
                        v = strtoul(&inputbuf[4], NULL, 0);
@@ -358,8 +386,16 @@ ISR(USART_RX_vect) {
                        ledpwm_setled(LEDPWM_REDLED, (((uint16_t)ledpwm_re * ledpwm_bri) / 255));
                        ledpwm_setled(LEDPWM_GREENLED, (((uint16_t)ledpwm_gr * ledpwm_bri) / 255));
                        ledpwm_setled(LEDPWM_BLUELED, (((uint16_t)ledpwm_bl * ledpwm_bri) / 255));
-                       console_printpgm_P(PSTR("brightness set to 0x"));
-                       console_printhex8(v);
+                       console_printpgm_noirq_P(PSTR("brightness set to 0x"));
+                       console_printhex8_noirq(v);
+               } else if (strcmp_P(inputbuf, PSTR("rfstatus")) == 0) {
+                       uint32_t st;
+                       st = rfm12_readstatus();
+                       console_printpgm_noirq_P(PSTR("rfm12 status is "));
+                       console_printhex8_noirq(st >> 24);
+                       console_printhex8_noirq(st >> 16);
+                       console_printhex8_noirq(st >>  8);
+                       console_printhex8_noirq(st >>  0);
 #ifdef JOKECMDS
                } else if (strncmp_P(inputbuf, PSTR("ls"), 2) == 0) {
                        console_printpgm_noirq_P(PSTR("Total 4711\r\n"));
diff --git a/eepromdata.h b/eepromdata.h
new file mode 100644 (file)
index 0000000..96e4268
--- /dev/null
@@ -0,0 +1,18 @@
+/* $Id: eepromdata.h,v 1.1 2010/07/24 20:55:48 simimeie Exp $
+ * Defines the contents of the EEPROM.
+ * The EEPROM contains settings and can also contain "programs" for the LEDs.
+ * Usually you only need to reprogram the eeprom after changing values here,
+ * unless compiler version changed and thus the data got reordered.
+ */ 
+
+#define EEPROM __attribute__ ((section (".eeprom")))
+
+/* The default brightness */
+uint8_t EEPROM ee_defledbrightness = 128;
+
+/* All the rest of the memory is used for storing LED "programs".
+ * For the following to work, <avr/io.h> needs to be included before this file -
+ * which usually should be the case anyways.
+ * Formula is: E2END + 1 - (number of bytes used by other stuff in EEPROM) */
+uint8_t EEPROM ee_ledprograms[E2END + 1 - 1];
+
diff --git a/main.c b/main.c
index 8f6f34fe01dbbab7cc9269fe1aae3f68c79f7200..3e66f1a5c5532373de52eb35575138d6d2b907e5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.6 2010/07/10 07:32:08 simimeie Exp $
+/* $Id: main.c,v 1.7 2010/07/24 20:55:48 simimeie Exp $
  * Main file for the HaWo moodlight.
  * This is the main file that glues it all together. It also contains all
  * functionality that is too small to require an extra file.
 #include "ledpwm.h"
 #include "ircontrol.h"
 #include "timers.h"
-/* #include "eepromdata.h" */
-
-uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
-
-/* This is needed to recover from a watchdog reset, as the watchdog
- * stays active after the reset.
- * The variable is just to make the reason of the last reset accessible
- * later. */
-void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init3")));
-void get_mcusr(void) {
-  mcusr_mirror = MCUSR;
-  MCUSR = 0;
-  wdt_disable();
-}
+#include "ledframing.h"
+#include "rfm12.h"
+#include "eepromdata.h"
 
 #define IRSTATE_RED       1
 #define IRSTATE_GREEN     2
@@ -44,15 +33,15 @@ int main(void)
   uint8_t irstate = 0;
   
   /* Load settings from EEPROM */
-#if 0
-  something = eeprom_read_byte(&ee_something);
-#endif /* LEDMODULE */
+  ledpwm_bri = eeprom_read_byte(&ee_defledbrightness);
 
   /* Initialize stuff */
   console_init();
   timers_init();
   ledpwm_init();
+  ledframing_init();
   ircontrol_init();
+  rfm12_init();
   
   wdt_enable(WDTO_2S);
 
@@ -63,13 +52,6 @@ int main(void)
   /* All set up, enable interrupts and go. */
   sei();
   
-  if (mcusr_mirror & _BV(WDRF)) {
-    console_printpgm_P(PSTR("NOTE: last reset was from Watchdog Timer."));
-  }
-  if (mcusr_mirror & _BV(BORF)) {
-    console_printpgm_P(PSTR("NOTE: last reset was from Brownout."));
-  }
-  
   while (1) { /* We should never exit */
     wdt_reset();
     uint8_t k = ircontrol_getlastcommand();
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
 }
diff --git a/rfm12.h b/rfm12.h
index df9692453664d5d62a7f80ff699385a2f8e462b3..3873e22effe378a496784f0ce63fbd2ab06ad735 100644 (file)
--- a/rfm12.h
+++ b/rfm12.h
@@ -1,4 +1,4 @@
-/* $Id: rfm12.h,v 1.1 2010/07/11 09:09:26 simimeie Exp $
+/* $Id: rfm12.h,v 1.2 2010/07/24 20:55:48 simimeie Exp $
  * Functions for communicating with the rfm12(b) module
  */
 
@@ -6,5 +6,7 @@
 #define __RFM12B_H__
 
 void rfm12_init(void);
+void rfm12_sendcommand(uint16_t cmd);
+uint32_t rfm12_readstatus(void);
 
 #endif /* __RFM12B_H__ */
This page took 0.123596 seconds and 4 git commands to generate.