Subversion Repositories shark

Rev

Rev 730 | Rev 733 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
281 giacomo 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Giacomo Guidi       <giacomo@gandalf.sssup.it>
381 giacomo 10
 *   Mauro Marinoni      <mauro.marinoni@unipv.it>
281 giacomo 11
 *   (see the web pages for full authors list)
12
 *
13
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
14
 *
15
 * http://www.sssup.it
16
 * http://retis.sssup.it
17
 * http://shark.sssup.it
18
 */
19
 
20
/*
21
 * Copyright (C) 2002 Paolo Gai
22
 *
23
 * This program is free software; you can redistribute it and/or modify
24
 * it under the terms of the GNU General Public License as published by
25
 * the Free Software Foundation; either version 2 of the License, or
26
 * (at your option) any later version.
27
 *
28
 * This program is distributed in the hope that it will be useful,
29
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31
 * GNU General Public License for more details.
32
 *
33
 * You should have received a copy of the GNU General Public License
34
 * along with this program; if not, write to the Free Software
35
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
36
 *
37
 */
38
 
282 giacomo 39
#include "kernel/kern.h"
281 giacomo 40
 
717 giacomo 41
#include "drivers/scom.h"
42
#include "drivers/scomirq.h"
281 giacomo 43
 
717 giacomo 44
#include "servo.h"
286 giacomo 45
 
358 giacomo 46
//#define SERVO_DEBUG
286 giacomo 47
 
398 giacomo 48
#define SERVO_SPEED 19200
286 giacomo 49
#define SERVO_PARITY NONE
50
#define SERVO_LEN 8
51
#define SERVO_STOP 1
282 giacomo 52
 
358 giacomo 53
#define SERVO_CLOCK 20000000 /* 20MHz */
54
 
315 giacomo 55
#define TICK_LEN 1600 /* ns */
316 giacomo 56
#define TICK_LEN_PERIOD 51200 /* ns */
290 giacomo 57
 
58
struct servo_data {
59
  int min_angle_sec;
60
  int max_angle_sec;
61
  int delta_tick;
62
  int zero_tick;
63
};
64
 
381 giacomo 65
struct servo_data servo_table[4][16] = {
66
  {{-324000, 324000, 1200, 1600},
316 giacomo 67
  {-324000, 324000, 1200, 1600},
68
  {-324000, 324000, 1200, 1600},
69
  {-324000, 324000, 1200, 1600},
70
  {-324000, 324000, 1200, 1600},
71
  {-324000, 324000, 1200, 1600},
72
  {-324000, 324000, 1200, 1600},
73
  {-324000, 324000, 1200, 1600},
335 giacomo 74
  {-324000, 324000, 1200, 1600},
75
  {-324000, 324000, 1200, 1600},
76
  {-324000, 324000, 1200, 1600},
77
  {-324000, 324000, 1200, 1600},
78
  {-324000, 324000, 1200, 1600},
79
  {-324000, 324000, 1200, 1600},
80
  {-324000, 324000, 1200, 1600},
381 giacomo 81
  {-324000, 324000, 1200, 1600}},
82
  {{-324000, 324000, 1200, 1600},
335 giacomo 83
  {-324000, 324000, 1200, 1600},
381 giacomo 84
  {-324000, 324000, 1200, 1600},
85
  {-324000, 324000, 1200, 1600},
86
  {-324000, 324000, 1200, 1600},
87
  {-324000, 324000, 1200, 1600},
88
  {-324000, 324000, 1200, 1600},
89
  {-324000, 324000, 1200, 1600},
90
  {-324000, 324000, 1200, 1600},
91
  {-324000, 324000, 1200, 1600},
92
  {-324000, 324000, 1200, 1600},
93
  {-324000, 324000, 1200, 1600},
94
  {-324000, 324000, 1200, 1600},
95
  {-324000, 324000, 1200, 1600},
96
  {-324000, 324000, 1200, 1600},
97
  {-324000, 324000, 1200, 1600}},
98
  {{-324000, 324000, 1200, 1600},
99
  {-324000, 324000, 1200, 1600},
100
  {-324000, 324000, 1200, 1600},
101
  {-324000, 324000, 1200, 1600},
102
  {-324000, 324000, 1200, 1600},
103
  {-324000, 324000, 1200, 1600},
104
  {-324000, 324000, 1200, 1600},
105
  {-324000, 324000, 1200, 1600},
106
  {-324000, 324000, 1200, 1600},
107
  {-324000, 324000, 1200, 1600},
108
  {-324000, 324000, 1200, 1600},
109
  {-324000, 324000, 1200, 1600},
110
  {-324000, 324000, 1200, 1600},
111
  {-324000, 324000, 1200, 1600},
112
  {-324000, 324000, 1200, 1600},
113
  {-324000, 324000, 1200, 1600}},
114
  {{-324000, 324000, 1200, 1600},
115
  {-324000, 324000, 1200, 1600},
116
  {-324000, 324000, 1200, 1600},
117
  {-324000, 324000, 1200, 1600},
118
  {-324000, 324000, 1200, 1600},
119
  {-324000, 324000, 1200, 1600},
120
  {-324000, 324000, 1200, 1600},
121
  {-324000, 324000, 1200, 1600},
122
  {-324000, 324000, 1200, 1600},
123
  {-324000, 324000, 1200, 1600},
124
  {-324000, 324000, 1200, 1600},
125
  {-324000, 324000, 1200, 1600},
126
  {-324000, 324000, 1200, 1600},
127
  {-324000, 324000, 1200, 1600},
128
  {-324000, 324000, 1200, 1600},
129
  {-324000, 324000, 1200, 1600}}};
