aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--main.c22
-rw-r--r--pwm.c81
-rw-r--r--pwm.h11
4 files changed, 103 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index 8996720..1c28676 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,10 @@
MCU = atmega88
+CFLAGS=-Os
all: sanduhr.hex
-sanduhr.elf: main.c i2c.c i2c.h uart.c uart.h timer.c timer.h gyro.c gyro.h accel.c accel.h common.h speaker.c speaker.h
- avr-gcc -std=gnu99 -mmcu=$(MCU) -Os -o $@ $^
+sanduhr.elf: main.c i2c.c i2c.h uart.c uart.h timer.c timer.h gyro.c gyro.h accel.c accel.h common.h speaker.c speaker.h pwm.c pwm.h
+ avr-gcc -std=gnu99 -mmcu=$(MCU) $(CFLAGS) -o $@ $^
sanduhr.hex: sanduhr.elf
avr-objcopy -O ihex -R .eeprom $< $@
diff --git a/main.c b/main.c
index 84aa75e..015abc3 100644
--- a/main.c
+++ b/main.c
@@ -14,19 +14,7 @@
#include "gyro.h"
#include "accel.h"
#include "speaker.h"
-
-static void ledInit () {
- /* set led1,led2 to output */
- DDRB |= (1 << PB6) | (1 << PB7);
- /* set led3,led4,led5,led6 to output */
- DDRD |= (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5);
-}
-
-/* show data with leds */
-static void ledShow (const unsigned char val) {
- PORTB = (PORTB & ~((1 << PB6) | (1 << PB7))) | ((val & 0x3) << PB6);
- PORTD = (PORTD & ~((1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5))) | (((val >> 2) & 0xf) << PD2);
-}
+#include "pwm.h"
static void cpuInit () {
/* enter change prescaler mode */
@@ -45,12 +33,12 @@ static void cpuInit () {
int main () {
cpuInit ();
- ledInit ();
twInit ();
uartInit ();
gyroInit ();
accelInit ();
speakerInit ();
+ pwmInit ();
set_sleep_mode (SLEEP_MODE_IDLE);
printf ("initialization done\n");
@@ -59,6 +47,7 @@ int main () {
sei ();
gyroStart ();
accelStart ();
+ pwmStart ();
#if 0
speakerStart ();
@@ -70,6 +59,10 @@ int main () {
bool checkGyro = false;
while (1) {
while (!timerHit ()) {
+ for (uint8_t i = 0; i < 6; i++) {
+ pwmSetBrightness (i, abs (gyroGetZTicks ()));
+ }
+
/* round-robin to prevent starvation */
if (checkGyro) {
gyroProcess ();
@@ -97,6 +90,7 @@ int main () {
#endif
}
timerStop ();
+ pwmStop ();
printf ("stopped\n");
diff --git a/pwm.c b/pwm.c
new file mode 100644
index 0000000..eaaa5af
--- /dev/null
+++ b/pwm.c
@@ -0,0 +1,81 @@
+/* LED pwm, uses timer0
+ * XXX: this works, but we should use non-linear steps
+ */
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <stdbool.h>
+
+#include "speaker.h"
+
+#define PWM_STEPS 16
+
+/* inverse brightness; 0 is max brightness, PWM_STEPS off */
+static uint8_t invbrightness[6];
+static uint8_t count = 0;
+
+ISR(TIMER0_COMPA_vect) {
+ if (count == 0) {
+ /* switch off all LEDs */
+ PORTB = PORTB & ~((1 << PB6) | (1 << PB7));
+ PORTD = PORTD & ~((1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5));
+ } else {
+ uint8_t pb = 0, pd = 0;
+ if (count > invbrightness[0]) {
+ pb |= (1 << PB6);
+ }
+ if (count > invbrightness[1]) {
+ pb |= (1 << PB7);
+ }
+ if (count > invbrightness[2]) {
+ pd |= (1 << PD2);
+ }
+ if (count > invbrightness[3]) {
+ pd |= (1 << PD3);
+ }
+ if (count > invbrightness[4]) {
+ pd |= (1 << PD4);
+ }
+ if (count > invbrightness[5]) {
+ pd |= (1 << PD5);
+ }
+ /* actually set them */
+ PORTB |= pb;
+ PORTD |= pd;
+ }
+ ++count;
+ if (count >= PWM_STEPS) {
+ count = 0;
+ }
+}
+
+void pwmInit () {
+ /* set led1,led2 to output */
+ DDRB |= (1 << PB6) | (1 << PB7);
+ /* set led3,led4,led5,led6 to output */
+ DDRD |= (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5);
+}
+
+void pwmStart () {
+ /* reset timer value */
+ TCNT0 = 0;
+ /* set ctc timer0 (part 1) */
+ TCCR0A = 0;
+ /* enable compare match interrupt */
+ TIMSK0 = (1 << OCIE0A);
+ /* compare value; interrupt on every tick */
+ OCR0A = 0;
+ /* io clock with 8 prescaler (>8 is too slow and starts flickering); ctc
+ * (part 2) */
+ TCCR0B = (1 << CS01) | (1 << WGM02);
+}
+
+void pwmStop () {
+ /* zero clock source */
+ TCCR0B = 0;
+}
+
+void pwmSetBrightness (const uint8_t i, const uint8_t b) {
+ invbrightness[i] = b;
+}
+
diff --git a/pwm.h b/pwm.h
new file mode 100644
index 0000000..eeb93c6
--- /dev/null
+++ b/pwm.h
@@ -0,0 +1,11 @@
+#ifndef PWM_H
+#define PWM_H
+
+#include <stdint.h>
+void pwmInit ();
+void pwmStart ();
+void pwmStop ();
+void pwmSetBrightness (const uint8_t i, const uint8_t b);
+
+#endif /* PWM_H */
+