Project

General

Profile

Statistics
| Revision:

root / branches / encoders / code / lib / src / libdragonfly / encoders.c @ 809

History | View | Annotate | Download (7.3 KB)

1 749 bneuman
#include "encoders.h"
2
#include "spi.h"
3
#include <dragonfly_lib.h>
4
#include "ring_buffer.h"
5 546 kwoo
6 749 bneuman
unsigned int left_data_buf;
7
unsigned int right_data_buf;
8
char buf_index;
9
10
unsigned int left_data;
11
unsigned int right_data;
12
13
unsigned int left_data_array[BUFFER_SIZE];
14
unsigned 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 771 bneuman
int left_v;
23
int right_v;
24
25
26
volatile short int data_ready;
27
28 749 bneuman
void encoder_recv(char data);
29
30
//Helper Function Prototypes
31
inline void left_data_array_put(unsigned short int value);
32
inline unsigned int left_data_array_top(void);
33
inline unsigned int left_data_array_prev(void);
34
inline unsigned int left_data_array_bottom(void);
35
36
inline void right_data_array_put(unsigned short int value);
37
inline unsigned int right_data_array_top(void);
38
inline unsigned int right_data_array_prev(void);
39
inline unsigned int right_data_array_bottom(void);
40
41
//RING_BUFFER_NEW(enc_buffer, BUFFER_SIZE, short int);
42
43
void encoder_recv_complete(void);
44
45
void encoder_recv_complete(){
46 771 bneuman
47
   //  usb_puts("[");usb_puti(left_dx);usb_puts(",");usb_puti(right_dx);usb_puts("]\r\n");
48
   //   usb_puts("\r\n");
49
  data_ready++;
50
51 809 justin
  //delay_ms(ENCODER_DELAY);
52 771 bneuman
53
   spi_transfer(5);
54 749 bneuman
}
55
56 752 bneuman
void put_bin(char data){
57
  int i;
58 749 bneuman
59 752 bneuman
  for(i=7;i>=0;i--)
60
    usb_puti((data>>i)&1);
61
  usb_puts(" ");
62
}
63
64 809 justin
/**
65
 * Initializes the encoders variables
66
 **/
67 749 bneuman
void encoders_init(void){
68
        int i;
69 771 bneuman
70
        data_ready=0;
71 749 bneuman
72 752 bneuman
        spi_init(encoder_recv/*put_bin*/, encoder_recv_complete);
73 749 bneuman
        buf_index = 0;
74
        left_data_buf = 0;
75
        right_data_buf= 0;
76
        left_data = -1;
77
        right_data = -1;
78 771 bneuman
79
80
        left_v=0;
81
        right_v=0;
82
83 749 bneuman
        //RING_BUFFER_INIT(enc_buffer,BUFFER_SIZE);
84
        left_data_idx = 0;
85
        right_data_idx = 0;
86
        for(i = 0; i < BUFFER_SIZE; i++) {
87
                left_data_array[i] = 0;
88
        }
89
        for(i = 0; i < BUFFER_SIZE; i++) {
90
                right_data_array[i] = 0;
91
        }
92
        spi_transfer(5);
93
}
94
95 809 justin
/**
96
 * Returns the specified encoders value
97
 *
98
 * @param encoder this is the encoder that you want to read. Valid arguments
99
 *          are LEFT and RIGHT
100
 *
101
 * @return the value of the specified encoder
102
 **/
103 749 bneuman
int encoder_read(char encoder){
104
        if(encoder==LEFT)
105
                return left_data;
106
        else if(encoder==RIGHT)
107
                return right_data;
108
        else return -1;
109
}
110
111
int encoder_change(char encoder){
112
        return 0;
113
}
114
115
char encoder_direction(char encoder){
116
        return 0;
117
}
118 809 justin
/**
119
 * Gets the velocity of the specified encoder.
120
 *
121
 * @param encoder the encoder that you want to read, use LEFT or RIGHT
122
 *
123
 * @return The velocity of the specified encoder.
124
 **/
