Project

General

Profile

Statistics
| Revision:

root / branches / encoders / code / projects / libdragonfly / encoders.c @ 844

History | View | Annotate | Download (7.66 KB)

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

    
6
unsigned int left_data_buf;
7
unsigned int right_data_buf;
8
char encoder_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
int left_v;
23
int right_v;
24

    
25

    
26
volatile short int data_ready;
27

    
28
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
   encoder_buf_index = 0;
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
  //delay_ms(ENCODER_DELAY);
52

    
53
   spi_transfer(5);
54
}
55

    
56
void put_bin(char data){
57
  int i;
58

    
59
  for(i=7;i>=0;i--)
60
    usb_puti((data>>i)&1);
61
  usb_puts(" ");
62
}
63

    
64
/**
65
 * Initializes the encoders variables
66
 **/
67
void encoders_init(void){
68
        int i;
69
        
70
        data_ready=0;
71

    
72
        spi_init(encoder_recv/*put_bin*/, encoder_recv_complete);
73
        encoder_buf_index = 0;
74
        left_data_buf = 0;
75
        right_data_buf= 0;
76
        left_data = -1;
77
        right_data = -1;
78
        
79
        
80
        left_v=0;
81
        right_v=0;
82
        
83
        //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
        //usb_puts("\tencoders.c Debug: ENCODERS INITIALIZED\n\r");
94
}
95

    
96
/**
97
 * Returns the specified encoders value
98
 *
99
 * @param encoder this is the encoder that you want to read. Valid arguments
100
 *          are LEFT and RIGHT
101
 *
102
 * @return the value of the specified encoder
103
 **/
104
int encoder_read(char encoder){
105
        if(encoder==LEFT){
106
                //usb_puts("\tencoders.c Debug: PRINTING LEFT ENCODER VALUE\n\r");
107
                return left_data;
108
        }
109
        else if(encoder==RIGHT){
110
                //usb_puts("\tencoders.c Debug: PRINTING RIGHT ENCODER VALUE\n\r");
111
                return right_data;
112
        }
113
        else{
114
                //usb_puts("\tencoders.c Debug: INVALID ENCODER - USE LEFT/RIGHT\n\r");
115
                 return -1;
116
        }
117
}
118

    
119
int encoder_change(char encoder){
120
        return 0;
121
}
122

    
123
char encoder_direction(char encoder){
124
        return 0;
125
}
126
/**
127
 * Gets the velocity of the specified encoder.
128
 *
129
 * @param encoder the encoder that you want to read, use LEFT or RIGHT
130
 *
131
 * @return The velocity of the specified encoder.
132
 **/
133
int encoder_get_dx(char encoder) {
134
        if(encoder==LEFT)
135
                return left_dx;
136
        else if(encoder==RIGHT)
137
                return right_dx;
138
        else return -1;
139
}
140

    
141
/**
142
 * Resets the value of the velocity global variable for the specified
143
 *  encoder.
144
 *
145
 * @param encoder the encoder that you want to modify
146
 **/
147
void encoder_rst_dx(char encoder) {
148
        if(encoder==LEFT)
149
                left_dx = 0;
150
        else if(encoder==RIGHT)
151
                right_dx = 0;
152
}
153

    
154
/**
155
 * Returns the current time count for the encoders.
156
 **/
157
int encoder_get_tc(void) {
158
        return timecount;
159
}
160

    
161
/**
162
 * Resets the time count for the encoders.
163
 **/