290 giacomo 130
 
730 giacomo 131
//#define SERVO_TIMEOUT 10000
132
 
717 giacomo 133
#define RXTX_BUFF_MAX 100
726 giacomo 134
volatile static BYTE RXTX_buff[4][RXTX_BUFF_MAX];
135
volatile static BYTE *RXTX_addr[4][RXTX_BUFF_MAX];
725 giacomo 136
volatile unsigned int RX_position[4] = {0,0,0,0};
137
volatile unsigned int TX_position[4] = {0,0,0,0};
730 giacomo 138
volatile unsigned int RX_cycle[4] =  {0,0,0,0};
139
volatile unsigned int TX_cycle[4] =  {0,0,0,0};
728 giacomo 140
volatile unsigned int servo_skip[4] = {0,0,0,0};
141
volatile unsigned int lock_write[4] = {0,0,0,0};
730 giacomo 142
volatile int servo_timer[4] = {NIL,NIL,NIL,NIL};
286 giacomo 143
 
144
const int BaudTable[] = {
145
        1200,
146
        2400,
147
        4800,
148
        9600,
149
        14400,
150
        19200,
151
        38400,
152
        57600,
153
        115200,
154
        -1};
155
 
721 giacomo 156
void servo_rx_error(unsigned port, unsigned type) {
292 giacomo 157
 
721 giacomo 158
  kern_printf("(SERVO: BUFFER ERROR PORT:%d ERR:%d)",port,type);
717 giacomo 159
 
281 giacomo 160
}
161
 
