diff --git a/firmware/include/pentabug/hal.h b/firmware/include/pentabug/hal.h index 919591c..622186b 100644 --- a/firmware/include/pentabug/hal.h +++ b/firmware/include/pentabug/hal.h @@ -42,6 +42,13 @@ void motor_on(void); void motor_off(void); void motor_inv(void); +// BUZZER + +void buzzer_up(void); +void buzzer_down(void); +void buzzer_inv(void); +void buzzer_off(void); + // WAITING // waits the given amount of ms diff --git a/firmware/lib/hal.c b/firmware/lib/hal.c index 932a6a1..0315023 100644 --- a/firmware/lib/hal.c +++ b/firmware/lib/hal.c @@ -19,17 +19,21 @@ inline static void major_interrupt(void) { uint8_t i = 0; for(i = 0; i < 2; ++i) { + // button pressed? if(PINB & (1 << i)) { - if(button_count[i] && button_count[i] > 10 && button_count[i] < 200) { + // pressed for more than 50ms is a click + if(button_count[i] > 10 && button_count[i] < 200) { button_pressed[i] = 1; } + // not pressed, reset button_count[i] = 0; } else { + //.count time pressed ++button_count[i]; } - // 1s pressed + // 1s pressed, request next app if(button_count[i] == 200) { next_app(i ? 1 : -1); } @@ -38,10 +42,14 @@ inline static void major_interrupt(void) { // WARNING: this interrupt is already way too big. extend only in case of emergency! ISR(TIMER0_COMPA_vect) { + // generate 38kHz signal + if(ir_active) { PORTD ^= 1 << 2; } + // call button handling less often + ++int_skip; if(int_skip >= 64 * 5) { @@ -49,6 +57,8 @@ ISR(TIMER0_COMPA_vect) { major_interrupt(); } + // tell wait_ms() that 1/38 ms has passed + --wait_time; } @@ -68,6 +78,8 @@ void init_hw(void) { TCCR0A = (1 << WGM01); TCCR0B = (1 << CS00); + // activate interrupts + sei(); } @@ -164,10 +176,32 @@ void motor_inv(void) { PORTB ^= 1 << 6; } +void buzzer_up(void) { + PORTB |= 1 << 7; + PORTC &= ~(1 << 0); +} + +void buzzer_down(void) { + PORTB &= ~(1 << 7); + PORTC |= 1 << 0; +} + +void buzzer_inv(void) { + PORTB ^= 1 << 7; + PORTC ^= 1 << 0; +} + +void buzzer_off(void) { + PORTB &= ~(1 << 7); + PORTC &= ~(1 << 0); +} + void wait_ms(uint16_t ms) { // TODO: this function seems to be ~10% too fast int32_t cycles = ms * (int32_t)64; + // wait_time is int16_t for performance reasons, so we have to wait multiple times + while(cycles >= INT16_MAX) { cycles -= INT16_MAX; wait_time = INT16_MAX; @@ -177,6 +211,8 @@ void wait_ms(uint16_t ms) { } } + // wait the odd time left + wait_time = cycles; while(wait_time > 0) { diff --git a/firmware/lib/music.c b/firmware/lib/music.c index 8cc5002..7f72ccf 100644 --- a/firmware/lib/music.c +++ b/firmware/lib/music.c @@ -7,18 +7,20 @@ #include static void tune(void) { - PORTB ^= 1 << 7; + buzzer_inv(); } void set_note(uint16_t note, uint8_t octave) { if(note != NOTE_PAUSE) { + buzzer_up(); start_timer(PRESCALE_8, note >> octave, tune); } else { - stop_timer(); + stop_note(); } } void stop_note(void) { + buzzer_off(); stop_timer(); }