164
void encoder_rst_tc(void) {
165
        timecount = 0;
166
}
167

    
168

    
169
int encoder_get_v(char encoder){
170
        int last, res=0;
171
        
172
        cli();
173
        
174
        if(encoder==LEFT){
175
                if(left_data_idx==0)
176
                        last = BUFFER_SIZE - 1;
177
                else
178
                        last = left_data_idx - 1;
179
                res = ((int)left_data_array[last]) - ((int)left_data_array[left_data_idx]);
180
        }
181
        if(encoder==RIGHT){
182
                if(right_data_idx==0)
183
                        last = BUFFER_SIZE - 1;
184
                else
185
                        last = right_data_idx - 1;
186
                res = ((int)right_data_array[right_data_idx]) - ((int)right_data_array[last]);
187
        }
188
        
189
        sei();
190

    
191
        while(res<MIN_V)//underflow
192
                res+=1024;
193
        while(res>MAX_V)//overflow
194
                res-=1024;
195

    
196
        return res;
197
}
198

    
199
void encoder_wait(int n){
200
        while(data_ready<n);
201
        data_ready=0;
202
}
203

    
204

    
205
//Full reads occur every 40 microseconds. This function should be called
206
//every 8 microseconds.
207
void encoder_recv(char data){
208
        short int dx;
209
        
210
        //Parse the encoder data, comes in over 5 bytes 16 bits per encoder,
211
        // second is offset by 1 bit.
212
        switch(encoder_buf_index){        
213
        case 0: 
214
                right_data_buf |= ((short)data)<<8 & 0xff00;
215
                break;
216
        case 1:
217
                right_data_buf |= ((short)data) & 0xff;
218
                break;
219
        case 2:
220
                left_data_buf |= (((short)data) << 9) & (0x7F << 9);
221
                break;
222
        case 3:
223
                left_data_buf |= (((short)data) << 1) & (0xFF<<1);
224
                break;
225
        case 4: left_data_buf |= (((short)data)>>7) & 0x1;
226
        }        
227
                
228
        encoder_buf_index = (encoder_buf_index + 1) % 5;
229

    
230
        if(encoder_buf_index==0) {
231
                  
232
                if(left_data_buf & (COF | LIN) || !(left_data_buf & OCF))  left_data = INVALID;
233
                else if(((left_data_buf & MagINCn) > 0)  && ((left_data_buf & MagDECn) > 0)) left_data = MAGNET_FAILURE;
234
                else left_data = (left_data_buf>>5) & 1023;
235
                        
236
                if(right_data_buf & (COF | LIN) || !(right_data_buf & OCF)) right_data = INVALID;
237
                else if ( ((right_data_buf & MagINCn) > 0)  && ((right_data_buf & MagDECn) > 0)) right_data = MAGNET_FAILURE;
238
                else right_data = (right_data_buf>>5) & 1023;
239
                        
240
                  left_data_buf = 0;
241
                right_data_buf = 0;
242

    
243
                
244
                if(left_data != INVALID && left_data != MAGNET_FAILURE) {
245
                        left_data_array_put(left_data);
246

    
247
                        //Adjust left accumulator
248
                        dx = left_data_array_prev() - left_data;
249
                        
250
                        //Adjust velocity: save last dx
251
                        left_v = left_dx;
252

    
253
                        if(left_data_array_prev()==0)  dx=0;
254

    
255
                        if(dx > 512) left_dx += dx - 1023; //Underflow
256
                        else if(dx < -512) left_dx += dx + 1023; //Overflow
257
                        else left_dx += dx;
258
                        
259
                        //Adjust velocity: update
260
                        left_v = left_dx - left_v;
261
                }
262

    
263
                if(right_data != INVALID && right_data != MAGNET_FAILURE) {
264
                        right_data_array_put(right_data);
265

    
266
                        //Adjust right accumulator
267
                        dx = right_data - right_data_array_prev();
268

    
269
                        if(right_data_array_prev()==0) dx=0;
270
                          
271
                        if(dx > 512) right_dx += dx - 1023; //underflow
272
                        else if(dx < -512) right_dx += dx + 1023; //overflow 
273
                        else right_dx += dx;
274
                }
275
        }
276

    
277
        //Increment timecount accumulator
278
        timecount++;
279
}
280

    
281

    
282
void encoders_print_data_array(void){
283
        int i;
284
        usb_puts("Left Data: Pointer is ");
285
        usb_puti(left_data_idx);
286
        usb_puts("\n\r");
287
        for(i=0; i<BUFFER_SIZE; i++){
288
                usb_puti(left_data_array[i]);
289
                usb_putc(' ');
290
        }
291
        usb_puts("\r\n");
292
        usb_puts("Right Data: Pointer is");
293
        usb_puti(right_data_idx);
294
        usb_puts("\n\r");
295
        for(i=0; i<BUFFER_SIZE; i++){
296
                usb_puti(right_data_array[i]);
297
                usb_putc(' ');
298
        }
299
        usb_puts("\r\n\r\n");
300
}
301

    
302

    
303
//Helper Functions
304
inline void left_data_array_put(unsigned short int value) {
305
        if(left_data_idx == BUFFER_SIZE-1)
306
                left_data_idx = 0;
307
        else
308
                left_data_idx++;
309
        left_data_array[left_data_idx] = value;
310
}
311

    
312
inline unsigned int left_data_array_top(void) {
313
        return left_data_array[left_data_idx];
314
}
315

    
316
inline unsigned int left_data_array_prev(void) {
317
        if(left_data_idx == 0)
318
                return left_data_array[BUFFER_SIZE-1];
319
        else
320
                return left_data_array[left_data_idx - 1];
321
}
322

    
323
inline unsigned int left_data_array_bottom(void) {
324
        if(left_data_idx == BUFFER_SIZE-1)
325
                return left_data_array[0];
326
        else
327
                return left_data_array[left_data_idx + 1];
328
}
329

    
330
inline void right_data_array_put(unsigned short int value) {
331
        if(right_data_idx == BUFFER_SIZE-1)
332
                right_data_idx = 0;
333
        else
334
                right_data_idx++;
335
        right_data_array[right_data_idx] = value;
336
}
337

    
338
inline unsigned int right_data_array_top(void) {
339
        return right_data_array[right_data_idx];
340
}
341

    
342
inline unsigned int right_data_array_prev(void) {
343
        if(right_data_idx == 0)
344
                return right_data_array[BUFFER_SIZE-1];
345
        else
346
                return right_data_array[right_data_idx - 1];
347
}
348

    
349
inline unsigned int right_data_array_bottom(void) {
350
        if(right_data_idx == BUFFER_SIZE-1)
351
                return right_data_array[0];
352
        else
353
                return right_data_array[right_data_idx + 1];
354
}
355