717 giacomo 162
void servo_indication(unsigned port, BYTE data) {
727 giacomo 163
 
717 giacomo 164
 if (RXTX_addr[port][RX_position[port]] == NULL) {
165
   if (data != RXTX_buff[port][RX_position[port]])
721 giacomo 166
     servo_rx_error(port,1);
726 giacomo 167
 
717 giacomo 168
   RX_position[port]++;
721 giacomo 169
 
170
   if (RX_position[port] >= RXTX_BUFF_MAX) {
730 giacomo 171
        RX_cycle[port]++;
721 giacomo 172
        RX_position[port] = 0;
173
   }
730 giacomo 174
   if ((RX_cycle[port] == TX_cycle[port] && RX_position[port] > TX_position[port]) ||
175
        (RX_cycle[port] > TX_cycle[port]))
721 giacomo 176
     servo_rx_error(port,2);
177
 
717 giacomo 178
 } else {
179
   *RXTX_addr[port][RX_position[port]] = data;
726 giacomo 180
   RXTX_buff[port][RX_position[port]]  = 1; //Unlock the data
181
 
717 giacomo 182
   RX_position[port]++;
721 giacomo 183
 
184
   if (RX_position[port] >= RXTX_BUFF_MAX) {
730 giacomo 185
        RX_cycle[port]++;
721 giacomo 186
        RX_position[port] = 0;
187
   }
730 giacomo 188
   if ((RX_cycle[port] == TX_cycle[port] && RX_position[port] > TX_position[port]) ||
189
        (RX_cycle[port] > TX_cycle[port]))
727 giacomo 190
     servo_rx_error(port,3);
726 giacomo 191
 
717 giacomo 192
 }
295 giacomo 193
 
286 giacomo 194
}
195
 
730 giacomo 196
extern unsigned SCom_Error[4];
727 giacomo 197
 
717 giacomo 198
void servo_confirm(unsigned port, BYTE msg_status) {
286 giacomo 199
 
727 giacomo 200
  if (msg_status == COM_ERROR) {
730 giacomo 201
    kern_printf("(SERVO: PORT:%d ERROR:%d)",port,SCom_Error[port]);
727 giacomo 202
  }
286 giacomo 203
 
730 giacomo 204
  lock_write[port] = 0;
727 giacomo 205
 
717 giacomo 206
}
207
 
208
int servo_send_msg(unsigned port, BYTE *msg, unsigned len_msg, BYTE *res, unsigned len_res) {
209
 
726 giacomo 210
  int i = 0, old, oldcycle, RX = 0;
721 giacomo 211
  SYS_FLAGS f;
212
 
728 giacomo 213
  while(lock_write[port] == 1);
214
  lock_write[port] = 1;
727 giacomo 215
 
721 giacomo 216
  f = kern_fsave();
217
 
717 giacomo 218
  old = TX_position[port];
730 giacomo 219
  oldcycle = TX_cycle[port];
717 giacomo 220
 
221
  while(i < len_msg) {
222
    RXTX_buff[port][TX_position[port]] = msg[i];
223
    RXTX_addr[port][TX_position[port]] = NULL;
224
    TX_position[port]++;
721 giacomo 225
    if (TX_position[port] >= RXTX_BUFF_MAX) {
730 giacomo 226
        TX_cycle[port]++;
721 giacomo 227
        TX_position[port] = 0;
228
    }
717 giacomo 229
    if (TX_position[port] == RX_position[port]) {
230
        TX_position[port] = old;
730 giacomo 231
        TX_cycle[port] = oldcycle;
232
        lock_write[port] = 0;
721 giacomo 233
        kern_frestore(f);
717 giacomo 234
        return -1;
235
    }
236
    i++;
237
  }
238
 
239
  i = 0;
240
  while(i < len_res) {
726 giacomo 241
    RXTX_buff[port][TX_position[port]] = 0; //Lock the data
717 giacomo 242
    RXTX_addr[port][TX_position[port]] = res+i;
726 giacomo 243
    RX = TX_position[port];
717 giacomo 244
    TX_position[port]++;
721 giacomo 245
    if (TX_position[port] >= RXTX_BUFF_MAX) {
730 giacomo 246
        TX_cycle[port]++;
721 giacomo 247
        TX_position[port] = 0;
248
    }
717 giacomo 249
    if (TX_position[port] == RX_position[port]) {
250
        TX_position[port] = old;
730 giacomo 251
        TX_cycle[port] = oldcycle;
252
        lock_write[port] = 0;
721 giacomo 253
        kern_frestore(f);
717 giacomo 254
        return -1;
255
    }
256
    i++;
257
  }
258
 
721 giacomo 259
  kern_frestore(f);
260
 
717 giacomo 261
  com_irq_send(port, len_msg, msg);
262
 
725 giacomo 263
  return RX;
264
 
265
}
266
 
