forked from ahmetonat/STM32F10X-GCC-Encoder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathencoder.c
148 lines (120 loc) · 3.83 KB
/
encoder.c
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
144
145
146
147
148
#include "encoder.h"
//Retains the state of the keys for the encoder.
static __IO uint8_t keystate[NumKeys];
void init_ENC (void){
int i;
init_ENC_GPIO();
//TODO: Prepare a new init_ENC(), and place this into that function.
// Call init_ENC_GPIO from there.
for (i=0; i<NumKeys;++i){
keystate[i]=KeyAtRest;
// keyoldstate[i]=keystate[i];
}
}
//Fixed GPIO initialization code.
void init_ENC_GPIO (void){
GPIO_InitTypeDef GPIO_InitStruct;
// Enable GPIOA (ENC) Clock
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA, ENABLE );
GPIO_StructInit (&GPIO_InitStruct);
// Configure ENC pins
GPIO_InitStruct.GPIO_Pin = ENC_A_GPIO_PIN| ENC_B_GPIO_PIN| ENC_C_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //Input pull up.
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(ENC_GPIO_PORT, &GPIO_InitStruct);
}
//************* Functions *******************************************
void check_keypress(uint8_t key){
// Checks the button passed in the argument, and
// debounces it using a digital LPF.
// The decision is returned as the corresponding element of
// of the variable keystate[] (==KeyPressed or KeyAtRest)
int x;
int tmp;
int keyread;
// static __IO uint8_t key1dsp;
static uint8_t keydsp[NumKeys]; //Initialized to zero by compiler.
//This part depends on the hardware:
if (key==ENC_A){
keyread=GPIO_ReadInputDataBit (ENC_GPIO_PORT, ENC_A_GPIO_PIN);
}else if (key==ENC_B){
keyread=GPIO_ReadInputDataBit (ENC_GPIO_PORT, ENC_B_GPIO_PIN);
}else if (key==ENC_C){
keyread=GPIO_ReadInputDataBit (ENC_GPIO_PORT, ENC_C_GPIO_PIN);
}
if (keyread==KeyPressed){
x=0x3F;
}else{ //KeyAtIdle;
x=0;
}
// The LPF code is:
//y(t) = 0.25x(t)+0.75y(t) DSP based debounce.
//1.0=FF, 0.25=0x3F, 0.75y(t)= y(t)-(y(t)>>2)
tmp=(keydsp[key] >>2); //=key1state/4
keydsp[key]= x+keydsp[key]-tmp; //keydsp*3/4
//hysteresis:
if ((keydsp[key]>0xF0) && (keystate[key]==KeyAtRest)){
keystate[key]=KeyPressed;
} //else
if ((keydsp[key] <0x0F) && (keystate[key]==KeyPressed)){
keystate[key]=KeyAtRest;
}
}
int EncRead_Guarded(void){
int retval;
static int keyoldstate[NumKeys]; //Static to make it fast...
//If ENC_A is pressed:
keyoldstate[ENC_A]=keystate[ENC_A];
check_keypress(ENC_A);
keyoldstate[ENC_B]=keystate[ENC_B];
check_keypress(ENC_B);
keyoldstate[ENC_C]=keystate[ENC_C];
check_keypress(ENC_C);
retval=NOCHANGE;
// if(keyoldstate[ENC_C]!=keystate[ENC_C]){
if (keystate[ENC_C]==KeyPressed){
retval = CLICK; //Signal caller that encoder was pressed.
if(keyoldstate[ENC_A]!=keystate[ENC_A]){
if (keystate[ENC_A]==KeyPressed){ //Rising edge on A
//xprintf ("A+ ");
if(keystate[ENC_B]==KeyPressed){
//xprintf ("DN ");
retval = DOWN;
}else{
//xprintf ("UP ");
retval=UP;
}
}else if(keystate[ENC_A]==KeyAtRest) {//Falling edge on A
//xprintf ("A- ");
if(keystate[ENC_B]==KeyAtRest){
//xprintf ("DN ");
retval = DOWN;
}else{
//xprintf ("UP ");
retval=UP;
}
} // END: else if(keystate[ENC_A]==KeyAtRest)
} // END: if(keyoldstate[ENC_A]!=keystate[ENC_A])
} // END: if (keystate[ENC_C]==KeyPressed)
/* //The code below might be useful for debug.
// If ENC_B is pressed:
if(keyoldstate[ENC_B]!=keystate[ENC_B]){
if (keystate[ENC_B]==KeyPressed){
//xprintf ("B+ ");
}else{
//xprintf ("B- ");
}
} //END: if ENC_B
// If ENC_C is pressed:
if(keyoldstate[ENC_C]!=keystate[ENC_C]){
if (keystate[ENC_C]==KeyPressed){
//LED_ON();
//xprintf ("C+ ");
}else{
//LED_OFF();
//xprintf ("C- ");
}
} //END: if ENC_C
*/
return (retval);
}