Subversion Repositories shark

Rev

Rev 726 | Rev 728 | 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
 
717 giacomo 131
#define RXTX_BUFF_MAX 100
726 giacomo 132
volatile static BYTE RXTX_buff[4][RXTX_BUFF_MAX];
133
volatile static BYTE *RXTX_addr[4][RXTX_BUFF_MAX];
725 giacomo 134
volatile unsigned int RX_position[4] = {0,0,0,0};
135
volatile unsigned int TX_position[4] = {0,0,0,0};
136
volatile unsigned int RX_cycle = 0;
137
volatile unsigned int TX_cycle = 0;
727 giacomo 138
volatile unsigned int servo_skip = 0;
139
volatile unsigned int lock_write = 0;
286 giacomo 140
 
141
const int BaudTable[] = {
142
        1200,
143
        2400,
144
        4800,
145
        9600,
146
        14400,
147
        19200,
148
        38400,
149
        57600,
150
        115200,
151
        -1};
152
 
721 giacomo 153
void servo_rx_error(unsigned port, unsigned type) {
292 giacomo 154
 
721 giacomo 155
  kern_printf("(SERVO: BUFFER ERROR PORT:%d ERR:%d)",port,type);
717 giacomo 156
 
281 giacomo 157
}
158
 
717 giacomo 159
void servo_indication(unsigned port, BYTE data) {
727 giacomo 160
 
717 giacomo 161
 if (RXTX_addr[port][RX_position[port]] == NULL) {
162
   if (data != RXTX_buff[port][RX_position[port]])
721 giacomo 163
     servo_rx_error(port,1);
726 giacomo 164
 
717 giacomo 165
   RX_position[port]++;
721 giacomo 166
 
167
   if (RX_position[port] >= RXTX_BUFF_MAX) {
168
        RX_cycle++;
169
        RX_position[port] = 0;
170
   }
171
   if ((RX_cycle == TX_cycle && RX_position[port] > TX_position[port]) ||
172
        (RX_cycle > TX_cycle))
173
     servo_rx_error(port,2);
174
 
717 giacomo 175
 } else {
176
   *RXTX_addr[port][RX_position[port]] = data;
726 giacomo 177
   RXTX_buff[port][RX_position[port]]  = 1; //Unlock the data
178
 
717 giacomo 179
   RX_position[port]++;
721 giacomo 180
 
181
   if (RX_position[port] >= RXTX_BUFF_MAX) {
182
        RX_cycle++;
183
        RX_position[port] = 0;
184
   }
185
   if ((RX_cycle == TX_cycle && RX_position[port] > TX_position[port]) ||
186
        (RX_cycle > TX_cycle))
727 giacomo 187
     servo_rx_error(port,3);
726 giacomo 188
 
717 giacomo 189
 }
295 giacomo 190
 
286 giacomo 191
}
192
 
727 giacomo 193
extern int SCom_Error;
194
 
717 giacomo 195
void servo_confirm(unsigned port, BYTE msg_status) {
286 giacomo 196
 
727 giacomo 197
  if (msg_status == COM_ERROR) {
198
    kern_printf("(SERVO: PORT:%d ERROR:%d)",port,SCom_Error);
199
    servo_skip = 1;
200
  }
286 giacomo 201
 
727 giacomo 202
  if (msg_status == COM_OK) {
203
    lock_write = 0;
204
  }
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
 
727 giacomo 213
  while(lock_write == 1);
214
  lock_write = 1;
215
 
721 giacomo 216
  f = kern_fsave();
217
 
717 giacomo 218
  old = TX_position[port];
721 giacomo 219
  oldcycle = TX_cycle;
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) {
226
        TX_cycle++;
227
        TX_position[port] = 0;
228
    }
717 giacomo 229
    if (TX_position[port] == RX_position[port]) {
230
        TX_position[port] = old;
721 giacomo 231
        TX_cycle = oldcycle;
232
        kern_frestore(f);
717 giacomo 233
        return -1;
234
    }
235
    i++;
236
  }
237
 
238
  i = 0;
239
  while(i < len_res) {
726 giacomo 240
    RXTX_buff[port][TX_position[port]] = 0; //Lock the data
717 giacomo 241
    RXTX_addr[port][TX_position[port]] = res+i;
726 giacomo 242
    RX = TX_position[port];
717 giacomo 243
    TX_position[port]++;
721 giacomo 244
    if (TX_position[port] >= RXTX_BUFF_MAX) {
245
        TX_cycle++;
246
        TX_position[port] = 0;
247
    }
717 giacomo 248
    if (TX_position[port] == RX_position[port]) {
249
        TX_position[port] = old;
721 giacomo 250
        TX_cycle = oldcycle;
251
        kern_frestore(f);
717 giacomo 252
        return -1;
253
    }
254
    i++;
255
  }
