-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathswitches.c
More file actions
143 lines (107 loc) · 3.37 KB
/
switches.c
File metadata and controls
143 lines (107 loc) · 3.37 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <stdlib.h>
#include <stdio.h>
#include <avr/io.h>
#include <stdint.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "event.h"
/*
* Protos
*/
//void switches_read(uint16_t t);
/*
* Global variables, representing the debounced switch state and changes
*/
volatile uint8_t sw_porta = 0;
volatile uint8_t sw_portb = 0;
volatile int8_t sw_enc_delta;
/*
* These variables hold the current state of the keys and is used to check
* If a key is pressed at a point in time.
*/
volatile uint8_t sw_porta_state = 0, sw_portb_state = 0;
void inline switches_init(void)
{
printf("switches_init()\n\r");
/* Setup the ports */
DDRA = 0x00; // All pins are INPUT
PORTA = 0xFF; // Enable pull ups
DDRB = 0; // All pins are INPUT
PORTB = 0xFF; // Enable pull ups
printf("switches_init() - exit\n\r");
}
static inline void switches_encoder()
{
static uint8_t last_state = 0,last_cnt = 0;
uint8_t new_state;
new_state=PINB & (_BV(PINB1) | _BV(PINB0));
if ((new_state^last_cnt)==(_BV(PINB1) | _BV(PINB0)) )
{
if ((new_state ^ last_state)==_BV(PINB1))
{
sw_enc_delta += 1;
}
else
{
sw_enc_delta -= 1;
}
last_cnt=new_state;
}
last_state=new_state;
}
/*
* This function is called by the Timer 1 interrupt service routine
* to handle the button debouncing
*/
void switches_tick()
{
/* Read the input pins */
static uint8_t porta_ct0 = 0, portb_ct0 = 0, porta_ct1 = 0, portb_ct1 = 0;
uint8_t porta_now, portb_now;
/*
* read current state of keys (active-low),
* clear corresponding bit in i when key has changed
*/
porta_now = sw_porta_state ^ ~PINA; // key changed ?
/*
* ct0 and ct1 form a two bit counter for each key,
* where ct0 holds LSB and ct1 holds MSB
* After a key is pressed longer than four times the
* sampling period, the corresponding bit in key_state is set
*/
porta_ct0 = ~( porta_ct0 & porta_now ); // reset or count ct0
porta_ct1 = (porta_ct0 ^ porta_ct1) & porta_now; // reset or count ct1
porta_now &= porta_ct0 & porta_ct1; // count until roll over ?
sw_porta_state ^= porta_now; // then toggle debounced state
/*
* To notify main program of pressed key, the correspondig bit
* in global variable key_press is set.
* The main loop needs to clear this bit
*/
sw_porta |= sw_porta_state & porta_now; // 0->1: key press detect
/*
* And now PORTB
*/
/*
* read current state of keys (active-low),
* clear corresponding bit in i when key has changed
*/
portb_now = sw_portb_state ^ ~PINB; // key changed ?
/*
* ct0 and ct1 form a two bit counter for each key,
* where ct0 holds LSB and ct1 holds MSB
* After a key is pressed longer than four times the
* sampling period, the corresponding bit in key_state is set
*/
portb_ct0 = ~( portb_ct0 & portb_now ); // reset or count ct0
portb_ct1 = (portb_ct0 ^ portb_ct1) & portb_now; // reset or count ct1
portb_now &= portb_ct0 & portb_ct1; // count until roll over ?
sw_portb_state ^= portb_now; // then toggle debounced state
/*
* To notify main program of pressed key, the correspondig bit
* in global variable key_press is set.
* The main loop needs to clear this bit
*/
sw_portb |= sw_portb_state & portb_now;
switches_encoder();
}