730 giacomo 267
void servo_timeout(void *arg) {
268
 
269
  unsigned port = (unsigned)(arg);
270
 
271
  servo_timer[port] = NIL;
272
  servo_skip[port] = 1;
273
 
274
  kern_printf("(SERVO: TIMEOUT PORT:%d)",port);
275
 
276
}
277
 
726 giacomo 278
int servo_wait(unsigned port, int RX) {
725 giacomo 279
 
730 giacomo 280
  #ifdef SERVO_TIMEOUT
281
    struct timespec acttime;
282
  #endif
728 giacomo 283
  servo_skip[port] = 0;
727 giacomo 284
 
730 giacomo 285
  #ifdef SERVO_TIMEOUT
286
    kern_gettime(&acttime);
287
    ADDUSEC2TIMESPEC(SERVO_TIMEOUT,&acttime);
288
    servo_timer[port] = kern_event_post(&acttime,servo_timeout,(void *)(port));
289
  #endif
290
 
725 giacomo 291
  /* Active wait until number bytes received */
728 giacomo 292
  while (RXTX_buff[port][RX] == 0 && servo_skip[port] == 0);
725 giacomo 293
 
730 giacomo 294
  #ifdef SERVO_TIMEOUT
295
  if (servo_timer[port] != NIL)
296
    kern_event_delete(servo_timer[port]);
297
  #endif
298
 
286 giacomo 299
  return 0;
300
 
301
}
302
 
358 giacomo 303
int servo_open(int port,int speed)
286 giacomo 304
{
305
  int err;
306
 
358 giacomo 307
  err = com_open((unsigned)(port), (DWORD)speed, SERVO_PARITY, SERVO_LEN, SERVO_STOP);
308
 
717 giacomo 309
  com_init_irq((unsigned)(port));
310
 
311
  com_set_functions(servo_confirm,servo_indication);
312
 
721 giacomo 313
  com_irq_enable((unsigned)(port),ALL_IRQ);
314
 
286 giacomo 315
  return err;
316
 
317
}
318
 
358 giacomo 319
int servo_close(int port)
286 giacomo 320
{
321
  int err;
322
 
724 giacomo 323
  com_irq_disable((unsigned)(port),ALL_IRQ);
324
 
717 giacomo 325
  com_close_irq((unsigned)(port));
326
 
358 giacomo 327
  err = com_close((unsigned)(port));
286 giacomo 328
 
329
  return err;
330
 
331
}
332
 
333
/* 1000.011w:bbbb.bbbb */
358 giacomo 334
int servo_set_RS232_baudrate(int port, int baud)
281 giacomo 335
{
724 giacomo 336
  unsigned char b[2];
337
  int spbrg_temp, i;
286 giacomo 338
  unsigned char spbrg, w;
358 giacomo 339
  int servo_port = (unsigned)(port);
286 giacomo 340
 
341
  i = 0;
342
  while(BaudTable[i] != baud && BaudTable[i] != -1) i++;
343
  if (BaudTable[i] == -1) {
344
    kern_printf("SERVO:Error wrong baud rate\n");
345
    return -1;
346
  }
347
 
358 giacomo 348
  w = 1;
453 giacomo 349
  spbrg_temp = (SERVO_CLOCK*10 / (16*baud)) - 10;
412 giacomo 350
  if (spbrg_temp>2550) {
358 giacomo 351
    w = 0;
453 giacomo 352
    spbrg_temp = (SERVO_CLOCK*10 / (64*baud)) - 10;
286 giacomo 353
  }
412 giacomo 354
  spbrg = spbrg_temp / 10;
453 giacomo 355
  if (spbrg_temp % 10 > 5) spbrg++;
412 giacomo 356
 
286 giacomo 357
  #ifdef SERVO_DEBUG
358
    kern_printf("(SERVO:SBPRG %d W %d)",spbrg,w);
358 giacomo 359
  #endif
360
 
724 giacomo 361
  b[0] = 0x86 | (w & 0x01);
362
  b[1] = spbrg;
363
  servo_send_msg(servo_port, b, 2, NULL, 0);
358 giacomo 364
 
724 giacomo 365
  return 0;
381 giacomo 366
 
281 giacomo 367
}
368
 
