aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2014-09-16 15:31:53 +0200
committerLars-Dominik Braun <lars@6xq.net>2014-09-16 15:33:30 +0200
commitb742ab3a288a1164b4ceb6e58ae42115d320d580 (patch)
tree7df7348f08f79e6e4cb3f492ba77f5d08260fa88
parent0a9d079451c1ae4ba85f6735943734767140248d (diff)
downloadhourglass-b742ab3a288a1164b4ceb6e58ae42115d320d580.tar.gz
hourglass-b742ab3a288a1164b4ceb6e58ae42115d320d580.tar.bz2
hourglass-b742ab3a288a1164b4ceb6e58ae42115d320d580.zip
Finally fix speaker
Use one timer for LED/speaker. Not sure why two did not work.
-rw-r--r--Makefile2
-rw-r--r--main.c3
-rw-r--r--pwm.c91
-rw-r--r--pwm.h14
-rw-r--r--speaker.c55
-rw-r--r--speaker.h13
-rw-r--r--ui.c18
7 files changed, 62 insertions, 134 deletions
diff --git a/Makefile b/Makefile
index ce838c5..56998e1 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ CFLAGS=-Os -Wall -Wextra
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 pwm.c pwm.h ui.c ui.h
+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 pwm.c pwm.h ui.c ui.h
avr-gcc -std=gnu99 -mmcu=$(MCU) $(CFLAGS) -o $@ $^
sanduhr.hex: sanduhr.elf
diff --git a/main.c b/main.c
index de3cda2..b9bb5ce 100644
--- a/main.c
+++ b/main.c
@@ -12,7 +12,6 @@
#include "timer.h"
#include "gyro.h"
#include "accel.h"
-#include "speaker.h"
#include "pwm.h"
#include "ui.h"
@@ -37,8 +36,8 @@ int main () {
uartInit ();
gyroInit ();
accelInit ();
- speakerInit ();
pwmInit ();
+ pwmStart ();
set_sleep_mode (SLEEP_MODE_IDLE);
puts ("initialization done");
diff --git a/pwm.c b/pwm.c
index 0d0b28d..568ed73 100644
--- a/pwm.c
+++ b/pwm.c
@@ -9,29 +9,32 @@
#include <stdlib.h>
#include <string.h>
-#include "speaker.h"
#include "pwm.h"
static uint8_t count = 0;
-static uint8_t toggle[PWM_MAX_BRIGHTNESS][2];
-/* led bitfield, indicating which ones are leds */
-static const uint8_t bits[2] = {(1 << PB6) | (1 << PB7),
- (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5)};
-
-static void allLedsOff () {
- PORTB &= ~bits[0];
- PORTD &= ~bits[1];
-}
+static uint8_t speakerCount = 0;
+static uint8_t pwmvalue[PWM_MAX_BRIGHTNESS][2];
+/* led bitfield, indicating which ones are pwm-controlled */
+static const uint8_t offbits[2] = {(uint8_t) ~((1 << PB6) | (1 << PB7)),
+ (uint8_t) ~((1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6))};
ISR(TIMER0_COMPA_vect) {
- /* the 16th+ state is always ignored/force-off */
- if (count >= PWM_MAX_BRIGHTNESS-1) {
- allLedsOff ();
- } else {
- PORTB ^= toggle[count][0];
- PORTD ^= toggle[count][1];
+#warning "speaker works now, led1 and 2 do not work"
+ if (speakerCount > 0) {
+ --speakerCount;
+ /* stop speaker after beep */
+ if (speakerCount == 0) {
+ /* in speakerStart we set every 2nd to 1 */
+ for (uint8_t i = 0; i < PWM_MAX_BRIGHTNESS; i += 2) {
+ pwmvalue[i][1] &= ~(1 << PD6);
+ }
+ }
}
- /* 16 steps */
+
+ PORTB = pwmvalue[count][0];
+ PORTD = pwmvalue[count][1];
+
+ /* auto wrap-around */
count = (count+1) & (PWM_MAX_BRIGHTNESS-1);
}
@@ -50,23 +53,12 @@ static uint8_t ledToShift (const uint8_t i) {
return shifts[i];
}
-#if 0
-static void ledOff (const uint8_t i) {
- assert (i < PWM_LED_COUNT);
- if (ledToArray (i) == 0) {
- PORTB = PORTB & ~(1 << ledToShift (i));
- } else {
- PORTD = PORTD & ~(1 << ledToShift (i));
- }
-}
-#endif
-
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);
- memset (toggle, 0, sizeof (toggle));
+ memset (pwmvalue, 0, sizeof (pwmvalue));
}
void pwmStart () {
@@ -78,9 +70,14 @@ void pwmStart () {
/* enable compare match interrupt */
TIMSK0 = (1 << OCIE0A);
/* compare value */
- OCR0A = 255;
+ OCR0A = 1;
/* io clock with prescaler 64; ctc (part 2) */
- TCCR0B = (0 << CS02) | (1 << CS01) | (1 << CS00);
+ TCCR0B = (1 << CS02) | (0 << CS01) | (1 << CS00);
+}
+
+static void allLedsOff () {
+ PORTB &= offbits[0];
+ PORTD &= offbits[1];
}
void pwmStop () {
@@ -95,19 +92,31 @@ void pwmStop () {
*/
void pwmSet (const uint8_t i, const uint8_t value) {
assert (i < PWM_LED_COUNT);
+ assert (value <= PWM_MAX_BRIGHTNESS);
+
const uint8_t array = ledToArray (i);
const uint8_t bit = 1 << ledToShift (i);
- /* disable all toggles */
- for (uint8_t j = 0; j < PWM_MAX_BRIGHTNESS; j++) {
- toggle[j][array] &= ~bit;
+
+ for (uint8_t j = 0; j < value; j++) {
+ pwmvalue[j][array] |= bit;
}
- uint8_t toggleat;
- if (value < PWM_MAX_BRIGHTNESS) {
- toggleat = PWM_MAX_BRIGHTNESS-value;
- } else {
- /* max brightness */
- toggleat = 0;
+ for (uint8_t j = value; j < PWM_MAX_BRIGHTNESS; j++) {
+ pwmvalue[j][array] &= ~bit;
}
- toggle[toggleat][array] |= bit;
+}
+
+void speakerStart (const speakerMode mode) {
+ /* 12.8ms */
+ speakerCount = 100;
+ for (uint8_t i = 0; i < PWM_MAX_BRIGHTNESS; i += 2) {
+ pwmvalue[i][1] |= (1 << PD6);
+ }
+}
+
+void speakerInit () {
+ /* set PD6 to output */
+ DDRD |= (1 << PD6);
+ /* turn off */
+ PORTD = PORTD & ~(1 << PD6);
}
diff --git a/pwm.h b/pwm.h
index 96deaae..c67f2a6 100644
--- a/pwm.h
+++ b/pwm.h
@@ -7,12 +7,18 @@ void pwmStart ();
void pwmStop ();
void pwmSet (const uint8_t, const uint8_t);
-/* LED on (max brightness) */
-#define PWM_ON UINT8_MAX
-/* LED off */
-#define PWM_OFF 0
+typedef enum {
+ SPEAKER_BEEP,
+} speakerMode;
+
+void speakerStart (const speakerMode);
+
#define PWM_LED_COUNT 6
+
+#define PWM_OFF 0
+/* must be power-of-two */
#define PWM_MAX_BRIGHTNESS 8
+#define PWM_ON PWM_MAX_BRIGHTNESS
#endif /* PWM_H */
diff --git a/speaker.c b/speaker.c
deleted file mode 100644
index e96afcf..0000000
--- a/speaker.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* speaker control, uses timer2
- */
-
-#include "common.h"
-
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include "speaker.h"
-
-static volatile uint16_t count;
-
-/* Compare interrupt
- */
-ISR(TIMER2_COMPA_vect) {
- PORTD ^= (1 << PD6);
- --count;
- if (count == 0) {
- speakerStop ();
- }
-}
-
-void speakerInit () {
- /* set PD6 to output */
- DDRD |= (1 << PD6);
- /* turn off */
- PORTD = PORTD & ~(1 << PD6);
-}
-
-void speakerStart (const speakerMode mode) {
- /* 12.8ms */
- count = 100;
-
- /* compare value (hit on every tick) */
- OCR2A = 1;
- /* reset timer value */
- TCNT2 = 0;
- /* set ctc mode */
- TCCR2A = (1 << WGM21);
- /* enable overflow interrupt */
- TIMSK2 = (1 << OCIE2A);
- /* io clock with 1024 prescaler -> ~4kHz tone, ctc part2 */
- TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20);
-}
-
-void speakerStop () {
- /* zero clock source */
- TCCR2B &= ~(0x7);
- /* turn off */
- PORTD = PORTD & ~(1 << PD6);
-}
-
diff --git a/speaker.h b/speaker.h
deleted file mode 100644
index a035a6b..0000000
--- a/speaker.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef SPEAKER_H
-#define SPEAKER_H
-
-typedef enum {
- SPEAKER_BEEP,
-} speakerMode;
-
-void speakerInit ();
-void speakerStart (const speakerMode);
-void speakerStop ();
-
-#endif /* SPEAKER_H */
-
diff --git a/ui.c b/ui.c
index e7ab241..3a695ae 100644
--- a/ui.c
+++ b/ui.c
@@ -8,7 +8,6 @@
#include "ui.h"
#include "accel.h"
#include "gyro.h"
-#include "speaker.h"
#include "timer.h"
#include "pwm.h"
@@ -98,14 +97,12 @@ static void doSelectCoarse () {
puts ("\ncoarseValue\n");
fwrite (&coarseValue, sizeof (coarseValue), 1, stdout);
- pwmStop ();
for (uint8_t i = 0; i < coarseValue; i++) {
pwmSet (horizonLed (i), PWM_ON);
}
for (uint8_t i = coarseValue; i < PWM_LED_COUNT; i++) {
pwmSet (horizonLed (i), PWM_OFF);
}
- pwmStart ();
}
}
@@ -115,7 +112,6 @@ static void doSelectFine () {
if (accelGetShakeCount () >= 2) {
/* stop selection */
accelResetShakeCount ();
- pwmStop ();
mode = UIMODE_IDLE;
puts ("selectfine->idle");
speakerStart (SPEAKER_BEEP);
@@ -130,7 +126,6 @@ static void doSelectFine () {
puts ("\nfineValue\n");
fwrite (&fineValue, sizeof (fineValue), 1, stdout);
- pwmStop ();
/* from bottom to top for positive values, top to bottom for negative
* values */
if (fineValue >= 0) {
@@ -148,7 +143,6 @@ static void doSelectFine () {
pwmSet (horizonLed (PWM_LED_COUNT-1-i), PWM_OFF);
}
}
- pwmStart ();
}
}
@@ -157,7 +151,6 @@ static void doSelectFine () {
static void doIdle () {
if (horizonChanged) {
/* start timer */
- pwmStop ();
for (uint8_t i = 0; i < PWM_LED_COUNT; i++) {
brightness[i] = 0;
pwmSet (horizonLed (i), PWM_OFF);
@@ -165,7 +158,6 @@ static void doIdle () {
currLed = PWM_LED_COUNT-1;
brightness[currLed] = PWM_MAX_BRIGHTNESS;
pwmSet (horizonLed (currLed), brightness[currLed]);
- pwmStart ();
timerValue = coarseValue * (uint32_t) 10*60*1000*1000 +
fineValue * (uint32_t) 60*1000*1000;
@@ -202,17 +194,14 @@ static void doRun () {
fwrite (&timerElapsed, sizeof (timerElapsed), 1, stdout);
if (timerElapsed >= timerValue) {
/* ring the alarm! */
- pwmStop ();
for (uint8_t i = 0; i < PWM_LED_COUNT; i++) {
pwmSet (i, PWM_MAX_BRIGHTNESS);
}
- pwmStart ();
mode = UIMODE_ALARM;
puts ("run->alarm");
speakerStart (SPEAKER_BEEP);
} else {
/* one step */
- pwmStop ();
--brightness[currLed];
pwmSet (horizonLed (currLed), brightness[currLed]);
++brightness[currLed-1];
@@ -220,7 +209,6 @@ static void doRun () {
if (brightness[currLed] == 0 && currLed > 0) {
--currLed;
}
- pwmStart ();
puts ("\ncurrLed");
fwrite (&currLed, sizeof (currLed), 1, stdout);
puts ("\nbrightness");
@@ -231,7 +219,6 @@ static void doRun () {
mode = UIMODE_IDLE;
puts ("run->idle (stopped)");
speakerStart (SPEAKER_BEEP);
- pwmStop ();
}
}
@@ -241,7 +228,6 @@ static void doAlarm () {
if (horizonChanged) {
timerStop ();
/* stop blinking */
- pwmStop ();
mode = UIMODE_IDLE;
}
}
@@ -254,7 +240,6 @@ static void doInit () {
if (h != HORIZON_NONE) {
mode = UIMODE_IDLE;
puts ("init->idle");
- pwmStop ();
#if 0
/* debugging */
@@ -270,7 +255,6 @@ static void doInit () {
currLed = PWM_LED_COUNT-1;
brightness[currLed] = PWM_MAX_BRIGHTNESS;
pwmSet (horizonLed (currLed), brightness[currLed]);
- pwmStart ();
timerStart (brightnessStep);
#endif
}
@@ -292,7 +276,6 @@ void uiLoop () {
uint8_t i = 0;
uint8_t brightness = 0;
while (1) {
- pwmStop ();
for (uint8_t j = 0; j < PWM_LED_COUNT; j++) {
pwmSet (horizonLed (j), PWM_OFF);
}
@@ -305,7 +288,6 @@ void uiLoop () {
brightness = 0;
}
}
- pwmStart ();
_delay_ms (1000);
}
#endif