aboutsummaryrefslogtreecommitdiff
path: root/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui.c')
-rw-r--r--ui.c157
1 files changed, 88 insertions, 69 deletions
diff --git a/ui.c b/ui.c
index 57c75c5..0bfe7ba 100644
--- a/ui.c
+++ b/ui.c
@@ -14,13 +14,6 @@
#include "pwm.h"
#define sign(x) ((x < 0) ? -1 : 1)
-/* 10 seconds */
-#define SELECT_M1_INC 10
-/* 1 minute steps for mode 2 */
-#define SELECT_M2_INC 60
-/* start of mode 2, seconds */
-#define SELECT_M2_START (5*60)
-#define SELECT_MAX (60*60)
/* stop alarm after #seconds */
#define ALARM_TIME 30
@@ -30,7 +23,8 @@ typedef enum {
/* deep sleep */
UIMODE_SLEEP,
/* select time */
- UIMODE_SELECT,
+ UIMODE_SELECT_COARSE,
+ UIMODE_SELECT_FINE,
/* idle, showing time */
UIMODE_IDLE,
/* count time */
@@ -41,7 +35,10 @@ typedef enum {
static uimode mode = UIMODE_INIT;
/* timer seconds */
-static int16_t seconds = 0;
+static int16_t coarseSeconds = 0, fineSeconds = 0;
+static uint8_t step = 0, substep = 0;
+static uint16_t secPerSubstep = 0;
+static uint16_t substepsec = 0;
static horizon h = HORIZON_NONE;
static bool horizonChanged = false;
@@ -71,48 +68,53 @@ static uint8_t horizonLed (uint8_t i) {
}
}
-/*
- * We use the following LED coding (top to bottom):
- * 1-5 minutes: (off) (5m ) (4m ) (3m ) (2m ) (1m )
- * 5-60 minutes: (on ) (50m) (40m) (30m) (20m) (10m)
- */
-static void updateLeds () {
- if (seconds <= SELECT_M2_START) {
- const uint8_t minutes = seconds / 60;
- for (uint8_t i = 0; i < minutes; i++) {
- pwmSetBlink (horizonLed (i), PWM_BLINK_ON);
- }
- /* 10 second steps */
- pwmSetBlink (horizonLed (minutes), (seconds - minutes*60)/10);
- for (uint8_t i = minutes+1; i < PWM_LED_COUNT; i++) {
- pwmSetBlink (horizonLed (i), PWM_BLINK_OFF);
- }
+static int16_t limits (const int16_t in, const int16_t min, const int16_t max) {
+ if (in < min) {
+ return min;
+ } else if (in > max) {
+ return max;
} else {
- const uint8_t tenminutes = seconds/60/10;
+ return in;
+ }
+}
+
+/* Timer value selection
+ */
+static void doSelectCoarse () {
+ if (accelGetShakeCount () >= 2) {
+ /* stop selection */
+ accelResetShakeCount ();
+ mode = UIMODE_SELECT_FINE;
+ printf ("selectcoarse->selectfine(%i)\n", coarseSeconds);
+ return;
+ }
+
+ /* use zticks as seconds */
+ const int16_t zticks = gyroGetZTicks ();
+ if (abs (zticks) > 0) {
+ gyroResetZTicks ();
+ coarseSeconds = limits(coarseSeconds + zticks*60*5, 0, 60*60);
+ printf ("c:%it:%i\n", coarseSeconds, zticks);
+
+ const uint8_t tenminutes = coarseSeconds/60/10;
for (uint8_t i = 0; i < tenminutes; i++) {
pwmSetBlink (horizonLed (i), PWM_BLINK_ON);
}
- /* 2 minute steps */
- pwmSetBlink (horizonLed (tenminutes),
- (seconds - tenminutes*10*60)/60/2);
- for (uint8_t i = tenminutes+1; i < PWM_LED_COUNT-1; i++) {
+ for (uint8_t i = tenminutes; i < PWM_LED_COUNT; i++) {
pwmSetBlink (horizonLed (i), PWM_BLINK_OFF);
}
- pwmSetBlink (horizonLed (PWM_LED_COUNT-1), PWM_BLINK_ON);
}
}
-/* Timer value selection
- */
-static void doSelect () {
+static void doSelectFine () {
if (accelGetShakeCount () >= 2) {
/* stop selection */
accelResetShakeCount ();
+ step = 6;
+ substep = 3;
+ secPerSubstep = (coarseSeconds + fineSeconds)/(6*3);
mode = UIMODE_IDLE;
- printf ("select->idle(%i)\n", seconds);
- speakerStart ();
- _delay_ms (50);
- speakerStop ();
+ printf ("selectfine->idle(%u,%u)\n", coarseSeconds + fineSeconds, secPerSubstep);
return;
}
@@ -120,33 +122,28 @@ static void doSelect () {
const int16_t zticks = gyroGetZTicks ();
if (abs (zticks) > 0) {
gyroResetZTicks ();
- if (seconds > SELECT_M2_START) {
- const int16_t newseconds = seconds + sign (zticks) * SELECT_M2_INC;
- /* when decrementing one minute steps might be too much */
- if (newseconds < SELECT_M2_START) {
- seconds = SELECT_M2_START;
- } else {
- seconds = newseconds;
- }
- } else {
- /* 10 second steps */
- seconds += sign (zticks) * SELECT_M1_INC;
+ fineSeconds = limits(fineSeconds + zticks*30, -5*60, 5*60);
+ printf ("f:%it:%i\n", fineSeconds, zticks);
+
+ const uint8_t minutes = abs (fineSeconds)/60;
+ for (uint8_t i = 0; i < minutes; i++) {
+ pwmSetBlink (horizonLed (i), PWM_BLINK_ON);
}
- if (seconds < 0) {
- seconds = 0;
- } else if (seconds > SELECT_MAX) {
- seconds = SELECT_MAX;
+ for (uint8_t i = minutes; i < PWM_LED_COUNT-1; i++) {
+ pwmSetBlink (horizonLed (i), PWM_BLINK_OFF);
+ }
+ if (fineSeconds < 0) {
+ pwmSetBlink (horizonLed (PWM_LED_COUNT-1), PWM_BLINK_ON);
+ } else {
+ pwmSetBlink (horizonLed (PWM_LED_COUNT-1), PWM_BLINK_OFF);
}
- printf ("%i\n", seconds);
}
-
- updateLeds ();
}
/* Idle function, waits for timer start or select commands
*/
static void doIdle () {
- if (horizonChanged && seconds > 0) {
+ if (horizonChanged) {
/* start timer */
mode = UIMODE_RUN;
timerStart ();
@@ -157,7 +154,7 @@ static void doIdle () {
} else if (accelGetShakeCount () >= 2) {
/* set timer */
accelResetShakeCount ();
- mode = UIMODE_SELECT;
+ mode = UIMODE_SELECT_COARSE;
printf ("idle->select\n");
speakerStart ();
_delay_ms (50);
@@ -170,17 +167,33 @@ static void doIdle () {
*/
static void doRun () {
if (timerHit ()) {
- --seconds;
- printf ("run: %i\n", seconds);
- updateLeds ();
- if (seconds == 0) {
+ ++substepsec;
+ if (substepsec > secPerSubstep) {
+ --substep;
+ substepsec = 0;
+ }
+ if (substep == 0) {
+ --step;
+ substep = 3;
+ substepsec = 0;
+ }
+ printf("s:%uss:%u\n", step, substep);
+ if (step == 0) {
/* blink all leds */
for (uint8_t i = 0; i < PWM_LED_COUNT; i++) {
pwmSetBlink (i, 1);
}
- seconds = ALARM_TIME;
+ step = ALARM_TIME;
mode = UIMODE_ALARM;
printf ("run->alarm\n");
+ } else {
+ for (uint8_t i = 0; i < step-1; i++) {
+ pwmSetBlink (horizonLed (i), PWM_BLINK_ON);
+ }
+ pwmSetBlink (horizonLed (step-1), PWM_BLINK_ON);
+ for (uint8_t i = step; i < PWM_LED_COUNT; i++) {
+ pwmSetBlink (horizonLed (i), PWM_BLINK_OFF);
+ }
}
} else if (horizonChanged) {
/* stop timer */
@@ -193,11 +206,11 @@ static void doRun () {
*/
static void doAlarm () {
if (timerHit ()) {
- --seconds;
+ --step;
}
- if (horizonChanged || seconds == 0) {
+ if (horizonChanged || step == 0) {
timerStop ();
- seconds = 0;
+ step = 0;
/* stop blinking */
for (uint8_t i = 0; i < PWM_LED_COUNT; i++) {
pwmSetBlink (i, PWM_BLINK_OFF);
@@ -214,7 +227,9 @@ static void doInit () {
if (h != HORIZON_NONE) {
mode = UIMODE_IDLE;
printf ("init->idle\n");
- updateLeds ();
+ for (uint8_t i = 0; i < PWM_LED_COUNT; i++) {
+ pwmSetBlink (horizonLed (i), PWM_BLINK_OFF);
+ }
}
}
@@ -245,8 +260,12 @@ void uiLoop () {
doInit ();
break;
- case UIMODE_SELECT:
- doSelect ();
+ case UIMODE_SELECT_COARSE:
+ doSelectCoarse ();
+ break;
+
+ case UIMODE_SELECT_FINE:
+ doSelectFine ();
break;
case UIMODE_IDLE: