pigpiod_if2.c
Go to the documentation of this file.
00001 /*
00002 This is free and unencumbered software released into the public domain.
00003 
00004 Anyone is free to copy, modify, publish, use, compile, sell, or
00005 distribute this software, either in source code form or as a compiled
00006 binary, for any purpose, commercial or non-commercial, and by any
00007 means.
00008 
00009 In jurisdictions that recognize copyright laws, the author or authors
00010 of this software dedicate any and all copyright interest in the
00011 software to the public domain. We make this dedication for the benefit
00012 of the public at large and to the detriment of our heirs and
00013 successors. We intend this dedication to be an overt act of
00014 relinquishment in perpetuity of all present and future rights to this
00015 software under copyright law.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00018 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00019 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00020 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
00021 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00022 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00023 OTHER DEALINGS IN THE SOFTWARE.
00024 
00025 For more information, please refer to <http://unlicense.org/>
00026 */
00027 
00028 /* PIGPIOD_IF2_VERSION 13 */
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <stdint.h>
00033 #include <string.h>
00034 #include <fcntl.h>
00035 #include <unistd.h>
00036 #include <errno.h>
00037 #include <time.h>
00038 #include <netdb.h>
00039 #include <pthread.h>
00040 
00041 #include <sys/types.h>
00042 #include <sys/stat.h>
00043 #include <sys/time.h>
00044 #include <sys/socket.h>
00045 #include <netinet/tcp.h>
00046 #include <sys/select.h>
00047 
00048 #include <arpa/inet.h>
00049 
00050 #include "pigpio.h"
00051 #include "command.h"
00052 
00053 #include "pigpiod_if2.h"
00054 
00055 #define PI_MAX_REPORTS_PER_READ 4096
00056 
00057 #define STACK_SIZE (256*1024)
00058 
00059 #define MAX_PI 32
00060 
00061 typedef void (*CBF_t) ();
00062 
00063 struct callback_s
00064 {
00065 
00066    int id;
00067    int pi;
00068    int gpio;
00069    int edge;
00070    CBF_t f;
00071    void * user;
00072    int ex;
00073    callback_t *prev;
00074    callback_t *next;
00075 };
00076 
00077 struct evtCallback_s
00078 {
00079 
00080    int id;
00081    int pi;
00082    int event;
00083    CBF_t f;
00084    void * user;
00085    int ex;
00086    evtCallback_t *prev;
00087    evtCallback_t *next;
00088 };
00089 
00090 /* GLOBALS ---------------------------------------------------------------- */
00091 
00092 static int             gPiInUse     [MAX_PI];
00093 
00094 static int             gPigCommand  [MAX_PI];
00095 static int             gPigHandle   [MAX_PI];
00096 static int             gPigNotify   [MAX_PI];
00097 
00098 static uint32_t        gEventBits   [MAX_PI];
00099 static uint32_t        gNotifyBits  [MAX_PI];
00100 static uint32_t        gLastLevel   [MAX_PI];
00101 
00102 static pthread_t       *gPthNotify  [MAX_PI];
00103 
00104 static pthread_mutex_t gCmdMutex    [MAX_PI];
00105 static int             gCancelState [MAX_PI];
00106 
00107 static callback_t *gCallBackFirst = 0;
00108 static callback_t *gCallBackLast  = 0;
00109 
00110 static evtCallback_t *geCallBackFirst = 0;
00111 static evtCallback_t *geCallBackLast  = 0;
00112 
00113 /* PRIVATE ---------------------------------------------------------------- */
00114 
00115 static void _pml(int pi)
00116 {
00117    int cancelState;
00118 
00119    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState);
00120    pthread_mutex_lock(&gCmdMutex[pi]);
00121    gCancelState[pi] = cancelState;
00122 }
00123 
00124 static void _pmu(int pi)
00125 {
00126    int cancelState;
00127 
00128    cancelState = gCancelState[pi];
00129    pthread_mutex_unlock(&gCmdMutex[pi]);
00130    pthread_setcancelstate(cancelState, NULL);
00131 }
00132 
00133 static int pigpio_command(int pi, int command, int p1, int p2, int rl)
00134 {
00135    cmdCmd_t cmd;
00136 
00137    if ((pi < 0) || (pi >= MAX_PI) || !gPiInUse[pi])
00138       return pigif_unconnected_pi;
00139 
00140    cmd.cmd = command;
00141    cmd.p1  = p1;
00142    cmd.p2  = p2;
00143    cmd.res = 0;
00144 
00145    _pml(pi);
00146 
00147    if (send(gPigCommand[pi], &cmd, sizeof(cmd), 0) != sizeof(cmd))
00148    {
00149       _pmu(pi);
00150       return pigif_bad_send;
00151    }
00152 
00153    if (recv(gPigCommand[pi], &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
00154    {
00155       _pmu(pi);
00156       return pigif_bad_recv;
00157    }
00158 
00159    if (rl) _pmu(pi);
00160 
00161    return cmd.res;
00162 }
00163 
00164 static int pigpio_notify(int pi)
00165 {
00166    cmdCmd_t cmd;
00167 
00168    if ((pi < 0) || (pi >= MAX_PI) || !gPiInUse[pi])
00169       return pigif_unconnected_pi;
00170 
00171    cmd.cmd = PI_CMD_NOIB;
00172    cmd.p1  = 0;
00173    cmd.p2  = 0;
00174    cmd.res = 0;
00175 
00176    _pml(pi);
00177 
00178    if (send(gPigNotify[pi], &cmd, sizeof(cmd), 0) != sizeof(cmd))
00179    {
00180       _pmu(pi);
00181       return pigif_bad_send;
00182    }
00183 
00184    if (recv(gPigNotify[pi], &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
00185    {
00186       _pmu(pi);
00187       return pigif_bad_recv;
00188    }
00189 
00190    _pmu(pi);
00191 
00192    return cmd.res;
00193 }
00194 
00195 static int pigpio_command_ext
00196    (int pi, int command, int p1, int p2, int p3,
00197     int extents, gpioExtent_t *ext, int rl)
00198 {
00199    int i;
00200    cmdCmd_t cmd;
00201 
00202    if ((pi < 0) || (pi >= MAX_PI) || !gPiInUse[pi])
00203       return pigif_unconnected_pi;
00204 
00205    cmd.cmd = command;
00206    cmd.p1  = p1;
00207    cmd.p2  = p2;
00208    cmd.p3  = p3;
00209 
00210    _pml(pi);
00211 
00212    if (send(gPigCommand[pi], &cmd, sizeof(cmd), 0) != sizeof(cmd))
00213    {
00214       _pmu(pi);
00215       return pigif_bad_send;
00216    }
00217 
00218    for (i=0; i<extents; i++)
00219    {
00220       if (send(gPigCommand[pi], ext[i].ptr, ext[i].size, 0) != ext[i].size)
00221       {
00222          _pmu(pi);
00223          return pigif_bad_send;
00224       }
00225    }
00226 
00227    if (recv(gPigCommand[pi], &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
00228    {
00229       _pmu(pi);
00230       return pigif_bad_recv;
00231    }
00232    if (rl) _pmu(pi);
00233 
00234    return cmd.res;
00235 }
00236 
00237 static int pigpioOpenSocket(char *addr, char *port)
00238 {
00239    int sock, err, opt;
00240    struct addrinfo hints, *res, *rp;
00241    const char *addrStr, *portStr;
00242 
00243    if (!addr)
00244    {
00245       addrStr = getenv(PI_ENVADDR);
00246 
00247       if ((!addrStr) || (!strlen(addrStr)))
00248       {
00249          addrStr = PI_DEFAULT_SOCKET_ADDR_STR;
00250       }
00251    }
00252    else addrStr = addr;
00253 
00254    if (!port)
00255    {
00256       portStr = getenv(PI_ENVPORT);
00257 
00258       if ((!portStr) || (!strlen(portStr)))
00259       {
00260          portStr = PI_DEFAULT_SOCKET_PORT_STR;
00261       }
00262    }
00263    else portStr = port;
00264 
00265    memset (&hints, 0, sizeof (hints));
00266 
00267    hints.ai_family   = PF_UNSPEC;
00268    hints.ai_socktype = SOCK_STREAM;
00269    hints.ai_flags   |= AI_CANONNAME;
00270 
00271    err = getaddrinfo (addrStr, portStr, &hints, &res);
00272 
00273    if (err) return pigif_bad_getaddrinfo;
00274 
00275    for (rp=res; rp!=NULL; rp=rp->ai_next)
00276    {
00277       sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
00278 
00279       if (sock == -1) continue;
00280 
00281       /* Disable the Nagle algorithm. */
00282       opt = 1;
00283       setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int));
00284 
00285       if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) break;
00286    }
00287 
00288    freeaddrinfo(res);
00289 
00290    if (rp == NULL) return pigif_bad_connect;
00291 
00292    return sock;
00293 }
00294 
00295 static void dispatch_notification(int pi, gpioReport_t *r)
00296 {
00297    callback_t *p;
00298    evtCallback_t *ep;
00299    uint32_t changed;
00300    int l, g;
00301 
00302 /*
00303    printf("s=%4x f=%4x t=%10u l=%8x\n",
00304       r->seqno, r->flags, r->tick, r->level);
00305 */
00306 
00307    if (r->flags == 0)
00308    {
00309       changed = (r->level ^ gLastLevel[pi]) & gNotifyBits[pi];
00310 
00311       gLastLevel[pi] = r->level;
00312 
00313       p = gCallBackFirst;
00314 
00315       while (p)
00316       {
00317          if (((p->pi) == pi) && (changed & (1<<(p->gpio))))
00318          {
00319             if ((r->level) & (1<<(p->gpio))) l = 1; else l = 0;
00320             if ((p->edge) ^ l)
00321             {
00322                if (p->ex) (p->f)(pi, p->gpio, l, r->tick, p->user);
00323                else       (p->f)(pi, p->gpio, l, r->tick);
00324             }
00325          }
00326          p = p->next;
00327       }
00328    }
00329    else
00330    {
00331       if ((r->flags) & PI_NTFY_FLAGS_WDOG)
00332       {
00333          g = (r->flags) & 31;
00334 
00335          p = gCallBackFirst;
00336 
00337          while (p)
00338          {
00339             if (((p->pi) == pi) && ((p->gpio) == g))
00340             {
00341                if (p->ex) (p->f)(pi, g, PI_TIMEOUT, r->tick, p->user);
00342                else       (p->f)(pi, g, PI_TIMEOUT, r->tick);
00343             }
00344             p = p->next;
00345          }
00346       }
00347       else if ((r->flags) & PI_NTFY_FLAGS_EVENT)
00348       {
00349          g = (r->flags) & 31;
00350 
00351          ep = geCallBackFirst;
00352 
00353          while (ep)
00354          {
00355             if (((ep->pi) == pi) && ((ep->event) == g))
00356             {
00357                if (ep->ex) (ep->f)(pi, g, r->tick, ep->user);
00358                else        (ep->f)(pi, g, r->tick);
00359             }
00360             ep = ep->next;
00361          }
00362       }
00363    }
00364 }
00365 
00366 static void *pthNotifyThread(void *x)
00367 {
00368    static int got = 0;
00369    int pi;
00370    int bytes, r;
00371    gpioReport_t report[PI_MAX_REPORTS_PER_READ];
00372 
00373    pi = *((int*)x);
00374    free(x); /* memory allocated in pigpio_start */
00375 
00376    while (1)
00377    {
00378       bytes = read(gPigNotify[pi], (char*)&report+got, sizeof(report)-got);
00379 
00380       if (bytes > 0) got += bytes;
00381       else break;
00382 
00383       r = 0;
00384 
00385       while (got >= sizeof(gpioReport_t))
00386       {
00387          dispatch_notification(pi, &report[r]);
00388 
00389          r++;
00390 
00391          got -= sizeof(gpioReport_t);
00392       }
00393 
00394       /* copy any partial report to start of array */
00395       
00396       if (got && r) report[0] = report[r];
00397    }
00398 
00399    fprintf(stderr, "notify thread for pi %d broke with read error %d\n",
00400       pi, bytes);
00401 
00402    while (1) sleep(1);
00403 
00404    return NULL;
00405 }
00406 
00407 static void findNotifyBits(int pi)
00408 {
00409    callback_t *p;
00410    uint32_t bits = 0;
00411 
00412    p = gCallBackFirst;
00413 
00414    while (p)
00415    {
00416       if (p->pi == pi) bits |= (1<<(p->gpio));
00417       p = p->next;
00418    }
00419 
00420    if (bits != gNotifyBits[pi])
00421    {
00422       gNotifyBits[pi] = bits;
00423       pigpio_command(pi, PI_CMD_NB, gPigHandle[pi], gNotifyBits[pi], 1);
00424    }
00425 }
00426 
00427 static void _wfe(
00428    int pi, unsigned user_gpio, unsigned level, uint32_t tick, void *user)
00429 {
00430    *(int *)user = 1;
00431 }
00432 
00433 static int intCallback(
00434    int pi, unsigned user_gpio, unsigned edge, void *f, void *user, int ex)
00435 {
00436    static int id = 0;
00437    callback_t *p;
00438 
00439    if ((user_gpio >=0) && (user_gpio < 32) && (edge >=0) && (edge <= 2) && f)
00440    {
00441       /* prevent duplicates */
00442 
00443       p = gCallBackFirst;
00444 
00445       while (p)
00446       {
00447          if ((p->pi   == pi)        &&
00448              (p->gpio == user_gpio) &&
00449              (p->edge == edge)      &&
00450              (p->f    == f))
00451          {
00452             return pigif_duplicate_callback;
00453          }
00454          p = p->next;
00455       }
00456 
00457       p = malloc(sizeof(callback_t));
00458 
00459       if (p)
00460       {
00461          if (!gCallBackFirst) gCallBackFirst = p;
00462 
00463          p->id = id++;
00464          p->pi = pi;
00465          p->gpio = user_gpio;
00466          p->edge = edge;
00467          p->f = f;
00468          p->user = user;
00469          p->ex = ex;
00470          p->next = 0;
00471          p->prev = gCallBackLast;
00472 
00473          if (p->prev) (p->prev)->next = p;
00474          gCallBackLast = p;
00475 
00476          findNotifyBits(pi);
00477 
00478          return p->id;
00479       }
00480 
00481       return pigif_bad_malloc;
00482    }
00483 
00484    return pigif_bad_callback;
00485 }
00486 
00487 static void findEventBits(int pi)
00488 {
00489    evtCallback_t *ep;
00490    uint32_t bits = 0;
00491 
00492    ep = geCallBackFirst;
00493 
00494    while (ep)
00495    {
00496       if (ep->pi == pi) bits |= (1<<(ep->event));
00497       ep = ep->next;
00498    }
00499 
00500    if (bits != gEventBits[pi])
00501    {
00502       gEventBits[pi] = bits;
00503       pigpio_command(pi, PI_CMD_EVM, gPigHandle[pi], gEventBits[pi], 1);
00504    }
00505 }
00506 
00507 static void _ewfe(
00508    int pi, unsigned event, uint32_t tick, void *user)
00509 {
00510    *(int *)user = 1;
00511 }
00512 
00513 static int intEventCallback(
00514    int pi, unsigned event, void *f, void *user, int ex)
00515 {
00516    static int id = 0;
00517    evtCallback_t *ep;
00518 
00519    if ((event >=0) && (event < 32) && f)
00520    {
00521       /* prevent duplicates */
00522 
00523       ep = geCallBackFirst;
00524 
00525       while (ep)
00526       {
00527          if ((ep->pi    == pi)    &&
00528              (ep->event == event) &&
00529              (ep->f     == f))
00530          {
00531             return pigif_duplicate_callback;
00532          }
00533          ep = ep->next;
00534       }
00535 
00536       ep = malloc(sizeof(evtCallback_t));
00537 
00538       if (ep)
00539       {
00540          if (!geCallBackFirst) geCallBackFirst = ep;
00541 
00542          ep->id = id++;
00543          ep->pi = pi;
00544          ep->event = event;
00545          ep->f = f;
00546          ep->user = user;
00547          ep->ex = ex;
00548          ep->next = 0;
00549          ep->prev = geCallBackLast;
00550 
00551          if (ep->prev) (ep->prev)->next = ep;
00552          geCallBackLast = ep;
00553 
00554          findEventBits(pi);
00555 
00556          return ep->id;
00557       }
00558 
00559       return pigif_bad_malloc;
00560    }
00561 
00562    return pigif_bad_callback;
00563 }
00564 
00565 static int recvMax(int pi, void *buf, int bufsize, int sent)
00566 {
00567    /*
00568    Copy at most bufSize bytes from the receieved message to
00569    buf.  Discard the rest of the message.
00570    */
00571    uint8_t scratch[4096];
00572    int remaining, fetch, count;
00573 
00574    if (sent < bufsize) count = sent; else count = bufsize;
00575 
00576    if (count) recv(gPigCommand[pi], buf, count, MSG_WAITALL);
00577 
00578    remaining = sent - count;
00579 
00580    while (remaining)
00581    {
00582       fetch = remaining;
00583       if (fetch > sizeof(scratch)) fetch = sizeof(scratch);
00584       recv(gPigCommand[pi], scratch, fetch, MSG_WAITALL);
00585       remaining -= fetch;
00586    }
00587 
00588    return count;
00589 }
00590 
00591 /* PUBLIC ----------------------------------------------------------------- */
00592 
00593 double time_time(void)
00594 {
00595    struct timeval tv;
00596    double t;
00597 
00598    gettimeofday(&tv, 0);
00599 
00600    t = (double)tv.tv_sec + ((double)tv.tv_usec / 1E6);
00601 
00602    return t;
00603 }
00604 
00605 void time_sleep(double seconds)
00606 {
00607    struct timespec ts, rem;
00608 
00609    if (seconds > 0.0)
00610    {
00611       ts.tv_sec = seconds;
00612       ts.tv_nsec = (seconds-(double)ts.tv_sec) * 1E9;
00613 
00614       while (clock_nanosleep(CLOCK_REALTIME, 0, &ts, &rem))
00615       {
00616          /* copy remaining time to ts */
00617          ts.tv_sec  = rem.tv_sec;
00618          ts.tv_nsec = rem.tv_nsec;
00619       }
00620    }
00621 }
00622 
00623 char *pigpio_error(int errnum)
00624 {
00625    if (errnum > -1000) return cmdErrStr(errnum);
00626    else
00627    {
00628       switch(errnum)
00629       {
00630          case pigif_bad_send:
00631             return "failed to send to pigpiod";
00632          case pigif_bad_recv:
00633             return "failed to receive from pigpiod";
00634          case pigif_bad_getaddrinfo:
00635             return "failed to find address of pigpiod";
00636          case pigif_bad_connect:
00637             return "failed to connect to pigpiod";
00638          case pigif_bad_socket:
00639             return "failed to create socket";
00640          case pigif_bad_noib:
00641             return "failed to open notification in band";
00642          case pigif_duplicate_callback:
00643             return "identical callback exists";
00644          case pigif_bad_malloc:
00645             return "failed to malloc";
00646          case pigif_bad_callback:
00647             return "bad callback parameter";
00648          case pigif_notify_failed:
00649             return "failed to create notification thread";
00650          case pigif_callback_not_found:
00651             return "callback not found";
00652          case pigif_unconnected_pi:
00653             return "not connected to Pi";
00654          case pigif_too_many_pis:
00655             return "too many connected Pis";
00656 
00657          default:
00658             return "unknown error";
00659       }
00660    }
00661 }
00662 
00663 unsigned pigpiod_if_version(void)
00664 {
00665    return PIGPIOD_IF2_VERSION;
00666 }
00667 
00668 pthread_t *start_thread(gpioThreadFunc_t thread_func, void *userdata)
00669 {
00670    pthread_t *pth;
00671    pthread_attr_t pthAttr;
00672 
00673    pth = malloc(sizeof(pthread_t));
00674 
00675    if (pth)
00676    {
00677       if (pthread_attr_init(&pthAttr))
00678       {
00679          perror("pthread_attr_init failed");
00680          free(pth);
00681          return NULL;
00682       }
00683 
00684       if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE))
00685       {
00686          perror("pthread_attr_setstacksize failed");
00687          free(pth);
00688          return NULL;
00689       }
00690 
00691       if (pthread_create(pth, &pthAttr, thread_func, userdata))
00692       {
00693          perror("pthread_create socket failed");
00694          free(pth);
00695          return NULL;
00696       }
00697    }
00698    return pth;
00699 }
00700 
00701 void stop_thread(pthread_t *pth)
00702 {
00703    if (pth)
00704    {
00705       pthread_cancel(*pth);
00706       pthread_join(*pth, NULL);
00707       free(pth);
00708    }
00709 }
00710 
00711 int pigpio_start(char *addrStr, char *portStr)
00712 {
00713    int pi;
00714    int *userdata;
00715 
00716    if ((!addrStr) || (strlen(addrStr) == 0))
00717    {
00718       addrStr = "localhost";
00719    }
00720 
00721    for (pi=0; pi<MAX_PI; pi++)
00722    {
00723       if (!gPiInUse[pi]) break;
00724    }
00725 
00726    if (pi >= MAX_PI) return pigif_too_many_pis;
00727 
00728    gPiInUse[pi] = 1;
00729 
00730    pthread_mutex_init(&gCmdMutex[pi], NULL);
00731 
00732    gPigCommand[pi] = pigpioOpenSocket(addrStr, portStr);
00733 
00734    if (gPigCommand[pi] >= 0)
00735    {
00736       gPigNotify[pi] = pigpioOpenSocket(addrStr, portStr);
00737 
00738       if (gPigNotify[pi] >= 0)
00739       {
00740          gPigHandle[pi] = pigpio_notify(pi);
00741 
00742          if (gPigHandle[pi] < 0) return pigif_bad_noib;
00743          else
00744          {
00745             gLastLevel[pi] = read_bank_1(pi);
00746 
00747             /* must be freed by pthNotifyThread */
00748             userdata = malloc(sizeof(*userdata));
00749             *userdata = pi;
00750 
00751             gPthNotify[pi] = start_thread(pthNotifyThread, userdata);
00752 
00753             if (gPthNotify[pi]) return pi;
00754             else                return pigif_notify_failed;
00755 
00756          }
00757       }
00758       else return gPigNotify[pi];
00759    }
00760    else return gPigCommand[pi];
00761 }
00762 
00763 void pigpio_stop(int pi)
00764 {
00765    if ((pi < 0) || (pi >= MAX_PI) || !gPiInUse[pi]) return;
00766 
00767    if (gPthNotify[pi])
00768    {
00769       stop_thread(gPthNotify[pi]);
00770       gPthNotify[pi] = 0;
00771    }
00772 
00773    if (gPigCommand[pi] >= 0)
00774    {
00775       if (gPigHandle[pi] >= 0)
00776       {
00777          pigpio_command(pi, PI_CMD_NC, gPigHandle[pi], 0, 1);
00778          gPigHandle[pi] = -1;
00779       }
00780 
00781       close(gPigCommand[pi]);
00782       gPigCommand[pi] = -1;
00783    }
00784 
00785    if (gPigNotify[pi] >= 0)
00786    {
00787       close(gPigNotify[pi]);
00788       gPigNotify[pi] = -1;
00789    }
00790 
00791    gPiInUse[pi] = 0;
00792 }
00793 
00794 int set_mode(int pi, unsigned gpio, unsigned mode)
00795    {return pigpio_command(pi, PI_CMD_MODES, gpio, mode, 1);}
00796 
00797 int get_mode(int pi, unsigned gpio)
00798    {return pigpio_command(pi, PI_CMD_MODEG, gpio, 0, 1);}
00799 
00800 int set_pull_up_down(int pi, unsigned gpio, unsigned pud)
00801    {return pigpio_command(pi, PI_CMD_PUD, gpio, pud, 1);}
00802 
00803 int gpio_read(int pi, unsigned gpio)
00804    {return pigpio_command(pi, PI_CMD_READ, gpio, 0, 1);}
00805 
00806 int gpio_write(int pi, unsigned gpio, unsigned level)
00807    {return pigpio_command(pi, PI_CMD_WRITE, gpio, level, 1);}
00808 
00809 int set_PWM_dutycycle(int pi, unsigned user_gpio, unsigned dutycycle)
00810    {return pigpio_command(pi, PI_CMD_PWM, user_gpio, dutycycle, 1);}
00811 
00812 int get_PWM_dutycycle(int pi, unsigned user_gpio)
00813    {return pigpio_command(pi, PI_CMD_GDC, user_gpio, 0, 1);}
00814 
00815 int set_PWM_range(int pi, unsigned user_gpio, unsigned range)
00816    {return pigpio_command(pi, PI_CMD_PRS, user_gpio, range, 1);}
00817 
00818 int get_PWM_range(int pi, unsigned user_gpio)
00819    {return pigpio_command(pi, PI_CMD_PRG, user_gpio, 0, 1);}
00820 
00821 int get_PWM_real_range(int pi, unsigned user_gpio)
00822    {return pigpio_command(pi, PI_CMD_PRRG, user_gpio, 0, 1);}
00823 
00824 int set_PWM_frequency(int pi, unsigned user_gpio, unsigned frequency)
00825    {return pigpio_command(pi, PI_CMD_PFS, user_gpio, frequency, 1);}
00826 
00827 int get_PWM_frequency(int pi, unsigned user_gpio)
00828    {return pigpio_command(pi, PI_CMD_PFG, user_gpio, 0, 1);}
00829 
00830 int set_servo_pulsewidth(int pi, unsigned user_gpio, unsigned pulsewidth)
00831    {return pigpio_command(pi, PI_CMD_SERVO, user_gpio, pulsewidth, 1);}
00832 
00833 int get_servo_pulsewidth(int pi, unsigned user_gpio)
00834    {return pigpio_command(pi, PI_CMD_GPW, user_gpio, 0, 1);}
00835 
00836 int notify_open(int pi)
00837    {return pigpio_command(pi, PI_CMD_NO, 0, 0, 1);}
00838 
00839 int notify_begin(int pi, unsigned handle, uint32_t bits)
00840    {return pigpio_command(pi, PI_CMD_NB, handle, bits, 1);}
00841 
00842 int notify_pause(int pi, unsigned handle)
00843    {return pigpio_command(pi, PI_CMD_NB, handle, 0, 1);}
00844 
00845 int notify_close(int pi, unsigned handle)
00846    {return pigpio_command(pi, PI_CMD_NC, handle, 0, 1);}
00847 
00848 int set_watchdog(int pi, unsigned user_gpio, unsigned timeout)
00849    {return pigpio_command(pi, PI_CMD_WDOG, user_gpio, timeout, 1);}
00850 
00851 uint32_t read_bank_1(int pi)
00852    {return pigpio_command(pi, PI_CMD_BR1, 0, 0, 1);}
00853 
00854 uint32_t read_bank_2(int pi)
00855    {return pigpio_command(pi, PI_CMD_BR2, 0, 0, 1);}
00856 
00857 int clear_bank_1(int pi, uint32_t levels)
00858    {return pigpio_command(pi, PI_CMD_BC1, levels, 0, 1);}
00859 
00860 int clear_bank_2(int pi, uint32_t levels)
00861    {return pigpio_command(pi, PI_CMD_BC2, levels, 0, 1);}
00862 
00863 int set_bank_1(int pi, uint32_t levels)
00864    {return pigpio_command(pi, PI_CMD_BS1, levels, 0, 1);}
00865 
00866 int set_bank_2(int pi, uint32_t levels)
00867    {return pigpio_command(pi, PI_CMD_BS2, levels, 0, 1);}
00868 
00869 int hardware_clock(int pi, unsigned gpio, unsigned frequency)
00870    {return pigpio_command(pi, PI_CMD_HC, gpio, frequency, 1);}
00871 
00872 int hardware_PWM(int pi, unsigned gpio, unsigned frequency, uint32_t dutycycle)
00873 {
00874    gpioExtent_t ext[1];
00875    
00876    /*
00877    p1=gpio
00878    p2=frequency
00879    p3=4
00880    ## extension ##
00881    uint32_t dutycycle
00882    */
00883 
00884    ext[0].size = sizeof(dutycycle);
00885    ext[0].ptr = &dutycycle;
00886 
00887    return pigpio_command_ext(
00888       pi, PI_CMD_HP, gpio, frequency, sizeof(dutycycle), 1, ext, 1);
00889 }
00890 
00891 uint32_t get_current_tick(int pi)
00892    {return pigpio_command(pi, PI_CMD_TICK, 0, 0, 1);}
00893 
00894 uint32_t get_hardware_revision(int pi)
00895    {return pigpio_command(pi, PI_CMD_HWVER, 0, 0, 1);}
00896 
00897 uint32_t get_pigpio_version(int pi)
00898    {return pigpio_command(pi, PI_CMD_PIGPV, 0, 0, 1);}
00899 
00900 int wave_clear(int pi)
00901    {return pigpio_command(pi, PI_CMD_WVCLR, 0, 0, 1);}
00902 
00903 int wave_add_new(int pi)
00904    {return pigpio_command(pi, PI_CMD_WVNEW, 0, 0, 1);}
00905 
00906 int wave_add_generic(int pi, unsigned numPulses, gpioPulse_t *pulses)
00907 {
00908    gpioExtent_t ext[1];
00909    
00910    /*
00911    p1=0
00912    p2=0
00913    p3=pulses*sizeof(gpioPulse_t)
00914    ## extension ##
00915    gpioPulse_t[] pulses
00916    */
00917 
00918    if (!numPulses) return 0;
00919 
00920    ext[0].size = numPulses * sizeof(gpioPulse_t);
00921    ext[0].ptr = pulses;
00922 
00923    return pigpio_command_ext(
00924       pi, PI_CMD_WVAG, 0, 0, ext[0].size, 1, ext, 1);
00925 }
00926 
00927 int wave_add_serial(
00928    int pi, unsigned user_gpio, unsigned baud, uint32_t databits,
00929    uint32_t stophalfbits, uint32_t offset,  unsigned numChar, char *str)
00930 {
00931    uint8_t buf[12];
00932    gpioExtent_t ext[2];
00933 
00934    /*
00935    p1=user_gpio
00936    p2=baud
00937    p3=len+12
00938    ## extension ##
00939    uint32_t databits
00940    uint32_t stophalfbits
00941    uint32_t offset
00942    char[len] str
00943    */
00944 
00945    if (!numChar) return 0;
00946 
00947    memcpy(buf, &databits, 4);
00948    memcpy(buf+4, &stophalfbits, 4);
00949    memcpy(buf+8, &offset, 4);
00950 
00951    ext[0].size = sizeof(buf);
00952    ext[0].ptr = buf;
00953 
00954    ext[1].size = numChar;
00955    ext[1].ptr = str;
00956 
00957    return pigpio_command_ext(pi, PI_CMD_WVAS,
00958       user_gpio, baud, numChar+sizeof(buf), 2, ext, 1);
00959 }
00960 
00961 int wave_create(int pi)
00962    {return pigpio_command(pi, PI_CMD_WVCRE, 0, 0, 1);}
00963 
00964 int wave_delete(int pi, unsigned wave_id)
00965    {return pigpio_command(pi, PI_CMD_WVDEL, wave_id, 0, 1);}
00966 
00967 int wave_tx_start(int pi) /* DEPRECATED */
00968    {return pigpio_command(pi, PI_CMD_WVGO, 0, 0, 1);}
00969 
00970 int wave_tx_repeat(int pi) /* DEPRECATED */
00971    {return pigpio_command(pi, PI_CMD_WVGOR, 0, 0, 1);}
00972 
00973 int wave_send_once(int pi, unsigned wave_id)
00974    {return pigpio_command(pi, PI_CMD_WVTX, wave_id, 0, 1);}
00975 
00976 int wave_send_repeat(int pi, unsigned wave_id)
00977    {return pigpio_command(pi, PI_CMD_WVTXR, wave_id, 0, 1);}
00978 
00979 int wave_send_using_mode(int pi, unsigned wave_id, unsigned mode)
00980    {return pigpio_command(pi, PI_CMD_WVTXM, wave_id, mode, 1);}
00981 
00982 int wave_chain(int pi, char *buf, unsigned bufSize)
00983 {
00984    gpioExtent_t ext[1];
00985 
00986    /*
00987    p1=0
00988    p2=0
00989    p3=bufSize
00990    ## extension ##
00991    char buf[bufSize]
00992    */
00993 
00994    ext[0].size = bufSize;
00995    ext[0].ptr = buf;
00996 
00997    return pigpio_command_ext
00998       (pi, PI_CMD_WVCHA, 0, 0, bufSize, 1, ext, 1);
00999 }
01000 
01001 int wave_tx_at(int pi)
01002    {return pigpio_command(pi, PI_CMD_WVTAT, 0, 0, 1);}
01003 
01004 int wave_tx_busy(int pi)
01005    {return pigpio_command(pi, PI_CMD_WVBSY, 0, 0, 1);}
01006 
01007 int wave_tx_stop(int pi)
01008    {return pigpio_command(pi, PI_CMD_WVHLT, 0, 0, 1);}
01009 
01010 int wave_get_micros(int pi)
01011    {return pigpio_command(pi, PI_CMD_WVSM, 0, 0, 1);}
01012 
01013 int wave_get_high_micros(int pi)
01014    {return pigpio_command(pi, PI_CMD_WVSM, 1, 0, 1);}
01015 
01016 int wave_get_max_micros(int pi)
01017    {return pigpio_command(pi, PI_CMD_WVSM, 2, 0, 1);}
01018 
01019 int wave_get_pulses(int pi)
01020    {return pigpio_command(pi, PI_CMD_WVSP, 0, 0, 1);}
01021 
01022 int wave_get_high_pulses(int pi)
01023    {return pigpio_command(pi, PI_CMD_WVSP, 1, 0, 1);}
01024 
01025 int wave_get_max_pulses(int pi)
01026    {return pigpio_command(pi, PI_CMD_WVSP, 2, 0, 1);}
01027 
01028 int wave_get_cbs(int pi)
01029    {return pigpio_command(pi, PI_CMD_WVSC, 0, 0, 1);}
01030 
01031 int wave_get_high_cbs(int pi)
01032    {return pigpio_command(pi, PI_CMD_WVSC, 1, 0, 1);}
01033 
01034 int wave_get_max_cbs(int pi)
01035    {return pigpio_command(pi, PI_CMD_WVSC, 2, 0, 1);}
01036 
01037 int gpio_trigger(int pi, unsigned user_gpio, unsigned pulseLen, uint32_t level)
01038 {
01039    gpioExtent_t ext[1];
01040    
01041    /*
01042    p1=user_gpio
01043    p2=pulseLen 
01044    p3=4
01045    ## extension ##
01046    unsigned level
01047    */
01048 
01049    ext[0].size = sizeof(uint32_t);
01050    ext[0].ptr = &level;
01051 
01052    return pigpio_command_ext(
01053       pi, PI_CMD_TRIG, user_gpio, pulseLen, 4, 1, ext, 1);
01054 }
01055 
01056 int set_glitch_filter(int pi, unsigned user_gpio, unsigned steady)
01057    {return pigpio_command(pi, PI_CMD_FG, user_gpio, steady, 1);}
01058 
01059 int set_noise_filter(int pi, unsigned user_gpio, unsigned steady, unsigned active)
01060 {
01061    gpioExtent_t ext[1];
01062    
01063    /*
01064    p1=user_gpio
01065    p2=steady
01066    p3=4
01067    ## extension ##
01068    unsigned active
01069    */
01070 
01071    ext[0].size = sizeof(uint32_t);
01072    ext[0].ptr = &active;
01073 
01074    return pigpio_command_ext(
01075       pi, PI_CMD_FN, user_gpio, steady, 4, 1, ext, 1);
01076 }
01077 
01078 int store_script(int pi, char *script)
01079 {
01080    unsigned len;
01081    gpioExtent_t ext[1];
01082 
01083    /*
01084    p1=0
01085    p2=0
01086    p3=len
01087    ## extension ##
01088    char[len] script
01089    */
01090 
01091    len = strlen(script);
01092 
01093    if (!len) return 0;
01094 
01095    ext[0].size = len;
01096    ext[0].ptr = script;
01097 
01098    return pigpio_command_ext(pi, PI_CMD_PROC, 0, 0, len, 1, ext, 1);
01099 }
01100 
01101 int run_script(int pi, unsigned script_id, unsigned numPar, uint32_t *param)
01102 {
01103    gpioExtent_t ext[1];
01104 
01105    /*
01106    p1=script id
01107    p2=0
01108    p3=numPar * 4
01109    ## extension ##
01110    uint32_t[numPar] pars
01111    */
01112 
01113    ext[0].size = 4 * numPar;
01114    ext[0].ptr = param;
01115 
01116    return pigpio_command_ext
01117       (pi, PI_CMD_PROCR, script_id, 0, numPar*4, 1, ext, 1);
01118 }
01119 
01120 int update_script(int pi, unsigned script_id, unsigned numPar, uint32_t *param)
01121 {
01122    gpioExtent_t ext[1];
01123 
01124    /*
01125    p1=script id
01126    p2=0
01127    p3=numPar * 4
01128    ## extension ##
01129    uint32_t[numPar] pars
01130    */
01131 
01132    ext[0].size = 4 * numPar;
01133    ext[0].ptr = param;
01134 
01135    return pigpio_command_ext
01136       (pi, PI_CMD_PROCU, script_id, 0, numPar*4, 1, ext, 1);
01137 }
01138 
01139 int script_status(int pi, unsigned script_id, uint32_t *param)
01140 {
01141    int status;
01142    uint32_t p[PI_MAX_SCRIPT_PARAMS+1]; /* space for script status */
01143 
01144    status = pigpio_command(pi, PI_CMD_PROCP, script_id, 0, 0);
01145 
01146    if (status > 0)
01147    {
01148       recvMax(pi, p, sizeof(p), status);
01149       status = p[0];
01150       if (param) memcpy(param, p+1, sizeof(p)-4);
01151    }
01152 
01153    _pmu(pi);
01154 
01155    return status;
01156 }
01157 
01158 int stop_script(int pi, unsigned script_id)
01159    {return pigpio_command(pi, PI_CMD_PROCS, script_id, 0, 1);}
01160 
01161 int delete_script(int pi, unsigned script_id)
01162    {return pigpio_command(pi, PI_CMD_PROCD, script_id, 0, 1);}
01163 
01164 int bb_serial_read_open(int pi, unsigned user_gpio, unsigned baud, uint32_t bbBits)
01165 {
01166    gpioExtent_t ext[1];
01167    
01168    /*
01169    p1=user_gpio
01170    p2=baud
01171    p3=4
01172    ## extension ##
01173    unsigned bbBits
01174    */
01175 
01176    ext[0].size = sizeof(uint32_t);
01177    ext[0].ptr = &bbBits;
01178 
01179    return pigpio_command_ext(
01180       pi, PI_CMD_SLRO, user_gpio, baud, 4, 1, ext, 1);
01181 }
01182 
01183 int bb_serial_read(int pi, unsigned user_gpio, void *buf, size_t bufSize)
01184 {
01185    int bytes;
01186 
01187    bytes = pigpio_command(pi, PI_CMD_SLR, user_gpio, bufSize, 0);
01188 
01189    if (bytes > 0)
01190    {
01191       bytes = recvMax(pi, buf, bufSize, bytes);
01192    }
01193 
01194    _pmu(pi);
01195 
01196    return bytes;
01197 }
01198 
01199 int bb_serial_read_close(int pi, unsigned user_gpio)
01200    {return pigpio_command(pi, PI_CMD_SLRC, user_gpio, 0, 1);}
01201 
01202 int bb_serial_invert(int pi, unsigned user_gpio, unsigned invert)
01203    {return pigpio_command(pi, PI_CMD_SLRI, user_gpio, invert, 1);}
01204 
01205 int i2c_open(int pi, unsigned i2c_bus, unsigned i2c_addr, uint32_t i2c_flags)
01206 {
01207    gpioExtent_t ext[1];
01208 
01209    /*
01210    p1=i2c_bus
01211    p2=i2c_addr
01212    p3=4
01213    ## extension ##
01214    uint32_t i2c_flags
01215    */
01216 
01217    ext[0].size = sizeof(uint32_t);
01218    ext[0].ptr = &i2c_flags;
01219 
01220    return pigpio_command_ext
01221       (pi, PI_CMD_I2CO, i2c_bus, i2c_addr, 4, 1, ext, 1);
01222 }
01223 
01224 int i2c_close(int pi, unsigned handle)
01225    {return pigpio_command(pi, PI_CMD_I2CC, handle, 0, 1);}
01226 
01227 int i2c_write_quick(int pi, unsigned handle, unsigned bit)
01228    {return pigpio_command(pi, PI_CMD_I2CWQ, handle, bit, 1);}
01229 
01230 int i2c_write_byte(int pi, unsigned handle, unsigned val)
01231    {return pigpio_command(pi, PI_CMD_I2CWS, handle, val, 1);}
01232 
01233 int i2c_read_byte(int pi, unsigned handle)
01234    {return pigpio_command(pi, PI_CMD_I2CRS, handle, 0, 1);}
01235 
01236 int i2c_write_byte_data(int pi, unsigned handle, unsigned reg, uint32_t val)
01237 {
01238    gpioExtent_t ext[1];
01239 
01240    /*
01241    p1=handle
01242    p2=reg
01243    p3=4
01244    ## extension ##
01245    uint32_t val
01246    */
01247 
01248    ext[0].size = sizeof(uint32_t);
01249    ext[0].ptr = &val;
01250 
01251    return pigpio_command_ext
01252       (pi, PI_CMD_I2CWB, handle, reg, 4, 1, ext, 1);
01253 }
01254 
01255 int i2c_write_word_data(int pi, unsigned handle, unsigned reg, uint32_t val)
01256 {
01257    gpioExtent_t ext[1];
01258 
01259    /*
01260    p1=handle
01261    p2=reg
01262    p3=4
01263    ## extension ##
01264    uint32_t val
01265    */
01266 
01267    ext[0].size = sizeof(uint32_t);
01268    ext[0].ptr = &val;
01269 
01270    return pigpio_command_ext
01271       (pi, PI_CMD_I2CWW, handle, reg, 4, 1, ext, 1);
01272 }
01273 
01274 int i2c_read_byte_data(int pi, unsigned handle, unsigned reg)
01275    {return pigpio_command(pi, PI_CMD_I2CRB, handle, reg, 1);}
01276 
01277 int i2c_read_word_data(int pi, unsigned handle, unsigned reg)
01278    {return pigpio_command(pi, PI_CMD_I2CRW, handle, reg, 1);}
01279 
01280 int i2c_process_call(int pi, unsigned handle, unsigned reg, uint32_t val)
01281 {
01282    gpioExtent_t ext[1];
01283 
01284    /*
01285    p1=handle
01286    p2=reg
01287    p3=4
01288    ## extension ##
01289    uint32_t val
01290    */
01291 
01292    ext[0].size = sizeof(uint32_t);
01293    ext[0].ptr = &val;
01294 
01295    return pigpio_command_ext
01296       (pi, PI_CMD_I2CPK, handle, reg, 4, 1, ext, 1);
01297 }
01298 
01299 int i2c_write_block_data(
01300    int pi, unsigned handle, unsigned reg, char *buf, unsigned count)
01301 {
01302    gpioExtent_t ext[1];
01303 
01304    /*
01305    p1=handle
01306    p2=reg
01307    p3=count
01308    ## extension ##
01309    char buf[count]
01310    */
01311 
01312    ext[0].size = count;
01313    ext[0].ptr = buf;
01314 
01315    return pigpio_command_ext
01316       (pi, PI_CMD_I2CWK, handle, reg, count, 1, ext, 1);
01317 }
01318 
01319 int i2c_read_block_data(int pi, unsigned handle, unsigned reg, char *buf)
01320 {
01321    int bytes;
01322 
01323    bytes = pigpio_command(pi, PI_CMD_I2CRK, handle, reg, 0);
01324 
01325    if (bytes > 0)
01326    {
01327       bytes = recvMax(pi, buf, 32, bytes);
01328    }
01329 
01330    _pmu(pi);
01331 
01332    return bytes;
01333 }
01334 
01335 int i2c_block_process_call(
01336    int pi, unsigned handle, unsigned reg, char *buf, unsigned count)
01337 {
01338    int bytes;
01339    gpioExtent_t ext[1];
01340 
01341    /*
01342    p1=handle
01343    p2=reg
01344    p3=count
01345    ## extension ##
01346    char buf[count]
01347    */
01348 
01349    ext[0].size = count;
01350    ext[0].ptr = buf;
01351 
01352    bytes = pigpio_command_ext
01353       (pi, PI_CMD_I2CPK, handle, reg, count, 1, ext, 0);
01354 
01355    if (bytes > 0)
01356    {
01357       bytes = recvMax(pi, buf, 32, bytes);
01358    }
01359 
01360    _pmu(pi);
01361 
01362    return bytes;
01363 }
01364 
01365 int i2c_read_i2c_block_data(
01366    int pi, unsigned handle, unsigned reg, char *buf, uint32_t count)
01367 {
01368    int bytes;
01369    gpioExtent_t ext[1];
01370 
01371    /*
01372    p1=handle
01373    p2=reg
01374    p3=4
01375    ## extension ##
01376    uint32_t count
01377    */
01378 
01379    ext[0].size = sizeof(uint32_t);
01380    ext[0].ptr = &count;
01381 
01382    bytes = pigpio_command_ext
01383       (pi, PI_CMD_I2CRI, handle, reg, 4, 1, ext, 0);
01384 
01385    if (bytes > 0)
01386    {
01387       bytes = recvMax(pi, buf, count, bytes);
01388    }
01389 
01390    _pmu(pi);
01391 
01392    return bytes;
01393 }
01394 
01395 
01396 int i2c_write_i2c_block_data(
01397    int pi, unsigned handle, unsigned reg, char *buf, unsigned count)
01398 {
01399    gpioExtent_t ext[1];
01400 
01401    /*
01402    p1=handle
01403    p2=reg
01404    p3=count
01405    ## extension ##
01406    char buf[count]
01407    */
01408 
01409    ext[0].size = count;
01410    ext[0].ptr = buf;
01411 
01412    return pigpio_command_ext
01413       (pi, PI_CMD_I2CWI, handle, reg, count, 1, ext, 1);
01414 }
01415 
01416 int i2c_read_device(int pi, unsigned handle, char *buf, unsigned count)
01417 {
01418    int bytes;
01419 
01420    bytes = pigpio_command(pi, PI_CMD_I2CRD, handle, count, 0);
01421 
01422    if (bytes > 0)
01423    {
01424       bytes = recvMax(pi, buf, count, bytes);
01425    }
01426 
01427    _pmu(pi);
01428 
01429    return bytes;
01430 }
01431 
01432 int i2c_write_device(int pi, unsigned handle, char *buf, unsigned count)
01433 {
01434    gpioExtent_t ext[1];
01435 
01436    /*
01437    p1=handle
01438    p2=0
01439    p3=count
01440    ## extension ##
01441    char buf[count]
01442    */
01443 
01444    ext[0].size = count;
01445    ext[0].ptr = buf;
01446 
01447    return pigpio_command_ext
01448       (pi, PI_CMD_I2CWD, handle, 0, count, 1, ext, 1);
01449 }
01450 
01451 int i2c_zip(
01452    int pi,
01453    unsigned handle,
01454    char    *inBuf,
01455    unsigned inLen,
01456    char    *outBuf,
01457    unsigned outLen)
01458 {
01459    int bytes;
01460    gpioExtent_t ext[1];
01461 
01462    /*
01463    p1=handle
01464    p2=0
01465    p3=inLen
01466    ## extension ##
01467    char inBuf[inLen]
01468    */
01469 
01470    ext[0].size = inLen;
01471    ext[0].ptr = inBuf;
01472 
01473    bytes = pigpio_command_ext
01474       (pi, PI_CMD_I2CZ, handle, 0, inLen, 1, ext, 0);
01475 
01476    if (bytes > 0)
01477    {
01478       bytes = recvMax(pi, outBuf, outLen, bytes);
01479    }
01480 
01481    _pmu(pi);
01482 
01483    return bytes;
01484 }
01485 
01486 int bb_i2c_open(int pi, unsigned SDA, unsigned SCL, unsigned baud)
01487 {
01488    gpioExtent_t ext[1];
01489 
01490    /*
01491    p1=SDA
01492    p2=SCL
01493    p3=4
01494    ## extension ##
01495    uint32_t baud
01496    */
01497 
01498    ext[0].size = sizeof(uint32_t);
01499    ext[0].ptr = &baud;
01500 
01501    return pigpio_command_ext
01502       (pi, PI_CMD_BI2CO, SDA, SCL, 4, 1, ext, 1);
01503 }
01504 
01505 int bb_i2c_close(int pi, unsigned SDA)
01506    {return pigpio_command(pi, PI_CMD_BI2CC, SDA, 0, 1);}
01507 
01508 int bb_i2c_zip(
01509    int      pi,
01510    unsigned SDA,
01511    char    *inBuf,
01512    unsigned inLen,
01513    char    *outBuf,
01514    unsigned outLen)
01515 {
01516    int bytes;
01517    gpioExtent_t ext[1];
01518 
01519    /*
01520    p1=SDA
01521    p2=0
01522    p3=inLen
01523    ## extension ##
01524    char inBuf[inLen]
01525    */
01526 
01527    ext[0].size = inLen;
01528    ext[0].ptr = inBuf;
01529 
01530    bytes = pigpio_command_ext
01531       (pi, PI_CMD_BI2CZ, SDA, 0, inLen, 1, ext, 0);
01532 
01533    if (bytes > 0)
01534    {
01535       bytes = recvMax(pi, outBuf, outLen, bytes);
01536    }
01537 
01538    _pmu(pi);
01539 
01540    return bytes;
01541 }
01542 
01543 int bb_spi_open(
01544    int pi,
01545    unsigned CS, unsigned MISO, unsigned MOSI, unsigned SCLK,
01546    unsigned baud, unsigned spiFlags)
01547 {
01548    uint8_t buf[20];
01549    gpioExtent_t ext[1];
01550 
01551    /*
01552    p1=CS
01553    p2=0
01554    p3=20
01555    ## extension ##
01556    uint32_t MISO
01557    uint32_t MOSI
01558    uint32_t SCLK
01559    uint32_t baud
01560    uint32_t spiFlags
01561    */
01562 
01563    ext[0].size = 20;
01564    ext[0].ptr = &buf;
01565 
01566    memcpy(buf +  0, &MISO, 4);
01567    memcpy(buf +  4, &MOSI, 4);
01568    memcpy(buf +  8, &SCLK, 4);
01569    memcpy(buf + 12, &baud, 4);
01570    memcpy(buf + 16, &spiFlags, 4);
01571 
01572    return pigpio_command_ext
01573       (pi, PI_CMD_BSPIO, CS, 0, 20, 1, ext, 1);
01574 }
01575 
01576 int bb_spi_close(int pi, unsigned CS)
01577    {return pigpio_command(pi, PI_CMD_BSPIC, CS, 0, 1);}
01578 
01579 int bb_spi_xfer(
01580    int pi,
01581    unsigned CS,
01582    char    *txBuf,
01583    char    *rxBuf,
01584    unsigned count)
01585 {
01586    int bytes;
01587    gpioExtent_t ext[1];
01588 
01589    /*
01590    p1=CS
01591    p2=0
01592    p3=count
01593    ## extension ##
01594    char txBuf[count]
01595    */
01596 
01597    ext[0].size = count;
01598    ext[0].ptr = txBuf;
01599 
01600    bytes = pigpio_command_ext
01601       (pi, PI_CMD_BSPIX, CS, 0, count, 1, ext, 0);
01602 
01603    if (bytes > 0)
01604    {
01605       bytes = recvMax(pi, rxBuf, count, bytes);
01606    }
01607 
01608    _pmu(pi);
01609 
01610    return bytes;
01611 }
01612 
01613 int spi_open(int pi, unsigned channel, unsigned speed, uint32_t flags)
01614 {
01615    gpioExtent_t ext[1];
01616 
01617    /*
01618    p1=channel
01619    p2=speed
01620    p3=4
01621    ## extension ##
01622    uint32_t flags
01623    */
01624 
01625    ext[0].size = sizeof(uint32_t);
01626    ext[0].ptr = &flags;
01627 
01628    return pigpio_command_ext
01629       (pi, PI_CMD_SPIO, channel, speed, 4, 1, ext, 1);
01630 }
01631 
01632 int spi_close(int pi, unsigned handle)
01633    {return pigpio_command(pi, PI_CMD_SPIC, handle, 0, 1);}
01634 
01635 int spi_read(int pi, unsigned handle, char *buf, unsigned count)
01636 {
01637    int bytes;
01638 
01639    bytes = pigpio_command
01640       (pi, PI_CMD_SPIR, handle, count, 0);
01641 
01642    if (bytes > 0)
01643    {
01644       bytes = recvMax(pi, buf, count, bytes);
01645    }
01646 
01647    _pmu(pi);
01648 
01649    return bytes;
01650 }
01651 
01652 int spi_write(int pi, unsigned handle, char *buf, unsigned count)
01653 {
01654    gpioExtent_t ext[1];
01655 
01656    /*
01657    p1=handle
01658    p2=0
01659    p3=count
01660    ## extension ##
01661    char buf[count]
01662    */
01663 
01664    ext[0].size = count;
01665    ext[0].ptr = buf;
01666 
01667    return pigpio_command_ext
01668       (pi, PI_CMD_SPIW, handle, 0, count, 1, ext, 1);
01669 }
01670 
01671 int spi_xfer(int pi, unsigned handle, char *txBuf, char *rxBuf, unsigned count)
01672 {
01673    int bytes;
01674    gpioExtent_t ext[1];
01675 
01676    /*
01677    p1=handle
01678    p2=0
01679    p3=count
01680    ## extension ##
01681    char buf[count]
01682    */
01683 
01684    ext[0].size = count;
01685    ext[0].ptr = txBuf;
01686 
01687    bytes = pigpio_command_ext
01688       (pi, PI_CMD_SPIX, handle, 0, count, 1, ext, 0);
01689 
01690    if (bytes > 0)
01691    {
01692       bytes = recvMax(pi, rxBuf, count, bytes);
01693    }
01694 
01695    _pmu(pi);
01696 
01697    return bytes;
01698 }
01699 
01700 int serial_open(int pi, char *dev, unsigned baud, unsigned flags)
01701 {
01702    int len;
01703    gpioExtent_t ext[1];
01704 
01705    len = strlen(dev);
01706 
01707    /*
01708    p1=baud
01709    p2=flags
01710    p3=len
01711    ## extension ##
01712    char dev[len]
01713    */
01714 
01715    ext[0].size = len;
01716    ext[0].ptr = dev;
01717 
01718    return pigpio_command_ext
01719       (pi, PI_CMD_SERO, baud, flags, len, 1, ext, 1);
01720 }
01721 
01722 int serial_close(int pi, unsigned handle)
01723    {return pigpio_command(pi, PI_CMD_SERC, handle, 0, 1);}
01724 
01725 int serial_write_byte(int pi, unsigned handle, unsigned val)
01726    {return pigpio_command(pi, PI_CMD_SERWB, handle, val, 1);}
01727 
01728 int serial_read_byte(int pi, unsigned handle)
01729    {return pigpio_command(pi, PI_CMD_SERRB, handle, 0, 1);}
01730 
01731 int serial_write(int pi, unsigned handle, char *buf, unsigned count)
01732 {
01733    gpioExtent_t ext[1];
01734 
01735    /*
01736    p1=handle
01737    p2=0
01738    p3=count
01739    ## extension ##
01740    char buf[count]
01741    */
01742 
01743    ext[0].size = count;
01744    ext[0].ptr = buf;
01745 
01746    return pigpio_command_ext
01747       (pi, PI_CMD_SERW, handle, 0, count, 1, ext, 1);
01748 }
01749 
01750 int serial_read(int pi, unsigned handle, char *buf, unsigned count)
01751 {
01752    int bytes;
01753 
01754    bytes = pigpio_command
01755       (pi, PI_CMD_SERR, handle, count, 0);
01756 
01757    if (bytes > 0)
01758    {
01759       bytes = recvMax(pi, buf, count, bytes);
01760    }
01761 
01762    _pmu(pi);
01763 
01764    return bytes;
01765 }
01766 
01767 int serial_data_available(int pi, unsigned handle)
01768    {return pigpio_command(pi, PI_CMD_SERDA, handle, 0, 1);}
01769 
01770 int custom_1(int pi, unsigned arg1, unsigned arg2, char *argx, unsigned count)
01771 {
01772    gpioExtent_t ext[1];
01773 
01774    /*
01775    p1=arg1
01776    p2=arg2
01777    p3=count
01778    ## extension ##
01779    char argx[count]
01780    */
01781 
01782    ext[0].size = count;
01783    ext[0].ptr = argx;
01784 
01785    return pigpio_command_ext(
01786       pi, PI_CMD_CF1, arg1, arg2, count, 1, ext, 1);
01787 }
01788 
01789 
01790 int custom_2(int pi, unsigned arg1, char *argx, unsigned count,
01791              char *retBuf, uint32_t retMax)
01792 {
01793    int bytes;
01794    gpioExtent_t ext[1];
01795 
01796    /*
01797    p1=arg1
01798    p2=retMax
01799    p3=count
01800    ## extension ##
01801    char argx[count]
01802    */
01803 
01804    ext[0].size = count;
01805    ext[0].ptr = argx;
01806 
01807    bytes = pigpio_command_ext
01808       (pi, PI_CMD_CF2, arg1, retMax, count, 1, ext, 0);
01809 
01810    if (bytes > 0)
01811    {
01812       bytes = recvMax(pi, retBuf, retMax, bytes);
01813    }
01814 
01815    _pmu(pi);
01816 
01817    return bytes;
01818 }
01819 
01820 int get_pad_strength(int pi, unsigned pad)
01821    {return pigpio_command(pi, PI_CMD_PADG, pad, 0, 1);}
01822 
01823 int set_pad_strength(int pi, unsigned pad, unsigned padStrength)
01824    {return pigpio_command(pi, PI_CMD_PADS, pad, padStrength, 1);}
01825 
01826 int shell_(int pi, char *scriptName, char *scriptString)
01827 {
01828    int ln, ls;
01829    gpioExtent_t ext[2];
01830 
01831    ln = strlen(scriptName);
01832    ls = strlen(scriptString);
01833    /*
01834    p1=len(scriptName)
01835    p2=0
01836    p3=len(scriptName) + len(scriptString) + 1
01837    ## extension ##
01838    char[]
01839    */
01840 
01841    ext[0].size = ln + 1; /* include null byte */
01842    ext[0].ptr = scriptName;
01843 
01844    ext[1].size = ls;
01845    ext[1].ptr = scriptString;
01846 
01847    return pigpio_command_ext
01848       (pi, PI_CMD_SHELL, ln, 0, ln+ls+1, 2, ext, 1);
01849 }
01850 
01851 int file_open(int pi, char *file, unsigned mode)
01852 {
01853    int len;
01854    gpioExtent_t ext[1];
01855 
01856    len = strlen(file);
01857 
01858    /*
01859    p1=mode
01860    p2=0
01861    p3=len
01862    ## extension ##
01863    char file[len]
01864    */
01865 
01866    ext[0].size = len;
01867    ext[0].ptr = file;
01868 
01869    return pigpio_command_ext
01870       (pi, PI_CMD_FO, mode, 0, len, 1, ext, 1);
01871 }
01872 
01873 int file_close(int pi, unsigned handle)
01874    {return pigpio_command(pi, PI_CMD_FC, handle, 0, 1);}
01875 
01876 int file_write(int pi, unsigned handle, char *buf, unsigned count)
01877 {
01878    gpioExtent_t ext[1];
01879 
01880    /*
01881    p1=handle
01882    p2=0
01883    p3=count
01884    ## extension ##
01885    char buf[count]
01886    */
01887 
01888    ext[0].size = count;
01889    ext[0].ptr = buf;
01890 
01891    return pigpio_command_ext
01892       (pi, PI_CMD_FW, handle, 0, count, 1, ext, 1);
01893 }
01894 
01895 int file_read(int pi, unsigned handle, char *buf, unsigned count)
01896 {
01897    int bytes;
01898 
01899    bytes = pigpio_command
01900       (pi, PI_CMD_FR, handle, count, 0);
01901 
01902    if (bytes > 0)
01903    {
01904       bytes = recvMax(pi, buf, count, bytes);
01905    }
01906 
01907    _pmu(pi);
01908 
01909    return bytes;
01910 }
01911 
01912 int file_seek(int pi, unsigned handle, int32_t seekOffset, int seekFrom)
01913 {
01914    gpioExtent_t ext[1];
01915 
01916    /*
01917    p1=handle
01918    p2=seekOffset
01919    p3=4
01920    ## extension ##
01921    uint32_t seekFrom
01922    */
01923 
01924    ext[0].size = sizeof(uint32_t);
01925    ext[0].ptr = &seekFrom;
01926 
01927    return pigpio_command_ext
01928       (pi, PI_CMD_FS, handle, seekOffset, 4, 1, ext, 1);
01929 }
01930 
01931 int file_list(int pi, char *fpat,  char *buf, unsigned count)
01932 {
01933    int len;
01934    int bytes;
01935    gpioExtent_t ext[1];
01936 
01937    len = strlen(fpat);
01938 
01939    /*
01940    p1=60000
01941    p2=0
01942    p3=len
01943    ## extension ##
01944    char fpat[len]
01945    */
01946 
01947    ext[0].size = len;
01948    ext[0].ptr = fpat;
01949 
01950    bytes = pigpio_command_ext(pi, PI_CMD_FL, 60000, 0, len, 1, ext, 0);
01951 
01952    if (bytes > 0)
01953    {
01954       bytes = recvMax(pi, buf, count, bytes);
01955    }
01956 
01957    _pmu(pi);
01958 
01959    return bytes;
01960 }
01961 
01962 int callback(int pi, unsigned user_gpio, unsigned edge, CBFunc_t f)
01963    {return intCallback(pi, user_gpio, edge, f, 0, 0);}
01964 
01965 int callback_ex(
01966    int pi, unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *user)
01967    {return intCallback(pi, user_gpio, edge, f, user, 1);}
01968 
01969 int callback_cancel(unsigned id)
01970 {
01971    callback_t *p;
01972    int pi;
01973 
01974    p = gCallBackFirst;
01975 
01976    while (p)
01977    {
01978       if (p->id == id)
01979       {
01980          pi = p->pi;
01981 
01982          if (p->prev) {p->prev->next = p->next;}
01983          else         {gCallBackFirst = p->next;}
01984 
01985          if (p->next) {p->next->prev = p->prev;}
01986          else         {gCallBackLast = p->prev;}
01987 
01988          free(p);
01989 
01990          findNotifyBits(pi);
01991 
01992          return 0;
01993       }
01994       p = p->next;
01995    }
01996    return pigif_callback_not_found;
01997 }
01998 
01999 int wait_for_edge(int pi, unsigned user_gpio, unsigned edge, double timeout)
02000 {
02001    int triggered = 0;
02002    int id;
02003    double due;
02004 
02005    if ((pi < 0) || (pi >= MAX_PI) || !gPiInUse[pi])
02006       return pigif_unconnected_pi;
02007 
02008    if (timeout <= 0.0) return 0;
02009 
02010    due = time_time() + timeout;
02011 
02012    id = callback_ex(pi, user_gpio, edge, _wfe, &triggered);
02013 
02014    while (!triggered && (time_time() < due)) time_sleep(0.05);
02015 
02016    callback_cancel(id);
02017 
02018    return triggered;
02019 }
02020 
02021 int bsc_xfer(int pi, bsc_xfer_t *bscxfer)
02022 {
02023    int bytes;
02024    int status;
02025    gpioExtent_t ext[1];
02026 
02027    /*
02028    p1=control
02029    p2=0
02030    p3=len
02031    ## extension ##
02032    char buf[len]
02033    */
02034 
02035    ext[0].size = bscxfer->txCnt;
02036    ext[0].ptr = bscxfer->txBuf;
02037 
02038    bytes = pigpio_command_ext
02039       (pi, PI_CMD_BSCX, bscxfer->control, 0, bscxfer->txCnt, 1, ext, 0);
02040 
02041    if (bytes > 0)
02042    {
02043       recvMax(pi, &status, 4, 4);
02044       status = ntohl(status);
02045       bytes -= 4;
02046       bytes = recvMax(pi, bscxfer->rxBuf, sizeof(bscxfer->rxBuf), bytes);
02047       bscxfer->rxCnt = bytes;
02048    }
02049    else
02050    {
02051       status = bytes;
02052    }
02053 
02054    _pmu(pi);
02055 
02056    return status;
02057 }
02058 
02059 
02060 int bsc_i2c(int pi, int i2c_addr, bsc_xfer_t *bscxfer)
02061 {
02062    int control = 0;
02063 
02064    if (i2c_addr) control = (i2c_addr<<16) | 0x305;
02065    bscxfer->control = control;
02066    return bsc_xfer(pi, bscxfer);
02067 }
02068 
02069 
02070 int event_callback(int pi, unsigned event, evtCBFunc_t f)
02071    {return intEventCallback(pi, event, f, 0, 0);}
02072 
02073 int event_callback_ex(
02074    int pi, unsigned event, evtCBFuncEx_t f, void *user)
02075    {return intEventCallback(pi, event, f, user, 1);}
02076 
02077 int event_callback_cancel(unsigned id)
02078 {
02079    evtCallback_t *ep;
02080    int pi;
02081 
02082    ep = geCallBackFirst;
02083 
02084    while (ep)
02085    {
02086       if (ep->id == id)
02087       {
02088          pi = ep->pi;
02089 
02090          if (ep->prev) {ep->prev->next = ep->next;}
02091          else          {geCallBackFirst = ep->next;}
02092 
02093          if (ep->next) {ep->next->prev = ep->prev;}
02094          else          {geCallBackLast = ep->prev;}
02095 
02096          free(ep);
02097 
02098          findEventBits(pi);
02099 
02100          return 0;
02101       }
02102       ep = ep->next;
02103    }
02104    return pigif_callback_not_found;
02105 }
02106 
02107 int wait_for_event(int pi, unsigned event, double timeout)
02108 {
02109    int triggered = 0;
02110    int id;
02111    double due;
02112 
02113    if ((pi < 0) || (pi >= MAX_PI) || !gPiInUse[pi])
02114       return pigif_unconnected_pi;
02115 
02116    if (timeout <= 0.0) return 0;
02117 
02118    due = time_time() + timeout;
02119 
02120    id = event_callback_ex(pi, event, _ewfe, &triggered);
02121 
02122    while (!triggered && (time_time() < due)) time_sleep(0.05);
02123 
02124    event_callback_cancel(id);
02125 
02126    return triggered;
02127 }
02128 
02129 int event_trigger(int pi, unsigned event)
02130    {return pigpio_command(pi, PI_CMD_EVM, event, 0, 1);}
02131 


cob_hand_bridge
Author(s): Mathias L├╝dtke
autogenerated on Thu Jun 6 2019 20:43:57