285 giacomo 369
/* 1000.0101 */
358 giacomo 370
int servo_get_RS232_baudrate(int port)
281 giacomo 371
{
724 giacomo 372
  unsigned char b[1],r[2];
373
  int res, res_w, res_b;
358 giacomo 374
  int servo_port = (unsigned)(port);
725 giacomo 375
  int RX;
358 giacomo 376
 
724 giacomo 377
  b[0] = 0x85;
725 giacomo 378
  RX = servo_send_msg(servo_port, b, 1, r, 2);
358 giacomo 379
 
732 giacomo 380
  if (RX != -1) {
381
 
382
    servo_wait(servo_port, RX);
383
 
384
    if (servo_skip[port] == 0) {
725 giacomo 385
 
732 giacomo 386
      res_w = r[0]; /* bit W */
387
      res_b = r[1]; /* byte SPBRG */
465 giacomo 388
 
732 giacomo 389
      if (res_w != -1 && res_b != -1) {
390
        if (res_w)
391
          res = SERVO_CLOCK / ( 16 * (res_b + 1) );
392
        else
393
          res = SERVO_CLOCK / ( 64 * (res_b + 1) );
394
      } else {
395
        return -1;
396
      }
358 giacomo 397
 
732 giacomo 398
      return res;
358 giacomo 399
 
732 giacomo 400
    } else return -1;
401
 
402
  } else return -1;
403
 
281 giacomo 404
}
405
 
286 giacomo 406
/* 1000.0100 */
358 giacomo 407
int servo_store_RS232_baudrate(int port)
281 giacomo 408
{
724 giacomo 409
  unsigned char b[1];
358 giacomo 410
  int servo_port = (unsigned)(port);
411
 
724 giacomo 412
  b[0] = 0x84;
413
  servo_send_msg(servo_port, b, 1, NULL, 0);
414
 
415
  return 0;
358 giacomo 416
 
281 giacomo 417
}
418
 
289 giacomo 419
/* 1000.1010:llll.llll */
358 giacomo 420
int servo_set_period(int port, int period)
281 giacomo 421
{
724 giacomo 422
  unsigned char b[2];
358 giacomo 423
  int servo_port = (unsigned)(port);
424
 
724 giacomo 425
  b[0] = 0x8A;
426
  b[1] = (period*1000)/TICK_LEN_PERIOD/8 & 0xFF;
427
  servo_send_msg(servo_port, b, 2, NULL, 0);  
381 giacomo 428
 
724 giacomo 429
  return 0;
358 giacomo 430
 
281 giacomo 431
}
432
 
285 giacomo 433
/* 1000.1001 */
358 giacomo 434
int servo_get_period(int port)
281 giacomo 435
{
724 giacomo 436
  unsigned char b[1],r[1];
725 giacomo 437
  int res, RX;
358 giacomo 438
  int servo_port = (unsigned)(port);
439
 
724 giacomo 440
  b[0] = 0x89;
725 giacomo 441
  RX = servo_send_msg(servo_port, b, 1, r, 1);
358 giacomo 442
 
732 giacomo 443
  if (RX != -1) {
444
 
445
    servo_wait(servo_port, RX);
446
 
447
    if (servo_skip[port] == 0) {
725 giacomo 448
 
732 giacomo 449
      res = r[0];
381 giacomo 450
 
732 giacomo 451
      return (((unsigned char)(res))*TICK_LEN_PERIOD/1000*8);
358 giacomo 452
 
732 giacomo 453
    } else return -1;
454
 
455
  } else return -1;
456
 
281 giacomo 457
}
458
 
