cheetah.c
Go to the documentation of this file.
00001 /*=========================================================================
00002 | Cheetah Interface Library
00003 |--------------------------------------------------------------------------
00004 | Copyright (c) 2004-2008 Total Phase, Inc.
00005 | All rights reserved.
00006 | www.totalphase.com
00007 |
00008 | Redistribution and use in source and binary forms, with or without
00009 | modification, are permitted provided that the following conditions
00010 | are met:
00011 |
00012 | - Redistributions of source code must retain the above copyright
00013 |   notice, this list of conditions and the following disclaimer.
00014 |
00015 | - Redistributions in binary form must reproduce the above copyright
00016 |   notice, this list of conditions and the following disclaimer in the
00017 |   documentation and/or other materials provided with the distribution.
00018 |
00019 | - Neither the name of Total Phase, Inc. nor the names of its
00020 |   contributors may be used to endorse or promote products derived from
00021 |   this software without specific prior written permission.
00022 |
00023 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
00027 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034 | POSSIBILITY OF SUCH DAMAGE.
00035 |--------------------------------------------------------------------------
00036 | To access Total Phase Cheetah devices through the API:
00037 |
00038 | 1) Use one of the following shared objects:
00039 |      cheetah.so       --  Linux shared object
00040 |          or
00041 |      cheetah.dll      --  Windows dynamic link library
00042 |
00043 | 2) Along with one of the following language modules:
00044 |      cheetah.c/h      --  C/C++ API header file and interface module
00045 |      cheetah_py.py    --  Python API
00046 |      cheetah.bas      --  Visual Basic 6 API
00047 |      cheetah.cs       --  C# .NET source
00048 |      cheetah_net.dll  --  Compiled .NET binding
00049  ========================================================================*/
00050 
00051 
00052 /*=========================================================================
00053 | INCLUDES
00054  ========================================================================*/
00055 /* This #include can be customized to conform to the user's build paths. */
00056 #include "biotac_sensors/cheetah.h"
00057 
00058 
00059 /*=========================================================================
00060 | VERSION CHECK
00061  ========================================================================*/
00062 #define CH_CFILE_VERSION   0x0300   /* v3.00 */
00063 #define CH_REQ_SW_VERSION  0x0300   /* v3.00 */
00064 
00065 /*
00066  * Make sure that the header file was included and that
00067  * the version numbers match.
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 | DEFINES
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 | LINUX AND DARWIN SUPPORT
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  * These functions allow the Linux behavior to emulate
00120  * the Windows behavior as specified below in the Windows
00121  * support section.
00122  * 
00123  * First, search for the shared object in the application
00124  * binary path, then in the current working directory.
00125  * 
00126  * Searching the application binary path requires /proc
00127  * filesystem support, which is standard in 2.4.x kernels.
00128  * 
00129  * If the /proc filesystem is not present, the shared object
00130  * will not be loaded from the execution path unless that path
00131  * is either the current working directory or explicitly
00132  * specified in LD_LIBRARY_PATH.
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     // Check if the file is readable
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     // Clean up and exit
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     /* Make sure that SO_NAME is not an absolute path. */
00168     if (SO_NAME[0] == '/')  return;
00169 
00170     /* Check the execution directory name. */
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         /* If there is a match, return immediately. */
00180         if (_checkPath(path))  return;
00181     }
00182 
00183     /* Check the current working directory. */
00184     p = getcwd(path, MAX_SO_PATH);
00185     if (p != 0)  _checkPath(path);
00186 }
00187 
00188 #endif
00189 
00190 
00191 /*=========================================================================
00192 | WINDOWS SUPPORT
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  * Use the default Windows DLL loading rules:
00207  *   1.  The directory from which the application binary was loaded.
00208  *   2.  The application's current directory.
00209  *   3a. [Windows NT/2000/XP only] 32-bit system directory
00210  *       (default: c:\winnt\System32)
00211  *   3b. 16-bit system directory
00212  *       (default: c:\winnt\System or c:\windows\system)
00213  *   4.  The windows directory
00214  *       (default: c:\winnt or c:\windows)
00215  *   5.  The directories listed in the PATH environment variable
00216  */
00217 static void _setSearchPath () {
00218     /* Do nothing */
00219 }
00220 
00221 #endif
00222 
00223 
00224 /*=========================================================================
00225 | SHARED LIBRARY LOADER
00226  ========================================================================*/
00227 /* The error conditions can be customized depending on the application. */
00228 static void *_loadFunction (const char *name, int *result) {
00229     static DLL_HANDLE handle = 0;
00230     void * function = 0;
00231 
00232     /* Load the shared library if necessary */
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     /* Bind the requested function in the shared library */
00298     function = (void *)dlsym(handle, name);
00299     *result  = function ? API_OK : API_UNABLE_TO_LOAD_FUNCTION;
00300     return function;
00301 }
00302 
00303 
00304 /*=========================================================================
00305 | FUNCTIONS
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 


biotac_sensors
Author(s): Ian McMahon
autogenerated on Sun Oct 5 2014 22:30:25