-# $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
# 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
-/* $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.
*/
#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 */
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) {
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);
} 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"));
--- /dev/null
+/* $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);
+}
--- /dev/null
+/* $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_ */
--- /dev/null
+/* $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 */
+}
--- /dev/null
+/* $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_ */
-/* $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.
#include <util/delay.h>
#include "console.h"
+#include "ledpwm.h"
+#include "ircontrol.h"
/* #include "eepromdata.h" */
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
int main(void)
{
- uint8_t i;
+ uint8_t i = 0;
/* Load settings from EEPROM */
#if 0
/* Initialize stuff */
console_init();
+ ledpwm_init();
+ ircontrol_init();
wdt_enable(WDTO_2S);
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); */
}
}