289 giacomo 459
/* 1000.1000 */
358 giacomo 460
int servo_store_period(int port)
281 giacomo 461
{
724 giacomo 462
  unsigned char b[1];
358 giacomo 463
  int servo_port = (unsigned)(port);
464
 
724 giacomo 465
  b[0] = 0x88;
466
  servo_send_msg(servo_port, b, 1, NULL, 0);
358 giacomo 467
 
724 giacomo 468
  return 0;
381 giacomo 469
 
281 giacomo 470
}
471
 
283 giacomo 472
/* 1000.1100 */
358 giacomo 473
int servo_get_setup_switch(int port)
281 giacomo 474
{
724 giacomo 475
  unsigned char b[1],r[1];
725 giacomo 476
  int res, RX;
358 giacomo 477
  int servo_port = (unsigned)(port);
478
 
724 giacomo 479
  b[0] = 0x8C;
725 giacomo 480
  RX = servo_send_msg(servo_port, b, 1, r, 1);  
281 giacomo 481
 
732 giacomo 482
  if (RX != -1) {
483
 
484
    servo_wait(servo_port, RX);
485
 
486
    if (servo_skip[port] == 0) {
725 giacomo 487
 
732 giacomo 488
       res = r[0];
281 giacomo 489
 
732 giacomo 490
       return res;
283 giacomo 491
 
732 giacomo 492
    } else return -1;
493
 
494
  } else return -1;
495
 
281 giacomo 496
}
497
 
283 giacomo 498
/* 1000.111s */
358 giacomo 499
int servo_set_RC5_switch(int port, int data)
281 giacomo 500
{
724 giacomo 501
  unsigned char b[1];
358 giacomo 502
  int servo_port = (unsigned)(port);
503
 
724 giacomo 504
  b[0] = 0x8E | (data & 0x01);
505
  servo_send_msg(servo_port, b, 1, NULL, 0);
281 giacomo 506
 
724 giacomo 507
  return 0;
381 giacomo 508
 
281 giacomo 509
}
510
 
323 giacomo 511
/* 1000.0000:0000.Mmmm */
358 giacomo 512
int servo_turn_off(int port, int servo)
285 giacomo 513
{
724 giacomo 514
  unsigned char b[2];
358 giacomo 515
  int servo_port = (unsigned)(port);
516
 
517
  if (servo > 15) return -1;
724 giacomo 518
 
519
  b[0] = 0x80;
520
  b[1] = 0x00 | (servo & 0x0F);
521
  servo_send_msg(servo_port, b, 2, NULL, 0);
381 giacomo 522
 
724 giacomo 523
  return 0;
285 giacomo 524
 
525
}
526
 
325 giacomo 527
/* 1000.0000:0001.Mmmm */
358 giacomo 528
int servo_turn_on(int port, int servo)
285 giacomo 529
{
721 giacomo 530
  unsigned char b[2];
358 giacomo 531
  int servo_port = (unsigned)(port);
532
 
323 giacomo 533
  if (servo > 15) return -1;
358 giacomo 534
 
721 giacomo 535
  b[0] = 0x80;
536
  b[1] = 0x10 | (servo & 0x0F);
537
  servo_send_msg(servo_port, b, 2, NULL, 0);
358 giacomo 538
 
721 giacomo 539
  return 0;
358 giacomo 540
 
285 giacomo 541
}
542
 
291 giacomo 543
/* 1000.0000:0010.0000 */
358 giacomo 544
int servo_turn_off_all(int port)
323 giacomo 545
{
724 giacomo 546
  unsigned char b[2];
358 giacomo 547
  int servo_port = (unsigned)(port);
548
 
724 giacomo 549
  b[0] = 0x80;
550
  b[1] = 0x20;
551
  servo_send_msg(servo_port, b, 2, NULL, 0);
358 giacomo 552
 
724 giacomo 553
  return 0;
358 giacomo 554
 
285 giacomo 555
}
556
 
