diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 92 |
1 files changed, 74 insertions, 18 deletions
@@ -3,6 +3,9 @@ #include "main.h" #include "tm1637.h" +#define SECOND (1e3) +#define LONG_PRESS_DURATION (300) + const unsigned short leds[] = {PINOUT_LED_1, PINOUT_LED_2, PINOUT_LED_3, PINOUT_LED_4}; volatile bool led_direction = false; @@ -84,10 +87,8 @@ void interrupt_setup() { * 0 or 1 which indicates if the LED should be turned on (1) or off (0). */ void led_write(int num, int on) { - int pin = leds[num]; - GPIOB->ODR ^= (((GPIOB->ODR & (1 << pin)) >> pin) ^ on) << pin; - // GPIOB->ODR &= ~(1 << leds[num]); - // GPIOB->ODR |= (on << leds[num]); + GPIOB->ODR &= ~(1 << leds[num]); + GPIOB->ODR |= (on << leds[num]); } /* @@ -118,10 +119,6 @@ void next_led() { led_write(led, 1); } -void dumb_delay() { - for(unsigned long i = 0; i < 50e3; i++); -} - /** * This function uses timer 3 to generate a blocking delay of <milliseconds>. * It uses the channel 1 capture/compare register to check if the time (in @@ -135,6 +132,7 @@ void timer_delay(unsigned short millis) { } void timer_display(unsigned int minutes, unsigned int seconds, bool colon) { + tm1637_dispcfg(pot_read() / 512, 1); // 512 = 2**12 / 8; [0,4096]->[0,8] tm1637_segmentsend(0, tm1637_font[minutes / 10]); tm1637_segmentsend(1, tm1637_font[minutes % 10] | (colon * TM1637_COLON)); tm1637_segmentsend(2, tm1637_font[seconds / 10]); @@ -148,20 +146,78 @@ int main() { unsigned int minutes = 0; unsigned int seconds = 0; + bool pause = false; + button_state state = up_idle; + bool reverse = false; + unsigned short led = 0; + + // timers + unsigned long millis_stopwatch = 0; + unsigned long millis_looplicht = 0; + unsigned long millis_button_dn = 0; + + bool long_press = false; tm1637_dispcfg(7, 1); while (1) { - timer_delay(500); - timer_display(minutes, seconds, false); - timer_delay(500); - timer_display(minutes, seconds, true); - - seconds++; - if (seconds >= 60) { - seconds = 0; - minutes++; - if (minutes >= 100) minutes = 0; + uint8_t button_now = button_read(); + switch(state) { + case up_idle: { + state = button_now ? down_edge : up_idle; + millis_button_dn = 0; + break; + } + case down_edge: { + state = button_now ? down_idle : up_idle; + millis_button_dn = 1; + break; + } + case down_idle: { + state = button_now ? down_idle : up_edge; + millis_button_dn++; + break; + } + case up_edge: { + state = button_now ? down_idle : up_idle; + long_press = millis_button_dn >= LONG_PRESS_DURATION; + + if (!long_press) pause = !pause; + else { + pause = true; + minutes = 0; + seconds = 0; + millis_stopwatch = 0; + } + break; + } + } + if (millis_stopwatch % 50 == 0) timer_display(minutes, seconds, millis_stopwatch > (SECOND / 2)); + + if (millis_stopwatch == SECOND) { + seconds++; + if (seconds >= 60) { + seconds = 0; + minutes++; + if (minutes >= 100) minutes = 0; + } + millis_stopwatch = 0; } + + unsigned int delay_amount = 50 + pot_read(); + if (millis_looplicht >= delay_amount) { + for(int j = 0; j < 4; j++) led_write(j, 0); + + // calculate next led index + led = (led + ((2 * reverse) - 1)) & 0b11; + + led_write(led, 1); + + millis_looplicht = 0; + } + + timer_delay(1); + millis_looplicht++; + if (!pause) millis_stopwatch++; } } |