125 749 bneuman
int encoder_get_dx(char encoder) {
126
        if(encoder==LEFT)
127
                return left_dx;
128
        else if(encoder==RIGHT)
129
                return right_dx;
130
        else return -1;
131
}
132
133 809 justin
/**
134
 * Resets the value of the velocity global variable for the specified
135
 *  encoder.
136
 *
137
 * @param encoder the encoder that you want to modify
138
 **/
139 749 bneuman
void encoder_rst_dx(char encoder) {
140
        if(encoder==LEFT)
141
                left_dx = 0;
142
        else if(encoder==RIGHT)
143
                right_dx = 0;
144
}
145
146 809 justin
/**
147
 * Returns the current time count for the encoders.
148
 **/
149 749 bneuman
int encoder_get_tc(void) {
150
        return timecount;
151
}
152
153 809 justin
/**
154
 * Resets the time count for the encoders.
155
 **/
156 749 bneuman
void encoder_rst_tc(void) {
157
        timecount = 0;
158
}
159
160
161 771 bneuman
int encoder_get_v(char encoder){
162
        int last, res=0;
163
164
        cli();
165
166
        if(encoder==LEFT){
167
                if(left_data_idx==0)
168
                        last = BUFFER_SIZE - 1;
169
                else
170
                        last = left_data_idx - 1;
171
                res = ((int)left_data_array[last]) - ((int)left_data_array[left_data_idx]);
172
        }
173
        if(encoder==RIGHT){
174
                if(right_data_idx==0)
175
                        last = BUFFER_SIZE - 1;
176
                else
177
                        last = right_data_idx - 1;
178
                res = ((int)right_data_array[right_data_idx]) - ((int)right_data_array[last]);
179
        }
180
181
        sei();
182
183
        while(res<MIN_V)//underflow
184
                res+=1024;
185
        while(res>MAX_V)//overflow
186
                res-=1024;
187
188
        return res;
189
}
190
191
void encoder_wait(int n){
192
        while(data_ready<n);
193
        data_ready=0;
194
}
195
196
197 749 bneuman
//Full reads occur every 40 microseconds. This function should be called
198
//every 8 microseconds.
199
void encoder_recv(char data){
200
        short int dx;
201
202 809 justin
        //Parse the encoder data, comes in over 5 bytes 16 bits per encoder,
203
        // second is offset by 1 bit.
204
        switch(buf_index){
205
        case 0:
206
                right_data_buf |= ((short)data)<<8 & 0xff00;
207
                break;
208
        case 1:
209
                right_data_buf |= ((short)data) & 0xff;
210
                break;
211
        case 2:
212
                left_data_buf |= (((short)data) << 9) & (0x7F << 9);
213
                break;
214
        case 3:
215
                left_data_buf |= (((short)data) << 1) & (0xFF<<1);
216
                break;
217
        case 4: left_data_buf |= (((short)data)>>7) & 0x1;
218
        }
219 771 bneuman
220 809 justin
        buf_index = (buf_index + 1) % 5;
221 752 bneuman
222 809 justin
        if(buf_index==0) {
223
224
                if(left_data_buf & (COF | LIN) || !(left_data_buf & OCF))  left_data = INVALID;
225
                else if(((left_data_buf & MagINCn) > 0)  && ((left_data_buf & MagDECn) > 0)) left_data = MAGNET_FAILURE;
226
                else left_data = (left_data_buf>>5) & 1023;
227 771 bneuman
228 809 justin
                if(right_data_buf & (COF | LIN) || !(right_data_buf & OCF)) right_data = INVALID;
229
                else if ( ((right_data_buf & MagINCn) > 0)  && ((right_data_buf & MagDECn) > 0)) right_data = MAGNET_FAILURE;
230
                else right_data = (right_data_buf>>5) & 1023;
231 771 bneuman
232 809 justin
                  left_data_buf = 0;
233
                right_data_buf = 0;
234 749 bneuman
235 771 bneuman
236 809 justin
                if(left_data != INVALID && left_data != MAGNET_FAILURE) {
237 771 bneuman
                        left_data_array_put(left_data);
238 752 bneuman
239 771 bneuman
                        //Adjust left accumulator
240
                        dx = left_data_array_prev() - left_data;
241
242
                        //Adjust velocity: save last dx
243
                        left_v = left_dx;
244 752 bneuman
245 809 justin
                        if(left_data_array_prev()==0)  dx=0;
246 752 bneuman
247 809 justin
                        if(dx > 512) left_dx += dx - 1023; //Underflow
248
                        else if(dx < -512) left_dx += dx + 1023; //Overflow
249
                        else left_dx += dx;
250 771 bneuman
251
                        //Adjust velocity: update
252
                        left_v = left_dx - left_v;
253 749 bneuman
                }
254
255 809 justin
                if(right_data != INVALID && right_data != MAGNET_FAILURE) {
256 771 bneuman
                        right_data_array_put(right_data);
257 749 bneuman
258 771 bneuman
                        //Adjust right accumulator
259
                        dx = right_data - right_data_array_prev();
260 752 bneuman
261 809 justin
                        if(right_data_array_prev()==0) dx=0;
262
263
                        if(dx > 512) right_dx += dx - 1023; //underflow
264
                        else if(dx < -512) right_dx += dx + 1023; //overflow
265
                        else right_dx += dx;
266 749 bneuman
                }
267 809 justin
        }
268 749 bneuman
269 809 justin
        //Increment timecount accumulator
270
        timecount++;
271 749 bneuman
}
272
273 809 justin
void encoders_print_data_array(void){
274
        int i;
275
        usb_puts("Left Data: Pointer is ");
276
        usb_puti(left_data_idx);
277
        usb_puts("\n\r");
278
        for(i=0; i<BUFFER_SIZE; i++){
279
                usb_puti(left_data_array[i]);
280
                usb_putc(' ');
281
        }
282
        usb_puts("\r\n");
283
        usb_puts("Right Data: Pointer is");
284
        usb_puti(right_data_idx);
285
        usb_puts("\n\r");
286
        for(i=0; i<BUFFER_SIZE; i++){
287
                usb_puti(right_data_array[i]);
288
                usb_putc(' ');
289
        }
290
        usb_puts("\r\n\r\n");
291
}
292
293
294 749 bneuman
//Helper Functions
295
inline void left_data_array_put(unsigned short int value) {
296
        if(left_data_idx == BUFFER_SIZE-1)
297
                left_data_idx = 0;
298
        else
299
                left_data_idx++;
300
        left_data_array[left_data_idx] = value;
301
}
302
303
inline unsigned int left_data_array_top(void) {
304
        return left_data_array[left_data_idx];
305
}
306
307
inline unsigned int left_data_array_prev(void) {
308
        if(left_data_idx == 0)
309
                return left_data_array[BUFFER_SIZE-1];
310
        else
311
                return left_data_array[left_data_idx - 1];
312
}
313
314
inline unsigned int left_data_array_bottom(void) {
315
        if(left_data_idx == BUFFER_SIZE-1)
316
                return left_data_array[0];
317
        else
318
                return left_data_array[left_data_idx + 1];
319
}
320
321
inline void right_data_array_put(unsigned short int value) {
322
        if(right_data_idx == BUFFER_SIZE-1)
323
                right_data_idx = 0;
324
        else
325
                right_data_idx++;
326
        right_data_array[right_data_idx] = value;
327
}
328
329
inline unsigned int right_data_array_top(void) {
330
        return right_data_array[right_data_idx];
331
}
332
333
inline unsigned int right_data_array_prev(void) {
334
        if(right_data_idx == 0)
335
                return right_data_array[BUFFER_SIZE-1];
336
        else
337
                return right_data_array[right_data_idx - 1];
338
}
339
340
inline unsigned int right_data_array_bottom(void) {
341
        if(right_data_idx == BUFFER_SIZE-1)
342
                return right_data_array[0];
343
        else
344
                return right_data_array[right_data_idx + 1];
345
}