256
 
721 giacomo 257
  kern_frestore(f);
258
 
717 giacomo 259
  com_irq_send(port, len_msg, msg);
260
 
725 giacomo 261
  return RX;
262
 
263
}
264
 
726 giacomo 265
int servo_wait(unsigned port, int RX) {
725 giacomo 266
 
727 giacomo 267
  servo_skip = 0;
268
 
725 giacomo 269
  /* Active wait until number bytes received */
727 giacomo 270
  while (RXTX_buff[port][RX] == 0 && servo_skip == 0);
725 giacomo 271
 
286 giacomo 272
  return 0;
273
 
274
}
275
 
358 giacomo 276
int servo_open(int port,int speed)
286 giacomo 277
{
278
  int err;
279
 
358 giacomo 280
  err = com_open((unsigned)(port), (DWORD)speed, SERVO_PARITY, SERVO_LEN, SERVO_STOP);
281
 
717 giacomo 282
  com_init_irq((unsigned)(port));
283
 
284
  com_set_functions(servo_confirm,servo_indication);
285
 
721 giacomo 286
  com_irq_enable((unsigned)(port),ALL_IRQ);
287
 
286 giacomo 288
  return err;
289
 
290
}
291
 
358 giacomo 292
int servo_close(int port)
286 giacomo 293
{
294
  int err;
295
 
724 giacomo 296
  com_irq_disable((unsigned)(port),ALL_IRQ);
297
 
717 giacomo 298
  com_close_irq((unsigned)(port));
299
 
358 giacomo 300
  err = com_close((unsigned)(port));
286 giacomo 301
 
302
  return err;
303
 
304
}
305
 
306
/* 1000.011w:bbbb.bbbb */
358 giacomo 307
int servo_set_RS232_baudrate(int port, int baud)
281 giacomo 308
{
724 giacomo 309
  unsigned char b[2];
310
  int spbrg_temp, i;
286 giacomo 311
  unsigned char spbrg, w;
358 giacomo 312
  int servo_port = (unsigned)(port);
286 giacomo 313
 
314
  i = 0;
315
  while(BaudTable[i] != baud && BaudTable[i] != -1) i++;
316
  if (BaudTable[i] == -1) {
317
    kern_printf("SERVO:Error wrong baud rate\n");
318
    return -1;
319
  }
320
 
358 giacomo 321
  w = 1;
453 giacomo 322
  spbrg_temp = (SERVO_CLOCK*10 / (16*baud)) - 10;
412 giacomo 323
  if (spbrg_temp>2550) {
358 giacomo 324
    w = 0;
453 giacomo 325
    spbrg_temp = (SERVO_CLOCK*10 / (64*baud)) - 10;
286 giacomo 326
  }
412 giacomo 327
  spbrg = spbrg_temp / 10;
453 giacomo 328
  if (spbrg_temp % 10 > 5) spbrg++;
412 giacomo 329
 
286 giacomo 330
  #ifdef SERVO_DEBUG
331
    kern_printf("(SERVO:SBPRG %d W %d)",spbrg,w);
358 giacomo 332
  #endif
333
 
724 giacomo 334
  b[0] = 0x86 | (w & 0x01);
335
  b[1] = spbrg;
336
  servo_send_msg(servo_port, b, 2, NULL, 0);
358 giacomo 337
 
724 giacomo 338
  return 0;
381 giacomo 339
 
281 giacomo 340
}
341
 
285 giacomo 342
/* 1000.0101 */
358 giacomo 343
int servo_get_RS232_baudrate(int port)
281 giacomo 344
{
724 giacomo 345
  unsigned char b[1],r[2];
346
  int res, res_w, res_b;
358 giacomo 347
  int servo_port = (unsigned)(port);
725 giacomo 348
  int RX;
358 giacomo 349
 
724 giacomo 350
  b[0] = 0x85;
725 giacomo 351
  RX = servo_send_msg(servo_port, b, 1, r, 2);
358 giacomo 352
 
726 giacomo 353
  servo_wait(servo_port, RX);
725 giacomo 354
 
724 giacomo 355
  res_w = r[0]; /* bit W */
356
  res_b = r[1]; /* byte SPBRG */
465 giacomo 357
 
358
  if (res_w != -1 && res_b != -1) {
359
    if (res_w)
360
      res = SERVO_CLOCK / ( 16 * (res_b + 1) );
361
    else
362
      res = SERVO_CLOCK / ( 64 * (res_b + 1) );
363
  } else {
364
    return -1;
365
  }
358 giacomo 366
 
724 giacomo 367
  return res;
358 giacomo 368
 
281 giacomo 369
}
370
 
