aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c92
1 files changed, 74 insertions, 18 deletions
diff --git a/src/main.c b/src/main.c
index 264d56a..81da424 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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++;
}
}