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].