286 giacomo 371
/* 1000.0100 */
358 giacomo 372
int servo_store_RS232_baudrate(int port)
281 giacomo 373
{
724 giacomo 374
  unsigned char b[1];
358 giacomo 375
  int servo_port = (unsigned)(port);
376
 
724 giacomo 377
  b[0] = 0x84;
378
  servo_send_msg(servo_port, b, 1, NULL, 0);
379
 
380
  return 0;
358 giacomo 381
 
281 giacomo 382
}
383
 
289 giacomo 384
/* 1000.1010:llll.llll */
358 giacomo 385
int servo_set_period(int port, int period)
281 giacomo 386
{
724 giacomo 387
  unsigned char b[2];
358 giacomo 388
  int servo_port = (unsigned)(port);
389
 
724 giacomo 390
  b[0] = 0x8A;
391
  b[1] = (period*1000)/TICK_LEN_PERIOD/8 & 0xFF;
392
  servo_send_msg(servo_port, b, 2, NULL, 0);  
381 giacomo 393
 
724 giacomo 394
  return 0;
358 giacomo 395
 
281 giacomo 396
}
397
 
285 giacomo 398
/* 1000.1001 */
358 giacomo 399
int servo_get_period(int port)
281 giacomo 400
{
724 giacomo 401
  unsigned char b[1],r[1];
725 giacomo 402
  int res, RX;
358 giacomo 403
  int servo_port = (unsigned)(port);
404
 
724 giacomo 405
  b[0] = 0x89;
725 giacomo 406
  RX = servo_send_msg(servo_port, b, 1, r, 1);
358 giacomo 407
 
726 giacomo 408
  servo_wait(servo_port, RX);
725 giacomo 409
 
724 giacomo 410
  res = r[0];
381 giacomo 411
 
724 giacomo 412
  return (((unsigned char)(res))*TICK_LEN_PERIOD/1000*8);
358 giacomo 413
 
281 giacomo 414
}
415
 
289 giacomo 416
/* 1000.1000 */
358 giacomo 417
int servo_store_period(int port)
281 giacomo 418
{
724 giacomo 419
  unsigned char b[1];
358 giacomo 420
  int servo_port = (unsigned)(port);
421
 
724 giacomo 422
  b[0] = 0x88;
423
  servo_send_msg(servo_port, b, 1, NULL, 0);
358 giacomo 424
 
724 giacomo 425
  return 0;
381 giacomo 426
 
281 giacomo 427
}
428
 
283 giacomo 429
/* 1000.1100 */
358 giacomo 430
int servo_get_setup_switch(int port)
281 giacomo 431
{
724 giacomo 432
  unsigned char b[1],r[1];
725 giacomo 433
  int res, RX;
358 giacomo 434
  int servo_port = (unsigned)(port);
435
 
724 giacomo 436
  b[0] = 0x8C;
725 giacomo 437
  RX = servo_send_msg(servo_port, b, 1, r, 1);  
281 giacomo 438
 
726 giacomo 439
  servo_wait(servo_port, RX);
725 giacomo 440
 
724 giacomo 441
  res = r[0];
281 giacomo 442
 
724 giacomo 443
  return res;
283 giacomo 444
 
281 giacomo 445
}
446
 
283 giacomo 447
/* 1000.111s */
358 giacomo 448
int servo_set_RC5_switch(int port, int data)
281 giacomo 449
{
724 giacomo 450
  unsigned char b[1];
358 giacomo 451
  int servo_port = (unsigned)(port);
452
 
724 giacomo 453
  b[0] = 0x8E | (data & 0x01);
454
  servo_send_msg(servo_port, b, 1, NULL, 0);
281 giacomo 455
 
724 giacomo 456
  return 0;
381 giacomo 457
 
281 giacomo 458
}
459
 
323 giacomo 460
/* 1000.0000:0000.Mmmm */
358 giacomo 461
int servo_turn_off(int port, int servo)
285 giacomo 462
{
724 giacomo 463
  unsigned char b[2];
358 giacomo 464
  int servo_port = (unsigned)(port);
465
 
466
  if (servo > 15) return -1;
724 giacomo 467
 
468
  b[0] = 0x80;
469
  b[1] = 0x00 | (servo & 0x0F);
470
  servo_send_msg(servo_port, b, 2, NULL, 0);
381 giacomo 471
 
724 giacomo 472
  return 0;
285 giacomo 473
 
474
}
475
 
