- add LED control with PWM
authorsimimeie <simimeie>
Sat, 26 Jun 2010 19:08:18 +0000 (19:08 +0000)
committersimimeie <simimeie>
Sat, 26 Jun 2010 19:08:18 +0000 (19:08 +0000)
- add infrared control - just displaying when the IR receiver pin toggles
  for now.
- some minor text corrections to the console and support for setting LED
  brightness from there.
- add new files to Makefile

Makefile
console.c
ircontrol.c [new file with mode: 0644]
ircontrol.h [new file with mode: 0644]
ledpwm.c [new file with mode: 0644]
ledpwm.h [new file with mode: 0644]
main.c

index d91c8756aa30ffa50905ca356b606ef35b9603bb..d78c6e469758980c953fa0779b75503d4cdb5b01 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.1 2010/06/26 12:28:08 simimeie Exp $
+# $Id: Makefile,v 1.2 2010/06/26 19:08:18 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 main.c
+SRCS   = console.c ledpwm.c ircontrol.c main.c
 PROG   = moodlight
 
 # compiler flags
index a8445cbbe4f83729becced0d131841f19d4ba057..140765cff33886754ed24d3397cdce2bc00159b4 100644 (file)
--- a/console.c
+++ b/console.c
@@ -1,4 +1,4 @@
-/* $Id: console.c,v 1.1 2010/06/26 12:28:08 simimeie Exp $
+/* $Id: console.c,v 1.2 2010/06/26 19:08:18 simimeie Exp $
  * Functions for a serial console.
  */
 
@@ -8,7 +8,9 @@
 #include <avr/version.h>
 #include <util/delay.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include "console.h"
+#include "ledpwm.h"
 
 /* PD0 is RXD, PD1 is TXD, but we don't need to address them manually */
 
@@ -27,14 +29,14 @@ static uint8_t escstatus = 0;
 static prog_uint8_t CRLF[] = "\r\n";
 static prog_uint8_t WELCOMEMSG[] = "\r\n"\
                                   "\r\n ******************************************"\
-                                  "\r\n * universal mainboard v1                 *"\
-                                  "\r\n * (C) Michael 'PoempelFox' Meier 05/2010 *"\
+                                  "\r\n * HaWo Moodlight v0 (prototype)          *"\
+                                  "\r\n * (C) Michael 'PoempelFox' Meier 06/2010 *"\
                                   "\r\n ******************************************"\
                                   "\r\n"\
                                   "\r\nProcessor: atmega328"\
                                   "\r\nAVR-libc: " __AVR_LIBC_VERSION_STRING__ " (" __AVR_LIBC_DATE_STRING__ ")"\
                                   "\r\nSoftware Version 0.1, Compiled " __DATE__ " " __TIME__;
