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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include "biotac_sensors/cheetah.h"
00057
00058
00059
00060
00061
00062 #define CH_CFILE_VERSION 0x0300
00063 #define CH_REQ_SW_VERSION 0x0300
00064
00065
00066
00067
00068
00069 #ifndef CH_HEADER_VERSION
00070 # error Unable to include header file. Please check include path.
00071
00072 #elif CH_HEADER_VERSION != CH_CFILE_VERSION
00073 # error Version mismatch between source and header files.
00074
00075 #endif
00076
00077
00078
00079
00080
00081 #define API_NAME "cheetah"
00082 #define API_DEBUG CH_DEBUG
00083 #define API_OK CH_OK
00084 #define API_UNABLE_TO_LOAD_LIBRARY CH_UNABLE_TO_LOAD_LIBRARY
00085 #define API_INCOMPATIBLE_LIBRARY CH_INCOMPATIBLE_LIBRARY
00086 #define API_UNABLE_TO_LOAD_FUNCTION CH_UNABLE_TO_LOAD_FUNCTION
00087 #define API_HEADER_VERSION CH_HEADER_VERSION
00088 #define API_REQ_SW_VERSION CH_REQ_SW_VERSION
00089
00090
00091
00092
00093
00094 #if defined(__APPLE_CC__) && !defined(DARWIN)
00095 #define DARWIN
00096 #endif
00097
00098 #if defined(linux) || defined(DARWIN)
00099
00100 #include <stdio.h>
00101 #include <stdlib.h>
00102 #include <unistd.h>
00103 #include <string.h>
00104 #include <fcntl.h>
00105
00106 #ifdef DARWIN
00107 #define DLOPEN_NO_WARN
00108 extern int _NSGetExecutablePath (char *buf, unsigned long *bufsize);
00109 #endif
00110
00111 #include <dlfcn.h>
00112
00113 #define DLL_HANDLE void *
00114 #define MAX_SO_PATH 256
00115
00116 static char SO_NAME[MAX_SO_PATH+1] = API_NAME ".so";
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 static int _checkPath (const char *path) {
00135 char *filename = (char *)malloc(strlen(path) +1 + strlen(SO_NAME) +1);
00136 int fd;
00137
00138
00139 sprintf(filename, "%s/%s", path, SO_NAME);
00140 fd = open(filename, O_RDONLY);
00141 if (fd >= 0) {
00142 strncpy(SO_NAME, filename, MAX_SO_PATH);
00143 close(fd);
00144 }
00145
00146
00147 free(filename);
00148 return (fd >= 0);
00149 }
00150
00151 static int _getExecPath (char *path, unsigned long maxlen) {
00152 #ifdef linux
00153 return readlink("/proc/self/exe", path, maxlen);
00154 #endif
00155
00156 #ifdef DARWIN
00157 _NSGetExecutablePath(path, &maxlen);
00158 return maxlen;
00159 #endif
00160 }
00161
00162 static void _setSearchPath () {
00163 char path[MAX_SO_PATH+1];
00164 int count;
00165 char *p;
00166
00167
00168 if (SO_NAME[0] == '/') return;
00169
00170
00171 memset(path, 0, sizeof(path));
00172 count = _getExecPath(path, MAX_SO_PATH);
00173
00174 if (count > 0) {
00175 char *p = strrchr(path, '/');
00176 if (p == path) ++p;
00177 if (p != 0) *p = '\0';
00178
00179
00180 if (_checkPath(path)) return;
00181 }
00182
00183
00184 p = getcwd(path, MAX_SO_PATH);
00185 if (p != 0) _checkPath(path);
00186 }
00187
00188 #endif
00189
00190
00191
00192
00193
00194 #if defined(WIN32) || defined(_WIN32)
00195
00196 #include <stdio.h>
00197 #include <windows.h>
00198
00199 #define DLL_HANDLE HINSTANCE
00200 #define dlopen(name, flags) LoadLibraryA(name)
00201 #define dlsym(handle, name) GetProcAddress(handle, name)
00202 #define dlerror() "Exiting program"
00203 #define SO_NAME API_NAME ".dll"
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 static void _setSearchPath () {
00218
00219 }
00220
00221 #endif
00222
00223
00224
00225
00226
00227
00228 static void *_loadFunction (const char *name, int *result) {
00229 static DLL_HANDLE handle = 0;
00230 void * function = 0;
00231
00232
00233 if (handle == 0) {
00234 u32 (*version) (void);
00235 u16 sw_version;
00236 u16 api_version_req;
00237
00238 _setSearchPath();
00239 handle = dlopen(SO_NAME, RTLD_LAZY);
00240 if (handle == 0) {
00241 #if API_DEBUG
00242 fprintf(stderr, "Unable to load %s\n", SO_NAME);
00243 fprintf(stderr, "%s\n", dlerror());
00244 #endif
00245 *result = API_UNABLE_TO_LOAD_LIBRARY;
00246 return 0;
00247 }
00248
00249 version = (void *)dlsym(handle, "c_version");
00250 if (version == 0) {
00251 #if API_DEBUG
00252 fprintf(stderr, "Unable to bind c_version() in %s\n",
00253 SO_NAME);
00254 fprintf(stderr, "%s\n", dlerror());
00255 #endif
00256 handle = 0;
00257 *result = API_INCOMPATIBLE_LIBRARY;
00258 return 0;
00259 }
00260
00261 sw_version = (u16)((version() >> 0) & 0xffff);
00262 api_version_req = (u16)((version() >> 16) & 0xffff);
00263 if (sw_version < API_REQ_SW_VERSION ||
00264 API_HEADER_VERSION < api_version_req)
00265 {
00266 #if API_DEBUG
00267 fprintf(stderr, "\nIncompatible versions:\n");
00268
00269 fprintf(stderr, " Header version = v%d.%02d ",
00270 (API_HEADER_VERSION >> 8) & 0xff, API_HEADER_VERSION & 0xff);
00271
00272 if (sw_version < API_REQ_SW_VERSION)
00273 fprintf(stderr, "(requires library >= %d.%02d)\n",
00274 (API_REQ_SW_VERSION >> 8) & 0xff,
00275 API_REQ_SW_VERSION & 0xff);
00276 else
00277 fprintf(stderr, "(library version OK)\n");
00278
00279
00280 fprintf(stderr, " Library version = v%d.%02d ",
00281 (sw_version >> 8) & 0xff,
00282 (sw_version >> 0) & 0xff);
00283
00284 if (API_HEADER_VERSION < api_version_req)
00285 fprintf(stderr, "(requires header >= %d.%02d)\n",
00286 (api_version_req >> 8) & 0xff,
00287 (api_version_req >> 0) & 0xff);
00288 else
00289 fprintf(stderr, "(header version OK)\n");
00290 #endif
00291 handle = 0;
00292 *result = API_INCOMPATIBLE_LIBRARY;
00293 return 0;
00294 }
00295 }
00296
00297
00298 function = (void *)dlsym(handle, name);
00299 *result = function ? API_OK : API_UNABLE_TO_LOAD_FUNCTION;
00300 return function;
00301 }
00302
00303
00304
00305
00306
00307 static int (*c_ch_find_devices) (int, u16 *) = 0;
00308 int ch_find_devices (
00309 int num_devices,
00310 u16 * devices
00311 )
00312 {
00313 if (c_ch_find_devices == 0) {
00314 int res = 0;
00315 if (!(c_ch_find_devices = _loadFunction("c_ch_find_devices", &res)))
00316 return res;
00317 }
00318 return c_ch_find_devices(num_devices, devices);
00319 }
00320
00321
00322 static int (*c_ch_find_devices_ext) (int, u16 *, int, u32 *) = 0;
00323 int ch_find_devices_ext (
00324 int num_devices,
00325 u16 * devices,
00326 int num_ids,
00327 u32 * unique_ids
00328 )
00329 {
00330 if (c_ch_find_devices_ext == 0) {
00331 int res = 0;
00332 if (!(c_ch_find_devices_ext = _loadFunction("c_ch_find_devices_ext", &res)))
00333 return res;
00334 }
00335 return c_ch_find_devices_ext(num_devices, devices, num_ids, unique_ids);
00336 }
00337
00338
00339 static Cheetah (*c_ch_open) (int) = 0;
00340 Cheetah ch_open (
00341 int port_number
00342 )
00343 {
00344 if (c_ch_open == 0) {
00345 int res = 0;
00346 if (!(c_ch_open = _loadFunction("c_ch_open", &res)))
00347 return res;
00348 }
00349 return c_ch_open(port_number);
00350 }
00351
00352
00353 static Cheetah (*c_ch_open_ext) (int, CheetahExt *) = 0;
00354 Cheetah ch_open_ext (
00355 int port_number,
00356 CheetahExt * ch_ext
00357 )
00358 {
00359 if (c_ch_open_ext == 0) {
00360 int res = 0;
00361 if (!(c_ch_open_ext = _loadFunction("c_ch_open_ext", &res)))
00362 return res;
00363 }
00364 return c_ch_open_ext(port_number, ch_ext);
00365 }
00366
00367
00368 static int (*c_ch_close) (Cheetah) = 0;
00369 int ch_close (
00370 Cheetah cheetah
00371 )
00372 {
00373 if (c_ch_close == 0) {
00374 int res = 0;
00375 if (!(c_ch_close = _loadFunction("c_ch_close", &res)))
00376 return res;
00377 }
00378 return c_ch_close(cheetah);
00379 }
00380
00381
00382 static int (*c_ch_port) (Cheetah) = 0;
00383 int ch_port (
00384 Cheetah cheetah
00385 )
00386 {
00387 if (c_ch_port == 0) {
00388 int res = 0;
00389 if (!(c_ch_port = _loadFunction("c_ch_port", &res)))
00390 return res;
00391 }
00392 return c_ch_port(cheetah);
00393 }
00394
00395
00396 static u32 (*c_ch_unique_id) (Cheetah) = 0;
00397 u32 ch_unique_id (
00398 Cheetah cheetah
00399 )
00400 {
00401 if (c_ch_unique_id == 0) {
00402 int res = 0;
00403 if (!(c_ch_unique_id = _loadFunction("c_ch_unique_id", &res)))
00404 return res;
00405 }
00406 return c_ch_unique_id(cheetah);
00407 }
00408
00409
00410 static const char * (*c_ch_status_string) (int) = 0;
00411 const char * ch_status_string (
00412 int status
00413 )
00414 {
00415 if (c_ch_status_string == 0) {
00416 int res = 0;
00417 if (!(c_ch_status_string = _loadFunction("c_ch_status_string", &res)))
00418 return 0;
00419 }
00420 return c_ch_status_string(status);
00421 }
00422
00423
00424 static int (*c_ch_version) (Cheetah, CheetahVersion *) = 0;
00425 int ch_version (
00426 Cheetah cheetah,
00427 CheetahVersion * version
00428 )
00429 {
00430 if (c_ch_version == 0) {
00431 int res = 0;
00432 if (!(c_ch_version = _loadFunction("c_ch_version", &res)))
00433 return res;
00434 }
00435 return c_ch_version(cheetah, version);
00436 }
00437
00438
00439 static u32 (*c_ch_sleep_ms) (u32) = 0;
00440 u32 ch_sleep_ms (
00441 u32 milliseconds
00442 )
00443 {
00444 if (c_ch_sleep_ms == 0) {
00445 int res = 0;
00446 if (!(c_ch_sleep_ms = _loadFunction("c_ch_sleep_ms", &res)))
00447 return res;
00448 }
00449 return c_ch_sleep_ms(milliseconds);
00450 }
00451
00452
00453 static int (*c_ch_target_power) (Cheetah, u08) = 0;
00454 int ch_target_power (
00455 Cheetah cheetah,
00456 u08 power_flag
00457 )
00458 {
00459 if (c_ch_target_power == 0) {
00460 int res = 0;
00461 if (!(c_ch_target_power = _loadFunction("c_ch_target_power", &res)))
00462 return res;
00463 }
00464 return c_ch_target_power(cheetah, power_flag);
00465 }
00466
00467
00468 static int (*c_ch_host_ifce_speed) (Cheetah) = 0;
00469 int ch_host_ifce_speed (
00470 Cheetah cheetah
00471 )
00472 {
00473 if (c_ch_host_ifce_speed == 0) {
00474 int res = 0;
00475 if (!(c_ch_host_ifce_speed = _loadFunction("c_ch_host_ifce_speed", &res)))
00476 return res;
00477 }
00478 return c_ch_host_ifce_speed(cheetah);
00479 }
00480
00481
00482 static int (*c_ch_dev_addr) (Cheetah) = 0;
00483 int ch_dev_addr (
00484 Cheetah cheetah
00485 )
00486 {
00487 if (c_ch_dev_addr == 0) {
00488 int res = 0;
00489 if (!(c_ch_dev_addr = _loadFunction("c_ch_dev_addr", &res)))
00490 return res;
00491 }
00492 return c_ch_dev_addr(cheetah);
00493 }
00494
00495
00496 static int (*c_ch_spi_bitrate) (Cheetah, int) = 0;
00497 int ch_spi_bitrate (
00498 Cheetah cheetah,
00499 int bitrate_khz
00500 )
00501 {
00502 if (c_ch_spi_bitrate == 0) {
00503 int res = 0;
00504 if (!(c_ch_spi_bitrate = _loadFunction("c_ch_spi_bitrate", &res)))
00505 return res;
00506 }
00507 return c_ch_spi_bitrate(cheetah, bitrate_khz);
00508 }
00509
00510
00511 static int (*c_ch_spi_configure) (Cheetah, CheetahSpiPolarity, CheetahSpiPhase, CheetahSpiBitorder, u08) = 0;
00512 int ch_spi_configure (
00513 Cheetah cheetah,
00514 CheetahSpiPolarity polarity,
00515 CheetahSpiPhase phase,
00516 CheetahSpiBitorder bitorder,
00517 u08 ss_polarity
00518 )
00519 {
00520 if (c_ch_spi_configure == 0) {
00521 int res = 0;
00522 if (!(c_ch_spi_configure = _loadFunction("c_ch_spi_configure", &res)))
00523 return res;
00524 }
00525 return c_ch_spi_configure(cheetah, polarity, phase, bitorder, ss_polarity);
00526 }
00527
00528
00529 static int (*c_ch_spi_queue_clear) (Cheetah) = 0;
00530 int ch_spi_queue_clear (
00531 Cheetah cheetah
00532 )
00533 {
00534 if (c_ch_spi_queue_clear == 0) {
00535 int res = 0;
00536 if (!(c_ch_spi_queue_clear = _loadFunction("c_ch_spi_queue_clear", &res)))
00537 return res;
00538 }
00539 return c_ch_spi_queue_clear(cheetah);
00540 }
00541
00542
00543 static int (*c_ch_spi_queue_oe) (Cheetah, u08) = 0;
00544 int ch_spi_queue_oe (
00545 Cheetah cheetah,
00546 u08 oe
00547 )
00548 {
00549 if (c_ch_spi_queue_oe == 0) {
00550 int res = 0;
00551 if (!(c_ch_spi_queue_oe = _loadFunction("c_ch_spi_queue_oe", &res)))
00552 return res;
00553 }
00554 return c_ch_spi_queue_oe(cheetah, oe);
00555 }
00556
00557
00558 static int (*c_ch_spi_queue_delay_cycles) (Cheetah, int) = 0;
00559 int ch_spi_queue_delay_cycles (
00560 Cheetah cheetah,
00561 int cycles
00562 )
00563 {
00564 if (c_ch_spi_queue_delay_cycles == 0) {
00565 int res = 0;
00566 if (!(c_ch_spi_queue_delay_cycles = _loadFunction("c_ch_spi_queue_delay_cycles", &res)))
00567 return res;
00568 }
00569 return c_ch_spi_queue_delay_cycles(cheetah, cycles);
00570 }
00571
00572
00573 static int (*c_ch_spi_queue_delay_ns) (Cheetah, int) = 0;
00574 int ch_spi_queue_delay_ns (
00575 Cheetah cheetah,
00576 int nanoseconds
00577 )
00578 {
00579 if (c_ch_spi_queue_delay_ns == 0) {
00580 int res = 0;
00581 if (!(c_ch_spi_queue_delay_ns = _loadFunction("c_ch_spi_queue_delay_ns", &res)))
00582 return res;
00583 }
00584 return c_ch_spi_queue_delay_ns(cheetah, nanoseconds);
00585 }
00586
00587
00588 static int (*c_ch_spi_queue_ss) (Cheetah, u08) = 0;
00589 int ch_spi_queue_ss (
00590 Cheetah cheetah,
00591 u08 active
00592 )
00593 {
00594 if (c_ch_spi_queue_ss == 0) {
00595 int res = 0;
00596 if (!(c_ch_spi_queue_ss = _loadFunction("c_ch_spi_queue_ss", &res)))
00597 return res;
00598 }
00599 return c_ch_spi_queue_ss(cheetah, active);
00600 }
00601
00602
00603 static int (*c_ch_spi_queue_byte) (Cheetah, int, u08) = 0;
00604 int ch_spi_queue_byte (
00605 Cheetah cheetah,
00606 int count,
00607 u08 data
00608 )
00609 {
00610 if (c_ch_spi_queue_byte == 0) {
00611 int res = 0;
00612 if (!(c_ch_spi_queue_byte = _loadFunction("c_ch_spi_queue_byte", &res)))
00613 return res;
00614 }
00615 return c_ch_spi_queue_byte(cheetah, count, data);
00616 }
00617
00618
00619 static int (*c_ch_spi_queue_array) (Cheetah, int, const u08 *) = 0;
00620 int ch_spi_queue_array (
00621 Cheetah cheetah,
00622 int num_bytes,
00623 const u08 * data_out
00624 )
00625 {
00626 if (c_ch_spi_queue_array == 0) {
00627 int res = 0;
00628 if (!(c_ch_spi_queue_array = _loadFunction("c_ch_spi_queue_array", &res)))
00629 return res;
00630 }
00631 return c_ch_spi_queue_array(cheetah, num_bytes, data_out);
00632 }
00633
00634
00635 static int (*c_ch_spi_batch_length) (Cheetah) = 0;
00636 int ch_spi_batch_length (
00637 Cheetah cheetah
00638 )
00639 {
00640 if (c_ch_spi_batch_length == 0) {
00641 int res = 0;
00642 if (!(c_ch_spi_batch_length = _loadFunction("c_ch_spi_batch_length", &res)))
00643 return res;
00644 }
00645 return c_ch_spi_batch_length(cheetah);
00646 }
00647
00648
00649 static int (*c_ch_spi_batch_shift) (Cheetah, int, u08 *) = 0;
00650 int ch_spi_batch_shift (
00651 Cheetah cheetah,
00652 int num_bytes,
00653 u08 * data_in
00654 )
00655 {
00656 if (c_ch_spi_batch_shift == 0) {
00657 int res = 0;
00658 if (!(c_ch_spi_batch_shift = _loadFunction("c_ch_spi_batch_shift", &res)))
00659 return res;
00660 }
00661 return c_ch_spi_batch_shift(cheetah, num_bytes, data_in);
00662 }
00663
00664
00665 static int (*c_ch_spi_async_submit) (Cheetah) = 0;
00666 int ch_spi_async_submit (
00667 Cheetah cheetah
00668 )
00669 {
00670 if (c_ch_spi_async_submit == 0) {
00671 int res = 0;
00672 if (!(c_ch_spi_async_submit = _loadFunction("c_ch_spi_async_submit", &res)))
00673 return res;
00674 }
00675 return c_ch_spi_async_submit(cheetah);
00676 }
00677
00678
00679 static int (*c_ch_spi_async_collect) (Cheetah, int, u08 *) = 0;
00680 int ch_spi_async_collect (
00681 Cheetah cheetah,
00682 int num_bytes,
00683 u08 * data_in
00684 )
00685 {
00686 if (c_ch_spi_async_collect == 0) {
00687 int res = 0;
00688 if (!(c_ch_spi_async_collect = _loadFunction("c_ch_spi_async_collect", &res)))
00689 return res;
00690 }
00691 return c_ch_spi_async_collect(cheetah, num_bytes, data_in);
00692 }
00693
00694