325 giacomo 476
/* 1000.0000:0001.Mmmm */
358 giacomo 477
int servo_turn_on(int port, int servo)
285 giacomo 478
{
721 giacomo 479
  unsigned char b[2];
358 giacomo 480
  int servo_port = (unsigned)(port);
481
 
323 giacomo 482
  if (servo > 15) return -1;
358 giacomo 483
 
721 giacomo 484
  b[0] = 0x80;
485
  b[1] = 0x10 | (servo & 0x0F);
486
  servo_send_msg(servo_port, b, 2, NULL, 0);
358 giacomo 487
 
721 giacomo 488
  return 0;
358 giacomo 489
 
285 giacomo 490
}
491
 
291 giacomo 492
/* 1000.0000:0010.0000 */
358 giacomo 493
int servo_turn_off_all(int port)
323 giacomo 494
{
724 giacomo 495
  unsigned char b[2];
358 giacomo 496
  int servo_port = (unsigned)(port);
497
 
724 giacomo 498
  b[0] = 0x80;
499
  b[1] = 0x20;
500
  servo_send_msg(servo_port, b, 2, NULL, 0);
358 giacomo 501
 
724 giacomo 502
  return 0;
358 giacomo 503
 
285 giacomo 504
}
505
 
291 giacomo 506
/* 1000.0000:0010.0001 */
358 giacomo 507
int servo_turn_on_all(int port)
285 giacomo 508
{
724 giacomo 509
  unsigned char b[2];
358 giacomo 510
  int servo_port = (unsigned)(port);
511
 
724 giacomo 512
  b[0] = 0x80;
513
  b[1] = 0x21;
514
  servo_send_msg(servo_port, b, 2, NULL, 0);
515
 
516
  return 0;
358 giacomo 517
 
285 giacomo 518
}
519
 
323 giacomo 520
/* 1000.0000:0101.000M:mmmm.mmmm */
724 giacomo 521
int servo_set_levels(int port, int bank, int mask)
315 giacomo 522
{
724 giacomo 523
  unsigned char b[3];
358 giacomo 524
  int servo_port = (unsigned)(port);
525
 
724 giacomo 526
  b[0] = 0x80;
527
  b[1] = 0x50 | (0x01 & bank);
528
  b[2] = (unsigned char)(mask & 0xFF);
529
  servo_send_msg(servo_port, b, 3, NULL, 0);
358 giacomo 530
 
724 giacomo 531
  return 0;
358 giacomo 532
 
315 giacomo 533
}
534
 
323 giacomo 535
/* 1000.0000:0100.000M */
358 giacomo 536
int servo_get_levels(int port, int bank)
297 giacomo 537
{
724 giacomo 538
  unsigned char b[2],r[1];
725 giacomo 539
  int res, RX;
358 giacomo 540
  int servo_port = (unsigned)(port);
541
 
724 giacomo 542
  b[0] = 0x80;
543
  b[1] = 0x40 | (0x01 & bank);
725 giacomo 544
  RX = servo_send_msg(servo_port, b, 2, r, 1);
381 giacomo 545
 
726 giacomo 546
  servo_wait(servo_port, RX);
725 giacomo 547
 
724 giacomo 548
  res = r[0];
358 giacomo 549
 
724 giacomo 550
  return res;
358 giacomo 551
 
297 giacomo 552
}
553
 
554
/* 1000.0000:1000.0000 */
358 giacomo 555
int servo_store_levels(int port)
297 giacomo 556
{
724 giacomo 557
  unsigned char b[2];
358 giacomo 558
  int servo_port = (unsigned)(port);
559
 
724 giacomo 560
  b[0] = 0x80;
561
  b[1] = 0x80;
562
  servo_send_msg(servo_port, b, 2, NULL, 0);
381 giacomo 563
 
724 giacomo 564
  return 0;
358 giacomo 565
 
297 giacomo 566
}
567
 
493 giacomo 568
int servo_set_max_angle_sec(int port, int servo, int angle_sec)
290 giacomo 569
{
570
 
381 giacomo 571
  servo_table[port][servo].max_angle_sec = angle_sec;
290 giacomo 572
  return 0;
573
 
574
}
575
 
493 giacomo 576
int servo_set_min_angle_sec(int port, int servo, int angle_sec)
290 giacomo 577
{
578
 
381 giacomo 579
  servo_table[port][servo].min_angle_sec = angle_sec;
290 giacomo 580
  return 0;
581
 
582
}
583
 