291 giacomo 557
/* 1000.0000:0010.0001 */
358 giacomo 558
int servo_turn_on_all(int port)
285 giacomo 559
{
724 giacomo 560
  unsigned char b[2];
358 giacomo 561
  int servo_port = (unsigned)(port);
562
 
724 giacomo 563
  b[0] = 0x80;
564
  b[1] = 0x21;
565
  servo_send_msg(servo_port, b, 2, NULL, 0);
566
 
567
  return 0;
358 giacomo 568
 
285 giacomo 569
}
570
 
323 giacomo 571
/* 1000.0000:0101.000M:mmmm.mmmm */
724 giacomo 572
int servo_set_levels(int port, int bank, int mask)
315 giacomo 573
{
724 giacomo 574
  unsigned char b[3];
358 giacomo 575
  int servo_port = (unsigned)(port);
576
 
724 giacomo 577
  b[0] = 0x80;
578
  b[1] = 0x50 | (0x01 & bank);
579
  b[2] = (unsigned char)(mask & 0xFF);
580
  servo_send_msg(servo_port, b, 3, NULL, 0);
358 giacomo 581
 
724 giacomo 582
  return 0;
358 giacomo 583
 
315 giacomo 584
}
585
 
323 giacomo 586
/* 1000.0000:0100.000M */
358 giacomo 587
int servo_get_levels(int port, int bank)
297 giacomo 588
{
724 giacomo 589
  unsigned char b[2],r[1];
725 giacomo 590
  int res, RX;
358 giacomo 591
  int servo_port = (unsigned)(port);
592
 
724 giacomo 593
  b[0] = 0x80;
594
  b[1] = 0x40 | (0x01 & bank);
725 giacomo 595
  RX = servo_send_msg(servo_port, b, 2, r, 1);
596
 
732 giacomo 597
  if (RX != -1) {
598
 
599
    servo_wait(servo_port, RX);
600
 
601
    if (servo_skip[port] == 0) {
358 giacomo 602
 
732 giacomo 603
      res = r[0];
358 giacomo 604
 
732 giacomo 605
      return res;
606
 
607
    } else return -1;
608
 
609
  } else return -1;
610
 
297 giacomo 611
}
612
 
613
/* 1000.0000:1000.0000 */
358 giacomo 614
int servo_store_levels(int port)
297 giacomo 615
{
724 giacomo 616
  unsigned char b[2];
358 giacomo 617
  int servo_port = (unsigned)(port);
618
 
724 giacomo 619
  b[0] = 0x80;
620
  b[1] = 0x80;
621
  servo_send_msg(servo_port, b, 2, NULL, 0);
381 giacomo 622
 
724 giacomo 623
  return 0;
358 giacomo 624
 
297 giacomo 625
}
626
 
493 giacomo 627
int servo_set_max_angle_sec(int port, int servo, int angle_sec)
290 giacomo 628
{
629
 
381 giacomo 630
  servo_table[port][servo].max_angle_sec = angle_sec;
290 giacomo 631
  return 0;
632
 
633
}
634
 
493 giacomo 635
int servo_set_min_angle_sec(int port, int servo, int angle_sec)
290 giacomo 636
{
637
 
381 giacomo 638
  servo_table[port][servo].min_angle_sec = angle_sec;
290 giacomo 639
  return 0;
640
 
641
}
642
 
381 giacomo 643
int servo_set_servo_tick(int port, int servo, int zero_tick, int delta_tick)
644
{
645
 
646
  if (zero_tick != -1) servo_table[port][servo].zero_tick = zero_tick;
647
  if (delta_tick != -1) servo_table[port][servo].delta_tick = delta_tick;
648
  return 0;
649
 
650
}
651
 
