00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include "ax12.h"
00029 #ifdef CONFIG_MODULE_SCHEDULER
00030 #include <scheduler.h>
00031 #endif
00032
00033 void AX12_init(AX12 *s)
00034 {
00035 s->hardware_send = NULL;
00036 s->hardware_recv = NULL;
00037 s->hardware_switch = NULL;
00038 }
00039
00040
00041
00042
00043 void AX12_set_hardware_send(AX12 *s, int8_t(*pf)(uint8_t))
00044 {
00045 s->hardware_send = pf;
00046 }
00047
00048 void AX12_set_hardware_recv(AX12 *s, int16_t(*pf)(void))
00049 {
00050 s->hardware_recv = pf;
00051 }
00052
00053 void AX12_set_hardware_switch(AX12 *s, void(*pf)(uint8_t))
00054 {
00055 s->hardware_switch = pf;
00056 }
00057
00058
00059
00060
00061
00062 uint8_t AX12_checksum(AX12_Packet *packet)
00063 {
00064 uint8_t i;
00065 uint8_t checksum=0;
00066
00067 checksum += packet->id;
00068 checksum += packet->instruction;
00069
00070
00071 checksum += packet->nparams + 2;
00072
00073 for (i=0; i<packet->nparams; i++)
00074 checksum += packet->params[i];
00075
00076 return ~checksum;
00077 }
00078
00079
00080 uint8_t AX12_send(AX12 *s, AX12_Packet *packet)
00081 {
00082 uint8_t i;
00083 uint8_t flags;
00084 uint8_t err;
00085
00086 #ifdef CONFIG_MODULE_SCHEDULER
00087 uint8_t scheduler_prio;
00088
00089 scheduler_prio = scheduler_disable_save();
00090 #endif
00091
00092 if (packet->nparams > AX12_MAX_PARAMS) {
00093 err = AX12_ERROR_TYPE_INVALID_PACKET;
00094 goto fail;
00095 }
00096
00097
00098 s->hardware_switch(AX12_STATE_WRITE);
00099
00100
00101 if (s->hardware_send(0xFF)) {
00102 err = AX12_ERROR_TYPE_XMIT_FAILED;
00103 goto fail;
00104 }
00105
00106 if (s->hardware_send(0xFF)) {
00107 err = AX12_ERROR_TYPE_XMIT_FAILED;
00108 goto fail;
00109 }
00110
00111
00112 if (s->hardware_send(packet->id)) {
00113 err = AX12_ERROR_TYPE_XMIT_FAILED;
00114 goto fail;
00115 }
00116
00117
00118 if (s->hardware_send(packet->nparams + 2)) {
00119 err = AX12_ERROR_TYPE_XMIT_FAILED;
00120 goto fail;
00121 }
00122
00123
00124 if (s->hardware_send(packet->instruction)) {
00125 err = AX12_ERROR_TYPE_XMIT_FAILED;
00126 goto fail;
00127 }
00128
00129
00130 for (i=0; i<(packet->nparams); i++) {
00131 if (s->hardware_send(packet->params[i])) {
00132 err = AX12_ERROR_TYPE_XMIT_FAILED;
00133 goto fail;
00134 }
00135 }
00136
00137 IRQ_LOCK(flags);
00138
00139
00140
00141 if (s->hardware_send(AX12_checksum(packet))) {
00142 IRQ_UNLOCK(flags);
00143 err = AX12_ERROR_TYPE_XMIT_FAILED;
00144 goto fail;
00145 }
00146
00147
00148 s->hardware_switch(AX12_STATE_READ);
00149
00150 IRQ_UNLOCK(flags);
00151
00152 #ifdef CONFIG_MODULE_SCHEDULER
00153 scheduler_enable_restore(scheduler_prio);
00154 #endif
00155 return 0;
00156
00157 fail:
00158
00159 s->hardware_switch(AX12_STATE_READ);
00160 #ifdef CONFIG_MODULE_SCHEDULER
00161 scheduler_enable_restore(scheduler_prio);
00162 #endif
00163 return err;
00164 }
00165
00166
00167 uint8_t AX12_recv(AX12 *s, AX12_Packet *packet)
00168 {
00169 int16_t c;
00170 uint8_t length;
00171 uint8_t i;
00172
00173
00174 s->hardware_switch(AX12_STATE_READ);
00175
00176 c = s->hardware_recv();
00177 if (c == -1)
00178 return AX12_ERROR_TYPE_NO_ANSWER;
00179 if (c != 0xFF)
00180 return AX12_ERROR_TYPE_INVALID_PACKET;
00181
00182 c = s->hardware_recv();
00183 if (c == -1)
00184 return AX12_ERROR_TYPE_TIMEOUT;
00185 if (c != 0xFF)
00186 return AX12_ERROR_TYPE_INVALID_PACKET;
00187
00188 c = s->hardware_recv();
00189 if (c == -1)
00190 return AX12_ERROR_TYPE_TIMEOUT;
00191 packet->id = c;
00192
00193 c = s->hardware_recv();
00194 if (c == -1)
00195 return AX12_ERROR_TYPE_TIMEOUT;
00196 length = c;
00197 packet->nparams = length - 2;
00198 if (packet->nparams > AX12_MAX_PARAMS)
00199 return AX12_ERROR_TYPE_INVALID_PACKET;
00200
00201 c = s->hardware_recv();
00202 if (c == -1)
00203 return AX12_ERROR_TYPE_TIMEOUT;
00204 packet->error = c;
00205 if (packet->error)
00206 return packet->error;
00207
00208 for (i=0; i<(length-2); i++) {
00209 c = s->hardware_recv();
00210 if (c == -1)
00211 return AX12_ERROR_TYPE_TIMEOUT;
00212 packet->params[i] = c;
00213 }
00214
00215
00216 c = s->hardware_recv();
00217
00218 if (c != AX12_checksum(packet))
00219 return AX12_ERROR_TYPE_BAD_CKSUM;
00220
00221 return 0;
00222 }
00223
00224
00225
00226
00227
00228 uint8_t AX12_write_byte(AX12 *s, uint8_t id, AX12_ADDRESS address,
00229 uint8_t data)
00230 {
00231 AX12_Packet p, rp;
00232 uint8_t ret;
00233
00234 memset(&p, 0, sizeof(p));
00235 memset(&rp, 0, sizeof(rp));
00236
00237 p.id = id;
00238 p.instruction = AX12_WRITE;
00239 p.nparams = 2;
00240
00241
00242 p.params[0] = (uint8_t)address;
00243
00244
00245 p.params[1] = data;
00246
00247
00248 ret = AX12_send(s, &p);
00249 if (ret)
00250 return ret;
00251
00252
00253 if (p.id == AX12_BROADCAST_ID)
00254 return 0;
00255
00256
00257 return AX12_recv(s, &rp);
00258 }
00259
00260
00261 uint8_t AX12_write_int(AX12 *s, uint8_t id, AX12_ADDRESS address,
00262 uint16_t data)
00263 {
00264 AX12_Packet p, rp;
00265 uint8_t ret;
00266
00267 memset(&p, 0, sizeof(p));
00268 memset(&rp, 0, sizeof(rp));
00269
00270 p.id = id;
00271 p.instruction = AX12_WRITE;
00272 p.nparams = 3;
00273
00274
00275 p.params[0] = (uint8_t)address;
00276
00277
00278 p.params[1] = 0xFF & data;
00279
00280
00281 p.params[2] = data>>8;
00282
00283
00284 ret = AX12_send(s, &p);
00285 if (ret)
00286 return ret;
00287
00288
00289 if (p.id == AX12_BROADCAST_ID)
00290 return 0;
00291
00292
00293 return AX12_recv(s, &rp);
00294 }
00295
00296
00297
00298 uint8_t AX12_read_byte(AX12 *s, uint8_t id, AX12_ADDRESS address,
00299 uint8_t *val)
00300 {
00301 AX12_Packet p, rp;
00302 uint8_t ret;
00303
00304 memset(&p, 0, sizeof(p));
00305 memset(&rp, 0, sizeof(rp));
00306
00307 p.id = id;
00308 p.instruction = AX12_READ;
00309 p.nparams = 2;
00310
00311
00312 p.params[0] = (uint8_t)address;
00313
00314
00315 p.params[1] = 1;
00316
00317
00318 ret = AX12_send(s, &p);
00319 if (ret)
00320 return ret;
00321
00322 ret = AX12_recv(s, &rp);
00323 if (ret)
00324 return ret;
00325
00326 *val = rp.params[0];
00327 return 0;
00328 }
00329
00330 uint8_t AX12_read_int(AX12 *s, uint8_t id, AX12_ADDRESS address,
00331 uint16_t *val)
00332 {
00333 AX12_Packet p, rp;
00334 uint8_t ret;
00335
00336 memset(&p, 0, sizeof(p));
00337 memset(&rp, 0, sizeof(rp));
00338
00339 p.id = id;
00340 p.instruction = AX12_READ;
00341 p.nparams = 2;
00342
00343
00344 p.params[0] = (uint8_t)address;
00345
00346
00347 p.params[1] = 2;
00348
00349
00350 ret = AX12_send(s, &p);
00351 if (ret)
00352 return ret;
00353
00354 ret = AX12_recv(s, &rp);
00355 if (ret)
00356 return ret;
00357
00358 *val = rp.params[0] + ((rp.params[1])<<8);
00359 return 0;
00360 }
00361
00362
00363
00364
00365 uint8_t AX12_set_position(AX12 *s,uint8_t id, uint16_t position)
00366 {
00367 return AX12_write_int(s, id, AA_GOAL_POSITION_L, position);
00368 }
00369
00370 uint8_t AX12_set_position2(AX12 *s, uint8_t id, uint16_t position,
00371 uint16_t speed)
00372 {
00373 AX12_Packet p, rp;
00374 uint8_t ret;
00375
00376 p.id = id;
00377 p.instruction = AX12_WRITE;
00378 p.nparams = 5;
00379
00380
00381 p.params[0] = AA_GOAL_POSITION_L;
00382
00383 p.params[1] = 0xFF & position;
00384 p.params[2] = position>>8;
00385
00386 p.params[3] = 0xFF & speed;
00387 p.params[4] = speed>>8;
00388
00389
00390 ret = AX12_send(s, &p);
00391 if (ret)
00392 return ret;
00393
00394
00395 if(p.id == AX12_BROADCAST_ID)
00396 return 0;
00397
00398
00399 return AX12_recv(s, &rp);
00400 }
00401
00402 uint8_t AX12_set_position3(AX12*s, uint8_t id, uint16_t position,
00403 uint16_t speed, uint16_t torque)
00404 {
00405 AX12_Packet p, rp;
00406 uint8_t ret;
00407
00408 p.id = id;
00409 p.instruction = AX12_WRITE;
00410 p.nparams = 7;
00411
00412
00413 p.params[0] = AA_GOAL_POSITION_L;
00414
00415 p.params[1] = 0xFF & position;
00416 p.params[2] = position>>8;
00417
00418 p.params[3] = 0xFF & speed;
00419 p.params[4] = speed>>8;
00420
00421 p.params[5] = 0xFF & torque;
00422 p.params[6] = torque>>8;
00423
00424
00425 ret = AX12_send(s, &p);
00426 if (ret)
00427 return ret;
00428
00429
00430 if(p.id == AX12_BROADCAST_ID)
00431 return 0;
00432
00433
00434 return AX12_recv(s, &rp);
00435 }
00436
00437 uint8_t AX12_get_position(AX12 *s, uint8_t id, uint16_t *pos)
00438 {
00439 return AX12_read_int(s, id, AA_PRESENT_POSITION_L, pos);
00440 }
00441
00442 uint8_t AX12_get_speed(AX12 *s, uint8_t id, uint16_t *speed)
00443 {
00444 return AX12_read_int(s, id, AA_PRESENT_SPEED_L, speed);
00445 }
00446
00447 uint8_t AX12_get_load(AX12 *s, uint8_t id, uint16_t *load)
00448 {
00449 return AX12_read_int(s, id, AA_PRESENT_LOAD_L, load);
00450 }
00451
00452 uint8_t AX12_ping(AX12 *s, uint8_t id)
00453 {
00454 AX12_Packet p, rp;
00455 uint8_t ret;
00456
00457 p.id = id;
00458 p.instruction = AX12_PING;
00459 p.nparams = 0;
00460
00461
00462 ret = AX12_send(s, &p);
00463 if (ret)
00464 return ret;
00465
00466
00467 if(p.id == AX12_BROADCAST_ID)
00468 return 0;
00469
00470
00471 return AX12_recv(s, &rp);
00472 }
00473
00474 uint8_t AX12_reset(AX12 *s, uint8_t id)
00475 {
00476 AX12_Packet p, rp;
00477 uint8_t ret;
00478
00479 p.id = id;
00480 p.instruction = AX12_RESET;
00481 p.nparams = 0;
00482
00483
00484 ret = AX12_send(s, &p);
00485 if (ret)
00486 return ret;
00487
00488
00489 if(p.id == AX12_BROADCAST_ID)
00490 return 0;
00491
00492
00493 return AX12_recv(s, &rp);
00494 }