Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / mapping / odometry / encoders.c @ 884

History | View | Annotate | Download (5.02 KB)

1
#include "encoders.h" 
2
#include "spi.h" 
3
#include <dragonfly_lib.h> 
4
#include "ring_buffer.h" 
5

    
6
unsigned short int left_data_buf;
7
unsigned short int right_data_buf;
8
char buf_index;
9

    
10
unsigned short int left_data;
11
unsigned short int right_data;
12

    
13
unsigned short int left_data_array[BUFFER_SIZE];
14
unsigned short int right_data_array[BUFFER_SIZE];
15
int left_data_idx;
16
int right_data_idx;
17

    
18
int left_dx;
19
int right_dx;
20
long int timecount;
21

    
22
void encoder_recv(char data);
23

    
24
//Helper Function Prototypes
25
inline void left_data_array_put(unsigned short int value);
26
inline unsigned short int left_data_array_top(void);
27
inline unsigned short int left_data_array_prev(void);
28
inline unsigned short int left_data_array_bottom(void);
29

    
30
inline void right_data_array_put(unsigned short int value);
31
inline unsigned short int right_data_array_top(void);
32
inline unsigned short int right_data_array_prev(void);
33
inline unsigned short int right_data_array_bottom(void);
34

    
35
//RING_BUFFER_NEW(enc_buffer, BUFFER_SIZE, short int);
36

    
37
void encoder_init(void){
38
        int i;
39

    
40
        spi_init(encoder_recv,NULL);
41
        buf_index = 0;
42
        left_data_buf = 0;
43
        right_data_buf= 0;
44
        left_data = -1;
45
        right_data = -1;
46
        //RING_BUFFER_INIT(enc_buffer,BUFFER_SIZE);
47
        left_data_idx = 0;
48
        right_data_idx = 0;
49
        for(i = 0; i < BUFFER_SIZE; i++) {
50
                left_data_array[i] = 0;
51
        }
52
        for(i = 0; i < BUFFER_SIZE; i++) {
53
                right_data_array[i] = 0;
54
        }
55
}
56

    
57
int encoder_read(char encoder){
58
        if(encoder==LEFT)
59
                return left_data;
60
        else if(encoder==RIGHT)
61
                return right_data;
62
        else return -1;
63
}
64

    
65
int encoder_change(char encoder){
66
        return 0;
67
}
68

    
69
char encoder_direction(char encoder){
70
        return 0;
71
}
72

    
73
int encoder_get_dx(char encoder) {
74
        if(encoder==LEFT)
75
                return left_dx;
76
        else if(encoder==RIGHT)
77
                return right_dx;
78
        else return -1;
79
}
80

    
81
void encoder_rst_dx(char encoder) {
82
        if(encoder==LEFT)
83
                left_dx = 0;
84
        else if(encoder==RIGHT)
85
                right_dx = 0;
86
}
87

    
88
int encoder_get_tc(void) {
89
        return timecount;
90
}
91

    
92
void encoder_rst_tc(void) {
93
        timecount = 0;
94
}
95

    
96

    
97

    
98
//Full reads occur every 40 microseconds. This function should be called
99
//every 8 microseconds.
100
void encoder_recv(char data){
101
        short int dx;
102

    
103
        //First two bytes are normal.        
104
        if(buf_index < 2)
105
                right_data_buf |= (((short)data) << ((1-buf_index)*8)) & (0xFF<<(1-buf_index));
106
        
107
        //Second two bytes are skewed by one junk bit at the top.         
108
        else if (buf_index == 2)
109
                left_data_buf |= (((short)data) << 9) & (0x7F << 9);
110
                
111
        else if (buf_index == 3)
112
                left_data_buf |= (((short)data) << 1) & (0xFF<<1);
113
        //Only want the highest bit.        
114
        else if (buf_index == 4)
115
                left_data_buf |= (((short)data)>>7) & 0x1;
116

    
117
        
118
        buf_index = (buf_index + 1) % 5;
119

    
120
        if(buf_index==0){
121
                if(left_data_buf & (OCF | COF | LIN)) 
122
                        left_data = INVALID;
123
                
124
                else if(((left_data_buf & MagINCn) > 0)  && ((left_data_buf & MagDECn) > 0)) 
125
                        left_data = MAGNET_FAILURE;
126
                
127
                else left_data = (left_data_buf>>5) & 1023;
128
                
129
                if(right_data_buf & (OCF | COF | LIN)) 
130
                        right_data = INVALID;
131
                
132
                else if ( ((left_data_buf & MagINCn) > 0)  && ((left_data_buf & MagDECn) > 0)) 
133
                        left_data = MAGNET_FAILURE;
134
                
135
                else right_data = (right_data_buf>>5) & 1023;
136
        
137
                                                        
138
                
139
                left_data_buf = 0;
140
                right_data_buf = 0;
141
        }
142

    
143
        
144
        if(left_data < INVALID) {
145
                //Put new data onto data array
146
                left_data_array_put(left_data);
147

    
148
                //Adjust left accumulator
149
                dx = left_data - left_data_array_prev();
150
                if(dx > 5) { //underflow
151
                        left_dx += dx - 1023;
152
                }
153
                else if(dx < -5) { //overflow
154
                        left_dx += dx + 1023;
155
                }
156
                else {
157
                        left_dx += dx;
158
                }
159
        }
160

    
161
        if(right_data < INVALID) {
162
                //Put new data onto data array
163
                right_data_array_put(right_data);
164

    
165
                //Adjust right accumulator
166
                dx = right_data - right_data_array_prev();
167
                if(dx > 5) { //underflow
168
                        right_dx += dx - 1023;
169
                }
170
                else if(dx < -5) { //overflow
171
                        right_dx += dx + 1023;
172
                }
173
                else {
174
                        right_dx += dx;
175
                }
176
        }
177

    
178
        //Increment timecount accumulator
179
        timecount++;
180
}
181

    
182
//Helper Functions
183
inline void left_data_array_put(unsigned short int value) {
184
        if(left_data_idx == BUFFER_SIZE-1)
185
                left_data_idx = 0;
186
        else
187
                left_data_idx++;
188
        left_data_array[left_data_idx] = value;
189
}
190

    
191
inline unsigned short int left_data_array_top(void) {
192
        return left_data_array[left_data_idx];
193
}
194

    
195
inline unsigned short int left_data_array_prev(void) {
196
        if(left_data_idx == 0)
197
                return left_data_array[BUFFER_SIZE-1];
198
        else
199
                return left_data_array[left_data_idx - 1];
200
}
201

    
202
inline unsigned short int left_data_array_bottom(void) {
203
        if(left_data_idx == BUFFER_SIZE-1)
204
                return left_data_array[0];
205
        else
206
                return left_data_array[left_data_idx + 1];
207
}
208

    
209
inline void right_data_array_put(unsigned short int value) {
210
        if(right_data_idx == BUFFER_SIZE-1)
211
                right_data_idx = 0;
212
        else
213
                right_data_idx++;
214
        right_data_array[right_data_idx] = value;
215
}
216

    
217
inline unsigned short int right_data_array_top(void) {
218
        return right_data_array[right_data_idx];
219
}
220

    
221
inline unsigned short int right_data_array_prev(void) {
222
        if(right_data_idx == 0)
223
                return right_data_array[BUFFER_SIZE-1];
224
        else
225
                return right_data_array[right_data_idx - 1];
226
}
227

    
228
inline unsigned short int right_data_array_bottom(void) {
229
        if(right_data_idx == BUFFER_SIZE-1)
230
                return right_data_array[0];
231
        else
232
                return right_data_array[right_data_idx + 1];
233
}