323 giacomo 652
/* 0000.Pppp:0000.vvvv:vvvv.vvvv */
358 giacomo 653
int servo_set_angle_sec(int port, int servo, int angle_sec)
281 giacomo 654
{
717 giacomo 655
  unsigned char b[3];
730 giacomo 656
  int angle_tick, res = 0;
358 giacomo 657
  int servo_port = (unsigned)(port);
282 giacomo 658
 
323 giacomo 659
  if (servo > 15) return -1;
282 giacomo 660
 
381 giacomo 661
  angle_tick = (servo_table[port][servo].zero_tick + angle_sec *
662
                servo_table[port][servo].delta_tick /
542 giacomo 663
                (servo_table[port][servo].max_angle_sec - servo_table[port][servo].min_angle_sec)) * 1000 / TICK_LEN;
290 giacomo 664
 
717 giacomo 665
  b[0] = 0x00 | (servo & 0x0F);
666
  b[1] = 0x00 | ((angle_tick >> 8) & 0x0F);
667
  b[2] = 0x00 | (angle_tick & 0xFF);
730 giacomo 668
  res = servo_send_msg(servo_port, b, 3, NULL, 0);
358 giacomo 669
 
730 giacomo 670
  return res;
282 giacomo 671
 
281 giacomo 672
}
673
 
323 giacomo 674
/* 0010.Pppp */
358 giacomo 675
int servo_store_default_position(int port, int servo)
290 giacomo 676
{
724 giacomo 677
  unsigned char b[1];
730 giacomo 678
  int res = 0;
358 giacomo 679
  int servo_port = (unsigned)(port);
290 giacomo 680
 
323 giacomo 681
  if (servo > 15) return -1;
358 giacomo 682
 
724 giacomo 683
  b[0] = 0x20 | (servo & 0x0F);
730 giacomo 684
  res = servo_send_msg(servo_port, b, 1, NULL, 0);  
358 giacomo 685
 
730 giacomo 686
  return res;
358 giacomo 687
 
290 giacomo 688
}
689
 
323 giacomo 690
/* 0001.Pppp */
358 giacomo 691
int servo_get_angle_sec(int port, int servo)
281 giacomo 692
{
724 giacomo 693
  unsigned char b[1],r[2];
725 giacomo 694
  int res,data,RX;
358 giacomo 695
  int servo_port = (unsigned)(port);
696
 
323 giacomo 697
  if (servo > 15) return -1;
358 giacomo 698
 
724 giacomo 699
  b[0] = 0x10 | (servo & 0x0F);
725 giacomo 700
  RX = servo_send_msg(servo_port, b, 1, r, 2);
281 giacomo 701
 
730 giacomo 702
  if (RX != -1) {
725 giacomo 703
 
730 giacomo 704
    servo_wait(servo_port, RX);
282 giacomo 705
 
730 giacomo 706
    if (servo_skip[port] == 0) {
290 giacomo 707
 
730 giacomo 708
      res = (int)(r[0]) << 8;
709
      res |= r[1];
282 giacomo 710
 
730 giacomo 711
      data = ((res*TICK_LEN/1000) - servo_table[port][servo].zero_tick) *
712
              (servo_table[port][servo].max_angle_sec - servo_table[port][servo].min_angle_sec) /
713
               servo_table[port][servo].delta_tick;
714
 
715
      return data;
716
 
717
    } else return -1;
718
 
719
  } else return -1;
720
 
281 giacomo 721
}
722
 
282 giacomo 723
/* 0100:0aaa */
358 giacomo 724
int servo_get_analog(int port, int adport)
281 giacomo 725
{
724 giacomo 726
  unsigned char b[1],r[2];
725 giacomo 727
  int res, RX;
358 giacomo 728
  int servo_port = (unsigned)(port);
729
 
381 giacomo 730
  if (adport > 7) return -1;
358 giacomo 731
 
724 giacomo 732
  b[0] = 0x40 | (adport & 0x07);
725 giacomo 733
  RX = servo_send_msg(servo_port, b, 1, r, 2);
281 giacomo 734
 
732 giacomo 735
  if (RX != -1) {
725 giacomo 736
 
732 giacomo 737
    servo_wait(servo_port, RX);
282 giacomo 738
 
732 giacomo 739
    if (servo_skip[port] == 0) {
282 giacomo 740
 
732 giacomo 741
      res = (int)r[0] << 8;
742
      res |= r[1];
743
 
744
      return res;
745
 
746
    } else return -1;
747
 
748
  } else return -1;
749
 
281 giacomo 750
}
751