summaryrefslogtreecommitdiff
path: root/dim.c
blob: 21ea528c9f841e8f55c15b834bf6c498abca6a4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
struct switchcfg {
	uint8_t targets0[2];
	uint8_t targets1[2];
	uint8_t lastclick;
	int8_t dir;
	uint8_t tgt1active;
};

#define T_DOUBLECLICK 75
struct switchcfg sw;

static uint8_t tast_curstate(void)
{
	uint16_t sum = 0;
	sum += target_get(sw.targets0[0]);
	sum += target_get(sw.targets0[1]);
	if (sw.tgt1active) {
		sum += target_get(sw.targets1[0]);
		sum += target_get(sw.targets1[1]);
		sum++;
		sum >>= 1;
	}
	sum++;
	sum >>= 1;
	return sum;
}

static void tast_applystate(uint8_t all, uint8_t target)
{
	target_set(sw.targets0[0], target);
	target_set(sw.targets0[1], target);
	if (all) {
		target_set(sw.targets1[0], target);
		target_set(sw.targets1[1], target);
	}
}

static void tast_click(void)
{
	uint8_t ltarget, all;

	uart_puts("# click\n");
	if (sw.lastclick < T_DOUBLECLICK) {
		sw.lastclick = T_DOUBLECLICK;
		sw.tgt1active = 1;
		sw.dir = -1;
		ltarget = 0xff;
		all = 1;
	} else {
		sw.lastclick = 0;
		ltarget = tast_curstate();
		if (ltarget) {
			sw.tgt1active = 0;
			sw.dir = +1;
			ltarget = 0;
			all = 1;
		} else {
			sw.dir = -1;
			ltarget = 0xff;
			all = 0;
		}
	}
	tast_applystate(all, ltarget);
}

static void do_tick(void)
{
	static uint8_t history;
	static uint8_t downctr;
	uint8_t state;

	history <<= 1;
	history |= (PIND >> D_TAST) & 1;

	if (sw.lastclick < 0xff)
		sw.lastclick++;

	if (history & 0x3f) {
		if (!downctr)
			return;
		if (downctr < 60) {
			//PORTD &= ~(1 << D_LED1);
			tast_click();
		} else
			sw.dir = -sw.dir;

		downctr = 0;
		return;
	}

	if (downctr < 60) {
		PORTD |= (1 << D_LED1);
		downctr++;
	} else {
		state = tast_curstate();
		PORTD &= ~(1 << D_LED1);

		uart_puts("\t# dim ");
		uart_puthex(state);
		uart_puts(" ");
		uart_puthex(sw.dir);
		uart_puts("\n");
		for (int i = 0; i < 6; i++) {
			state += sw.dir;
			if (state == 0xff)
				state = 0xfe;
			if (state < 0x55)
				state = 0x55;
		}
		tast_applystate(sw.tgt1active, state);
	}
}

static void dim_init(void)
{
	sw.targets0[0] = 0x03;
	sw.targets0[1] = 0x04;
	sw.targets1[0] = 0x01;
	sw.targets1[1] = 0x02;
	sw.lastclick = 0xff;
	sw.dir = 1;
	sw.tgt1active = 0;
}