diff options
author | Lars-Dominik Braun <lars@6xq.net> | 2014-09-16 15:31:53 +0200 |
---|---|---|
committer | Lars-Dominik Braun <lars@6xq.net> | 2014-09-16 15:33:30 +0200 |
commit | b742ab3a288a1164b4ceb6e58ae42115d320d580 (patch) | |
tree | 7df7348f08f79e6e4cb3f492ba77f5d08260fa88 | |
parent | 0a9d079451c1ae4ba85f6735943734767140248d (diff) | |
download | hourglass-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-- | Makefile | 2 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | pwm.c | 91 | ||||
-rw-r--r-- | pwm.h | 14 | ||||
-rw-r--r-- | speaker.c | 55 | ||||
-rw-r--r-- | speaker.h | 13 | ||||
-rw-r--r-- | ui.c | 18 |
7 files changed, 62 insertions, 134 deletions
@@ -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 @@ -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"); @@ -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); } @@ -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 */ - @@ -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 |