381 giacomo 584
int servo_set_servo_tick(int port, int servo, int zero_tick, int delta_tick)
585
{
586
 
587
  if (zero_tick != -1) servo_table[port][servo].zero_tick = zero_tick;
588
  if (delta_tick != -1) servo_table[port][servo].delta_tick = delta_tick;
589
  return 0;
590
 
591
}
592
 
323 giacomo 593
/* 0000.Pppp:0000.vvvv:vvvv.vvvv */
358 giacomo 594
int servo_set_angle_sec(int port, int servo, int angle_sec)
281 giacomo 595
{
717 giacomo 596
  unsigned char b[3];
597
  int angle_tick;
358 giacomo 598
  int servo_port = (unsigned)(port);
282 giacomo 599
 
323 giacomo 600
  if (servo > 15) return -1;
282 giacomo 601
 
381 giacomo 602
  angle_tick = (servo_table[port][servo].zero_tick + angle_sec *
603
                servo_table[port][servo].delta_tick /
542 giacomo 604
                (servo_table[port][servo].max_angle_sec - servo_table[port][servo].min_angle_sec)) * 1000 / TICK_LEN;
290 giacomo 605
 
717 giacomo 606
  b[0] = 0x00 | (servo & 0x0F);
607
  b[1] = 0x00 | ((angle_tick >> 8) & 0x0F);
608
  b[2] = 0x00 | (angle_tick & 0xFF);
609
  servo_send_msg(servo_port, b, 3, NULL, 0);
358 giacomo 610
 
717 giacomo 611
  return 0;
282 giacomo 612
 
281 giacomo 613
}
614
 
323 giacomo 615
/* 0010.Pppp */
358 giacomo 616
int servo_store_default_position(int port, int servo)
290 giacomo 617
{
724 giacomo 618
  unsigned char b[1];
358 giacomo 619
  int servo_port = (unsigned)(port);
290 giacomo 620
 
323 giacomo 621
  if (servo > 15) return -1;
358 giacomo 622
 
724 giacomo 623
  b[0] = 0x20 | (servo & 0x0F);
624
  servo_send_msg(servo_port, b, 1, NULL, 0);  
358 giacomo 625
 
724 giacomo 626
  return 0;
358 giacomo 627
 
290 giacomo 628
}
629
 
323 giacomo 630
/* 0001.Pppp */
358 giacomo 631
int servo_get_angle_sec(int port, int servo)
281 giacomo 632
{
724 giacomo 633
  unsigned char b[1],r[2];
725 giacomo 634
  int res,data,RX;
358 giacomo 635
  int servo_port = (unsigned)(port);
636
 
323 giacomo 637
  if (servo > 15) return -1;
358 giacomo 638
 
724 giacomo 639
  b[0] = 0x10 | (servo & 0x0F);
725 giacomo 640
  RX = servo_send_msg(servo_port, b, 1, r, 2);
281 giacomo 641
 
726 giacomo 642
  servo_wait(servo_port, RX);
725 giacomo 643
 
726 giacomo 644
  res = (int)(r[0]) << 8;
724 giacomo 645
  res |= r[1];
282 giacomo 646
 
381 giacomo 647
  data = ((res*TICK_LEN/1000) - servo_table[port][servo].zero_tick) *
648
          (servo_table[port][servo].max_angle_sec - servo_table[port][servo].min_angle_sec) /
649
           servo_table[port][servo].delta_tick;
290 giacomo 650
 
724 giacomo 651
  return data;
282 giacomo 652
 
281 giacomo 653
}
654
 
282 giacomo 655
/* 0100:0aaa */
358 giacomo 656
int servo_get_analog(int port, int adport)
281 giacomo 657
{
724 giacomo 658
  unsigned char b[1],r[2];
725 giacomo 659
  int res, RX;
358 giacomo 660
  int servo_port = (unsigned)(port);
661
 
381 giacomo 662
  if (adport > 7) return -1;
358 giacomo 663
 
724 giacomo 664
  b[0] = 0x40 | (adport & 0x07);
725 giacomo 665
  RX = servo_send_msg(servo_port, b, 1, r, 2);
281 giacomo 666
 
726 giacomo 667
  servo_wait(servo_port, RX);
725 giacomo 668
 
724 giacomo 669
  res = r[0] << 8;
670
  res |= r[1];
282 giacomo 671
 
724 giacomo 672
  return res;
282 giacomo 673
 
281 giacomo 674
}
675