-static prog_uint8_t PROMPT[] = "\r\nroot@mbv1# ";
+static prog_uint8_t PROMPT[] = "\r\nroot@moodlight# ";
 
 /* Handler for TXC (TX Complete) IRQ */
 ISR(USART_TX_vect) {
@@ -260,6 +262,7 @@ ISR(USART_RX_vect) {
                        console_printpgm_noirq_P(PSTR("\r\n motd             repeat welcome message"));
                        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 save             saves settings to EEPROM")); */
                } else if (strcmp_P(inputbuf, PSTR("motd")) == 0) {
                        console_printpgm_noirq_P(WELCOMEMSG);
@@ -319,6 +322,24 @@ ISR(USART_RX_vect) {
                } else if (strcmp_P(inputbuf, PSTR("status")) == 0) {
                        console_printpgm_noirq_P(PSTR("Current status:\r\n"));
                        console_printpgm_noirq_P(PSTR("none. nothing implemented yet."));
+               } else if (strncmp_P(inputbuf, PSTR("r "), 2) == 0) {
+                       uint8_t v;
+                       v = strtoul(&inputbuf[2], NULL, 0);
+                       ledpwm_setled(LEDPWM_REDLED, v);
+                       console_printpgm_P(PSTR("brightness of RED LED set to 0x"));
+                       console_printhex8(v);
+               } else if (strncmp_P(inputbuf, PSTR("g "), 2) == 0) {
+                       uint8_t v;
+                       v = strtoul(&inputbuf[2], NULL, 0);
+                       ledpwm_setled(LEDPWM_GREENLED, v);
+                       console_printpgm_P(PSTR("brightness of GREEN LED set to 0x"));
+                       console_printhex8(v);
+               } else if (strncmp_P(inputbuf, PSTR("b "), 2) == 0) {
+                       uint8_t v;
+                       v = strtoul(&inputbuf[2], NULL, 0);
+                       ledpwm_setled(LEDPWM_BLUELED, v);
+                       console_printpgm_P(PSTR("brightness of BLUE LED set to 0x"));
+                       console_printhex8(v);
 #ifdef JOKECMDS
                } else if (strncmp_P(inputbuf, PSTR("ls"), 2) == 0) {
                        console_printpgm_noirq_P(PSTR("Total 4711\r\n"));
diff --git a/ircontrol.c b/ircontrol.c
new file mode 100644 (file)
index 0000000..cf7e494
--- /dev/null
@@ -0,0 +1,29 @@
+/* $Id: ircontrol.c,v 1.1 2010/06/26 19:08:18 simimeie Exp $
+ * Functions for the infrared receiver
+ *
+ * The infrared receiver is connected to PB0 / PCINT0.
+ */
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "ircontrol.h"
+#include "console.h"
+
+ISR(PCINT0_vect) {
+  uint8_t v = PINB & _BV(PB0);
+  if (v) {
+    console_printpgm_P(PSTR("!1!"));
+  } else {
+    console_printpgm_P(PSTR("!0!"));
+  }
+}
+
+void ircontrol_init(void)
+{
+  /* Activate pullup */
+  PORTB |= _BV(PB0);
+  /* enable PCINT0 */
+  PCICR |= _BV(PCIE0);
+  /* Enable pin change interrupt 0 (=PB0) in pcint0 */
+  PCMSK0 |= _BV(PCINT0);
+}
diff --git a/ircontrol.h b/ircontrol.h
new file mode 100644 (file)
index 0000000..b1a42ef
--- /dev/null
@@ -0,0 +1,11 @@
+/* $Id: ircontrol.h,v 1.1 2010/06/26 19:08:18 simimeie Exp $
+ * Functions for the infrared receiver
+ */
+
+#ifndef _IRCONTROL_H_
+#define _IRCONTROL_H_
+
+/* Init infrared receiver (pins) */
+void ircontrol_init(void);
+
+#endif /* _IRCONTROL_H_ */
diff --git a/ledpwm.c b/ledpwm.c
new file mode 100644 (file)
index 0000000..dfc26d6
--- /dev/null
+++ b/ledpwm.c
@@ -0,0 +1,96 @@
+/* $Id: ledpwm.c,v 1.1 2010/06/26 19:08:18 simimeie Exp $
+ * Functions for led brightness control via PWM (pulse width modulation).
+ */
+
+#include <avr/io.h>
+#include "ledpwm.h"
+
+/* Select between Phase correct PWM and Fast PWM mode.
+ * setting this to 1 selects phase correct mode, everything else is Fast PWM. */
+#define PHASECORRECTPWM 1
+/*
+ * Our hardware connections are as follows:
+ *  Red -> PD6 / OC0A
+ *  Green -> PD5 / OC0B
+ *  Blue -> PD3 / OC2B
+ */
+void ledpwm_init(void)
+{
+  /* Set OC2B, OC0A and OC0B to output */
+  DDRD |= _BV(PD3) | _BV(PD5) | _BV(PD6);
+  /* Set compare output mode for OC2B in timer counter control register: */
+#if (PHASECORRECTPWM == 1)
+  /* select phase correct PWM mode (1). WGM2 bit is 0 so we don't need to touch TCCR2B. */
+  TCCR2A |= _BV(COM2B1) | _BV(WGM20);
+#else  /* not PHASECORRECTPWM */
+  /* set output at BOTTOM (=0), clear it on compare match.
+   * select fast PWM mode 3. WGM2 bit is 0 so we don't need to touch TCCR2B. */
+  TCCR2A |= _BV(COM2B1) | _BV(WGM20) /*| _BV(WGM21)*/;
+#endif /* PHASECORRECTPWM */
+  /* select clock source: cpu clock without prescaler. */
+  TCCR2B |= _BV(CS20);
+  /* Default brightness: PWM 0 */
+  OCR2B = 0;
+  /* Set compare output mode for OC0A and OC0B in timer counter control register: */
+#if (PHASECORRECTPWM == 1)
+  /* select phase correct PWM mode (1). WGM2 bit is 0 so we don't need to touch TCCR0B. */
+  TCCR0A |= _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00);
+#else  /* not PHASECORRECTPWM */
+  /* set output at BOTTOM (=0), clear it on compare match.
+   * select fast PWM mode 3. WGM2 bit is 0 so we don't need to touch TCCR0B. */
+  TCCR0A |= _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00) | _BV(WGM01);
+#endif /* PHASECORRECTPWM */
+  /* select clock source: i/o clock without prescaler. */
+  TCCR0B |= _BV(CS20);
+  /* Default brightness: PWM 0 */
+  OCR0A = 0;
+  OCR0B = 0;
+}
+
+/* In none-phase-correct PWM mode, This function does some mapping of
+ * the values:
+ * 0 really turns the LED off.
+ * 1 is an PWM value of 0, which still lets the LED glimmer.
+ * 2 to 254 are mapped to PWM 3 to 253 (always one less!)
+ * 255 is mapped to PWM 255.
+ * So there is no way to set PWM 254, but you cannot visually see the
+ * difference to 253 or 255 anyways...
+ * In phase-correct PWM mode there does not need to be a mapping, 0 means off.
+ */
+void ledpwm_setled(uint8_t led, uint8_t val)
+{
+#if (PHASECORRECTPWM == 1)
+  switch (led) {
+  case LEDPWM_REDLED:   OCR0A = val; break;
+  case LEDPWM_GREENLED: OCR0B = val; break;
+  case LEDPWM_BLUELED:  OCR2B = val; break;
+  };
+#else /* not PHASECORRECTPWM */
+  if (val == 0) {
+    switch (led) {
+    case LEDPWM_REDLED:   DDRD &= (uint8_t)~_BV(PD6);
+                          break;
+    case LEDPWM_GREENLED: DDRD &= (uint8_t)~_BV(PD5);
+                          break;
+    case LEDPWM_BLUELED:  DDRD &= (uint8_t)~_BV(PD3);
+                          break;
+    };
+  } else {
+    val -= 1;
+    if (val == 254) {
+      val = 255;
+    }
+    switch (led) {
+    case LEDPWM_REDLED:   DDRD |= _BV(PD6);
+                          OCR0A = val;
+                          break;
+    case LEDPWM_GREENLED: DDRD |= _BV(PD5);
+                          OCR0B = val;
+                          break;
+    case LEDPWM_BLUELED:  DDRD |= _BV(PD3);
+                          OCR2B = val;
+                          break;
+    };
+  }
+#endif /* PHASECORRECTPWM */
+}
diff --git a/ledpwm.h b/ledpwm.h
new file mode 100644 (file)
index 0000000..2b9dc2f
--- /dev/null
+++ b/ledpwm.h
@@ -0,0 +1,18 @@
+/* $Id: ledpwm.h,v 1.1 2010/06/26 19:08:18 simimeie Exp $
+ * Functions for led brightness control via PWM (pulse width modulation).
+ */
+
+#ifndef _LEDPWM_H_
+#define _LEDPWM_H_
+
+#define LEDPWM_REDLED    1
+#define LEDPWM_GREENLED  2
+#define LEDPWM_BLUELED   3
+
+/* Init PWM (pins and timers) */
+void ledpwm_init(void);
+
+/* Set brightness for a certain LED */
+void ledpwm_setled(uint8_t led, uint8_t val);
+
+#endif /* _LEDPWM_H_ */
diff --git a/main.c b/main.c
index 3073f335f192567a5c314c2a4005c15d78409203..3b8e373b81f641ceeb7f28873ddbfc123aa22fcd 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.1 2010/06/26 12:28:08 simimeie Exp $
+/* $Id: main.c,v 1.2 2010/06/26 19:08:18 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.
@@ -16,6 +16,8 @@
 #include <util/delay.h>
 
 #include "console.h"
+#include "ledpwm.h"
+#include "ircontrol.h"
 /* #include "eepromdata.h" */
 
 uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
@@ -33,7 +35,7 @@ void get_mcusr(void) {
 
 int main(void)
 {
-  uint8_t i;
+  uint8_t i = 0;
   
   /* Load settings from EEPROM */
 #if 0
@@ -42,6 +44,8 @@ int main(void)
 
   /* Initialize stuff */
   console_init();
+  ledpwm_init();
+  ircontrol_init();
   
   wdt_enable(WDTO_2S);
 
@@ -61,5 +65,11 @@ int main(void)
   
   while (1) { /* We should never exit */
     wdt_reset();
+    /* i++;
+    console_printhex8(i);
+    ledpwm_setled(LEDPWM_REDLED, i);
+    ledpwm_setled(LEDPWM_GREENLED, i+128);
+    ledpwm_setled(LEDPWM_BLUELED, 255-i);
+    _delay_ms(500); */
   }
 }
This page took 0.062539 seconds and 4 git commands to generate.