aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.c92
-rw-r--r--src/main.h7
-rw-r--r--src/tm1637.c40
3 files changed, 105 insertions, 34 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++;
}
}
diff --git a/src/main.h b/src/main.h
index 0714611..2df67e1 100644
--- a/src/main.h
+++ b/src/main.h
@@ -24,3 +24,10 @@ void dumb_delay();
void timer_delay(unsigned short millis);
int main();
+typedef enum {
+ up_idle = 0,
+ down_edge = 1,
+ down_idle = 2,
+ up_edge = 3,
+} button_state;
+
diff --git a/src/tm1637.c b/src/tm1637.c
index 9cc79d6..d4a4e44 100644
--- a/src/tm1637.c
+++ b/src/tm1637.c
@@ -33,17 +33,6 @@ void _tm1637_pin_write(uint32_t pin, bool state) {
GPIOA->ODR ^= (((GPIOA->ODR & (1 << pin)) >> pin) ^ state) << pin;
}
-void tm1637_begin() {
- _tm1637_GPIOMODE_gp_output();
-
- // general purpose output mode for clk
- GPIOA->MODER &= ~(0b11 << (PINOUT_DISP_CLK * 2));
- GPIOA->MODER |= (0b01 << (PINOUT_DISP_CLK * 2));
-
- _tm1637_pin_write(PINOUT_DISP_CLK, 1);
- _tm1637_pin_write(PINOUT_DISP_DIO, 1);
-}
-
void _tm1637_start() {
_tm1637_pin_write(PINOUT_DISP_DIO, 0);
}
@@ -54,13 +43,15 @@ void _tm1637_stop() {
}
bool _tm1637_ack() {
+ bool ack = false;
_tm1637_pin_write(PINOUT_DISP_CLK, 0);
_tm1637_pin_write(PINOUT_DISP_DIO, 0);
_tm1637_GPIOMODE_open_drain();
+ ack = (GPIOA->IDR & (1 << PINOUT_DISP_DIO)) == 0;
_tm1637_pin_write(PINOUT_DISP_CLK, 1);
_tm1637_pin_write(PINOUT_DISP_CLK, 0);
_tm1637_GPIOMODE_gp_output();
- return true;
+ return ack;
}
/**
@@ -70,7 +61,6 @@ bool _tm1637_ack() {
*/
TM1637Sequence _tm1637_send(TM1637Sequence command) {
TM1637Sequence response = { .data = 0, .length = 0 };
-
_tm1637_start();
for (uint32_t byte = 0; byte < command.length; byte++) {
@@ -79,11 +69,10 @@ TM1637Sequence _tm1637_send(TM1637Sequence command) {
_tm1637_pin_write(PINOUT_DISP_DIO, (command.data[byte] & (1 << bit)) >> bit);
_tm1637_pin_write(PINOUT_DISP_CLK, 1);
}
- //TODO: confirm ack
- /*bool ack =*/ _tm1637_ack();
+ bool ack = _tm1637_ack();
+ if (!ack) byte -= 1;
}
- // stop condition
_tm1637_stop();
return response;
@@ -111,3 +100,22 @@ void tm1637_segmentsend(uint8_t segment, uint8_t data) {
};
_tm1637_send(seq);
}
+
+void _tm1637_clear() {
+ for (unsigned int x = 0; x < 4; x++)
+ tm1637_segmentsend(x, 0);
+}
+
+void tm1637_begin() {
+ _tm1637_GPIOMODE_gp_output();
+
+ // general purpose output mode for clk
+ GPIOA->MODER &= ~(0b11 << (PINOUT_DISP_CLK * 2));
+ GPIOA->MODER |= (0b01 << (PINOUT_DISP_CLK * 2));
+
+ _tm1637_pin_write(PINOUT_DISP_CLK, 1);
+ _tm1637_pin_write(PINOUT_DISP_DIO, 1);
+
+ _tm1637_clear();
+}
+