pigpio.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 /* pigpio version 67 */
00029 
00030 /* include ------------------------------------------------------- */
00031 
00032 #define _GNU_SOURCE
00033 
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <strings.h>
00037 #include <stdlib.h>
00038 #include <stdint.h>
00039 #include <stdarg.h>
00040 #include <ctype.h>
00041 #include <syslog.h>
00042 #include <poll.h>
00043 #include <unistd.h>
00044 #include <fcntl.h>
00045 #include <termios.h>
00046 #include <signal.h>
00047 #include <errno.h>
00048 #include <time.h>
00049 #include <sys/ioctl.h>
00050 #include <limits.h>
00051 #include <pthread.h>
00052 #include <sys/time.h>
00053 #include <sys/mman.h>
00054 #include <sys/types.h>
00055 #include <sys/stat.h>
00056 #include <sys/file.h>
00057 #include <sys/socket.h>
00058 #include <sys/sysmacros.h>
00059 #include <netinet/tcp.h>
00060 #include <arpa/inet.h>
00061 #include <sys/select.h>
00062 #include <fnmatch.h>
00063 #include <glob.h>
00064 
00065 #include "pigpio.h"
00066 
00067 #include "command.h"
00068 
00069 
00070 /* --------------------------------------------------------------- */
00071 
00072 /*
00073  0 GPFSEL0   GPIO Function Select 0
00074  1 GPFSEL1   GPIO Function Select 1
00075  2 GPFSEL2   GPIO Function Select 2
00076  3 GPFSEL3   GPIO Function Select 3
00077  4 GPFSEL4   GPIO Function Select 4
00078  5 GPFSEL5   GPIO Function Select 5
00079  6 -         Reserved
00080  7 GPSET0    GPIO Pin Output Set 0
00081  8 GPSET1    GPIO Pin Output Set 1
00082  9 -         Reserved
00083 10 GPCLR0    GPIO Pin Output Clear 0
00084 11 GPCLR1    GPIO Pin Output Clear 1
00085 12 -         Reserved
00086 13 GPLEV0    GPIO Pin Level 0
00087 14 GPLEV1    GPIO Pin Level 1
00088 15 -         Reserved
00089 16 GPEDS0    GPIO Pin Event Detect Status 0
00090 17 GPEDS1    GPIO Pin Event Detect Status 1
00091 18 -         Reserved
00092 19 GPREN0    GPIO Pin Rising Edge Detect Enable 0
00093 20 GPREN1    GPIO Pin Rising Edge Detect Enable 1
00094 21 -         Reserved
00095 22 GPFEN0    GPIO Pin Falling Edge Detect Enable 0
00096 23 GPFEN1    GPIO Pin Falling Edge Detect Enable 1
00097 24 -         Reserved
00098 25 GPHEN0    GPIO Pin High Detect Enable 0
00099 26 GPHEN1    GPIO Pin High Detect Enable 1
00100 27 -         Reserved
00101 28 GPLEN0    GPIO Pin Low Detect Enable 0
00102 29 GPLEN1    GPIO Pin Low Detect Enable 1
00103 30 -         Reserved
00104 31 GPAREN0   GPIO Pin Async. Rising Edge Detect 0
00105 32 GPAREN1   GPIO Pin Async. Rising Edge Detect 1
00106 33 -         Reserved
00107 34 GPAFEN0   GPIO Pin Async. Falling Edge Detect 0
00108 35 GPAFEN1   GPIO Pin Async. Falling Edge Detect 1
00109 36 -         Reserved
00110 37 GPPUD     GPIO Pin Pull-up/down Enable
00111 38 GPPUDCLK0 GPIO Pin Pull-up/down Enable Clock 0
00112 39 GPPUDCLK1 GPIO Pin Pull-up/down Enable Clock 1
00113 40 -         Reserved
00114 41 -         Test
00115 */
00116 
00117 /*
00118 0 CS           DMA Channel 0 Control and Status
00119 1 CPI_ONBLK_AD DMA Channel 0 Control Block Address
00120 2 TI           DMA Channel 0 CB Word 0 (Transfer Information)
00121 3 SOURCE_AD    DMA Channel 0 CB Word 1 (Source Address)
00122 4 DEST_AD      DMA Channel 0 CB Word 2 (Destination Address)
00123 5 TXFR_LEN     DMA Channel 0 CB Word 3 (Transfer Length)
00124 6 STRIDE       DMA Channel 0 CB Word 4 (2D Stride)
00125 7 NEXTCPI_ONBK DMA Channel 0 CB Word 5 (Next CB Address)
00126 8 DEBUG        DMA Channel 0 Debug
00127 */
00128 
00129 /*
00130 DEBUG register bits
00131 
00132 bit 2 READ_ERROR
00133 
00134    Slave Read Response Error RW 0x0
00135 
00136    Set if the read operation returned an error value on
00137    the read response bus. It can be cleared by writing
00138    a 1.
00139 
00140 bit 1 FIFO_ERROR
00141 
00142    Fifo Error RW 0x0
00143 
00144    Set if the optional read Fifo records an error
00145    condition. It can be cleared by writing a 1.
00146 
00147 bit 0 READ_LAST_NOT_SET_ERROR
00148 
00149    Read Last Not Set Error RW 0x0
00150 
00151    If the AXI read last signal was not set when
00152    expected, then this error bit will be set. It can be
00153    cleared by writing a 1.
00154 */
00155 
00156 /*
00157 0 CTL        PWM Control
00158 1 STA        PWM Status
00159 2 DMAC       PWM DMA Configuration
00160 4 RNG1       PWM Channel 1 Range
00161 5 DAT1       PWM Channel 1 Data
00162 6 FIF1       PWM FIFO Input
00163 8 RNG2       PWM Channel 2 Range
00164 9 DAT2       PWM Channel 2 Data
00165 */
00166 
00167 /*
00168 0 PCM_CS     PCM Control and Status
00169 1 PCM_FIFO   PCM FIFO Data
00170 2 PCM_MODE   PCM Mode
00171 3 PCM_RXC    PCM Receive Configuration
00172 4 PCM_TXC    PCM Transmit Configuration
00173 5 PCM_DREQ   PCM DMA Request Level
00174 6 PCM_INTEN  PCM Interrupt Enables
00175 7 PCM_INTSTC PCM Interrupt Status & Clear
00176 8 PCM_GRAY   PCM Gray Mode Control
00177 */
00178 
00179 /*
00180 0 CS  System Timer Control/Status
00181 1 CLO System Timer Counter Lower 32 bits
00182 2 CHI System Timer Counter Higher 32 bits
00183 3 C0  System Timer Compare 0
00184 4 C1  System Timer Compare 1
00185 5 C2  System Timer Compare 2
00186 6 C3  System Timer Compare 3
00187 */
00188 
00189 /* define -------------------------------------------------------- */
00190 
00191 #define THOUSAND 1000
00192 #define MILLION  1000000
00193 #define BILLION  1000000000
00194 
00195 #define BANK (gpio>>5)
00196 
00197 #define BIT  (1<<(gpio&0x1F))
00198 
00199 #ifndef EMBEDDED_IN_VM
00200 #define DBG(level, format, arg...) DO_DBG(level, format, ## arg)
00201 #else
00202 #define DBG(level, format, arg...)
00203 #endif
00204 
00205 #define DO_DBG(level, format, arg...)                              \
00206    {                                                               \
00207       if ((gpioCfg.dbgLevel >= level) &&                           \
00208          (!(gpioCfg.internals & PI_CFG_NOSIGHANDLER)))             \
00209          fprintf(stderr, "%s %s: " format "\n" ,                   \
00210             myTimeStamp(), __FUNCTION__ , ## arg);                 \
00211    }
00212 
00213 #ifndef DISABLE_SER_CHECK_INITED
00214 #define SER_CHECK_INITED CHECK_INITED
00215 #else
00216 #define SER_CHECK_INITED
00217 #endif
00218 
00219 #define CHECK_INITED                                               \
00220    do                                                              \
00221    {                                                               \
00222       if (!libInitialised)                                         \
00223       {                                                            \
00224          DBG(DBG_ALWAYS,                                           \
00225            "pigpio uninitialised, call gpioInitialise()");         \
00226          return PI_NOT_INITIALISED;                                \
00227       }                                                            \
00228    }                                                               \
00229    while (0)
00230 
00231 #define CHECK_INITED_RET_NULL_PTR                                  \
00232    do                                                              \
00233    {                                                               \
00234       if (!libInitialised)                                         \
00235       {                                                            \
00236          DBG(DBG_ALWAYS,                                           \
00237            "pigpio uninitialised, call gpioInitialise()");         \
00238          return (NULL);                                            \
00239       }                                                            \
00240    }                                                               \
00241    while (0)
00242 
00243 #define CHECK_INITED_RET_NIL                                       \
00244    do                                                              \
00245    {                                                               \
00246       if (!libInitialised)                                         \
00247       {                                                            \
00248          DBG(DBG_ALWAYS,                                           \
00249            "pigpio uninitialised, call gpioInitialise()");         \
00250       }                                                            \
00251    }                                                               \
00252    while (0)
00253 
00254 #define CHECK_NOT_INITED                                           \
00255    do                                                              \
00256    {                                                               \
00257       if (libInitialised)                                          \
00258       {                                                            \
00259          DBG(DBG_ALWAYS,                                           \
00260             "pigpio initialised, call gpioTerminate()");           \
00261          return PI_INITIALISED;                                    \
00262       }                                                            \
00263    }                                                               \
00264    while (0)
00265 
00266 #define SOFT_ERROR(x, format, arg...)                              \
00267    do                                                              \
00268    {                                                               \
00269       DBG(DBG_ALWAYS, format, ## arg);                             \
00270       return x;                                                    \
00271    }                                                               \
00272    while (0)
00273 
00274 #define TIMER_ADD(a, b, result)                                    \
00275    do                                                              \
00276    {                                                               \
00277       (result)->tv_sec =  (a)->tv_sec  + (b)->tv_sec;              \
00278       (result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec;             \
00279       if ((result)->tv_nsec >= BILLION)                            \
00280       {                                                            \
00281         ++(result)->tv_sec;                                        \
00282         (result)->tv_nsec -= BILLION;                              \
00283       }                                                            \
00284    }                                                               \
00285    while (0)
00286 
00287 #define TIMER_SUB(a, b, result)                                    \
00288    do                                                              \
00289    {                                                               \
00290       (result)->tv_sec =  (a)->tv_sec  - (b)->tv_sec;              \
00291       (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec;             \
00292       if ((result)->tv_nsec < 0)                                   \
00293       {                                                            \
00294          --(result)->tv_sec;                                       \
00295          (result)->tv_nsec += BILLION;                             \
00296       }                                                            \
00297    }                                                               \
00298    while (0)
00299 
00300 #define PI_PERI_BUS 0x7E000000
00301 
00302 #define AUX_BASE   (pi_peri_phys + 0x00215000)
00303 #define BSCS_BASE  (pi_peri_phys + 0x00214000)
00304 #define CLK_BASE   (pi_peri_phys + 0x00101000)
00305 #define DMA_BASE   (pi_peri_phys + 0x00007000)
00306 #define DMA15_BASE (pi_peri_phys + 0x00E05000)
00307 #define GPIO_BASE  (pi_peri_phys + 0x00200000)
00308 #define PADS_BASE  (pi_peri_phys + 0x00100000)
00309 #define PCM_BASE   (pi_peri_phys + 0x00203000)
00310 #define PWM_BASE   (pi_peri_phys + 0x0020C000)
00311 #define SPI_BASE   (pi_peri_phys + 0x00204000)
00312 #define SYST_BASE  (pi_peri_phys + 0x00003000)
00313 
00314 #define AUX_LEN   0xD8
00315 #define BSCS_LEN  0x40
00316 #define CLK_LEN   0xA8
00317 #define DMA_LEN   0x1000 /* allow access to all channels */
00318 #define GPIO_LEN  0xB4
00319 #define PADS_LEN  0x38
00320 #define PCM_LEN   0x24
00321 #define PWM_LEN   0x28
00322 #define SPI_LEN   0x18
00323 #define SYST_LEN  0x1C
00324 
00325 #define DMA_ENABLE (0xFF0/4)
00326 
00327 #define GPFSEL0    0
00328 
00329 #define GPSET0     7
00330 #define GPSET1     8
00331 
00332 #define GPCLR0    10
00333 #define GPCLR1    11
00334 
00335 #define GPLEV0    13
00336 #define GPLEV1    14
00337 
00338 #define GPEDS0    16
00339 #define GPEDS1    17
00340 
00341 #define GPREN0    19
00342 #define GPREN1    20
00343 #define GPFEN0    22
00344 #define GPFEN1    23
00345 #define GPHEN0    25
00346 #define GPHEN1    26
00347 #define GPLEN0    28
00348 #define GPLEN1    29
00349 #define GPAREN0   31
00350 #define GPAREN1   32
00351 #define GPAFEN0   34
00352 #define GPAFEN1   35
00353 
00354 #define GPPUD     37
00355 #define GPPUDCLK0 38
00356 #define GPPUDCLK1 39
00357 
00358 #define DMA_CS        0
00359 #define DMA_CONBLK_AD 1
00360 #define DMA_DEBUG     8
00361 
00362 /* DMA CS Control and Status bits */
00363 #define DMA_CHANNEL_RESET       (1<<31)
00364 #define DMA_WAIT_ON_WRITES      (1<<28)
00365 #define DMA_PANIC_PRIORITY(x) ((x)<<20)
00366 #define DMA_PRIORITY(x)       ((x)<<16)
00367 #define DMA_INTERRUPT_STATUS    (1<< 2)
00368 #define DMA_END_FLAG            (1<< 1)
00369 #define DMA_ACTIVATE            (1<< 0)
00370 
00371 /* DMA control block "info" field bits */
00372 #define DMA_NO_WIDE_BURSTS          (1<<26)
00373 #define DMA_PERIPHERAL_MAPPING(x) ((x)<<16)
00374 #define DMA_BURST_LENGTH(x)       ((x)<<12)
00375 #define DMA_SRC_IGNORE              (1<<11)
00376 #define DMA_SRC_DREQ                (1<<10)
00377 #define DMA_SRC_WIDTH               (1<< 9)
00378 #define DMA_SRC_INC                 (1<< 8)
00379 #define DMA_DEST_IGNORE             (1<< 7)
00380 #define DMA_DEST_DREQ               (1<< 6)
00381 #define DMA_DEST_WIDTH              (1<< 5)
00382 #define DMA_DEST_INC                (1<< 4)
00383 #define DMA_WAIT_RESP               (1<< 3)
00384 
00385 #define DMA_DEBUG_READ_ERR           (1<<2)
00386 #define DMA_DEBUG_FIFO_ERR           (1<<1)
00387 #define DMA_DEBUG_RD_LST_NOT_SET_ERR (1<<0)
00388 
00389 #define DMA_LITE_FIRST 7
00390 #define DMA_LITE_MAX 0xfffc
00391 
00392 #define PWM_CTL      0
00393 #define PWM_STA      1
00394 #define PWM_DMAC     2
00395 #define PWM_RNG1     4
00396 #define PWM_DAT1     5
00397 #define PWM_FIFO     6
00398 #define PWM_RNG2     8
00399 #define PWM_DAT2     9
00400 
00401 #define PWM_CTL_MSEN2 (1<<15)
00402 #define PWM_CTL_PWEN2 (1<<8)
00403 #define PWM_CTL_MSEN1 (1<<7)
00404 #define PWM_CTL_CLRF1 (1<<6)
00405 #define PWM_CTL_USEF1 (1<<5)
00406 #define PWM_CTL_MODE1 (1<<1)
00407 #define PWM_CTL_PWEN1 (1<<0)
00408 
00409 #define PWM_DMAC_ENAB      (1 <<31)
00410 #define PWM_DMAC_PANIC(x) ((x)<< 8)
00411 #define PWM_DMAC_DREQ(x)   (x)
00412 
00413 #define PCM_CS     0
00414 #define PCM_FIFO   1
00415 #define PCM_MODE   2
00416 #define PCM_RXC    3
00417 #define PCM_TXC    4
00418 #define PCM_DREQ   5
00419 #define PCM_INTEN  6
00420 #define PCM_INTSTC 7
00421 #define PCM_GRAY   8
00422 
00423 #define PCM_CS_STBY     (1 <<25)
00424 #define PCM_CS_SYNC     (1 <<24)
00425 #define PCM_CS_RXSEX    (1 <<23)
00426 #define PCM_CS_RXERR    (1 <<16)
00427 #define PCM_CS_TXERR    (1 <<15)
00428 #define PCM_CS_DMAEN    (1  <<9)
00429 #define PCM_CS_RXTHR(x) ((x)<<7)
00430 #define PCM_CS_TXTHR(x) ((x)<<5)
00431 #define PCM_CS_RXCLR    (1  <<4)
00432 #define PCM_CS_TXCLR    (1  <<3)
00433 #define PCM_CS_TXON     (1  <<2)
00434 #define PCM_CS_RXON     (1  <<1)
00435 #define PCM_CS_EN       (1  <<0)
00436 
00437 #define PCM_MODE_CLK_DIS  (1  <<28)
00438 #define PCM_MODE_PDMN     (1  <<27)
00439 #define PCM_MODE_PDME     (1  <<26)
00440 #define PCM_MODE_FRXP     (1  <<25)
00441 #define PCM_MODE_FTXP     (1  <<24)
00442 #define PCM_MODE_CLKM     (1  <<23)
00443 #define PCM_MODE_CLKI     (1  <<22)
00444 #define PCM_MODE_FSM      (1  <<21)
00445 #define PCM_MODE_FSI      (1  <<20)
00446 #define PCM_MODE_FLEN(x)  ((x)<<10)
00447 #define PCM_MODE_FSLEN(x) ((x)<< 0)
00448 
00449 #define PCM_RXC_CH1WEX    (1  <<31)
00450 #define PCM_RXC_CH1EN     (1  <<30)
00451 #define PCM_RXC_CH1POS(x) ((x)<<20)
00452 #define PCM_RXC_CH1WID(x) ((x)<<16)
00453 #define PCM_RXC_CH2WEX    (1  <<15)
00454 #define PCM_RXC_CH2EN     (1  <<14)
00455 #define PCM_RXC_CH2POS(x) ((x)<< 4)
00456 #define PCM_RXC_CH2WID(x) ((x)<< 0)
00457 
00458 #define PCM_TXC_CH1WEX    (1  <<31)
00459 #define PCM_TXC_CH1EN     (1  <<30)
00460 #define PCM_TXC_CH1POS(x) ((x)<<20)
00461 #define PCM_TXC_CH1WID(x) ((x)<<16)
00462 #define PCM_TXC_CH2WEX    (1  <<15)
00463 #define PCM_TXC_CH2EN     (1  <<14)
00464 #define PCM_TXC_CH2POS(x) ((x)<< 4)
00465 #define PCM_TXC_CH2WID(x) ((x)<< 0)
00466 
00467 #define PCM_DREQ_TX_PANIC(x) ((x)<<24)
00468 #define PCM_DREQ_RX_PANIC(x) ((x)<<16)
00469 #define PCM_DREQ_TX_REQ_L(x) ((x)<< 8)
00470 #define PCM_DREQ_RX_REQ_L(x) ((x)<< 0)
00471 
00472 #define PCM_INTEN_RXERR (1<<3)
00473 #define PCM_INTEN_TXERR (1<<2)
00474 #define PCM_INTEN_RXR   (1<<1)
00475 #define PCM_INTEN_TXW   (1<<0)
00476 
00477 #define PCM_INTSTC_RXERR (1<<3)
00478 #define PCM_INTSTC_TXERR (1<<2)
00479 #define PCM_INTSTC_RXR   (1<<1)
00480 #define PCM_INTSTC_TXW   (1<<0)
00481 
00482 #define PCM_GRAY_FLUSH (1<<2)
00483 #define PCM_GRAY_CLR   (1<<1)
00484 #define PCM_GRAY_EN    (1<<0)
00485 
00486 #define BCM_PASSWD  (0x5A<<24)
00487 
00488 #define CLK_CTL_MASH(x)((x)<<9)
00489 #define CLK_CTL_BUSY    (1 <<7)
00490 #define CLK_CTL_KILL    (1 <<5)
00491 #define CLK_CTL_ENAB    (1 <<4)
00492 #define CLK_CTL_SRC(x) ((x)<<0)
00493 
00494 #define CLK_SRCS 2
00495 
00496 #define CLK_CTL_SRC_OSC  1
00497 #define CLK_CTL_SRC_PLLD 6
00498 
00499 #define CLK_OSC_FREQ   19200000
00500 #define CLK_PLLD_FREQ 500000000
00501 
00502 #define CLK_DIV_DIVI(x) ((x)<<12)
00503 #define CLK_DIV_DIVF(x) ((x)<< 0)
00504 
00505 #define CLK_GP0_CTL 28
00506 #define CLK_GP0_DIV 29
00507 #define CLK_GP1_CTL 30
00508 #define CLK_GP1_DIV 31
00509 #define CLK_GP2_CTL 32
00510 #define CLK_GP2_DIV 33
00511 
00512 #define CLK_PCMCTL 38
00513 #define CLK_PCMDIV 39
00514 
00515 #define CLK_PWMCTL 40
00516 #define CLK_PWMDIV 41
00517 
00518 #define SYST_CS      0
00519 #define SYST_CLO     1
00520 #define SYST_CHI     2
00521 
00522 /* SPI */
00523 
00524 #define SPI_CS   0
00525 #define SPI_FIFO 1
00526 #define SPI_CLK  2
00527 #define SPI_DLEN 3
00528 #define SPI_LTOH 4
00529 #define SPI_DC   5
00530 
00531 #define SPI_CS_LEN_LONG    (1<<25)
00532 #define SPI_CS_DMA_LEN     (1<<24)
00533 #define SPI_CS_CSPOLS(x) ((x)<<21)
00534 #define SPI_CS_RXF         (1<<20)
00535 #define SPI_CS_RXR         (1<<19)
00536 #define SPI_CS_TXD         (1<<18)
00537 #define SPI_CS_RXD         (1<<17)
00538 #define SPI_CS_DONE        (1<<16)
00539 #define SPI_CS_LEN         (1<<13)
00540 #define SPI_CS_REN         (1<<12)
00541 #define SPI_CS_ADCS        (1<<11)
00542 #define SPI_CS_INTR        (1<<10)
00543 #define SPI_CS_INTD        (1<<9)
00544 #define SPI_CS_DMAEN       (1<<8)
00545 #define SPI_CS_TA          (1<<7)
00546 #define SPI_CS_CSPOL(x)  ((x)<<6)
00547 #define SPI_CS_CLEAR(x)  ((x)<<4)
00548 #define SPI_CS_MODE(x)   ((x)<<2)
00549 #define SPI_CS_CS(x)     ((x)<<0)
00550 
00551 #define SPI_DC_RPANIC(x) ((x)<<24)
00552 #define SPI_DC_RDREQ(x)  ((x)<<16)
00553 #define SPI_DC_TPANIC(x) ((x)<<8)
00554 #define SPI_DC_TDREQ(x)  ((x)<<0)
00555 
00556 #define SPI_MODE0 0
00557 #define SPI_MODE1 1
00558 #define SPI_MODE2 2
00559 #define SPI_MODE3 3
00560 
00561 #define SPI_CS0     0
00562 #define SPI_CS1     1
00563 #define SPI_CS2     2
00564 
00565 /* standard SPI gpios (ALT0) */
00566 
00567 #define PI_SPI_CE0   8
00568 #define PI_SPI_CE1   7
00569 #define PI_SPI_SCLK 11
00570 #define PI_SPI_MISO  9
00571 #define PI_SPI_MOSI 10
00572 
00573 /* auxiliary SPI gpios (ALT4) */
00574 
00575 #define PI_ASPI_CE0  18
00576 #define PI_ASPI_CE1  17
00577 #define PI_ASPI_CE2  16
00578 #define PI_ASPI_MISO 19
00579 #define PI_ASPI_MOSI 20
00580 #define PI_ASPI_SCLK 21
00581 
00582 /* AUX */
00583 
00584 #define AUX_IRQ     0
00585 #define AUX_ENABLES 1
00586 
00587 #define AUX_MU_IO_REG   16
00588 #define AUX_MU_IER_REG  17
00589 #define AUX_MU_IIR_REG  18
00590 #define AUX_MU_LCR_REG  19
00591 #define AUX_MU_MCR_REG  20
00592 #define AUX_MU_LSR_REG  21
00593 #define AUX_MU_MSR_REG  22
00594 #define AUX_MU_SCRATCH  23
00595 #define AUX_MU_CNTL_REG 24
00596 #define AUX_MU_STAT_REG 25
00597 #define AUX_MU_BAUD_REG 26
00598 
00599 #define AUX_SPI0_CNTL0_REG 32
00600 #define AUX_SPI0_CNTL1_REG 33
00601 #define AUX_SPI0_STAT_REG  34
00602 #define AUX_SPI0_PEEK_REG  35
00603 
00604 #define AUX_SPI0_IO_REG    40
00605 #define AUX_SPI0_TX_HOLD   44
00606 
00607 #define AUX_SPI1_CNTL0_REG 48
00608 #define AUX_SPI1_CNTL1_REG 49
00609 #define AUX_SPI1_STAT_REG  50
00610 #define AUX_SPI1_PEEK_REG  51
00611 
00612 #define AUX_SPI1_IO_REG    56
00613 #define AUX_SPI1_TX_HOLD   60
00614 
00615 #define AUXENB_SPI2 (1<<2)
00616 #define AUXENB_SPI1 (1<<1)
00617 #define AUXENB_UART (1<<0)
00618 
00619 #define AUXSPI_CNTL0_SPEED(x)      ((x)<<20)
00620 #define AUXSPI_CNTL0_CS(x)         ((x)<<17)
00621 #define AUXSPI_CNTL0_POSTINP         (1<<16)
00622 #define AUXSPI_CNTL0_VAR_CS          (1<<15)
00623 #define AUXSPI_CNTL0_VAR_WIDTH       (1<<14)
00624 #define AUXSPI_CNTL0_DOUT_HOLD(x)  ((x)<<12)
00625 #define AUXSPI_CNTL0_ENABLE          (1<<11)
00626 #define AUXSPI_CNTL0_IN_RISING(x)  ((x)<<10)
00627 #define AUXSPI_CNTL0_CLR_FIFOS       (1<<9)
00628 #define AUXSPI_CNTL0_OUT_RISING(x) ((x)<<8)
00629 #define AUXSPI_CNTL0_INVERT_CLK(x) ((x)<<7)
00630 #define AUXSPI_CNTL0_MSB_FIRST(x)  ((x)<<6)
00631 #define AUXSPI_CNTL0_SHIFT_LEN(x)  ((x)<<0)
00632 
00633 #define AUXSPI_CNTL1_CS_HIGH(x)  ((x)<<8)
00634 #define AUXSPI_CNTL1_TX_IRQ        (1<<7)
00635 #define AUXSPI_CNTL1_DONE_IRQ      (1<<6)
00636 #define AUXSPI_CNTL1_MSB_FIRST(x)((x)<<1)
00637 #define AUXSPI_CNTL1_KEEP_INPUT    (1<<0)
00638 
00639 #define AUXSPI_STAT_TX_FIFO(x) ((x)<<28)
00640 #define AUXSPI_STAT_RX_FIFO(x) ((x)<<20)
00641 #define AUXSPI_STAT_TX_FULL      (1<<10)
00642 #define AUXSPI_STAT_TX_EMPTY     (1<<9)
00643 #define AUXSPI_STAT_RX_EMPTY     (1<<7)
00644 #define AUXSPI_STAT_BUSY         (1<<6)
00645 #define AUXSPI_STAT_BITS(x)    ((x)<<0)
00646 
00647 /* --------------------------------------------------------------- */
00648 
00649 #define NORMAL_DMA (DMA_NO_WIDE_BURSTS | DMA_WAIT_RESP)
00650 
00651 #define TIMED_DMA(x) (DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(x))
00652 
00653 #define PCM_TIMER (((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS)
00654 #define PWM_TIMER (((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS)
00655 
00656 #define DBG_MIN_LEVEL 0
00657 #define DBG_ALWAYS    0
00658 #define DBG_STARTUP   1
00659 #define DBG_DMACBS    2
00660 #define DBG_SCRIPT    3
00661 #define DBG_USER      4
00662 #define DBG_INTERNAL  5
00663 #define DBG_SLOW_TICK 6
00664 #define DBG_FAST_TICK 7
00665 #define DBG_MAX_LEVEL 8
00666 
00667 #define GPIO_UNDEFINED 0
00668 #define GPIO_WRITE     1
00669 #define GPIO_PWM       2
00670 #define GPIO_SERVO     3
00671 #define GPIO_HW_CLK    4
00672 #define GPIO_HW_PWM    5
00673 #define GPIO_SPI       6
00674 #define GPIO_I2C       7
00675 
00676 #define STACK_SIZE (256*1024)
00677 
00678 #define PAGE_SIZE 4096
00679 
00680 #define PWM_FREQS 18
00681 
00682 #define CYCLES_PER_BLOCK 80
00683 #define PULSE_PER_CYCLE  25
00684 
00685 #define PAGES_PER_BLOCK 53
00686 
00687 #define CBS_PER_IPAGE 117
00688 #define LVS_PER_IPAGE  38
00689 #define OFF_PER_IPAGE  38
00690 #define TCK_PER_IPAGE   2
00691 #define ON_PER_IPAGE    2
00692 #define PAD_PER_IPAGE   7
00693 
00694 #define CBS_PER_OPAGE 118
00695 #define OOL_PER_OPAGE  79
00696 
00697 /*
00698 Wave Count Block
00699 
00700 Assumes two counters per block.  Each counter 4 * 16 (16^4=65536)
00701    0  CB [13]  13*8  104 CBs for counter 0
00702  104  CB [13]  13*8  104 CBs for counter 1
00703  208  CB [60]  60*8  480 CBs reserved to construct wave
00704  688 OOL [60]  60*1   60 OOL reserved to construct wave
00705  748 OOL[136] 136*1  136 OOL for counter 0
00706  884 OOL[136] 136*1  136 OOL for counter 1
00707 1020 pad  [4]   4*1    4 spare
00708 */
00709 
00710 #define WCB_CNT_PER_PAGE 2
00711 #define WCB_COUNTERS (WCB_CNT_PER_PAGE * PI_WAVE_COUNT_PAGES)
00712 #define WCB_CNT_CBS 13
00713 #define WCB_CNT_OOL 68
00714 #define WCB_COUNTER_OOL (WCB_CNT_PER_PAGE * WCB_CNT_OOL)
00715 #define WCB_COUNTER_CBS (WCB_CNT_PER_PAGE * WCB_CNT_CBS)
00716 #define WCB_CHAIN_CBS   60
00717 #define WCB_CHAIN_OOL   60
00718 
00719 #define CBS_PER_CYCLE ((PULSE_PER_CYCLE*3)+2)
00720 
00721 #define NUM_CBS (CBS_PER_CYCLE * bufferCycles)
00722 
00723 #define SUPERCYCLE 800
00724 #define SUPERLEVEL 20000
00725 
00726 #define BLOCK_SIZE (PAGES_PER_BLOCK*PAGE_SIZE)
00727 
00728 #define DMAI_PAGES (PAGES_PER_BLOCK * bufferBlocks)
00729 
00730 #define DMAO_PAGES (PAGES_PER_BLOCK * PI_WAVE_BLOCKS)
00731 
00732 #define NUM_WAVE_OOL (DMAO_PAGES * OOL_PER_OPAGE)
00733 #define NUM_WAVE_CBS (DMAO_PAGES * CBS_PER_OPAGE)
00734 
00735 #define TICKSLOTS 50
00736 
00737 #define PI_I2C_CLOSED   0
00738 #define PI_I2C_RESERVED 1
00739 #define PI_I2C_OPENED   2
00740 
00741 #define PI_SPI_CLOSED   0
00742 #define PI_SPI_RESERVED 1
00743 #define PI_SPI_OPENED   2
00744 
00745 #define PI_SER_CLOSED   0
00746 #define PI_SER_RESERVED 1
00747 #define PI_SER_OPENED   2
00748 
00749 #define PI_FILE_CLOSED   0
00750 #define PI_FILE_RESERVED 1
00751 #define PI_FILE_OPENED   2
00752 
00753 #define PI_NOTIFY_CLOSED   0
00754 #define PI_NOTIFY_RESERVED 1
00755 #define PI_NOTIFY_CLOSING  2
00756 #define PI_NOTIFY_OPENED   3
00757 #define PI_NOTIFY_RUNNING  4
00758 #define PI_NOTIFY_PAUSED   5
00759 
00760 #define PI_WFRX_NONE     0
00761 #define PI_WFRX_SERIAL   1
00762 #define PI_WFRX_I2C_SDA  2
00763 #define PI_WFRX_I2C_SCL  3
00764 #define PI_WFRX_SPI_SCLK 4
00765 #define PI_WFRX_SPI_MISO 5
00766 #define PI_WFRX_SPI_MOSI 6
00767 #define PI_WFRX_SPI_CS   7
00768 
00769 #define PI_WF_MICROS   1
00770 
00771 #define BPD 4
00772 
00773 #define MAX_REPORT 250
00774 #define MAX_SAMPLE 4000
00775 
00776 #define DEFAULT_PWM_IDX 5
00777 
00778 #define MAX_EMITS (PIPE_BUF / sizeof(gpioReport_t))
00779 
00780 #define SRX_BUF_SIZE 8192
00781 
00782 #define PI_I2C_RETRIES 0x0701
00783 #define PI_I2C_TIMEOUT 0x0702
00784 #define PI_I2C_SLAVE   0x0703
00785 #define PI_I2C_FUNCS   0x0705
00786 #define PI_I2C_RDWR    0x0707
00787 #define PI_I2C_SMBUS   0x0720
00788 
00789 #define PI_I2C_SMBUS_READ  1
00790 #define PI_I2C_SMBUS_WRITE 0
00791 
00792 #define PI_I2C_SMBUS_QUICK            0
00793 #define PI_I2C_SMBUS_BYTE             1
00794 #define PI_I2C_SMBUS_BYTE_DATA        2
00795 #define PI_I2C_SMBUS_WORD_DATA        3
00796 #define PI_I2C_SMBUS_PROC_CALL        4
00797 #define PI_I2C_SMBUS_BLOCK_DATA       5
00798 #define PI_I2C_SMBUS_I2C_BLOCK_BROKEN 6
00799 #define PI_I2C_SMBUS_BLOCK_PROC_CALL  7
00800 #define PI_I2C_SMBUS_I2C_BLOCK_DATA   8
00801 
00802 #define PI_I2C_SMBUS_BLOCK_MAX     32
00803 #define PI_I2C_SMBUS_I2C_BLOCK_MAX 32
00804 
00805 #define PI_I2C_FUNC_SMBUS_QUICK            0x00010000
00806 #define PI_I2C_FUNC_SMBUS_READ_BYTE        0x00020000
00807 #define PI_I2C_FUNC_SMBUS_WRITE_BYTE       0x00040000
00808 #define PI_I2C_FUNC_SMBUS_READ_BYTE_DATA   0x00080000
00809 #define PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA  0x00100000
00810 #define PI_I2C_FUNC_SMBUS_READ_WORD_DATA   0x00200000
00811 #define PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA  0x00400000
00812 #define PI_I2C_FUNC_SMBUS_PROC_CALL        0x00800000
00813 #define PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA  0x01000000
00814 #define PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
00815 #define PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK   0x04000000
00816 #define PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK  0x08000000
00817 
00818 #define PI_MASH_MAX_FREQ 23800000
00819 
00820 #define FLUSH_PAGES 1024
00821 
00822 #define MB_DEV_MAJOR 100
00823 
00824 #define MB_IOCTL _IOWR(MB_DEV_MAJOR, 0, char *)
00825 
00826 #define MB_DEV1 "/dev/vcio"
00827 #define MB_DEV2 "/dev/pigpio-mb"
00828 
00829 #define BUS_TO_PHYS(x) ((x)&~0xC0000000)
00830 
00831 #define MB_END_TAG 0
00832 #define MB_PROCESS_REQUEST 0
00833 
00834 #define MB_ALLOCATE_MEMORY_TAG 0x3000C
00835 #define MB_LOCK_MEMORY_TAG     0x3000D
00836 #define MB_UNLOCK_MEMORY_TAG   0x3000E
00837 #define MB_RELEASE_MEMORY_TAG  0x3000F
00838 
00839 #define PI_SCRIPT_FREE     0
00840 #define PI_SCRIPT_RESERVED 1
00841 #define PI_SCRIPT_IN_USE   2
00842 #define PI_SCRIPT_DYING    3
00843 
00844 #define PI_SCRIPT_HALT   0
00845 #define PI_SCRIPT_RUN    1
00846 #define PI_SCRIPT_DELETE 2
00847 
00848 #define PI_SCRIPT_STACK_SIZE 256
00849 
00850 #define PI_SPI_FLAGS_CHANNEL(x)    ((x&7)<<29)
00851 
00852 #define PI_SPI_FLAGS_GET_CHANNEL(x) (((x)>>29)&7)
00853 #define PI_SPI_FLAGS_GET_BITLEN(x)  (((x)>>16)&63)
00854 #define PI_SPI_FLAGS_GET_RX_LSB(x)  (((x)>>15)&1)
00855 #define PI_SPI_FLAGS_GET_TX_LSB(x)  (((x)>>14)&1)
00856 #define PI_SPI_FLAGS_GET_3WREN(x)   (((x)>>10)&15)
00857 #define PI_SPI_FLAGS_GET_3WIRE(x)   (((x)>>9)&1)
00858 #define PI_SPI_FLAGS_GET_AUX_SPI(x) (((x)>>8)&1)
00859 #define PI_SPI_FLAGS_GET_RESVD(x)   (((x)>>5)&7)
00860 #define PI_SPI_FLAGS_GET_CSPOLS(x)  (((x)>>2)&7)
00861 #define PI_SPI_FLAGS_GET_MODE(x)     ((x)&3)
00862 
00863 #define PI_SPI_FLAGS_GET_CPHA(x)  ((x)&1)
00864 #define PI_SPI_FLAGS_GET_CPOL(x)  ((x)&2)
00865 #define PI_SPI_FLAGS_GET_CSPOL(x) ((x)&4)
00866 
00867 #define PI_STARTING 0
00868 #define PI_RUNNING  1
00869 #define PI_ENDING   2
00870 
00871 #define PI_THREAD_NONE    0
00872 #define PI_THREAD_STARTED 1
00873 #define PI_THREAD_RUNNING 2
00874 
00875 #define PI_MAX_PATH 512
00876 
00877 /* typedef ------------------------------------------------------- */
00878 
00879 typedef void (*callbk_t) ();
00880 
00881 typedef struct
00882 {
00883    rawCbs_t cb           [128];
00884 } dmaPage_t;
00885 
00886 typedef struct
00887 {
00888    rawCbs_t cb           [CBS_PER_IPAGE];
00889    uint32_t level        [LVS_PER_IPAGE];
00890    uint32_t gpioOff      [OFF_PER_IPAGE];
00891    uint32_t tick         [TCK_PER_IPAGE];
00892    uint32_t gpioOn       [ON_PER_IPAGE];
00893    uint32_t periphData;
00894    uint32_t pad          [PAD_PER_IPAGE];
00895 } dmaIPage_t;
00896 
00897 typedef struct
00898 {
00899    rawCbs_t cb     [CBS_PER_OPAGE];
00900    uint32_t OOL    [OOL_PER_OPAGE];
00901    uint32_t periphData;
00902 } dmaOPage_t;
00903 
00904 typedef struct
00905 {
00906    uint8_t  is;
00907    uint8_t  pad;
00908    uint16_t width;
00909    uint16_t range; /* dutycycles specified by 0 .. range */
00910    uint16_t freqIdx;
00911    uint16_t deferOff;
00912    uint16_t deferRng;
00913 } gpioInfo_t;
00914 
00915 typedef struct
00916 {
00917    callbk_t func;
00918    unsigned ex;
00919    void *userdata;
00920 
00921    int      wdSteadyUs;
00922    uint32_t wdTick;
00923    uint32_t wdLBitV;
00924 
00925    int      nfSteadyUs;
00926    int      nfActiveUs;
00927    int      nfActive;
00928    uint32_t nfTick1;
00929    uint32_t nfTick2;
00930    uint32_t nfLBitV;
00931    uint32_t nfRBitV;
00932 
00933    uint32_t gfSteadyUs;
00934    uint32_t gfTick;
00935    uint32_t gfLBitV;
00936    uint32_t gfRBitV;
00937 
00938 } gpioAlert_t;
00939 
00940 typedef struct
00941 {
00942    callbk_t func;
00943    unsigned ex;
00944    void *userdata;
00945    int ignore;
00946    int fired;
00947 } eventAlert_t;
00948 
00949 typedef struct
00950 {
00951    unsigned gpio;
00952    pthread_t *pth;
00953    callbk_t func;
00954    unsigned edge;
00955    int timeout;
00956    unsigned ex;
00957    void *userdata;
00958    int inited;
00959 } gpioISR_t;
00960 
00961 typedef struct
00962 {
00963    callbk_t func;
00964    unsigned ex;
00965    void *userdata;
00966 } gpioSignal_t;
00967 
00968 typedef struct
00969 {
00970    callbk_t func;
00971    unsigned ex;
00972    void *userdata;
00973    uint32_t bits;
00974 } gpioGetSamples_t;
00975 
00976 typedef struct
00977 {
00978    callbk_t func;
00979    unsigned ex;
00980    void *userdata;
00981    unsigned id;
00982    unsigned running;
00983    unsigned millis;
00984    pthread_t pthId;
00985 } gpioTimer_t;
00986 
00987 typedef struct
00988 {
00989    unsigned id;
00990    unsigned state;
00991    unsigned request;
00992    unsigned run_state;
00993    uint32_t waitBits;
00994    uint32_t eventBits;
00995    uint32_t changedBits;
00996    pthread_t *pthIdp;
00997    pthread_mutex_t pthMutex;
00998    pthread_cond_t pthCond;
00999    cmdScript_t script;
01000 } gpioScript_t;
01001 
01002 
01003 typedef struct
01004 {
01005    uint16_t valid;
01006    uint16_t servoIdx;
01007 } clkCfg_t;
01008 
01009 typedef struct
01010 {
01011    uint16_t seqno;
01012    uint16_t state;
01013    uint32_t bits;
01014    uint32_t eventBits;
01015    uint32_t lastReportTick;
01016    int      fd;
01017    int      pipe;
01018    int      max_emits;
01019 } gpioNotify_t;
01020 
01021 typedef struct
01022 {
01023    uint16_t state;
01024    int16_t  fd;
01025    uint32_t mode;
01026 } fileInfo_t;
01027 
01028 typedef struct
01029 {
01030    uint16_t state;
01031    int16_t  fd;
01032    uint32_t addr;
01033    uint32_t flags;
01034    uint32_t funcs;
01035 } i2cInfo_t;
01036 
01037 typedef struct
01038 {
01039    uint16_t state;
01040    int16_t  fd;
01041    uint32_t flags;
01042 } serInfo_t;
01043 
01044 typedef struct
01045 {
01046    uint16_t state;
01047    unsigned speed;
01048    uint32_t flags;
01049 } spiInfo_t;
01050 
01051 typedef struct
01052 {
01053    uint32_t alertTicks;
01054    uint32_t lateTicks;
01055    uint32_t moreToDo;
01056    uint32_t diffTick[TICKSLOTS];
01057    uint32_t cbTicks;
01058    uint32_t cbCalls;
01059    uint32_t maxEmit;
01060    uint32_t emitFrags;
01061    uint32_t maxSamples;
01062    uint32_t numSamples;
01063    uint32_t DMARestarts;
01064    uint32_t dmaInitCbsCount;
01065    uint32_t goodPipeWrite;
01066    uint32_t shortPipeWrite;
01067    uint32_t wouldBlockPipeWrite;
01068 } gpioStats_t;
01069 
01070 typedef struct
01071 {
01072    unsigned bufferMilliseconds;
01073    unsigned clockMicros;
01074    unsigned clockPeriph;
01075    unsigned DMAprimaryChannel;
01076    unsigned DMAsecondaryChannel;
01077    unsigned socketPort;
01078    unsigned ifFlags;
01079    unsigned memAllocMode;
01080    unsigned dbgLevel;
01081    unsigned alertFreq;
01082    uint32_t internals;
01083       /*
01084       0-3: dbgLevel
01085       4-7: alertFreq
01086       */
01087 } gpioCfg_t;
01088 
01089 typedef struct
01090 {
01091    uint32_t micros;
01092    uint32_t highMicros;
01093    uint32_t maxMicros;
01094    uint32_t pulses;
01095    uint32_t highPulses;
01096    uint32_t maxPulses;
01097    uint32_t cbs;
01098    uint32_t highCbs;
01099    uint32_t maxCbs;
01100 } wfStats_t;
01101 
01102 typedef struct
01103 {
01104    char    *buf;
01105    uint32_t bufSize;
01106    int      readPos;
01107    int      writePos;
01108    uint32_t fullBit; /* nanoseconds */
01109    uint32_t halfBit; /* nanoseconds */
01110    int      timeout; /* millisconds */
01111    uint32_t startBitTick; /* microseconds */
01112    uint32_t nextBitDiff; /* nanoseconds */
01113    int      bit;
01114    uint32_t data;
01115    int      bytes; /* 1, 2, 4 */
01116    int      level;
01117    int      dataBits; /* 1-32 */
01118    int      invert; /* 0, 1 */
01119 } wfRxSerial_t;
01120 
01121 typedef struct
01122 {
01123    int SDA;
01124    int SCL;
01125    int delay;
01126    int SDAMode;
01127    int SCLMode;
01128    int started;
01129 } wfRxI2C_t;
01130 
01131 typedef struct
01132 {
01133    int CS;
01134    int MISO;
01135    int MOSI;
01136    int SCLK;
01137    int usage;
01138    int delay;
01139    int spiFlags;
01140    int MISOMode;
01141    int MOSIMode;
01142    int CSMode;
01143    int SCLKMode;
01144 } wfRxSPI_t;
01145 
01146 typedef struct
01147 {
01148    int      mode;
01149    int      gpio;
01150    uint32_t baud;
01151    pthread_mutex_t mutex;
01152    union
01153    {
01154       wfRxSerial_t s;
01155       wfRxI2C_t    I;
01156       wfRxSPI_t    S;
01157    };
01158 } wfRx_t;
01159 
01160 union my_smbus_data
01161 {
01162    uint8_t  byte;
01163    uint16_t word;
01164    uint8_t  block[PI_I2C_SMBUS_BLOCK_MAX + 2];
01165 };
01166 
01167 struct my_smbus_ioctl_data
01168 {
01169    uint8_t read_write;
01170    uint8_t command;
01171    uint32_t size;
01172    union my_smbus_data *data;
01173 };
01174 
01175 typedef struct
01176 {
01177    pi_i2c_msg_t *msgs; /* pointers to pi_i2c_msgs */
01178    uint32_t     nmsgs; /* number of pi_i2c_msgs */
01179 } my_i2c_rdwr_ioctl_data_t;
01180 
01181 typedef struct
01182 {
01183    unsigned div;
01184    unsigned frac;
01185    unsigned clock;
01186 } clkInf_t;
01187 
01188 typedef struct
01189 {
01190    unsigned  handle;        /* mbAllocateMemory() */
01191    uintptr_t bus_addr;      /* mbLockMemory() */
01192    uintptr_t *virtual_addr; /* mbMapMem() */
01193    unsigned  size;          /* in bytes */
01194 } DMAMem_t;
01195 
01196 /* global -------------------------------------------------------- */
01197 
01198 /* initialise once then preserve */
01199 
01200 static volatile uint32_t piCores      = 0;
01201 static volatile uint32_t pi_peri_phys = 0x20000000;
01202 static volatile uint32_t pi_dram_bus  = 0x40000000;
01203 static volatile uint32_t pi_mem_flag  = 0x0C;
01204 
01205 static int libInitialised = 0;
01206 
01207 /* initialise every gpioInitialise */
01208 
01209 static struct timespec libStarted;
01210 
01211 static uint32_t sockNetAddr[MAX_CONNECT_ADDRESSES];
01212 
01213 static int numSockNetAddr = 0;
01214 
01215 static uint32_t reportedLevel = 0;
01216 
01217 static int waveClockInited = 0;
01218 static int PWMClockInited = 0;
01219 
01220 static volatile gpioStats_t gpioStats;
01221 
01222 static int gpioMaskSet = 0;
01223 
01224 /* initialise if not libInitialised */
01225 
01226 static uint64_t gpioMask;
01227 
01228 static rawWave_t wf[3][PI_WAVE_MAX_PULSES];
01229 
01230 static int wfc[3]={0, 0, 0};
01231 
01232 static int wfcur=0;
01233 
01234 static wfStats_t wfStats=
01235 {
01236    0, 0, PI_WAVE_MAX_MICROS,
01237    0, 0, PI_WAVE_MAX_PULSES,
01238    0, 0, (DMAO_PAGES * CBS_PER_OPAGE)
01239 };
01240 
01241 static rawWaveInfo_t waveInfo[PI_MAX_WAVES];
01242 
01243 static wfRx_t wfRx[PI_MAX_USER_GPIO+1];
01244 
01245 static int waveOutBotCB  = PI_WAVE_COUNT_PAGES*CBS_PER_OPAGE;
01246 static int waveOutBotOOL = PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE;
01247 static int waveOutTopOOL = NUM_WAVE_OOL;
01248 static int waveOutCount = 0;
01249 
01250 static uint32_t *waveEndPtr = NULL;
01251 
01252 static volatile uint32_t alertBits   = 0;
01253 static volatile uint32_t monitorBits = 0;
01254 static volatile uint32_t notifyBits  = 0;
01255 static volatile uint32_t scriptBits  = 0;
01256 static volatile uint32_t gFilterBits = 0;
01257 static volatile uint32_t nFilterBits = 0;
01258 static volatile uint32_t wdogBits    = 0;
01259 
01260 static volatile uint32_t scriptEventBits  = 0;
01261 
01262 static volatile int runState = PI_STARTING;
01263 
01264 static int pthAlertRunning  = PI_THREAD_NONE;
01265 static int pthFifoRunning   = PI_THREAD_NONE;
01266 static int pthSocketRunning = PI_THREAD_NONE;
01267 
01268 static gpioAlert_t      gpioAlert  [PI_MAX_USER_GPIO+1];
01269 
01270 static eventAlert_t     eventAlert [PI_MAX_EVENT+1];
01271 
01272 static gpioISR_t        gpioISR    [PI_MAX_GPIO+1];
01273 
01274 static gpioGetSamples_t gpioGetSamples;
01275 
01276 static gpioInfo_t       gpioInfo   [PI_MAX_GPIO+1];
01277 
01278 static gpioNotify_t     gpioNotify [PI_NOTIFY_SLOTS];
01279 
01280 static fileInfo_t       fileInfo   [PI_FILE_SLOTS];
01281 static i2cInfo_t        i2cInfo    [PI_I2C_SLOTS];
01282 static serInfo_t        serInfo    [PI_SER_SLOTS];
01283 static spiInfo_t        spiInfo    [PI_SPI_SLOTS];
01284 
01285 static gpioScript_t     gpioScript [PI_MAX_SCRIPTS];
01286 
01287 static gpioSignal_t     gpioSignal [PI_MAX_SIGNUM+1];
01288 
01289 static gpioTimer_t      gpioTimer  [PI_MAX_TIMER+1];
01290 
01291 static int pwmFreq[PWM_FREQS];
01292 
01293 /* reset after gpioTerminated */
01294 
01295 /* resources which must be released on gpioTerminate */
01296 
01297 static FILE * inpFifo = NULL;
01298 static FILE * outFifo = NULL;
01299 
01300 static int fdLock       = -1;
01301 static int fdMem        = -1;
01302 static int fdSock       = -1;
01303 static int fdPmap       = -1;
01304 static int fdMbox       = -1;
01305 
01306 static DMAMem_t *dmaMboxBlk = MAP_FAILED;
01307 static uintptr_t * * dmaPMapBlk = MAP_FAILED;
01308 static dmaPage_t * * dmaVirt = MAP_FAILED;
01309 static dmaPage_t * * dmaBus = MAP_FAILED;
01310 
01311 static dmaIPage_t * * dmaIVirt = MAP_FAILED;
01312 static dmaIPage_t * * dmaIBus = MAP_FAILED;
01313 
01314 static dmaOPage_t * * dmaOVirt = MAP_FAILED;
01315 static dmaOPage_t * * dmaOBus = MAP_FAILED;
01316 
01317 static volatile uint32_t * auxReg  = MAP_FAILED;
01318 static volatile uint32_t * bscsReg = MAP_FAILED;
01319 static volatile uint32_t * clkReg  = MAP_FAILED;
01320 static volatile uint32_t * dmaReg  = MAP_FAILED;
01321 static volatile uint32_t * gpioReg = MAP_FAILED;
01322 static volatile uint32_t * padsReg = MAP_FAILED;
01323 static volatile uint32_t * pcmReg  = MAP_FAILED;
01324 static volatile uint32_t * pwmReg  = MAP_FAILED;
01325 static volatile uint32_t * spiReg  = MAP_FAILED;
01326 static volatile uint32_t * systReg = MAP_FAILED;
01327 
01328 static volatile uint32_t * dmaIn   = MAP_FAILED;
01329 static volatile uint32_t * dmaOut  = MAP_FAILED;
01330 
01331 static uint32_t hw_clk_freq[3];
01332 static uint32_t hw_pwm_freq[2];
01333 static uint32_t hw_pwm_duty[2];
01334 static uint32_t hw_pwm_real_range[2];
01335 
01336 static volatile gpioCfg_t gpioCfg =
01337 {
01338    PI_DEFAULT_BUFFER_MILLIS,
01339    PI_DEFAULT_CLK_MICROS,
01340    PI_DEFAULT_CLK_PERIPHERAL,
01341    PI_DEFAULT_DMA_PRIMARY_CHANNEL,
01342    PI_DEFAULT_DMA_SECONDARY_CHANNEL,
01343    PI_DEFAULT_SOCKET_PORT,
01344    PI_DEFAULT_IF_FLAGS,
01345    PI_DEFAULT_MEM_ALLOC_MODE,
01346    0, /* dbgLevel */
01347    0, /* alertFreq */
01348    0, /* internals */
01349 };
01350 
01351 /* no initialisation required */
01352 
01353 static unsigned bufferBlocks; /* number of blocks in buffer */
01354 static unsigned bufferCycles; /* number of cycles */
01355 
01356 static pthread_t pthAlert;
01357 static pthread_t pthFifo;
01358 static pthread_t pthSocket;
01359 
01360 static uint32_t spi_dummy;
01361 
01362 static unsigned old_mode_ce0;
01363 static unsigned old_mode_ce1;
01364 static unsigned old_mode_sclk;
01365 static unsigned old_mode_miso;
01366 static unsigned old_mode_mosi;
01367 
01368 static uint32_t old_spi_cs;
01369 static uint32_t old_spi_clk;
01370 
01371 static unsigned old_mode_ace0;
01372 static unsigned old_mode_ace1;
01373 static unsigned old_mode_ace2;
01374 static unsigned old_mode_asclk;
01375 static unsigned old_mode_amiso;
01376 static unsigned old_mode_amosi;
01377 
01378 static uint32_t old_spi_cntl0;
01379 static uint32_t old_spi_cntl1;
01380 
01381 static uint32_t bscFR;
01382 
01383 /* const --------------------------------------------------------- */
01384 
01385 static const uint8_t clkDef[PI_MAX_GPIO + 1] =
01386 {
01387  /*             0     1     2     3     4     5     6     7     8     9 */
01388    /* 0 */   0x00, 0x00, 0x00, 0x00, 0x84, 0x94, 0xA4, 0x00, 0x00, 0x00,
01389    /* 1 */   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01390    /* 2 */   0x82, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01391    /* 3 */   0x00, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
01392    /* 4 */   0x00, 0x00, 0x94, 0xA4, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00,
01393    /* 5 */   0x00, 0x00, 0x00, 0x00,
01394 };
01395 
01396 /*
01397  7 6 5 4 3 2 1 0
01398  V . C C . M M M
01399 
01400  V: 0 no clock, 1 has a clock
01401 CC: 00 CLK0, 01 CLK1, 10 CLK2
01402  M: 100 ALT0, 010 ALT5
01403 
01404  gpio4  GPCLK0 ALT0
01405  gpio5  GPCLK1 ALT0 B+ and compute module only (reserved for system use)
01406  gpio6  GPCLK2 ALT0 B+ and compute module only
01407  gpio20 GPCLK0 ALT5 B+ and compute module only
01408  gpio21 GPCLK1 ALT5 Not available on Rev.2 B (reserved for system use)
01409 
01410  gpio32 GPCLK0 ALT0 Compute module only
01411  gpio34 GPCLK0 ALT0 Compute module only
01412  gpio42 GPCLK1 ALT0 Compute module only (reserved for system use)
01413  gpio43 GPCLK2 ALT0 Compute module only
01414  gpio44 GPCLK1 ALT0 Compute module only (reserved for system use)
01415 */
01416 
01417 static const uint8_t PWMDef[PI_MAX_GPIO + 1] =
01418 {
01419    /*          0     1     2     3     4     5     6     7     8     9 */
01420    /* 0 */   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01421    /* 1 */   0x00, 0x00, 0x84, 0x94, 0x00, 0x00, 0x00, 0x00, 0x82, 0x92,
01422    /* 2 */   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01423    /* 3 */   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01424    /* 4 */   0x84, 0x94, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00,
01425    /* 5 */   0x00, 0x00, 0x85, 0x95,
01426 };
01427 
01428 /*
01429  7 6 5 4 3 2 1 0
01430  V . . P . M M M
01431 
01432  V: 0 no PWM, 1 has a PWM
01433  P: 0 PWM0, 1 PWM1
01434  M: 010 ALT5, 100 ALT0, 101 ALT1
01435 
01436  gpio12 pwm0 ALT0
01437  gpio13 pwm1 ALT0
01438  gpio18 pwm0 ALT5
01439  gpio19 pwm1 ALT5
01440  gpio40 pwm0 ALT0
01441  gpio41 pwm1 ALT0
01442  gpio45 pwm1 ALT0
01443  gpio52 pwm0 ALT1
01444  gpio53 pwm1 ALT1
01445 */
01446 
01447 static const clkCfg_t clkCfg[]=
01448 {
01449    /* valid servo */
01450       {   0,    0}, /*  0 */
01451       {   1,   17}, /*  1 */
01452       {   1,   16}, /*  2 */
01453       {   0,    0}, /*  3 */
01454       {   1,   15}, /*  4 */
01455       {   1,   14}, /*  5 */
01456       {   0,    0}, /*  6 */
01457       {   0,    0}, /*  7 */
01458       {   1,   13}, /*  8 */
01459       {   0,    0}, /*  9 */
01460       {   1,   12}, /* 10 */
01461 };
01462 
01463 static const uint16_t pwmCycles[PWM_FREQS]=
01464    {  1,    2,    4,    5,    8,   10,   16,    20,    25,
01465      32,   40,   50,   80,  100,  160,  200,   400,   800};
01466 
01467 static const uint16_t pwmRealRange[PWM_FREQS]=
01468    { 25,   50,  100,  125,  200,  250,  400,   500,   625,
01469     800, 1000, 1250, 2000, 2500, 4000, 5000, 10000, 20000};
01470 
01471 /* prototype ----------------------------------------------------- */
01472 
01473 static void intNotifyBits(void);
01474 
01475 static void intScriptBits(void);
01476 
01477 static void intScriptEventBits(void);
01478 
01479 static int  gpioNotifyOpenInBand(int fd);
01480 
01481 static void initHWClk
01482    (int clkCtl, int clkDiv, int clkSrc, int divI, int divF, int MASH);
01483 
01484 static void initDMAgo(volatile uint32_t  *dmaAddr, uint32_t cbAddr);
01485 
01486 int gpioWaveTxStart(unsigned wave_mode); /* deprecated */
01487 
01488 static void closeOrphanedNotifications(int slot, int fd);
01489 
01490 
01491 /* ======================================================================= */
01492 
01493 int myScriptNameValid(char *name)
01494 {
01495    int i, c, len, valid;
01496 
01497    len = strlen(name);
01498 
01499    valid = 1;
01500 
01501    for (i=0; i<len; i++)
01502    {
01503       c = name[i];
01504 
01505       if ((!isalnum(c)) && (c != '_') && (c != '-'))
01506       {
01507          valid = 0;
01508          break;
01509       }
01510    }
01511    return valid;
01512 }
01513 
01514 /* ----------------------------------------------------------------------- */
01515 
01516 static char * myTimeStamp()
01517 {
01518    static struct timeval last;
01519    static char buf[32];
01520    struct timeval now;
01521 
01522    struct tm tmp;
01523 
01524    gettimeofday(&now, NULL);
01525 
01526    if (now.tv_sec != last.tv_sec)
01527    {
01528       localtime_r(&now.tv_sec, &tmp);
01529       strftime(buf, sizeof(buf), "%F %T", &tmp);
01530       last.tv_sec = now.tv_sec;
01531    }
01532 
01533    return buf;
01534 }
01535 
01536 /* ----------------------------------------------------------------------- */
01537 
01538 int myPathBad(char *name)
01539 {
01540    int i, c, len, in_part, parts, last_char_dot;
01541    char *bad="/*?.";
01542 
01543    parts = 0;
01544    in_part = 0;
01545    last_char_dot = 0;
01546 
01547    len = strlen(name);
01548 
01549    for (i=0; i<len; i++)
01550    {
01551       c = name[i];
01552 
01553       if (memchr(bad, c, 4)) /* wildcard or directory character */
01554       {
01555          if (c == '.')
01556          {
01557             if (last_char_dot) return 1;
01558             last_char_dot = 1;
01559          }
01560          else last_char_dot = 0;
01561 
01562          in_part = 0;
01563       }
01564       else /* normal character */
01565       {
01566          last_char_dot = 0;
01567 
01568          if (!in_part) parts++;
01569 
01570          in_part = 1;
01571       }
01572    }
01573 
01574    if (parts < 2) return 1; else return 0;
01575 }
01576 
01577 /* ----------------------------------------------------------------------- */
01578 
01579 static char *myBuf2Str(unsigned count, char *buf)
01580 {
01581    static char str[128];
01582    int i, c;
01583 
01584    if (count && buf)
01585    {
01586       if (count > 40) c = 40; else c = count;
01587 
01588       for (i=0; i<c; i++) sprintf(str+(3*i), "%02X ", buf[i]);
01589       str[(3*c)-1] = 0;
01590    }
01591    else str[0] = 0;
01592 
01593    return str;
01594 }
01595 
01596 /* ----------------------------------------------------------------------- */
01597 
01598 static int my_smbus_access(
01599    int fd, char rw, uint8_t cmd, int size, union my_smbus_data *data)
01600 {
01601    struct my_smbus_ioctl_data args;
01602 
01603    DBG(DBG_INTERNAL, "rw=%d reg=%d cmd=%d data=%s",
01604       rw, cmd, size, myBuf2Str(data->byte+1, (char*)data));
01605 
01606    args.read_write = rw;
01607    args.command    = cmd;
01608    args.size       = size;
01609    args.data       = data;
01610 
01611    return ioctl(fd, PI_I2C_SMBUS, &args);
01612 }
01613 
01614 /* ----------------------------------------------------------------------- */
01615 
01616 static void myGpioSetMode(unsigned gpio, unsigned mode)
01617 {
01618    int reg, shift;
01619 
01620    reg   =  gpio/10;
01621    shift = (gpio%10) * 3;
01622 
01623    gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (mode<<shift);
01624 }
01625 
01626 
01627 /* ----------------------------------------------------------------------- */
01628 
01629 static int myGpioRead(unsigned gpio)
01630 {
01631    if ((*(gpioReg + GPLEV0 + BANK) & BIT) != 0) return PI_ON;
01632    else                                         return PI_OFF;
01633 }
01634 
01635 
01636 /* ----------------------------------------------------------------------- */
01637 
01638 static void myGpioWrite(unsigned gpio, unsigned level)
01639 {
01640    if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
01641    else                 *(gpioReg + GPSET0 + BANK) = BIT;
01642 }
01643 
01644 /* ----------------------------------------------------------------------- */
01645 
01646 static void myGpioSleep(int seconds, int micros)
01647 {
01648    struct timespec ts, rem;
01649 
01650    ts.tv_sec  = seconds;
01651    ts.tv_nsec = micros * 1000;
01652 
01653    while (clock_nanosleep(CLOCK_REALTIME, 0, &ts, &rem))
01654    {
01655       /* copy remaining time to ts */
01656       ts = rem;
01657    }
01658 }
01659 
01660 /* ----------------------------------------------------------------------- */
01661 
01662 static uint32_t myGpioDelay(uint32_t micros)
01663 {
01664    uint32_t start;
01665 
01666    start = systReg[SYST_CLO];
01667 
01668    if (micros <= PI_MAX_BUSY_DELAY)
01669    {
01670       while ((systReg[SYST_CLO] - start) <= micros);
01671    }
01672    else
01673    {
01674       myGpioSleep(micros/MILLION, micros%MILLION);
01675    }
01676 
01677    return (systReg[SYST_CLO] - start);
01678 }
01679 
01680 /* ----------------------------------------------------------------------- */
01681 
01682 static void myCreatePipe(char * name, int perm)
01683 {
01684    unlink(name);
01685 
01686    mkfifo(name, perm);
01687 
01688    if (chmod(name, perm) < 0)
01689    {
01690       DBG(DBG_ALWAYS, "Can't set permissions (%d) for %s, %m", perm, name);
01691       return;
01692    }
01693 }
01694 
01695 /* ----------------------------------------------------------------------- */
01696 
01697 static void myOffPageSlot(int pos, int * page, int * slot)
01698 {
01699    *page = pos/OFF_PER_IPAGE;
01700    *slot = pos%OFF_PER_IPAGE;
01701 }
01702 
01703 /* ----------------------------------------------------------------------- */
01704 
01705 static void myLvsPageSlot(int pos, int * page, int * slot)
01706 {
01707    *page = pos/LVS_PER_IPAGE;
01708    *slot = pos%LVS_PER_IPAGE;
01709 }
01710 
01711 /* ----------------------------------------------------------------------- */
01712 
01713 static void myTckPageSlot(int pos, int * page, int * slot)
01714 {
01715    *page = pos/TCK_PER_IPAGE;
01716    *slot = pos%TCK_PER_IPAGE;
01717 }
01718 
01719 /* ----------------------------------------------------------------------- */
01720 
01721 static uint32_t myGetLevel(int pos)
01722 {
01723    uint32_t level;
01724    int page, slot;
01725 
01726    myLvsPageSlot(pos, &page, &slot);
01727 
01728    level = dmaIVirt[page]->level[slot];
01729 
01730    return level;
01731 }
01732 
01733 /* ----------------------------------------------------------------------- */
01734 
01735 static int myI2CGetPar(char *inBuf, int *inPos, int inLen, int *esc)
01736 {
01737    int bytes;
01738 
01739    if (*esc) bytes = 2; else bytes = 1;
01740 
01741    *esc = 0;
01742 
01743    if (*inPos <= (inLen - bytes))
01744    {
01745       if (bytes == 1)
01746       {
01747          return inBuf[(*inPos)++];
01748       }
01749       else
01750       {
01751          (*inPos) += 2;
01752          return inBuf[*inPos-2] + (inBuf[*inPos-1]<<8);
01753       }
01754    }
01755    return -1;
01756 }
01757 
01758 /* ----------------------------------------------------------------------- */
01759 
01760 static uint32_t myGetTick(int pos)
01761 {
01762    uint32_t tick;
01763    int page, slot;
01764 
01765    myTckPageSlot(pos, &page, &slot);
01766 
01767    tick = dmaIVirt[page]->tick[slot];
01768 
01769    return tick;
01770 }
01771 
01772 static int myPermit(unsigned gpio)
01773 {
01774    if (gpio <= PI_MAX_GPIO)
01775    {
01776       if (gpioMask & ((uint64_t)(1)<<gpio)) return 1;
01777       else return 0;
01778    }
01779    return 1; /* will fail for bad gpio number */
01780 }
01781 
01782 static void flushMemory(void)
01783 {
01784    static int val = 0;
01785 
01786    void *dummy;
01787 
01788    dummy = mmap(
01789        0, (FLUSH_PAGES*PAGE_SIZE),
01790        PROT_READ|PROT_WRITE|PROT_EXEC,
01791        MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_LOCKED,
01792        -1, 0);
01793 
01794    if (dummy == MAP_FAILED)
01795    {
01796       DBG(DBG_STARTUP, "mmap dummy failed (%m)");
01797    }
01798    else
01799    {
01800       memset(dummy, val++, (FLUSH_PAGES*PAGE_SIZE));
01801       memset(dummy, val++, (FLUSH_PAGES*PAGE_SIZE));
01802       munmap(dummy, FLUSH_PAGES*PAGE_SIZE);
01803    }
01804 }
01805 
01806 /* ----------------------------------------------------------------------- */
01807 
01808 static void wfRx_lock(int i)
01809 {
01810    pthread_mutex_lock(&wfRx[i].mutex);
01811 }
01812 
01813 /* ----------------------------------------------------------------------- */
01814 
01815 static void wfRx_unlock(int i)
01816 {
01817    pthread_mutex_unlock(&wfRx[i].mutex);
01818 }
01819 
01820 /* ----------------------------------------------------------------------- */
01821 
01822 static void spinWhileStarting(void)
01823 {
01824    while (runState == PI_STARTING)
01825    {
01826       if (piCores == 1) myGpioDelay(1000);
01827       else flushMemory();
01828    }
01829 }
01830 
01831 /* ----------------------------------------------------------------------- */
01832 
01833 static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
01834 {
01835    int res, i, j;
01836    uint32_t mask;
01837    uint32_t tmp1, tmp2, tmp3, tmp4, tmp5;
01838    gpioPulse_t *pulse;
01839    bsc_xfer_t xfer;
01840    int masked;
01841    res = 0;
01842 
01843    switch (p[0])
01844    {
01845       case PI_CMD_BC1:
01846          mask = gpioMask;
01847 
01848          res = gpioWrite_Bits_0_31_Clear(p[1]&mask);
01849 
01850          if ((mask | p[1]) != mask)
01851          {
01852             DBG(DBG_USER,
01853                "gpioWrite_Bits_0_31_Clear: bad bits %08X (permissions %08X)",
01854                p[1], mask);
01855             res = PI_SOME_PERMITTED;
01856          }
01857          break;
01858 
01859       case PI_CMD_BC2:
01860          mask = gpioMask>>32;
01861 
01862          res = gpioWrite_Bits_32_53_Clear(p[1]&mask);
01863 
01864          if ((mask | p[1]) != mask)
01865          {
01866             DBG(DBG_USER,
01867                "gpioWrite_Bits_32_53_Clear: bad bits %08X (permissions %08X)",
01868                p[1], mask);
01869             res = PI_SOME_PERMITTED;
01870          }
01871          break;
01872 
01873       case PI_CMD_BI2CC:
01874          res = bbI2CClose(p[1]);
01875          break;
01876 
01877       case PI_CMD_BI2CO:
01878          memcpy(&p[4], buf, 4);
01879          res = bbI2COpen(p[1], p[2], p[4]);
01880          break;
01881 
01882       case PI_CMD_BI2CZ:
01883          /* use half buffer for write, half buffer for read */
01884          if (p[3] > (bufSize/2)) p[3] = bufSize/2;
01885          res = bbI2CZip(p[1], buf, p[3], buf+(bufSize/2), bufSize/2);
01886          if (res > 0)
01887          {
01888             memcpy(buf, buf+(bufSize/2), res);
01889          }
01890          break;
01891 
01892       case PI_CMD_BSCX:
01893          xfer.control = p[1];
01894          if (p[3] > BSC_FIFO_SIZE) p[3] = BSC_FIFO_SIZE;
01895          xfer.txCnt = p[3];
01896          if (p[3]) memcpy(&xfer.txBuf, buf, p[3]);
01897          res = bscXfer(&xfer);
01898          if (res >= 0)
01899          {
01900             memcpy(buf, &res, 4);
01901             res = 4 + xfer.rxCnt;
01902             if (res > 4) memcpy(buf+4, &xfer.rxBuf, res-4);
01903          }
01904          break;
01905 
01906       case PI_CMD_BSPIO:
01907 
01908          memcpy(&tmp1, buf+ 0, 4); // MISO
01909          memcpy(&tmp2, buf+ 4, 4); // MOSI
01910          memcpy(&tmp3, buf+ 8, 4); // SCLK
01911          memcpy(&tmp4, buf+12, 4); // baud
01912          memcpy(&tmp5, buf+16, 4); // flags
01913 
01914          if (!myPermit(p[1]))
01915          {
01916             DBG(DBG_USER,
01917                "bbSPIOpen: gpio %d, no permission to update CS", p[1]);
01918             res = PI_NOT_PERMITTED;
01919          }
01920 
01921          if (!myPermit(tmp1))
01922          {
01923             DBG(DBG_USER,
01924                "bbSPIOpen: gpio %d, no permission to update MISO", tmp1);
01925             res = PI_NOT_PERMITTED;
01926          }
01927 
01928          if (!myPermit(tmp2))
01929          {
01930             DBG(DBG_USER,
01931                "bbSPIOpen: gpio %d, no permission to update MOSI", tmp2);
01932             res = PI_NOT_PERMITTED;
01933          }
01934 
01935          if (!myPermit(tmp3))
01936          {
01937             DBG(DBG_USER,
01938                "bbSPIOpen: gpio %d, no permission to update SCLK", tmp3);
01939             res = PI_NOT_PERMITTED;
01940          }
01941 
01942          if (!res) res = bbSPIOpen(p[1], tmp1, tmp2, tmp3, tmp4, tmp5);
01943          break;
01944 
01945       case PI_CMD_BSPIC:
01946          res = bbSPIClose(p[1]);
01947          break;
01948 
01949       case PI_CMD_BSPIX:
01950          if (p[3] > bufSize) p[3] = bufSize;
01951             res = bbSPIXfer(p[1], buf, buf, p[3]);
01952          break;
01953 
01954       case PI_CMD_BR1: res = gpioRead_Bits_0_31(); break;
01955 
01956       case PI_CMD_BR2: res = gpioRead_Bits_32_53(); break;
01957 
01958       case PI_CMD_BS1:
01959          mask = gpioMask;
01960 
01961          res = gpioWrite_Bits_0_31_Set(p[1]&mask);
01962 
01963          if ((mask | p[1]) != mask)
01964          {
01965             DBG(DBG_USER,
01966                "gpioWrite_Bits_0_31_Set: bad bits %08X (permissions %08X)",
01967                p[1], mask);
01968             res = PI_SOME_PERMITTED;
01969          }
01970          break;
01971 
01972       case PI_CMD_BS2:
01973          mask = gpioMask>>32;
01974 
01975          res = gpioWrite_Bits_32_53_Set(p[1]&mask);
01976 
01977          if ((mask | p[1]) != mask)
01978          {
01979             DBG(DBG_USER,
01980                "gpioWrite_Bits_32_53_Set: bad bits %08X (permissions %08X)",
01981                p[1], mask);
01982             res = PI_SOME_PERMITTED;
01983          }
01984          break;
01985 
01986       case PI_CMD_CF1:
01987          res = gpioCustom1(p[1], p[2], buf, p[3]);
01988          break;
01989 
01990       case PI_CMD_CF2:
01991          /* a couple of extra precautions for untrusted code */
01992          if (p[2] > bufSize) p[2] = bufSize;
01993          res = gpioCustom2(p[1], buf, p[3], buf, p[2]);
01994          if (res > p[2]) res = p[2];
01995          break;
01996 
01997       case PI_CMD_CGI: res = gpioCfgGetInternals(); break;
01998 
01999       case PI_CMD_CSI: res = gpioCfgSetInternals(p[1]); break;
02000 
02001       case PI_CMD_EVM: res = eventMonitor(p[1], p[2]); break;
02002 
02003       case PI_CMD_EVT: res = eventTrigger(p[1]); break;
02004 
02005       case PI_CMD_FC: res = fileClose(p[1]); break;
02006 
02007       case PI_CMD_FG:
02008          res = gpioGlitchFilter(p[1], p[2]);
02009          break;
02010 
02011       case PI_CMD_FL:
02012          if (p[1] > bufSize) p[1] = bufSize;
02013          res = fileList(buf, buf, p[1]);
02014          break;
02015 
02016       case PI_CMD_FN:
02017          memcpy(&p[4], buf, 4);
02018          res = gpioNoiseFilter(p[1], p[2], p[4]);
02019          break;
02020 
02021       case PI_CMD_FO: res = fileOpen(buf, p[1]); break;
02022 
02023       case PI_CMD_FR:
02024          if (p[2] > bufSize) p[2] = bufSize;
02025          res = fileRead(p[1], buf, p[2]);
02026          break;
02027 
02028       case PI_CMD_FS:
02029          memcpy(&p[4], buf, 4);
02030          res = fileSeek(p[1], p[2], p[4]);
02031          break;
02032 
02033       case PI_CMD_FW: res = fileWrite(p[1], buf, p[3]); break;
02034 
02035       case PI_CMD_GDC: res = gpioGetPWMdutycycle(p[1]); break;
02036 
02037       case PI_CMD_GPW: res = gpioGetServoPulsewidth(p[1]); break;
02038 
02039       case PI_CMD_HC:
02040          /* special case to allow password in upper byte */
02041          if (myPermit(p[1]&0xFFFFFF)) res = gpioHardwareClock(p[1], p[2]);
02042          else
02043          {
02044             DBG(DBG_USER,
02045                "gpioHardwareClock: gpio %d, no permission to update",
02046                 p[1] & 0xFFFFFF);
02047             res = PI_NOT_PERMITTED;
02048          }
02049          break;
02050 
02051       case PI_CMD_HELP: break;
02052 
02053       case PI_CMD_HP:
02054          if (myPermit(p[1]))
02055          {
02056             memcpy(&p[4], buf, 4);
02057             res = gpioHardwarePWM(p[1], p[2], p[4]);
02058          }
02059          else
02060          {
02061             DBG(DBG_USER,
02062                "gpioHardwarePWM: gpio %d, no permission to update", p[1]);
02063             res = PI_NOT_PERMITTED;
02064          }
02065          break;
02066 
02067       case PI_CMD_HWVER: res = gpioHardwareRevision(); break;
02068 
02069 
02070 
02071       case PI_CMD_I2CC: res = i2cClose(p[1]); break;
02072 
02073       case PI_CMD_I2CO:
02074          memcpy(&p[4], buf, 4);
02075          res = i2cOpen(p[1], p[2], p[4]);
02076          break;
02077 
02078       case PI_CMD_I2CPC:
02079          memcpy(&p[4], buf, 4);
02080          res = i2cProcessCall(p[1], p[2], p[4]);
02081          break;
02082 
02083       case PI_CMD_I2CPK:
02084          res = i2cBlockProcessCall(p[1], p[2], buf, p[3]);
02085          break;
02086 
02087       case PI_CMD_I2CRB: res = i2cReadByteData(p[1], p[2]); break;
02088 
02089       case PI_CMD_I2CRD:
02090          if (p[2] > bufSize) p[2] = bufSize;
02091          res = i2cReadDevice(p[1], buf, p[2]);
02092          break;
02093 
02094       case PI_CMD_I2CRI:
02095          memcpy(&p[4], buf, 4);
02096          res = i2cReadI2CBlockData(p[1], p[2], buf, p[4]);
02097          break;
02098 
02099       case PI_CMD_I2CRK:
02100          res = i2cReadBlockData(p[1], p[2], buf);
02101          break;
02102 
02103       case PI_CMD_I2CRS: res = i2cReadByte(p[1]); break;
02104 
02105       case PI_CMD_I2CRW: res = i2cReadWordData(p[1], p[2]); break;
02106 
02107       case PI_CMD_I2CWB:
02108          memcpy(&p[4], buf, 4);
02109          res = i2cWriteByteData(p[1], p[2], p[4]);
02110          break;
02111 
02112       case PI_CMD_I2CWD:
02113          res = i2cWriteDevice(p[1], buf, p[3]);
02114          break;
02115 
02116       case PI_CMD_I2CWI:
02117          res = i2cWriteI2CBlockData(p[1], p[2], buf, p[3]);
02118          break;
02119 
02120       case PI_CMD_I2CWK:
02121          res = i2cWriteBlockData(p[1], p[2], buf, p[3]);
02122          break;
02123 
02124       case PI_CMD_I2CWQ: res = i2cWriteQuick(p[1], p[2]); break;
02125 
02126       case PI_CMD_I2CWS: res = i2cWriteByte(p[1], p[2]); break;
02127 
02128       case PI_CMD_I2CWW:
02129          memcpy(&p[4], buf, 4);
02130          res = i2cWriteWordData(p[1], p[2], p[4]);
02131          break;
02132 
02133       case PI_CMD_I2CZ:
02134          /* use half buffer for write, half buffer for read */
02135          if (p[3] > (bufSize/2)) p[3] = bufSize/2;
02136          res = i2cZip(p[1], buf, p[3], buf+(bufSize/2), bufSize/2);
02137          if (res > 0)
02138          {
02139             memcpy(buf, buf+(bufSize/2), res);
02140          }
02141          break;
02142 
02143       case PI_CMD_MICS:
02144          if (p[1] <= PI_MAX_MICS_DELAY) myGpioDelay(p[1]);
02145          else res = PI_BAD_MICS_DELAY;
02146          break;
02147 
02148       case PI_CMD_MILS:
02149          if (p[1] <= PI_MAX_MILS_DELAY) myGpioDelay(p[1] * 1000);
02150          else res = PI_BAD_MILS_DELAY;
02151          break;
02152 
02153       case PI_CMD_MODEG: res = gpioGetMode(p[1]); break;
02154 
02155       case PI_CMD_MODES:
02156          if (myPermit(p[1])) res = gpioSetMode(p[1], p[2]);
02157          else
02158          {
02159             DBG(DBG_USER,
02160                "gpioSetMode: gpio %d, no permission to update", p[1]);
02161             res = PI_NOT_PERMITTED;
02162          }
02163          break;
02164 
02165       case PI_CMD_NB: res = gpioNotifyBegin(p[1], p[2]); break;
02166 
02167       case PI_CMD_NC: res = gpioNotifyClose(p[1]); break;
02168 
02169       case PI_CMD_NO: res = gpioNotifyOpen();  break;
02170 
02171       case PI_CMD_NP: res = gpioNotifyPause(p[1]); break;
02172 
02173       case PI_CMD_PADG: res = gpioGetPad(p[1]); break;
02174 
02175       case PI_CMD_PADS: res = gpioSetPad(p[1], p[2]); break;
02176 
02177       case PI_CMD_PFG: res = gpioGetPWMfrequency(p[1]); break;
02178 
02179       case PI_CMD_PFS:
02180          if (myPermit(p[1])) res = gpioSetPWMfrequency(p[1], p[2]);
02181          else
02182          {
02183             DBG(DBG_USER,
02184                "gpioSetPWMfrequency: gpio %d, no permission to update", p[1]);
02185             res = PI_NOT_PERMITTED;
02186          }
02187          break;
02188 
02189       case PI_CMD_PIGPV: res = gpioVersion(); break;
02190 
02191       case PI_CMD_PRG: res = gpioGetPWMrange(p[1]); break;
02192 
02193       case PI_CMD_PROC:
02194          res = gpioStoreScript(buf);
02195          break;
02196 
02197       case PI_CMD_PROCD: res = gpioDeleteScript(p[1]); break;
02198 
02199       case PI_CMD_PROCP:
02200          res = gpioScriptStatus(p[1], (uint32_t *)buf);
02201          break;
02202 
02203       case PI_CMD_PROCR:
02204          res = gpioRunScript(p[1], p[3]/4, (uint32_t *)buf);
02205          break;
02206 
02207       case PI_CMD_PROCS: res = gpioStopScript(p[1]); break;
02208 
02209       case PI_CMD_PROCU:
02210          res = gpioUpdateScript(p[1], p[3]/4, (uint32_t *)buf);
02211          break;
02212 
02213       case PI_CMD_PRRG: res = gpioGetPWMrealRange(p[1]); break;
02214 
02215       case PI_CMD_PRS:
02216          if (myPermit(p[1])) res = gpioSetPWMrange(p[1], p[2]);
02217          else
02218          {
02219             DBG(DBG_USER,
02220                "gpioSetPWMrange: gpio %d, no permission to update", p[1]);
02221             res = PI_NOT_PERMITTED;
02222          }
02223          break;
02224 
02225       case PI_CMD_PUD:
02226          if (myPermit(p[1])) res = gpioSetPullUpDown(p[1], p[2]);
02227          else
02228          {
02229             DBG(DBG_USER,
02230                "gpioSetPullUpDown: gpio %d, no permission to update", p[1]);
02231             res = PI_NOT_PERMITTED;
02232          }
02233          break;
02234 
02235       case PI_CMD_PWM:
02236          if (myPermit(p[1])) res = gpioPWM(p[1], p[2]);
02237          else
02238          {
02239             DBG(DBG_USER, "gpioPWM: gpio %d, no permission to update", p[1]);
02240             res = PI_NOT_PERMITTED;
02241          }
02242          break;
02243 
02244       case PI_CMD_READ: res = gpioRead(p[1]); break;
02245 
02246       case PI_CMD_SERVO:
02247          if (myPermit(p[1])) res = gpioServo(p[1], p[2]);
02248          else
02249          {
02250             DBG(DBG_USER,
02251                "gpioServo: gpio %d, no permission to update", p[1]);
02252             res = PI_NOT_PERMITTED;
02253          }
02254          break;
02255 
02256 
02257 
02258       case PI_CMD_SERRB: res = serReadByte(p[1]); break;
02259 
02260       case PI_CMD_SERWB: res = serWriteByte(p[1], p[2]); break;
02261 
02262       case PI_CMD_SERC: res = serClose(p[1]); break;
02263 
02264       case PI_CMD_SERDA: res = serDataAvailable(p[1]); break;
02265 
02266       case PI_CMD_SERO: res = serOpen(buf, p[1], p[2]); break;
02267 
02268       case PI_CMD_SERR:
02269          if (p[2] > bufSize) p[2] = bufSize;
02270          res = serRead(p[1], buf, p[2]);
02271          break;
02272 
02273       case PI_CMD_SERW: res = serWrite(p[1], buf, p[3]); break;
02274 
02275 
02276       case PI_CMD_SHELL:
02277           res = shell(buf, buf+p[1]+1);
02278           break;
02279 
02280 
02281       case PI_CMD_SLR:
02282          if (p[2] > bufSize) p[2] = bufSize;
02283          res = gpioSerialRead(p[1], buf, p[2]);
02284          break;
02285 
02286       case PI_CMD_SLRC: res = gpioSerialReadClose(p[1]); break;
02287 
02288       case PI_CMD_SLRO:
02289          memcpy(&p[4], buf, 4);
02290          res = gpioSerialReadOpen(p[1], p[2], p[4]); break;
02291 
02292       case PI_CMD_SLRI: res = gpioSerialReadInvert(p[1], p[2]); break;
02293 
02294       case PI_CMD_SPIC:
02295          res = spiClose(p[1]);
02296          break;
02297 
02298       case PI_CMD_SPIO:
02299          memcpy(&p[4], buf, 4);
02300          res = spiOpen(p[1], p[2], p[4]);
02301          break;
02302 
02303       case PI_CMD_SPIR:
02304          if (p[2] > bufSize) p[2] = bufSize;
02305          res = spiRead(p[1], buf, p[2]);
02306          break;
02307 
02308       case PI_CMD_SPIW:
02309          if (p[3] > bufSize) p[3] = bufSize;
02310          res = spiWrite(p[1], buf, p[3]);
02311          break;
02312 
02313       case PI_CMD_SPIX:
02314          if (p[3] > bufSize) p[3] = bufSize;
02315          res = spiXfer(p[1], buf, buf, p[3]);
02316          break;
02317 
02318       case PI_CMD_TICK: res = gpioTick(); break;
02319 
02320       case PI_CMD_TRIG:
02321          if (myPermit(p[1]))
02322          {
02323             memcpy(&p[4], buf, 4);
02324             res = gpioTrigger(p[1], p[2], p[4]);
02325          }
02326          else
02327          {
02328             DBG(DBG_USER,
02329                "gpioTrigger: gpio %d, no permission to update", p[1]);
02330             res = PI_NOT_PERMITTED;
02331          }
02332          break;
02333 
02334       case PI_CMD_WDOG: res = gpioSetWatchdog(p[1], p[2]); break;
02335 
02336       case PI_CMD_WRITE:
02337          if (myPermit(p[1])) res = gpioWrite(p[1], p[2]);
02338          else
02339          {
02340             DBG(DBG_USER, "gpioWrite: gpio %d, no permission to update", p[1]);
02341             res = PI_NOT_PERMITTED;
02342          }
02343          break;
02344 
02345 
02346 
02347       case PI_CMD_WVAG:
02348 
02349          /* need to mask off any non permitted gpios */
02350 
02351          mask = gpioMask;
02352          pulse = (gpioPulse_t *)buf;
02353          j = p[3]/sizeof(gpioPulse_t);
02354          masked = 0;
02355 
02356          for (i=0; i<j; i++)
02357          {
02358             tmp1 = pulse[i].gpioOn & mask;
02359             if (tmp1 != pulse[i].gpioOn)
02360             {
02361                pulse[i].gpioOn = tmp1;
02362                masked = 1;
02363             }
02364 
02365             tmp1 = pulse[i].gpioOff & mask;
02366             if (tmp1 != pulse[i].gpioOff)
02367             {
02368                pulse[i].gpioOff = tmp1;
02369                masked = 1;
02370             }
02371             DBG(DBG_SCRIPT, "on=%X off=%X delay=%d",
02372                pulse[i].gpioOn, pulse[i].gpioOff, pulse[i].usDelay);
02373          }
02374 
02375          res = gpioWaveAddGeneric(j, pulse);
02376 
02377          /* report permission error unless another error occurred */
02378          if (masked && (res >= 0)) res = PI_SOME_PERMITTED;
02379 
02380          break;
02381 
02382       case PI_CMD_WVAS:
02383          if (myPermit(p[1]))
02384          {
02385             memcpy(&tmp1, buf, 4);   /* databits */
02386             memcpy(&tmp2, buf+4, 4); /* stophalfbits */
02387             memcpy(&tmp3, buf+8, 4); /* offset */
02388             res = gpioWaveAddSerial
02389                (p[1], p[2], tmp1, tmp2, tmp3, p[3]-12, buf+12);
02390          }
02391          else
02392          {
02393             DBG(
02394                DBG_USER,
02395                "gpioWaveAddSerial: gpio %d, no permission to update", p[1]);
02396             res = PI_NOT_PERMITTED;
02397          }
02398          break;
02399 
02400       case PI_CMD_WVBSY: res = gpioWaveTxBusy(); break;
02401 
02402       case PI_CMD_WVCHA:
02403          if (p[3] > bufSize) p[3] = bufSize;
02404          res = gpioWaveChain(buf, p[3]);
02405          break;
02406 
02407 
02408       case PI_CMD_WVCLR: res = gpioWaveClear(); break;
02409 
02410       case PI_CMD_WVCRE: res = gpioWaveCreate(); break;
02411 
02412       case PI_CMD_WVDEL: res = gpioWaveDelete(p[1]); break;
02413 
02414       case PI_CMD_WVGO:  res = gpioWaveTxStart(PI_WAVE_MODE_ONE_SHOT); break;
02415 
02416       case PI_CMD_WVGOR: res = gpioWaveTxStart(PI_WAVE_MODE_REPEAT); break;
02417 
02418       case PI_CMD_WVHLT: res = gpioWaveTxStop(); break;
02419 
02420       case PI_CMD_WVNEW: res = gpioWaveAddNew(); break;
02421 
02422       case PI_CMD_WVSC:
02423          switch(p[1])
02424          {
02425             case 0: res = gpioWaveGetCbs();     break;
02426             case 1: res = gpioWaveGetHighCbs(); break;
02427             case 2: res = gpioWaveGetMaxCbs();  break;
02428             default: res = PI_BAD_WVSC_COMMND;
02429          }
02430          break;
02431 
02432       case PI_CMD_WVSM:
02433          switch(p[1])
02434          {
02435             case 0: res = gpioWaveGetMicros();     break;
02436             case 1: res = gpioWaveGetHighMicros(); break;
02437             case 2: res = gpioWaveGetMaxMicros();  break;
02438             default: res = PI_BAD_WVSM_COMMND;
02439          }
02440          break;
02441 
02442       case PI_CMD_WVSP:
02443          switch(p[1])
02444          {
02445             case 0: res = gpioWaveGetPulses();     break;
02446             case 1: res = gpioWaveGetHighPulses(); break;
02447             case 2: res = gpioWaveGetMaxPulses();  break;
02448             default: res = PI_BAD_WVSP_COMMND;
02449          }
02450          break;
02451 
02452       case PI_CMD_WVTAT: res = gpioWaveTxAt(); break;
02453 
02454       case PI_CMD_WVTX:
02455          res = gpioWaveTxSend(p[1], PI_WAVE_MODE_ONE_SHOT); break;
02456 
02457       case PI_CMD_WVTXM:
02458          res = gpioWaveTxSend(p[1], p[2]); break;
02459 
02460       case PI_CMD_WVTXR:
02461          res = gpioWaveTxSend(p[1], PI_WAVE_MODE_REPEAT); break;
02462 
02463       default:
02464          res = PI_UNKNOWN_COMMAND;
02465          break;
02466    }
02467 
02468    return res;
02469 }
02470 
02471 /* ----------------------------------------------------------------------- */
02472 
02473 static void mySetGpioOff(unsigned gpio, int pos)
02474 {
02475    int page, slot;
02476 
02477    myOffPageSlot(pos, &page, &slot);
02478 
02479    dmaIVirt[page]->gpioOff[slot] |= (1<<gpio);
02480 }
02481 
02482 /* ----------------------------------------------------------------------- */
02483 
02484 static void myClearGpioOff(unsigned gpio, int pos)
02485 {
02486    int page, slot;
02487 
02488    myOffPageSlot(pos, &page, &slot);
02489 
02490    dmaIVirt[page]->gpioOff[slot] &= ~(1<<gpio);
02491 }
02492 
02493 /* ----------------------------------------------------------------------- */
02494 
02495 static void mySetGpioOn(unsigned gpio, int pos)
02496 {
02497    int page, slot;
02498 
02499    page = pos/ON_PER_IPAGE;
02500    slot = pos%ON_PER_IPAGE;
02501 
02502    dmaIVirt[page]->gpioOn[slot] |= (1<<gpio);
02503 }
02504 
02505 /* ----------------------------------------------------------------------- */
02506 
02507 static void myClearGpioOn(unsigned gpio, int pos)
02508 {
02509    int page, slot;
02510 
02511    page = pos/ON_PER_IPAGE;
02512    slot = pos%ON_PER_IPAGE;
02513 
02514    dmaIVirt[page]->gpioOn[slot] &= ~(1<<gpio);
02515 }
02516 
02517 /* ----------------------------------------------------------------------- */
02518 
02519 static void myGpioSetPwm(unsigned gpio, int oldVal, int newVal)
02520 {
02521    int switchGpioOff;
02522    int newOff, oldOff, realRange, cycles, i;
02523    int deferOff, deferRng;
02524 
02525    DBG(DBG_INTERNAL,
02526       "myGpioSetPwm %d from %d to %d", gpio, oldVal, newVal);
02527 
02528    switchGpioOff = 0;
02529 
02530    realRange = pwmRealRange[gpioInfo[gpio].freqIdx];
02531 
02532    cycles    = pwmCycles   [gpioInfo[gpio].freqIdx];
02533 
02534    newOff = (newVal * realRange)/gpioInfo[gpio].range;
02535    oldOff = (oldVal * realRange)/gpioInfo[gpio].range;
02536 
02537    deferOff = gpioInfo[gpio].deferOff;
02538    deferRng = gpioInfo[gpio].deferRng;
02539 
02540    if (gpioInfo[gpio].deferOff)
02541    {
02542       for (i=0; i<SUPERLEVEL; i+=deferRng)
02543       {
02544          myClearGpioOff(gpio, i+deferOff);
02545       }
02546       gpioInfo[gpio].deferOff = 0;
02547    }
02548 
02549    if (newOff != oldOff)
02550    {
02551       if (newOff && oldOff)                      /* PWM CHANGE */
02552       {
02553          if (newOff != realRange)
02554          {
02555             for (i=0; i<SUPERLEVEL; i+=realRange) mySetGpioOff(gpio, i+newOff);
02556          }
02557 
02558          if (newOff > oldOff)
02559          {
02560             for (i=0; i<SUPERLEVEL; i+=realRange)
02561                myClearGpioOff(gpio, i+oldOff);
02562          }
02563          else
02564          {
02565             gpioInfo[gpio].deferOff = oldOff;
02566             gpioInfo[gpio].deferRng = realRange;
02567          }
02568       }
02569       else if (newOff)                           /* PWM START */
02570       {
02571          if (newOff != realRange)
02572          {
02573             for (i=0; i<SUPERLEVEL; i+=realRange) mySetGpioOff(gpio, i+newOff);
02574          }
02575 
02576          /* schedule new gpio on */
02577 
02578          for (i=0; i<SUPERCYCLE; i+=cycles) mySetGpioOn(gpio, i);
02579       }
02580       else                                       /* PWM STOP */
02581       {
02582          /* deschedule gpio on */
02583 
02584          for (i=0; i<SUPERCYCLE; i+=cycles)
02585             myClearGpioOn(gpio, i);
02586 
02587          for (i=0; i<SUPERLEVEL; i+=realRange)
02588             myClearGpioOff(gpio, i+oldOff);
02589 
02590          switchGpioOff = 1;
02591       }
02592 
02593       if (switchGpioOff)
02594       {
02595          *(gpioReg + GPCLR0) = (1<<gpio);
02596          *(gpioReg + GPCLR0) = (1<<gpio);
02597       }
02598    }
02599 }
02600 
02601 /* ----------------------------------------------------------------------- */
02602 
02603 static void myGpioSetServo(unsigned gpio, int oldVal, int newVal)
02604 {
02605    int newOff, oldOff, realRange, cycles, i;
02606    int deferOff, deferRng;
02607 
02608    DBG(DBG_INTERNAL,
02609       "myGpioSetServo %d from %d to %d", gpio, oldVal, newVal);
02610 
02611    realRange = pwmRealRange[clkCfg[gpioCfg.clockMicros].servoIdx];
02612    cycles    = pwmCycles   [clkCfg[gpioCfg.clockMicros].servoIdx];
02613 
02614    newOff = (newVal * realRange)/20000;
02615    oldOff = (oldVal * realRange)/20000;
02616 
02617    deferOff = gpioInfo[gpio].deferOff;
02618    deferRng = gpioInfo[gpio].deferRng;
02619 
02620    if (gpioInfo[gpio].deferOff)
02621    {
02622       for (i=0; i<SUPERLEVEL; i+=deferRng)
02623       {
02624          myClearGpioOff(gpio, i+deferOff);
02625       }
02626       gpioInfo[gpio].deferOff = 0;
02627    }
02628 
02629    if (newOff != oldOff)
02630    {
02631       if (newOff && oldOff)                       /* SERVO CHANGE */
02632       {
02633          for (i=0; i<SUPERLEVEL; i+=realRange)
02634             mySetGpioOff(gpio, i+newOff);
02635 
02636          if (newOff > oldOff)
02637          {
02638             for (i=0; i<SUPERLEVEL; i+=realRange)
02639                myClearGpioOff(gpio, i+oldOff);
02640          }
02641          else
02642          {
02643             gpioInfo[gpio].deferOff = oldOff;
02644             gpioInfo[gpio].deferRng = realRange;
02645          }
02646       }
02647       else if (newOff)                            /* SERVO START */
02648       {
02649          for (i=0; i<SUPERLEVEL; i+=realRange)
02650             mySetGpioOff(gpio, i+newOff);
02651 
02652          /* schedule new gpio on */
02653 
02654          for (i=0; i<SUPERCYCLE; i+=cycles) mySetGpioOn(gpio, i);
02655       }
02656       else                                        /* SERVO STOP */
02657       {
02658          /* deschedule gpio on */
02659 
02660          for (i=0; i<SUPERCYCLE; i+=cycles)
02661             myClearGpioOn(gpio, i);
02662 
02663          /* if in pulse then delay for the last cycle to complete */
02664 
02665          if (myGpioRead(gpio)) myGpioDelay(PI_MAX_SERVO_PULSEWIDTH);
02666 
02667          /* deschedule gpio off */
02668 
02669          for (i=0; i<SUPERLEVEL; i+=realRange)
02670             myClearGpioOff(gpio, i+oldOff);
02671       }
02672    }
02673 }
02674 
02675 /* ======================================================================= */
02676 
02677 /*
02678 https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
02679 */
02680 
02681 static int mbCreate(char *dev)
02682 {
02683    /* <0 error */
02684 
02685    unlink(dev);
02686 
02687    return mknod(dev, S_IFCHR|0600, makedev(MB_DEV_MAJOR, 0));
02688 }
02689 
02690 static int mbOpen(void)
02691 {
02692    /* <0 error */
02693 
02694    int fd;
02695 
02696    fd = open(MB_DEV1, 0);
02697 
02698    if (fd < 0)
02699    {
02700       mbCreate(MB_DEV2);
02701       fd = open(MB_DEV2, 0);
02702    }
02703    return fd;
02704 }
02705 
02706 static void mbClose(int fd)
02707 {
02708    close(fd);
02709 }
02710 
02711 static int mbProperty(int fd, void *buf)
02712 {
02713    return ioctl(fd, MB_IOCTL, buf);
02714 }
02715 
02716 static unsigned mbAllocateMemory(
02717    int fd, unsigned size, unsigned align, unsigned flags)
02718 {
02719    int i=1;
02720    unsigned p[32];
02721 
02722    p[i++] = MB_PROCESS_REQUEST;
02723    p[i++] = MB_ALLOCATE_MEMORY_TAG;
02724    p[i++] = 12;
02725    p[i++] = 12;
02726    p[i++] = size;
02727    p[i++] = align;
02728    p[i++] = flags;
02729    p[i++] = MB_END_TAG;
02730    p[0] = i*sizeof(*p);
02731 
02732    mbProperty(fd, p);
02733 
02734    return p[5];
02735 }
02736 
02737 static unsigned mbLockMemory(int fd, unsigned handle)
02738 {
02739    int i=1;
02740    unsigned p[32];
02741 
02742    p[i++] = MB_PROCESS_REQUEST;
02743    p[i++] = MB_LOCK_MEMORY_TAG;
02744    p[i++] = 4;
02745    p[i++] = 4;
02746    p[i++] = handle;
02747    p[i++] = MB_END_TAG;
02748    p[0] = i*sizeof(*p);
02749 
02750    mbProperty(fd, p);
02751 
02752    return p[5];
02753 }
02754 
02755 static unsigned mbUnlockMemory(int fd, unsigned handle)
02756 {
02757    int i=1;
02758    unsigned p[32];
02759 
02760    p[i++] = MB_PROCESS_REQUEST;
02761    p[i++] = MB_UNLOCK_MEMORY_TAG;
02762    p[i++] = 4;
02763    p[i++] = 4;
02764    p[i++] = handle;
02765    p[i++] = MB_END_TAG;
02766    p[0] = i*sizeof(*p);
02767 
02768    mbProperty(fd, p);
02769 
02770    return p[5];
02771 }
02772 
02773 static unsigned mbReleaseMemory(int fd, unsigned handle)
02774 {
02775    int i=1;
02776    unsigned p[32];
02777 
02778    p[i++] = MB_PROCESS_REQUEST;
02779    p[i++] = MB_RELEASE_MEMORY_TAG;
02780    p[i++] = 4;
02781    p[i++] = 4;
02782    p[i++] = handle;
02783    p[i++] = MB_END_TAG;
02784    p[0] = i*sizeof(*p);
02785 
02786    mbProperty(fd, p);
02787 
02788    return p[5];
02789 }
02790 
02791 static void *mbMapMem(unsigned base, unsigned size)
02792 {
02793    void *mem = MAP_FAILED;
02794 
02795    mem = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fdMem, base);
02796 
02797    return mem;
02798 }
02799 
02800 static int mbUnmapMem(void *addr, unsigned size)
02801 {
02802    /* 0 okay, -1 fail */
02803    return munmap(addr, size);
02804 }
02805 
02806 static void mbDMAFree(DMAMem_t *DMAMemP)
02807 {
02808    if (DMAMemP->handle)
02809    {
02810       mbUnmapMem(DMAMemP->virtual_addr, DMAMemP->size);
02811       mbUnlockMemory(fdMbox, DMAMemP->handle);
02812       mbReleaseMemory(fdMbox, DMAMemP->handle);
02813       DMAMemP->handle = 0;
02814    }
02815 }
02816 
02817 static int mbDMAAlloc(DMAMem_t *DMAMemP, unsigned size, uint32_t pi_mem_flag)
02818 {
02819    DMAMemP->size = size;
02820 
02821    DMAMemP->handle =
02822       mbAllocateMemory(fdMbox, size, PAGE_SIZE, pi_mem_flag);
02823 
02824    if (DMAMemP->handle)
02825    {
02826       DMAMemP->bus_addr = mbLockMemory(fdMbox, DMAMemP->handle);
02827 
02828       DMAMemP->virtual_addr =
02829          mbMapMem(BUS_TO_PHYS(DMAMemP->bus_addr), size);
02830 
02831       return 1;
02832    }
02833    return 0;
02834 }
02835 
02836 
02837 /* ======================================================================= */
02838 
02839 rawCbs_t * rawWaveCBAdr(int cbNum)
02840 {
02841    int page, slot;
02842 
02843    page = cbNum/CBS_PER_OPAGE;
02844    slot = cbNum%CBS_PER_OPAGE;
02845 
02846    return &dmaOVirt[page]->cb[slot];
02847 }
02848 
02849 
02850 /* ----------------------------------------------------------------------- */
02851 
02852 static uint32_t waveCbPOadr(int pos)
02853 {
02854    int page, slot;
02855 
02856    page = pos/CBS_PER_OPAGE;
02857    slot = pos%CBS_PER_OPAGE;
02858 
02859    return (uint32_t) &dmaOBus[page]->cb[slot];
02860 }
02861 
02862 /* ----------------------------------------------------------------------- */
02863 
02864 static void waveOOLPageSlot(int pos, int *page, int *slot)
02865 {
02866    *page = pos/OOL_PER_OPAGE;
02867    *slot = pos%OOL_PER_OPAGE;
02868 }
02869 
02870 
02871 /* ----------------------------------------------------------------------- */
02872 
02873 static void waveSetOOL(int pos, uint32_t OOL)
02874 {
02875    int page, slot;
02876 
02877    waveOOLPageSlot(pos, &page, &slot);
02878 
02879    dmaOVirt[page]->OOL[slot] = OOL;
02880 }
02881 
02882 /* ----------------------------------------------------------------------- */
02883 
02884 static uint32_t waveOOLPOadr(int pos)
02885 {
02886    int page, slot;
02887 
02888    waveOOLPageSlot(pos, &page, &slot);
02889 
02890    return (uint32_t) &dmaOBus[page]->OOL[slot];
02891 }
02892 
02893 
02894 /* ----------------------------------------------------------------------- */
02895 
02896 static void waveBitDelay
02897    (unsigned baud, unsigned bits, unsigned stops, unsigned *bitDelay)
02898 {
02899    unsigned fullBit, last, diff, t, i;
02900 
02901    /* scaled 1000X */
02902 
02903    fullBit = 1000000000 / baud;
02904    last = 0;
02905 
02906    for (i=0; i<=bits; i++)
02907    {
02908       t = (((i+1)*fullBit)+500)/1000;
02909       diff = t - last;
02910       last = t;
02911       bitDelay[i] = diff;
02912    }
02913 
02914    t = (((bits+1)*fullBit) + ((stops*fullBit)/2) + 500)/1000;
02915    diff = t - last;
02916    bitDelay[i] = diff;
02917 }
02918 
02919 static int waveDelayCBs(uint32_t delay)
02920 {
02921    uint32_t cbs;
02922 
02923    if (!delay) return 0;
02924    if (gpioCfg.DMAsecondaryChannel < DMA_LITE_FIRST) return 1;
02925    cbs = BPD * delay / DMA_LITE_MAX;
02926    if  ((BPD * delay) % DMA_LITE_MAX) cbs++;
02927    return cbs;
02928 }
02929 
02930 /* ----------------------------------------------------------------------- */
02931 
02932 static void waveCBsOOLs(int *numCBs, int *numBOOLs, int *numTOOLs)
02933 {
02934    int numCB=0, numBOOL=0, numTOOL=0;
02935 
02936    unsigned i;
02937 
02938    unsigned numWaves;
02939 
02940    rawWave_t *waves;
02941 
02942    numWaves = wfc[wfcur];
02943    waves    = wf [wfcur];
02944 
02945    /* delay cb at start of DMA */
02946 
02947    numCB++;
02948 
02949    for (i=0; i<numWaves; i++)
02950    {
02951       if (waves[i].gpioOn)                 {numCB++; numBOOL++;}
02952       if (waves[i].gpioOff)                {numCB++; numBOOL++;}
02953       if (waves[i].flags & WAVE_FLAG_READ) {numCB++; numTOOL++;}
02954       if (waves[i].flags & WAVE_FLAG_TICK) {numCB++; numTOOL++;}
02955 
02956       numCB += waveDelayCBs(waves[i].usDelay);
02957    }
02958 
02959    *numCBs   = numCB;
02960    *numBOOLs = numBOOL;
02961    *numTOOLs = numTOOL;
02962 }
02963 
02964 /* ----------------------------------------------------------------------- */
02965 
02966 static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL)
02967 {
02968    int botCB=*CB, botOOL=*BOOL, topOOL=*TOOL;
02969 
02970    int status;
02971 
02972    rawCbs_t *p=NULL;
02973 
02974    unsigned i, repeatCB;
02975 
02976    unsigned numWaves;
02977 
02978    unsigned delayCBs, dcb;
02979 
02980    uint32_t delayLeft;
02981 
02982    rawWave_t * waves;
02983 
02984    numWaves = wfc[wfcur];
02985    waves    = wf [wfcur];
02986 
02987    /* add delay cb at start of DMA */
02988 
02989    p = rawWaveCBAdr(botCB++);
02990 
02991    /* use the secondary clock */
02992 
02993    if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
02994    {
02995       p->info = NORMAL_DMA | TIMED_DMA(2);
02996       p->dst  = PCM_TIMER;
02997    }
02998    else
02999    {
03000       p->info = NORMAL_DMA | TIMED_DMA(5);
03001       p->dst  = PWM_TIMER;
03002    }
03003 
03004    p->src    = (uint32_t) (&dmaOBus[0]->periphData);
03005    p->length = BPD * 20 / PI_WF_MICROS; /* 20 micros delay */
03006    p->next   = waveCbPOadr(botCB);
03007 
03008    repeatCB = botCB;
03009 
03010    for (i=0; i<numWaves; i++)
03011    {
03012       if (waves[i].gpioOn)
03013       {
03014          waveSetOOL(botOOL, waves[i].gpioOn);
03015 
03016          p = rawWaveCBAdr(botCB++);
03017 
03018          p->info   = NORMAL_DMA;
03019          p->src    = waveOOLPOadr(botOOL++);
03020          p->dst    = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_BUS;
03021          p->length = 4;
03022          p->next   = waveCbPOadr(botCB);
03023       }
03024 
03025       if (waves[i].gpioOff)
03026       {
03027          waveSetOOL(botOOL, waves[i].gpioOff);
03028 
03029          p = rawWaveCBAdr(botCB++);
03030 
03031          p->info   = NORMAL_DMA;
03032          p->src    = waveOOLPOadr(botOOL++);
03033          p->dst    = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_BUS;
03034          p->length = 4;
03035          p->next   = waveCbPOadr(botCB);
03036       }
03037 
03038       if (waves[i].flags & WAVE_FLAG_READ)
03039       {
03040          p = rawWaveCBAdr(botCB++);
03041 
03042          p->info   = NORMAL_DMA;
03043          p->src    = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_BUS;
03044          p->dst    = waveOOLPOadr(--topOOL);
03045          p->length = 4;
03046          p->next   = waveCbPOadr(botCB);
03047       }
03048 
03049       if (waves[i].flags & WAVE_FLAG_TICK)
03050       {
03051          p = rawWaveCBAdr(botCB++);
03052 
03053          p->info   = NORMAL_DMA;
03054          p->src    = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_BUS;
03055          p->dst    = waveOOLPOadr(--topOOL);
03056          p->length = 4;
03057          p->next   = waveCbPOadr(botCB);
03058       }
03059 
03060       if (waves[i].usDelay)
03061       {
03062          delayLeft = waves[i].usDelay;
03063 
03064          delayCBs = waveDelayCBs(delayLeft);
03065 
03066          for (dcb=0; dcb<delayCBs; dcb++)
03067          {
03068             p = rawWaveCBAdr(botCB++);
03069 
03070             /* use the secondary clock */
03071 
03072             if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
03073             {
03074                p->info = NORMAL_DMA | TIMED_DMA(2);
03075                p->dst  = PCM_TIMER;
03076             }
03077             else
03078             {
03079                p->info = NORMAL_DMA | TIMED_DMA(5);
03080                p->dst  = PWM_TIMER;
03081             }
03082 
03083             p->src = (uint32_t) (&dmaOBus[0]->periphData);
03084 
03085             p->length = BPD * delayLeft / PI_WF_MICROS;
03086 
03087             if ((gpioCfg.DMAsecondaryChannel >= DMA_LITE_FIRST) &&
03088                 (p->length > DMA_LITE_MAX))
03089             {
03090                p->length = DMA_LITE_MAX;
03091             }
03092 
03093             delayLeft -= (p->length / BPD);
03094 
03095             p->next = waveCbPOadr(botCB);
03096          }
03097       }
03098    }
03099 
03100    if (p != NULL)
03101    {
03102       if (wave_mode == PI_WAVE_MODE_ONE_SHOT)
03103            p->next = 0;
03104       else p->next = waveCbPOadr(repeatCB);
03105    }
03106 
03107    status = botCB - *CB;
03108 
03109    *CB   = botCB;
03110    *BOOL = botOOL;
03111    *TOOL = topOOL;
03112 
03113    return status;
03114 }
03115 
03116 /* ----------------------------------------------------------------------- */
03117 
03118 static void waveRxSerial(wfRx_t *w, int level, uint32_t tick)
03119 {
03120    int diffTicks, lastLevel;
03121    int newWritePos;
03122 
03123    level = level ^ w->s.invert;
03124 
03125    if (w->s.bit >= 0)
03126    {
03127       diffTicks = tick - w->s.startBitTick;
03128 
03129       if (level != PI_TIMEOUT)
03130       {
03131          w->s.level = level;
03132          lastLevel = !level;
03133       }
03134       else lastLevel = w->s.level;
03135 
03136       while ((w->s.bit <= w->s.dataBits) &&
03137              (diffTicks > (w->s.nextBitDiff/1000)))
03138       {
03139          if (w->s.bit)
03140          {
03141             if (lastLevel) w->s.data |= (1<<(w->s.bit-1));
03142          }
03143          else w->s.data = 0;
03144 
03145          ++(w->s.bit);
03146 
03147          w->s.nextBitDiff += w->s.fullBit;
03148       }
03149 
03150       if (w->s.bit > w->s.dataBits)
03151       {
03152          memcpy(w->s.buf + w->s.writePos, &w->s.data, w->s.bytes);
03153 
03154          /* don't let writePos catch readPos */
03155 
03156          newWritePos = (w->s.writePos + w->s.bytes) % (w->s.bufSize);
03157 
03158          if (newWritePos != w->s.readPos) w->s.writePos = newWritePos;
03159 
03160          if (level == 0)
03161          {
03162             gpioSetWatchdog(w->gpio, w->s.timeout);
03163             w->s.bit          = 0;
03164             w->s.startBitTick = tick;
03165             w->s.nextBitDiff  = w->s.halfBit;
03166          }
03167          else
03168          {
03169             w->s.bit = -1;
03170             gpioSetWatchdog(w->gpio, 0);
03171          }
03172       }
03173    }
03174    else
03175    {
03176       /* start bit if high->low */
03177 
03178       if (level == 0)
03179       {
03180          gpioSetWatchdog(w->gpio, w->s.timeout);
03181          w->s.level        = 0;
03182          w->s.bit          = 0;
03183          w->s.startBitTick = tick;
03184          w->s.nextBitDiff  = w->s.halfBit;
03185       }
03186    }
03187 }
03188 
03189 
03190 /* ----------------------------------------------------------------------- */
03191 
03192 static void waveRxBit(int gpio, int level, uint32_t tick)
03193 {
03194    switch (wfRx[gpio].mode)
03195    {
03196       case PI_WFRX_SERIAL:
03197          waveRxSerial(&wfRx[gpio], level, tick);
03198    }
03199 }
03200 
03201 
03202 /* ----------------------------------------------------------------------- */
03203 
03204 int rawWaveAddGeneric(unsigned numIn1, rawWave_t *in1)
03205 {
03206    unsigned inPos1=0, inPos2=0, outPos=0, level = NUM_WAVE_OOL;
03207 
03208    unsigned cbs=0;
03209 
03210    unsigned numIn2, numOut;
03211 
03212    uint32_t tNow, tNext1, tNext2, tDelay;
03213 
03214    rawWave_t *in2, *out;
03215 
03216    numIn2 = wfc[wfcur];
03217    in2    = wf[wfcur];
03218 
03219    numOut = PI_WAVE_MAX_PULSES;
03220    out   = wf[1-wfcur];
03221 
03222    tNow = 0;
03223 
03224    if (!numIn1) tNext1 = -1; else tNext1 = 0;
03225    if (!numIn2) tNext2 = -1; else tNext2 = 0;
03226 
03227    while (((inPos1<numIn1) || (inPos2<numIn2)) && (outPos<numOut))
03228    {
03229       if (tNext1 < tNext2)
03230       {
03231          /* pulse 1 due */
03232 
03233          if (tNow < tNext1)
03234          {
03235             /* extend previous delay */
03236             out[outPos-1].usDelay += (tNext1 - tNow);
03237             tNow = tNext1;
03238          }
03239 
03240          out[outPos].gpioOn  = in1[inPos1].gpioOn;
03241          out[outPos].gpioOff = in1[inPos1].gpioOff;
03242          out[outPos].flags   = in1[inPos1].flags;
03243 
03244          tNext1 = tNow + in1[inPos1].usDelay; ++inPos1;
03245       }
03246       else if (tNext2 < tNext1)
03247       {
03248          /* pulse 2 due */
03249 
03250          if (tNow < tNext2)
03251          {
03252             /* extend previous delay */
03253             out[outPos-1].usDelay += (tNext2 - tNow);
03254             tNow = tNext2;
03255          }
03256 
03257          out[outPos].gpioOn  = in2[inPos2].gpioOn;
03258          out[outPos].gpioOff = in2[inPos2].gpioOff;
03259          out[outPos].flags   = in2[inPos2].flags;
03260 
03261          tNext2 = tNow + in2[inPos2].usDelay; ++inPos2;
03262       }
03263       else
03264       {
03265          /* pulse 1 and 2 both due */
03266 
03267          if (tNow < tNext1)
03268          {
03269             /* extend previous delay */
03270             out[outPos-1].usDelay += (tNext1 - tNow);
03271             tNow = tNext1;
03272          }
03273 
03274          out[outPos].gpioOn  = in1[inPos1].gpioOn  | in2[inPos2].gpioOn;
03275          out[outPos].gpioOff = in1[inPos1].gpioOff | in2[inPos2].gpioOff;
03276          out[outPos].flags   = in1[inPos1].flags   | in2[inPos2].flags;
03277 
03278          tNext1 = tNow + in1[inPos1].usDelay; ++inPos1;
03279          tNext2 = tNow + in2[inPos2].usDelay; ++inPos2;
03280       }
03281 
03282       if (tNext1 <= tNext2) { tDelay = tNext1 - tNow; tNow = tNext1; }
03283       else                  { tDelay = tNext2 - tNow; tNow = tNext2; }
03284 
03285       out[outPos].usDelay = tDelay;
03286 
03287       cbs += waveDelayCBs(tDelay);
03288 
03289       if (out[outPos].gpioOn) cbs++; /* one cb if gpio on */
03290 
03291       if (out[outPos].gpioOff) cbs++; /* one cb if gpio off */
03292 
03293       if (out[outPos].flags & WAVE_FLAG_READ)
03294       {
03295          cbs++; /* one cb if read */
03296          --level;
03297       }
03298 
03299       if (out[outPos].flags & WAVE_FLAG_TICK)
03300       {
03301          cbs++; /* one cb if tick */
03302          --level;
03303       }
03304 
03305       outPos++;
03306 
03307       if (inPos1 >= numIn1) tNext1 = -1;
03308       if (inPos2 >= numIn2) tNext2 = -1;
03309 
03310    }
03311 
03312    if ((outPos < numOut) && (outPos < level))
03313    {
03314       wfStats.micros = tNow;
03315 
03316       if (tNow > wfStats.highMicros) wfStats.highMicros = tNow;
03317 
03318       wfStats.pulses = outPos;
03319 
03320       if (outPos > wfStats.highPulses) wfStats.highPulses = outPos;
03321 
03322       wfStats.cbs    = cbs;
03323 
03324       if (cbs > wfStats.highCbs) wfStats.highCbs = cbs;
03325 
03326       wfc[1-wfcur] = outPos;
03327       wfcur = 1 - wfcur;
03328 
03329       return outPos;
03330    }
03331    else return PI_TOO_MANY_PULSES;
03332 }
03333 
03334 /* ======================================================================= */
03335 
03336 int i2cWriteQuick(unsigned handle, unsigned bit)
03337 {
03338    int status;
03339 
03340    DBG(DBG_USER, "handle=%d bit=%d", handle, bit);
03341 
03342    CHECK_INITED;
03343 
03344    if (handle >= PI_I2C_SLOTS)
03345       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03346 
03347    if (i2cInfo[handle].state != PI_I2C_OPENED)
03348       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03349 
03350    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_QUICK) == 0)
03351       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03352 
03353    if (bit > 1)
03354       SOFT_ERROR(PI_BAD_PARAM, "bad bit (%d)", bit);
03355 
03356    status = my_smbus_access(
03357       i2cInfo[handle].fd, bit, 0, PI_I2C_SMBUS_QUICK, NULL);
03358 
03359    if (status < 0)
03360    {
03361       DBG(DBG_USER, "error=%d (%m)", status);
03362       return PI_I2C_WRITE_FAILED;
03363    }
03364 
03365    return status;
03366 }
03367 
03368 int i2cReadByte(unsigned handle)
03369 {
03370    union my_smbus_data data;
03371    int status;
03372 
03373    DBG(DBG_USER, "handle=%d", handle);
03374 
03375    CHECK_INITED;
03376 
03377    if (handle >= PI_I2C_SLOTS)
03378       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03379 
03380    if (i2cInfo[handle].state != PI_I2C_OPENED)
03381       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03382 
03383    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE) == 0)
03384       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03385 
03386    status = my_smbus_access(
03387       i2cInfo[handle].fd, PI_I2C_SMBUS_READ, 0, PI_I2C_SMBUS_BYTE, &data);
03388 
03389    if (status < 0)
03390    {
03391       DBG(DBG_USER, "error=%d (%m)", status);
03392       return PI_I2C_READ_FAILED;
03393    }
03394 
03395    return 0xFF & data.byte;
03396 }
03397 
03398 
03399 int i2cWriteByte(unsigned handle, unsigned bVal)
03400 {
03401    int status;
03402 
03403    DBG(DBG_USER, "handle=%d bVal=%d", handle, bVal);
03404 
03405    CHECK_INITED;
03406 
03407    if (handle >= PI_I2C_SLOTS)
03408       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03409 
03410    if (i2cInfo[handle].state != PI_I2C_OPENED)
03411       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03412 
03413    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE) == 0)
03414       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03415 
03416    if (bVal > 0xFF)
03417       SOFT_ERROR(PI_BAD_PARAM, "bad bVal (%d)", bVal);
03418 
03419    status = my_smbus_access(
03420             i2cInfo[handle].fd,
03421             PI_I2C_SMBUS_WRITE,
03422             bVal,
03423             PI_I2C_SMBUS_BYTE,
03424             NULL);
03425 
03426    if (status < 0)
03427    {
03428       DBG(DBG_USER, "error=%d (%m)", status);
03429       return PI_I2C_WRITE_FAILED;
03430    }
03431 
03432    return status;
03433 }
03434 
03435 
03436 int i2cReadByteData(unsigned handle, unsigned reg)
03437 {
03438    union my_smbus_data data;
03439    int status;
03440 
03441    DBG(DBG_USER, "handle=%d reg=%d", handle, reg);
03442 
03443    CHECK_INITED;
03444 
03445    if (handle >= PI_I2C_SLOTS)
03446       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03447 
03448    if (i2cInfo[handle].state != PI_I2C_OPENED)
03449       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03450 
03451    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0)
03452       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03453 
03454    if (reg > 0xFF)
03455       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03456 
03457    status = my_smbus_access(i2cInfo[handle].fd,
03458             PI_I2C_SMBUS_READ, reg, PI_I2C_SMBUS_BYTE_DATA, &data);
03459 
03460    if (status < 0)
03461    {
03462       DBG(DBG_USER, "error=%d (%m)", status);
03463       return PI_I2C_READ_FAILED;
03464    }
03465 
03466    return 0xFF & data.byte;
03467 }
03468 
03469 
03470 int i2cWriteByteData(unsigned handle, unsigned reg, unsigned bVal)
03471 {
03472    union my_smbus_data data;
03473 
03474    int status;
03475 
03476    DBG(DBG_USER, "handle=%d reg=%d bVal=%d", handle, reg, bVal);
03477 
03478    CHECK_INITED;
03479 
03480    if (handle >= PI_I2C_SLOTS)
03481       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03482 
03483    if (i2cInfo[handle].state != PI_I2C_OPENED)
03484       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03485 
03486    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA) == 0)
03487       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03488 
03489    if (reg > 0xFF)
03490       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03491 
03492    if (bVal > 0xFF)
03493       SOFT_ERROR(PI_BAD_PARAM, "bad bVal (%d)", bVal);
03494 
03495    data.byte = bVal;
03496 
03497    status = my_smbus_access(
03498             i2cInfo[handle].fd,
03499             PI_I2C_SMBUS_WRITE,
03500             reg,
03501             PI_I2C_SMBUS_BYTE_DATA,
03502             &data);
03503 
03504    if (status < 0)
03505    {
03506       DBG(DBG_USER, "error=%d (%m)", status);
03507       return PI_I2C_WRITE_FAILED;
03508    }
03509 
03510    return status;
03511 }
03512 
03513 
03514 int i2cReadWordData(unsigned handle, unsigned reg)
03515 {
03516    union my_smbus_data data;
03517    int status;
03518 
03519    DBG(DBG_USER, "handle=%d reg=%d", handle, reg);
03520 
03521    CHECK_INITED;
03522 
03523    if (handle >= PI_I2C_SLOTS)
03524       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03525 
03526    if (i2cInfo[handle].state != PI_I2C_OPENED)
03527       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03528 
03529    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_WORD_DATA) == 0)
03530       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03531 
03532    if (reg > 0xFF)
03533       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03534 
03535    status = (my_smbus_access(
03536       i2cInfo[handle].fd,
03537       PI_I2C_SMBUS_READ,
03538       reg,
03539       PI_I2C_SMBUS_WORD_DATA,
03540       &data));
03541 
03542    if (status < 0)
03543    {
03544       DBG(DBG_USER, "error=%d (%m)", status);
03545       return PI_I2C_READ_FAILED;
03546    }
03547 
03548    return 0xFFFF & data.word;
03549 }
03550 
03551 
03552 int i2cWriteWordData(unsigned handle, unsigned reg, unsigned wVal)
03553 {
03554    union my_smbus_data data;
03555 
03556    int status;
03557 
03558    DBG(DBG_USER, "handle=%d reg=%d wVal=%d", handle, reg, wVal);
03559 
03560    CHECK_INITED;
03561 
03562    if (handle >= PI_I2C_SLOTS)
03563       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03564 
03565    if (i2cInfo[handle].state != PI_I2C_OPENED)
03566       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03567 
03568    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA) == 0)
03569       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03570 
03571    if (reg > 0xFF)
03572       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03573 
03574    if (wVal > 0xFFFF)
03575       SOFT_ERROR(PI_BAD_PARAM, "bad wVal (%d)", wVal);
03576 
03577    data.word = wVal;
03578 
03579    status = my_smbus_access(
03580             i2cInfo[handle].fd,
03581             PI_I2C_SMBUS_WRITE,
03582             reg,
03583             PI_I2C_SMBUS_WORD_DATA,
03584             &data);
03585 
03586    if (status < 0)
03587    {
03588       DBG(DBG_USER, "error=%d (%m)", status);
03589       return PI_I2C_WRITE_FAILED;
03590    }
03591 
03592    return status;
03593 }
03594 
03595 
03596 int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal)
03597 {
03598    union my_smbus_data data;
03599    int status;
03600 
03601    DBG(DBG_USER, "handle=%d reg=%d wVal=%d", handle, reg, wVal);
03602 
03603    CHECK_INITED;
03604 
03605    if (handle >= PI_I2C_SLOTS)
03606       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03607 
03608    if (i2cInfo[handle].state != PI_I2C_OPENED)
03609       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03610 
03611    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
03612       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03613 
03614    if (reg > 0xFF)
03615       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03616 
03617    if (wVal > 0xFFFF)
03618       SOFT_ERROR(PI_BAD_PARAM, "bad wVal (%d)", wVal);
03619 
03620    data.word = wVal;
03621 
03622    status = (my_smbus_access(
03623       i2cInfo[handle].fd,
03624       PI_I2C_SMBUS_WRITE,
03625       reg, PI_I2C_SMBUS_PROC_CALL,
03626       &data));
03627 
03628    if (status < 0)
03629    {
03630       DBG(DBG_USER, "error=%d (%m)", status);
03631       return PI_I2C_READ_FAILED;
03632    }
03633 
03634    return 0xFFFF & data.word;
03635 }
03636 
03637 
03638 int i2cReadBlockData(unsigned handle, unsigned reg, char *buf)
03639 {
03640    union my_smbus_data data;
03641 
03642    int i, status;
03643 
03644    DBG(DBG_USER, "handle=%d reg=%d buf=%08X", handle, reg, (unsigned)buf);
03645 
03646    CHECK_INITED;
03647 
03648    if (handle >= PI_I2C_SLOTS)
03649       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03650 
03651    if (i2cInfo[handle].state != PI_I2C_OPENED)
03652       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03653 
03654    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA) == 0)
03655       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03656 
03657    if (reg > 0xFF)
03658       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03659 
03660    status = (my_smbus_access(
03661       i2cInfo[handle].fd,
03662       PI_I2C_SMBUS_READ,
03663       reg,
03664       PI_I2C_SMBUS_BLOCK_DATA,
03665       &data));
03666 
03667    if (status < 0)
03668    {
03669       DBG(DBG_USER, "error=%d (%m)", status);
03670       return PI_I2C_READ_FAILED;
03671    }
03672    else
03673    {
03674       if (data.block[0] <= PI_I2C_SMBUS_BLOCK_MAX)
03675       {
03676          for (i=0; i<data.block[0]; i++) buf[i] = data.block[i+1];
03677          return data.block[0];
03678       }
03679       else return PI_I2C_READ_FAILED;
03680    }
03681 }
03682 
03683 
03684 int i2cWriteBlockData(
03685    unsigned handle, unsigned reg, char *buf, unsigned count)
03686 {
03687    union my_smbus_data data;
03688 
03689    int i, status;
03690 
03691    DBG(DBG_USER, "handle=%d reg=%d count=%d [%s]",
03692       handle, reg, count, myBuf2Str(count, buf));
03693 
03694    CHECK_INITED;
03695 
03696    if (handle >= PI_I2C_SLOTS)
03697       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03698 
03699    if (i2cInfo[handle].state != PI_I2C_OPENED)
03700       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03701 
03702    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) == 0)
03703       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03704 
03705    if (reg > 0xFF)
03706       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03707 
03708    if ((count < 1) || (count > 32))
03709       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
03710 
03711    for (i=1; i<=count; i++) data.block[i] = buf[i-1];
03712    data.block[0] = count;
03713 
03714    status = my_smbus_access(
03715             i2cInfo[handle].fd,
03716             PI_I2C_SMBUS_WRITE,
03717             reg,
03718             PI_I2C_SMBUS_BLOCK_DATA,
03719             &data);
03720 
03721    if (status < 0)
03722    {
03723       DBG(DBG_USER, "error=%d (%m)", status);
03724       return PI_I2C_WRITE_FAILED;
03725    }
03726 
03727    return status;
03728 }
03729 
03730 
03731 int i2cBlockProcessCall(
03732    unsigned handle, unsigned reg, char *buf, unsigned count)
03733 {
03734    union my_smbus_data data;
03735 
03736    int i, status;
03737 
03738    DBG(DBG_USER, "handle=%d reg=%d count=%d [%s]",
03739       handle, reg, count, myBuf2Str(count, buf));
03740 
03741    CHECK_INITED;
03742 
03743    if (handle >= PI_I2C_SLOTS)
03744       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03745 
03746    if (i2cInfo[handle].state != PI_I2C_OPENED)
03747       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03748 
03749    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0)
03750       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03751 
03752    if (reg > 0xFF)
03753       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03754 
03755    if ((count < 1) || (count > 32))
03756       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
03757 
03758    for (i=1; i<=count; i++) data.block[i] = buf[i-1];
03759    data.block[0] = count;
03760 
03761    status = (my_smbus_access(
03762       i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg,
03763       PI_I2C_SMBUS_BLOCK_PROC_CALL, &data));
03764 
03765    if (status < 0)
03766    {
03767       DBG(DBG_USER, "error=%d (%m)", status);
03768       return PI_I2C_READ_FAILED;
03769    }
03770    else
03771    {
03772       if (data.block[0] <= PI_I2C_SMBUS_BLOCK_MAX)
03773       {
03774          for (i=0; i<data.block[0]; i++) buf[i] = data.block[i+1];
03775          return data.block[0];
03776       }
03777       else return PI_I2C_READ_FAILED;
03778    }
03779 }
03780 
03781 
03782 int i2cReadI2CBlockData(
03783    unsigned handle, unsigned reg, char *buf, unsigned count)
03784 {
03785    union my_smbus_data data;
03786 
03787    int i, status;
03788    uint32_t size;
03789 
03790    DBG(DBG_USER, "handle=%d reg=%d count=%d buf=%08X",
03791       handle, reg, count, (unsigned)buf);
03792 
03793    CHECK_INITED;
03794 
03795    if (handle >= PI_I2C_SLOTS)
03796       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03797 
03798    if (i2cInfo[handle].state != PI_I2C_OPENED)
03799       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03800 
03801    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK) == 0)
03802       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03803 
03804    if (reg > 0xFF)
03805       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03806 
03807    if ((count < 1) || (count > 32))
03808       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
03809 
03810    if (count == 32)
03811       size = PI_I2C_SMBUS_I2C_BLOCK_BROKEN;
03812    else
03813       size = PI_I2C_SMBUS_I2C_BLOCK_DATA;
03814 
03815    data.block[0] = count;
03816 
03817    status = (my_smbus_access(
03818       i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, size, &data));
03819 
03820    if (status < 0)
03821    {
03822       DBG(DBG_USER, "error=%d (%m)", status);
03823       return PI_I2C_READ_FAILED;
03824    }
03825    else
03826    {
03827       if (data.block[0] <= PI_I2C_SMBUS_I2C_BLOCK_MAX)
03828       {
03829          for (i=0; i<data.block[0]; i++) buf[i] = data.block[i+1];
03830          return data.block[0];
03831       }
03832       else return PI_I2C_READ_FAILED;
03833    }
03834 }
03835 
03836 
03837 int i2cWriteI2CBlockData(
03838    unsigned handle, unsigned reg, char *buf, unsigned count)
03839 {
03840    union my_smbus_data data;
03841 
03842    int i, status;
03843 
03844    DBG(DBG_USER, "handle=%d reg=%d count=%d [%s]",
03845       handle, reg, count, myBuf2Str(count, buf));
03846 
03847    CHECK_INITED;
03848 
03849    if (handle >= PI_I2C_SLOTS)
03850       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03851 
03852    if (i2cInfo[handle].state != PI_I2C_OPENED)
03853       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03854 
03855    if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) == 0)
03856       SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver");
03857 
03858    if (reg > 0xFF)
03859       SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg);
03860 
03861    if ((count < 1) || (count > 32))
03862       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
03863 
03864    for (i=1; i<=count; i++) data.block[i] = buf[i-1];
03865 
03866    data.block[0] = count;
03867 
03868    status = my_smbus_access(
03869             i2cInfo[handle].fd,
03870             PI_I2C_SMBUS_WRITE,
03871             reg,
03872             PI_I2C_SMBUS_I2C_BLOCK_BROKEN,
03873             &data);
03874 
03875    if (status < 0)
03876    {
03877       DBG(DBG_USER, "error=%d (%m)", status);
03878       return PI_I2C_WRITE_FAILED;
03879    }
03880 
03881    return status;
03882 }
03883 
03884 int i2cWriteDevice(unsigned handle, char *buf, unsigned count)
03885 {
03886    int bytes;
03887 
03888    DBG(DBG_USER, "handle=%d count=%d [%s]",
03889       handle, count, myBuf2Str(count, buf));
03890 
03891    CHECK_INITED;
03892 
03893    if (handle >= PI_I2C_SLOTS)
03894       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03895 
03896    if (i2cInfo[handle].state != PI_I2C_OPENED)
03897       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03898 
03899    if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT))
03900       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
03901 
03902    bytes = write(i2cInfo[handle].fd, buf, count);
03903 
03904    if (bytes != count)
03905    {
03906       DBG(DBG_USER, "error=%d (%m)", bytes);
03907       return PI_I2C_WRITE_FAILED;
03908    }
03909 
03910    return 0;
03911 }
03912 
03913 int i2cReadDevice(unsigned handle, char *buf, unsigned count)
03914 {
03915    int bytes;
03916 
03917    DBG(DBG_USER, "handle=%d count=%d buf=%08X",
03918       handle, count, (unsigned)buf);
03919 
03920    CHECK_INITED;
03921 
03922    if (handle >= PI_I2C_SLOTS)
03923       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03924 
03925    if (i2cInfo[handle].state != PI_I2C_OPENED)
03926       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
03927 
03928    if ((count < 1) || (count > PI_MAX_I2C_DEVICE_COUNT))
03929       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
03930 
03931    bytes = read(i2cInfo[handle].fd, buf, count);
03932 
03933    if (bytes != count)
03934    {
03935       DBG(DBG_USER, "error=%d (%m)", bytes);
03936       return PI_I2C_READ_FAILED;
03937    }
03938 
03939    return bytes;
03940 }
03941 
03942 int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
03943 {
03944    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
03945    char dev[32];
03946    int i, slot, fd;
03947    uint32_t funcs;
03948 
03949    DBG(DBG_USER, "i2cBus=%d i2cAddr=%d flags=0x%X",
03950       i2cBus, i2cAddr, i2cFlags);
03951 
03952    CHECK_INITED;
03953 
03954    if (i2cAddr > PI_MAX_I2C_ADDR)
03955       SOFT_ERROR(PI_BAD_I2C_ADDR, "bad I2C address (%d)", i2cAddr);
03956 
03957    if (i2cFlags)
03958       SOFT_ERROR(PI_BAD_FLAGS, "bad flags (0x%X)", i2cFlags);
03959 
03960    slot = -1;
03961 
03962    pthread_mutex_lock(&mutex);
03963 
03964    for (i=0; i<PI_I2C_SLOTS; i++)
03965    {
03966       if (i2cInfo[i].state == PI_I2C_CLOSED)
03967       {
03968          slot = i;
03969          i2cInfo[slot].state = PI_I2C_RESERVED;
03970          break;
03971       }
03972    }
03973 
03974    pthread_mutex_unlock(&mutex);
03975 
03976    if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no I2C handles");
03977 
03978    sprintf(dev, "/dev/i2c-%d", i2cBus);
03979 
03980    if ((fd = open(dev, O_RDWR)) < 0)
03981    {
03982       /* try a modprobe */
03983 
03984       if (system("/sbin/modprobe i2c_dev") == -1) { /* ignore errors */}
03985       if (system("/sbin/modprobe i2c_bcm2835") == -1) { /* ignore errors */}
03986 
03987       myGpioDelay(100000);
03988 
03989       if ((fd = open(dev, O_RDWR)) < 0)
03990       {
03991          i2cInfo[slot].state = PI_I2C_CLOSED;
03992          return PI_BAD_I2C_BUS;
03993       }
03994    }
03995 
03996    if (ioctl(fd, PI_I2C_SLAVE, i2cAddr) < 0)
03997    {
03998       close(fd);
03999       i2cInfo[slot].state = PI_I2C_CLOSED;
04000       return PI_I2C_OPEN_FAILED;
04001    }
04002 
04003    if (ioctl(fd, PI_I2C_FUNCS, &funcs) < 0)
04004    {
04005       funcs = -1; /* assume all smbus commands allowed */
04006    }
04007 
04008    i2cInfo[slot].fd = fd;
04009    i2cInfo[slot].addr = i2cAddr;
04010    i2cInfo[slot].flags = i2cFlags;
04011    i2cInfo[slot].funcs = funcs;
04012    i2cInfo[i].state = PI_I2C_OPENED;
04013 
04014    return slot;
04015 }
04016 
04017 int i2cClose(unsigned handle)
04018 {
04019    DBG(DBG_USER, "handle=%d", handle);
04020 
04021    CHECK_INITED;
04022 
04023    if (handle >= PI_I2C_SLOTS)
04024       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04025 
04026    if (i2cInfo[handle].state != PI_I2C_OPENED)
04027       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04028 
04029    if (i2cInfo[handle].fd >= 0) close(i2cInfo[handle].fd);
04030 
04031    i2cInfo[handle].fd = -1;
04032    i2cInfo[handle].state = PI_I2C_CLOSED;
04033 
04034    return 0;
04035 }
04036 
04037 void i2cSwitchCombined(int setting)
04038 {
04039    int fd;
04040 
04041    DBG(DBG_USER, "setting=%d", setting);
04042 
04043    fd = open(PI_I2C_COMBINED, O_WRONLY);
04044 
04045    if (fd >= 0)
04046    {
04047       if (setting)
04048       {
04049          if (write(fd, "1\n", 2) == -1) { /* ignore errors */ }
04050       }
04051       else
04052       {
04053          if (write(fd, "0\n", 2) == -1) { /* ignore errors */ }
04054       }
04055 
04056       close(fd);
04057    }
04058 }
04059 
04060 int i2cSegments(unsigned handle, pi_i2c_msg_t *segs, unsigned numSegs)
04061 {
04062    int retval;
04063    my_i2c_rdwr_ioctl_data_t rdwr;
04064 
04065    DBG(DBG_USER, "handle=%d", handle);
04066 
04067    CHECK_INITED;
04068 
04069    if (handle >= PI_I2C_SLOTS)
04070       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04071 
04072    if (i2cInfo[handle].state != PI_I2C_OPENED)
04073       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04074 
04075    if (segs == NULL)
04076       SOFT_ERROR(PI_BAD_POINTER, "null segments");
04077 
04078    if (numSegs > PI_I2C_RDRW_IOCTL_MAX_MSGS)
04079       SOFT_ERROR(PI_TOO_MANY_SEGS, "too many segments (%d)", numSegs);
04080 
04081    rdwr.msgs = segs;
04082    rdwr.nmsgs = numSegs;
04083 
04084    retval = ioctl(i2cInfo[handle].fd, PI_I2C_RDWR, &rdwr);
04085 
04086    if (retval >= 0) return retval;
04087    else             return PI_BAD_I2C_SEG;
04088 }
04089 
04090 int i2cZip(
04091    unsigned handle,
04092    char *inBuf, unsigned inLen, char *outBuf, unsigned outLen)
04093 {
04094    int numSegs, inPos, outPos, status, bytes, flags, addr;
04095    int esc, setesc;
04096    pi_i2c_msg_t segs[PI_I2C_RDRW_IOCTL_MAX_MSGS];
04097 
04098    DBG(DBG_USER, "handle=%d inBuf=%s outBuf=%08X len=%d",
04099       handle, myBuf2Str(inLen, (char *)inBuf), (int)outBuf, outLen);
04100 
04101    CHECK_INITED;
04102 
04103    if (handle >= PI_I2C_SLOTS)
04104       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04105 
04106    if (i2cInfo[handle].state != PI_I2C_OPENED)
04107       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04108 
04109    if (!inBuf || !inLen)
04110       SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
04111 
04112    if (!outBuf && outLen)
04113       SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
04114 
04115    numSegs = 0;
04116 
04117    inPos = 0;
04118    outPos = 0;
04119    status = 0;
04120 
04121    addr = i2cInfo[handle].addr;
04122    flags = 0;
04123    esc = 0;
04124    setesc = 0;
04125 
04126    while (!status && (inPos < inLen))
04127    {
04128       DBG(DBG_INTERNAL, "status=%d inpos=%d inlen=%d cmd=%d addr=%d flags=%x",
04129          status, inPos, inLen, inBuf[inPos], addr, flags);
04130 
04131       switch (inBuf[inPos++])
04132       {
04133          case PI_I2C_END:
04134             status = 1;
04135             break;
04136 
04137          case PI_I2C_COMBINED_ON:
04138             /* Run prior transactions before setting combined flag */
04139             if (numSegs)
04140             {
04141                status = i2cSegments(handle, segs, numSegs);
04142                if (status >= 0) status = 0; /* continue */
04143                numSegs = 0;
04144             }
04145             i2cSwitchCombined(1);
04146             break;
04147 
04148          case PI_I2C_COMBINED_OFF:
04149             /* Run prior transactions before clearing combined flag */
04150             if (numSegs)
04151             {
04152                status = i2cSegments(handle, segs, numSegs);
04153                if (status >= 0) status = 0; /* continue */
04154                numSegs = 0;
04155             }
04156             i2cSwitchCombined(0);
04157             break;
04158 
04159          case PI_I2C_ADDR:
04160             addr = myI2CGetPar(inBuf, &inPos, inLen, &esc);
04161             if (addr < 0) status = PI_BAD_I2C_CMD;
04162             break;
04163 
04164          case PI_I2C_FLAGS:
04165             /* cheat to force two byte flags */
04166             esc = 1;
04167             flags = myI2CGetPar(inBuf, &inPos, inLen, &esc);
04168             if (flags < 0) status = PI_BAD_I2C_CMD;
04169             break;
04170 
04171          case PI_I2C_ESC:
04172             setesc = 1;
04173             break;
04174 
04175          case PI_I2C_READ:
04176 
04177             bytes = myI2CGetPar(inBuf, &inPos, inLen, &esc);
04178 
04179             if (bytes >= 0)
04180             {
04181                if ((bytes + outPos) < outLen)
04182                {
04183                   segs[numSegs].addr = addr;
04184                   segs[numSegs].flags = (flags|1);
04185                   segs[numSegs].len = bytes;
04186                   segs[numSegs].buf = (uint8_t *)(outBuf + outPos);
04187                   outPos += bytes;
04188                   numSegs++;
04189                   if (numSegs >= PI_I2C_RDRW_IOCTL_MAX_MSGS)
04190                   {
04191                      status = i2cSegments(handle, segs, numSegs);
04192                      if (status >= 0) status = 0; /* continue */
04193                      numSegs = 0;
04194                   }
04195                }
04196                else status = PI_BAD_I2C_RLEN;
04197             }
04198             else status = PI_BAD_I2C_RLEN;
04199             break;
04200 
04201          case PI_I2C_WRITE:
04202 
04203             bytes = myI2CGetPar(inBuf, &inPos, inLen, &esc);
04204 
04205             if (bytes >= 0)
04206             {
04207                if ((bytes + inPos) < inLen)
04208                {
04209                   segs[numSegs].addr = addr;
04210                   segs[numSegs].flags = (flags&0xfffe);
04211                   segs[numSegs].len = bytes;
04212                   segs[numSegs].buf = (uint8_t *)(inBuf + inPos);
04213                   inPos += bytes;
04214                   numSegs++;
04215                   if (numSegs >= PI_I2C_RDRW_IOCTL_MAX_MSGS)
04216                   {
04217                      status = i2cSegments(handle, segs, numSegs);
04218                      if (status >= 0) status = 0; /* continue */
04219                      numSegs = 0;
04220                   }
04221                }
04222                else status = PI_BAD_I2C_WLEN;
04223             }
04224             else status = PI_BAD_I2C_WLEN;
04225             break;
04226 
04227          default:
04228             status = PI_BAD_I2C_CMD;
04229       }
04230 
04231       if (setesc) esc = 1; else esc = 0;
04232 
04233       setesc = 0;
04234    }
04235 
04236    if (status >= 0)
04237    {
04238       if (numSegs) status = i2cSegments(handle, segs, numSegs);
04239    }
04240 
04241    if (status >= 0) status = outPos;
04242 
04243    return status;
04244 }
04245 
04246 /* ======================================================================= */
04247 
04248 /*SPI */
04249 
04250 static uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf)
04251 {
04252    uint32_t bits=0;
04253 
04254    if (buf)
04255    {
04256       if      (bitlen <=  8) bits = *((( uint8_t*)buf)+pos);
04257       else if (bitlen <= 16) bits = *(((uint16_t*)buf)+pos);
04258       else                   bits = *(((uint32_t*)buf)+pos);
04259 
04260       if (msbf) bits <<= (32-bitlen);
04261    }
04262 
04263    return bits;
04264 }
04265 
04266 static void _spiRXBits(
04267    char *buf, int pos, int bitlen, int msbf, uint32_t bits)
04268 {
04269    if (buf)
04270    {
04271       if (!msbf) bits >>= (32-bitlen);
04272 
04273       if      (bitlen <=  8) *((( uint8_t*)buf)+pos) = bits;
04274       else if (bitlen <= 16) *(((uint16_t*)buf)+pos) = bits;
04275       else                   *(((uint32_t*)buf)+pos) = bits;
04276    }
04277 }
04278 
04279 static void spiACS(int channel, int on)
04280 {
04281    int gpio;
04282 
04283    switch (channel)
04284    {
04285        case  0: gpio = PI_ASPI_CE0; break;
04286        case  1: gpio = PI_ASPI_CE1; break;
04287        default: gpio = PI_ASPI_CE2; break;
04288    }
04289    myGpioWrite(gpio, on);
04290 }
04291 
04292 static void spiGoA(
04293    unsigned speed,    /* bits per second */
04294    uint32_t flags,    /* flags           */
04295    char     *txBuf,   /* tx buffer       */
04296    char     *rxBuf,   /* rx buffer       */
04297    unsigned count)    /* number of bytes */
04298 {
04299    int cs;
04300    char bit_ir[4] = {1, 0, 0, 1}; /* read on rising edge */
04301    char bit_or[4] = {0, 1, 1, 0}; /* write on rising edge */
04302    char bit_ic[4] = {0, 0, 1, 1}; /* invert clock */
04303 
04304    int mode, bitlen, txmsbf, rxmsbf, channel;
04305    unsigned txCnt=0;
04306    unsigned rxCnt=0;
04307    uint32_t spiDefaults;
04308    uint32_t statusReg;
04309    int txFull, rxEmpty;
04310 
04311    channel = PI_SPI_FLAGS_GET_CHANNEL(flags);
04312    mode   =  PI_SPI_FLAGS_GET_MODE   (flags);
04313 
04314    bitlen =  PI_SPI_FLAGS_GET_BITLEN (flags);
04315 
04316    if (!bitlen) bitlen = 8;
04317 
04318    /* correct count for word size */
04319 
04320    if (bitlen >  8) count /= 2;
04321    if (bitlen > 16) count /= 2;
04322 
04323    txmsbf = !PI_SPI_FLAGS_GET_TX_LSB (flags);
04324    rxmsbf = !PI_SPI_FLAGS_GET_RX_LSB (flags);
04325 
04326    cs = PI_SPI_FLAGS_GET_CSPOLS(flags) & (1<<channel);
04327 
04328    spiDefaults = AUXSPI_CNTL0_SPEED(125000000/speed)   |
04329                  AUXSPI_CNTL0_IN_RISING(bit_ir[mode])  |
04330                  AUXSPI_CNTL0_OUT_RISING(bit_or[mode]) |
04331                  AUXSPI_CNTL0_INVERT_CLK(bit_ic[mode]) |
04332                  AUXSPI_CNTL0_MSB_FIRST(txmsbf)        |
04333                  AUXSPI_CNTL0_SHIFT_LEN(bitlen);
04334 
04335    if (!count)
04336    {
04337       auxReg[AUX_SPI0_CNTL0_REG] =
04338          AUXSPI_CNTL0_ENABLE | AUXSPI_CNTL0_CLR_FIFOS;
04339 
04340       myGpioDelay(10);
04341 
04342       auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE  | spiDefaults;
04343 
04344       auxReg[AUX_SPI0_CNTL1_REG] = AUXSPI_CNTL1_MSB_FIRST(rxmsbf);
04345 
04346       return;
04347    }
04348 
04349    auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE  | spiDefaults;
04350 
04351    auxReg[AUX_SPI0_CNTL1_REG] = AUXSPI_CNTL1_MSB_FIRST(rxmsbf);
04352 
04353    spiACS(channel, cs);
04354 
04355    while ((txCnt < count) || (rxCnt < count))
04356    {
04357       statusReg = auxReg[AUX_SPI0_STAT_REG];
04358 
04359       rxEmpty = statusReg & AUXSPI_STAT_RX_EMPTY;
04360 
04361       txFull = (((statusReg>>28)&15) > 2);
04362 
04363       if (rxCnt < count)
04364       {
04365          if (!rxEmpty)
04366          {
04367             _spiRXBits(
04368                rxBuf, rxCnt++, bitlen, rxmsbf, auxReg[AUX_SPI0_IO_REG]);
04369          }
04370       }
04371 
04372       if (txCnt < count)
04373       {
04374          if (!txFull)
04375          {
04376             if (txCnt != (count-1))
04377             {
04378                auxReg[AUX_SPI0_TX_HOLD] =
04379                   _spiTXBits(txBuf, txCnt++, bitlen, txmsbf);
04380             }
04381             else
04382             {
04383                auxReg[AUX_SPI0_IO_REG] =
04384                   _spiTXBits(txBuf, txCnt++, bitlen, txmsbf);
04385             }
04386          }
04387       }
04388    }
04389 
04390    while ((auxReg[AUX_SPI0_STAT_REG] & AUXSPI_STAT_BUSY)) ;
04391 
04392    spiACS(channel, !cs);
04393 }
04394 
04395 static void spiGoS(
04396    unsigned speed,
04397    uint32_t flags,
04398    char     *txBuf,
04399    char     *rxBuf,
04400    unsigned count)
04401 {
04402    unsigned txCnt=0;
04403    unsigned rxCnt=0;
04404    unsigned cnt, cnt4w, cnt3w;
04405    uint32_t spiDefaults;
04406    unsigned mode, channel, cspol, cspols, flag3w, ren3w;
04407 
04408    channel = PI_SPI_FLAGS_GET_CHANNEL(flags);
04409    mode   =  PI_SPI_FLAGS_GET_MODE   (flags);
04410    cspols =  PI_SPI_FLAGS_GET_CSPOLS(flags);
04411    cspol  =  (cspols>>channel) & 1;
04412    flag3w =  PI_SPI_FLAGS_GET_3WIRE(flags);
04413    ren3w =   PI_SPI_FLAGS_GET_3WREN(flags);
04414 
04415    spiDefaults = SPI_CS_MODE(mode)     |
04416                  SPI_CS_CSPOLS(cspols) |
04417                  SPI_CS_CS(channel)    |
04418                  SPI_CS_CSPOL(cspol)   |
04419                  SPI_CS_CLEAR(3);
04420 
04421    spiReg[SPI_DLEN] = 2; /* undocumented, stops inter-byte gap */
04422 
04423    spiReg[SPI_CS] = spiDefaults; /* stop */
04424 
04425    if (!count) return;
04426 
04427    if (flag3w)
04428    {
04429       if (ren3w < count)
04430       {
04431          cnt4w = ren3w;
04432          cnt3w = count - ren3w;
04433       }
04434       else
04435       {
04436          cnt4w = count;
04437          cnt3w = 0;
04438       }
04439    }
04440    else
04441    {
04442       cnt4w = count;
04443       cnt3w = 0;
04444    }
04445 
04446    spiReg[SPI_CLK] = 250000000/speed;
04447 
04448    spiReg[SPI_CS] = spiDefaults | SPI_CS_TA; /* start */
04449 
04450    cnt = cnt4w;
04451 
04452    while((txCnt < cnt) || (rxCnt < cnt))
04453    {
04454       while((rxCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_RXD)))
04455       {
04456          if (rxBuf) rxBuf[rxCnt] = spiReg[SPI_FIFO];
04457          else       spi_dummy    = spiReg[SPI_FIFO];
04458          rxCnt++;
04459       }
04460 
04461       while((txCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_TXD)))
04462       {
04463          if (txBuf) spiReg[SPI_FIFO] = txBuf[txCnt];
04464          else       spiReg[SPI_FIFO] = 0;
04465          txCnt++;
04466       }
04467    }
04468 
04469    while (!(spiReg[SPI_CS] & SPI_CS_DONE)) ;
04470 
04471    /* now switch to 3-wire bus */
04472 
04473    cnt += cnt3w;
04474 
04475    spiReg[SPI_CS] |= SPI_CS_REN;
04476 
04477    while((txCnt < cnt) || (rxCnt < cnt))
04478    {
04479       while((rxCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_RXD)))
04480       {
04481          if (rxBuf) rxBuf[rxCnt] = spiReg[SPI_FIFO];
04482          else       spi_dummy    = spiReg[SPI_FIFO];
04483          rxCnt++;
04484       }
04485 
04486       while((txCnt < cnt) && ((spiReg[SPI_CS] & SPI_CS_TXD)))
04487       {
04488          if (txBuf) spiReg[SPI_FIFO] = txBuf[txCnt];
04489          else       spiReg[SPI_FIFO] = 0;
04490          txCnt++;
04491       }
04492    }
04493 
04494    while (!(spiReg[SPI_CS] & SPI_CS_DONE)) ;
04495 
04496    spiReg[SPI_CS] = spiDefaults; /* stop */
04497 }
04498 
04499 static void spiGo(
04500    unsigned speed,
04501    uint32_t flags,
04502    char     *txBuf,
04503    char     *rxBuf,
04504    unsigned count)
04505 {
04506    static pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER;
04507    static pthread_mutex_t aux_mutex = PTHREAD_MUTEX_INITIALIZER;
04508 
04509    if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
04510    {
04511       pthread_mutex_lock(&aux_mutex);
04512       spiGoA(speed, flags, txBuf, rxBuf, count);
04513       pthread_mutex_unlock(&aux_mutex);
04514    }
04515    else
04516    {
04517       pthread_mutex_lock(&main_mutex);
04518       spiGoS(speed, flags, txBuf, rxBuf, count);
04519       pthread_mutex_unlock(&main_mutex);
04520    }
04521 }
04522 
04523 static int spiAnyOpen(uint32_t flags)
04524 {
04525    int i, aux;
04526 
04527    aux = PI_SPI_FLAGS_GET_AUX_SPI(flags);
04528 
04529    for (i=0; i<PI_SPI_SLOTS; i++)
04530    {
04531       if ((spiInfo[i].state == PI_SPI_OPENED) &&
04532          (PI_SPI_FLAGS_GET_AUX_SPI(spiInfo[i].flags) == aux))
04533             return 1;
04534    }
04535    return 0;
04536 }
04537 
04538 static void spiInit(uint32_t flags)
04539 {
04540    uint32_t resvd, cspols;
04541 
04542    resvd  = PI_SPI_FLAGS_GET_RESVD(flags);
04543    cspols = PI_SPI_FLAGS_GET_CSPOLS(flags);
04544 
04545    if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
04546    {
04547       /* enable module and access to registers */
04548 
04549       auxReg[AUX_ENABLES] |= AUXENB_SPI1;
04550 
04551       /* save original state */
04552 
04553       old_mode_ace0  = gpioGetMode(PI_ASPI_CE0);
04554       old_mode_ace1  = gpioGetMode(PI_ASPI_CE1);
04555       old_mode_ace2  = gpioGetMode(PI_ASPI_CE2);
04556       old_mode_asclk = gpioGetMode(PI_ASPI_SCLK);
04557       old_mode_amiso = gpioGetMode(PI_ASPI_MISO);
04558       old_mode_amosi = gpioGetMode(PI_ASPI_MOSI);
04559 
04560       old_spi_cntl0 = auxReg[AUX_SPI0_CNTL0_REG];
04561       old_spi_cntl1 = auxReg[AUX_SPI0_CNTL1_REG];
04562 
04563       /* manually control auxiliary SPI chip selects */
04564 
04565       if (!(resvd&1))
04566       {
04567          myGpioSetMode(PI_ASPI_CE0,  PI_OUTPUT);
04568          myGpioWrite(PI_ASPI_CE0, !(cspols&1));
04569       }
04570 
04571       if (!(resvd&2))
04572       {
04573          myGpioSetMode(PI_ASPI_CE1,  PI_OUTPUT);
04574          myGpioWrite(PI_ASPI_CE1, !(cspols&2));
04575       }
04576 
04577       if (!(resvd&4))
04578       {
04579          myGpioSetMode(PI_ASPI_CE2,  PI_OUTPUT);
04580          myGpioWrite(PI_ASPI_CE2, !(cspols&4));
04581       }
04582 
04583       /* set gpios to SPI mode */
04584 
04585       myGpioSetMode(PI_ASPI_SCLK, PI_ALT4);
04586       myGpioSetMode(PI_ASPI_MISO, PI_ALT4);
04587       myGpioSetMode(PI_ASPI_MOSI, PI_ALT4);
04588    }
04589    else
04590    {
04591       /* save original state */
04592 
04593       old_mode_ce0  = gpioGetMode(PI_SPI_CE0);
04594       old_mode_ce1  = gpioGetMode(PI_SPI_CE1);
04595       old_mode_sclk = gpioGetMode(PI_SPI_SCLK);
04596       old_mode_miso = gpioGetMode(PI_SPI_MISO);
04597       old_mode_mosi = gpioGetMode(PI_SPI_MOSI);
04598 
04599       old_spi_cs  = spiReg[SPI_CS];
04600       old_spi_clk = spiReg[SPI_CLK];
04601 
04602       /* set gpios to SPI mode */
04603 
04604       if (!(resvd&1)) myGpioSetMode(PI_SPI_CE0,  PI_ALT0);
04605       if (!(resvd&2)) myGpioSetMode(PI_SPI_CE1,  PI_ALT0);
04606 
04607       myGpioSetMode(PI_SPI_SCLK, PI_ALT0);
04608       myGpioSetMode(PI_SPI_MISO, PI_ALT0);
04609       myGpioSetMode(PI_SPI_MOSI, PI_ALT0);
04610    }
04611 }
04612 
04613 static void spiTerm(uint32_t flags)
04614 {
04615    int resvd;
04616 
04617    resvd = PI_SPI_FLAGS_GET_RESVD(flags);
04618 
04619    if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
04620    {
04621       /* disable module and access to registers */
04622 
04623       auxReg[AUX_ENABLES] &= (~AUXENB_SPI1);
04624 
04625       /* restore original state */
04626 
04627       if (!(resvd&1)) myGpioSetMode(PI_ASPI_CE0,  old_mode_ace0);
04628       if (!(resvd&2)) myGpioSetMode(PI_ASPI_CE1,  old_mode_ace1);
04629       if (!(resvd&4)) myGpioSetMode(PI_ASPI_CE2,  old_mode_ace2);
04630 
04631       myGpioSetMode(PI_ASPI_SCLK, old_mode_asclk);
04632       myGpioSetMode(PI_ASPI_MISO, old_mode_amiso);
04633       myGpioSetMode(PI_ASPI_MOSI, old_mode_amosi);
04634 
04635       auxReg[AUX_SPI0_CNTL0_REG] = old_spi_cntl0;
04636       auxReg[AUX_SPI0_CNTL1_REG] = old_spi_cntl1;
04637    }
04638    else
04639    {
04640       /* restore original state */
04641 
04642       if (!(resvd&1)) myGpioSetMode(PI_SPI_CE0,  old_mode_ce0);
04643       if (!(resvd&2)) myGpioSetMode(PI_SPI_CE1,  old_mode_ce1);
04644 
04645       myGpioSetMode(PI_SPI_SCLK, old_mode_sclk);
04646       myGpioSetMode(PI_SPI_MISO, old_mode_miso);
04647       myGpioSetMode(PI_SPI_MOSI, old_mode_mosi);
04648 
04649       spiReg[SPI_CS]  = old_spi_cs;
04650       spiReg[SPI_CLK] = old_spi_clk;
04651    }
04652 }
04653 
04654 int spiOpen(unsigned spiChan, unsigned baud, unsigned spiFlags)
04655 {
04656    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
04657    int i, slot;
04658 
04659    DBG(DBG_USER, "spiChan=%d baud=%d spiFlags=0x%X",
04660       spiChan, baud, spiFlags);
04661 
04662    CHECK_INITED;
04663 
04664    if (PI_SPI_FLAGS_GET_AUX_SPI(spiFlags))
04665    {
04666       if (gpioHardwareRevision() < 16)
04667          SOFT_ERROR(PI_NO_AUX_SPI, "no auxiliary SPI on Pi A or B");
04668 
04669       i = PI_NUM_AUX_SPI_CHANNEL;
04670    }
04671    else
04672       i = PI_NUM_STD_SPI_CHANNEL;
04673 
04674    if (spiChan >= i)
04675       SOFT_ERROR(PI_BAD_SPI_CHANNEL, "bad spiChan (%d)", spiChan);
04676 
04677    if ((baud < PI_SPI_MIN_BAUD) || (baud > PI_SPI_MAX_BAUD))
04678       SOFT_ERROR(PI_BAD_SPI_SPEED, "bad baud (%d)", baud);
04679 
04680    if (spiFlags > (1<<22))
04681       SOFT_ERROR(PI_BAD_FLAGS, "bad spiFlags (0x%X)", spiFlags);
04682 
04683    if (!spiAnyOpen(spiFlags)) /* initialise on first open */
04684    {
04685       spiInit(spiFlags);
04686       spiGo(baud, spiFlags, NULL, NULL, 0);
04687    }
04688 
04689    slot = -1;
04690 
04691    pthread_mutex_lock(&mutex);
04692 
04693    for (i=0; i<PI_SPI_SLOTS; i++)
04694    {
04695       if (spiInfo[i].state == PI_SPI_CLOSED)
04696       {
04697          slot = i;
04698          spiInfo[slot].state = PI_SPI_RESERVED;
04699          break;
04700       }
04701    }
04702 
04703    pthread_mutex_unlock(&mutex);
04704 
04705    if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no SPI handles");
04706 
04707    spiInfo[slot].speed = baud;
04708    spiInfo[slot].flags = spiFlags | PI_SPI_FLAGS_CHANNEL(spiChan);
04709    spiInfo[slot].state = PI_SPI_OPENED;
04710 
04711    return slot;
04712 }
04713 
04714 int spiClose(unsigned handle)
04715 {
04716    DBG(DBG_USER, "handle=%d", handle);
04717 
04718    CHECK_INITED;
04719 
04720    if (handle >= PI_SPI_SLOTS)
04721       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04722 
04723    if (spiInfo[handle].state != PI_SPI_OPENED)
04724       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04725 
04726    spiInfo[handle].state = PI_I2C_CLOSED;
04727 
04728    if (!spiAnyOpen(spiInfo[handle].flags))
04729       spiTerm(spiInfo[handle].flags); /* terminate on last close */
04730 
04731    return 0;
04732 }
04733 
04734 int spiRead(unsigned handle, char *buf, unsigned count)
04735 {
04736    DBG(DBG_USER, "handle=%d count=%d [%s]",
04737       handle, count, myBuf2Str(count, buf));
04738 
04739    CHECK_INITED;
04740 
04741    if (handle >= PI_SPI_SLOTS)
04742       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04743 
04744    if (spiInfo[handle].state != PI_SPI_OPENED)
04745       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04746 
04747    if (count > PI_MAX_SPI_DEVICE_COUNT)
04748       SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
04749 
04750    spiGo(spiInfo[handle].speed, spiInfo[handle].flags, NULL, buf, count);
04751 
04752    return count;
04753 }
04754 
04755 int spiWrite(unsigned handle, char *buf, unsigned count)
04756 {
04757    DBG(DBG_USER, "handle=%d count=%d [%s]",
04758       handle, count, myBuf2Str(count, buf));
04759 
04760    CHECK_INITED;
04761 
04762    if (handle >= PI_SPI_SLOTS)
04763       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04764 
04765    if (spiInfo[handle].state != PI_SPI_OPENED)
04766       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04767 
04768    if (count > PI_MAX_SPI_DEVICE_COUNT)
04769       SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
04770 
04771    spiGo(spiInfo[handle].speed, spiInfo[handle].flags, buf, NULL, count);
04772 
04773    return count;
04774 }
04775 
04776 int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)
04777 {
04778    DBG(DBG_USER, "handle=%d count=%d [%s]",
04779       handle, count, myBuf2Str(count, txBuf));
04780 
04781    CHECK_INITED;
04782 
04783    if (handle >= PI_SPI_SLOTS)
04784       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04785 
04786    if (spiInfo[handle].state != PI_SPI_OPENED)
04787       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04788 
04789    if (count > PI_MAX_SPI_DEVICE_COUNT)
04790       SOFT_ERROR(PI_BAD_SPI_COUNT, "bad count (%d)", count);
04791 
04792    spiGo(spiInfo[handle].speed, spiInfo[handle].flags, txBuf, rxBuf, count);
04793 
04794    return count;
04795 }
04796 
04797 /* ======================================================================= */
04798 
04799 
04800 int serOpen(char *tty, unsigned serBaud, unsigned serFlags)
04801 {
04802    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
04803    struct termios new;
04804    int speed;
04805    int fd;
04806    int i, slot;
04807 
04808    DBG(DBG_USER, "tty=%s serBaud=%d serFlags=0x%X", tty, serBaud, serFlags);
04809 
04810    SER_CHECK_INITED;
04811 
04812    if (strncmp("/dev/tty", tty, 8) && strncmp("/dev/serial", tty, 11))
04813       SOFT_ERROR(PI_BAD_SER_DEVICE, "bad device (%s)", tty);
04814 
04815    switch (serBaud)
04816    {
04817       case     50: speed =     B50; break;
04818       case     75: speed =     B75; break;
04819       case    110: speed =    B110; break;
04820       case    134: speed =    B134; break;
04821       case    150: speed =    B150; break;
04822       case    200: speed =    B200; break;
04823       case    300: speed =    B300; break;
04824       case    600: speed =    B600; break;
04825       case   1200: speed =   B1200; break;
04826       case   1800: speed =   B1800; break;
04827       case   2400: speed =   B2400; break;
04828       case   4800: speed =   B4800; break;
04829       case   9600: speed =   B9600; break;
04830       case  19200: speed =  B19200; break;
04831       case  38400: speed =  B38400; break;
04832       case  57600: speed =  B57600; break;
04833       case 115200: speed = B115200; break;
04834       case 230400: speed = B230400; break;
04835 
04836       default:
04837          SOFT_ERROR(PI_BAD_SER_SPEED, "bad speed (%d)", serBaud);
04838    }
04839 
04840    if (serFlags)
04841       SOFT_ERROR(PI_BAD_FLAGS, "bad flags (0x%X)", serFlags);
04842 
04843    slot = -1;
04844 
04845    pthread_mutex_lock(&mutex);
04846 
04847    for (i=0; i<PI_SER_SLOTS; i++)
04848    {
04849       if (serInfo[i].state == PI_SER_CLOSED)
04850       {
04851          slot = i;
04852          serInfo[slot].state = PI_SER_RESERVED;
04853          break;
04854       }
04855    }
04856 
04857    pthread_mutex_unlock(&mutex);
04858 
04859    if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no serial handles");
04860 
04861    if ((fd = open(tty, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
04862    {
04863       serInfo[slot].state = PI_SER_CLOSED;
04864       return PI_SER_OPEN_FAILED;
04865    }
04866 
04867    tcgetattr(fd, &new);
04868 
04869    cfmakeraw(&new);
04870 
04871    cfsetispeed(&new, speed);
04872    cfsetospeed(&new, speed);
04873 
04874    new.c_cc [VMIN]  = 0;
04875    new.c_cc [VTIME] = 0;
04876 
04877    tcflush(fd, TCIFLUSH);
04878    tcsetattr(fd, TCSANOW, &new);
04879 
04880    //fcntl(fd, F_SETFL, O_RDWR);
04881 
04882    serInfo[slot].fd = fd;
04883    serInfo[slot].flags = serFlags;
04884    serInfo[slot].state = PI_SER_OPENED;
04885 
04886    return slot;
04887 }
04888 
04889 int serClose(unsigned handle)
04890 {
04891    DBG(DBG_USER, "handle=%d", handle);
04892 
04893    SER_CHECK_INITED;
04894 
04895    if (handle >= PI_SER_SLOTS)
04896       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04897 
04898    if (serInfo[handle].state != PI_SER_OPENED)
04899       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04900 
04901    if (serInfo[handle].fd >= 0) close(serInfo[handle].fd);
04902 
04903    serInfo[handle].fd = -1;
04904    serInfo[handle].state = PI_SER_CLOSED;
04905 
04906    return 0;
04907 }
04908 
04909 int serWriteByte(unsigned handle, unsigned bVal)
04910 {
04911    char c;
04912 
04913    DBG(DBG_USER, "handle=%d bVal=%d", handle, bVal);
04914 
04915    SER_CHECK_INITED;
04916 
04917    if (handle >= PI_SER_SLOTS)
04918       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04919 
04920    if (serInfo[handle].state != PI_SER_OPENED)
04921       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04922 
04923    if (bVal > 0xFF)
04924       SOFT_ERROR(PI_BAD_PARAM, "bad parameter (%d)", bVal);
04925 
04926    c = bVal;
04927 
04928    if (write(serInfo[handle].fd, &c, 1) != 1)
04929       return PI_SER_WRITE_FAILED;
04930    else
04931       return 0;
04932 }
04933 
04934 int serReadByte(unsigned handle)
04935 {
04936    int r;
04937    char x;
04938 
04939    DBG(DBG_USER, "handle=%d", handle);
04940 
04941    SER_CHECK_INITED;
04942 
04943    if (handle >= PI_SER_SLOTS)
04944       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04945 
04946    if (serInfo[handle].state != PI_SER_OPENED)
04947       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04948 
04949    r = read(serInfo[handle].fd, &x, 1);
04950 
04951    if (r == 1)
04952       return ((int)x) & 0xFF;
04953 
04954    else if (r == 0)
04955       return PI_SER_READ_NO_DATA;
04956 
04957    else if ((r == -1) && (errno == EAGAIN))
04958       return PI_SER_READ_NO_DATA;
04959 
04960    else
04961       return PI_SER_READ_FAILED;
04962 }
04963 
04964 int serWrite(unsigned handle, char *buf, unsigned count)
04965 {
04966    int written=0, wrote=0;
04967 
04968    DBG(DBG_USER, "handle=%d count=%d [%s]",
04969       handle, count, myBuf2Str(count, buf));
04970 
04971    SER_CHECK_INITED;
04972 
04973    if (handle >= PI_SER_SLOTS)
04974       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04975 
04976    if (serInfo[handle].state != PI_SER_OPENED)
04977       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
04978 
04979    if (!count)
04980       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
04981 
04982    while ((written != count) && (wrote >= 0))
04983    {
04984       wrote = write(serInfo[handle].fd, buf+written, count-written);
04985 
04986       if (wrote >= 0)
04987       {
04988          written += wrote;
04989 
04990          if (written != count) time_sleep(0.05);
04991       }
04992    }
04993 
04994    if (written != count)
04995       return PI_SER_WRITE_FAILED;
04996    else
04997       return 0;
04998 }
04999 
05000 int serRead(unsigned handle, char *buf, unsigned count)
05001 {
05002    int r;
05003 
05004    DBG(DBG_USER, "handle=%d count=%d buf=0x%X", handle, count, (unsigned)buf);
05005 
05006    SER_CHECK_INITED;
05007 
05008    if (handle >= PI_SER_SLOTS)
05009       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
05010 
05011    if (serInfo[handle].state != PI_SER_OPENED)
05012       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
05013 
05014    if (!count)
05015       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
05016 
05017    r = read(serInfo[handle].fd, buf, count);
05018 
05019    if (r == -1)
05020    {
05021       if (errno == EAGAIN)
05022          return PI_SER_READ_NO_DATA;
05023       else
05024          return PI_SER_READ_FAILED;
05025    }
05026    else
05027    {
05028       if (r < count) buf[r] = 0;
05029       return r;
05030    }
05031 }
05032 
05033 int serDataAvailable(unsigned handle)
05034 {
05035    int result;
05036 
05037    DBG(DBG_USER, "handle=%d", handle);
05038 
05039    SER_CHECK_INITED;
05040 
05041    if (handle >= PI_SER_SLOTS)
05042       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
05043 
05044    if (serInfo[handle].state != PI_SER_OPENED)
05045       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
05046 
05047    if (ioctl(serInfo[handle].fd, FIONREAD, &result) == -1) return 0;
05048 
05049    return result;
05050 }
05051 
05052 /* ======================================================================= */
05053 
05054 static int chooseBestClock
05055    (clkInf_t *clkInf, unsigned f, unsigned numc, unsigned *cf)
05056 {
05057    int c, valid, offby, offby2, best_offby;
05058    uint32_t div;
05059    uint64_t frac;
05060 
05061    valid = 0;
05062    best_offby = 0;
05063 
05064    for (c=0; c<numc; c++)
05065    {
05066       div = cf[c] / f;
05067 
05068       if ((div > 1) && (div < 4096))
05069       {
05070          if (f < PI_MASH_MAX_FREQ)
05071          {
05072             frac = cf[c] - (div * f);
05073             frac = (frac * 4096) / f;
05074             offby = cf[c] - (div * f) - ((frac * f) / 4096);
05075             if (frac < 4095)
05076             {
05077                offby2 = cf[c] - (div * f) - (((frac+1) * f) / 4096);
05078                if (offby2 < 0) offby2 = -offby2;
05079                if (offby2 < offby)
05080                {
05081                   offby = offby2;
05082                   frac++;
05083                }
05084             }
05085          }
05086          else
05087          {
05088             frac = 0;
05089             offby = cf[c] - (div * f);
05090             if (div < 4095)
05091             {
05092                offby2 = cf[c] - ((div+1) * f);
05093                if (offby2 < 0) offby2 = -offby2;
05094                if (offby2 < offby)
05095                {
05096                   offby = offby2;
05097                   div++;
05098                }
05099             }
05100          }
05101 
05102          if ((!valid) || (offby <= best_offby))
05103          {
05104             valid = 1;
05105             clkInf->div = div;
05106             clkInf->frac = frac;
05107             clkInf->clock = c;
05108             best_offby = offby;
05109          }
05110       }
05111    }
05112    return valid;
05113 }
05114 
05115 /* ======================================================================= */
05116 
05117 static rawCbs_t * dmaCB2adr(int pos)
05118 {
05119    int page, slot;
05120 
05121    page = pos/CBS_PER_IPAGE;
05122    slot = pos%CBS_PER_IPAGE;
05123 
05124    return &dmaIVirt[page]->cb[slot];
05125 }
05126 
05127 /* ----------------------------------------------------------------------- */
05128 
05129 static void dmaCbPrint(int pos)
05130 {
05131    rawCbs_t * p;
05132 
05133    p = dmaCB2adr(pos);
05134 
05135    fprintf(stderr, "i=%x s=%x d=%x len=%x s=%x nxt=%x\n",
05136       p->info, p->src, p->dst, p->length, p->stride, p->next);
05137 }
05138 
05139 /* ----------------------------------------------------------------------- */
05140 
05141 static unsigned dmaNowAtICB(void)
05142 {
05143    unsigned cb;
05144    static unsigned lastPage=0;
05145    unsigned page;
05146    uint32_t cbAddr;
05147    uint32_t startTick, endTick;
05148 
05149    startTick = systReg[SYST_CLO];
05150 
05151    cbAddr = dmaIn[DMA_CONBLK_AD];
05152 
05153    page = lastPage;
05154 
05155    /* which page are we dma'ing? */
05156 
05157    while (1)
05158    {
05159       cb = (cbAddr - ((int)dmaIBus[page])) / 32;
05160 
05161       if (cb < CBS_PER_IPAGE)
05162       {
05163          endTick = systReg[SYST_CLO];
05164 
05165          if (endTick != startTick)
05166             gpioStats.cbTicks += (endTick - startTick);
05167 
05168          gpioStats.cbCalls++;
05169 
05170          lastPage = page;
05171 
05172          return (page*CBS_PER_IPAGE) + cb;
05173       }
05174 
05175       if (page++ >= DMAI_PAGES) page=0;
05176 
05177       if (page == lastPage) break;
05178    }
05179 
05180    return 0;
05181 }
05182 
05183 /* ----------------------------------------------------------------------- */
05184 
05185 static int dmaNowAtOCB(void)
05186 {
05187    unsigned cb;
05188    unsigned page;
05189    uint32_t cbAddr;
05190 
05191    cbAddr = dmaOut[DMA_CONBLK_AD];
05192 
05193    if (!cbAddr) return -PI_NO_TX_WAVE;
05194 
05195    page = 0;
05196 
05197    /* which page are we dma'ing? */
05198 
05199    while (1)
05200    {
05201       cb = (cbAddr - ((int)dmaOBus[page])) / 32;
05202 
05203       if (cb < CBS_PER_OPAGE) return (page*CBS_PER_OPAGE) + cb;
05204 
05205       if (page++ >= DMAO_PAGES) break;
05206    }
05207 
05208    /* Try twice */
05209 
05210    cbAddr = dmaOut[DMA_CONBLK_AD];
05211 
05212    if (!cbAddr) return -PI_NO_TX_WAVE;
05213 
05214    page = 0;
05215 
05216    /* which page are we dma'ing? */
05217 
05218    while (1)
05219    {
05220       cb = (cbAddr - ((int)dmaOBus[page])) / 32;
05221 
05222       if (cb < CBS_PER_OPAGE) return (page*CBS_PER_OPAGE) + cb;
05223 
05224       if (page++ >= DMAO_PAGES) break;
05225    }
05226 
05227    return -PI_WAVE_NOT_FOUND;
05228 }
05229 
05230 /* ----------------------------------------------------------------------- */
05231 
05232 unsigned rawWaveCB(void)
05233 {
05234    unsigned cb;
05235    static unsigned lastPage=0;
05236    unsigned page;
05237    uint32_t cbAddr;
05238 
05239    cbAddr = dmaOut[DMA_CONBLK_AD];
05240 
05241    if (!cbAddr) return -1;
05242 
05243    page = lastPage;
05244 
05245    /* which page are we dma'ing? */
05246 
05247    while (1)
05248    {
05249       cb = (cbAddr - ((int)dmaOBus[page])) / 32;
05250 
05251       if (cb < CBS_PER_OPAGE)
05252       {
05253          lastPage = page;
05254 
05255          return (page*CBS_PER_OPAGE) + cb;
05256       }
05257 
05258       if (page++ >= DMAO_PAGES) page=0;
05259 
05260       if (page == lastPage) break;
05261    }
05262 
05263    return 0;
05264 }
05265 
05266 /* ----------------------------------------------------------------------- */
05267 
05268 static unsigned dmaCurrentSlot(unsigned pos)
05269 {
05270    unsigned cycle=0, slot=0, tmp;
05271 
05272    cycle = (pos/CBS_PER_CYCLE);
05273    tmp   = (pos%CBS_PER_CYCLE);
05274 
05275    if (tmp > 2) slot = ((tmp-2)/3);
05276 
05277    return (cycle*PULSE_PER_CYCLE)+slot;
05278 }
05279 
05280 /* ----------------------------------------------------------------------- */
05281 
05282 static uint32_t dmaPwmDataAdr(int pos)
05283 {
05284    return (uint32_t) &dmaIBus[pos]->periphData;
05285 }
05286 
05287 /* ----------------------------------------------------------------------- */
05288 
05289 static uint32_t dmaGpioOnAdr(int pos)
05290 {
05291    int page, slot;
05292 
05293    page = pos/ON_PER_IPAGE;
05294    slot = pos%ON_PER_IPAGE;
05295 
05296    return (uint32_t) &dmaIBus[page]->gpioOn[slot];
05297 }
05298 
05299 /* ----------------------------------------------------------------------- */
05300 
05301 static uint32_t dmaGpioOffAdr(int pos)
05302 {
05303    int page, slot;
05304 
05305    myOffPageSlot(pos, &page, &slot);
05306 
05307    return (uint32_t) &dmaIBus[page]->gpioOff[slot];
05308 }
05309 
05310 /* ----------------------------------------------------------------------- */
05311 
05312 static uint32_t dmaTickAdr(int pos)
05313 {
05314    int page, slot;
05315 
05316    myTckPageSlot(pos, &page, &slot);
05317 
05318    return (uint32_t) &dmaIBus[page]->tick[slot];
05319 }
05320 
05321 /* ----------------------------------------------------------------------- */
05322 
05323 static uint32_t dmaReadLevelsAdr(int pos)
05324 {
05325    int page, slot;
05326 
05327    myLvsPageSlot(pos, &page, &slot);
05328 
05329    return (uint32_t) &dmaIBus[page]->level[slot];
05330 }
05331 
05332 /* ----------------------------------------------------------------------- */
05333 
05334 static uint32_t dmaCbAdr(int pos)
05335 {
05336    int page, slot;
05337 
05338    page = (pos/CBS_PER_IPAGE);
05339    slot = (pos%CBS_PER_IPAGE);
05340 
05341    return (uint32_t) &dmaIBus[page]->cb[slot];
05342 }
05343 
05344 /* ----------------------------------------------------------------------- */
05345 
05346 static void dmaGpioOnCb(int b, int pos)
05347 {
05348    rawCbs_t * p;
05349 
05350    p = dmaCB2adr(b);
05351 
05352    p->info   = NORMAL_DMA;
05353    p->src    = dmaGpioOnAdr(pos);
05354    p->dst    = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_BUS;
05355    p->length = 4;
05356    p->next   = dmaCbAdr(b+1);
05357 }
05358 
05359 /* ----------------------------------------------------------------------- */
05360 
05361 static void dmaTickCb(int b, int pos)
05362 {
05363    rawCbs_t * p;
05364 
05365    p = dmaCB2adr(b);
05366 
05367    p->info   = NORMAL_DMA;
05368    p->src    = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_BUS;
05369    p->dst    = dmaTickAdr(pos);
05370    p->length = 4;
05371    p->next   = dmaCbAdr(b+1);
05372 }
05373 
05374 /* ----------------------------------------------------------------------- */
05375 
05376 static void dmaGpioOffCb(int b, int pos)
05377 {
05378    rawCbs_t * p;
05379 
05380    p = dmaCB2adr(b);
05381 
05382    p->info   = NORMAL_DMA;
05383    p->src    = dmaGpioOffAdr(pos);
05384    p->dst    = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_BUS;
05385    p->length = 4;
05386    p->next   = dmaCbAdr(b+1);
05387 }
05388 
05389 /* ----------------------------------------------------------------------- */
05390 
05391 static void dmaReadLevelsCb(int b, int pos)
05392 {
05393    rawCbs_t * p;
05394 
05395    p = dmaCB2adr(b);
05396 
05397    p->info   = NORMAL_DMA;
05398    p->src    = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_BUS;
05399    p->dst    = dmaReadLevelsAdr(pos);
05400    p->length = 4;
05401    p->next   = dmaCbAdr(b+1);
05402 }
05403 
05404 /* ----------------------------------------------------------------------- */
05405 
05406 static void dmaDelayCb(int b)
05407 {
05408    rawCbs_t * p;
05409 
05410    p = dmaCB2adr(b);
05411 
05412    if (gpioCfg.clockPeriph == PI_CLOCK_PCM)
05413    {
05414       p->info = NORMAL_DMA | TIMED_DMA(2);
05415       p->dst  = PCM_TIMER;
05416    }
05417    else
05418    {
05419       p->info = NORMAL_DMA | TIMED_DMA(5);
05420       p->dst  = PWM_TIMER;
05421    }
05422 
05423    p->src    = dmaPwmDataAdr(b%DMAI_PAGES);
05424    p->length = 4;
05425    p->next   = dmaCbAdr(b+1);
05426 }
05427 
05428 /* ----------------------------------------------------------------------- */
05429 
05430 static void dmaInitCbs(void)
05431 {
05432    int b, pulse, level, cycle;
05433 
05434    rawCbs_t * p;
05435 
05436    /* set up the DMA control blocks */
05437 
05438    DBG(DBG_STARTUP, "");
05439 
05440    gpioStats.dmaInitCbsCount++;
05441 
05442    b = -1;
05443    level = 0;
05444 
05445    for (cycle=0; cycle<bufferCycles; cycle++)
05446    {
05447       b++; dmaGpioOnCb(b, cycle%SUPERCYCLE); /* gpio on slot */
05448 
05449       b++; dmaTickCb(b, cycle);              /* tick slot */
05450 
05451       for (pulse=0; pulse<PULSE_PER_CYCLE; pulse++)
05452       {
05453          b++; dmaReadLevelsCb(b, level);               /* read levels slot */
05454 
05455          b++; dmaDelayCb(b);                           /* delay slot */
05456 
05457          b++; dmaGpioOffCb(b, (level%SUPERLEVEL)+1);   /* gpio off slot */
05458 
05459          ++level;
05460       }
05461    }
05462 
05463    /* point last cb back to first for continuous loop */
05464 
05465    p = dmaCB2adr(b);
05466 
05467    p->next = dmaCbAdr(0);
05468 
05469    DBG(DBG_STARTUP, "DMA page type count = %d", sizeof(dmaIPage_t));
05470 
05471    DBG(DBG_STARTUP, "%d control blocks (exp=%d)", b+1, NUM_CBS);
05472 }
05473 
05474 /* ======================================================================= */
05475 
05476 
05477 static void sigHandler(int signum)
05478 {
05479    if ((signum >= PI_MIN_SIGNUM) && (signum <= PI_MAX_SIGNUM))
05480    {
05481       if (gpioSignal[signum].func)
05482       {
05483          if (gpioSignal[signum].ex)
05484          {
05485             (gpioSignal[signum].func)(signum, gpioSignal[signum].userdata);
05486          }
05487          else
05488          {
05489             (gpioSignal[signum].func)(signum);
05490          }
05491       }
05492       else
05493       {
05494          switch(signum)
05495          {
05496             case SIGUSR1:
05497 
05498                if (gpioCfg.dbgLevel > DBG_MIN_LEVEL) --gpioCfg.dbgLevel;
05499                else gpioCfg.dbgLevel = DBG_MIN_LEVEL;
05500                DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel);
05501                break;
05502 
05503             case SIGUSR2:
05504                if (gpioCfg.dbgLevel < DBG_MAX_LEVEL) ++gpioCfg.dbgLevel;
05505                else gpioCfg.dbgLevel = DBG_MAX_LEVEL;
05506                DBG(DBG_USER, "Debug level %d\n", gpioCfg.dbgLevel);
05507                break;
05508 
05509             case SIGPIPE:
05510             case SIGWINCH:
05511                DBG(DBG_USER, "signal %d ignored", signum);
05512                break;
05513 
05514             case SIGCHLD:
05515                /* Used to notify threads of events */
05516                break;
05517 
05518             default:
05519                DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum);
05520                gpioTerminate();
05521                exit(-1);
05522          }
05523       }
05524    }
05525    else
05526    {
05527       /* exit */
05528 
05529       DBG(DBG_ALWAYS, "Unhandled signal %d, terminating\n", signum);
05530       gpioTerminate();
05531       exit(-1);
05532    }
05533 }
05534 
05535 /* ----------------------------------------------------------------------- */
05536 
05537 static void sigSetHandler(void)
05538 {
05539    int i;
05540    struct sigaction new;
05541 
05542    for (i=PI_MIN_SIGNUM; i<=PI_MAX_SIGNUM; i++)
05543    {
05544 
05545       memset(&new, 0, sizeof(new));
05546       new.sa_handler = sigHandler;
05547 
05548       sigaction(i, &new, NULL);
05549    }
05550 }
05551 
05552 /*
05553    freq mics  net
05554  0 1000 1000  900
05555  1 4000  250  225
05556  2 3750  266  240
05557  3 3500  285  257
05558  4 3250  307  276
05559  5 3000  333  300
05560  6 2750  363  327
05561  7 2500  400  360
05562  8 2250  444  400
05563  9 2000  500  450
05564 10 1750  571  514
05565 11 1500  666  600
05566 12 1250  800  720
05567 13 1000 1000  900
05568 14 750  1333 1200
05569 15 500  2000 1800
05570 */
05571 
05572 unsigned alert_delays[]=
05573 {
05574    900000, 225000, 240000, 257142, 276923, 300000,  327272,  360000,
05575    400000, 450000, 514285, 600000, 720000, 900000, 1200000, 1800000
05576 };
05577 
05578 /* ======================================================================= */
05579 
05580 static void alertGlitchFilter(gpioSample_t *sample, int numSamples)
05581 {
05582    int i, j, diff;
05583    uint32_t steadyUs, changedTick, RBitV, LBitV;
05584    uint32_t bit, bitV;
05585 
05586    for (i=0; i<=PI_MAX_USER_GPIO; i++)
05587    {
05588       bit = (1<<i);
05589 
05590       if (monitorBits & bit & gFilterBits)
05591       {
05592          steadyUs    = gpioAlert[i].gfSteadyUs;
05593          RBitV       = gpioAlert[i].gfRBitV;
05594          LBitV       = gpioAlert[i].gfLBitV;
05595          changedTick = gpioAlert[i].gfTick;
05596 
05597          for (j=0; j<numSamples; j++)
05598          {
05599             bitV = sample[j].level & bit;
05600 
05601             if (bitV != LBitV)
05602             {
05603                /* Difference between level and last level.
05604                   Restart steady timer. */
05605 
05606                changedTick = sample[j].tick;
05607                LBitV = bitV;
05608             }
05609 
05610             if (bitV != RBitV)
05611             {
05612                /* Difference between level and reported level. */
05613 
05614                diff = sample[j].tick - changedTick;
05615 
05616                if (diff >= steadyUs)
05617                {
05618                   /* Level stable for steady period. */
05619                   RBitV = bitV;
05620                }
05621                else
05622                {
05623                   /* Keep reporting old level. */
05624 
05625                   sample[j].level ^= bit;
05626                }
05627             }
05628 
05629          }
05630 
05631          gpioAlert[i].gfRBitV = RBitV;
05632          gpioAlert[i].gfLBitV = LBitV;
05633          gpioAlert[i].gfTick  = changedTick;
05634       }
05635    }
05636 }
05637 
05638 static void alertNoiseFilter(gpioSample_t *sample, int numSamples)
05639 {
05640    int i, j, diff;
05641    uint32_t LBitV;
05642    uint32_t bit, bitV;
05643    uint32_t nowTick;
05644 
05645    for (i=0; i<=PI_MAX_USER_GPIO; i++)
05646    {
05647       bit = (1<<i);
05648 
05649       if (monitorBits & bit & nFilterBits)
05650       {
05651          LBitV = gpioAlert[i].nfLBitV;
05652 
05653          for (j=0; j<numSamples; j++)
05654          {
05655             bitV = sample[j].level & bit;
05656             nowTick = sample[j].tick;
05657 
05658             if (gpioAlert[i].nfActive) /* reporting events */
05659             {
05660                diff = nowTick - gpioAlert[i].nfTick2;
05661 
05662                if (diff >= 0)
05663                {
05664                   /* Stop reporting gpio changes */
05665 
05666                   gpioAlert[i].nfActive = 0;
05667                   gpioAlert[i].nfTick1 = nowTick;
05668                }
05669             }
05670             else /* waiting for steady us */
05671             {
05672                if (bitV != LBitV)
05673                {
05674                   diff = nowTick - gpioAlert[i].nfTick1;
05675                   gpioAlert[i].nfTick1 = nowTick;
05676 
05677                   if (diff >= gpioAlert[i].nfSteadyUs)
05678                   {
05679                      /* Start reporting gpio changes */
05680 
05681                      gpioAlert[i].nfRBitV = LBitV;
05682                      gpioAlert[i].nfActive = 1;
05683                      gpioAlert[i].nfTick2 =
05684                         nowTick + gpioAlert[i].nfActiveUs;
05685                   }
05686                }
05687             }
05688 
05689             if (!gpioAlert[i].nfActive)
05690             {
05691                if (bitV != gpioAlert[i].nfRBitV)
05692                   sample[j].level ^= bit;
05693             }
05694 
05695             LBitV = bitV;
05696          }
05697 
05698          gpioAlert[i].nfLBitV = LBitV;
05699 
05700       }
05701    }
05702 }
05703 
05704 static void alertEmit(
05705    gpioSample_t *sample, int numSamples, uint32_t changedBits, uint32_t eTick)
05706 {
05707    uint32_t oldLevel, newLevel;
05708    int32_t diff;
05709    int emit, seqno, emitted;
05710    uint32_t changes, bits, timeoutBits, eventBits;
05711    int d;
05712    int b, n, v;
05713    int err;
05714    int max_emits;
05715    char fifo[32];
05716    /* ensure space for maximum number of watchdog and event notifications */
05717    gpioReport_t report[MAX_REPORT+PI_MAX_USER_GPIO+1+PI_MAX_EVENT+1];
05718 
05719    if (changedBits)
05720    {
05721       if (gpioGetSamples.func)
05722       {
05723          if (gpioGetSamples.ex)
05724          {
05725             (gpioGetSamples.func)
05726                (sample, numSamples, gpioGetSamples.userdata);
05727          }
05728          else
05729          {
05730             (gpioGetSamples.func)(sample, numSamples);
05731          }
05732       }
05733    }
05734 
05735    eventBits = 0;
05736 
05737    if (bscFR != (bscsReg[BSC_FR]&0xffff))
05738    {
05739       bscFR = bscsReg[BSC_FR]&0xffff;
05740       eventAlert[PI_EVENT_BSC].fired = 1;
05741    }
05742 
05743    for (b=0; b<=PI_MAX_EVENT; b++)
05744    {
05745       if (eventAlert[b].fired && (!eventAlert[b].ignore))
05746       {
05747          eventBits |= (1<<b);
05748 
05749          if (eventAlert[b].func)
05750          {
05751             if (eventAlert[b].ex)
05752             {
05753                (eventAlert[b].func)(b, eTick, eventAlert[b].userdata);
05754             }
05755             else
05756             {
05757                (eventAlert[b].func)(b, eTick);
05758             }
05759          }
05760       }
05761 
05762       eventAlert[b].fired = 0;
05763    }
05764 
05765    /* call alert callbacks for each bit transition */
05766 
05767    if (changedBits & alertBits)
05768    {
05769       oldLevel = (reportedLevel & alertBits);
05770 
05771       for (d=0; d<numSamples; d++)
05772       {
05773          newLevel = (sample[d].level & alertBits);
05774 
05775          if (newLevel != oldLevel)
05776          {
05777             changes = (newLevel ^ oldLevel);
05778 
05779             for (b=0; b<=PI_MAX_USER_GPIO; b++)
05780             {
05781                if (changes & (1<<b))
05782                {
05783                   if (newLevel & (1<<b)) v = 1; else v = 0;
05784 
05785                   if (gpioAlert[b].func)
05786                   {
05787                      if (gpioAlert[b].ex)
05788                      {
05789                         (gpioAlert[b].func)
05790                            (b, v, sample[d].tick,
05791                             gpioAlert[b].userdata);
05792                      }
05793                      else
05794                      {
05795                         (gpioAlert[b].func)(b, v, sample[d].tick);
05796                      }
05797                   }
05798                }
05799             }
05800             oldLevel = newLevel;
05801          }
05802       }
05803    }
05804 
05805    /* check for watchdog timeouts */
05806 
05807    timeoutBits = 0;
05808 
05809    if (wdogBits)
05810    {
05811       for (b=0; b<=PI_MAX_USER_GPIO; b++)
05812       {
05813          if (gpioAlert[b].wdSteadyUs)
05814          {
05815             diff = eTick - gpioAlert[b].wdTick;
05816 
05817             if (diff >= gpioAlert[b].wdSteadyUs)
05818             {
05819                timeoutBits |= (1<<b);
05820 
05821                gpioAlert[b].wdTick = eTick;
05822 
05823                if (gpioAlert[b].func)
05824                {
05825                   if (gpioAlert[b].ex)
05826                   {
05827                      (gpioAlert[b].func)(b, PI_TIMEOUT, eTick,
05828                                             gpioAlert[b].userdata);
05829                   }
05830                   else
05831                   {
05832                      (gpioAlert[b].func)(b, PI_TIMEOUT, eTick);
05833                   }
05834                }
05835             }
05836          }
05837       }
05838    }
05839 
05840    for (n=0; n<PI_NOTIFY_SLOTS; n++)
05841    {
05842       if (gpioNotify[n].state == PI_NOTIFY_CLOSING)
05843       {
05844          if (gpioNotify[n].pipe)
05845          {
05846             DBG(DBG_INTERNAL, "close notify pipe %d", gpioNotify[n].fd);
05847             close(gpioNotify[n].fd);
05848 
05849             sprintf(fifo, "/dev/pigpio%d", n);
05850 
05851             unlink(fifo);
05852          }
05853 
05854          gpioNotify[n].state = PI_NOTIFY_CLOSED;
05855       }
05856       else if (gpioNotify[n].state >= PI_NOTIFY_OPENED)
05857       {
05858          bits = gpioNotify[n].bits;
05859 
05860          emit = 0;
05861 
05862          seqno = gpioNotify[n].seqno;
05863 
05864          if (gpioNotify[n].state == PI_NOTIFY_RUNNING)
05865          {
05866             /* check to see if any bits have changed for this
05867                notification.
05868 
05869                bits         is the set of notification bits
05870                changedBits is the set of changed bits
05871             */
05872 
05873             if (changedBits & bits)
05874             {
05875                oldLevel = reportedLevel & bits;
05876 
05877                for (d=0; d<numSamples; d++)
05878                {
05879                   newLevel = sample[d].level & bits;
05880 
05881                   if (newLevel != oldLevel)
05882                   {
05883                      report[emit].seqno = seqno;
05884                      report[emit].flags = 0;
05885                      report[emit].tick  = sample[d].tick;
05886                      report[emit].level = sample[d].level;
05887 
05888                      oldLevel = newLevel;
05889 
05890                      emit++;
05891                      seqno++;
05892                   }
05893                }
05894             }
05895 
05896             /* check to see if any watchdogs are due for this
05897                notification.
05898 
05899                bits        is the set of notification bits
05900                timeoutBits is the set of timed out bits
05901             */
05902 
05903             bits = gpioNotify[n].bits;
05904 
05905             if (timeoutBits & bits)
05906             {
05907                /* at least one watchdog has fired for this
05908                   notification.
05909                */
05910 
05911                for (b=0; b<=PI_MAX_USER_GPIO; b++)
05912                {
05913                   if (timeoutBits & bits & (1<<b))
05914                   {
05915                      if (numSamples)
05916                         newLevel = sample[numSamples-1].level;
05917                      else
05918                         newLevel = reportedLevel;
05919 
05920                      report[emit].seqno = seqno;
05921                      report[emit].flags =
05922                         PI_NTFY_FLAGS_WDOG | PI_NTFY_FLAGS_BIT(b);
05923                      report[emit].tick  = eTick;
05924                      report[emit].level = newLevel;
05925 
05926                      emit++;
05927                      seqno++;
05928                   }
05929                }
05930             }
05931          }
05932 
05933          /* check to see if any events are due
05934 
05935             eventBits is the set of events
05936          */
05937 
05938          if (eventBits & gpioNotify[n].eventBits)
05939          {
05940             for (b=0; b<=PI_MAX_EVENT; b++)
05941             {
05942                if (eventBits & gpioNotify[n].eventBits & (1<<b))
05943                {
05944                   if (numSamples)
05945                      newLevel = sample[numSamples-1].level;
05946                   else
05947                      newLevel = reportedLevel;
05948 
05949                   report[emit].seqno = seqno;
05950                   report[emit].flags = 
05951                      PI_NTFY_FLAGS_EVENT | PI_NTFY_FLAGS_BIT(b);
05952                   report[emit].tick  = eTick;
05953                   report[emit].level = newLevel;
05954 
05955                   emit++;
05956                   seqno++;
05957                }
05958             }
05959          }
05960 
05961          if (!emit)
05962          {
05963             if ((int)(eTick - gpioNotify[n].lastReportTick) > 60000000)
05964             {
05965                if (numSamples)
05966                   newLevel = sample[numSamples-1].level;
05967                else
05968                   newLevel = reportedLevel;
05969 
05970                report[emit].seqno = seqno;
05971                report[emit].flags = PI_NTFY_FLAGS_ALIVE;
05972                report[emit].tick  = eTick;
05973                report[emit].level = newLevel;
05974 
05975                emit++;
05976                seqno++;
05977             }
05978          }
05979 
05980          if (emit)
05981          {
05982             DBG(DBG_FAST_TICK, "notification %d (%d reports, %x-%x)",
05983                n, emit, report[0].seqno,  report[emit-1].seqno);
05984             gpioNotify[n].lastReportTick = eTick;
05985             max_emits = gpioNotify[n].max_emits;
05986 
05987             if (emit > gpioStats.maxEmit) gpioStats.maxEmit = emit;
05988 
05989             emitted = 0;
05990 
05991             while (emit > 0)
05992             {
05993                if (emit > max_emits)
05994                {
05995                   gpioStats.emitFrags++;
05996 
05997                   err = write(gpioNotify[n].fd,
05998                            report+emitted,
05999                            max_emits*sizeof(gpioReport_t));
06000 
06001                   if (err != (max_emits*sizeof(gpioReport_t)))
06002                   {
06003                      if (err < 0)
06004                      {
06005                         if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
06006                         {
06007                            /* serious error, no point continuing */
06008 
06009                            DBG(DBG_ALWAYS, "fd=%d err=%d errno=%d",
06010                               gpioNotify[n].fd, err, errno);
06011 
06012                            DBG(DBG_ALWAYS, "%s", strerror(errno));
06013 
06014                            gpioNotify[n].bits  = 0;
06015                            gpioNotify[n].state = PI_NOTIFY_CLOSING;
06016                            intNotifyBits();
06017                            break;
06018                         }
06019                         else gpioStats.wouldBlockPipeWrite++;
06020                      }
06021                      else
06022                      {
06023                         gpioStats.shortPipeWrite++;
06024                         DBG(DBG_ALWAYS, "emitted %d, asked for %d",
06025                            err/sizeof(gpioReport_t), max_emits);
06026                      }
06027                   }
06028                   else
06029                   {
06030                      gpioStats.goodPipeWrite++;
06031                   }
06032 
06033                   emitted += max_emits;
06034                   emit    -= max_emits;
06035                }
06036                else
06037                {
06038                   err = write(gpioNotify[n].fd,
06039                            report+emitted,
06040                            emit*sizeof(gpioReport_t));
06041 
06042                   if (err != (emit*sizeof(gpioReport_t)))
06043                   {
06044                      if (err < 0)
06045                      {
06046                         if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
06047                         {
06048                            DBG(DBG_ALWAYS, "fd=%d err=%d errno=%d",
06049                               gpioNotify[n].fd, err, errno);
06050 
06051                            DBG(DBG_ALWAYS, "%s", strerror(errno));
06052 
06053                            /* serious error, no point continuing */
06054                            gpioNotify[n].bits  = 0;
06055                            gpioNotify[n].state = PI_NOTIFY_CLOSING;
06056                            intNotifyBits();
06057                            break;
06058                         }
06059                         else gpioStats.wouldBlockPipeWrite++;
06060                      }
06061                      else
06062                      {
06063                         gpioStats.shortPipeWrite++;
06064                         DBG(DBG_ALWAYS, "emitted %d, asked for %d",
06065                            err/sizeof(gpioReport_t), emit);
06066                      }
06067                   }
06068                   else
06069                   {
06070                      gpioStats.goodPipeWrite++;
06071                   }
06072 
06073                   emitted += emit;
06074                   emit = 0;
06075                }
06076             }
06077 
06078             gpioNotify[n].seqno = seqno;
06079          }
06080       }
06081    }
06082 
06083    if (changedBits & scriptBits)
06084    {
06085       for (n=0; n<PI_MAX_SCRIPTS; n++)
06086       {
06087          if ((gpioScript[n].state     == PI_SCRIPT_IN_USE)  &&
06088              (gpioScript[n].run_state == PI_SCRIPT_WAITING) &&
06089              (gpioScript[n].waitBits & changedBits))
06090          {
06091             pthread_mutex_lock(&gpioScript[n].pthMutex);
06092 
06093             if (gpioScript[n].run_state == PI_SCRIPT_WAITING)
06094             {
06095                gpioScript[n].changedBits =
06096                   gpioScript[n].waitBits & changedBits;
06097                pthread_cond_signal(&gpioScript[n].pthCond);
06098             }
06099 
06100             pthread_mutex_unlock(&gpioScript[n].pthMutex);
06101          }
06102       }
06103    }
06104 
06105    if (eventBits & scriptEventBits)
06106    {
06107       for (n=0; n<PI_MAX_SCRIPTS; n++)
06108       {
06109          if ((gpioScript[n].state     == PI_SCRIPT_IN_USE)  &&
06110              (gpioScript[n].run_state == PI_SCRIPT_WAITING) &&
06111              (gpioScript[n].eventBits & eventBits))
06112          {
06113             pthread_mutex_lock(&gpioScript[n].pthMutex);
06114 
06115             if (gpioScript[n].run_state == PI_SCRIPT_WAITING)
06116             {
06117                gpioScript[n].changedBits =
06118                   gpioScript[n].eventBits & eventBits;
06119                pthread_cond_signal(&gpioScript[n].pthCond);
06120             }
06121 
06122             pthread_mutex_unlock(&gpioScript[n].pthMutex);
06123          }
06124       }
06125    }
06126 
06127    if (numSamples) reportedLevel = sample[numSamples-1].level;
06128 }
06129 
06130 static void alertWdogCheck(gpioSample_t *sample, int numSamples)
06131 {
06132    /*
06133    Go through and set the last time each GPIO with a watchdog changed state.
06134    */
06135 
06136    int i, j;
06137    uint32_t LBitV;
06138    uint32_t bit;
06139 
06140    for (i=0; i<=PI_MAX_USER_GPIO; i++)
06141    {
06142       bit = (1<<i);
06143 
06144       if (monitorBits & bit & wdogBits)
06145       {
06146          LBitV = gpioAlert[i].wdLBitV;
06147 
06148          for (j=0; j<numSamples; j++)
06149          {
06150             if ((sample[j].level & bit) != LBitV)
06151             {
06152                LBitV = sample[j].level & bit;
06153                gpioAlert[i].wdTick = sample[j].tick;
06154             }
06155          }
06156 
06157          gpioAlert[i].wdLBitV = LBitV;
06158       }
06159    }
06160 }
06161 
06162 static void * pthAlertThread(void *x)
06163 {
06164    struct timespec req, rem;
06165    uint32_t oldLevel, newLevel, level;
06166    uint32_t oldSlot,  newSlot;
06167    uint32_t expected, ft, sTick;
06168    uint32_t changedBits;
06169    int32_t diff, minDiff, stickInited;
06170    int cycle, pulse;
06171    int numSamples, ticks, i;
06172    int rp, reports, totalSamples;
06173    int stopped;
06174    int moreToDo;
06175    gpioSample_t sample[MAX_SAMPLE];
06176 
06177    req.tv_sec = 0;
06178 
06179    /* don't start until DMA started */
06180 
06181    spinWhileStarting();
06182 
06183    reportedLevel = gpioReg[GPLEV0];
06184 
06185    oldLevel = reportedLevel;
06186 
06187    oldSlot = dmaCurrentSlot(dmaNowAtICB());
06188 
06189    oldSlot = (oldSlot / PULSE_PER_CYCLE) * PULSE_PER_CYCLE;
06190 
06191    cycle = (oldSlot/PULSE_PER_CYCLE);
06192 
06193    pulse = 0;
06194 
06195    stopped = 0;
06196 
06197    moreToDo = 0;
06198 
06199    stickInited = 0;
06200 
06201    sTick = 0;
06202 
06203    minDiff = gpioCfg.clockMicros / 2;
06204 
06205    while (1)
06206    {
06207       /* Check that DMA is running okay */
06208 
06209       if (dmaIn[DMA_CONBLK_AD])
06210       {
06211          if (stopped)
06212          {
06213             DBG(DBG_STARTUP, "****** GOING ******");
06214             stopped = 0;
06215          }
06216       }
06217       else
06218       {
06219          stopped = 1;
06220 
06221          myGpioDelay(5000);
06222 
06223          if (runState == PI_RUNNING)
06224          {
06225             /* should never be executed, leave code just in case */
06226 
06227             gpioCfg.internals |= PI_CFG_STATS;
06228 
06229             dmaInitCbs();
06230             flushMemory();
06231             initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]);
06232             myGpioDelay(5000); /* let DMA run for a while */
06233             oldSlot = dmaCurrentSlot(dmaNowAtICB());
06234             gpioStats.DMARestarts++;
06235          }
06236       }
06237 
06238       newSlot = dmaCurrentSlot(dmaNowAtICB());
06239 
06240       newSlot = (newSlot / PULSE_PER_CYCLE) * PULSE_PER_CYCLE;
06241 
06242       numSamples = 0;
06243 
06244       /*
06245       Extract samples from DMA ring buffer.
06246       */
06247 
06248       while ((oldSlot != newSlot) && (numSamples < MAX_SAMPLE))
06249       {
06250          level = myGetLevel(oldSlot++);
06251 
06252          sample[numSamples].tick  = sTick;
06253          sample[numSamples].level = level;
06254 
06255          numSamples++;
06256 
06257          sTick += gpioCfg.clockMicros;
06258 
06259          if (++pulse >= PULSE_PER_CYCLE)
06260          {
06261             pulse = 0;
06262 
06263             if (++cycle >= bufferCycles)
06264             {
06265                cycle = 0;
06266                oldSlot = 0;
06267             }
06268 
06269             expected = sTick;
06270 
06271             sTick = myGetTick(cycle);
06272 
06273             if (stickInited)
06274             {
06275                diff = sTick - expected;
06276 
06277                if (abs(diff) > minDiff)
06278                {
06279                   ft = sample[numSamples-PULSE_PER_CYCLE].tick;
06280 
06281                   ticks = sTick - ft;
06282 
06283                   for (i=1; i<PULSE_PER_CYCLE; i++)
06284                   {
06285                      sample[numSamples-PULSE_PER_CYCLE+i].tick =
06286                         ((i*ticks)/PULSE_PER_CYCLE) + ft;
06287                   }
06288                }
06289 
06290                diff += (TICKSLOTS/2);
06291 
06292                if (diff < 0)
06293                {
06294                   gpioStats.diffTick[0]++;
06295                }
06296 
06297                else if (diff >= TICKSLOTS)
06298                {
06299                   gpioStats.diffTick[TICKSLOTS-1]++;
06300                }
06301 
06302                else gpioStats.diffTick[diff]++;
06303             }
06304             else
06305             {
06306                stickInited = 1;
06307                numSamples = 0;
06308                if (!(gpioCfg.ifFlags & PI_DISABLE_ALERT))
06309                {
06310                   pthAlertRunning = PI_THREAD_RUNNING;
06311                }
06312             }
06313          }
06314       }
06315 
06316       if (oldSlot == newSlot) moreToDo = 0; else moreToDo = 1;
06317 
06318       /* Apply glitch filter */
06319 
06320       if (numSamples && gFilterBits) alertGlitchFilter(sample, numSamples);
06321 
06322       /* Apply noise filter */
06323 
06324       if (numSamples && nFilterBits) alertNoiseFilter(sample, numSamples);
06325 
06326       /* Compact samples */
06327 
06328       changedBits = 0;
06329       oldLevel &= monitorBits;
06330       reports = 0;
06331       totalSamples = 0;
06332 
06333       for (rp=0; rp<numSamples; rp++)
06334       {
06335          newLevel = (sample[rp].level & monitorBits);
06336 
06337          if (newLevel != oldLevel)
06338          {
06339             sample[reports].tick  = sample[rp].tick;
06340             sample[reports].level = sample[rp].level;
06341             changedBits |= (newLevel ^ oldLevel);
06342             oldLevel = newLevel;
06343 
06344             reports++;
06345 
06346             if (reports >= MAX_REPORT)
06347             {
06348                totalSamples += reports;
06349 
06350                /* Rebase watchdog timeouts */
06351                if (wdogBits) alertWdogCheck(sample, reports);
06352 
06353                gpioStats.numSamples += reports;
06354 
06355                alertEmit(sample, reports, changedBits, sample[rp].tick);
06356 
06357                changedBits = 0;
06358                reports = 0;
06359             }
06360          }
06361       }
06362 
06363       if (reports)
06364       {
06365          totalSamples += reports;
06366 
06367          /* Rebase watchdog timeouts */
06368          if (wdogBits) alertWdogCheck(sample, reports);
06369 
06370          gpioStats.numSamples += reports;
06371       }
06372 
06373       alertEmit(sample, reports, changedBits, sTick);
06374 
06375       if (totalSamples > gpioStats.maxSamples)
06376          gpioStats.maxSamples = numSamples;
06377 
06378       req.tv_sec = 0;
06379       req.tv_nsec = alert_delays[(gpioCfg.internals>>PI_CFG_ALERT_FREQ)&15];
06380 
06381       if (moreToDo)
06382       {
06383          gpioStats.moreToDo++;
06384       }
06385       else
06386       {
06387          gpioStats.alertTicks++;
06388 
06389          while (nanosleep(&req, &rem))
06390          {
06391             req.tv_sec  = rem.tv_sec;
06392             req.tv_nsec = rem.tv_nsec;
06393          }
06394       }
06395    }
06396 
06397    return 0;
06398 }
06399 
06400 /* ======================================================================= */
06401 
06402 static int scrPop(gpioScript_t *s, int *SP, int *S)
06403 {
06404    if ((*SP) > 0)
06405    {
06406       return S[--(*SP)];
06407    }
06408    else
06409    {
06410       s->run_state = PI_SCRIPT_FAILED;
06411       DBG(DBG_ALWAYS, "script %d too many pops", s->id);
06412       return 0;
06413    }
06414 }
06415 
06416 /* ----------------------------------------------------------------------- */
06417 
06418 static void scrPush(gpioScript_t *s, int *SP, int *S, int val)
06419 {
06420    if ((*SP) < PI_SCRIPT_STACK_SIZE)
06421    {
06422       S[(*SP)++] = val;
06423    }
06424    else
06425    {
06426       s->run_state = PI_SCRIPT_FAILED;
06427       DBG(DBG_ALWAYS, "script %d too many pushes", s->id);
06428    }
06429 }
06430 
06431 /* ----------------------------------------------------------------------- */
06432 
06433 static void scrSwap(int *v1, int *v2)
06434 {
06435    int t;
06436 
06437    t=*v1; *v1=*v2; *v2= t;
06438 }
06439 
06440 /* ----------------------------------------------------------------------- */
06441 
06442 static int scrEvtWait(gpioScript_t *s, uint32_t bits)
06443 {
06444    pthread_mutex_lock(&s->pthMutex);
06445 
06446    if (s->request == PI_SCRIPT_RUN)
06447    {
06448       s->run_state = PI_SCRIPT_WAITING;
06449       s->eventBits = bits;
06450       intScriptEventBits();
06451 
06452       pthread_cond_wait(&s->pthCond, &s->pthMutex);
06453 
06454       s->waitBits = 0;
06455       intScriptEventBits();
06456       s->run_state = PI_SCRIPT_RUNNING;
06457    }
06458 
06459    pthread_mutex_unlock(&s->pthMutex);
06460 
06461    return s->changedBits;
06462 }
06463 
06464 /* ----------------------------------------------------------------------- */
06465 
06466 static int scrWait(gpioScript_t *s, uint32_t bits)
06467 {
06468    pthread_mutex_lock(&s->pthMutex);
06469 
06470    if (s->request == PI_SCRIPT_RUN)
06471    {
06472       s->run_state = PI_SCRIPT_WAITING;
06473       s->waitBits = bits;
06474       intScriptBits();
06475 
06476       pthread_cond_wait(&s->pthCond, &s->pthMutex);
06477 
06478       s->waitBits = 0;
06479       intScriptBits();
06480       s->run_state = PI_SCRIPT_RUNNING;
06481    }
06482 
06483    pthread_mutex_unlock(&s->pthMutex);
06484 
06485    return s->changedBits;
06486 }
06487 
06488 /* ----------------------------------------------------------------------- */
06489 
06490 static int scrSys(char *cmd, uint32_t p1, uint32_t p2)
06491 {
06492    char buf[1024];
06493    int status;
06494 
06495    if (!myScriptNameValid(cmd))
06496       SOFT_ERROR(PI_BAD_SCRIPT_NAME, "bad script name (%s)", cmd);
06497 
06498    snprintf(buf, sizeof(buf), "/opt/pigpio/cgi/%s %u %u", cmd, p1, p2);
06499 
06500    DBG(DBG_USER, "%s", buf);
06501 
06502    status = system(buf);
06503 
06504    if (status < 0) status = PI_BAD_SHELL_STATUS;
06505 
06506    return status;
06507 }
06508 
06509 /* ----------------------------------------------------------------------- */
06510 
06511 static void *pthScript(void *x)
06512 {
06513    gpioScript_t *s;
06514    cmdInstr_t instr;
06515    int p1, p2, p1o, p2o, p3o, *t1, *t2;
06516    int PC, A, F, SP;
06517    int S[PI_SCRIPT_STACK_SIZE];
06518    char buf[CMD_MAX_EXTENSION];
06519 
06520 
06521    S[0] = 0; /* to prevent compiler warning */
06522 
06523    s = x;
06524 
06525    while ((volatile int)s->request != PI_SCRIPT_DELETE)
06526    {
06527       pthread_mutex_lock(&s->pthMutex);
06528       s->run_state = PI_SCRIPT_HALTED;
06529       pthread_cond_wait(&s->pthCond, &s->pthMutex);
06530       pthread_mutex_unlock(&s->pthMutex);
06531 
06532       s->run_state = PI_SCRIPT_RUNNING;
06533 
06534       A  = 0;
06535       F  = 0;
06536       PC = 0;
06537       SP = 0;
06538 
06539       while (((volatile int)s->request   == PI_SCRIPT_RUN    ) &&
06540                            (s->run_state == PI_SCRIPT_RUNNING))
06541       {
06542          instr = s->script.instr[PC];
06543 
06544          p1o = instr.p[1];
06545          p2o = instr.p[2];
06546 
06547          if      (instr.opt[1] == CMD_VAR) instr.p[1] = s->script.var[p1o];
06548          else if (instr.opt[1] == CMD_PAR) instr.p[1] = s->script.par[p1o];
06549 
06550          if      (instr.opt[2] == CMD_VAR) instr.p[2] = s->script.var[p2o];
06551          else if (instr.opt[2] == CMD_PAR) instr.p[2] = s->script.par[p2o];
06552 /*
06553          fprintf(stderr, "PC=%d cmd=%d p1o=%d p1=%d p2o=%d p2=%d\n",
06554             PC, instr.p[0], p1o, instr.p[1], p2o, instr.p[2]);
06555          fflush(stderr);
06556 */
06557          if (instr.p[0] < PI_CMD_SCRIPT)
06558          {
06559             if (instr.p[3])
06560             {
06561                if ((instr.p[3] == sizeof(int)) && ((instr.opt[3] == CMD_VAR) || (instr.opt[3] == CMD_PAR)))
06562                {
06563                   /* Hack to allow register use in 3rd parameter */
06564                   memcpy((char*)&p3o, (char *)instr.p[4], sizeof(int));
06565                   if (instr.opt[3] == CMD_VAR) memcpy(buf, (char *)&(s->script.var[p3o]), sizeof(int));
06566                   else                         memcpy(buf, (char *)&(s->script.par[p3o]), sizeof(int));
06567                }
06568                else
06569                {
06570                   memcpy(buf, (char *)instr.p[4], instr.p[3]);
06571                }
06572             }
06573 
06574             A = myDoCommand(instr.p, sizeof(buf)-1, buf);
06575 
06576             F = A;
06577 
06578             PC++;
06579          }
06580          else
06581          {
06582             p1 = instr.p[1];
06583             p2 = instr.p[2];
06584 
06585             switch (instr.p[0])
06586             {
06587                case PI_CMD_ADD:   A+=p1; F=A;                     PC++; break;
06588 
06589                case PI_CMD_AND:   A&=p1; F=A;                     PC++; break;
06590 
06591                case PI_CMD_CALL:  scrPush(s, &SP, S, PC+1);    PC = p1; break;
06592 
06593                case PI_CMD_CMP:   F=A-p1;                         PC++; break;
06594 
06595                case PI_CMD_DCR:
06596                   if (instr.opt[1] == CMD_PAR)
06597                      {--s->script.par[p1o]; F=s->script.par[p1o];}
06598                   else
06599                      {--s->script.var[p1o]; F=s->script.var[p1o];}
06600                   PC++;
06601                   break;
06602 
06603                case PI_CMD_DCRA:  --A; F=A;                       PC++; break;
06604 
06605                case PI_CMD_DIV:   A/=p1; F=A;                     PC++; break;
06606 
06607                case PI_CMD_HALT:  s->run_state = PI_SCRIPT_HALTED;      break;
06608 
06609                case PI_CMD_EVTWT: A=scrEvtWait(s, p1); F=A;       PC++; break;
06610 
06611                case PI_CMD_INR:
06612                   if (instr.opt[1] == CMD_PAR)
06613                      {++s->script.par[p1o]; F=s->script.par[p1o];}
06614                   else
06615                      {++s->script.var[p1o]; F=s->script.var[p1o];}
06616                   PC++;
06617                   break;
06618 
06619                case PI_CMD_INRA:  ++A; F=A;                       PC++; break;
06620 
06621                case PI_CMD_JM:    if (F<0)  PC=p1; else PC++;           break;
06622 
06623                case PI_CMD_JMP:   PC=p1;                                break;
06624 
06625                case PI_CMD_JNZ:   if (F)    PC=p1; else PC++;           break;
06626 
06627                case PI_CMD_JP:    if (F>=0) PC=p1; else PC++;           break;
06628 
06629                case PI_CMD_JZ:    if (!F)   PC=p1; else PC++;           break;
06630 
06631                case PI_CMD_LD:
06632                   if (instr.opt[1] == CMD_PAR) s->script.par[p1o]=p2;
06633                   else                         s->script.var[p1o]=p2;
06634                   PC++;
06635                   break;
06636 
06637                case PI_CMD_LDA:   A=p1;                           PC++; break;
06638 
06639                case PI_CMD_LDAB:
06640                   if ((p1 >= 0) && (p1 < sizeof(buf))) A = buf[p1];
06641                   PC++;
06642                   break;
06643 
06644                case PI_CMD_MLT:   A*=p1; F=A;                     PC++; break;
06645 
06646                case PI_CMD_MOD:   A%=p1; F=A;                     PC++; break;
06647 
06648                case PI_CMD_OR:    A|=p1; F=A;                     PC++; break;
06649 
06650                case PI_CMD_POP:
06651                   if (instr.opt[1] == CMD_PAR)
06652                      s->script.par[p1o]=scrPop(s, &SP, S);
06653                   else
06654                      s->script.var[p1o]=scrPop(s, &SP, S);
06655                   PC++;
06656                   break;
06657 
06658                case PI_CMD_POPA:  A=scrPop(s, &SP, S);            PC++; break;
06659 
06660                case PI_CMD_PUSH:
06661                   if (instr.opt[1] == CMD_PAR)
06662                      scrPush(s, &SP, S, s->script.par[p1o]);
06663                   else
06664                      scrPush(s, &SP, S, s->script.var[p1o]);
06665                   PC++;
06666                   break;
06667 
06668                case PI_CMD_PUSHA: scrPush(s, &SP, S, A);          PC++; break;
06669 
06670                case PI_CMD_RET:   PC=scrPop(s, &SP, S);                 break;
06671 
06672                case PI_CMD_RL:
06673                   if (instr.opt[1] == CMD_PAR)
06674                      {s->script.par[p1o]<<=p2; F=s->script.par[p1o];}
06675                   else
06676                      {s->script.var[p1o]<<=p2; F=s->script.var[p1o];}
06677                   PC++;
06678                   break;
06679 
06680                case PI_CMD_RLA:   A<<=p1; F=A;                    PC++; break;
06681 
06682                case PI_CMD_RR:
06683                   if (instr.opt[1] == CMD_PAR)
06684                      {s->script.par[p1o]>>=p2; F=s->script.par[p1o];}
06685                   else
06686                      {s->script.var[p1o]>>=p2; F=s->script.var[p1o];}
06687                   PC++;
06688                   break;
06689 
06690                case PI_CMD_RRA:   A>>=p1; F=A;                    PC++; break;
06691 
06692                case PI_CMD_STA:
06693                   if (instr.opt[1] == CMD_PAR) s->script.par[p1o]=A;
06694                   else                         s->script.var[p1o]=A;
06695                   PC++;
06696                   break;
06697 
06698                case PI_CMD_STAB:
06699                   if ((p1 >= 0) && (p1 < sizeof(buf))) buf[p1] = A;
06700                   PC++;
06701                   break;
06702 
06703                case PI_CMD_SUB:   A-=p1; F=A;                     PC++; break;
06704 
06705                case PI_CMD_SYS:
06706                   A=scrSys((char*)instr.p[4], A, *(gpioReg + GPLEV0));
06707                   F=A;
06708                   PC++;
06709                   break;
06710 
06711                case PI_CMD_WAIT:  A=scrWait(s, p1); F=A;          PC++; break;
06712 
06713                case PI_CMD_X:
06714                   if (instr.opt[1] == CMD_PAR) t1 = &s->script.par[p1o];
06715                   else                         t1 = &s->script.var[p1o];
06716 
06717                   if (instr.opt[2] == CMD_PAR) t2 = &s->script.par[p2o];
06718                   else                         t2 = &s->script.var[p2o];
06719 
06720                   scrSwap(t1, t2);
06721                   PC++;
06722                   break;
06723 
06724                case PI_CMD_XA:
06725                   if (instr.opt[1] == CMD_PAR)
06726                      scrSwap(&s->script.par[p1o], &A);
06727                   else
06728                      scrSwap(&s->script.var[p1o], &A);
06729                   PC++;
06730                   break;
06731 
06732                case PI_CMD_XOR:   A^=p1; F=A;                     PC++; break;
06733 
06734             }
06735          }
06736 
06737          if (PC >= s->script.instrs) s->run_state = PI_SCRIPT_HALTED;
06738 
06739       }
06740 
06741       if ((volatile int)s->request == PI_SCRIPT_HALT)
06742          s->run_state = PI_SCRIPT_HALTED;
06743 
06744    }
06745 
06746    return 0;
06747 }
06748 
06749 /* ----------------------------------------------------------------------- */
06750 
06751 static void * pthTimerTick(void *x)
06752 {
06753    gpioTimer_t *tp;
06754    struct timespec req, rem;
06755 
06756    tp = x;
06757 
06758    while (1)
06759    {
06760       req.tv_sec  = tp->millis / THOUSAND;
06761       req.tv_nsec = (tp->millis % THOUSAND) * THOUSAND * THOUSAND;
06762 
06763       while (nanosleep(&req, &rem))
06764       {
06765          req.tv_sec  = rem.tv_sec;
06766          req.tv_nsec = rem.tv_nsec;
06767       }
06768 
06769       if (tp->ex) (tp->func)(tp->userdata);
06770       else        (tp->func)();
06771    }
06772 
06773    return 0;
06774 }
06775 
06776 /* ----------------------------------------------------------------------- */
06777 
06778 
06779 static void * pthFifoThread(void *x)
06780 {
06781    char buf[CMD_MAX_EXTENSION];
06782    int idx, flags, len, res, i;
06783    uint32_t p[CMD_P_ARR];
06784    cmdCtlParse_t ctl;
06785    uint32_t *param;
06786    char v[CMD_MAX_EXTENSION];
06787 
06788    myCreatePipe(PI_INPFIFO, 0662);
06789 
06790    if ((inpFifo = fopen(PI_INPFIFO, "r+")) == NULL)
06791       SOFT_ERROR((void*)PI_INIT_FAILED, "fopen %s failed(%m)", PI_INPFIFO);
06792 
06793    myCreatePipe(PI_OUTFIFO, 0664);
06794 
06795    if ((outFifo = fopen(PI_OUTFIFO, "w+")) == NULL)
06796       SOFT_ERROR((void*)PI_INIT_FAILED, "fopen %s failed (%m)", PI_OUTFIFO);
06797 
06798    /* set outFifo non-blocking */
06799 
06800    flags = fcntl(fileno(outFifo), F_GETFL, 0);
06801    fcntl(fileno(outFifo), F_SETFL, flags | O_NONBLOCK);
06802 
06803    /* don't start until DMA started */
06804 
06805    spinWhileStarting();
06806 
06807    while (1)
06808    {
06809       if (fgets(buf, sizeof(buf), inpFifo) == NULL)
06810          SOFT_ERROR((void*)PI_INIT_FAILED, "fifo fgets failed (%m)");
06811 
06812       len = strlen(buf);
06813 
06814       if (len)
06815       {
06816         --len;
06817         buf[len] = 0; /* replace terminating */
06818       }
06819 
06820       ctl.eaten = 0;
06821       idx = 0;
06822 
06823       while (((ctl.eaten)<len) && (idx >= 0))
06824       {
06825          if ((idx=cmdParse(buf, p, CMD_MAX_EXTENSION, v, &ctl)) >= 0)
06826          {
06827             /* make sure extensions are null terminated */
06828 
06829             v[p[3]] = 0;
06830 
06831             res = myDoCommand(p, sizeof(v)-1, v);
06832 
06833             switch (cmdInfo[idx].rv)
06834             {
06835                case 0:
06836                   fprintf(outFifo, "%d\n", res);
06837                   break;
06838 
06839                case 1:
06840                   fprintf(outFifo, "%d\n", res);
06841                   break;
06842 
06843                case 2:
06844                   fprintf(outFifo, "%d\n", res);
06845                   break;
06846 
06847                case 3:
06848                   fprintf(outFifo, "%08X\n", res);
06849                   break;
06850 
06851                case 4:
06852                   fprintf(outFifo, "%u\n", res);
06853                   break;
06854 
06855                case 5:
06856                   fprintf(outFifo, "%s", cmdUsage);
06857                   break;
06858 
06859                case 6:
06860                   fprintf(outFifo, "%d", res);
06861                   if (res > 0)
06862                   {
06863                      for (i=0; i<res; i++)
06864                      {
06865                         fprintf(outFifo, " %d", v[i]);
06866                      }
06867                   }
06868                   fprintf(outFifo, "\n");
06869                   break;
06870 
06871                case 7:
06872                   if (res < 0) fprintf(outFifo, "%d\n", res);
06873                   else
06874                   {
06875                      fprintf(outFifo, "%d", res);
06876                      param = (uint32_t *)v;
06877                      for (i=0; i<PI_MAX_SCRIPT_PARAMS; i++)
06878                      {
06879                         fprintf(outFifo, " %d", param[i]);
06880                      }
06881                      fprintf(outFifo, "\n");
06882                   }
06883                   break;
06884             }
06885          }
06886          else fprintf(outFifo, "%d\n", PI_BAD_FIFO_COMMAND);
06887       }
06888 
06889       fflush(outFifo);
06890    }
06891 
06892    return 0;
06893 }
06894 
06895 /* ----------------------------------------------------------------------- */
06896 
06897 static void *pthSocketThreadHandler(void *fdC)
06898 {
06899    int sock = *(int*)fdC;
06900    uint32_t p[10];
06901    int opt;
06902    char buf[CMD_MAX_EXTENSION];
06903 
06904    free(fdC);
06905 
06906    /* Disable the Nagle algorithm. */
06907    opt = 1;
06908    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int));
06909 
06910    while (1)
06911    {
06912       if (recv(sock, p, 16, MSG_WAITALL) != 16) break;
06913 
06914       if (p[3])
06915       {
06916          if (p[3] < sizeof(buf))
06917          {
06918             /* read extension into buf */
06919             if (recv(sock, buf, p[3], MSG_WAITALL) != p[3])
06920             {
06921                /* Serious error.  No point continuing. */
06922                DBG(DBG_ALWAYS,
06923                   "recv failed for %d bytes, sock=%d", p[3], sock);
06924 
06925                closeOrphanedNotifications(-1, sock);
06926 
06927                close(sock);
06928 
06929                return 0;
06930             }
06931          }
06932          else
06933          {
06934             /* Serious error.  No point continuing. */
06935             DBG(DBG_ALWAYS,
06936                "ext too large %d(%d), sock=%d", p[3], sizeof(buf), sock);
06937 
06938             closeOrphanedNotifications(-1, sock);
06939 
06940             close(sock);
06941 
06942             return 0;
06943          }
06944       }
06945 
06946       /* add null terminator in case it's a string */
06947 
06948       buf[p[3]] = 0;
06949 
06950       switch (p[0])
06951       {
06952          case PI_CMD_NOIB:
06953 
06954             p[3] = gpioNotifyOpenInBand(sock);
06955 
06956            /* Enable the Nagle algorithm. */
06957             opt = 0;
06958             setsockopt(
06959                sock, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(int));
06960 
06961             break;
06962 
06963          case PI_CMD_PROCP:
06964             p[3] = myDoCommand(p, sizeof(buf)-1, buf+sizeof(int));
06965             if (((int)p[3]) >= 0)
06966             {
06967                memcpy(buf, &p[3], 4);
06968                p[3] = 4 + (4*PI_MAX_SCRIPT_PARAMS);
06969             }
06970             break;
06971 
06972          default:
06973             p[3] = myDoCommand(p, sizeof(buf)-1, buf);
06974       }
06975 
06976       if (write(sock, p, 16) == -1) { /* ignore errors */ }
06977 
06978       switch (p[0])
06979       {
06980          /* extensions */
06981 
06982          case PI_CMD_BI2CZ:
06983          case PI_CMD_BSCX:
06984          case PI_CMD_CF2:
06985          case PI_CMD_FL:
06986          case PI_CMD_FR:
06987          case PI_CMD_I2CPK:
06988          case PI_CMD_I2CRD:
06989          case PI_CMD_I2CRI:
06990          case PI_CMD_I2CRK:
06991          case PI_CMD_I2CZ:
06992          case PI_CMD_PROCP:
06993          case PI_CMD_SERR:
06994          case PI_CMD_SLR:
06995          case PI_CMD_SPIX:
06996          case PI_CMD_SPIR:
06997          case PI_CMD_BSPIX:
06998 
06999             if (((int)p[3]) > 0)
07000             {
07001                if (write(sock, buf, p[3]) == 1) { /* ignore errors */ }
07002             }
07003             break;
07004 
07005          default:
07006            break;
07007       }
07008    }
07009 
07010    closeOrphanedNotifications(-1, sock);
07011 
07012    close(sock);
07013 
07014    return 0;
07015 }
07016 
07017 static int addrAllowed(struct sockaddr *saddr)
07018 {
07019    int i;
07020    uint32_t addr;
07021 
07022    if (!numSockNetAddr) return 1;
07023 
07024    // FIXME: add IPv6 whitelisting support
07025    if (saddr->sa_family != AF_INET) return 0;
07026 
07027    addr = ((struct sockaddr_in *) saddr)->sin_addr.s_addr;
07028 
07029    for (i=0; i<numSockNetAddr; i++)
07030    {
07031       if (addr == sockNetAddr[i]) return 1;
07032    }
07033    return 0;
07034 }
07035 
07036 /* ----------------------------------------------------------------------- */
07037 
07038 static void * pthSocketThread(void *x)
07039 {
07040    int fdC=0, c, *sock;
07041    struct sockaddr_storage client;
07042    pthread_attr_t attr;
07043 
07044    if (pthread_attr_init(&attr))
07045       SOFT_ERROR((void*)PI_INIT_FAILED,
07046          "pthread_attr_init failed (%m)");
07047 
07048    if (pthread_attr_setstacksize(&attr, STACK_SIZE))
07049       SOFT_ERROR((void*)PI_INIT_FAILED,
07050          "pthread_attr_setstacksize failed (%m)");
07051 
07052    if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
07053       SOFT_ERROR((void*)PI_INIT_FAILED,
07054          "pthread_attr_setdetachstate failed (%m)");
07055 
07056    /* fdSock opened in gpioInitialise so that we can treat
07057       failure to bind as fatal. */
07058 
07059    listen(fdSock, 100);
07060 
07061    c = sizeof(client);
07062 
07063    /* don't start until DMA started */
07064 
07065    spinWhileStarting();
07066 
07067    while (fdC >= 0)
07068    {
07069       pthread_t thr;
07070 
07071       fdC = accept(fdSock, (struct sockaddr *)&client, (socklen_t*)&c);
07072 
07073       closeOrphanedNotifications(-1, fdC);
07074 
07075       if (addrAllowed((struct sockaddr *)&client))
07076       {
07077          sock = malloc(sizeof(int));
07078 
07079          *sock = fdC;
07080 
07081          if (pthread_create
07082             (&thr, &attr, pthSocketThreadHandler, (void*) sock) < 0)
07083             SOFT_ERROR((void*)PI_INIT_FAILED,
07084                "socket pthread_create failed (%m)");
07085       }
07086       else
07087       {
07088          close(fdC);
07089       }
07090    }
07091 
07092    if (fdC < 0)
07093       SOFT_ERROR((void*)PI_INIT_FAILED, "accept failed (%m)");
07094 
07095    return 0;
07096 }
07097 
07098 /* ======================================================================= */
07099 
07100 static void initCheckLockFile(void)
07101 {
07102    int fd;
07103    int count;
07104    int pid;
07105    int err;
07106    int delete;
07107    char str[20];
07108 
07109    fd = open(PI_LOCKFILE, O_RDONLY);
07110 
07111    if (fd != -1)
07112    {
07113       DBG(DBG_STARTUP, "lock file exists");
07114       delete = 1;
07115 
07116       count = read(fd, str, sizeof(str)-1);
07117 
07118       if (count)
07119       {
07120          pid = atoi(str);
07121          err = kill(pid, 0);
07122          if (!err) delete = 0; /* process still exists */
07123          DBG(DBG_STARTUP, "lock file pid=%d err=%d", pid, err);
07124       }
07125 
07126       close(fd);
07127       DBG(DBG_STARTUP, "lock file delete=%d", delete);
07128 
07129       if (delete) unlink(PI_LOCKFILE);
07130    }
07131 }
07132 
07133 static int initGrabLockFile(void)
07134 {
07135    int fd;
07136    int lockResult;
07137    char pidStr[20];
07138 
07139    initCheckLockFile();
07140 
07141    /* try to grab the lock file */
07142 
07143    fd = open(PI_LOCKFILE, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0644);
07144 
07145    if (fd != -1)
07146    {
07147       lockResult = flock(fd, LOCK_EX|LOCK_NB);
07148 
07149       if(lockResult == 0)
07150       {
07151          sprintf(pidStr, "%d\n", (int)getpid());
07152 
07153          if (write(fd, pidStr, strlen(pidStr)) == -1)
07154          {
07155             /* ignore errors */
07156          }
07157       }
07158       else
07159       {
07160          close(fd);
07161          return -1;
07162       }
07163    }
07164 
07165    return fd;
07166 }
07167 
07168 /* ----------------------------------------------------------------------- */
07169 
07170 static uint32_t * initMapMem(int fd, uint32_t addr, uint32_t len)
07171 {
07172     return (uint32_t *) mmap(0, len,
07173        PROT_READ|PROT_WRITE|PROT_EXEC,
07174        MAP_SHARED|MAP_LOCKED,
07175        fd, addr);
07176 }
07177 
07178 /* ----------------------------------------------------------------------- */
07179 
07180 static int initCheckPermitted(void)
07181 {
07182    DBG(DBG_STARTUP, "");
07183 
07184    if ((fdMem = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
07185    {
07186       DBG(DBG_ALWAYS,
07187          "\n" \
07188          "+---------------------------------------------------------+\n" \
07189          "|Sorry, you don't have permission to run this program.    |\n" \
07190          "|Try running as root, e.g. precede the command with sudo. |\n" \
07191          "+---------------------------------------------------------+\n\n");
07192       return -1;
07193    }
07194    return 0;
07195 }
07196 
07197 /* ----------------------------------------------------------------------- */
07198 
07199 static int initPeripherals(void)
07200 {
07201    uint32_t dmaBase;
07202 
07203    DBG(DBG_STARTUP, "");
07204 
07205    gpioReg = initMapMem(fdMem, GPIO_BASE, GPIO_LEN);
07206 
07207    if (gpioReg == MAP_FAILED)
07208       SOFT_ERROR(PI_INIT_FAILED, "mmap gpio failed (%m)");
07209 
07210    /* dma channels 0-14 share one page, 15 has another */
07211 
07212    if (gpioCfg.DMAprimaryChannel < 15)
07213    {
07214       dmaBase = DMA_BASE;
07215    }
07216    else dmaBase = DMA15_BASE;
07217 
07218    dmaReg = initMapMem(fdMem, dmaBase,  DMA_LEN);
07219 
07220    if (dmaReg == MAP_FAILED)
07221       SOFT_ERROR(PI_INIT_FAILED, "mmap dma failed (%m)");
07222 
07223    if (gpioCfg.DMAprimaryChannel < 15)
07224    {
07225       dmaIn =  dmaReg + (gpioCfg.DMAprimaryChannel   * 0x40);
07226       dmaOut = dmaReg + (gpioCfg.DMAsecondaryChannel * 0x40);
07227    }
07228 
07229    DBG(DBG_STARTUP, "DMA #%d @ %08X @ %08X",
07230       gpioCfg.DMAprimaryChannel, dmaBase, (uint32_t)dmaIn);
07231 
07232    DBG(DBG_STARTUP, "debug reg is %08X", dmaIn[DMA_DEBUG]);
07233 
07234    clkReg  = initMapMem(fdMem, CLK_BASE,  CLK_LEN);
07235 
07236    if (clkReg == MAP_FAILED)
07237       SOFT_ERROR(PI_INIT_FAILED, "mmap clk failed (%m)");
07238 
07239    systReg  = initMapMem(fdMem, SYST_BASE,  SYST_LEN);
07240 
07241    if (systReg == MAP_FAILED)
07242       SOFT_ERROR(PI_INIT_FAILED, "mmap syst failed (%m)");
07243 
07244    spiReg  = initMapMem(fdMem, SPI_BASE,  SPI_LEN);
07245 
07246    if (spiReg == MAP_FAILED)
07247       SOFT_ERROR(PI_INIT_FAILED, "mmap spi failed (%m)");
07248 
07249    pwmReg  = initMapMem(fdMem, PWM_BASE,  PWM_LEN);
07250 
07251    if (pwmReg == MAP_FAILED)
07252       SOFT_ERROR(PI_INIT_FAILED, "mmap pwm failed (%m)");
07253 
07254    pcmReg  = initMapMem(fdMem, PCM_BASE,  PCM_LEN);
07255 
07256    if (pcmReg == MAP_FAILED)
07257       SOFT_ERROR(PI_INIT_FAILED, "mmap pcm failed (%m)");
07258 
07259    auxReg  = initMapMem(fdMem, AUX_BASE,  AUX_LEN);
07260 
07261    if (auxReg == MAP_FAILED)
07262       SOFT_ERROR(PI_INIT_FAILED, "mmap aux failed (%m)");
07263 
07264    padsReg  = initMapMem(fdMem, PADS_BASE,  PADS_LEN);
07265 
07266    if (padsReg == MAP_FAILED)
07267       SOFT_ERROR(PI_INIT_FAILED, "mmap pads failed (%m)");
07268 
07269    bscsReg  = initMapMem(fdMem, BSCS_BASE,  BSCS_LEN);
07270 
07271    if (bscsReg == MAP_FAILED)
07272       SOFT_ERROR(PI_INIT_FAILED, "mmap bscs failed (%m)");
07273 
07274    return 0;
07275 }
07276 
07277 /* ----------------------------------------------------------------------- */
07278 
07279 static int initZaps
07280    (int  pmapFd, void *virtualBase, int  basePage, int  pages)
07281 {
07282    int n;
07283    long index;
07284    off_t offset;
07285    ssize_t t;
07286    uint32_t physical;
07287    int status;
07288    uint32_t pageAdr;
07289    unsigned long long pa;
07290 
07291    DBG(DBG_STARTUP, "");
07292 
07293    status = 0;
07294 
07295    pageAdr = (uint32_t) dmaVirt[basePage];
07296 
07297    index  = ((uint32_t)virtualBase / PAGE_SIZE) * 8;
07298 
07299    offset = lseek(pmapFd, index, SEEK_SET);
07300 
07301    if (offset != index)
07302       SOFT_ERROR(PI_INIT_FAILED, "lseek pagemap failed (%m)");
07303 
07304    for (n=0; n<pages; n++)
07305    {
07306       t = read(pmapFd, &pa, sizeof(pa));
07307 
07308       if (t != sizeof(pa))
07309          SOFT_ERROR(PI_INIT_FAILED, "read pagemap failed (%m)");
07310 
07311       DBG(DBG_STARTUP, "pf%d=%016llX", n, pa);
07312 
07313       physical = 0x3FFFFFFF & (PAGE_SIZE * (pa & 0xFFFFFFFF));
07314 
07315       if (physical)
07316       {
07317          dmaBus[basePage+n] = (dmaPage_t *) (physical | pi_dram_bus);
07318 
07319          dmaVirt[basePage+n] = mmap
07320          (
07321             (void *)pageAdr,
07322             PAGE_SIZE,
07323             PROT_READ|PROT_WRITE,
07324             MAP_SHARED|MAP_FIXED|MAP_LOCKED|MAP_NORESERVE,
07325             fdMem,
07326             physical
07327          );
07328       }
07329       else status = 1;
07330 
07331       pageAdr += PAGE_SIZE;
07332    }
07333 
07334    return status;
07335 }
07336 
07337 /* ----------------------------------------------------------------------- */
07338 
07339 static int initPagemapBlock(int block)
07340 {
07341    int trys, ok;
07342    unsigned pageNum;
07343 
07344    DBG(DBG_STARTUP, "block=%d", block);
07345 
07346    dmaPMapBlk[block] = mmap(
07347        0, (PAGES_PER_BLOCK*PAGE_SIZE),
07348        PROT_READ|PROT_WRITE,
07349        MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_LOCKED,
07350        -1, 0);
07351 
07352    if (dmaPMapBlk[block] == MAP_FAILED)
07353       SOFT_ERROR(PI_INIT_FAILED, "mmap dma block %d failed (%m)", block);
07354 
07355    /* force allocation of physical memory */
07356 
07357    memset((void *)dmaPMapBlk[block], 0xAA, (PAGES_PER_BLOCK*PAGE_SIZE));
07358 
07359    memset((void *)dmaPMapBlk[block], 0xFF, (PAGES_PER_BLOCK*PAGE_SIZE));
07360 
07361    memset((void *)dmaPMapBlk[block], 0, (PAGES_PER_BLOCK*PAGE_SIZE));
07362 
07363    pageNum = block * PAGES_PER_BLOCK;
07364 
07365    dmaVirt[pageNum] = mmap(
07366        0, (PAGES_PER_BLOCK*PAGE_SIZE),
07367        PROT_READ|PROT_WRITE,
07368        MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_LOCKED,
07369        -1, 0);
07370 
07371    if (dmaVirt[pageNum] == MAP_FAILED)
07372       SOFT_ERROR(PI_INIT_FAILED, "mmap dma block %d failed (%m)", block);
07373 
07374    munmap(dmaVirt[pageNum], PAGES_PER_BLOCK*PAGE_SIZE);
07375 
07376    trys = 0;
07377    ok = 0;
07378 
07379    while ((trys < 10) && !ok)
07380    {
07381       if (initZaps(fdPmap,
07382                     dmaPMapBlk[block],
07383                     pageNum,
07384                     PAGES_PER_BLOCK) == 0) ok = 1;
07385       else myGpioDelay(50000);
07386 
07387       ++trys;
07388    }
07389 
07390    if (!ok) SOFT_ERROR(PI_INIT_FAILED, "initZaps failed");
07391 
07392    return 0;
07393 }
07394 
07395 static int initMboxBlock(int block)
07396 {
07397    int n, ok;
07398    unsigned page;
07399    uintptr_t virtualAdr;
07400    uintptr_t busAdr;
07401 
07402    DBG(DBG_STARTUP, "block=%d", block);
07403 
07404    ok = mbDMAAlloc
07405       (&dmaMboxBlk[block], PAGES_PER_BLOCK * PAGE_SIZE, pi_mem_flag);
07406 
07407    if (!ok) SOFT_ERROR(PI_INIT_FAILED, "init mbox zaps failed");
07408 
07409    page = block * PAGES_PER_BLOCK;
07410 
07411    virtualAdr = (uintptr_t) dmaMboxBlk[block].virtual_addr;
07412    busAdr = dmaMboxBlk[block].bus_addr;
07413 
07414    for (n=0; n<PAGES_PER_BLOCK; n++)
07415    {
07416       dmaVirt[page+n] = (dmaPage_t *) virtualAdr;
07417       dmaBus[page+n] = (dmaPage_t *) busAdr;
07418       virtualAdr += PAGE_SIZE;
07419       busAdr += PAGE_SIZE;
07420    }
07421 
07422    return 0;
07423 }
07424 
07425 /* ----------------------------------------------------------------------- */
07426 
07427 static int initAllocDMAMem(void)
07428 {
07429    int i, servoCycles, superCycles;
07430    int status;
07431 
07432    DBG(DBG_STARTUP, "");
07433 
07434    /* Calculate the number of blocks needed for buffers.  The number
07435       of blocks must be a multiple of the 20ms servo cycle.
07436    */
07437 
07438    servoCycles = gpioCfg.bufferMilliseconds / 20;
07439    if           (gpioCfg.bufferMilliseconds % 20) servoCycles++;
07440 
07441    bufferCycles = (SUPERCYCLE * servoCycles) / gpioCfg.clockMicros;
07442 
07443    superCycles = bufferCycles / SUPERCYCLE;
07444    if           (bufferCycles % SUPERCYCLE) superCycles++;
07445 
07446    bufferCycles = SUPERCYCLE * superCycles;
07447 
07448    bufferBlocks = bufferCycles / CYCLES_PER_BLOCK;
07449 
07450    DBG(DBG_STARTUP, "bmillis=%d mics=%d bblk=%d bcyc=%d",
07451       gpioCfg.bufferMilliseconds, gpioCfg.clockMicros,
07452       bufferBlocks, bufferCycles);
07453 
07454    /* allocate memory for pointers to virtual and bus memory pages */
07455 
07456    dmaVirt = mmap(
07457        0, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *),
07458        PROT_READ|PROT_WRITE,
07459        MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
07460        -1, 0);
07461 
07462    if (dmaVirt == MAP_FAILED)
07463       SOFT_ERROR(PI_INIT_FAILED, "mmap dma virtual failed (%m)");
07464 
07465    dmaBus = mmap(
07466        0, PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *),
07467        PROT_READ|PROT_WRITE,
07468        MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
07469        -1, 0);
07470 
07471    if (dmaBus == MAP_FAILED)
07472       SOFT_ERROR(PI_INIT_FAILED, "mmap dma bus failed (%m)");
07473 
07474    dmaIVirt = (dmaIPage_t **) dmaVirt;
07475    dmaIBus  = (dmaIPage_t **) dmaBus;
07476 
07477    dmaOVirt = (dmaOPage_t **)(dmaVirt + (PAGES_PER_BLOCK*bufferBlocks));
07478    dmaOBus  = (dmaOPage_t **)(dmaBus  + (PAGES_PER_BLOCK*bufferBlocks));
07479 
07480    if ((gpioCfg.memAllocMode == PI_MEM_ALLOC_PAGEMAP) ||
07481        ((gpioCfg.memAllocMode == PI_MEM_ALLOC_AUTO) &&
07482         (gpioCfg.bufferMilliseconds > PI_DEFAULT_BUFFER_MILLIS)))
07483    {
07484       /* pagemap allocation of DMA memory */
07485 
07486       dmaPMapBlk = mmap(
07487           0, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *),
07488           PROT_READ|PROT_WRITE,
07489           MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
07490           -1, 0);
07491 
07492       if (dmaPMapBlk == MAP_FAILED)
07493          SOFT_ERROR(PI_INIT_FAILED, "pagemap mmap block failed (%m)");
07494 
07495       fdPmap = open("/proc/self/pagemap", O_RDONLY);
07496 
07497       if (fdPmap < 0)
07498          SOFT_ERROR(PI_INIT_FAILED, "pagemap open failed(%m)");
07499 
07500       for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++)
07501       {
07502          status = initPagemapBlock(i);
07503          if (status < 0)
07504          {
07505             close(fdPmap);
07506             return status;
07507          }
07508       }
07509 
07510       close(fdPmap);
07511 
07512       DBG(DBG_STARTUP, "dmaPMapBlk=%08X dmaIn=%08X",
07513          (uint32_t)dmaPMapBlk, (uint32_t)dmaIn);
07514    }
07515    else
07516    {
07517       /* mailbox allocation of DMA memory */
07518 
07519       dmaMboxBlk = mmap(
07520           0, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(DMAMem_t),
07521           PROT_READ|PROT_WRITE,
07522           MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED,
07523           -1, 0);
07524 
07525       if (dmaMboxBlk == MAP_FAILED)
07526          SOFT_ERROR(PI_INIT_FAILED, "mmap mbox block failed (%m)");
07527 
07528       fdMbox = mbOpen();
07529 
07530       if (fdMbox < 0)
07531          SOFT_ERROR(PI_INIT_FAILED, "mbox open failed(%m)");
07532 
07533       for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++)
07534       {
07535          status = initMboxBlock(i);
07536          if (status < 0)
07537          {
07538             mbClose(fdMbox);
07539             return status;
07540          }
07541       }
07542 
07543       mbClose(fdMbox);
07544 
07545       DBG(DBG_STARTUP, "dmaMboxBlk=%08X dmaIn=%08X",
07546          (uint32_t)dmaMboxBlk, (uint32_t)dmaIn);
07547    }
07548 
07549    DBG(DBG_STARTUP,
07550       "gpioReg=%08X pwmReg=%08X pcmReg=%08X clkReg=%08X auxReg=%08X",
07551       (uint32_t)gpioReg, (uint32_t)pwmReg,
07552       (uint32_t)pcmReg,  (uint32_t)clkReg, (uint32_t)auxReg);
07553 
07554    for (i=0; i<DMAI_PAGES; i++)
07555       DBG(DBG_STARTUP, "dmaIBus[%d]=%08X", i, (uint32_t)dmaIBus[i]);
07556 
07557    if (gpioCfg.dbgLevel >= DBG_DMACBS)
07558    {
07559       fprintf(stderr, "*** INPUT DMA CONTROL BLOCKS ***\n");
07560       for (i=0; i<NUM_CBS; i++) dmaCbPrint(i);
07561    }
07562 
07563    return 0;
07564 }
07565 
07566 /* ----------------------------------------------------------------------- */
07567 
07568 static void initPWM(unsigned bits)
07569 {
07570    DBG(DBG_STARTUP, "bits=%d", bits);
07571 
07572    /* reset PWM */
07573 
07574    pwmReg[PWM_CTL] = 0;
07575 
07576    myGpioDelay(10);
07577 
07578    pwmReg[PWM_STA] = -1;
07579 
07580    myGpioDelay(10);
07581 
07582    /* set number of bits to transmit */
07583 
07584    pwmReg[PWM_RNG1] = bits;
07585 
07586    myGpioDelay(10);
07587 
07588    dmaIVirt[0]->periphData = 1;
07589 
07590    /* enable PWM DMA, raise panic and dreq thresholds to 15 */
07591 
07592    pwmReg[PWM_DMAC] = PWM_DMAC_ENAB      |
07593                       PWM_DMAC_PANIC(15) |
07594                       PWM_DMAC_DREQ(15);
07595 
07596    myGpioDelay(10);
07597 
07598    /* clear PWM fifo */
07599 
07600    pwmReg[PWM_CTL] = PWM_CTL_CLRF1;
07601 
07602    myGpioDelay(10);
07603 
07604    /* enable PWM channel 1 and use fifo */
07605 
07606    pwmReg[PWM_CTL] = PWM_CTL_USEF1 | PWM_CTL_MODE1 | PWM_CTL_PWEN1;
07607 }
07608 
07609 /* ----------------------------------------------------------------------- */
07610 
07611 static void initPCM(unsigned bits)
07612 {
07613    DBG(DBG_STARTUP, "bits=%d", bits);
07614 
07615    /* disable PCM so we can modify the regs */
07616 
07617    pcmReg[PCM_CS] = 0;
07618 
07619    myGpioDelay(1000);
07620 
07621    pcmReg[PCM_FIFO]   = 0;
07622    pcmReg[PCM_MODE]   = 0;
07623    pcmReg[PCM_RXC]    = 0;
07624    pcmReg[PCM_TXC]    = 0;
07625    pcmReg[PCM_DREQ]   = 0;
07626    pcmReg[PCM_INTEN]  = 0;
07627    pcmReg[PCM_INTSTC] = 0;
07628    pcmReg[PCM_GRAY]   = 0;
07629 
07630    myGpioDelay(1000);
07631 
07632    pcmReg[PCM_MODE] = PCM_MODE_FLEN(bits-1); /* # bits in frame */
07633 
07634    /* enable channel 1 with # bits width */
07635 
07636    pcmReg[PCM_TXC] = PCM_TXC_CH1EN | PCM_TXC_CH1WID(bits-8);
07637 
07638    pcmReg[PCM_CS] |= PCM_CS_STBY; /* clear standby */
07639 
07640    myGpioDelay(1000);
07641 
07642    pcmReg[PCM_CS] |= PCM_CS_TXCLR; /* clear TX FIFO */
07643 
07644    pcmReg[PCM_CS] |= PCM_CS_DMAEN; /* enable DREQ */
07645 
07646    pcmReg[PCM_DREQ] = PCM_DREQ_TX_PANIC(16) | PCM_DREQ_TX_REQ_L(30);
07647 
07648    pcmReg[PCM_INTSTC] = 0b1111; /* clear status bits */
07649 
07650    /* enable PCM */
07651 
07652    pcmReg[PCM_CS] |= PCM_CS_EN;
07653 
07654    /* enable tx */
07655 
07656    pcmReg[PCM_CS] |= PCM_CS_TXON;
07657 
07658    dmaIVirt[0]->periphData = 0x0F;
07659 }
07660 
07661 /* ----------------------------------------------------------------------- */
07662 
07663 static void initHWClk
07664    (int clkCtl, int clkDiv, int clkSrc, int divI, int divF, int MASH)
07665 {
07666    DBG(DBG_INTERNAL, "ctl=%d div=%d src=%d /I=%d /f=%d M=%d",
07667       clkCtl, clkDiv, clkSrc, divI, divF, MASH);
07668 
07669    /* kill the clock if busy, anything else isn't reliable */
07670 
07671    if (clkReg[clkCtl] & CLK_CTL_BUSY)
07672    {
07673       do
07674       {
07675          clkReg[clkCtl] = BCM_PASSWD | CLK_CTL_KILL;
07676       }
07677       while (clkReg[clkCtl] & CLK_CTL_BUSY);
07678    }
07679 
07680    clkReg[clkDiv] = (BCM_PASSWD | CLK_DIV_DIVI(divI) | CLK_DIV_DIVF(divF));
07681 
07682    usleep(10);
07683 
07684    clkReg[clkCtl] = (BCM_PASSWD | CLK_CTL_MASH(MASH) | CLK_CTL_SRC(clkSrc));
07685 
07686    usleep(10);
07687 
07688    clkReg[clkCtl] |= (BCM_PASSWD | CLK_CTL_ENAB);
07689 }
07690 
07691 static void initClock(int mainClock)
07692 {
07693    const unsigned BITS=10;
07694    int clockPWM;
07695    unsigned clkCtl, clkDiv, clkSrc, clkDivI, clkDivF, clkMash, clkBits;
07696    char *per;
07697    unsigned micros;
07698 
07699    DBG(DBG_STARTUP, "mainClock=%d", mainClock);
07700 
07701    if (mainClock) micros = gpioCfg.clockMicros;
07702    else           micros = PI_WF_MICROS;
07703 
07704    clockPWM = mainClock ^ (gpioCfg.clockPeriph == PI_CLOCK_PCM);
07705 
07706    if (clockPWM)
07707    {
07708       clkCtl = CLK_PWMCTL;
07709       clkDiv = CLK_PWMDIV;
07710       per = "PWM";
07711    }
07712    else
07713    {
07714       clkCtl = CLK_PCMCTL;
07715       clkDiv = CLK_PCMDIV;
07716       per = "PCM";
07717    }
07718 
07719    clkSrc  = CLK_CTL_SRC_PLLD;
07720    clkDivI = 50 * micros; /* 10      MHz - 1      MHz */
07721    clkBits = BITS;        /* 10/BITS MHz - 1/BITS MHz */
07722    clkDivF = 0;
07723    clkMash = 0;
07724 
07725    DBG(DBG_STARTUP, "%s PLLD divi=%d divf=%d mash=%d bits=%d",
07726       per, clkDivI, clkDivF, clkMash, clkBits);
07727 
07728    initHWClk(clkCtl, clkDiv, clkSrc, clkDivI, clkDivF, clkMash);
07729 
07730    if (clockPWM) initPWM(BITS);
07731    else          initPCM(BITS);
07732 
07733    myGpioDelay(2000);
07734 }
07735 
07736 /* ----------------------------------------------------------------------- */
07737 
07738 static void initDMAgo(volatile uint32_t  *dmaAddr, uint32_t cbAddr)
07739 {
07740    DBG(DBG_STARTUP, "");
07741 
07742    dmaAddr[DMA_CS] = DMA_CHANNEL_RESET;
07743 
07744    dmaAddr[DMA_CS] = DMA_INTERRUPT_STATUS | DMA_END_FLAG;
07745 
07746    dmaAddr[DMA_CONBLK_AD] = cbAddr;
07747 
07748    /* clear READ/FIFO/READ_LAST_NOT_SET error bits */
07749 
07750    dmaAddr[DMA_DEBUG] = DMA_DEBUG_READ_ERR            |
07751                         DMA_DEBUG_FIFO_ERR            |
07752                         DMA_DEBUG_RD_LST_NOT_SET_ERR;
07753 
07754 
07755    dmaAddr[DMA_CS] = DMA_WAIT_ON_WRITES    |
07756                      DMA_PANIC_PRIORITY(8) |
07757                      DMA_PRIORITY(8)       |
07758                      DMA_ACTIVATE;
07759 }
07760 
07761 /* ----------------------------------------------------------------------- */
07762 
07763 static void initClearGlobals(void)
07764 {
07765    int i;
07766 
07767    DBG(DBG_STARTUP, "");
07768 
07769    alertBits   = 0;
07770    monitorBits = 0;
07771    notifyBits  = 0;
07772    scriptBits  = 0;
07773    gFilterBits = 0;
07774    nFilterBits = 0;
07775    wdogBits    = 0;
07776 
07777    pthAlertRunning  = PI_THREAD_NONE;
07778    pthFifoRunning   = PI_THREAD_NONE;
07779    pthSocketRunning = PI_THREAD_NONE;
07780 
07781    wfc[0] = 0;
07782    wfc[1] = 0;
07783    wfc[2] = 0;
07784 
07785    wfcur=0;
07786 
07787    wfStats.micros     = 0;
07788    wfStats.highMicros = 0;
07789    wfStats.maxMicros  = PI_WAVE_MAX_MICROS;
07790 
07791    wfStats.pulses     = 0;
07792    wfStats.highPulses = 0;
07793    wfStats.maxPulses  = PI_WAVE_MAX_PULSES;
07794 
07795    wfStats.cbs        = 0;
07796    wfStats.highCbs    = 0;
07797    wfStats.maxCbs     = (PI_WAVE_BLOCKS * PAGES_PER_BLOCK * CBS_PER_OPAGE);
07798 
07799    gpioGetSamples.func     = NULL;
07800    gpioGetSamples.ex       = 0;
07801    gpioGetSamples.userdata = NULL;
07802    gpioGetSamples.bits     = 0;
07803 
07804    for (i=0; i<=PI_MAX_USER_GPIO; i++)
07805    {
07806       wfRx[i].mode      = PI_WFRX_NONE;
07807       pthread_mutex_init(&wfRx[i].mutex, NULL);
07808       gpioAlert[i].func = NULL;
07809    }
07810 
07811    for (i=0; i<=PI_MAX_GPIO; i++)
07812    {
07813       gpioInfo [i].is      = GPIO_UNDEFINED;
07814       gpioInfo [i].width   = 0;
07815       gpioInfo [i].range   = PI_DEFAULT_DUTYCYCLE_RANGE;
07816       gpioInfo [i].freqIdx = DEFAULT_PWM_IDX;
07817    }
07818 
07819    for (i=0; i<PI_NOTIFY_SLOTS; i++)
07820    {
07821       gpioNotify[i].seqno = 0;
07822       gpioNotify[i].state = PI_NOTIFY_CLOSED;
07823    }
07824 
07825    for (i=0; i<=PI_MAX_SIGNUM; i++)
07826    {
07827       gpioSignal[i].func     = NULL;
07828       gpioSignal[i].ex       = 0;
07829       gpioSignal[i].userdata = NULL;
07830    }
07831 
07832    for (i=0; i<=PI_MAX_TIMER; i++)
07833    {
07834       gpioTimer[i].running = 0;
07835       gpioTimer[i].func    = NULL;
07836    }
07837 
07838    for (i=0; i<=PI_MAX_EVENT; i++)
07839    {
07840       eventAlert[i].func      = NULL;
07841       eventAlert[i].ignore    = 0;
07842       eventAlert[i].fired     = 0;
07843    }
07844 
07845    /* calculate the usable PWM frequencies */
07846 
07847    for (i=0; i<PWM_FREQS; i++)
07848    {
07849       pwmFreq[i]=
07850          (1000000.0/
07851             ((float)PULSE_PER_CYCLE*gpioCfg.clockMicros*pwmCycles[i]))+0.5;
07852 
07853       DBG(DBG_STARTUP, "f%d is %d", i, pwmFreq[i]);
07854    }
07855 
07856    inpFifo = NULL;
07857    outFifo = NULL;
07858 
07859    fdLock       = -1;
07860    fdMem        = -1;
07861    fdSock       = -1;
07862 
07863    dmaMboxBlk = MAP_FAILED;
07864    dmaPMapBlk = MAP_FAILED;
07865    dmaVirt = MAP_FAILED;
07866    dmaBus  = MAP_FAILED;
07867 
07868    auxReg  = MAP_FAILED;
07869    clkReg  = MAP_FAILED;
07870    dmaReg  = MAP_FAILED;
07871    gpioReg = MAP_FAILED;
07872    pcmReg  = MAP_FAILED;
07873    pwmReg  = MAP_FAILED;
07874    systReg = MAP_FAILED;
07875    spiReg  = MAP_FAILED;
07876 }
07877 
07878 /* ----------------------------------------------------------------------- */
07879 
07880 static void initReleaseResources(void)
07881 {
07882    int i;
07883 
07884    DBG(DBG_STARTUP, "");
07885 
07886    /* shut down running threads */
07887 
07888    for (i=0; i<=PI_MAX_GPIO; i++)
07889    {
07890       if (gpioISR[i].pth)
07891       {
07892          /* destroy thread, unexport GPIO */
07893 
07894          gpioSetISRFunc(i, 0, 0, NULL);
07895       }
07896    }
07897 
07898    for (i=0; i<=PI_MAX_TIMER; i++)
07899    {
07900       if (gpioTimer[i].running)
07901       {
07902          /* destroy thread */
07903 
07904          pthread_cancel(gpioTimer[i].pthId);
07905          pthread_join(gpioTimer[i].pthId, NULL);
07906          gpioTimer[i].running = 0;
07907       }
07908    }
07909 
07910    if (pthAlertRunning != PI_THREAD_NONE)
07911    {
07912       pthread_cancel(pthAlert);
07913       pthread_join(pthAlert, NULL);
07914       pthAlertRunning = PI_THREAD_NONE;
07915    }
07916 
07917    if (pthFifoRunning != PI_THREAD_NONE)
07918    {
07919       pthread_cancel(pthFifo);
07920       pthread_join(pthFifo, NULL);
07921       pthFifoRunning = PI_THREAD_NONE;
07922    }
07923 
07924    if (pthSocketRunning != PI_THREAD_NONE)
07925    {
07926       pthread_cancel(pthSocket);
07927       pthread_join(pthSocket, NULL);
07928       pthSocketRunning = PI_THREAD_NONE;
07929    }
07930 
07931    /* release mmap'd memory */
07932 
07933    if (auxReg  != MAP_FAILED) munmap((void *)auxReg,  AUX_LEN);
07934    if (bscsReg != MAP_FAILED) munmap((void *)bscsReg, BSCS_LEN);
07935    if (clkReg  != MAP_FAILED) munmap((void *)clkReg,  CLK_LEN);
07936    if (dmaReg  != MAP_FAILED) munmap((void *)dmaReg,  DMA_LEN);
07937    if (gpioReg != MAP_FAILED) munmap((void *)gpioReg, GPIO_LEN);
07938    if (pcmReg  != MAP_FAILED) munmap((void *)pcmReg,  PCM_LEN);
07939    if (pwmReg  != MAP_FAILED) munmap((void *)pwmReg,  PWM_LEN);
07940    if (systReg != MAP_FAILED) munmap((void *)systReg, SYST_LEN);
07941    if (spiReg  != MAP_FAILED) munmap((void *)spiReg,  SPI_LEN);
07942 
07943    auxReg  = MAP_FAILED;
07944    bscsReg = MAP_FAILED;
07945    clkReg  = MAP_FAILED;
07946    dmaReg  = MAP_FAILED;
07947    gpioReg = MAP_FAILED;
07948    pcmReg  = MAP_FAILED;
07949    pwmReg  = MAP_FAILED;
07950    systReg = MAP_FAILED;
07951    spiReg  = MAP_FAILED;
07952 
07953    if (dmaBus != MAP_FAILED)
07954    {
07955       munmap(dmaBus,
07956          PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
07957    }
07958 
07959    dmaBus = MAP_FAILED;
07960 
07961    if (dmaVirt != MAP_FAILED)
07962    {
07963       for (i=0; i<PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS); i++)
07964       {
07965          munmap(dmaVirt[i], PAGE_SIZE);
07966       }
07967 
07968       munmap(dmaVirt,
07969          PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
07970    }
07971 
07972    dmaVirt = MAP_FAILED;
07973 
07974    if (dmaPMapBlk != MAP_FAILED)
07975    {
07976       for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++)
07977       {
07978          munmap(dmaPMapBlk[i], PAGES_PER_BLOCK*PAGE_SIZE);
07979       }
07980 
07981       munmap(dmaPMapBlk, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *));
07982    }
07983 
07984    dmaPMapBlk = MAP_FAILED;
07985 
07986    if (dmaMboxBlk != MAP_FAILED)
07987    {
07988       fdMbox = mbOpen();
07989 
07990       for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++)
07991       {
07992          mbDMAFree(&dmaMboxBlk[bufferBlocks+PI_WAVE_BLOCKS-i-1]);
07993       }
07994 
07995       mbClose(fdMbox);
07996 
07997       munmap(dmaMboxBlk, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(DMAMem_t));
07998    }
07999 
08000    dmaMboxBlk = MAP_FAILED;
08001 
08002    if (inpFifo != NULL)
08003    {
08004       fclose(inpFifo);
08005       unlink(PI_INPFIFO);
08006       inpFifo = NULL;
08007    }
08008 
08009    if (outFifo != NULL)
08010    {
08011       fclose(outFifo);
08012       unlink(PI_OUTFIFO);
08013       outFifo = NULL;
08014    }
08015 
08016    if (fdMem != -1)
08017    {
08018       close(fdMem);
08019       fdMem = -1;
08020    }
08021 
08022    if (fdLock != -1)
08023    {
08024       close(fdLock);
08025       unlink(PI_LOCKFILE);
08026       fdLock = -1;
08027    }
08028 
08029    if (fdSock != -1)
08030    {
08031       close(fdSock);
08032       fdSock = -1;
08033    }
08034 
08035    if (fdPmap != -1)
08036    {
08037       close(fdPmap);
08038       fdPmap = -1;
08039    }
08040 
08041    if (fdMbox != -1)
08042    {
08043       close(fdMbox);
08044       fdMbox = -1;
08045    }
08046 
08047    gpioStats.DMARestarts = 0;
08048    gpioStats.dmaInitCbsCount = 0;
08049 
08050    numSockNetAddr = 0;
08051 }
08052 
08053 int initInitialise(void)
08054 {
08055    int rev, i, model;
08056    struct sockaddr_in server;
08057    struct sockaddr_in6 server6;
08058    char * portStr;
08059    unsigned port;
08060    struct sched_param param;
08061    pthread_attr_t pthAttr;
08062 
08063    DBG(DBG_STARTUP, "");
08064 
08065    waveClockInited = 0;
08066    PWMClockInited = 0;
08067 
08068    clock_gettime(CLOCK_REALTIME, &libStarted);
08069 
08070    rev = gpioHardwareRevision();
08071 
08072    initClearGlobals();
08073 
08074    if (initCheckPermitted() < 0) return PI_INIT_FAILED;
08075 
08076    fdLock = initGrabLockFile();
08077 
08078    if (fdLock < 0)
08079       SOFT_ERROR(PI_INIT_FAILED, "Can't lock %s", PI_LOCKFILE);
08080 
08081    if (!gpioMaskSet)
08082    {
08083       if      (rev ==  0) gpioMask = PI_DEFAULT_UPDATE_MASK_UNKNOWN;
08084       else if (rev <   4) gpioMask = PI_DEFAULT_UPDATE_MASK_B1;
08085       else if (rev <  16) gpioMask = PI_DEFAULT_UPDATE_MASK_A_B2;
08086       else if (rev == 17) gpioMask = PI_DEFAULT_UPDATE_MASK_COMPUTE;
08087       else if (rev  < 20) gpioMask = PI_DEFAULT_UPDATE_MASK_APLUS_BPLUS;
08088       else if (rev == 20) gpioMask = PI_DEFAULT_UPDATE_MASK_COMPUTE;
08089       else if (rev == 21) gpioMask = PI_DEFAULT_UPDATE_MASK_APLUS_BPLUS;
08090       else
08091       {
08092          model = (rev >> 4) & 0xFF;
08093 
08094          /* model
08095          0=A 1=B
08096          2=A+ 3=B+
08097          4=Pi2B
08098          5=Alpha
08099          6=Compute Module
08100          7=Unknown
08101          8=Pi3B
08102          9=Zero
08103          */
08104          if      (model <  2) gpioMask = PI_DEFAULT_UPDATE_MASK_A_B2;
08105          else if (model <  4) gpioMask = PI_DEFAULT_UPDATE_MASK_APLUS_BPLUS;
08106          else if (model == 4) gpioMask = PI_DEFAULT_UPDATE_MASK_PI2B;
08107          else if (model == 6) gpioMask = PI_DEFAULT_UPDATE_MASK_COMPUTE;
08108          else if (model == 8) gpioMask = PI_DEFAULT_UPDATE_MASK_PI3B;
08109          else if (model == 9) gpioMask = PI_DEFAULT_UPDATE_MASK_ZERO;
08110          else                 gpioMask = PI_DEFAULT_UPDATE_MASK_UNKNOWN;
08111       }
08112 
08113       gpioMaskSet = 1;
08114    }
08115 
08116 #ifndef EMBEDDED_IN_VM
08117    if (!(gpioCfg.internals & PI_CFG_NOSIGHANDLER))
08118       sigSetHandler();
08119 #endif
08120 
08121    if (initPeripherals() < 0) return PI_INIT_FAILED;
08122 
08123    if (initAllocDMAMem() < 0) return PI_INIT_FAILED;
08124 
08125    /* done with /dev/mem */
08126 
08127    if (fdMem != -1)
08128    {
08129       close(fdMem);
08130       fdMem = -1;
08131    }
08132 
08133    param.sched_priority = sched_get_priority_max(SCHED_FIFO);
08134 
08135    if (gpioCfg.internals & PI_CFG_RT_PRIORITY)
08136       sched_setscheduler(0, SCHED_FIFO, &param);
08137 
08138    initClock(1); /* initialise main clock */
08139 
08140    atexit(gpioTerminate);
08141 
08142    if (pthread_attr_init(&pthAttr))
08143       SOFT_ERROR(PI_INIT_FAILED, "pthread_attr_init failed (%m)");
08144 
08145    if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE))
08146       SOFT_ERROR(PI_INIT_FAILED, "pthread_attr_setstacksize failed (%m)");
08147 
08148    if (!(gpioCfg.ifFlags & PI_DISABLE_ALERT))
08149    {
08150       if (pthread_create(&pthAlert, &pthAttr, pthAlertThread, &i))
08151          SOFT_ERROR(PI_INIT_FAILED, "pthread_create alert failed (%m)");
08152 
08153       pthAlertRunning = PI_THREAD_STARTED;
08154    }
08155 
08156    if (!(gpioCfg.ifFlags & PI_DISABLE_FIFO_IF))
08157    {
08158       if (pthread_create(&pthFifo, &pthAttr, pthFifoThread, &i))
08159          SOFT_ERROR(PI_INIT_FAILED, "pthread_create fifo failed (%m)");
08160 
08161       pthFifoRunning = PI_THREAD_STARTED;
08162    }
08163 
08164    if (!(gpioCfg.ifFlags & PI_DISABLE_SOCK_IF))
08165    {
08166       portStr = getenv(PI_ENVPORT);
08167       if (portStr) port = atoi(portStr); else port = gpioCfg.socketPort;
08168 
08169       // Accept connections on IPv6, unless we have an IPv4-only whitelist
08170       if (!numSockNetAddr)
08171       {
08172          fdSock = socket(AF_INET6, SOCK_STREAM , 0);
08173 
08174          if (fdSock != -1)
08175          {
08176             bzero((char *)&server6, sizeof(server6));
08177             server6.sin6_family = AF_INET6;
08178             if (gpioCfg.ifFlags & PI_LOCALHOST_SOCK_IF)
08179             {
08180                server6.sin6_addr = in6addr_loopback;
08181             }
08182             else
08183             {
08184                server6.sin6_addr = in6addr_any;
08185             }
08186             server6.sin6_port = htons(port);
08187 
08188             if (bind(fdSock,(struct sockaddr *)&server6, sizeof(server6)) < 0)
08189                SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
08190          }
08191       }
08192 
08193       if (numSockNetAddr || fdSock == -1)
08194       {
08195          fdSock = socket(AF_INET , SOCK_STREAM , 0);
08196 
08197          if (fdSock == -1)
08198             SOFT_ERROR(PI_INIT_FAILED, "socket failed (%m)");
08199 
08200          server.sin_family = AF_INET;
08201          if (gpioCfg.ifFlags & PI_LOCALHOST_SOCK_IF)
08202          {
08203             server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
08204          }
08205          else
08206          {
08207             server.sin_addr.s_addr = htonl(INADDR_ANY);
08208          }
08209          server.sin_port = htons(port);
08210 
08211          if (bind(fdSock,(struct sockaddr *)&server , sizeof(server)) < 0)
08212             SOFT_ERROR(PI_INIT_FAILED, "bind to port %d failed (%m)", port);
08213       }
08214 
08215       if (pthread_create(&pthSocket, &pthAttr, pthSocketThread, &i))
08216          SOFT_ERROR(PI_INIT_FAILED, "pthread_create socket failed (%m)");
08217 
08218       pthSocketRunning = PI_THREAD_STARTED;
08219    }
08220 
08221    myGpioDelay(1000);
08222 
08223    dmaInitCbs();
08224 
08225    flushMemory();
08226 
08227    initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]);
08228 
08229    return PIGPIO_VERSION;
08230 }
08231 
08232 
08233 /* ======================================================================= */
08234 
08235 int getBitInBytes(int bitPos, char *buf, int numBits)
08236 {
08237    int bitp, bufp;
08238 
08239    if (bitPos < numBits)
08240    {
08241       bufp =      bitPos / 8;
08242       bitp = 7 - (bitPos % 8);
08243       if (buf[bufp] & (1<<bitp)) return 1;
08244    }
08245 
08246    return 0;
08247 }
08248 
08249 /* ----------------------------------------------------------------------- */
08250 
08251 void putBitInBytes(int bitPos, char *buf, int bit)
08252 {
08253    int bitp, bufp;
08254 
08255    bufp =      bitPos / 8;
08256    bitp = 7 - (bitPos % 8);
08257 
08258    if (bit) buf[bufp] |=   (1<<bitp);
08259    else     buf[bufp] &= (~(1<<bitp));
08260 }
08261 
08262 /* ----------------------------------------------------------------------- */
08263 
08264 uint32_t rawWaveGetOOL(int pos)
08265 {
08266    int page, slot;
08267 
08268    if ((pos >= 0) && (pos < NUM_WAVE_OOL))
08269    {
08270       waveOOLPageSlot(pos, &page, &slot);
08271       return (dmaOVirt[page]->OOL[slot]);
08272    }
08273 
08274    return -1;
08275 }
08276 
08277 /* ----------------------------------------------------------------------- */
08278 
08279 void rawWaveSetOOL(int pos, uint32_t value)
08280 {
08281    int page, slot;
08282 
08283    if ((pos >= 0) && (pos < NUM_WAVE_OOL))
08284    {
08285       waveOOLPageSlot(pos, &page, &slot);
08286       dmaOVirt[page]->OOL[slot] = value;
08287    }
08288 }
08289 
08290 
08291 /* ----------------------------------------------------------------------- */
08292 
08293 uint32_t rawWaveGetOut(int pos)
08294 {
08295    int page, slot;
08296 
08297    if ((pos >= 0) && (pos < NUM_WAVE_OOL))
08298    {
08299       waveOOLPageSlot(pos, &page, &slot);
08300       return (dmaOVirt[page]->OOL[slot]);
08301    }
08302 
08303    return -1;
08304 }
08305 
08306 /* ----------------------------------------------------------------------- */
08307 
08308 void rawWaveSetOut(int pos, uint32_t value)
08309 {
08310    int page, slot;
08311 
08312    if ((pos >= 0) && (pos < NUM_WAVE_OOL))
08313    {
08314       waveOOLPageSlot(pos, &page, &slot);
08315       dmaOVirt[page]->OOL[slot] = value;
08316    }
08317 }
08318 
08319 
08320 /* ----------------------------------------------------------------------- */
08321 
08322 uint32_t rawWaveGetIn(int pos)
08323 {
08324    int page, slot;
08325 
08326    if ((pos >= 0) && (pos < NUM_WAVE_OOL))
08327    {
08328       waveOOLPageSlot((NUM_WAVE_OOL-1)-pos, &page, &slot);
08329       return (dmaOVirt[page]->OOL[slot]);
08330    }
08331 
08332    return -1;
08333 }
08334 
08335 /* ----------------------------------------------------------------------- */
08336 
08337 void rawWaveSetIn(int pos, uint32_t value)
08338 {
08339    int page, slot;
08340 
08341    if ((pos >= 0) && (pos < NUM_WAVE_OOL))
08342    {
08343       waveOOLPageSlot((NUM_WAVE_OOL-1)-pos, &page, &slot);
08344       dmaOVirt[page]->OOL[slot] = value;
08345    }
08346 }
08347 
08348 /* ----------------------------------------------------------------------- */
08349 
08350 rawWaveInfo_t rawWaveInfo(int wave_id)
08351 {
08352    rawWaveInfo_t dummy = {0, 0, 0, 0, 0, 0, 0, 0};
08353 
08354    if ((wave_id >=0) && (wave_id < PI_MAX_WAVES)) return waveInfo[wave_id];
08355    else                                           return dummy;
08356 }
08357 
08358 /* ----------------------------------------------------------------------- */
08359 
08360 double time_time(void)
08361 {
08362    struct timeval tv;
08363    double t;
08364 
08365    gettimeofday(&tv, 0);
08366 
08367    t = (double)tv.tv_sec + ((double)tv.tv_usec / 1E6);
08368 
08369    return t;
08370 }
08371 
08372 /* ----------------------------------------------------------------------- */
08373 
08374 void time_sleep(double seconds)
08375 {
08376    struct timespec ts, rem;
08377 
08378    if (seconds > 0.0)
08379    {
08380       ts.tv_sec = seconds;
08381       ts.tv_nsec = (seconds-(double)ts.tv_sec) * 1E9;
08382 
08383       while (clock_nanosleep(CLOCK_REALTIME, 0, &ts, &rem))
08384       {
08385          /* copy remaining time to ts */
08386          ts.tv_sec  = rem.tv_sec;
08387          ts.tv_nsec = rem.tv_nsec;
08388       }
08389    }
08390 }
08391 
08392 /* ----------------------------------------------------------------------- */
08393 
08394 void rawDumpWave(void)
08395 {
08396    int i;
08397 
08398    unsigned numWaves, t;
08399 
08400    rawWave_t *waves;
08401 
08402    numWaves = wfc[wfcur];
08403    waves    = wf [wfcur];
08404 
08405    t = 0;
08406 
08407    for (i=0; i<numWaves; i++)
08408    {
08409       fprintf(stderr, "%10u %08X %08X %08X %10u\n",
08410          t, waves[i].gpioOn, waves[i].gpioOff,
08411          waves[i].flags, waves[i].usDelay);
08412       t += waves[i].usDelay;
08413    }
08414 }
08415 
08416 /* ----------------------------------------------------------------------- */
08417 
08418 void rawDumpScript(unsigned script_id)
08419 {
08420    int i;
08421 
08422    if (script_id >= PI_MAX_SCRIPTS) return;
08423 
08424    if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
08425    {
08426 
08427       for (i=0; i<PI_MAX_SCRIPT_PARAMS; i++)
08428       {
08429          fprintf(stderr, "p%d=%d ", i, gpioScript[script_id].script.par[i]);
08430       }
08431 
08432       fprintf(stderr, "\n");
08433 
08434       for (i=0; i<PI_MAX_SCRIPT_VARS; i++)
08435       {
08436          fprintf(stderr, "v%d=%d ", i, gpioScript[script_id].script.var[i]);
08437       }
08438 
08439       fprintf(stderr, "\n");
08440 
08441       for (i=0; i<gpioScript[script_id].script.instrs; i++)
08442       {
08443          fprintf(stderr,
08444             "c%d=[%d, %d(%d), %d(%d), %d, %d]\n",
08445             i,
08446             gpioScript[script_id].script.instr[i].p[0],
08447             gpioScript[script_id].script.instr[i].p[1],
08448             gpioScript[script_id].script.instr[i].opt[1],
08449             gpioScript[script_id].script.instr[i].p[2],
08450             gpioScript[script_id].script.instr[i].opt[2],
08451             gpioScript[script_id].script.instr[i].p[3],
08452             gpioScript[script_id].script.instr[i].p[4]);
08453       }
08454    }
08455 }
08456 
08457 /* ======================================================================= */
08458 
08459 int gpioInitialise(void)
08460 {
08461    int status;
08462 
08463    if (libInitialised) return PIGPIO_VERSION;
08464 
08465    DBG(DBG_STARTUP, "not initialised, initialising");
08466 
08467    runState = PI_STARTING;
08468 
08469    status = initInitialise();
08470 
08471    if (status < 0)
08472    {
08473       runState = PI_ENDING;
08474       initReleaseResources();
08475    }
08476    else
08477    {
08478       libInitialised = 1;
08479 
08480       runState = PI_RUNNING;
08481 
08482       if (!(gpioCfg.ifFlags & PI_DISABLE_ALERT))
08483       {
08484          while (pthAlertRunning != PI_THREAD_RUNNING) myGpioDelay(1000);
08485       }
08486 
08487    }
08488 
08489    return status;
08490 }
08491 
08492 
08493 /* ----------------------------------------------------------------------- */
08494 
08495 void gpioTerminate(void)
08496 {
08497    int i;
08498 
08499    DBG(DBG_USER, "");
08500 
08501    if (!libInitialised) return;
08502 
08503    DBG(DBG_STARTUP, "initialised, terminating");
08504 
08505    runState = PI_ENDING;
08506 
08507    gpioMaskSet = 0;
08508 
08509    /* reset DMA */
08510 
08511    if (dmaReg != MAP_FAILED) dmaIn[DMA_CS] = DMA_CHANNEL_RESET;
08512    if (dmaReg != MAP_FAILED) dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
08513 
08514 #ifndef EMBEDDED_IN_VM
08515    if ((gpioCfg.internals & PI_CFG_STATS) &&
08516        (!(gpioCfg.internals & PI_CFG_NOSIGHANDLER)))
08517    {
08518       fprintf(stderr,
08519          "\n#####################################################\n");
08520       fprintf(stderr, "pigpio version=%d internals=%X\n",
08521          PIGPIO_VERSION, gpioCfg.internals);
08522 
08523       fprintf(stderr,
08524          "micros=%d allocMode=%d dmaInitCbs=%d DMARestarts=%d\n",
08525          gpioCfg.clockMicros, gpioCfg.memAllocMode,
08526          gpioStats.dmaInitCbsCount, gpioStats.DMARestarts);
08527 
08528       fprintf(stderr,
08529          "samples %u maxSamples %u maxEmit %u emitFrags %u\n",
08530          gpioStats.numSamples, gpioStats.maxSamples,
08531          gpioStats.maxEmit, gpioStats.emitFrags);
08532 
08533       fprintf(stderr, "cbTicks %d, cbCalls %u\n",
08534          gpioStats.cbTicks, gpioStats.cbCalls);
08535 
08536       fprintf(stderr, "pipe: good %u, short %u, would block %u\n",
08537          gpioStats.goodPipeWrite, gpioStats.shortPipeWrite,
08538          gpioStats.wouldBlockPipeWrite);
08539 
08540       fprintf(stderr, "alertTicks %u, lateTicks %u, moreToDo %u\n",
08541          gpioStats.alertTicks, gpioStats.lateTicks, gpioStats.moreToDo);
08542 
08543       for (i=0; i< TICKSLOTS; i++)
08544          fprintf(stderr, "%9u ", gpioStats.diffTick[i]);
08545 
08546       fprintf(stderr,
08547          "\n#####################################################\n\n\n");
08548    }
08549 
08550 #endif
08551    initReleaseResources();
08552 
08553    fflush(NULL);
08554 
08555    libInitialised = 0;
08556 }
08557 
08558 static void switchFunctionOff(unsigned gpio)
08559 {
08560    switch (gpioInfo[gpio].is)
08561    {
08562       case GPIO_SERVO:
08563          /* switch servo off */
08564          myGpioSetServo(gpio, gpioInfo[gpio].width, 0);
08565          gpioInfo[gpio].width = 0;
08566          break;
08567 
08568       case GPIO_PWM:
08569          /* switch pwm off */
08570          myGpioSetPwm(gpio, gpioInfo[gpio].width, 0);
08571          gpioInfo[gpio].width = 0;
08572          break;
08573 
08574       case GPIO_HW_CLK:
08575          /* No longer disable clock hardware, doing that was a bug. */
08576          gpioInfo[gpio].width = 0;
08577          break;
08578 
08579       case GPIO_HW_PWM:
08580          /* No longer disable PWM hardware, doing that was a bug. */
08581          gpioInfo[gpio].width = 0;
08582          break;
08583    }
08584 }
08585 
08586 static void stopHardwarePWM(void)
08587 {
08588    unsigned i, pwm;
08589 
08590    for (i=0; i<= PI_MAX_GPIO; i++)
08591    {
08592       if (gpioInfo[i].is == GPIO_HW_PWM)
08593       {
08594          pwm = (PWMDef[i] >> 4) & 3;
08595 
08596          if (pwm == 0) pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN1);
08597          else          pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN2);
08598 
08599          gpioInfo[i].width = 0;
08600          gpioInfo[i].is = GPIO_UNDEFINED;
08601       }
08602    }
08603 }
08604 
08605 /* ----------------------------------------------------------------------- */
08606 
08607 int gpioSetMode(unsigned gpio, unsigned mode)
08608 {
08609    int reg, shift, old_mode;
08610 
08611    DBG(DBG_USER, "gpio=%d mode=%d", gpio, mode);
08612 
08613    CHECK_INITED;
08614 
08615    if (gpio > PI_MAX_GPIO)
08616       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
08617 
08618    if (mode > PI_ALT3)
08619       SOFT_ERROR(PI_BAD_MODE, "gpio %d, bad mode (%d)", gpio, mode);
08620 
08621    reg   =  gpio/10;
08622    shift = (gpio%10) * 3;
08623 
08624    old_mode = (gpioReg[reg] >> shift) & 7;
08625 
08626    if (mode != old_mode)
08627    {
08628       switchFunctionOff(gpio);
08629 
08630       gpioInfo[gpio].is = GPIO_UNDEFINED;
08631    }
08632 
08633    gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (mode<<shift);
08634 
08635    return 0;
08636 }
08637 
08638 
08639 /* ----------------------------------------------------------------------- */
08640 
08641 int gpioGetMode(unsigned gpio)
08642 {
08643    int reg, shift;
08644 
08645    DBG(DBG_USER, "gpio=%d", gpio);
08646 
08647    CHECK_INITED;
08648 
08649    if (gpio > PI_MAX_GPIO)
08650       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
08651 
08652    reg   =  gpio/10;
08653    shift = (gpio%10) * 3;
08654 
08655    return (gpioReg[reg] >> shift) & 7;
08656 }
08657 
08658 
08659 /* ----------------------------------------------------------------------- */
08660 
08661 int gpioSetPullUpDown(unsigned gpio, unsigned pud)
08662 {
08663    DBG(DBG_USER, "gpio=%d pud=%d", gpio, pud);
08664 
08665    CHECK_INITED;
08666 
08667    if (gpio > PI_MAX_GPIO)
08668       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
08669 
08670    if (pud > PI_PUD_UP)
08671       SOFT_ERROR(PI_BAD_PUD, "gpio %d, bad pud (%d)", gpio, pud);
08672 
08673    *(gpioReg + GPPUD) = pud;
08674 
08675    myGpioDelay(1);
08676 
08677    *(gpioReg + GPPUDCLK0 + BANK) = BIT;
08678 
08679    myGpioDelay(1);
08680 
08681    *(gpioReg + GPPUD) = 0;
08682 
08683    *(gpioReg + GPPUDCLK0 + BANK) = 0;
08684 
08685    return 0;
08686 }
08687 
08688 
08689 /* ----------------------------------------------------------------------- */
08690 
08691 int gpioRead(unsigned gpio)
08692 {
08693    DBG(DBG_USER, "gpio=%d", gpio);
08694 
08695    CHECK_INITED;
08696 
08697    if (gpio > PI_MAX_GPIO)
08698       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
08699 
08700    if ((*(gpioReg + GPLEV0 + BANK) & BIT) != 0) return PI_ON;
08701    else                                         return PI_OFF;
08702 }
08703 
08704 
08705 /* ----------------------------------------------------------------------- */
08706 
08707 int gpioWrite(unsigned gpio, unsigned level)
08708 {
08709    DBG(DBG_USER, "gpio=%d level=%d", gpio, level);
08710 
08711    CHECK_INITED;
08712 
08713    if (gpio > PI_MAX_GPIO)
08714       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
08715 
08716    if (level > PI_ON)
08717       SOFT_ERROR(PI_BAD_LEVEL, "gpio %d, bad level (%d)", gpio, level);
08718 
08719    if (gpio <= PI_MAX_GPIO)
08720    {
08721       if (gpioInfo[gpio].is != GPIO_WRITE)
08722       {
08723          /* stop a glitch between setting mode then level */
08724          if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
08725          else                 *(gpioReg + GPSET0 + BANK) = BIT;
08726 
08727          switchFunctionOff(gpio);
08728 
08729          gpioInfo[gpio].is = GPIO_WRITE;
08730       }
08731    }
08732 
08733    myGpioSetMode(gpio, PI_OUTPUT);
08734 
08735    if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
08736    else                 *(gpioReg + GPSET0 + BANK) = BIT;
08737 
08738    return 0;
08739 }
08740 
08741 
08742 /* ----------------------------------------------------------------------- */
08743 
08744 int gpioPWM(unsigned gpio, unsigned val)
08745 {
08746    DBG(DBG_USER, "gpio=%d dutycycle=%d", gpio, val);
08747 
08748    CHECK_INITED;
08749 
08750    if (gpio > PI_MAX_USER_GPIO)
08751       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08752 
08753    if (val > gpioInfo[gpio].range)
08754       SOFT_ERROR(PI_BAD_DUTYCYCLE, "gpio %d, bad dutycycle (%d)", gpio, val);
08755 
08756    if (gpioInfo[gpio].is != GPIO_PWM)
08757    {
08758       switchFunctionOff(gpio);
08759 
08760       gpioInfo[gpio].is = GPIO_PWM;
08761 
08762       if (!val) myGpioWrite(gpio, 0);
08763    }
08764 
08765    myGpioSetMode(gpio, PI_OUTPUT);
08766 
08767    myGpioSetPwm(gpio, gpioInfo[gpio].width, val);
08768 
08769    gpioInfo[gpio].width=val;
08770 
08771    return 0;
08772 }
08773 
08774 /* ----------------------------------------------------------------------- */
08775 
08776 int gpioGetPWMdutycycle(unsigned gpio)
08777 {
08778    unsigned pwm;
08779 
08780    DBG(DBG_USER, "gpio=%d", gpio);
08781 
08782    CHECK_INITED;
08783 
08784    if (gpio > PI_MAX_USER_GPIO)
08785       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08786 
08787    switch (gpioInfo[gpio].is)
08788    {
08789       case GPIO_PWM:
08790          return gpioInfo[gpio].width;
08791 
08792       case GPIO_HW_PWM:
08793          pwm = (PWMDef[gpio] >> 4) & 3;
08794          return hw_pwm_duty[pwm];
08795 
08796       case GPIO_HW_CLK:
08797          return PI_HW_PWM_RANGE/2;
08798 
08799       default:
08800          SOFT_ERROR(PI_NOT_PWM_GPIO, "not a PWM gpio (%d)", gpio);
08801    }
08802 }
08803 
08804 
08805 /* ----------------------------------------------------------------------- */
08806 
08807 int gpioSetPWMrange(unsigned gpio, unsigned range)
08808 {
08809    int oldWidth, newWidth;
08810 
08811    DBG(DBG_USER, "gpio=%d range=%d", gpio, range);
08812 
08813    CHECK_INITED;
08814 
08815    if (gpio > PI_MAX_USER_GPIO)
08816       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08817 
08818    if ((range < PI_MIN_DUTYCYCLE_RANGE)  || (range > PI_MAX_DUTYCYCLE_RANGE))
08819       SOFT_ERROR(PI_BAD_DUTYRANGE, "gpio %d, bad range (%d)", gpio, range);
08820 
08821    oldWidth = gpioInfo[gpio].width;
08822 
08823    if (oldWidth)
08824    {
08825       if (gpioInfo[gpio].is == GPIO_PWM)
08826       {
08827          newWidth = (range * oldWidth) / gpioInfo[gpio].range;
08828 
08829          myGpioSetPwm(gpio, oldWidth, 0);
08830          gpioInfo[gpio].range = range;
08831          gpioInfo[gpio].width = newWidth;
08832          myGpioSetPwm(gpio, 0, newWidth);
08833       }
08834    }
08835 
08836    gpioInfo[gpio].range = range;
08837 
08838    /* return the actual range for the current gpio frequency */
08839 
08840    return pwmRealRange[gpioInfo[gpio].freqIdx];
08841 }
08842 
08843 
08844 /* ----------------------------------------------------------------------- */
08845 
08846 int gpioGetPWMrange(unsigned gpio)
08847 {
08848    DBG(DBG_USER, "gpio=%d", gpio);
08849 
08850    CHECK_INITED;
08851 
08852    if (gpio > PI_MAX_USER_GPIO)
08853       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08854 
08855    switch (gpioInfo[gpio].is)
08856    {
08857       case GPIO_HW_PWM:
08858       case GPIO_HW_CLK:
08859          return PI_HW_PWM_RANGE;
08860 
08861       default:
08862          return gpioInfo[gpio].range;
08863    }
08864 }
08865 
08866 
08867 /* ----------------------------------------------------------------------- */
08868 
08869 int gpioGetPWMrealRange(unsigned gpio)
08870 {
08871    unsigned pwm;
08872 
08873    DBG(DBG_USER, "gpio=%d", gpio);
08874 
08875    CHECK_INITED;
08876 
08877    if (gpio > PI_MAX_USER_GPIO)
08878       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08879 
08880    switch (gpioInfo[gpio].is)
08881    {
08882       case GPIO_HW_PWM:
08883          pwm = (PWMDef[gpio] >> 4) & 3;
08884          return hw_pwm_real_range[pwm];
08885 
08886       case GPIO_HW_CLK:
08887          return PI_HW_PWM_RANGE;
08888 
08889       default:
08890          return pwmRealRange[gpioInfo[gpio].freqIdx];
08891    }
08892 }
08893 
08894 
08895 /* ----------------------------------------------------------------------- */
08896 
08897 int gpioSetPWMfrequency(unsigned gpio, unsigned frequency)
08898 {
08899    int i, width;
08900    unsigned diff, best, idx;
08901 
08902    DBG(DBG_USER, "gpio=%d frequency=%d", gpio, frequency);
08903 
08904    CHECK_INITED;
08905 
08906    if (gpio > PI_MAX_USER_GPIO)
08907       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08908 
08909    if      (frequency > pwmFreq[0])           idx = 0;
08910    else if (frequency < pwmFreq[PWM_FREQS-1]) idx = PWM_FREQS-1;
08911    else
08912    {
08913       best = 100000; /* impossibly high frequency difference */
08914       idx = 0;
08915 
08916       for (i=0; i<PWM_FREQS; i++)
08917       {
08918          if (frequency > pwmFreq[i]) diff = frequency - pwmFreq[i];
08919          else                        diff = pwmFreq[i] - frequency;
08920 
08921          if (diff < best)
08922          {
08923             best = diff;
08924             idx = i;
08925          }
08926       }
08927    }
08928 
08929    width = gpioInfo[gpio].width;
08930 
08931    if (width)
08932    {
08933       if (gpioInfo[gpio].is == GPIO_PWM)
08934       {
08935          myGpioSetPwm(gpio, width, 0);
08936          gpioInfo[gpio].freqIdx = idx;
08937          myGpioSetPwm(gpio, 0, width);
08938       }
08939    }
08940 
08941    gpioInfo[gpio].freqIdx = idx;
08942 
08943    return pwmFreq[idx];
08944 }
08945 
08946 
08947 /* ----------------------------------------------------------------------- */
08948 
08949 int gpioGetPWMfrequency(unsigned gpio)
08950 {
08951    unsigned pwm, clock;
08952 
08953    DBG(DBG_USER, "gpio=%d", gpio);
08954 
08955    CHECK_INITED;
08956 
08957    if (gpio > PI_MAX_USER_GPIO)
08958       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08959 
08960    switch (gpioInfo[gpio].is)
08961    {
08962       case GPIO_HW_PWM:
08963          pwm = (PWMDef[gpio] >> 4) & 3;
08964          return hw_pwm_freq[pwm];
08965 
08966       case GPIO_HW_CLK:
08967          clock = (clkDef[gpio] >> 4) & 3;
08968          return hw_clk_freq[clock];
08969 
08970       default:
08971          return pwmFreq[gpioInfo[gpio].freqIdx];
08972    }
08973 }
08974 
08975 
08976 /* ----------------------------------------------------------------------- */
08977 
08978 int gpioServo(unsigned gpio, unsigned val)
08979 {
08980    DBG(DBG_USER, "gpio=%d pulsewidth=%d", gpio, val);
08981 
08982    CHECK_INITED;
08983 
08984    if (gpio > PI_MAX_USER_GPIO)
08985       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
08986 
08987    if ((val!=PI_SERVO_OFF) && (val<PI_MIN_SERVO_PULSEWIDTH))
08988       SOFT_ERROR(PI_BAD_PULSEWIDTH,
08989          "gpio %d, bad pulsewidth (%d)", gpio, val);
08990 
08991    if (val>PI_MAX_SERVO_PULSEWIDTH)
08992       SOFT_ERROR(PI_BAD_PULSEWIDTH,
08993          "gpio %d, bad pulsewidth (%d)", gpio, val);
08994 
08995    if (gpioInfo[gpio].is != GPIO_SERVO)
08996    {
08997       switchFunctionOff(gpio);
08998 
08999       gpioInfo[gpio].is = GPIO_SERVO;
09000 
09001       if (!val) myGpioWrite(gpio, 0);
09002    }
09003 
09004    myGpioSetMode(gpio, PI_OUTPUT);
09005 
09006    myGpioSetServo(gpio, gpioInfo[gpio].width, val);
09007 
09008    gpioInfo[gpio].width=val;
09009 
09010    return 0;
09011 }
09012 
09013 
09014 /* ----------------------------------------------------------------------- */
09015 
09016 int gpioGetServoPulsewidth(unsigned gpio)
09017 {
09018    DBG(DBG_USER, "gpio=%d", gpio);
09019 
09020    CHECK_INITED;
09021 
09022    if (gpio > PI_MAX_USER_GPIO)
09023       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
09024 
09025    if (gpioInfo[gpio].is != GPIO_SERVO)
09026       SOFT_ERROR(PI_NOT_SERVO_GPIO, "not a servo gpio (%d)", gpio);
09027 
09028    return gpioInfo[gpio].width;
09029 }
09030 
09031 
09032 /* ----------------------------------------------------------------------- */
09033 
09034 int gpioWaveClear(void)
09035 {
09036    DBG(DBG_USER, "");
09037 
09038    CHECK_INITED;
09039 
09040    wfc[0] = 0;
09041    wfc[1] = 0;
09042    wfc[2] = 0;
09043 
09044    wfcur = 0;
09045 
09046    wfStats.micros = 0;
09047    wfStats.pulses = 0;
09048    wfStats.cbs    = 0;
09049 
09050    waveOutBotCB  = PI_WAVE_COUNT_PAGES*CBS_PER_OPAGE;
09051    waveOutBotOOL = PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE;
09052    waveOutTopOOL = NUM_WAVE_OOL;
09053 
09054    waveOutCount = 0;
09055 
09056    waveEndPtr = NULL;
09057 
09058    return 0;
09059 }
09060 
09061 /* ----------------------------------------------------------------------- */
09062 
09063 int gpioWaveAddNew(void)
09064 {
09065    DBG(DBG_USER, "");
09066 
09067    CHECK_INITED;
09068 
09069    wfc[0] = 0;
09070    wfc[1] = 0;
09071    wfc[2] = 0;
09072 
09073    wfcur = 0;
09074 
09075    wfStats.micros = 0;
09076    wfStats.pulses = 0;
09077    wfStats.cbs    = 0;
09078 
09079    return 0;
09080 }
09081 
09082 /* ----------------------------------------------------------------------- */
09083 
09084 int gpioWaveAddGeneric(unsigned numPulses, gpioPulse_t *pulses)
09085 {
09086    int p;
09087 
09088    DBG(DBG_USER, "numPulses=%u pulses=%08X", numPulses, (uint32_t)pulses);
09089 
09090    CHECK_INITED;
09091 
09092    if (numPulses > PI_WAVE_MAX_PULSES)
09093       SOFT_ERROR(PI_TOO_MANY_PULSES, "bad number of pulses (%d)", numPulses);
09094 
09095    if (!pulses) SOFT_ERROR(PI_BAD_POINTER, "bad (NULL) pulses pointer");
09096 
09097    for (p=0; p<numPulses; p++)
09098    {
09099       wf[2][p].gpioOff = pulses[p].gpioOff;
09100       wf[2][p].gpioOn  = pulses[p].gpioOn;
09101       wf[2][p].usDelay = pulses[p].usDelay;
09102       wf[2][p].flags   = 0;
09103    }
09104 
09105    return rawWaveAddGeneric(numPulses, wf[2]);
09106 }
09107 
09108 /* ----------------------------------------------------------------------- */
09109 
09110 int gpioWaveAddSerial
09111    (unsigned gpio,
09112     unsigned baud,
09113     unsigned data_bits,
09114     unsigned stop_bits,
09115     unsigned offset,
09116     unsigned numBytes,
09117     char     *bstr)
09118 {
09119    int i, b, p, lev, c, v;
09120 
09121    uint16_t *wstr = (uint16_t *)bstr;
09122    uint32_t *lstr = (uint32_t *)bstr;
09123 
09124    unsigned bitDelay[32];
09125 
09126    DBG(DBG_USER,
09127       "gpio=%d baud=%d bits=%d stops=%d offset=%d numBytes=%d str=[%s]",
09128       gpio, baud, data_bits, stop_bits, offset,
09129       numBytes, myBuf2Str(numBytes, (char *)bstr));
09130 
09131    CHECK_INITED;
09132 
09133    if (gpio > PI_MAX_USER_GPIO)
09134       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
09135 
09136    if ((baud < PI_WAVE_MIN_BAUD) || (baud > PI_WAVE_MAX_BAUD))
09137       SOFT_ERROR(PI_BAD_WAVE_BAUD, "bad baud rate (%d)", baud);
09138 
09139    if ((data_bits < PI_MIN_WAVE_DATABITS) ||
09140        (data_bits > PI_MAX_WAVE_DATABITS))
09141       SOFT_ERROR(PI_BAD_DATABITS, "bad number of databits (%d)", data_bits);
09142 
09143    if ((stop_bits < PI_MIN_WAVE_HALFSTOPBITS) ||
09144        (stop_bits > PI_MAX_WAVE_HALFSTOPBITS))
09145       SOFT_ERROR(PI_BAD_STOPBITS,
09146          "bad number of (half) stop bits (%d)", stop_bits);
09147 
09148    if (gpio > PI_MAX_USER_GPIO)
09149       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
09150 
09151    if (numBytes > PI_WAVE_MAX_CHARS)
09152       SOFT_ERROR(PI_TOO_MANY_CHARS, "too many chars (%d)", numBytes);
09153 
09154    if (offset > PI_WAVE_MAX_MICROS)
09155       SOFT_ERROR(PI_BAD_SER_OFFSET, "offset too large (%d)", offset);
09156 
09157    if (data_bits > 8) numBytes /= 2;
09158    if (data_bits > 16) numBytes /= 2;
09159 
09160    if (!numBytes) return 0;
09161 
09162    waveBitDelay(baud, data_bits, stop_bits, bitDelay);
09163 
09164    p = 0;
09165 
09166    wf[2][p].gpioOn  = (1<<gpio);
09167    wf[2][p].gpioOff = 0;
09168    wf[2][p].flags   = 0;
09169 
09170    if (offset > bitDelay[0]) wf[2][p].usDelay = offset;
09171    else                      wf[2][p].usDelay = bitDelay[0];
09172 
09173    for (i=0; i<numBytes; i++)
09174    {
09175       p++;
09176 
09177       /* start bit */
09178 
09179       wf[2][p].gpioOn = 0;
09180       wf[2][p].gpioOff = (1<<gpio);
09181       wf[2][p].usDelay = bitDelay[0];
09182       wf[2][p].flags   = 0;
09183 
09184       lev = 0;
09185 
09186       if      (data_bits <  9) c = bstr[i];
09187       else if (data_bits < 17) c = wstr[i];
09188       else                  c = lstr[i];
09189 
09190       for (b=0; b<data_bits; b++)
09191       {
09192          if (c & (1<<b)) v=1; else v=0;
09193 
09194          if (v == lev) wf[2][p].usDelay += bitDelay[b+1];
09195          else
09196          {
09197             p++;
09198 
09199             lev = v;
09200 
09201             if (lev)
09202             {
09203                wf[2][p].gpioOn  = (1<<gpio);
09204                wf[2][p].gpioOff = 0;
09205                wf[2][p].flags   = 0;
09206             }
09207             else
09208             {
09209                wf[2][p].gpioOn  = 0;
09210                wf[2][p].gpioOff = (1<<gpio);
09211                wf[2][p].flags   = 0;
09212             }
09213 
09214             wf[2][p].usDelay = bitDelay[b+1];
09215          }
09216       }
09217 
09218       /* stop bit */
09219 
09220       if (lev) wf[2][p].usDelay += bitDelay[data_bits+1];
09221       else
09222       {
09223          p++;
09224 
09225          wf[2][p].gpioOn  = (1<<gpio);
09226          wf[2][p].gpioOff = 0;
09227          wf[2][p].usDelay = bitDelay[data_bits+1];
09228          wf[2][p].flags   = 0;
09229       }
09230    }
09231 
09232    p++;
09233 
09234    wf[2][p].gpioOn  = (1<<gpio);
09235    wf[2][p].gpioOff = 0;
09236    wf[2][p].usDelay = bitDelay[0];
09237    wf[2][p].flags   = 0;
09238 
09239    return rawWaveAddGeneric(p, wf[2]);
09240 }
09241 
09242 /* ----------------------------------------------------------------------- */
09243 
09244 int rawWaveAddSPI(
09245    rawSPI_t *spi,
09246    unsigned offset,
09247    unsigned spiSS,
09248    char *buf,
09249    unsigned spiTxBits,
09250    unsigned spiBitFirst,
09251    unsigned spiBitLast,
09252    unsigned spiBits)
09253 {
09254    int p, bit, dbv, halfbit;
09255    int rising_edge[2], read_cycle[2];
09256    uint32_t on_bits, off_bits;
09257    int tx_bit_pos;
09258 
09259    DBG(DBG_USER,
09260       "spi=%08X off=%d spiSS=%d tx=%08X, num=%d fb=%d lb=%d spiBits=%d",
09261       (uint32_t)spi, offset, spiSS, (uint32_t)buf, spiTxBits,
09262       spiBitFirst, spiBitLast, spiBits);
09263 
09264    CHECK_INITED;
09265 
09266    if (spiSS > PI_MAX_USER_GPIO)
09267       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", spiSS);
09268 
09269    /*
09270    CPOL CPHA
09271     0    0   read rising/write falling
09272     0    1   read falling/write rising
09273     1    0   read falling/write rising
09274     1    1   read rising/write falling
09275    */
09276 
09277    if (spi->clk_pol) {rising_edge[0] = 0; rising_edge[1] = 1;}
09278    else              {rising_edge[0] = 1; rising_edge[1] = 0;}
09279 
09280    if (spi->clk_pha) {read_cycle[0] = 0; read_cycle[1] = 1;}
09281    else              {read_cycle[0] = 1; read_cycle[1] = 0;}
09282 
09283    p = 0;
09284 
09285    if (offset)
09286    {
09287       wf[2][p].gpioOn  = 0;
09288       wf[2][p].gpioOff = 0;
09289       wf[2][p].flags   = 0;
09290       wf[2][p].usDelay = offset;
09291       p++;
09292    }
09293 
09294    on_bits = 0;
09295    off_bits = 0;
09296 
09297    tx_bit_pos = 0;
09298 
09299    /* preset initial mosi bit */
09300 
09301    if (getBitInBytes(tx_bit_pos, buf, spiTxBits))
09302    {
09303       on_bits  |= (1<<(spi->mosi));
09304       dbv = 1;
09305    }
09306    else
09307    {
09308       off_bits |= (1<<(spi->mosi));
09309       dbv = 0;
09310    }
09311 
09312    if (!spi->clk_pha) tx_bit_pos ++;
09313 
09314    if (spi->ss_pol) off_bits |= (1<<spiSS);
09315    else             on_bits  |= (1<<spiSS);
09316 
09317    if (spi->clk_pol) on_bits  |= (1<<(spi->clk));
09318    else              off_bits |= (1<<(spi->clk));
09319 
09320    wf[2][p].gpioOn  = on_bits;
09321    wf[2][p].gpioOff = off_bits;
09322    wf[2][p].flags   = 0;
09323 
09324    if (spi->clk_us > spi->ss_us) wf[2][p].usDelay = spi->clk_us;
09325    else                          wf[2][p].usDelay = spi->ss_us;
09326 
09327    p++;
09328 
09329    for (bit=1; bit<=spiBits; bit++)
09330    {
09331       for (halfbit=0; halfbit<2; halfbit++)
09332       {
09333          wf[2][p].usDelay = spi->clk_us;
09334          wf[2][p].flags = 0;
09335 
09336          on_bits = 0;
09337          off_bits = 0;
09338 
09339          if (read_cycle[halfbit])
09340          {
09341             if ((bit>=spiBitFirst) && (bit<=spiBitLast))
09342                wf[2][p].flags = WAVE_FLAG_READ;
09343          }
09344          else
09345          {
09346             if (getBitInBytes(tx_bit_pos, buf, spiTxBits))
09347             {
09348                if (!dbv) on_bits  |= (1<<(spi->mosi));
09349                dbv = 1;
09350             }
09351             else
09352             {
09353                if (dbv) off_bits |= (1<<(spi->mosi));
09354                dbv = 0;
09355             }
09356 
09357             ++tx_bit_pos;
09358          }
09359 
09360          if (rising_edge[halfbit]) on_bits  |= (1<<(spi->clk));
09361          else                      off_bits |= (1<<(spi->clk));
09362 
09363          wf[2][p].gpioOn = on_bits;
09364          wf[2][p].gpioOff = off_bits;
09365 
09366          p++;
09367       }
09368    }
09369 
09370    on_bits = 0;
09371    off_bits = 0;
09372 
09373    if (spi->ss_pol) on_bits  |= (1<<spiSS);
09374    else             off_bits |= (1<<spiSS);
09375 
09376    wf[2][p].gpioOn  = on_bits;
09377    wf[2][p].gpioOff = off_bits;
09378    wf[2][p].flags   = 0;
09379    wf[2][p].usDelay = 0;
09380 
09381    p++;
09382 
09383    return rawWaveAddGeneric(p, wf[2]);
09384 }
09385 
09386 /* ----------------------------------------------------------------------- */
09387 
09388 int gpioWaveCreate(void)
09389 {
09390    int i, wid;
09391    int numCB, numBOOL, numTOOL;
09392    int CB, BOOL, TOOL;
09393 
09394    DBG(DBG_USER, "");
09395 
09396    CHECK_INITED;
09397 
09398    if (wfc[wfcur] == 0) return PI_EMPTY_WAVEFORM;
09399 
09400    /* What resources are needed? */
09401 
09402    waveCBsOOLs(&numCB, &numBOOL, &numTOOL);
09403 
09404    wid = -1;
09405 
09406    /* Is there an exact fit with a deleted wave. */
09407 
09408    for (i=0; i<waveOutCount; i++)
09409    {
09410       if (waveInfo[i].deleted             &&
09411          (waveInfo[i].numCB   == numCB)   &&
09412          (waveInfo[i].numBOOL == numBOOL) &&
09413          (waveInfo[i].numTOOL == numTOOL))
09414       {
09415          /* Reuse the deleted waves resources. */
09416          wid = i;
09417          break;
09418       }
09419    }
09420 
09421    if (wid == -1)
09422    {
09423       /* Are there enough spare resources? */
09424 
09425       if ((numCB+waveOutBotCB) >= NUM_WAVE_CBS)
09426          return PI_TOO_MANY_CBS;
09427 
09428       if ((numBOOL+waveOutBotOOL) >= (waveOutTopOOL-numTOOL))
09429          return PI_TOO_MANY_OOL;
09430 
09431       if (wid >= PI_MAX_WAVES)
09432          return PI_NO_WAVEFORM_ID;
09433 
09434       wid = waveOutCount++;
09435 
09436       waveInfo[wid].botCB  = waveOutBotCB;
09437       waveInfo[wid].topCB  = waveOutBotCB + numCB -1;
09438       waveInfo[wid].botOOL = waveOutBotOOL;
09439       waveInfo[wid].topOOL = waveOutTopOOL;
09440       waveInfo[wid].numCB = numCB;
09441       waveInfo[wid].numBOOL = numBOOL;
09442       waveInfo[wid].numTOOL = numTOOL;
09443 
09444       waveOutBotCB += numCB;
09445       waveOutBotOOL += numBOOL;
09446       waveOutTopOOL -= numTOOL;
09447    }
09448 
09449    /* Must be room if got this far. */
09450 
09451    CB   = waveInfo[wid].botCB;
09452    BOOL = waveInfo[wid].botOOL;
09453    TOOL = waveInfo[wid].topOOL;
09454 
09455    wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL);
09456 
09457    /* Sanity check. */
09458 
09459    if ( (numCB   != (CB-waveInfo[wid].botCB))    ||
09460         (numBOOL != (BOOL-waveInfo[wid].botOOL)) ||
09461         (numTOOL != (waveInfo[wid].topOOL-TOOL)) )
09462    {
09463       DBG(DBG_ALWAYS, "ERROR wid=%d CBs %d=%d BOOL %d=%d TOOL %d=%d", wid,
09464          numCB,   CB-waveInfo[wid].botCB,
09465          numBOOL, BOOL-waveInfo[wid].botOOL,
09466          numTOOL, waveInfo[wid].topOOL-TOOL);
09467    }
09468 
09469    waveInfo[wid].deleted = 0;
09470 
09471    /* Consume waves. */
09472 
09473    wfc[0] = 0;
09474    wfc[1] = 0;
09475    wfc[2] = 0;
09476 
09477    wfcur = 0;
09478 
09479    return wid;
09480 }
09481 
09482 /* ----------------------------------------------------------------------- */
09483 
09484 int gpioWaveDelete(unsigned wave_id)
09485 {
09486    DBG(DBG_USER, "wave id=%d", wave_id);
09487 
09488    CHECK_INITED;
09489 
09490    if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
09491       SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
09492 
09493    waveInfo[wave_id].deleted = 1;
09494 
09495    if (wave_id == (waveOutCount-1))
09496    {
09497       /* top wave deleted, garbage collect any other deleted waves */
09498 
09499       while ((wave_id > 0) && (waveInfo[wave_id-1].deleted)) --wave_id;
09500 
09501       waveOutBotCB  = waveInfo[wave_id].botCB;
09502       waveOutBotOOL = waveInfo[wave_id].botOOL;
09503       waveOutTopOOL = waveInfo[wave_id].topOOL;
09504 
09505       waveOutCount = wave_id;
09506    }
09507 
09508    return 0;
09509 }
09510 
09511 /* ----------------------------------------------------------------------- */
09512 
09513 int gpioWaveTxStart(unsigned wave_mode)
09514 {
09515    /* This function is deprecated and has been removed. */
09516 
09517    CHECK_INITED;
09518 
09519    SOFT_ERROR(PI_DEPRECATED, "deprected function removed");
09520 }
09521 
09522 /* ----------------------------------------------------------------------- */
09523 
09524 int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
09525 {
09526    rawCbs_t *p=NULL;
09527 
09528    DBG(DBG_USER, "wave_id=%d wave_mode=%d", wave_id, wave_mode);
09529 
09530    CHECK_INITED;
09531 
09532    if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
09533       SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
09534 
09535    if (wave_mode > PI_WAVE_MODE_REPEAT_SYNC)
09536       SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", wave_mode);
09537 
09538    if (!waveClockInited)
09539    {
09540       stopHardwarePWM();
09541       initClock(0); /* initialise secondary clock */
09542       waveClockInited = 1;
09543       PWMClockInited = 0;
09544    }
09545 
09546    if (wave_mode < PI_WAVE_MODE_ONE_SHOT_SYNC)
09547    {
09548       dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
09549       dmaOut[DMA_CONBLK_AD] = 0;
09550    }
09551 
09552    p = rawWaveCBAdr(waveInfo[wave_id].topCB);
09553 
09554    if ((wave_mode & 1) == PI_WAVE_MODE_ONE_SHOT)
09555       p->next = 0;
09556    else
09557       p->next = waveCbPOadr(waveInfo[wave_id].botCB+1);
09558 
09559    if (waveEndPtr && (wave_mode > PI_WAVE_MODE_REPEAT))
09560    {
09561       *waveEndPtr = waveCbPOadr(waveInfo[wave_id].botCB+1);
09562 
09563       if (!dmaOut[DMA_CONBLK_AD])
09564       {
09565          initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
09566       }
09567    }
09568    else
09569    {
09570       initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
09571    }
09572 
09573    waveEndPtr = &p->next;
09574 
09575    /* for compatability with the deprecated gpioWaveTxStart return the
09576       number of cbs
09577    */
09578    return (waveInfo[wave_id].topCB - waveInfo[wave_id].botCB) + 1;
09579 }
09580 
09581 
09582 /* ----------------------------------------------------------------------- */
09583 
09584 static int chainGetCB(int n)
09585 {
09586    int block, index;
09587 
09588    if (n < (WCB_CHAIN_CBS * PI_WAVE_COUNT_PAGES))
09589    {
09590       block = n / WCB_CHAIN_CBS;
09591       index = n % WCB_CHAIN_CBS;
09592       return (block*CBS_PER_OPAGE) + WCB_COUNTER_CBS + index;
09593    }
09594    return -1;
09595 }
09596 
09597 static void chainSetVal(int n, uint32_t val)
09598 {
09599    int block, index;
09600    uint32_t *p;
09601 
09602    if (n < (WCB_CHAIN_OOL * PI_WAVE_COUNT_PAGES))
09603    {
09604       block = n / WCB_CHAIN_OOL;
09605       index = n % WCB_CHAIN_OOL;
09606       p = (uint32_t *) dmaOVirt[block] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09607       p[index] = val;
09608    }
09609 }
09610 
09611 static uint32_t chainGetValPadr(int n)
09612 {
09613    int block, index;
09614    uint32_t *p;
09615 
09616    if (n < (WCB_CHAIN_OOL * PI_WAVE_COUNT_PAGES))
09617    {
09618       block = n / WCB_CHAIN_OOL;
09619       index = n % WCB_CHAIN_OOL;
09620       p = (uint32_t *) dmaOBus[block] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09621       return (uint32_t) (p + index);
09622    }
09623    return 0;
09624 }
09625 
09626 static uint32_t chainGetCntVal(int counter, int slot)
09627 {
09628    uint32_t *p;
09629    int page, offset;
09630    page = counter / 2;
09631    offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
09632    p = (uint32_t *) dmaOVirt[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09633    return p[WCB_CHAIN_OOL+ offset + slot];
09634 }
09635 
09636 static void chainSetCntVal(int counter, int slot, uint32_t value)
09637 {
09638    uint32_t *p;
09639    int page, offset;
09640    page = counter / 2;
09641    offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
09642    p = (uint32_t *) dmaOVirt[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09643    p[WCB_CHAIN_OOL + offset + slot] = value;
09644 }
09645 
09646 static uint32_t chainGetCntValPadr(int counter, int slot)
09647 {
09648    uint32_t *p;
09649    int page, offset;
09650    page = counter / 2;
09651    offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
09652    p = (uint32_t *) dmaOBus[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09653    return (uint32_t)(p + WCB_CHAIN_OOL + offset + slot);
09654 }
09655 
09656 static int chainGetCntCB(int counter)
09657 {
09658    int page, offset;
09659    page = counter / 2;
09660    offset = (counter % 2 ? WCB_CNT_CBS : 0);
09661    return ((page * CBS_PER_OPAGE) + offset);
09662 }
09663 
09664 static void chainMakeCounter(
09665    unsigned counter,
09666    unsigned blklen,
09667    unsigned blocks,
09668    unsigned count,
09669    uint32_t repeat,
09670    uint32_t next)
09671 {
09672    rawCbs_t *p=NULL;
09673 
09674    int b, baseCB, dig;
09675    uint32_t nxt;
09676 
09677    int botCB;
09678 
09679    botCB  = chainGetCntCB(counter);
09680 
09681    baseCB = botCB;
09682 
09683    /* set up all the OOLs */
09684    for (b=0; b < (blocks*(blklen+1)); b++) chainSetCntVal(counter, b, repeat);
09685 
09686    for (b=0; b<blocks; b++)
09687       chainSetCntVal(counter,
09688          ((b*(blklen+1))+blklen),
09689          waveCbPOadr(baseCB+((b*3)+3)));
09690 
09691    for (b=0; b<blocks; b++)
09692    {
09693       /* copy BOTTOM to NEXT */
09694 
09695       p = rawWaveCBAdr(botCB++);
09696 
09697       p->info = NORMAL_DMA;
09698 
09699       p->src = chainGetCntValPadr(counter, b*(blklen+1));
09700       p->dst = (waveCbPOadr(botCB+1) + 20);
09701 
09702       p->length = 4;
09703       p->next   = waveCbPOadr(botCB);
09704 
09705       /* copy BOTTOM to TOP */
09706 
09707       p = rawWaveCBAdr(botCB++);
09708 
09709       p->info   = NORMAL_DMA;
09710 
09711       p->src = chainGetCntValPadr(counter, b*(blklen+1));
09712       p->dst = chainGetCntValPadr(counter, (b*(blklen+1))+blklen);
09713 
09714       p->length = 4;
09715       p->next   = waveCbPOadr(botCB);
09716 
09717       /* shift all down one */
09718 
09719       p = rawWaveCBAdr(botCB++);
09720 
09721       p->info   = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
09722 
09723       p->src = chainGetCntValPadr(counter, ((b*(blklen+1))+1));
09724       p->dst = chainGetCntValPadr(counter, ((b*(blklen+1))+0));
09725 
09726       p->length = blklen*4;
09727       p->next   = repeat;
09728    }
09729 
09730    /* reset the counter */
09731 
09732    p = rawWaveCBAdr(botCB);
09733 
09734    p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
09735 
09736    p->src = chainGetCntValPadr(counter, blocks*(blklen+1));
09737    p->dst = chainGetCntValPadr(counter, 0);
09738 
09739    p->length = blocks*(blklen+1)*4;
09740    p->next   = next;
09741 
09742    b = 0;
09743 
09744    while (count && (b<blocks))
09745    {
09746       dig = count % blklen;
09747       count /= blklen;
09748 
09749       if (count) nxt = chainGetCntVal(counter, (b*(blklen+1))+blklen);
09750       else       nxt = waveCbPOadr(botCB);
09751 
09752       chainSetCntVal(counter, b*(blklen+1)+dig, nxt);
09753 
09754       b++;
09755    }
09756 
09757    /* copy all the OOLs */
09758    for (b=0; b < (blocks*(blklen+1)); b++)
09759       chainSetCntVal(
09760          counter, b+(blocks*(blklen+1)), chainGetCntVal(counter, b));
09761 }
09762 
09763 
09764 int gpioWaveChain(char *buf, unsigned bufSize)
09765 {
09766    unsigned blklen=16, blocks=4;
09767    int cb, chaincb;
09768    rawCbs_t *p;
09769    int i, wid, cmd, loop, counters;
09770    unsigned cycles, delayCBs, dcb, delayLeft;
09771    uint32_t repeat, next, *endPtr;
09772    int stk_pos[10], stk_lev=0;
09773 
09774    cb = 0;
09775    loop = -1;
09776 
09777    DBG(DBG_USER, "bufSize=%d [%s]", bufSize, myBuf2Str(bufSize, buf));
09778 
09779    CHECK_INITED;
09780 
09781    if (!waveClockInited)
09782    {
09783       stopHardwarePWM();
09784       initClock(0); /* initialise secondary clock */
09785       waveClockInited = 1;
09786       PWMClockInited = 0;
09787    }
09788 
09789    dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
09790    dmaOut[DMA_CONBLK_AD] = 0;
09791    waveEndPtr = NULL;
09792    endPtr = NULL;
09793 
09794    /* add delay cb at start of DMA */
09795 
09796    p = rawWaveCBAdr(chainGetCB(cb++));
09797 
09798    /* use the secondary clock */
09799 
09800    if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
09801    {
09802       p->info = NORMAL_DMA | TIMED_DMA(2);
09803       p->dst  = PCM_TIMER;
09804    }
09805    else
09806    {
09807       p->info = NORMAL_DMA | TIMED_DMA(5);
09808       p->dst  = PWM_TIMER;
09809    }
09810 
09811    p->src    = (uint32_t) (&dmaOBus[0]->periphData);
09812    p->length = BPD * 20 / PI_WF_MICROS; /* 20 micros delay */
09813    p->next   = waveCbPOadr(chainGetCB(cb));
09814 
09815    counters = 0;
09816    wid = -1;
09817 
09818    i = 0;
09819 
09820    while (i<bufSize)
09821    {
09822       wid = (unsigned)buf[i];
09823 
09824       if (wid == 255) /* wave command */
09825       {
09826          if ((i+2) > bufSize)
09827             SOFT_ERROR(PI_BAD_CHAIN_CMD,
09828                "incomplete chain command (at %d)", i);
09829 
09830          cmd = buf[i+1];
09831 
09832          if (cmd == 0) /* loop begin */
09833          {
09834             if (stk_lev >= (sizeof(stk_pos)/sizeof(int)))
09835                SOFT_ERROR(PI_CHAIN_NESTING,
09836                   "chain counters nested too deep (at %d)", i);
09837 
09838             stk_pos[stk_lev++] = cb;
09839 
09840             i += 2;
09841          }
09842          else if (cmd == 1) /* loop end */
09843          {
09844             if (counters >= WCB_COUNTERS)
09845                SOFT_ERROR(PI_CHAIN_COUNTER,
09846                   "too many chain counters (at %d)", i);
09847 
09848             if ((i+4) > bufSize)
09849                SOFT_ERROR(PI_BAD_CHAIN_CMD,
09850                   "incomplete chain command (at %d)", i);
09851 
09852             loop = 0;
09853             if (--stk_lev >= 0) loop = stk_pos[stk_lev];
09854 
09855             if ((loop < 1) || (loop == cb))
09856                SOFT_ERROR(PI_BAD_CHAIN_LOOP,
09857                   "empty chain loop (at %d)", i);
09858 
09859             cycles = ((unsigned)buf[i+3] <<  8) + (unsigned)buf[i+2];
09860 
09861             i += 4;
09862 
09863             if (cycles > PI_MAX_WAVE_CYCLES)
09864                SOFT_ERROR(PI_CHAIN_LOOP_CNT,
09865                   "bad chain loop count (%d)", cycles);
09866 
09867             if (cycles == 0)
09868             {
09869                /* Skip the complete loop block.  Change
09870                   the next pointing to the start of the
09871                   loop block to the current cb.
09872                */
09873                p = rawWaveCBAdr(chainGetCB(loop));
09874                p->next = waveCbPOadr(chainGetCB(cb));
09875             }
09876             else if (cycles == 1)
09877             {
09878                /* Nothing to do, no need for a counter. */
09879             }
09880             else
09881             {
09882                chaincb = chainGetCB(cb++);
09883                if (chaincb < 0)
09884                   SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09885 
09886                p = rawWaveCBAdr(chaincb);
09887 
09888                repeat = waveCbPOadr(chainGetCB(loop));
09889 
09890                 /* Need to check next cb as well. */
09891 
09892                chaincb = chainGetCB(cb);
09893 
09894                if (chaincb < 0)
09895                   SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09896 
09897                next = waveCbPOadr(chainGetCB(cb));
09898 
09899                /* dummy src and dest */
09900                p->info = NORMAL_DMA;
09901                p->src = (uint32_t) (&dmaOBus[0]->periphData);
09902                p->dst = (uint32_t) (&dmaOBus[0]->periphData);
09903                p->length = 4;
09904                p->next = waveCbPOadr(chainGetCntCB(counters));
09905 
09906                chainMakeCounter(counters, blklen, blocks,
09907                             cycles-1, repeat, next);
09908 
09909                counters++;
09910             }
09911          }
09912          else if (cmd == 2) /* delay us */
09913          {
09914             if ((i+4) > bufSize)
09915                SOFT_ERROR(PI_BAD_CHAIN_CMD,
09916                   "incomplete chain command (at %d)", i);
09917 
09918             cycles = ((unsigned)buf[i+3] <<  8) + (unsigned)buf[i+2];
09919 
09920             i += 4;
09921 
09922             if (cycles > PI_MAX_WAVE_DELAY)
09923                SOFT_ERROR(PI_BAD_CHAIN_DELAY,
09924                   "bad chain delay micros (%d)", cycles);
09925 
09926             if (cycles)
09927             {
09928                delayLeft = cycles;
09929                delayCBs = waveDelayCBs(delayLeft);
09930                for (dcb=0; dcb<delayCBs; dcb++)
09931                {
09932                   chaincb = chainGetCB(cb++);
09933 
09934                   if (chaincb < 0)
09935                      SOFT_ERROR(
09936                         PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09937 
09938                   p = rawWaveCBAdr(chaincb);
09939 
09940                   /* use the secondary clock */
09941 
09942                   if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
09943                   {
09944                      p->info = NORMAL_DMA | TIMED_DMA(2);
09945                      p->dst  = PCM_TIMER;
09946                   }
09947                   else
09948                   {
09949                      p->info = NORMAL_DMA | TIMED_DMA(5);
09950                      p->dst  = PWM_TIMER;
09951                   }
09952 
09953                   p->src = (uint32_t) (&dmaOBus[0]->periphData);
09954 
09955                   p->length = BPD * delayLeft / PI_WF_MICROS;
09956 
09957                   if ((gpioCfg.DMAsecondaryChannel >= DMA_LITE_FIRST) &&
09958                       (p->length > DMA_LITE_MAX))
09959                   {
09960                      p->length = DMA_LITE_MAX;
09961                   }
09962 
09963                   delayLeft -= (p->length / BPD);
09964 
09965                   p->next = waveCbPOadr(chainGetCB(cb));
09966                }
09967             }
09968          }
09969          else if (cmd == 3) /* repeat loop forever */
09970          {
09971             i += 2;
09972 
09973             loop = 0;
09974             if (--stk_lev >= 0) loop = stk_pos[stk_lev];
09975 
09976             if ((loop < 1) || (loop == cb))
09977                SOFT_ERROR(PI_BAD_CHAIN_LOOP,
09978                   "empty chain loop (at %d)", i);
09979 
09980             chaincb = chainGetCB(cb++);
09981             if (chaincb < 0)
09982                SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09983 
09984             if (i < bufSize)
09985                SOFT_ERROR(PI_BAD_FOREVER,
09986                   "loop forever must be last command");
09987 
09988             p = rawWaveCBAdr(chaincb);
09989 
09990             /* dummy src and dest */
09991             p->info = NORMAL_DMA;
09992             p->src = (uint32_t) (&dmaOBus[0]->periphData);
09993             p->dst = (uint32_t) (&dmaOBus[0]->periphData);
09994             p->length = 4;
09995             p->next = waveCbPOadr(chainGetCB(loop));
09996             endPtr = &p->next;
09997          }
09998          else
09999             SOFT_ERROR(PI_BAD_CHAIN_CMD,
10000                "unknown chain command (255 %d)", cmd);
10001       }
10002       else if ((wid >= waveOutCount) || waveInfo[wid].deleted)
10003          SOFT_ERROR(PI_BAD_WAVE_ID, "undefined wave (%d)", wid);
10004       else
10005       {
10006          chaincb = chainGetCB(cb++);
10007 
10008          if (chaincb < 0)
10009             SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
10010 
10011          p = rawWaveCBAdr(chaincb);
10012 
10013          chaincb = chainGetCB(cb);
10014 
10015          if (chaincb < 0)
10016             SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
10017 
10018          chainSetVal(cb-1, waveCbPOadr(chaincb));
10019 
10020          /* patch next of wid topCB to next cb */
10021 
10022          p->info   = NORMAL_DMA;
10023          p->src    = chainGetValPadr(cb-1); /* this next */
10024          p->dst    = waveCbPOadr(waveInfo[wid].topCB) + 20; /* wid next */
10025          p->length = 4;
10026          p->next   = waveCbPOadr(waveInfo[wid].botCB+1);
10027 
10028          i += 1;
10029       }
10030    }
10031 
10032    chaincb = chainGetCB(cb++);
10033 
10034    if (chaincb < 0)
10035       SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
10036 
10037    p = rawWaveCBAdr(chaincb);
10038 
10039    p->info   = NORMAL_DMA;
10040    p->src    = (uint32_t) (&dmaOBus[0]->periphData);
10041    p->dst    = (uint32_t) (&dmaOBus[0]->periphData);
10042    p->length = 4;
10043    p->next = 0;
10044 
10045    if (!endPtr) endPtr = &p->next;
10046 
10047    initDMAgo((uint32_t *)dmaOut, waveCbPOadr(chainGetCB(0)));
10048 
10049    waveEndPtr = endPtr;
10050 
10051    return 0;
10052 }
10053 
10054 /*-------------------------------------------------------------------------*/
10055 
10056 int gpioWaveTxBusy(void)
10057 {
10058    DBG(DBG_USER, "");
10059 
10060    CHECK_INITED;
10061 
10062    if (dmaOut[DMA_CONBLK_AD])
10063       return 1;
10064    else
10065       return 0;
10066 }
10067 
10068 /*-------------------------------------------------------------------------*/
10069 
10070 int gpioWaveTxAt(void)
10071 {
10072    int i, cb;
10073 
10074    DBG(DBG_USER, "");
10075 
10076    CHECK_INITED;
10077 
10078    cb = dmaNowAtOCB();
10079 
10080    if (cb < 0) return -cb;
10081 
10082    for (i=0; i<PI_MAX_WAVES; i++)
10083    {
10084       if ( !waveInfo[i].deleted &&
10085           (cb >= waveInfo[i].botCB) &&
10086           (cb <= waveInfo[i].topCB) ) return i;
10087    }
10088 
10089    return PI_WAVE_NOT_FOUND;
10090 }
10091 
10092 /* ----------------------------------------------------------------------- */
10093 
10094 int gpioWaveTxStop(void)
10095 {
10096    DBG(DBG_USER, "");
10097 
10098    CHECK_INITED;
10099 
10100    dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
10101    dmaOut[DMA_CONBLK_AD] = 0;
10102 
10103    waveEndPtr = NULL;
10104 
10105    return 0;
10106 }
10107 
10108 /* ----------------------------------------------------------------------- */
10109 
10110 int gpioWaveGetMicros(void)
10111 {
10112    DBG(DBG_USER, "");
10113 
10114    CHECK_INITED;
10115 
10116    return wfStats.micros;
10117 }
10118 
10119 /* ----------------------------------------------------------------------- */
10120 
10121 int gpioWaveGetHighMicros(void)
10122 {
10123    DBG(DBG_USER, "");
10124 
10125    CHECK_INITED;
10126 
10127    return wfStats.highMicros;
10128 }
10129 
10130 /* ----------------------------------------------------------------------- */
10131 
10132 int gpioWaveGetMaxMicros(void)
10133 {
10134    DBG(DBG_USER, "");
10135 
10136    CHECK_INITED;
10137 
10138    return wfStats.maxMicros;
10139 }
10140 
10141 /* ----------------------------------------------------------------------- */
10142 
10143 int gpioWaveGetPulses(void)
10144 {
10145    DBG(DBG_USER, "");
10146 
10147    CHECK_INITED;
10148 
10149    return wfStats.pulses;
10150 }
10151 
10152 /* ----------------------------------------------------------------------- */
10153 
10154 int gpioWaveGetHighPulses(void)
10155 {
10156    DBG(DBG_USER, "");
10157 
10158    CHECK_INITED;
10159 
10160    return wfStats.highPulses;
10161 }
10162 
10163 /* ----------------------------------------------------------------------- */
10164 
10165 int gpioWaveGetMaxPulses(void)
10166 {
10167    DBG(DBG_USER, "");
10168 
10169    CHECK_INITED;
10170 
10171    return wfStats.maxPulses;
10172 }
10173 
10174 /* ----------------------------------------------------------------------- */
10175 
10176 int gpioWaveGetCbs(void)
10177 {
10178    DBG(DBG_USER, "");
10179 
10180    CHECK_INITED;
10181 
10182    return wfStats.cbs;
10183 }
10184 
10185 /* ----------------------------------------------------------------------- */
10186 
10187 int gpioWaveGetHighCbs(void)
10188 {
10189    DBG(DBG_USER, "");
10190 
10191    CHECK_INITED;
10192 
10193    return wfStats.highCbs;
10194 }
10195 
10196 /* ----------------------------------------------------------------------- */
10197 
10198 int gpioWaveGetMaxCbs(void)
10199 {
10200    DBG(DBG_USER, "");
10201 
10202    CHECK_INITED;
10203 
10204    return wfStats.maxCbs;
10205 }
10206 
10207 /* ----------------------------------------------------------------------- */
10208 
10209 static int read_SDA(wfRx_t *w)
10210 {
10211    myGpioSetMode(w->I.SDA, PI_INPUT);
10212    return myGpioRead(w->I.SDA);
10213 }
10214 
10215 static void set_SDA(wfRx_t *w)
10216 {
10217    myGpioSetMode(w->I.SDA, PI_INPUT);
10218 }
10219 
10220 static void clear_SDA(wfRx_t *w)
10221 {
10222    myGpioSetMode(w->I.SDA, PI_OUTPUT);
10223    myGpioWrite(w->I.SDA, 0);
10224 }
10225 
10226 static void clear_SCL(wfRx_t *w)
10227 {
10228    myGpioSetMode(w->I.SCL, PI_OUTPUT);
10229    myGpioWrite(w->I.SCL, 0);
10230 }
10231 
10232 static void I2C_delay(wfRx_t *w)
10233 {
10234    myGpioDelay(w->I.delay);
10235 }
10236 
10237 static void I2C_clock_stretch(wfRx_t *w)
10238 {
10239    uint32_t now, max_stretch=100000;
10240 
10241    myGpioSetMode(w->I.SCL, PI_INPUT);
10242    now = gpioTick();
10243    while ((myGpioRead(w->I.SCL) == 0) && ((gpioTick()-now) < max_stretch));
10244 }
10245 
10246 static void I2CStart(wfRx_t *w)
10247 {
10248    if (w->I.started)
10249    {
10250       set_SDA(w);
10251       I2C_delay(w);
10252       I2C_clock_stretch(w);
10253       I2C_delay(w);
10254    }
10255 
10256    clear_SDA(w);
10257    I2C_delay(w);
10258    clear_SCL(w);
10259    I2C_delay(w);
10260 
10261    w->I.started = 1;
10262 }
10263 
10264 static void I2CStop(wfRx_t *w)
10265 {
10266    clear_SDA(w);
10267    I2C_delay(w);
10268    I2C_clock_stretch(w);
10269    I2C_delay(w);
10270    set_SDA(w);
10271    I2C_delay(w);
10272 
10273    w->I.started = 0;
10274 }
10275 
10276 static void I2CPutBit(wfRx_t *w, int bit)
10277 {
10278    if (bit) set_SDA(w);
10279    else     clear_SDA(w);
10280 
10281    I2C_delay(w);
10282    I2C_clock_stretch(w);
10283    I2C_delay(w);
10284    clear_SCL(w);
10285 }
10286 
10287 static int I2CGetBit(wfRx_t *w)
10288 {
10289    int bit;
10290 
10291    set_SDA(w); /* let SDA float */
10292    I2C_delay(w);
10293    I2C_clock_stretch(w);
10294    bit = read_SDA(w);
10295    I2C_delay(w);
10296    clear_SCL(w);
10297 
10298    return bit;
10299 }
10300 
10301 static int I2CPutByte(wfRx_t *w, int byte)
10302 {
10303    int bit, nack;
10304 
10305    for(bit=0; bit<8; bit++)
10306    {
10307       I2CPutBit(w, byte & 0x80);
10308       byte <<= 1;
10309    }
10310 
10311    nack = I2CGetBit(w);
10312 
10313    return nack;
10314 }
10315 
10316 static uint8_t I2CGetByte(wfRx_t *w, int nack)
10317 {
10318    int bit, byte=0;
10319 
10320    for (bit=0; bit<8; bit++)
10321    {
10322       byte = (byte << 1) | I2CGetBit(w);
10323    }
10324 
10325    I2CPutBit(w, nack);
10326 
10327    return byte;
10328 }
10329 
10330 /*-------------------------------------------------------------------------*/
10331 
10332 int bbI2COpen(unsigned SDA, unsigned SCL, unsigned baud)
10333 {
10334    DBG(DBG_USER, "SDA=%d SCL=%d baud=%d", SDA, SCL, baud);
10335 
10336    CHECK_INITED;
10337 
10338    if (SDA > PI_MAX_USER_GPIO)
10339       SOFT_ERROR(PI_BAD_USER_GPIO, "bad SDA (%d)", SDA);
10340 
10341    if (SCL > PI_MAX_USER_GPIO)
10342       SOFT_ERROR(PI_BAD_USER_GPIO, "bad SCL (%d)", SCL);
10343 
10344    if ((baud < PI_BB_I2C_MIN_BAUD) || (baud > PI_BB_I2C_MAX_BAUD))
10345       SOFT_ERROR(PI_BAD_I2C_BAUD,
10346          "SDA %d, bad baud rate (%d)", SDA, baud);
10347 
10348    if (wfRx[SDA].mode != PI_WFRX_NONE)
10349       SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SDA);
10350 
10351    if ((wfRx[SCL].mode != PI_WFRX_NONE)  || (SCL == SDA))
10352       SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SCL);
10353 
10354    wfRx[SDA].gpio = SDA;
10355    wfRx[SDA].mode = PI_WFRX_I2C_SDA;
10356    wfRx[SDA].baud = baud;
10357 
10358    wfRx[SDA].I.started = 0;
10359    wfRx[SDA].I.SDA = SDA;
10360    wfRx[SDA].I.SCL = SCL;
10361    wfRx[SDA].I.delay = 500000 / baud;
10362    wfRx[SDA].I.SDAMode = gpioGetMode(SDA);
10363    wfRx[SDA].I.SCLMode = gpioGetMode(SCL);
10364 
10365    wfRx[SCL].gpio = SCL;
10366    wfRx[SCL].mode = PI_WFRX_I2C_SCL;
10367 
10368    myGpioSetMode(SDA, PI_INPUT);
10369    myGpioSetMode(SCL, PI_INPUT);
10370 
10371    return 0;
10372 }
10373 
10374 /* ----------------------------------------------------------------------- */
10375 
10376 int bbI2CClose(unsigned SDA)
10377 {
10378    DBG(DBG_USER, "SDA=%d", SDA);
10379 
10380    CHECK_INITED;
10381 
10382    if (SDA > PI_MAX_USER_GPIO)
10383       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA);
10384 
10385    switch(wfRx[SDA].mode)
10386    {
10387       case PI_WFRX_I2C_SDA:
10388 
10389          myGpioSetMode(wfRx[SDA].I.SDA, wfRx[SDA].I.SDAMode);
10390          myGpioSetMode(wfRx[SDA].I.SCL, wfRx[SDA].I.SCLMode);
10391 
10392          wfRx[wfRx[SDA].I.SDA].mode = PI_WFRX_NONE;
10393          wfRx[wfRx[SDA].I.SCL].mode = PI_WFRX_NONE;
10394 
10395          break;
10396 
10397       default:
10398 
10399          SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA);
10400 
10401          break;
10402 
10403    }
10404 
10405    return 0;
10406 }
10407 
10408 /*-------------------------------------------------------------------------*/
10409 
10410 int bbI2CZip(
10411    unsigned SDA,
10412    char *inBuf,
10413    unsigned inLen,
10414    char *outBuf,
10415    unsigned outLen)
10416 {
10417    int i, ack, inPos, outPos, status, bytes;
10418    int addr, flags, esc, setesc;
10419    wfRx_t *w;
10420 
10421    DBG(DBG_USER, "gpio=%d inBuf=%s outBuf=%08X len=%d",
10422       SDA, myBuf2Str(inLen, (char *)inBuf), (int)outBuf, outLen);
10423 
10424    CHECK_INITED;
10425 
10426    if (SDA > PI_MAX_USER_GPIO)
10427       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA);
10428 
10429    if (wfRx[SDA].mode != PI_WFRX_I2C_SDA)
10430       SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA);
10431 
10432    if (!inBuf || !inLen)
10433       SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
10434 
10435    if (!outBuf && outLen)
10436       SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
10437 
10438    w = &wfRx[SDA];
10439 
10440    inPos = 0;
10441    outPos = 0;
10442    status = 0;
10443 
10444    addr = 0;
10445    flags = 0;
10446    esc = 0;
10447    setesc = 0;
10448 
10449    wfRx_lock(SDA);
10450 
10451    while (!status && (inPos < inLen))
10452    {
10453       DBG(DBG_INTERNAL, "status=%d inpos=%d inlen=%d cmd=%d addr=%d flags=%x",
10454          status, inPos, inLen, inBuf[inPos], addr, flags);
10455 
10456       switch (inBuf[inPos++])
10457       {
10458          case PI_I2C_END:
10459             status = 1;
10460             break;
10461 
10462          case PI_I2C_START:
10463             I2CStart(w);
10464             break;
10465 
10466          case PI_I2C_STOP:
10467             I2CStop(w);
10468             break;
10469 
10470          case PI_I2C_ADDR:
10471             addr = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10472             if (addr < 0) status = PI_BAD_I2C_CMD;
10473             break;
10474 
10475          case PI_I2C_FLAGS:
10476             /* cheat to force two byte flags */
10477             esc = 1;
10478             flags = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10479             if (flags < 0) status = PI_BAD_I2C_CMD;
10480             break;
10481 
10482          case PI_I2C_ESC:
10483             setesc = 1;
10484             break;
10485 
10486          case PI_I2C_READ:
10487 
10488             bytes = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10489 
10490             if (bytes >= 0) ack = I2CPutByte(w, (addr<<1)|1);
10491 
10492             if (bytes > 0)
10493             {
10494                if (!ack)
10495                {
10496                   if ((bytes + outPos) <= outLen)
10497                   {
10498                      for (i=0; i<(bytes-1); i++)
10499                      {
10500                         outBuf[outPos++] = I2CGetByte(w, 0);
10501                      }
10502                      outBuf[outPos++] = I2CGetByte(w, 1);
10503                   }
10504                   else status = PI_BAD_I2C_RLEN;
10505                }
10506                else status = PI_I2C_READ_FAILED;
10507             }
10508             else status = PI_BAD_I2C_CMD;
10509             break;
10510 
10511          case PI_I2C_WRITE:
10512 
10513             bytes = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10514 
10515             if (bytes >= 0) ack = I2CPutByte(w, addr<<1);
10516 
10517             if (bytes > 0)
10518             {
10519                if (!ack)
10520                {
10521                   if ((bytes + inPos) <= inLen)
10522                   {
10523                      for (i=0; i<(bytes-1); i++)
10524                      {
10525                         ack = I2CPutByte(w, inBuf[inPos++]);
10526                         if (ack) status = PI_I2C_WRITE_FAILED;
10527                      }
10528                      ack = I2CPutByte(w, inBuf[inPos++]);
10529                   }
10530                   else status = PI_BAD_I2C_WLEN;
10531                } else status = PI_I2C_WRITE_FAILED;
10532             }
10533             else status = PI_BAD_I2C_CMD;
10534             break;
10535 
10536          default:
10537             status = PI_BAD_I2C_CMD;
10538       }
10539 
10540       if (setesc) esc = 1; else esc = 0;
10541 
10542       setesc = 0;
10543    }
10544 
10545    wfRx_unlock(SDA);
10546 
10547    if (status >= 0) status = outPos;
10548 
10549    return status;
10550 }
10551 
10552 /* ----------------------------------------------------------------------- */
10553 
10554 void bscInit(int mode)
10555 {
10556    bscsReg[BSC_CR]=0; /* clear device */
10557    bscsReg[BSC_RSR]=0; /* clear underrun and overrun errors */
10558    bscsReg[BSC_SLV]=0; /* clear I2C slave address */
10559    bscsReg[BSC_IMSC]=0xf; /* mask off all interrupts */
10560    bscsReg[BSC_ICR]=0x0f; /* clear all interrupts */
10561 
10562    gpioSetMode(BSC_SDA_MOSI, PI_ALT3);
10563    gpioSetMode(BSC_SCL_SCLK, PI_ALT3);
10564 
10565    if (mode > 1) /* SPI uses all GPIO */
10566    {
10567       gpioSetMode(BSC_MISO, PI_ALT3);
10568       gpioSetMode(BSC_CE_N, PI_ALT3);
10569    }
10570 }
10571 
10572 void bscTerm(int mode)
10573 {
10574    bscsReg[BSC_CR] = 0; /* clear device */
10575    bscsReg[BSC_RSR]=0; /* clear underrun and overrun errors */
10576    bscsReg[BSC_SLV]=0; /* clear I2C slave address */
10577 
10578    gpioSetMode(BSC_SDA_MOSI, PI_INPUT);
10579    gpioSetMode(BSC_SCL_SCLK, PI_INPUT);
10580 
10581    if (mode > 1)
10582    {
10583       gpioSetMode(BSC_MISO, PI_INPUT);
10584       gpioSetMode(BSC_CE_N, PI_INPUT);
10585    }
10586 }
10587 
10588 int bscXfer(bsc_xfer_t *xfer)
10589 {
10590    static int bscMode = 0;
10591 
10592    int copied=0;
10593    int active, mode;
10594 
10595    DBG(DBG_USER, "control=0x%X (sa=0x%X, cr=0x%X) tx=%d [%s]",
10596       xfer->control,
10597       ((xfer->control)>>16) & 127,
10598       (xfer->control) & 0x3fff,
10599       xfer->txCnt,
10600       myBuf2Str(xfer->txCnt, (char *)xfer->txBuf));
10601 
10602    CHECK_INITED;
10603 
10604    eventAlert[PI_EVENT_BSC].ignore = 1;
10605 
10606    if (xfer->control)
10607    {
10608       /*
10609          bscMode (0=None, 1=I2C, 2=SPI) tracks which GPIO have been
10610          set to BSC mode
10611       */
10612       if (xfer->control & 2) mode = 2; /* SPI */
10613       else                   mode = 1; /* assume I2C */
10614 
10615       if (mode > bscMode)
10616       {
10617          bscInit(bscMode);
10618          bscMode = mode;
10619       }
10620    }
10621    else
10622    {
10623       if (bscMode) bscTerm(bscMode);
10624       bscMode = 0;
10625       return 0; /* leave ignore set */
10626    }
10627 
10628    xfer->rxCnt = 0;
10629 
10630    bscsReg[BSC_SLV] = ((xfer->control)>>16) & 127;
10631    bscsReg[BSC_CR] = (xfer->control) & 0x3fff;
10632    bscsReg[BSC_RSR]=0; /* clear underrun and overrun errors */
10633 
10634    active = 1;
10635 
10636    while (active)
10637    {
10638       active = 0;
10639 
10640       while ((copied < xfer->txCnt) &&
10641              (!(bscsReg[BSC_FR] & BSC_FR_TXFF)))
10642       {
10643          bscsReg[BSC_DR] = xfer->txBuf[copied++];
10644          active = 1;
10645       }
10646 
10647       while ((xfer->rxCnt < BSC_FIFO_SIZE) &&
10648              (!(bscsReg[BSC_FR] & BSC_FR_RXFE)))
10649       {
10650          xfer->rxBuf[xfer->rxCnt++] = bscsReg[BSC_DR];
10651          active = 1;
10652       }
10653 
10654       if (!active)
10655       {
10656          active = bscsReg[BSC_FR] & (BSC_FR_RXBUSY | BSC_FR_TXBUSY);
10657       }
10658 
10659       if (active) myGpioSleep(0, 20);
10660    }
10661 
10662    bscFR = bscsReg[BSC_FR] & 0xffff;
10663 
10664    eventAlert[PI_EVENT_BSC].ignore = 0;
10665 
10666    return (copied<<16) | bscFR;
10667 }
10668 
10669 /* ----------------------------------------------------------------------- */
10670 
10671 static void set_CS(wfRx_t *w)
10672 {
10673    myGpioWrite(w->S.CS, PI_SPI_FLAGS_GET_CSPOL(w->S.spiFlags));
10674 }
10675 
10676 static void clear_CS(wfRx_t *w)
10677 {
10678    myGpioWrite(w->S.CS, !PI_SPI_FLAGS_GET_CSPOL(w->S.spiFlags));
10679 }
10680 
10681 static void set_SCLK(wfRx_t *w)
10682 {
10683    myGpioWrite(w->S.SCLK, !PI_SPI_FLAGS_GET_CPOL(w->S.spiFlags));
10684 }
10685 
10686 static void clear_SCLK(wfRx_t *w)
10687 {
10688    myGpioWrite(w->S.SCLK, PI_SPI_FLAGS_GET_CPOL(w->S.spiFlags));
10689 }
10690 
10691 static void SPI_delay(wfRx_t *w)
10692 {
10693    myGpioDelay(w->S.delay);
10694 }
10695 
10696 static void bbSPIStart(wfRx_t *w)
10697 {
10698    clear_SCLK(w);
10699 
10700    SPI_delay(w);
10701 
10702    set_CS(w);
10703 
10704    SPI_delay(w);
10705 }
10706 
10707 static void bbSPIStop(wfRx_t *w)
10708 {
10709    SPI_delay(w);
10710 
10711    clear_CS(w);
10712 
10713    SPI_delay(w);
10714 
10715    clear_SCLK(w);
10716 }
10717 
10718 static uint8_t bbSPIXferByte(wfRx_t *w, char txByte)
10719 {
10720    uint8_t bit, rxByte=0;
10721 
10722    if (PI_SPI_FLAGS_GET_CPHA(w->S.spiFlags))
10723    {
10724       /*
10725       CPHA = 1
10726       write on set clock
10727       read on clear clock
10728       */
10729 
10730       for (bit=0; bit<8; bit++)
10731       {
10732          set_SCLK(w);
10733 
10734          if (PI_SPI_FLAGS_GET_TX_LSB(w->S.spiFlags))
10735          {
10736             myGpioWrite(w->S.MOSI, txByte & 0x01);
10737             txByte >>= 1;
10738          }
10739          else
10740          {
10741             myGpioWrite(w->S.MOSI, txByte & 0x80);
10742             txByte <<= 1;
10743          }
10744 
10745          SPI_delay(w);
10746 
10747          clear_SCLK(w);
10748 
10749          if (PI_SPI_FLAGS_GET_RX_LSB(w->S.spiFlags))
10750          {
10751             rxByte = (rxByte >> 1) | myGpioRead(w->S.MISO) << 7;
10752          }
10753          else
10754          {
10755             rxByte = (rxByte << 1) | myGpioRead(w->S.MISO);
10756          }
10757 
10758          SPI_delay(w);
10759       }
10760    }
10761    else
10762    {
10763       /*
10764       CPHA = 0
10765       read on set clock
10766       write on clear clock
10767       */
10768 
10769       for (bit=0; bit<8; bit++)
10770       {
10771          if (PI_SPI_FLAGS_GET_TX_LSB(w->S.spiFlags))
10772          {
10773             myGpioWrite(w->S.MOSI, txByte & 0x01);
10774             txByte >>= 1;
10775          }
10776          else
10777          {
10778             myGpioWrite(w->S.MOSI, txByte & 0x80);
10779             txByte <<= 1;
10780          }
10781 
10782          SPI_delay(w);
10783 
10784          set_SCLK(w);
10785 
10786          if (PI_SPI_FLAGS_GET_RX_LSB(w->S.spiFlags))
10787          {
10788             rxByte = (rxByte >> 1) | myGpioRead(w->S.MISO) << 7;
10789          }
10790          else
10791          {
10792             rxByte = (rxByte << 1) | myGpioRead(w->S.MISO);
10793          }
10794 
10795          SPI_delay(w);
10796 
10797          clear_SCLK(w);
10798       }
10799    }
10800 
10801    return rxByte;
10802 }
10803 
10804 /*-------------------------------------------------------------------------*/
10805 
10806 int bbSPIOpen(
10807    unsigned CS, unsigned MISO, unsigned MOSI, unsigned SCLK,
10808    unsigned baud, unsigned spiFlags)
10809 {
10810    int valid;
10811    uint32_t bits;
10812 
10813    DBG(DBG_USER, "CS=%d MISO=%d MOSI=%d SCLK=%d baud=%d flags=%d",
10814       CS, MISO, MOSI, SCLK, baud, spiFlags);
10815 
10816    CHECK_INITED;
10817 
10818    if (CS > PI_MAX_USER_GPIO)
10819       SOFT_ERROR(PI_BAD_USER_GPIO, "bad CS (%d)", CS);
10820 
10821    if (MISO > PI_MAX_USER_GPIO)
10822       SOFT_ERROR(PI_BAD_USER_GPIO, "bad MISO (%d)", MISO);
10823 
10824    if (MOSI > PI_MAX_USER_GPIO)
10825       SOFT_ERROR(PI_BAD_USER_GPIO, "bad MOSI (%d)", MOSI);
10826 
10827    if (SCLK > PI_MAX_USER_GPIO)
10828       SOFT_ERROR(PI_BAD_USER_GPIO, "bad SCLK (%d)", SCLK);
10829 
10830    if ((baud < PI_BB_SPI_MIN_BAUD) || (baud > PI_BB_SPI_MAX_BAUD))
10831       SOFT_ERROR(PI_BAD_SPI_BAUD, "CS %d, bad baud (%d)", CS, baud);
10832 
10833    if (wfRx[CS].mode != PI_WFRX_NONE)
10834       SOFT_ERROR(PI_GPIO_IN_USE,
10835          "CS %d is already being used, mode %d", CS, wfRx[CS].mode);
10836 
10837    valid = 0;
10838 
10839    /* check all GPIO unique */
10840 
10841    bits = (1<<CS) | (1<<MISO) | (1<<MOSI) | (1<<SCLK);
10842 
10843    if (__builtin_popcount(bits) == 4)
10844    {
10845       if ((wfRx[MISO].mode == PI_WFRX_NONE) &&
10846           (wfRx[MOSI].mode == PI_WFRX_NONE) &&
10847           (wfRx[SCLK].mode == PI_WFRX_NONE))
10848       {
10849          valid = 1; /* first time GPIO used for SPI */
10850       }
10851       else
10852       {
10853          if ((wfRx[MISO].mode == PI_WFRX_SPI_MISO) &&
10854              (wfRx[MOSI].mode == PI_WFRX_SPI_MOSI) &&
10855              (wfRx[SCLK].mode == PI_WFRX_SPI_SCLK))
10856          {
10857             valid = 2; /* new CS for existing SPI GPIO */
10858          }
10859       }
10860    }
10861 
10862    if (!valid)
10863    {
10864       SOFT_ERROR(PI_GPIO_IN_USE,
10865          "GPIO already being used (%d=%d %d=%d, %d=%d %d=%d)",
10866           CS,   wfRx[CS].mode,
10867           MISO, wfRx[MISO].mode,
10868           MOSI, wfRx[MOSI].mode,
10869           SCLK, wfRx[SCLK].mode);
10870    }
10871 
10872    wfRx[CS].mode = PI_WFRX_SPI_CS;
10873    wfRx[CS].baud = baud;
10874 
10875    wfRx[CS].S.CS = CS;
10876    wfRx[CS].S.SCLK = SCLK;
10877 
10878    wfRx[CS].S.CSMode = gpioGetMode(CS);
10879    wfRx[CS].S.delay = (500000 / baud) - 1;
10880    wfRx[CS].S.spiFlags = spiFlags;
10881 
10882    /* preset CS to off */
10883 
10884    if (PI_SPI_FLAGS_GET_CSPOL(spiFlags))
10885       gpioWrite(CS, 0); /* active high */
10886    else
10887       gpioWrite(CS, 1); /* active low */
10888 
10889    /* The SCLK entry is used to store full information */
10890 
10891    if (valid == 1) /* first time GPIO for SPI */
10892    {
10893       wfRx[SCLK].S.usage = 1;
10894 
10895       wfRx[SCLK].S.SCLKMode = gpioGetMode(SCLK);
10896       wfRx[SCLK].S.MISOMode = gpioGetMode(MISO);
10897       wfRx[SCLK].S.MOSIMode = gpioGetMode(MOSI);
10898 
10899       wfRx[SCLK].mode = PI_WFRX_SPI_SCLK;
10900       wfRx[MISO].mode = PI_WFRX_SPI_MISO;
10901       wfRx[MOSI].mode = PI_WFRX_SPI_MOSI;
10902 
10903       wfRx[SCLK].S.SCLK = SCLK;
10904       wfRx[SCLK].S.MISO = MISO;
10905       wfRx[SCLK].S.MOSI = MOSI;
10906 
10907       myGpioSetMode(MISO, PI_INPUT);
10908       myGpioSetMode(SCLK, PI_OUTPUT);
10909       gpioWrite(MOSI, 0); /* low output */
10910    }
10911    else
10912    {
10913       wfRx[SCLK].S.usage++;
10914    }
10915 
10916    return 0;
10917 }
10918 
10919 /*-------------------------------------------------------------------------*/
10920 
10921 int bbSPIClose(unsigned CS)
10922 {
10923    int SCLK;
10924 
10925    DBG(DBG_USER, "CS=%d", CS);
10926 
10927    CHECK_INITED;
10928 
10929    if (CS > PI_MAX_USER_GPIO)
10930       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", CS);
10931 
10932    switch(wfRx[CS].mode)
10933    {
10934       case PI_WFRX_SPI_CS:
10935 
10936          myGpioSetMode(wfRx[CS].S.CS, wfRx[CS].S.CSMode);
10937          wfRx[CS].mode = PI_WFRX_NONE;
10938 
10939          SCLK = wfRx[CS].S.SCLK;
10940 
10941          if (--wfRx[SCLK].S.usage <= 0)
10942          {
10943             myGpioSetMode(wfRx[SCLK].S.MISO, wfRx[SCLK].S.MISOMode);
10944             myGpioSetMode(wfRx[SCLK].S.MOSI, wfRx[SCLK].S.MOSIMode);
10945             myGpioSetMode(wfRx[SCLK].S.SCLK, wfRx[SCLK].S.SCLKMode);
10946 
10947             wfRx[wfRx[SCLK].S.MISO].mode = PI_WFRX_NONE;
10948             wfRx[wfRx[SCLK].S.MOSI].mode = PI_WFRX_NONE;
10949             wfRx[wfRx[SCLK].S.SCLK].mode = PI_WFRX_NONE;
10950          }
10951 
10952          break;
10953 
10954       default:
10955 
10956          SOFT_ERROR(PI_NOT_SPI_GPIO, "no SPI on gpio (%d)", CS);
10957 
10958          break;
10959 
10960    }
10961 
10962    return 0;
10963 }
10964 
10965 /*-------------------------------------------------------------------------*/
10966 
10967 int bbSPIXfer(
10968    unsigned CS,
10969    char *inBuf,
10970    char *outBuf,
10971    unsigned count)
10972 {
10973    int SCLK;
10974    int pos;
10975    wfRx_t *w;
10976 
10977    DBG(DBG_USER, "CS=%d inBuf=%s outBuf=%08X count=%d",
10978       CS, myBuf2Str(count, (char *)inBuf), (int)outBuf, count);
10979 
10980    CHECK_INITED;
10981 
10982    if (CS > PI_MAX_USER_GPIO)
10983       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", CS);
10984 
10985    if (wfRx[CS].mode != PI_WFRX_SPI_CS)
10986       SOFT_ERROR(PI_NOT_SPI_GPIO, "no SPI on gpio (%d)", CS);
10987 
10988    if (!inBuf || !count)
10989       SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
10990 
10991    if (!outBuf && count)
10992       SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
10993 
10994    SCLK = wfRx[CS].S.SCLK;
10995 
10996    wfRx[SCLK].S.CS = CS;
10997    wfRx[SCLK].baud = wfRx[CS].baud;
10998    wfRx[SCLK].S.delay = wfRx[CS].S.delay;
10999    wfRx[SCLK].S.spiFlags = wfRx[CS].S.spiFlags;
11000 
11001    w = &wfRx[SCLK];
11002 
11003    wfRx_lock(SCLK);
11004 
11005    bbSPIStart(w);
11006      
11007    for (pos=0; pos < count; pos++)
11008    {
11009       outBuf[pos] = bbSPIXferByte(w, inBuf[pos]);
11010    }
11011 
11012    bbSPIStop(w);
11013 
11014    wfRx_unlock(SCLK);
11015 
11016    return count;
11017 }
11018 
11019 /*-------------------------------------------------------------------------*/
11020 
11021 int gpioSerialReadOpen(unsigned gpio, unsigned baud, unsigned data_bits)
11022 {
11023    int bitTime, timeout;
11024 
11025    DBG(DBG_USER, "gpio=%d baud=%d data_bits=%d", gpio, baud, data_bits);
11026 
11027    CHECK_INITED;
11028 
11029    if (gpio > PI_MAX_USER_GPIO)
11030       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11031 
11032    if ((baud < PI_BB_SER_MIN_BAUD) || (baud > PI_BB_SER_MAX_BAUD))
11033       SOFT_ERROR(PI_BAD_WAVE_BAUD,
11034          "gpio %d, bad baud rate (%d)", gpio, baud);
11035 
11036    if ((data_bits < PI_MIN_WAVE_DATABITS) ||
11037        (data_bits > PI_MAX_WAVE_DATABITS))
11038       SOFT_ERROR(PI_BAD_DATABITS,
11039          "gpio %d, bad data bits (%d)", gpio, data_bits);
11040 
11041    if (wfRx[gpio].mode != PI_WFRX_NONE)
11042       SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", gpio);
11043 
11044    bitTime = (1000 * MILLION) / baud; /* nanos */
11045 
11046    timeout  = ((data_bits+2) * bitTime)/MILLION; /* millis */
11047 
11048    if (timeout < 1) timeout = 1;
11049 
11050    wfRx[gpio].gpio = gpio;
11051    wfRx[gpio].mode = PI_WFRX_SERIAL;
11052    wfRx[gpio].baud = baud;
11053 
11054    wfRx[gpio].s.buf      = malloc(SRX_BUF_SIZE);
11055    wfRx[gpio].s.bufSize  = SRX_BUF_SIZE;
11056    wfRx[gpio].s.timeout  = timeout;
11057    wfRx[gpio].s.fullBit  = bitTime;         /* nanos */
11058    wfRx[gpio].s.halfBit  = (bitTime/2)+500; /* nanos (500 for rounding) */
11059    wfRx[gpio].s.readPos  = 0;
11060    wfRx[gpio].s.writePos = 0;
11061    wfRx[gpio].s.bit      = -1;
11062    wfRx[gpio].s.dataBits = data_bits;
11063    wfRx[gpio].s.invert   = PI_BB_SER_NORMAL;
11064 
11065    if      (data_bits <  9) wfRx[gpio].s.bytes = 1;
11066    else if (data_bits < 17) wfRx[gpio].s.bytes = 2;
11067    else                  wfRx[gpio].s.bytes = 4;
11068 
11069    gpioSetAlertFunc(gpio, waveRxBit);
11070 
11071    return 0;
11072 }
11073 
11074 /*-------------------------------------------------------------------------*/
11075 
11076 int gpioSerialReadInvert(unsigned gpio, unsigned invert)
11077 {
11078    DBG(DBG_USER, "gpio=%d invert=%d", gpio, invert);
11079 
11080    CHECK_INITED;
11081 
11082    if (gpio > PI_MAX_USER_GPIO)
11083       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11084 
11085    if (wfRx[gpio].mode != PI_WFRX_SERIAL)
11086       SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
11087 
11088    if ((invert < PI_BB_SER_NORMAL) ||
11089        (invert > PI_BB_SER_INVERT))
11090       SOFT_ERROR(PI_BAD_SER_INVERT,
11091          "bad invert level for gpio %d (%d)", gpio, invert);
11092 
11093    wfRx[gpio].s.invert = invert;
11094 
11095    return 0;
11096 }
11097 
11098 /*-------------------------------------------------------------------------*/
11099 
11100 int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize)
11101 {
11102    unsigned bytes=0, wpos;
11103    volatile wfRx_t *w;
11104 
11105    DBG(DBG_USER, "gpio=%d buf=%08X bufSize=%d", gpio, (int)buf, bufSize);
11106 
11107    CHECK_INITED;
11108 
11109    if (gpio > PI_MAX_USER_GPIO)
11110       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11111 
11112    if (bufSize == 0)
11113       SOFT_ERROR(PI_BAD_SERIAL_COUNT, "buffer size can't be zero");
11114 
11115    if (wfRx[gpio].mode != PI_WFRX_SERIAL)
11116       SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
11117 
11118    w = &wfRx[gpio];
11119 
11120    if (w->s.readPos != w->s.writePos)
11121    {
11122       wpos = w->s.writePos;
11123 
11124       if (wpos > w->s.readPos) bytes = wpos - w->s.readPos;
11125       else                     bytes = w->s.bufSize - w->s.readPos;
11126 
11127       if (bytes > bufSize) bytes = bufSize;
11128 
11129       /* copy in multiples of the data size in bytes */
11130 
11131       bytes = (bytes / w->s.bytes) * w->s.bytes;
11132 
11133       if (buf) memcpy(buf, w->s.buf+w->s.readPos, bytes);
11134 
11135       w->s.readPos += bytes;
11136 
11137       if (w->s.readPos >= w->s.bufSize) w->s.readPos = 0;
11138    }
11139    return bytes;
11140 }
11141 
11142 
11143 /*-------------------------------------------------------------------------*/
11144 
11145 int gpioSerialReadClose(unsigned gpio)
11146 {
11147    DBG(DBG_USER, "gpio=%d", gpio);
11148 
11149    CHECK_INITED;
11150 
11151    if (gpio > PI_MAX_USER_GPIO)
11152       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11153 
11154    switch(wfRx[gpio].mode)
11155    {
11156       case PI_WFRX_NONE:
11157 
11158          SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
11159 
11160          break;
11161 
11162       case PI_WFRX_SERIAL:
11163 
11164          free(wfRx[gpio].s.buf);
11165 
11166          gpioSetWatchdog(gpio, 0); /* switch off timeouts */
11167 
11168          gpioSetAlertFunc(gpio, NULL); /* cancel alert */
11169 
11170          wfRx[gpio].mode = PI_WFRX_NONE;
11171 
11172          break;
11173    }
11174 
11175    return 0;
11176 }
11177 
11178 
11179 /* ----------------------------------------------------------------------- */
11180 
11181 static int intEventSetFunc(
11182    unsigned event,
11183    void *   f,
11184    int      user,
11185    void *   userdata)
11186 {
11187    DBG(DBG_INTERNAL, "event=%d function=%08X, user=%d, userdata=%08X",
11188       event, (uint32_t)f, user, (uint32_t)userdata);
11189 
11190    eventAlert[event].ex = user;
11191    eventAlert[event].userdata = userdata;
11192 
11193    eventAlert[event].func = f;
11194 
11195    return 0;
11196 }
11197 
11198 
11199 /* ----------------------------------------------------------------------- */
11200 
11201 int eventSetFunc(unsigned event, eventFunc_t f)
11202 {
11203    DBG(DBG_USER, "event=%d function=%08X", event, (uint32_t)f);
11204 
11205    CHECK_INITED;
11206 
11207    if (event > PI_MAX_EVENT)
11208       SOFT_ERROR(PI_BAD_EVENT_ID, "bad event (%d)", event);
11209 
11210    intEventSetFunc(event, f, 0, NULL);
11211 
11212    return 0;
11213 }
11214 
11215 
11216 /* ----------------------------------------------------------------------- */
11217 
11218 int eventSetFuncEx(unsigned event, eventFuncEx_t f, void *userdata)
11219 {
11220    DBG(DBG_USER, "event=%d function=%08X userdata=%08X",
11221       event, (uint32_t)f, (uint32_t)userdata);
11222 
11223    CHECK_INITED;
11224 
11225    if (event > PI_MAX_EVENT)
11226       SOFT_ERROR(PI_BAD_EVENT_ID, "bad event (%d)", event);
11227 
11228    intEventSetFunc(event, f, 1, userdata);
11229 
11230    return 0;
11231 }
11232 
11233 
11234 /* ----------------------------------------------------------------------- */
11235 
11236 int eventMonitor(unsigned handle, uint32_t bits)
11237 {
11238    DBG(DBG_USER, "handle=%d bits=%08X", handle, bits);
11239 
11240    CHECK_INITED;
11241 
11242    if (handle >= PI_NOTIFY_SLOTS)
11243       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11244 
11245    if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11246       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11247 
11248    gpioNotify[handle].eventBits  = bits;
11249 
11250    return 0;
11251 }
11252 
11253 
11254 /* ----------------------------------------------------------------------- */
11255 
11256 int eventTrigger(unsigned event)
11257 {
11258    DBG(DBG_USER, "event=%d", event);
11259 
11260    CHECK_INITED;
11261 
11262    if (event > PI_MAX_EVENT)
11263       SOFT_ERROR(PI_BAD_EVENT_ID, "bad event (%d)", event);
11264 
11265    eventAlert[event].fired = 1;
11266 
11267    return 0;
11268 }
11269 
11270 
11271 /* ----------------------------------------------------------------------- */
11272 
11273 static int intGpioSetAlertFunc(
11274    unsigned gpio,
11275    void *   f,
11276    int      user,
11277    void *   userdata)
11278 {
11279    DBG(DBG_INTERNAL, "gpio=%d function=%08X, user=%d, userdata=%08X",
11280       gpio, (uint32_t)f, user, (uint32_t)userdata);
11281 
11282    gpioAlert[gpio].ex = user;
11283    gpioAlert[gpio].userdata = userdata;
11284 
11285    gpioAlert[gpio].func = f;
11286 
11287    if (f)
11288    {
11289       alertBits |= BIT;
11290    }
11291    else
11292    {
11293       alertBits &= ~BIT;
11294    }
11295 
11296    monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11297 
11298    return 0;
11299 }
11300 
11301 /* ----------------------------------------------------------------------- */
11302 
11303 int gpioSetAlertFunc(unsigned gpio, gpioAlertFunc_t f)
11304 {
11305    DBG(DBG_USER, "gpio=%d function=%08X", gpio, (uint32_t)f);
11306 
11307    CHECK_INITED;
11308 
11309    if (gpio > PI_MAX_USER_GPIO)
11310       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11311 
11312    intGpioSetAlertFunc(gpio, f, 0, NULL);
11313 
11314    return 0;
11315 }
11316 
11317 
11318 /* ----------------------------------------------------------------------- */
11319 
11320 int gpioSetAlertFuncEx(unsigned gpio, gpioAlertFuncEx_t f, void *userdata)
11321 {
11322    DBG(DBG_USER, "gpio=%d function=%08X userdata=%08X",
11323       gpio, (uint32_t)f, (uint32_t)userdata);
11324 
11325    CHECK_INITED;
11326 
11327    if (gpio > PI_MAX_USER_GPIO)
11328       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11329 
11330    intGpioSetAlertFunc(gpio, f, 1, userdata);
11331 
11332    return 0;
11333 }
11334 
11335 static void *pthISRThread(void *x)
11336 {
11337    gpioISR_t *isr = x;
11338    int fd;
11339    int retval;
11340    uint32_t tick;
11341    int level;
11342    uint32_t levels;
11343    struct pollfd pfd;
11344    char buf[64];
11345 
11346    DBG(DBG_USER, "gpio=%d edge=%d timeout=%d f=%x u=%d data=%x",
11347       isr->gpio, isr->edge, isr->timeout, (uint32_t)isr->func,
11348       isr->ex, (uint32_t)isr->userdata);
11349 
11350    sprintf(buf, "/sys/class/gpio/gpio%d/value", isr->gpio);
11351 
11352    if ((fd = open(buf, O_RDONLY)) < 0)
11353    {
11354       DBG(DBG_ALWAYS, "gpio %d not exported", isr->gpio);
11355       return NULL;
11356    }
11357 
11358    pfd.fd = fd;
11359 
11360    pfd.events = POLLPRI;
11361 
11362    lseek(fd, 0, SEEK_SET);    /* consume any prior interrupt */
11363    if (read(fd, buf, sizeof buf) == -1) { /* ignore errors */ }
11364 
11365    while (1)
11366    {
11367       retval = poll(&pfd, 1, isr->timeout); /* wait for interrupt */
11368 
11369       tick = systReg[SYST_CLO];
11370 
11371       levels = *(gpioReg + GPLEV0);
11372 
11373       if (retval >= 0)
11374       {
11375          lseek(fd, 0, SEEK_SET);    /* consume interrupt */
11376          if (read(fd, buf, sizeof buf) == -1) { /* ignore errors */ }
11377 
11378          if (retval)
11379          {
11380             if (levels & (1<<isr->gpio)) level = PI_ON; else level = PI_OFF;
11381          }
11382          else level = PI_TIMEOUT;
11383 
11384          if (isr->ex) (isr->func)(isr->gpio, level, tick, isr->userdata);
11385          else         (isr->func)(isr->gpio, level, tick);
11386       }
11387    }
11388 
11389    return NULL;
11390 }
11391 
11392 
11393 /* ----------------------------------------------------------------------- */
11394 
11395 static int intGpioSetISRFunc(
11396    unsigned gpio,
11397    unsigned edge,
11398    int timeout,
11399    void *f,
11400    int user,
11401    void *userdata)
11402 {
11403    char buf[64];
11404 
11405    char *edge_str[]={"rising\n", "falling\n", "both\n"};
11406    int fd;
11407    int err;
11408 
11409    DBG(DBG_INTERNAL,
11410       "gpio=%d edge=%d timeout=%d function=%08X user=%d userdata=%08X",
11411       gpio, edge, timeout, (uint32_t)f, user, (uint32_t)userdata);
11412 
11413    if (f)
11414    {
11415       if (!gpioISR[gpio].inited) /* export gpio if unexported */
11416       {
11417          fd = open("/sys/class/gpio/export", O_WRONLY);
11418          if (fd < 0) return PI_BAD_ISR_INIT;
11419 
11420          /* ignore write fail if already exported */
11421          sprintf(buf, "%d\n", gpio);
11422          err = write(fd, buf, strlen(buf));
11423          close(fd);
11424 
11425          sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
11426          fd = open(buf, O_WRONLY);
11427          if (fd < 0) return PI_BAD_ISR_INIT;
11428 
11429          err = write(fd, "in\n", 3);
11430          close(fd);
11431          if (err != 3) return PI_BAD_ISR_INIT;
11432 
11433          gpioISR[gpio].gpio = gpio;
11434          gpioISR[gpio].edge = -1;
11435          gpioISR[gpio].timeout = -1;
11436 
11437          gpioISR[gpio].inited = 1;
11438       }
11439 
11440       if (gpioISR[gpio].edge != edge)
11441       {
11442          sprintf(buf, "/sys/class/gpio/gpio%d/edge", gpio);
11443          fd = open(buf, O_WRONLY);
11444          if (fd < 0) return PI_BAD_ISR_INIT;
11445 
11446          err = write(fd, edge_str[edge], strlen(edge_str[edge]));
11447          close(fd);
11448          if (err != strlen(edge_str[edge])) return PI_BAD_ISR_INIT;
11449 
11450          gpioISR[gpio].edge = edge;
11451 
11452          if (gpioISR[gpio].pth != NULL)
11453             pthread_kill(*gpioISR[gpio].pth, SIGCHLD);
11454       }
11455 
11456       if (timeout <= 0) timeout = -1;
11457       if (gpioISR[gpio].timeout != timeout)
11458       {
11459          gpioISR[gpio].timeout = timeout;
11460 
11461          if (gpioISR[gpio].pth != NULL)
11462             pthread_kill(*gpioISR[gpio].pth, SIGCHLD);
11463       }
11464 
11465       gpioISR[gpio].func = f;
11466       gpioISR[gpio].ex = user;
11467       gpioISR[gpio].userdata = userdata;
11468 
11469       if (gpioISR[gpio].pth == NULL)
11470          gpioISR[gpio].pth = gpioStartThread(pthISRThread, &gpioISR[gpio]);
11471    }
11472    else /* null function, delete ISR, unexport gpio */
11473    {
11474       if (gpioISR[gpio].pth) /* delete any existing ISR */
11475       {
11476          gpioStopThread(gpioISR[gpio].pth);
11477          gpioISR[gpio].func = NULL;
11478          gpioISR[gpio].pth = NULL;
11479       }
11480 
11481       if (gpioISR[gpio].inited) /* unexport the gpio */
11482       {
11483          fd = open("/sys/class/gpio/unexport", O_WRONLY);
11484          if (fd < 0) return PI_BAD_ISR_INIT;
11485          sprintf(buf, "%d\n", gpio);
11486          err = write(fd, buf, strlen(buf));
11487          close(fd);
11488          if (err != strlen(buf)) return PI_BAD_ISR_INIT;
11489          gpioISR[gpio].inited = 0;
11490       }
11491    }
11492 
11493    return 0;
11494 }
11495 
11496 /* ----------------------------------------------------------------------- */
11497 
11498 int gpioSetISRFunc(
11499    unsigned gpio,
11500    unsigned edge,
11501    int timeout,
11502    gpioISRFunc_t f)
11503 {
11504    DBG(DBG_USER, "gpio=%d edge=%d timeout=%d function=%08X",
11505       gpio, edge, timeout, (uint32_t)f);
11506 
11507    CHECK_INITED;
11508 
11509    if (gpio > PI_MAX_GPIO)
11510       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
11511 
11512    if (edge > EITHER_EDGE)
11513       SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
11514 
11515    return intGpioSetISRFunc(gpio, edge, timeout, f, 0, NULL);
11516 }
11517 
11518 
11519 /* ----------------------------------------------------------------------- */
11520 
11521 int gpioSetISRFuncEx(
11522    unsigned gpio,
11523    unsigned edge,
11524    int timeout,
11525    gpioAlertFuncEx_t f,
11526    void *userdata)
11527 {
11528    DBG(DBG_USER, "gpio=%d edge=%d timeout=%d function=%08X userdata=%08X",
11529       gpio, edge, timeout, (uint32_t)f, (uint32_t)userdata);
11530 
11531    CHECK_INITED;
11532 
11533    if (gpio > PI_MAX_GPIO)
11534       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
11535 
11536    if (edge > EITHER_EDGE)
11537       SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
11538 
11539    return intGpioSetISRFunc(gpio, edge, timeout, f, 1, userdata);
11540 }
11541 
11542 static void closeOrphanedNotifications(int slot, int fd)
11543 {
11544    int i;
11545 
11546    /* Check for and close any orphaned notifications. */
11547 
11548    for (i=0; i<PI_NOTIFY_SLOTS; i++)
11549    {
11550       if ((i != slot) &&
11551           (gpioNotify[i].state >= PI_NOTIFY_OPENED) &&
11552           (gpioNotify[i].fd == fd))
11553       {
11554          DBG(DBG_USER, "closed orphaned fd=%d (handle=%d)", fd, i);
11555          gpioNotify[i].state = PI_NOTIFY_CLOSED;
11556          intNotifyBits();
11557       }
11558    }
11559 }
11560 
11561 /* ----------------------------------------------------------------------- */
11562 
11563 static void notifyMutex(int lock)
11564 {
11565    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
11566    if (lock) pthread_mutex_lock(&mutex);
11567    else      pthread_mutex_unlock(&mutex);
11568 }
11569 
11570 /* ----------------------------------------------------------------------- */
11571 
11572 int gpioNotifyOpenWithSize(int bufSize)
11573 {
11574    int i, slot, fd;
11575    char name[32];
11576 
11577    DBG(DBG_USER, "bufSize=%d", bufSize);
11578 
11579    CHECK_INITED;
11580 
11581    slot = -1;
11582 
11583    notifyMutex(1);
11584 
11585    for (i=0; i<PI_NOTIFY_SLOTS; i++)
11586    {
11587       if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
11588       {
11589          slot = i;
11590          gpioNotify[slot].state = PI_NOTIFY_RESERVED;
11591          break;
11592       }
11593    }
11594 
11595    notifyMutex(0);
11596 
11597    if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
11598 
11599    sprintf(name, "/dev/pigpio%d", slot);
11600 
11601    myCreatePipe(name, 0664);
11602 
11603    fd = open(name, O_RDWR|O_NONBLOCK);
11604 
11605    if (fd < 0)
11606    {
11607       gpioNotify[slot].state = PI_NOTIFY_CLOSED;
11608       SOFT_ERROR(PI_BAD_PATHNAME, "open %s failed (%m)", name);
11609    }
11610 
11611    if (bufSize != 0)
11612    {
11613       i = fcntl(fd, F_SETPIPE_SZ, bufSize);
11614       if (i != bufSize)
11615       {
11616          gpioNotify[slot].state = PI_NOTIFY_CLOSED;
11617          SOFT_ERROR(PI_BAD_PATHNAME,
11618             "fcntl %s size %d failed (%m)", name, bufSize);
11619       }
11620    }
11621 
11622    gpioNotify[slot].seqno = 0;
11623    gpioNotify[slot].bits  = 0;
11624    gpioNotify[slot].fd    = fd;
11625    gpioNotify[slot].pipe  = 1;
11626    gpioNotify[slot].max_emits  = MAX_EMITS;
11627    gpioNotify[slot].lastReportTick = gpioTick();
11628    gpioNotify[i].state = PI_NOTIFY_OPENED;
11629 
11630    closeOrphanedNotifications(slot, fd);
11631 
11632    return slot;
11633 }
11634 
11635 int gpioNotifyOpen(void)
11636 {
11637    return gpioNotifyOpenWithSize(0);
11638 }
11639 
11640 /* ----------------------------------------------------------------------- */
11641 
11642 static int gpioNotifyOpenInBand(int fd)
11643 {
11644    int i, slot;
11645 
11646    DBG(DBG_USER, "fd=%d", fd);
11647 
11648    CHECK_INITED;
11649 
11650    slot = -1;
11651 
11652    notifyMutex(1);
11653 
11654    for (i=0; i<PI_NOTIFY_SLOTS; i++)
11655    {
11656       if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
11657       {
11658          slot = i;
11659          gpioNotify[slot].state = PI_NOTIFY_RESERVED;
11660          break;
11661       }
11662    }
11663 
11664    notifyMutex(0);
11665 
11666    if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
11667 
11668    gpioNotify[slot].seqno = 0;
11669    gpioNotify[slot].bits  = 0;
11670    gpioNotify[slot].fd    = fd;
11671    gpioNotify[slot].pipe  = 0;
11672    gpioNotify[slot].max_emits  = MAX_EMITS;
11673    gpioNotify[slot].lastReportTick = gpioTick();
11674    gpioNotify[slot].state = PI_NOTIFY_OPENED;
11675 
11676    closeOrphanedNotifications(slot, fd);
11677 
11678    return slot;
11679 }
11680 
11681 
11682 /* ----------------------------------------------------------------------- */
11683 
11684 static void intScriptBits(void)
11685 {
11686    int i;
11687    uint32_t bits;
11688 
11689    bits = 0;
11690 
11691    for (i=0; i<PI_MAX_SCRIPTS; i++)
11692    {
11693       if (gpioScript[i].state == PI_SCRIPT_IN_USE)
11694       {
11695          bits |= gpioScript[i].waitBits;
11696       }
11697    }
11698 
11699    scriptBits = bits;
11700 
11701    monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11702 }
11703 
11704 
11705 static void intScriptEventBits(void)
11706 {
11707    int i;
11708    uint32_t bits;
11709 
11710    bits = 0;
11711 
11712    for (i=0; i<PI_MAX_SCRIPTS; i++)
11713    {
11714       if (gpioScript[i].state == PI_SCRIPT_IN_USE)
11715       {
11716          bits |= gpioScript[i].eventBits;
11717       }
11718    }
11719 
11720    scriptEventBits = bits;
11721 }
11722 
11723 
11724 static void intNotifyBits(void)
11725 {
11726    int i;
11727    uint32_t bits;
11728 
11729    bits = 0;
11730 
11731    for (i=0; i<PI_NOTIFY_SLOTS; i++)
11732    {
11733       if (gpioNotify[i].state == PI_NOTIFY_RUNNING)
11734       {
11735          bits |= gpioNotify[i].bits;
11736       }
11737    }
11738 
11739    notifyBits = bits;
11740 
11741    monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11742 }
11743 
11744 
11745 /* ----------------------------------------------------------------------- */
11746 
11747 int gpioNotifyBegin(unsigned handle, uint32_t bits)
11748 {
11749    DBG(DBG_USER, "handle=%d bits=%08X", handle, bits);
11750 
11751    CHECK_INITED;
11752 
11753    if (handle >= PI_NOTIFY_SLOTS)
11754       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11755 
11756    if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11757       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11758 
11759    gpioNotify[handle].bits  = bits;
11760 
11761    gpioNotify[handle].state = PI_NOTIFY_RUNNING;
11762 
11763    intNotifyBits();
11764 
11765    return 0;
11766 }
11767 
11768 
11769 /* ----------------------------------------------------------------------- */
11770 
11771 int gpioNotifyPause (unsigned handle)
11772 {
11773    DBG(DBG_USER, "handle=%d", handle);
11774 
11775    CHECK_INITED;
11776 
11777    if (handle >= PI_NOTIFY_SLOTS)
11778       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11779 
11780    if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11781       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11782 
11783    gpioNotify[handle].bits  = 0;
11784 
11785    gpioNotify[handle].state = PI_NOTIFY_PAUSED;
11786 
11787    intNotifyBits();
11788 
11789    return 0;
11790 }
11791 
11792 
11793 /* ----------------------------------------------------------------------- */
11794 
11795 int gpioNotifyClose(unsigned handle)
11796 {
11797    DBG(DBG_USER, "handle=%d", handle);
11798 
11799    CHECK_INITED;
11800 
11801    if (handle >= PI_NOTIFY_SLOTS)
11802       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11803 
11804    if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11805       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11806 
11807    gpioNotify[handle].bits  = 0;
11808 
11809    gpioNotify[handle].state = PI_NOTIFY_CLOSING;
11810 
11811    intNotifyBits();
11812 
11813    /* actual close done in alert thread */
11814 
11815    return 0;
11816 }
11817 
11818 /* ----------------------------------------------------------------------- */
11819 
11820 int gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level)
11821 {
11822    DBG(DBG_USER, "gpio=%d pulseLen=%d level=%d", gpio, pulseLen, level);
11823 
11824    CHECK_INITED;
11825 
11826    if (gpio > PI_MAX_USER_GPIO)
11827       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11828 
11829    if (level > PI_ON)
11830       SOFT_ERROR(PI_BAD_LEVEL, "gpio %d, bad level (%d)", gpio, level);
11831 
11832    if ((pulseLen > PI_MAX_BUSY_DELAY) || (!pulseLen))
11833       SOFT_ERROR(PI_BAD_PULSELEN,
11834          "gpio %d, bad pulseLen (%d)", gpio, pulseLen);
11835 
11836    if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
11837    else                 *(gpioReg + GPSET0 + BANK) = BIT;
11838 
11839    myGpioDelay(pulseLen);
11840 
11841    if (level != PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
11842    else                 *(gpioReg + GPSET0 + BANK) = BIT;
11843 
11844    return 0;
11845 }
11846 
11847 
11848 /* ----------------------------------------------------------------------- */
11849 
11850 int gpioSetWatchdog(unsigned gpio, unsigned timeout)
11851 {
11852    DBG(DBG_USER, "gpio=%d timeout=%d", gpio, timeout);
11853 
11854    CHECK_INITED;
11855 
11856    if (gpio > PI_MAX_USER_GPIO)
11857       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11858 
11859    if (timeout > PI_MAX_WDOG_TIMEOUT)
11860       SOFT_ERROR(PI_BAD_WDOG_TIMEOUT,
11861          "gpio %d, bad timeout (%d)", gpio, timeout);
11862 
11863    gpioAlert[gpio].wdTick   = systReg[SYST_CLO];
11864    gpioAlert[gpio].wdSteadyUs = timeout*1000;
11865 
11866    if (timeout) wdogBits |= (1<<gpio);
11867    else         wdogBits &= (~(1<<gpio));
11868 
11869    return 0;
11870 }
11871 
11872 /* ----------------------------------------------------------------------- */
11873 
11874 int gpioNoiseFilter(unsigned gpio, unsigned steady, unsigned active)
11875 {
11876    DBG(DBG_USER, "gpio=%d steady=%d active=%d", gpio, steady, active);
11877 
11878    CHECK_INITED;
11879 
11880    if (gpio > PI_MAX_USER_GPIO)
11881       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11882 
11883    if (steady > PI_MAX_STEADY)
11884       SOFT_ERROR(PI_BAD_FILTER, "bad steady (%d)", steady);
11885 
11886    if (active > PI_MAX_ACTIVE)
11887       SOFT_ERROR(PI_BAD_FILTER, "bad active (%d)", active);
11888 
11889    gpioAlert[gpio].nfTick1  = systReg[SYST_CLO];
11890    gpioAlert[gpio].nfTick2  = gpioAlert[gpio].nfTick1;
11891    gpioAlert[gpio].nfSteadyUs = steady;
11892    gpioAlert[gpio].nfActiveUs = active;
11893    gpioAlert[gpio].nfActive   = 0;
11894 
11895    if (steady) nFilterBits |= (1<<gpio);
11896    else        nFilterBits &= (~(1<<gpio));
11897 
11898    return 0;
11899 }
11900 
11901 
11902 /* ----------------------------------------------------------------------- */
11903 
11904 int gpioGlitchFilter(unsigned gpio, unsigned steady)
11905 {
11906    DBG(DBG_USER, "gpio=%d steady=%d", gpio, steady);
11907 
11908    CHECK_INITED;
11909 
11910    if (gpio > PI_MAX_USER_GPIO)
11911       SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11912 
11913    if (steady > PI_MAX_STEADY)
11914       SOFT_ERROR(PI_BAD_FILTER, "bad steady (%d)", steady);
11915 
11916    if (steady)
11917    {
11918       gpioAlert[gpio].gfTick  = systReg[SYST_CLO];
11919 
11920       if (gpioRead_Bits_0_31() & (1<<gpio))
11921       {
11922          gpioAlert[gpio].gfLBitV = (1<<gpio);
11923          gpioAlert[gpio].gfRBitV = 0 ;
11924       }
11925       else
11926       {
11927          gpioAlert[gpio].gfLBitV = 0 ;
11928          gpioAlert[gpio].gfRBitV = (1<<gpio);
11929       }
11930    }
11931 
11932    gpioAlert[gpio].gfSteadyUs = steady;
11933 
11934    if (steady) gFilterBits |= (1<<gpio);
11935    else        gFilterBits &= (~(1<<gpio));
11936 
11937    return 0;
11938 }
11939 
11940 /* ----------------------------------------------------------------------- */
11941 
11942 int gpioSetGetSamplesFunc(gpioGetSamplesFunc_t f, uint32_t bits)
11943 {
11944    DBG(DBG_USER, "function=%08X bits=%08X", (uint32_t)f, bits);
11945 
11946    CHECK_INITED;
11947 
11948    gpioGetSamples.ex       = 0;
11949    gpioGetSamples.userdata = NULL;
11950    gpioGetSamples.func     = f;
11951 
11952    if (f) gpioGetSamples.bits = bits;
11953    else   gpioGetSamples.bits = 0;
11954 
11955    monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11956 
11957    return 0;
11958 }
11959 
11960 
11961 /* ----------------------------------------------------------------------- */
11962 
11963 int gpioSetGetSamplesFuncEx(gpioGetSamplesFuncEx_t f,
11964                             uint32_t bits,
11965                             void * userdata)
11966 {
11967    DBG(DBG_USER, "function=%08X bits=%08X", (uint32_t)f, bits);
11968 
11969    CHECK_INITED;
11970 
11971    gpioGetSamples.ex       = 1;
11972    gpioGetSamples.userdata = userdata;
11973    gpioGetSamples.func     = f;
11974 
11975    if (f) gpioGetSamples.bits = bits;
11976    else   gpioGetSamples.bits = 0;
11977 
11978    monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11979 
11980    return 0;
11981 }
11982 
11983 
11984 /* ----------------------------------------------------------------------- */
11985 
11986 static int intGpioSetTimerFunc(unsigned id,
11987                                unsigned millis,
11988                                void *f,
11989                                int user,
11990                                void *userdata)
11991 {
11992    pthread_attr_t pthAttr;
11993 
11994    DBG(DBG_INTERNAL, "id=%d millis=%d function=%08X user=%d userdata=%08X",
11995       id, millis, (uint32_t)f, user, (uint32_t)userdata);
11996 
11997    gpioTimer[id].id   = id;
11998 
11999    if (f)
12000    {
12001       gpioTimer[id].func     = f;
12002       gpioTimer[id].ex       = user;
12003       gpioTimer[id].userdata = userdata;
12004       gpioTimer[id].millis   = millis;
12005 
12006       if (!gpioTimer[id].running)
12007       {
12008          if (pthread_attr_init(&pthAttr))
12009             SOFT_ERROR(PI_TIMER_FAILED,
12010                "pthread_attr_init failed (%m)");
12011 
12012          if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE))
12013             SOFT_ERROR(PI_TIMER_FAILED,
12014                "pthread_attr_setstacksize failed (%m)");
12015 
12016          if (pthread_create(
12017             &gpioTimer[id].pthId, &pthAttr, pthTimerTick, &gpioTimer[id]))
12018                SOFT_ERROR(PI_TIMER_FAILED,
12019                   "timer %d, create failed (%m)", id);
12020 
12021          gpioTimer[id].running = 1;
12022       }
12023    }
12024    else
12025    {
12026       if (gpioTimer[id].running)
12027       {
12028 
12029          /* destroy thread */
12030 
12031          if (pthread_self() == gpioTimer[id].pthId)
12032          {
12033             gpioTimer[id].running = 0;
12034             gpioTimer[id].func    = 0;
12035             pthread_exit(NULL);
12036          }
12037          else
12038          {
12039             if (pthread_cancel(gpioTimer[id].pthId))
12040                SOFT_ERROR(PI_TIMER_FAILED, "timer %d, cancel failed (%m)", id);
12041 
12042             if (pthread_join(gpioTimer[id].pthId, NULL))
12043                SOFT_ERROR(PI_TIMER_FAILED, "timer %d, join failed (%m)", id);
12044 
12045             gpioTimer[id].running = 0;
12046             gpioTimer[id].func    = 0;
12047          }
12048       }
12049    }
12050 
12051    return 0;
12052 }
12053 
12054 
12055 /* ----------------------------------------------------------------------- */
12056 
12057 int gpioSetTimerFunc(unsigned id, unsigned millis, gpioTimerFunc_t f)
12058 {
12059    DBG(DBG_USER, "id=%d millis=%d function=%08X", id, millis, (uint32_t)f);
12060 
12061    CHECK_INITED;
12062 
12063    if (id > PI_MAX_TIMER)
12064       SOFT_ERROR(PI_BAD_TIMER, "bad timer id (%d)", id);
12065 
12066    if ((millis < PI_MIN_MS) || (millis > PI_MAX_MS))
12067       SOFT_ERROR(PI_BAD_MS, "timer %d, bad millis (%d)", id, millis);
12068 
12069    intGpioSetTimerFunc(id, millis, f, 0, NULL);
12070 
12071    return 0;
12072 }
12073 
12074 
12075 /* ----------------------------------------------------------------------- */
12076 
12077 int gpioSetTimerFuncEx(unsigned id, unsigned millis, gpioTimerFuncEx_t f,
12078                        void * userdata)
12079 {
12080    DBG(DBG_USER, "id=%d millis=%d function=%08X, userdata=%08X",
12081       id, millis, (uint32_t)f, (uint32_t)userdata);
12082 
12083    CHECK_INITED;
12084 
12085    if (id > PI_MAX_TIMER)
12086       SOFT_ERROR(PI_BAD_TIMER, "bad timer id (%d)", id);
12087 
12088    if ((millis < PI_MIN_MS) || (millis > PI_MAX_MS))
12089       SOFT_ERROR(PI_BAD_MS, "timer %d, bad millis (%d)", id, millis);
12090 
12091    intGpioSetTimerFunc(id, millis, f, 1, userdata);
12092 
12093    return 0;
12094 }
12095 
12096 /* ----------------------------------------------------------------------- */
12097 
12098 pthread_t *gpioStartThread(gpioThreadFunc_t f, void *userdata)
12099 {
12100    pthread_t *pth;
12101    pthread_attr_t pthAttr;
12102 
12103    DBG(DBG_USER, "f=%08X, userdata=%08X", (uint32_t)f, (uint32_t)userdata);
12104 
12105    CHECK_INITED_RET_NULL_PTR;
12106 
12107    pth = malloc(sizeof(pthread_t));
12108 
12109    if (pth)
12110    {
12111       if (pthread_attr_init(&pthAttr))
12112       {
12113          free(pth);
12114          SOFT_ERROR(NULL, "pthread_attr_init failed");
12115       }
12116 
12117       if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE))
12118       {
12119          free(pth);
12120          SOFT_ERROR(NULL, "pthread_attr_setstacksize failed");
12121       }
12122 
12123       if (pthread_create(pth, &pthAttr, f, userdata))
12124       {
12125          free(pth);
12126          SOFT_ERROR(NULL, "pthread_create failed");
12127       }
12128    }
12129    return pth;
12130 }
12131 
12132 /* ----------------------------------------------------------------------- */
12133 
12134 void gpioStopThread(pthread_t *pth)
12135 {
12136    DBG(DBG_USER, "pth=%08X", (uint32_t)pth);
12137 
12138    CHECK_INITED_RET_NIL;
12139 
12140    if (pth)
12141    {
12142       if (pthread_self() == *pth)
12143       {
12144          free(pth);
12145          pthread_exit(NULL);
12146       }
12147       else
12148       {
12149          pthread_cancel(*pth);
12150          pthread_join(*pth, NULL);
12151          free(pth);
12152       }
12153    }
12154 }
12155 
12156 /* ----------------------------------------------------------------------- */
12157 
12158 int gpioStoreScript(char *script)
12159 {
12160    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
12161    gpioScript_t *s;
12162    int status, slot, i;
12163 
12164    DBG(DBG_USER, "script=[%s]", script);
12165 
12166    CHECK_INITED;
12167 
12168    slot = -1;
12169 
12170    pthread_mutex_lock(&mutex);
12171 
12172    for (i=0; i<PI_MAX_SCRIPTS; i++)
12173    {
12174       if (gpioScript[i].state == PI_SCRIPT_FREE)
12175       {
12176          slot = i;
12177          gpioScript[slot].state = PI_SCRIPT_RESERVED;
12178          break;
12179       }
12180    }
12181 
12182    pthread_mutex_unlock(&mutex);
12183 
12184    if (slot < 0) SOFT_ERROR(PI_NO_SCRIPT_ROOM, "no room for scripts");
12185 
12186    s = &gpioScript[slot];
12187 
12188    status = cmdParseScript(script, &s->script, 0);
12189 
12190    if (status == 0)
12191    {
12192       s->request   = PI_SCRIPT_HALT;
12193       s->run_state = PI_SCRIPT_INITING;
12194 
12195       pthread_cond_init(&s->pthCond, NULL);
12196       pthread_mutex_init(&s->pthMutex, NULL);
12197 
12198       s->id = slot;
12199 
12200       gpioScript[slot].state = PI_SCRIPT_IN_USE;
12201 
12202       s->pthIdp = gpioStartThread(pthScript, s);
12203 
12204       status = slot;
12205    }
12206    else
12207    {
12208       if (s->script.par) free(s->script.par);
12209       s->script.par = NULL;
12210       gpioScript[slot].state = PI_SCRIPT_FREE;
12211    }
12212 
12213    return status;
12214 }
12215 
12216 
12217 /* ----------------------------------------------------------------------- */
12218 
12219 int gpioRunScript(unsigned script_id, unsigned numParam, uint32_t *param)
12220 {
12221    int status = 0;
12222 
12223    DBG(DBG_USER, "script_id=%d numParam=%d param=%08X",
12224       script_id, numParam, (uint32_t)param);
12225 
12226    CHECK_INITED;
12227 
12228    if (script_id >= PI_MAX_SCRIPTS)
12229       SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12230 
12231    if (numParam > PI_MAX_SCRIPT_PARAMS)
12232       SOFT_ERROR(PI_TOO_MANY_PARAM, "bad number of parameters(%d)", numParam);
12233 
12234    if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12235    {
12236       pthread_mutex_lock(&gpioScript[script_id].pthMutex);
12237 
12238       if (gpioScript[script_id].run_state != PI_SCRIPT_INITING)
12239       {
12240          if ((numParam > 0) && (param != 0))
12241          {
12242             memcpy(gpioScript[script_id].script.par, param,
12243                sizeof(uint32_t) * numParam);
12244          }
12245 
12246          gpioScript[script_id].request = PI_SCRIPT_RUN;
12247 
12248          pthread_cond_signal(&gpioScript[script_id].pthCond);
12249       }
12250       else
12251       {
12252          status = PI_SCRIPT_NOT_READY;
12253       }
12254 
12255       pthread_mutex_unlock(&gpioScript[script_id].pthMutex);
12256 
12257       return status;
12258    }
12259    else
12260    {
12261       return PI_BAD_SCRIPT_ID;
12262    }
12263 }
12264 
12265 
12266 /* ----------------------------------------------------------------------- */
12267 
12268 int gpioUpdateScript(unsigned script_id, unsigned numParam, uint32_t *param)
12269 {
12270    DBG(DBG_USER, "script_id=%d numParam=%d param=%08X",
12271       script_id, numParam, (uint32_t)param);
12272 
12273    CHECK_INITED;
12274 
12275    if (script_id >= PI_MAX_SCRIPTS)
12276       SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12277 
12278    if (numParam > PI_MAX_SCRIPT_PARAMS)
12279       SOFT_ERROR(PI_TOO_MANY_PARAM, "bad number of parameters(%d)", numParam);
12280 
12281    if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12282    {
12283       if ((numParam > 0) && (param != 0))
12284       {
12285          memcpy(gpioScript[script_id].script.par, param,
12286             sizeof(uint32_t) * numParam);
12287       }
12288    }
12289    else
12290    {
12291       return PI_BAD_SCRIPT_ID;
12292    }
12293 
12294    return 0;
12295 }
12296 
12297 
12298 /* ----------------------------------------------------------------------- */
12299 
12300 int gpioScriptStatus(unsigned script_id, uint32_t *param)
12301 {
12302    DBG(DBG_USER, "script_id=%d param=%08X", script_id, (uint32_t)param);
12303 
12304    CHECK_INITED;
12305 
12306    if (script_id >= PI_MAX_SCRIPTS)
12307       SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12308 
12309    if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12310    {
12311       if (param != NULL)
12312       {
12313          memcpy(param, gpioScript[script_id].script.par,
12314             sizeof(uint32_t) * PI_MAX_SCRIPT_PARAMS);
12315       }
12316 
12317       return gpioScript[script_id].run_state;
12318    }
12319    else return PI_BAD_SCRIPT_ID;
12320 }
12321 
12322 
12323 /* ----------------------------------------------------------------------- */
12324 
12325 int gpioStopScript(unsigned script_id)
12326 {
12327    DBG(DBG_USER, "script_id=%d", script_id);
12328 
12329    CHECK_INITED;
12330 
12331    if (script_id >= PI_MAX_SCRIPTS)
12332       SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12333 
12334    if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12335    {
12336       pthread_mutex_lock(&gpioScript[script_id].pthMutex);
12337 
12338       gpioScript[script_id].request = PI_SCRIPT_HALT;
12339 
12340       if (gpioScript[script_id].run_state == PI_SCRIPT_WAITING)
12341       {
12342          pthread_cond_signal(&gpioScript[script_id].pthCond);
12343       }
12344 
12345       pthread_mutex_unlock(&gpioScript[script_id].pthMutex);
12346 
12347       return 0;
12348    }
12349    else return PI_BAD_SCRIPT_ID;
12350 }
12351 
12352 /* ----------------------------------------------------------------------- */
12353 
12354 int gpioDeleteScript(unsigned script_id)
12355 {
12356    DBG(DBG_USER, "script_id=%d", script_id);
12357 
12358    CHECK_INITED;
12359 
12360    if (script_id >= PI_MAX_SCRIPTS)
12361       SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12362 
12363    if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12364    {
12365       gpioScript[script_id].state = PI_SCRIPT_DYING;
12366 
12367       pthread_mutex_lock(&gpioScript[script_id].pthMutex);
12368 
12369       gpioScript[script_id].request = PI_SCRIPT_HALT;
12370 
12371       if (gpioScript[script_id].run_state == PI_SCRIPT_WAITING)
12372       {
12373          pthread_cond_signal(&gpioScript[script_id].pthCond);
12374       }
12375 
12376       pthread_mutex_unlock(&gpioScript[script_id].pthMutex);
12377 
12378       while (gpioScript[script_id].run_state == PI_SCRIPT_RUNNING)
12379       {
12380          myGpioSleep(0, 5000); /* give script time to halt */
12381       }
12382 
12383       gpioStopThread(gpioScript[script_id].pthIdp);
12384 
12385       if (gpioScript[script_id].script.par)
12386          free(gpioScript[script_id].script.par);
12387 
12388       gpioScript[script_id].script.par = NULL;
12389 
12390       gpioScript[script_id].state = PI_SCRIPT_FREE;
12391 
12392       return 0;
12393    }
12394    else return PI_BAD_SCRIPT_ID;
12395 }
12396 
12397 
12398 
12399 /* ----------------------------------------------------------------------- */
12400 
12401 int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
12402 {
12403    DBG(DBG_USER, "signum=%d function=%08X", signum, (uint32_t)f);
12404 
12405    CHECK_INITED;
12406 
12407    if (signum > PI_MAX_SIGNUM)
12408       SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
12409 
12410    gpioSignal[signum].ex = 0;
12411    gpioSignal[signum].userdata = NULL;
12412 
12413    gpioSignal[signum].func = f;
12414 
12415    return 0;
12416 }
12417 
12418 
12419 /* ----------------------------------------------------------------------- */
12420 
12421 int gpioSetSignalFuncEx(unsigned signum, gpioSignalFuncEx_t f,
12422                         void *userdata)
12423 {
12424    DBG(DBG_USER, "signum=%d function=%08X userdata=%08X",
12425       signum, (uint32_t)f, (uint32_t)userdata);
12426 
12427    CHECK_INITED;
12428 
12429    if (signum > PI_MAX_SIGNUM)
12430       SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
12431 
12432    gpioSignal[signum].ex = 1;
12433    gpioSignal[signum].userdata = userdata;
12434 
12435    gpioSignal[signum].func = f;
12436 
12437    return 0;
12438 }
12439 
12440 
12441 /* ----------------------------------------------------------------------- */
12442 
12443 uint32_t gpioRead_Bits_0_31(void)
12444 {
12445    DBG(DBG_USER, "");
12446 
12447    CHECK_INITED;
12448 
12449    return (*(gpioReg + GPLEV0));
12450 }
12451 
12452 
12453 /* ----------------------------------------------------------------------- */
12454 
12455 uint32_t gpioRead_Bits_32_53(void)
12456 {
12457    DBG(DBG_USER, "");
12458 
12459    CHECK_INITED;
12460 
12461    return (*(gpioReg + GPLEV1));
12462 }
12463 
12464 
12465 /* ----------------------------------------------------------------------- */
12466 
12467 int gpioWrite_Bits_0_31_Clear(uint32_t bits)
12468 {
12469    DBG(DBG_USER, "bits=%08X", bits);
12470 
12471    CHECK_INITED;
12472 
12473    *(gpioReg + GPCLR0) = bits;
12474 
12475    return 0;
12476 }
12477 
12478 
12479 /* ----------------------------------------------------------------------- */
12480 
12481 int gpioWrite_Bits_32_53_Clear(uint32_t bits)
12482 {
12483    DBG(DBG_USER, "bits=%08X", bits);
12484 
12485    CHECK_INITED;
12486 
12487    *(gpioReg + GPCLR1) = bits;
12488 
12489    return 0;
12490 }
12491 
12492 
12493 /* ----------------------------------------------------------------------- */
12494 
12495 int gpioWrite_Bits_0_31_Set(uint32_t bits)
12496 {
12497    DBG(DBG_USER, "bits=%08X", bits);
12498 
12499    CHECK_INITED;
12500 
12501    *(gpioReg + GPSET0) = bits;
12502 
12503    return 0;
12504 }
12505 
12506 
12507 /* ----------------------------------------------------------------------- */
12508 
12509 int gpioWrite_Bits_32_53_Set(uint32_t bits)
12510 {
12511    DBG(DBG_USER, "bits=%08X", bits);
12512 
12513    CHECK_INITED;
12514 
12515    *(gpioReg + GPSET1) = bits;
12516 
12517    return 0;
12518 }
12519 
12520 /* ----------------------------------------------------------------------- */
12521 
12522 int gpioHardwareClock(unsigned gpio, unsigned frequency)
12523 {
12524    int cctl[] = {CLK_GP0_CTL, CLK_GP1_CTL, CLK_GP2_CTL};
12525    int cdiv[] = {CLK_GP0_DIV, CLK_GP1_DIV, CLK_GP2_DIV};
12526    int csrc[CLK_SRCS] = {CLK_CTL_SRC_OSC, CLK_CTL_SRC_PLLD};
12527    uint32_t cfreq[CLK_SRCS]={CLK_OSC_FREQ, CLK_PLLD_FREQ};
12528    unsigned clock, mode, mash;
12529    int password = 0;
12530    double f;
12531    clkInf_t clkInf={0,0,0};
12532 
12533    DBG(DBG_USER, "gpio=%d frequency=%d", gpio, frequency);
12534 
12535    CHECK_INITED;
12536 
12537    if ((gpio >> 24) == 0x5A) password = 1;
12538 
12539    gpio &= 0xFFFFFF;
12540 
12541    if (gpio > PI_MAX_GPIO)
12542       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
12543 
12544    if (!clkDef[gpio])
12545       SOFT_ERROR(PI_NOT_HCLK_GPIO, "bad gpio for clock (%d)", gpio);
12546 
12547    if (((frequency < PI_HW_CLK_MIN_FREQ) ||
12548         (frequency > PI_HW_CLK_MAX_FREQ)) &&
12549         (frequency))
12550       SOFT_ERROR(PI_BAD_HCLK_FREQ,
12551          "bad hardware clock frequency (%d)", frequency);
12552 
12553    clock = (clkDef[gpio] >> 4) & 3;
12554 
12555    if ((clock == 1) && (!password))
12556       SOFT_ERROR(PI_BAD_HCLK_PASS,
12557          "Need password to use clock 1 (%d)", gpio);
12558 
12559    mode  = clkDef[gpio] & 7;
12560    mash = frequency < PI_MASH_MAX_FREQ ? 1 : 0;
12561 
12562    if (frequency)
12563    {
12564       if (chooseBestClock(&clkInf, frequency, CLK_SRCS, cfreq))
12565       {
12566          if (clkInf.frac == 0) mash = 0;
12567 
12568          initHWClk(cctl[clock], cdiv[clock],
12569             csrc[clkInf.clock], clkInf.div, clkInf.frac, mash);
12570 
12571          myGpioSetMode(gpio, mode);
12572 
12573          gpioInfo[gpio].is = GPIO_HW_CLK;
12574 
12575          f = (double) cfreq[clkInf.clock] /
12576            ((double)clkInf.div + ((double)clkInf.frac / 4096.0));
12577 
12578          hw_clk_freq[clock] = (f + 0.5);
12579 
12580          DBG(DBG_USER, "cf=%d div=%d frac=%d mash=%d",
12581             cfreq[clkInf.clock], clkInf.div, clkInf.frac, mash);
12582       }
12583       else
12584       {
12585          SOFT_ERROR(PI_BAD_HCLK_FREQ,
12586             "bad hardware clock frequency (%d)", frequency);
12587       }
12588    }
12589    else
12590    {
12591       /* frequency 0, stop clock */
12592       clkReg[cctl[clock]] = BCM_PASSWD | CLK_CTL_KILL;
12593 
12594       if (gpioInfo[gpio].is == GPIO_HW_CLK)
12595          gpioInfo[gpio].is = GPIO_UNDEFINED;
12596    }
12597 
12598    return 0;
12599 }
12600 
12601 /* ----------------------------------------------------------------------- */
12602 
12603 int gpioHardwarePWM(
12604    unsigned gpio, unsigned frequency, unsigned dutycycle)
12605 {
12606    uint32_t old_PWM_CTL;
12607    unsigned pwm, mode;
12608    uint32_t real_range, real_dutycycle;
12609 
12610    DBG(DBG_USER, "gpio=%d  frequency=%d dutycycle=%d",
12611       gpio, frequency, dutycycle);
12612 
12613    CHECK_INITED;
12614 
12615    if (gpio > PI_MAX_GPIO)
12616       SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
12617 
12618    if (!PWMDef[gpio])
12619       SOFT_ERROR(PI_NOT_HPWM_GPIO, "bad gpio for PWM (%d)", gpio);
12620 
12621    if (dutycycle > PI_HW_PWM_RANGE)
12622       SOFT_ERROR(PI_BAD_HPWM_DUTY, "bad PWM dutycycle (%d)", dutycycle);
12623 
12624    if (((frequency < PI_HW_PWM_MIN_FREQ) ||
12625         (frequency > PI_HW_PWM_MAX_FREQ)) &&
12626         (frequency))
12627       SOFT_ERROR(PI_BAD_HPWM_FREQ,
12628          "bad hardware PWM frequency (%d)", frequency);
12629 
12630    if (gpioCfg.clockPeriph == PI_CLOCK_PWM)
12631       SOFT_ERROR(PI_HPWM_ILLEGAL, "illegal, PWM in use for main clock");
12632 
12633    pwm = (PWMDef[gpio] >> 4) & 3;
12634    mode  = PWMDef[gpio] & 7;
12635 
12636    if (frequency)
12637    {
12638       real_range = ((double)CLK_PLLD_FREQ / (2.0 * frequency)) + 0.5;
12639       real_dutycycle = ((uint64_t)dutycycle * real_range) / PI_HW_PWM_RANGE;
12640 
12641       /* record the set PWM frequency and dutycycle */
12642 
12643       hw_pwm_freq[pwm] =
12644          ((double)CLK_PLLD_FREQ / ( 2.0 * real_range)) + 0.5;
12645 
12646       hw_pwm_duty[pwm]  = dutycycle;
12647 
12648       hw_pwm_real_range[pwm] = real_range;
12649 
12650       /* Abort any waveform transmission in progress */
12651 
12652       if (gpioWaveTxBusy()) gpioWaveTxStop();
12653 
12654       waveClockInited = 0;
12655 
12656       /* preserve channel enable only and mark space mode */
12657 
12658       old_PWM_CTL = pwmReg[PWM_CTL] &
12659          (PWM_CTL_PWEN1 | PWM_CTL_MSEN1 | PWM_CTL_PWEN2 | PWM_CTL_MSEN2);
12660 
12661       if (!PWMClockInited)
12662       {
12663          pwmReg[PWM_CTL] = 0;
12664 
12665          myGpioDelay(10);
12666 
12667          initHWClk(CLK_PWMCTL, CLK_PWMDIV, CLK_CTL_SRC_PLLD, 2, 0, 0);
12668 
12669          PWMClockInited = 1;
12670       }
12671 
12672       if (pwm == 0)
12673       {
12674          pwmReg[PWM_RNG1] = real_range;
12675          myGpioDelay(10);
12676          pwmReg[PWM_DAT1] = real_dutycycle;
12677          myGpioDelay(10);
12678 
12679          pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN1 | PWM_CTL_MSEN1);
12680       }
12681       else
12682       {
12683          pwmReg[PWM_RNG2] = real_range;
12684          myGpioDelay(10);
12685          pwmReg[PWM_DAT2] = real_dutycycle;
12686          myGpioDelay(10);
12687 
12688          pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN2 | PWM_CTL_MSEN2);
12689       }
12690 
12691       if (gpioInfo[gpio].is != GPIO_HW_PWM)
12692       {
12693          switchFunctionOff(gpio);
12694 
12695          myGpioSetMode(gpio, mode);
12696 
12697          gpioInfo[gpio].is = GPIO_HW_PWM;
12698       }
12699    }
12700    else
12701    {
12702       /* frequency 0, stop PWM */
12703 
12704       if (gpioInfo[gpio].is == GPIO_HW_PWM)
12705       {
12706          if (pwm == 0) pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN1);
12707          else          pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN2);
12708 
12709          gpioInfo[gpio].is = GPIO_UNDEFINED;
12710       }
12711    }
12712 
12713    return 0;
12714 }
12715 
12716 
12717 int gpioSetPad(unsigned pad, unsigned padStrength)
12718 {
12719    DBG(DBG_USER, "pad=%d  padStrength=%d", pad, padStrength);
12720 
12721    CHECK_INITED;
12722 
12723    if (pad > PI_MAX_PAD)
12724       SOFT_ERROR(PI_BAD_PAD, "bad pad number (%d)", pad);
12725 
12726    if ((padStrength < PI_MIN_PAD_STRENGTH) ||
12727        (padStrength > PI_MAX_PAD_STRENGTH))
12728       SOFT_ERROR(PI_BAD_STRENGTH, "bad pad drive strength (%d)", pad);
12729 
12730    /* 1-16 -> 0-7 */
12731 
12732    padStrength += 1;
12733    padStrength /= 2;
12734    padStrength -= 1;
12735 
12736    padsReg[11+pad] = BCM_PASSWD | 0x18 | (padStrength & 7) ;
12737 
12738    return 0;
12739 }
12740 
12741 int gpioGetPad(unsigned pad)
12742 {
12743    int strength;
12744 
12745    DBG(DBG_USER, "pad=%d", pad);
12746 
12747    CHECK_INITED;
12748 
12749    if (pad > PI_MAX_PAD)
12750       SOFT_ERROR(PI_BAD_PAD, "bad pad (%d)", pad);
12751 
12752    strength = padsReg[11+pad] & 7;
12753 
12754    strength *= 2;
12755    strength += 2;
12756 
12757    return strength;
12758 }
12759 
12760 int shell(char *scriptName, char *scriptString)
12761 {
12762    int status;
12763    char buf[4096];
12764 
12765    DBG(DBG_USER, "name=%s string=%s", scriptName, scriptString);
12766 
12767    CHECK_INITED;
12768 
12769    if (!myScriptNameValid(scriptName))
12770       SOFT_ERROR(PI_BAD_SCRIPT_NAME, "bad script name (%s)", scriptName);
12771 
12772    snprintf(buf, sizeof(buf),
12773       "/opt/pigpio/cgi/%s %s", scriptName, scriptString);
12774 
12775    DBG(DBG_USER, "%s", buf);
12776 
12777    status = system(buf);
12778 
12779    if (status < 0) status = PI_BAD_SHELL_STATUS;
12780 
12781    return status;
12782 }
12783 
12784 
12785 int fileApprove(char *filename)
12786 {
12787    char match[PI_MAX_PATH];
12788    char buffer[PI_MAX_PATH];
12789    char line[PI_MAX_PATH];
12790    char mperm=0;
12791    char perm;
12792    char term;
12793    FILE *f;
12794 
12795    buffer[0] = 0;
12796    match[0] = 0;
12797 
12798    f = fopen("/opt/pigpio/access", "r");
12799 
12800    if (!f) return PI_FILE_NONE;
12801 
12802    while (!feof(f))
12803    {
12804       buffer[0] = 0;
12805       perm = 0;
12806       term = 0;
12807       if (fgets(line, sizeof(line), f))
12808       {
12809          sscanf(line, " %511s %c%c", buffer, &perm, &term);
12810          if (term == 10)
12811          {
12812             if (myPathBad(buffer)) continue; /* disallow risky lines */
12813 
12814             if (fnmatch(buffer, filename, 0) == 0)
12815             {
12816                if (match[0])
12817                {
12818                   if (fnmatch(match, buffer, 0) == 0)
12819                   {
12820                      strcpy(match, buffer);
12821                      mperm = perm;
12822                   }
12823                }
12824                else
12825                {
12826                   strcpy(match, buffer);
12827                   mperm = perm;
12828                }
12829             }
12830          }
12831       }
12832    }
12833 
12834    fclose(f);
12835 
12836    if (match[0])
12837    {
12838       switch (toupper(mperm))
12839       {
12840          case 'R': return PI_FILE_READ;
12841          case 'W': return PI_FILE_WRITE;
12842          case 'U': return PI_FILE_RW;
12843          default : return PI_FILE_NONE;
12844       }
12845    }
12846 
12847    return PI_FILE_NONE;
12848 }
12849 
12850 int fileOpen(char *file, unsigned mode)
12851 {
12852    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
12853    int fd=-1;
12854    int i, slot, oflag, omode;
12855    struct stat statbuf;
12856 
12857    DBG(DBG_USER, "file=%s mode=%d", file, mode);
12858 
12859    CHECK_INITED;
12860 
12861    if ( (mode < PI_FILE_MIN) ||
12862         (mode > PI_FILE_MAX) ||
12863         ((mode & PI_FILE_RW) == 0) )
12864       SOFT_ERROR(PI_BAD_FILE_MODE, "bad mode (%d)", mode);
12865 
12866    if ((fileApprove(file) & mode) == PI_FILE_NONE)
12867       SOFT_ERROR(PI_NO_FILE_ACCESS, "no permission to access file (%s)", file);
12868 
12869    slot = -1;
12870 
12871    pthread_mutex_lock(&mutex);
12872 
12873    for (i=0; i<PI_FILE_SLOTS; i++)
12874    {
12875       if (fileInfo[i].state == PI_FILE_CLOSED)
12876       {
12877          slot = i;
12878          fileInfo[slot].state = PI_FILE_RESERVED;
12879          break;
12880       }
12881    }
12882 
12883    pthread_mutex_unlock(&mutex);
12884 
12885    if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no file handles");
12886 
12887    omode = 0;
12888    oflag = 0;
12889 
12890    if (mode & PI_FILE_APPEND)
12891    {
12892       mode |= PI_FILE_WRITE;
12893       oflag |= O_APPEND;
12894    }
12895 
12896    if (mode & PI_FILE_CREATE)
12897    {
12898       oflag |= O_CREAT;
12899       omode |= (S_IRUSR|S_IWUSR);
12900    }
12901 
12902    if (mode & PI_FILE_TRUNC)
12903    {
12904       mode |= PI_FILE_WRITE;
12905       oflag |= O_TRUNC;
12906    }
12907 
12908    switch(mode&PI_FILE_RW)
12909    {
12910       case PI_FILE_READ:
12911          fd = open(file, O_RDONLY|oflag, omode);
12912          break;
12913 
12914       case PI_FILE_WRITE:
12915          fd = open(file, O_WRONLY|oflag, omode);
12916          break;
12917 
12918       case PI_FILE_RW:
12919          fd = open(file, O_RDWR|oflag, omode);
12920          break;
12921    }
12922 
12923    if (fd == -1)
12924    {
12925       fileInfo[slot].state = PI_FILE_CLOSED;
12926       return PI_FIL_OPEN_FAILED;
12927    }
12928    else
12929    {
12930       if (stat(file, &statbuf) == 0)
12931       {
12932          if (S_ISDIR(statbuf.st_mode))
12933          {
12934             close(fd);
12935             fileInfo[slot].state = PI_FILE_CLOSED;
12936             SOFT_ERROR(PI_FILE_IS_A_DIR, "file is a directory (%s)", file);
12937          }
12938       }
12939    }
12940 
12941    fileInfo[slot].fd = fd;
12942    fileInfo[slot].mode = mode;
12943    fileInfo[slot].state = PI_FILE_OPENED;
12944 
12945    return slot;
12946 }
12947 
12948 int fileClose(unsigned handle)
12949 {
12950    DBG(DBG_USER, "handle=%d", handle);
12951 
12952    CHECK_INITED;
12953 
12954    if (handle >= PI_FILE_SLOTS)
12955       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12956 
12957    if (fileInfo[handle].state != PI_FILE_OPENED)
12958       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12959 
12960    if (fileInfo[handle].fd >= 0) close(fileInfo[handle].fd);
12961 
12962    fileInfo[handle].fd = -1;
12963    fileInfo[handle].state = PI_FILE_CLOSED;
12964 
12965    return 0;
12966 }
12967 
12968 int fileWrite(unsigned handle, char *buf, unsigned count)
12969 {
12970    int w;
12971 
12972    DBG(DBG_USER, "handle=%d count=%d [%s]",
12973       handle, count, myBuf2Str(count, buf));
12974 
12975    CHECK_INITED;
12976 
12977    if (handle >= PI_FILE_SLOTS)
12978       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12979 
12980    if (fileInfo[handle].state != PI_FILE_OPENED)
12981       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12982 
12983    if (!count)
12984       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
12985 
12986    if (!(fileInfo[handle].mode & PI_FILE_WRITE))
12987       SOFT_ERROR(PI_FILE_NOT_WOPEN, "file not opened for write");
12988 
12989    w = write(fileInfo[handle].fd, buf, count);
12990 
12991    if (w != count)
12992    {
12993       if (w == -1) DBG(DBG_USER, "write failed with errno %d", errno);
12994 
12995       return PI_BAD_FILE_WRITE;
12996    }
12997    return 0;
12998 }
12999 
13000 int fileRead(unsigned handle, char *buf, unsigned count)
13001 {
13002    int r;
13003 
13004    DBG(DBG_USER, "handle=%d count=%d buf=0x%X", handle, count, (unsigned)buf);
13005 
13006    CHECK_INITED;
13007 
13008    if (handle >= PI_FILE_SLOTS)
13009       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13010 
13011    if (fileInfo[handle].state != PI_FILE_OPENED)
13012       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13013 
13014    if (!count)
13015       SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
13016 
13017    if (!(fileInfo[handle].mode & PI_FILE_READ))
13018       SOFT_ERROR(PI_FILE_NOT_ROPEN, "file not opened for read");
13019 
13020    r = read(fileInfo[handle].fd, buf, count);
13021 
13022    if (r == -1)
13023    {
13024       DBG(DBG_USER, "read failed with errno %d", errno);
13025       return PI_BAD_FILE_READ;
13026    }
13027    else
13028    {
13029       buf[r] = 0;
13030       return r;
13031    }
13032 }
13033 
13034 
13035 int fileSeek(unsigned handle, int32_t seekOffset, int seekFrom)
13036 {
13037    int whence, s;
13038 
13039    DBG(DBG_USER, "handle=%d offset=%d from=%d",
13040       handle, seekOffset, seekFrom);
13041 
13042    CHECK_INITED;
13043 
13044    if (handle >= PI_FILE_SLOTS)
13045       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13046 
13047    if (fileInfo[handle].state != PI_FILE_OPENED)
13048       SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13049 
13050    switch (seekFrom)
13051    {
13052       case PI_FROM_START:
13053          whence = SEEK_SET;
13054          break;
13055 
13056       case PI_FROM_CURRENT:
13057          whence = SEEK_CUR;
13058          break;
13059 
13060       case PI_FROM_END:
13061          whence = SEEK_END;
13062          break;
13063 
13064       default:
13065          SOFT_ERROR(PI_BAD_FILE_SEEK, "bad seek from (%d)", seekFrom);
13066    }
13067 
13068    s = lseek(fileInfo[handle].fd, seekOffset, whence);
13069 
13070    if (s == -1)
13071    {
13072       DBG(DBG_USER, "seek failed with errno %d", errno);
13073       return PI_BAD_FILE_SEEK;
13074    }
13075 
13076    return s;
13077 }
13078 
13079 int fileList(char *fpat,  char *buf, unsigned count)
13080 {
13081    int len, bufpos;
13082    glob_t pglob;
13083    int i;
13084 
13085    DBG(DBG_USER, "fpat=%s count=%d buf=%x", fpat, count, (unsigned)buf);
13086 
13087    CHECK_INITED;
13088 
13089    if (fileApprove(fpat) == PI_FILE_NONE)
13090       SOFT_ERROR(PI_NO_FILE_ACCESS, "no permission to access file (%s)", fpat);
13091 
13092    bufpos = 0;
13093 
13094    if (glob(fpat, GLOB_MARK, NULL, &pglob) == 0)
13095    {
13096       for (i=0; i<pglob.gl_pathc; i++)
13097       {
13098          len = strlen(pglob.gl_pathv[i]);
13099          if ((bufpos + len + 1) < count)
13100          {
13101             strcpy(buf+bufpos, pglob.gl_pathv[i]);
13102             bufpos += len;
13103             buf[bufpos++] = '\n';
13104          }
13105       }
13106    }
13107    else
13108    {
13109       bufpos = PI_NO_FILE_MATCH;
13110    }
13111 
13112    globfree(&pglob);
13113 
13114    return bufpos;
13115 }
13116 
13117 
13118 
13119 /* ----------------------------------------------------------------------- */
13120 
13121 int gpioTime(unsigned timetype, int *seconds, int *micros)
13122 {
13123    struct timespec ts;
13124 
13125    DBG(DBG_USER, "timetype=%d &seconds=%08X &micros=%08X",
13126       timetype, (uint32_t)seconds, (uint32_t)micros);
13127 
13128    CHECK_INITED;
13129 
13130    if (timetype > PI_TIME_ABSOLUTE)
13131       SOFT_ERROR(PI_BAD_TIMETYPE, "bad timetype (%d)", timetype);
13132 
13133    if (timetype == PI_TIME_ABSOLUTE)
13134    {
13135       clock_gettime(CLOCK_REALTIME, &ts);
13136       *seconds = ts.tv_sec;
13137       *micros  = ts.tv_nsec/1000;
13138    }
13139    else
13140    {
13141       clock_gettime(CLOCK_REALTIME, &ts);
13142 
13143       TIMER_SUB(&ts, &libStarted, &ts);
13144 
13145       *seconds = ts.tv_sec;
13146       *micros  = ts.tv_nsec/1000;
13147    }
13148 
13149    return 0;
13150 }
13151 
13152 
13153 /* ----------------------------------------------------------------------- */
13154 
13155 int gpioSleep(unsigned timetype, int seconds, int micros)
13156 {
13157    struct timespec ts, rem;
13158 
13159    DBG(DBG_USER, "timetype=%d seconds=%d micros=%d",
13160       timetype, seconds, micros);
13161 
13162    CHECK_INITED;
13163 
13164    if (timetype > PI_TIME_ABSOLUTE)
13165       SOFT_ERROR(PI_BAD_TIMETYPE, "bad timetype (%d)", timetype);
13166 
13167    if (seconds < 0)
13168       SOFT_ERROR(PI_BAD_SECONDS, "bad seconds (%d)", seconds);
13169 
13170    if ((micros < 0) || (micros > 999999))
13171       SOFT_ERROR(PI_BAD_MICROS, "bad micros (%d)", micros);
13172 
13173    ts.tv_sec  = seconds;
13174    ts.tv_nsec = micros * 1000;
13175 
13176    if (timetype == PI_TIME_ABSOLUTE)
13177    {
13178       while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, &rem));
13179    }
13180    else
13181    {
13182       while (clock_nanosleep(CLOCK_REALTIME, 0, &ts, &rem))
13183       {
13184          /* copy remaining time to ts */
13185          ts.tv_sec  = rem.tv_sec;
13186          ts.tv_nsec = rem.tv_nsec;
13187       }
13188    }
13189 
13190    return 0;
13191 }
13192 
13193 
13194 /* ----------------------------------------------------------------------- */
13195 
13196 uint32_t gpioDelay(uint32_t micros)
13197 {
13198    uint32_t start;
13199 
13200    DBG(DBG_USER, "microseconds=%u", micros);
13201 
13202    CHECK_INITED;
13203 
13204    start = systReg[SYST_CLO];
13205 
13206    if (micros <= PI_MAX_BUSY_DELAY)
13207       while ((systReg[SYST_CLO] - start) <= micros);
13208    else
13209       gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION));
13210 
13211    return (systReg[SYST_CLO] - start);
13212 }
13213 
13214 
13215 /* ----------------------------------------------------------------------- */
13216 
13217 uint32_t gpioTick(void)
13218 {
13219    CHECK_INITED;
13220 
13221    return systReg[SYST_CLO];
13222 }
13223 
13224 
13225 /* ----------------------------------------------------------------------- */
13226 
13227 unsigned gpioVersion(void)
13228 {
13229    DBG(DBG_USER, "");
13230 
13231    return PIGPIO_VERSION;
13232 }
13233 
13234 
13235 /* ----------------------------------------------------------------------- */
13236 
13237 /*
13238 2 2  2  2 2 2  1 1 1 1  1 1 1 1  1 1 0 0 0 0 0 0  0 0 0 0
13239 5 4  3  2 1 0  9 8 7 6  5 4 3 2  1 0 9 8 7 6 5 4  3 2 1 0
13240 
13241 W W  S  M M M  B B B B  P P P P  T T T T T T T T  R R R R
13242 
13243 W  warranty void if either bit is set
13244 
13245 S  0=old (bits 0-22 are revision number) 1=new (following fields apply)
13246 
13247 M  0=256 1=512 2=1024
13248 
13249 B  0=Sony 1=Egoman 2=Embest 3=Unknown 4=Embest
13250 
13251 P  0=2835, 1=2836, 2=2837
13252 
13253 T  0=A 1=B 2=A+ 3=B+ 4=Pi2B 5=Alpha 6=Compute Module 7=Unknown 8=Pi3B 9=Zero
13254 
13255 R  PCB board revision
13256 
13257 */
13258 
13259 unsigned gpioHardwareRevision(void)
13260 {
13261    static unsigned rev = 0;
13262 
13263    FILE * filp;
13264    char buf[512];
13265    char term;
13266 
13267    DBG(DBG_USER, "");
13268 
13269    if (rev) return rev;
13270 
13271    piCores = 0;
13272 
13273    filp = fopen ("/proc/cpuinfo", "r");
13274 
13275    if (filp != NULL)
13276    {
13277       while (fgets(buf, sizeof(buf), filp) != NULL)
13278       {
13279          if (piCores == 0)
13280          {
13281             if (!strncasecmp("model name", buf, 10))
13282             {
13283                if (strstr (buf, "ARMv6") != NULL)
13284                {
13285                   piCores = 1;
13286                   pi_peri_phys = 0x20000000;
13287                   pi_dram_bus  = 0x40000000;
13288                   pi_mem_flag  = 0x0C;
13289                }
13290                else if (strstr (buf, "ARMv7") != NULL)
13291                {
13292                   piCores = 4;
13293                   pi_peri_phys = 0x3F000000;
13294                   pi_dram_bus  = 0xC0000000;
13295                   pi_mem_flag  = 0x04;
13296                }
13297                else if (strstr (buf, "ARMv8") != NULL)
13298                {
13299                   piCores = 4;
13300                   pi_peri_phys = 0x3F000000;
13301                   pi_dram_bus  = 0xC0000000;
13302                   pi_mem_flag  = 0x04;
13303                }
13304             }
13305          }
13306 
13307          if (!strncasecmp("revision\t:", buf, 10))
13308          {
13309             if (sscanf(buf+10, "%x%c", &rev, &term) == 2)
13310             {
13311                if (term != '\n') rev = 0;
13312                else rev &= 0xFFFFFF; /* mask out warranty bit */
13313             }
13314          }
13315       }
13316 
13317       fclose(filp);
13318    }
13319    return rev;
13320 }
13321 
13322 
13323 /* ----------------------------------------------------------------------- */
13324 
13325 int gpioCfgBufferSize(unsigned millis)
13326 {
13327    DBG(DBG_USER, "millis=%d", millis);
13328 
13329    CHECK_NOT_INITED;
13330 
13331    if ((millis < PI_BUF_MILLIS_MIN) || (millis > PI_BUF_MILLIS_MAX))
13332       SOFT_ERROR(PI_BAD_BUF_MILLIS, "bad millis (%d)", millis);
13333 
13334    gpioCfg.bufferMilliseconds = millis;
13335 
13336    return 0;
13337 }
13338 
13339 
13340 /* ----------------------------------------------------------------------- */
13341 
13342 int gpioCfgClock(unsigned micros, unsigned peripheral, unsigned source)
13343 {
13344    DBG(DBG_USER, "micros=%d peripheral=%d", micros, peripheral);
13345 
13346    CHECK_NOT_INITED;
13347 
13348    if ((micros < 1) || (micros > 10))
13349       SOFT_ERROR(PI_BAD_CLK_MICROS, "bad micros (%d)", micros);
13350 
13351    if (!clkCfg[micros].valid)
13352       SOFT_ERROR(PI_BAD_CLK_MICROS, "bad micros (%d)", micros);
13353 
13354    if (peripheral > PI_CLOCK_PCM)
13355       SOFT_ERROR(PI_BAD_CLK_PERIPH, "bad peripheral (%d)", peripheral);
13356 
13357    gpioCfg.clockMicros = micros;
13358    gpioCfg.clockPeriph = peripheral;
13359 
13360    return 0;
13361 }
13362 
13363 
13364 /* ----------------------------------------------------------------------- */
13365 
13366 int gpioCfgDMAchannel(unsigned DMAchannel)
13367 {
13368    DBG(DBG_USER, "channel=%d", DMAchannel);
13369 
13370    CHECK_NOT_INITED;
13371 
13372    if ((DMAchannel < PI_MIN_DMA_CHANNEL) || (DMAchannel > PI_MAX_DMA_CHANNEL))
13373       SOFT_ERROR(PI_BAD_CHANNEL, "bad channel (%d)", DMAchannel);
13374 
13375    gpioCfg.DMAprimaryChannel = DMAchannel;
13376 
13377    return 0;
13378 }
13379 
13380 
13381 /* ----------------------------------------------------------------------- */
13382 
13383 int gpioCfgDMAchannels(unsigned primaryChannel, unsigned secondaryChannel)
13384 {
13385    DBG(DBG_USER, "primary channel=%d, secondary channel=%d",
13386       primaryChannel, secondaryChannel);
13387 
13388    CHECK_NOT_INITED;
13389 
13390    if (primaryChannel > PI_MAX_DMA_CHANNEL)
13391       SOFT_ERROR(PI_BAD_PRIM_CHANNEL, "bad primary channel (%d)",
13392          primaryChannel);
13393 
13394    if ((secondaryChannel > PI_MAX_DMA_CHANNEL) ||
13395        (secondaryChannel == primaryChannel))
13396       SOFT_ERROR(PI_BAD_SECO_CHANNEL, "bad secondary channel (%d)",
13397          secondaryChannel);
13398 
13399    gpioCfg.DMAprimaryChannel   = primaryChannel;
13400    gpioCfg.DMAsecondaryChannel = secondaryChannel;
13401 
13402    return 0;
13403 }
13404 
13405 
13406 /*-------------------------------------------------------------------------*/
13407 
13408 int gpioCfgPermissions(uint64_t updateMask)
13409 {
13410    DBG(DBG_USER, "gpio update mask=%llX", updateMask);
13411 
13412    CHECK_NOT_INITED;
13413 
13414    gpioMask = updateMask;
13415 
13416    gpioMaskSet = 1;
13417 
13418    return 0;
13419 }
13420 
13421 
13422 /* ----------------------------------------------------------------------- */
13423 
13424 int gpioCfgInterfaces(unsigned ifFlags)
13425 {
13426    DBG(DBG_USER, "ifFlags=%X", ifFlags);
13427 
13428    CHECK_NOT_INITED;
13429 
13430    if (ifFlags > 15)
13431       SOFT_ERROR(PI_BAD_IF_FLAGS, "bad ifFlags (%X)", ifFlags);
13432 
13433    gpioCfg.ifFlags = ifFlags;
13434 
13435    return 0;
13436 }
13437 
13438 /* ----------------------------------------------------------------------- */
13439 
13440 int gpioCfgSocketPort(unsigned port)
13441 {
13442    DBG(DBG_USER, "port=%d", port);
13443 
13444    CHECK_NOT_INITED;
13445 
13446    if ((port < PI_MIN_SOCKET_PORT) || (port > PI_MAX_SOCKET_PORT))
13447       SOFT_ERROR(PI_BAD_SOCKET_PORT, "bad port (%d)", port);
13448 
13449    gpioCfg.socketPort = port;
13450 
13451    return 0;
13452 }
13453 
13454 
13455 /* ----------------------------------------------------------------------- */
13456 
13457 int gpioCfgMemAlloc(unsigned memAllocMode)
13458 {
13459    DBG(DBG_USER, "memAllocMode=%d", memAllocMode);
13460 
13461    CHECK_NOT_INITED;
13462 
13463    if (memAllocMode > PI_MEM_ALLOC_MAILBOX)
13464       SOFT_ERROR(
13465          PI_BAD_MALLOC_MODE, "bad mem alloc mode (%d)", memAllocMode);
13466 
13467    gpioCfg.memAllocMode = memAllocMode;
13468 
13469    return 0;
13470 }
13471 
13472 /* ----------------------------------------------------------------------- */
13473 
13474 int gpioCfgNetAddr(int numSockAddr, uint32_t *sockAddr)
13475 {
13476    int i;
13477 
13478    DBG(DBG_USER, "numSockAddr=%d sockAddr=%08X",
13479       numSockAddr, (unsigned)sockAddr);
13480 
13481    CHECK_NOT_INITED;
13482 
13483    if (numSockAddr <= 0) numSockNetAddr = 0;
13484    else
13485    {
13486       if (numSockAddr >= MAX_CONNECT_ADDRESSES)
13487          numSockAddr = MAX_CONNECT_ADDRESSES;
13488 
13489       for (i=0; i<numSockAddr; i++) sockNetAddr[i] = sockAddr[i];
13490 
13491       numSockNetAddr = numSockAddr;
13492    }
13493    return 0;
13494 }
13495 
13496 
13497 /* ----------------------------------------------------------------------- */
13498 
13499 uint32_t gpioCfgGetInternals(void)
13500 {
13501    return gpioCfg.internals;
13502 }
13503 
13504 int gpioCfgSetInternals(uint32_t cfgVal)
13505 {
13506    gpioCfg.internals = cfgVal;
13507    gpioCfg.dbgLevel = cfgVal & 0xF;
13508    gpioCfg.alertFreq = (cfgVal>>4) & 0xF;
13509    return 0;
13510 }
13511 
13512 int gpioCfgInternals(unsigned cfgWhat, unsigned cfgVal)
13513 {
13514    int retVal = PI_BAD_CFG_INTERNAL;
13515 
13516    DBG(DBG_USER, "cfgWhat=%u, cfgVal=%d", cfgWhat, cfgVal);
13517 
13518    switch(cfgWhat)
13519    {
13520       case 562484977:
13521 
13522          if (cfgVal) gpioCfg.internals |= PI_CFG_STATS;
13523          else gpioCfg.internals &= (~PI_CFG_STATS);
13524 
13525          DBG(DBG_ALWAYS, "show stats is %u", cfgVal);
13526 
13527          retVal = 0;
13528 
13529          break;
13530 
13531       case 984762879:
13532 
13533          if ((cfgVal >= DBG_ALWAYS) && (cfgVal <= DBG_MAX_LEVEL))
13534          {
13535             
13536             gpioCfg.dbgLevel = cfgVal;
13537             gpioCfg.internals = (gpioCfg.internals & (~0xF)) | cfgVal;
13538 
13539             DBG(DBG_ALWAYS, "Debug level is %u", cfgVal);
13540 
13541             retVal = 0;
13542          }
13543 
13544          break;
13545    }
13546 
13547    return retVal;
13548 }
13549 
13550 
13551 /* include any user customisations */
13552 
13553 #include "custom.cext"
13554 


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