Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (7.3 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 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

    
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
        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
}
94

    
95
/**
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
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
/**
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
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
/**
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
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
/**
147
 * Returns the current time count for the encoders.
148
 **/
149
int encoder_get_tc(void) {
150
        return timecount;
151
}
152

    
153
/**
154
 * Resets the time count for the encoders.
155
 **/
156
void encoder_rst_tc(void) {
157
        timecount = 0;
158
}
159

    
160

    
161
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
//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
        //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
                
220
        buf_index = (buf_index + 1) % 5;
221

    
222
        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
                        
228
                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
                        
232
                  left_data_buf = 0;
233
                right_data_buf = 0;
234

    
235
                
236
                if(left_data != INVALID && left_data != MAGNET_FAILURE) {
237
                        left_data_array_put(left_data);
238

    
239
                        //Adjust left accumulator
240
                        dx = left_data_array_prev() - left_data;
241
                        
242
                        //Adjust velocity: save last dx
243
                        left_v = left_dx;
244

    
245
                        if(left_data_array_prev()==0)  dx=0;
246

    
247
                        if(dx > 512) left_dx += dx - 1023; //Underflow
248
                        else if(dx < -512) left_dx += dx + 1023; //Overflow
249
                        else left_dx += dx;
250
                        
251
                        //Adjust velocity: update
252
                        left_v = left_dx - left_v;
253
                }
254

    
255
                if(right_data != INVALID && right_data != MAGNET_FAILURE) {
256
                        right_data_array_put(right_data);
257

    
258
                        //Adjust right accumulator
259
                        dx = right_data - right_data_array_prev();
260

    
261
                        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
                }
267
        }
268

    
269
        //Increment timecount accumulator
270
        timecount++;
271
}
272

    
273
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
//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
}
346