00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #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
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
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
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
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
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
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
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
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
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
00699
00700
00701
00702
00703
00704
00705
00706
00707
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
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;
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
01085
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;
01109 uint32_t halfBit;
01110 int timeout;
01111 uint32_t startBitTick;
01112 uint32_t nextBitDiff;
01113 int bit;
01114 uint32_t data;
01115 int bytes;
01116 int level;
01117 int dataBits;
01118 int invert;
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;
01178 uint32_t nmsgs;
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;
01191 uintptr_t bus_addr;
01192 uintptr_t *virtual_addr;
01193 unsigned size;
01194 } DMAMem_t;
01195
01196
01197
01198
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
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
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
01294
01295
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,
01347 0,
01348 0,
01349 };
01350
01351
01352
01353 static unsigned bufferBlocks;
01354 static unsigned bufferCycles;
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
01384
01385 static const uint8_t clkDef[PI_MAX_GPIO + 1] =
01386 {
01387
01388 0x00, 0x00, 0x00, 0x00, 0x84, 0x94, 0xA4, 0x00, 0x00, 0x00,
01389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01390 0x82, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01391 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
01392 0x00, 0x00, 0x94, 0xA4, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00,
01393 0x00, 0x00, 0x00, 0x00,
01394 };
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 static const uint8_t PWMDef[PI_MAX_GPIO + 1] =
01418 {
01419
01420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01421 0x00, 0x00, 0x84, 0x94, 0x00, 0x00, 0x00, 0x00, 0x82, 0x92,
01422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
01424 0x84, 0x94, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00,
01425 0x00, 0x00, 0x85, 0x95,
01426 };
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447 static const clkCfg_t clkCfg[]=
01448 {
01449
01450 { 0, 0},
01451 { 1, 17},
01452 { 1, 16},
01453 { 0, 0},
01454 { 1, 15},
01455 { 1, 14},
01456 { 0, 0},
01457 { 0, 0},
01458 { 1, 13},
01459 { 0, 0},
01460 { 1, 12},
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
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);
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))
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
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
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;
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
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);
01909 memcpy(&tmp2, buf+ 4, 4);
01910 memcpy(&tmp3, buf+ 8, 4);
01911 memcpy(&tmp4, buf+12, 4);
01912 memcpy(&tmp5, buf+16, 4);
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
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
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
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
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
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);
02386 memcpy(&tmp2, buf+4, 4);
02387 memcpy(&tmp3, buf+8, 4);
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)
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)
02570 {
02571 if (newOff != realRange)
02572 {
02573 for (i=0; i<SUPERLEVEL; i+=realRange) mySetGpioOff(gpio, i+newOff);
02574 }
02575
02576
02577
02578 for (i=0; i<SUPERCYCLE; i+=cycles) mySetGpioOn(gpio, i);
02579 }
02580 else
02581 {
02582
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)
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)
02648 {
02649 for (i=0; i<SUPERLEVEL; i+=realRange)
02650 mySetGpioOff(gpio, i+newOff);
02651
02652
02653
02654 for (i=0; i<SUPERCYCLE; i+=cycles) mySetGpioOn(gpio, i);
02655 }
02656 else
02657 {
02658
02659
02660 for (i=0; i<SUPERCYCLE; i+=cycles)
02661 myClearGpioOn(gpio, i);
02662
02663
02664
02665 if (myGpioRead(gpio)) myGpioDelay(PI_MAX_SERVO_PULSEWIDTH);
02666
02667
02668
02669 for (i=0; i<SUPERLEVEL; i+=realRange)
02670 myClearGpioOff(gpio, i+oldOff);
02671 }
02672 }
02673 }
02674
02675
02676
02677
02678
02679
02680
02681 static int mbCreate(char *dev)
02682 {
02683
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
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
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
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
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
02988
02989 p = rawWaveCBAdr(botCB++);
02990
02991
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;
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
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
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
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
03232
03233 if (tNow < tNext1)
03234 {
03235
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
03249
03250 if (tNow < tNext2)
03251 {
03252
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
03266
03267 if (tNow < tNext1)
03268 {
03269
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++;
03290
03291 if (out[outPos].gpioOff) cbs++;
03292
03293 if (out[outPos].flags & WAVE_FLAG_READ)
03294 {
03295 cbs++;
03296 --level;
03297 }
03298
03299 if (out[outPos].flags & WAVE_FLAG_TICK)
03300 {
03301 cbs++;
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
03983
03984 if (system("/sbin/modprobe i2c_dev") == -1) { }
03985 if (system("/sbin/modprobe i2c_bcm2835") == -1) { }
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;
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) { }
04050 }
04051 else
04052 {
04053 if (write(fd, "0\n", 2) == -1) { }
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
04139 if (numSegs)
04140 {
04141 status = i2cSegments(handle, segs, numSegs);
04142 if (status >= 0) status = 0;
04143 numSegs = 0;
04144 }
04145 i2cSwitchCombined(1);
04146 break;
04147
04148 case PI_I2C_COMBINED_OFF:
04149
04150 if (numSegs)
04151 {
04152 status = i2cSegments(handle, segs, numSegs);
04153 if (status >= 0) status = 0;
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
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;
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;
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
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,
04294 uint32_t flags,
04295 char *txBuf,
04296 char *rxBuf,
04297 unsigned count)
04298 {
04299 int cs;
04300 char bit_ir[4] = {1, 0, 0, 1};
04301 char bit_or[4] = {0, 1, 1, 0};
04302 char bit_ic[4] = {0, 0, 1, 1};
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
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;
04422
04423 spiReg[SPI_CS] = spiDefaults;
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;
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
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;
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
04548
04549 auxReg[AUX_ENABLES] |= AUXENB_SPI1;
04550
04551
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
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
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
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
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
04622
04623 auxReg[AUX_ENABLES] &= (~AUXENB_SPI1);
04624
04625
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
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))
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);
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
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
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
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
05209
05210 cbAddr = dmaOut[DMA_CONBLK_AD];
05211
05212 if (!cbAddr) return -PI_NO_TX_WAVE;
05213
05214 page = 0;
05215
05216
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
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
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);
05448
05449 b++; dmaTickCb(b, cycle);
05450
05451 for (pulse=0; pulse<PULSE_PER_CYCLE; pulse++)
05452 {
05453 b++; dmaReadLevelsCb(b, level);
05454
05455 b++; dmaDelayCb(b);
05456
05457 b++; dmaGpioOffCb(b, (level%SUPERLEVEL)+1);
05458
05459 ++level;
05460 }
05461 }
05462
05463
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
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
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
05554
05555
05556
05557
05558
05559
05560
05561
05562
05563
05564
05565
05566
05567
05568
05569
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
05604
05605
05606 changedTick = sample[j].tick;
05607 LBitV = bitV;
05608 }
05609
05610 if (bitV != RBitV)
05611 {
05612
05613
05614 diff = sample[j].tick - changedTick;
05615
05616 if (diff >= steadyUs)
05617 {
05618
05619 RBitV = bitV;
05620 }
05621 else
05622 {
05623
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)
05659 {
05660 diff = nowTick - gpioAlert[i].nfTick2;
05661
05662 if (diff >= 0)
05663 {
05664
05665
05666 gpioAlert[i].nfActive = 0;
05667 gpioAlert[i].nfTick1 = nowTick;
05668 }
05669 }
05670 else
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
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
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
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
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
05867
05868
05869
05870
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
05897
05898
05899
05900
05901
05902
05903 bits = gpioNotify[n].bits;
05904
05905 if (timeoutBits & bits)
05906 {
05907
05908
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
05934
05935
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
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
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
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
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
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
06226
06227 gpioCfg.internals |= PI_CFG_STATS;
06228
06229 dmaInitCbs();
06230 flushMemory();
06231 initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]);
06232 myGpioDelay(5000);
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
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
06319
06320 if (numSamples && gFilterBits) alertGlitchFilter(sample, numSamples);
06321
06322
06323
06324 if (numSamples && nFilterBits) alertNoiseFilter(sample, numSamples);
06325
06326
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
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
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;
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
06554
06555
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
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
06799
06800 flags = fcntl(fileno(outFifo), F_GETFL, 0);
06801 fcntl(fileno(outFifo), F_SETFL, flags | O_NONBLOCK);
06802
06803
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;
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
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
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
06919 if (recv(sock, buf, p[3], MSG_WAITALL) != p[3])
06920 {
06921
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
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
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
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) { }
06977
06978 switch (p[0])
06979 {
06980
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) { }
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
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
07057
07058
07059 listen(fdSock, 100);
07060
07061 c = sizeof(client);
07062
07063
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;
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
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
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
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
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
07435
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
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
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
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
07573
07574 pwmReg[PWM_CTL] = 0;
07575
07576 myGpioDelay(10);
07577
07578 pwmReg[PWM_STA] = -1;
07579
07580 myGpioDelay(10);
07581
07582
07583
07584 pwmReg[PWM_RNG1] = bits;
07585
07586 myGpioDelay(10);
07587
07588 dmaIVirt[0]->periphData = 1;
07589
07590
07591
07592 pwmReg[PWM_DMAC] = PWM_DMAC_ENAB |
07593 PWM_DMAC_PANIC(15) |
07594 PWM_DMAC_DREQ(15);
07595
07596 myGpioDelay(10);
07597
07598
07599
07600 pwmReg[PWM_CTL] = PWM_CTL_CLRF1;
07601
07602 myGpioDelay(10);
07603
07604
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
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);
07633
07634
07635
07636 pcmReg[PCM_TXC] = PCM_TXC_CH1EN | PCM_TXC_CH1WID(bits-8);
07637
07638 pcmReg[PCM_CS] |= PCM_CS_STBY;
07639
07640 myGpioDelay(1000);
07641
07642 pcmReg[PCM_CS] |= PCM_CS_TXCLR;
07643
07644 pcmReg[PCM_CS] |= PCM_CS_DMAEN;
07645
07646 pcmReg[PCM_DREQ] = PCM_DREQ_TX_PANIC(16) | PCM_DREQ_TX_REQ_L(30);
07647
07648 pcmReg[PCM_INTSTC] = 0b1111;
07649
07650
07651
07652 pcmReg[PCM_CS] |= PCM_CS_EN;
07653
07654
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
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;
07721 clkBits = BITS;
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
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
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
07887
07888 for (i=0; i<=PI_MAX_GPIO; i++)
07889 {
07890 if (gpioISR[i].pth)
07891 {
07892
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
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
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
08095
08096
08097
08098
08099
08100
08101
08102
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
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, ¶m);
08137
08138 initClock(1);
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
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
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
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
08564 myGpioSetServo(gpio, gpioInfo[gpio].width, 0);
08565 gpioInfo[gpio].width = 0;
08566 break;
08567
08568 case GPIO_PWM:
08569
08570 myGpioSetPwm(gpio, gpioInfo[gpio].width, 0);
08571 gpioInfo[gpio].width = 0;
08572 break;
08573
08574 case GPIO_HW_CLK:
08575
08576 gpioInfo[gpio].width = 0;
08577 break;
08578
08579 case GPIO_HW_PWM:
08580
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
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
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;
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
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
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
09271
09272
09273
09274
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
09300
09301 if (getBitInBytes(tx_bit_pos, buf, spiTxBits))
09302 {
09303 on_bits |= (1<<(spi->mosi));
09304 dbv = 1;
09305 }
09306 else
09307 {
09308 off_bits |= (1<<(spi->mosi));
09309 dbv = 0;
09310 }
09311
09312 if (!spi->clk_pha) tx_bit_pos ++;
09313
09314 if (spi->ss_pol) off_bits |= (1<<spiSS);
09315 else on_bits |= (1<<spiSS);
09316
09317 if (spi->clk_pol) on_bits |= (1<<(spi->clk));
09318 else off_bits |= (1<<(spi->clk));
09319
09320 wf[2][p].gpioOn = on_bits;
09321 wf[2][p].gpioOff = off_bits;
09322 wf[2][p].flags = 0;
09323
09324 if (spi->clk_us > spi->ss_us) wf[2][p].usDelay = spi->clk_us;
09325 else wf[2][p].usDelay = spi->ss_us;
09326
09327 p++;
09328
09329 for (bit=1; bit<=spiBits; bit++)
09330 {
09331 for (halfbit=0; halfbit<2; halfbit++)
09332 {
09333 wf[2][p].usDelay = spi->clk_us;
09334 wf[2][p].flags = 0;
09335
09336 on_bits = 0;
09337 off_bits = 0;
09338
09339 if (read_cycle[halfbit])
09340 {
09341 if ((bit>=spiBitFirst) && (bit<=spiBitLast))
09342 wf[2][p].flags = WAVE_FLAG_READ;
09343 }
09344 else
09345 {
09346 if (getBitInBytes(tx_bit_pos, buf, spiTxBits))
09347 {
09348 if (!dbv) on_bits |= (1<<(spi->mosi));
09349 dbv = 1;
09350 }
09351 else
09352 {
09353 if (dbv) off_bits |= (1<<(spi->mosi));
09354 dbv = 0;
09355 }
09356
09357 ++tx_bit_pos;
09358 }
09359
09360 if (rising_edge[halfbit]) on_bits |= (1<<(spi->clk));
09361 else off_bits |= (1<<(spi->clk));
09362
09363 wf[2][p].gpioOn = on_bits;
09364 wf[2][p].gpioOff = off_bits;
09365
09366 p++;
09367 }
09368 }
09369
09370 on_bits = 0;
09371 off_bits = 0;
09372
09373 if (spi->ss_pol) on_bits |= (1<<spiSS);
09374 else off_bits |= (1<<spiSS);
09375
09376 wf[2][p].gpioOn = on_bits;
09377 wf[2][p].gpioOff = off_bits;
09378 wf[2][p].flags = 0;
09379 wf[2][p].usDelay = 0;
09380
09381 p++;
09382
09383 return rawWaveAddGeneric(p, wf[2]);
09384 }
09385
09386
09387
09388 int gpioWaveCreate(void)
09389 {
09390 int i, wid;
09391 int numCB, numBOOL, numTOOL;
09392 int CB, BOOL, TOOL;
09393
09394 DBG(DBG_USER, "");
09395
09396 CHECK_INITED;
09397
09398 if (wfc[wfcur] == 0) return PI_EMPTY_WAVEFORM;
09399
09400
09401
09402 waveCBsOOLs(&numCB, &numBOOL, &numTOOL);
09403
09404 wid = -1;
09405
09406
09407
09408 for (i=0; i<waveOutCount; i++)
09409 {
09410 if (waveInfo[i].deleted &&
09411 (waveInfo[i].numCB == numCB) &&
09412 (waveInfo[i].numBOOL == numBOOL) &&
09413 (waveInfo[i].numTOOL == numTOOL))
09414 {
09415
09416 wid = i;
09417 break;
09418 }
09419 }
09420
09421 if (wid == -1)
09422 {
09423
09424
09425 if ((numCB+waveOutBotCB) >= NUM_WAVE_CBS)
09426 return PI_TOO_MANY_CBS;
09427
09428 if ((numBOOL+waveOutBotOOL) >= (waveOutTopOOL-numTOOL))
09429 return PI_TOO_MANY_OOL;
09430
09431 if (wid >= PI_MAX_WAVES)
09432 return PI_NO_WAVEFORM_ID;
09433
09434 wid = waveOutCount++;
09435
09436 waveInfo[wid].botCB = waveOutBotCB;
09437 waveInfo[wid].topCB = waveOutBotCB + numCB -1;
09438 waveInfo[wid].botOOL = waveOutBotOOL;
09439 waveInfo[wid].topOOL = waveOutTopOOL;
09440 waveInfo[wid].numCB = numCB;
09441 waveInfo[wid].numBOOL = numBOOL;
09442 waveInfo[wid].numTOOL = numTOOL;
09443
09444 waveOutBotCB += numCB;
09445 waveOutBotOOL += numBOOL;
09446 waveOutTopOOL -= numTOOL;
09447 }
09448
09449
09450
09451 CB = waveInfo[wid].botCB;
09452 BOOL = waveInfo[wid].botOOL;
09453 TOOL = waveInfo[wid].topOOL;
09454
09455 wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL);
09456
09457
09458
09459 if ( (numCB != (CB-waveInfo[wid].botCB)) ||
09460 (numBOOL != (BOOL-waveInfo[wid].botOOL)) ||
09461 (numTOOL != (waveInfo[wid].topOOL-TOOL)) )
09462 {
09463 DBG(DBG_ALWAYS, "ERROR wid=%d CBs %d=%d BOOL %d=%d TOOL %d=%d", wid,
09464 numCB, CB-waveInfo[wid].botCB,
09465 numBOOL, BOOL-waveInfo[wid].botOOL,
09466 numTOOL, waveInfo[wid].topOOL-TOOL);
09467 }
09468
09469 waveInfo[wid].deleted = 0;
09470
09471
09472
09473 wfc[0] = 0;
09474 wfc[1] = 0;
09475 wfc[2] = 0;
09476
09477 wfcur = 0;
09478
09479 return wid;
09480 }
09481
09482
09483
09484 int gpioWaveDelete(unsigned wave_id)
09485 {
09486 DBG(DBG_USER, "wave id=%d", wave_id);
09487
09488 CHECK_INITED;
09489
09490 if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
09491 SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
09492
09493 waveInfo[wave_id].deleted = 1;
09494
09495 if (wave_id == (waveOutCount-1))
09496 {
09497
09498
09499 while ((wave_id > 0) && (waveInfo[wave_id-1].deleted)) --wave_id;
09500
09501 waveOutBotCB = waveInfo[wave_id].botCB;
09502 waveOutBotOOL = waveInfo[wave_id].botOOL;
09503 waveOutTopOOL = waveInfo[wave_id].topOOL;
09504
09505 waveOutCount = wave_id;
09506 }
09507
09508 return 0;
09509 }
09510
09511
09512
09513 int gpioWaveTxStart(unsigned wave_mode)
09514 {
09515
09516
09517 CHECK_INITED;
09518
09519 SOFT_ERROR(PI_DEPRECATED, "deprected function removed");
09520 }
09521
09522
09523
09524 int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
09525 {
09526 rawCbs_t *p=NULL;
09527
09528 DBG(DBG_USER, "wave_id=%d wave_mode=%d", wave_id, wave_mode);
09529
09530 CHECK_INITED;
09531
09532 if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
09533 SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
09534
09535 if (wave_mode > PI_WAVE_MODE_REPEAT_SYNC)
09536 SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", wave_mode);
09537
09538 if (!waveClockInited)
09539 {
09540 stopHardwarePWM();
09541 initClock(0);
09542 waveClockInited = 1;
09543 PWMClockInited = 0;
09544 }
09545
09546 if (wave_mode < PI_WAVE_MODE_ONE_SHOT_SYNC)
09547 {
09548 dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
09549 dmaOut[DMA_CONBLK_AD] = 0;
09550 }
09551
09552 p = rawWaveCBAdr(waveInfo[wave_id].topCB);
09553
09554 if ((wave_mode & 1) == PI_WAVE_MODE_ONE_SHOT)
09555 p->next = 0;
09556 else
09557 p->next = waveCbPOadr(waveInfo[wave_id].botCB+1);
09558
09559 if (waveEndPtr && (wave_mode > PI_WAVE_MODE_REPEAT))
09560 {
09561 *waveEndPtr = waveCbPOadr(waveInfo[wave_id].botCB+1);
09562
09563 if (!dmaOut[DMA_CONBLK_AD])
09564 {
09565 initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
09566 }
09567 }
09568 else
09569 {
09570 initDMAgo((uint32_t *)dmaOut, waveCbPOadr(waveInfo[wave_id].botCB));
09571 }
09572
09573 waveEndPtr = &p->next;
09574
09575
09576
09577
09578 return (waveInfo[wave_id].topCB - waveInfo[wave_id].botCB) + 1;
09579 }
09580
09581
09582
09583
09584 static int chainGetCB(int n)
09585 {
09586 int block, index;
09587
09588 if (n < (WCB_CHAIN_CBS * PI_WAVE_COUNT_PAGES))
09589 {
09590 block = n / WCB_CHAIN_CBS;
09591 index = n % WCB_CHAIN_CBS;
09592 return (block*CBS_PER_OPAGE) + WCB_COUNTER_CBS + index;
09593 }
09594 return -1;
09595 }
09596
09597 static void chainSetVal(int n, uint32_t val)
09598 {
09599 int block, index;
09600 uint32_t *p;
09601
09602 if (n < (WCB_CHAIN_OOL * PI_WAVE_COUNT_PAGES))
09603 {
09604 block = n / WCB_CHAIN_OOL;
09605 index = n % WCB_CHAIN_OOL;
09606 p = (uint32_t *) dmaOVirt[block] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09607 p[index] = val;
09608 }
09609 }
09610
09611 static uint32_t chainGetValPadr(int n)
09612 {
09613 int block, index;
09614 uint32_t *p;
09615
09616 if (n < (WCB_CHAIN_OOL * PI_WAVE_COUNT_PAGES))
09617 {
09618 block = n / WCB_CHAIN_OOL;
09619 index = n % WCB_CHAIN_OOL;
09620 p = (uint32_t *) dmaOBus[block] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09621 return (uint32_t) (p + index);
09622 }
09623 return 0;
09624 }
09625
09626 static uint32_t chainGetCntVal(int counter, int slot)
09627 {
09628 uint32_t *p;
09629 int page, offset;
09630 page = counter / 2;
09631 offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
09632 p = (uint32_t *) dmaOVirt[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09633 return p[WCB_CHAIN_OOL+ offset + slot];
09634 }
09635
09636 static void chainSetCntVal(int counter, int slot, uint32_t value)
09637 {
09638 uint32_t *p;
09639 int page, offset;
09640 page = counter / 2;
09641 offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
09642 p = (uint32_t *) dmaOVirt[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09643 p[WCB_CHAIN_OOL + offset + slot] = value;
09644 }
09645
09646 static uint32_t chainGetCntValPadr(int counter, int slot)
09647 {
09648 uint32_t *p;
09649 int page, offset;
09650 page = counter / 2;
09651 offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
09652 p = (uint32_t *) dmaOBus[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
09653 return (uint32_t)(p + WCB_CHAIN_OOL + offset + slot);
09654 }
09655
09656 static int chainGetCntCB(int counter)
09657 {
09658 int page, offset;
09659 page = counter / 2;
09660 offset = (counter % 2 ? WCB_CNT_CBS : 0);
09661 return ((page * CBS_PER_OPAGE) + offset);
09662 }
09663
09664 static void chainMakeCounter(
09665 unsigned counter,
09666 unsigned blklen,
09667 unsigned blocks,
09668 unsigned count,
09669 uint32_t repeat,
09670 uint32_t next)
09671 {
09672 rawCbs_t *p=NULL;
09673
09674 int b, baseCB, dig;
09675 uint32_t nxt;
09676
09677 int botCB;
09678
09679 botCB = chainGetCntCB(counter);
09680
09681 baseCB = botCB;
09682
09683
09684 for (b=0; b < (blocks*(blklen+1)); b++) chainSetCntVal(counter, b, repeat);
09685
09686 for (b=0; b<blocks; b++)
09687 chainSetCntVal(counter,
09688 ((b*(blklen+1))+blklen),
09689 waveCbPOadr(baseCB+((b*3)+3)));
09690
09691 for (b=0; b<blocks; b++)
09692 {
09693
09694
09695 p = rawWaveCBAdr(botCB++);
09696
09697 p->info = NORMAL_DMA;
09698
09699 p->src = chainGetCntValPadr(counter, b*(blklen+1));
09700 p->dst = (waveCbPOadr(botCB+1) + 20);
09701
09702 p->length = 4;
09703 p->next = waveCbPOadr(botCB);
09704
09705
09706
09707 p = rawWaveCBAdr(botCB++);
09708
09709 p->info = NORMAL_DMA;
09710
09711 p->src = chainGetCntValPadr(counter, b*(blklen+1));
09712 p->dst = chainGetCntValPadr(counter, (b*(blklen+1))+blklen);
09713
09714 p->length = 4;
09715 p->next = waveCbPOadr(botCB);
09716
09717
09718
09719 p = rawWaveCBAdr(botCB++);
09720
09721 p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
09722
09723 p->src = chainGetCntValPadr(counter, ((b*(blklen+1))+1));
09724 p->dst = chainGetCntValPadr(counter, ((b*(blklen+1))+0));
09725
09726 p->length = blklen*4;
09727 p->next = repeat;
09728 }
09729
09730
09731
09732 p = rawWaveCBAdr(botCB);
09733
09734 p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
09735
09736 p->src = chainGetCntValPadr(counter, blocks*(blklen+1));
09737 p->dst = chainGetCntValPadr(counter, 0);
09738
09739 p->length = blocks*(blklen+1)*4;
09740 p->next = next;
09741
09742 b = 0;
09743
09744 while (count && (b<blocks))
09745 {
09746 dig = count % blklen;
09747 count /= blklen;
09748
09749 if (count) nxt = chainGetCntVal(counter, (b*(blklen+1))+blklen);
09750 else nxt = waveCbPOadr(botCB);
09751
09752 chainSetCntVal(counter, b*(blklen+1)+dig, nxt);
09753
09754 b++;
09755 }
09756
09757
09758 for (b=0; b < (blocks*(blklen+1)); b++)
09759 chainSetCntVal(
09760 counter, b+(blocks*(blklen+1)), chainGetCntVal(counter, b));
09761 }
09762
09763
09764 int gpioWaveChain(char *buf, unsigned bufSize)
09765 {
09766 unsigned blklen=16, blocks=4;
09767 int cb, chaincb;
09768 rawCbs_t *p;
09769 int i, wid, cmd, loop, counters;
09770 unsigned cycles, delayCBs, dcb, delayLeft;
09771 uint32_t repeat, next, *endPtr;
09772 int stk_pos[10], stk_lev=0;
09773
09774 cb = 0;
09775 loop = -1;
09776
09777 DBG(DBG_USER, "bufSize=%d [%s]", bufSize, myBuf2Str(bufSize, buf));
09778
09779 CHECK_INITED;
09780
09781 if (!waveClockInited)
09782 {
09783 stopHardwarePWM();
09784 initClock(0);
09785 waveClockInited = 1;
09786 PWMClockInited = 0;
09787 }
09788
09789 dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
09790 dmaOut[DMA_CONBLK_AD] = 0;
09791 waveEndPtr = NULL;
09792 endPtr = NULL;
09793
09794
09795
09796 p = rawWaveCBAdr(chainGetCB(cb++));
09797
09798
09799
09800 if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
09801 {
09802 p->info = NORMAL_DMA | TIMED_DMA(2);
09803 p->dst = PCM_TIMER;
09804 }
09805 else
09806 {
09807 p->info = NORMAL_DMA | TIMED_DMA(5);
09808 p->dst = PWM_TIMER;
09809 }
09810
09811 p->src = (uint32_t) (&dmaOBus[0]->periphData);
09812 p->length = BPD * 20 / PI_WF_MICROS;
09813 p->next = waveCbPOadr(chainGetCB(cb));
09814
09815 counters = 0;
09816 wid = -1;
09817
09818 i = 0;
09819
09820 while (i<bufSize)
09821 {
09822 wid = (unsigned)buf[i];
09823
09824 if (wid == 255)
09825 {
09826 if ((i+2) > bufSize)
09827 SOFT_ERROR(PI_BAD_CHAIN_CMD,
09828 "incomplete chain command (at %d)", i);
09829
09830 cmd = buf[i+1];
09831
09832 if (cmd == 0)
09833 {
09834 if (stk_lev >= (sizeof(stk_pos)/sizeof(int)))
09835 SOFT_ERROR(PI_CHAIN_NESTING,
09836 "chain counters nested too deep (at %d)", i);
09837
09838 stk_pos[stk_lev++] = cb;
09839
09840 i += 2;
09841 }
09842 else if (cmd == 1)
09843 {
09844 if (counters >= WCB_COUNTERS)
09845 SOFT_ERROR(PI_CHAIN_COUNTER,
09846 "too many chain counters (at %d)", i);
09847
09848 if ((i+4) > bufSize)
09849 SOFT_ERROR(PI_BAD_CHAIN_CMD,
09850 "incomplete chain command (at %d)", i);
09851
09852 loop = 0;
09853 if (--stk_lev >= 0) loop = stk_pos[stk_lev];
09854
09855 if ((loop < 1) || (loop == cb))
09856 SOFT_ERROR(PI_BAD_CHAIN_LOOP,
09857 "empty chain loop (at %d)", i);
09858
09859 cycles = ((unsigned)buf[i+3] << 8) + (unsigned)buf[i+2];
09860
09861 i += 4;
09862
09863 if (cycles > PI_MAX_WAVE_CYCLES)
09864 SOFT_ERROR(PI_CHAIN_LOOP_CNT,
09865 "bad chain loop count (%d)", cycles);
09866
09867 if (cycles == 0)
09868 {
09869
09870
09871
09872
09873 p = rawWaveCBAdr(chainGetCB(loop));
09874 p->next = waveCbPOadr(chainGetCB(cb));
09875 }
09876 else if (cycles == 1)
09877 {
09878
09879 }
09880 else
09881 {
09882 chaincb = chainGetCB(cb++);
09883 if (chaincb < 0)
09884 SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09885
09886 p = rawWaveCBAdr(chaincb);
09887
09888 repeat = waveCbPOadr(chainGetCB(loop));
09889
09890
09891
09892 chaincb = chainGetCB(cb);
09893
09894 if (chaincb < 0)
09895 SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09896
09897 next = waveCbPOadr(chainGetCB(cb));
09898
09899
09900 p->info = NORMAL_DMA;
09901 p->src = (uint32_t) (&dmaOBus[0]->periphData);
09902 p->dst = (uint32_t) (&dmaOBus[0]->periphData);
09903 p->length = 4;
09904 p->next = waveCbPOadr(chainGetCntCB(counters));
09905
09906 chainMakeCounter(counters, blklen, blocks,
09907 cycles-1, repeat, next);
09908
09909 counters++;
09910 }
09911 }
09912 else if (cmd == 2)
09913 {
09914 if ((i+4) > bufSize)
09915 SOFT_ERROR(PI_BAD_CHAIN_CMD,
09916 "incomplete chain command (at %d)", i);
09917
09918 cycles = ((unsigned)buf[i+3] << 8) + (unsigned)buf[i+2];
09919
09920 i += 4;
09921
09922 if (cycles > PI_MAX_WAVE_DELAY)
09923 SOFT_ERROR(PI_BAD_CHAIN_DELAY,
09924 "bad chain delay micros (%d)", cycles);
09925
09926 if (cycles)
09927 {
09928 delayLeft = cycles;
09929 delayCBs = waveDelayCBs(delayLeft);
09930 for (dcb=0; dcb<delayCBs; dcb++)
09931 {
09932 chaincb = chainGetCB(cb++);
09933
09934 if (chaincb < 0)
09935 SOFT_ERROR(
09936 PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09937
09938 p = rawWaveCBAdr(chaincb);
09939
09940
09941
09942 if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
09943 {
09944 p->info = NORMAL_DMA | TIMED_DMA(2);
09945 p->dst = PCM_TIMER;
09946 }
09947 else
09948 {
09949 p->info = NORMAL_DMA | TIMED_DMA(5);
09950 p->dst = PWM_TIMER;
09951 }
09952
09953 p->src = (uint32_t) (&dmaOBus[0]->periphData);
09954
09955 p->length = BPD * delayLeft / PI_WF_MICROS;
09956
09957 if ((gpioCfg.DMAsecondaryChannel >= DMA_LITE_FIRST) &&
09958 (p->length > DMA_LITE_MAX))
09959 {
09960 p->length = DMA_LITE_MAX;
09961 }
09962
09963 delayLeft -= (p->length / BPD);
09964
09965 p->next = waveCbPOadr(chainGetCB(cb));
09966 }
09967 }
09968 }
09969 else if (cmd == 3)
09970 {
09971 i += 2;
09972
09973 loop = 0;
09974 if (--stk_lev >= 0) loop = stk_pos[stk_lev];
09975
09976 if ((loop < 1) || (loop == cb))
09977 SOFT_ERROR(PI_BAD_CHAIN_LOOP,
09978 "empty chain loop (at %d)", i);
09979
09980 chaincb = chainGetCB(cb++);
09981 if (chaincb < 0)
09982 SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
09983
09984 if (i < bufSize)
09985 SOFT_ERROR(PI_BAD_FOREVER,
09986 "loop forever must be last command");
09987
09988 p = rawWaveCBAdr(chaincb);
09989
09990
09991 p->info = NORMAL_DMA;
09992 p->src = (uint32_t) (&dmaOBus[0]->periphData);
09993 p->dst = (uint32_t) (&dmaOBus[0]->periphData);
09994 p->length = 4;
09995 p->next = waveCbPOadr(chainGetCB(loop));
09996 endPtr = &p->next;
09997 }
09998 else
09999 SOFT_ERROR(PI_BAD_CHAIN_CMD,
10000 "unknown chain command (255 %d)", cmd);
10001 }
10002 else if ((wid >= waveOutCount) || waveInfo[wid].deleted)
10003 SOFT_ERROR(PI_BAD_WAVE_ID, "undefined wave (%d)", wid);
10004 else
10005 {
10006 chaincb = chainGetCB(cb++);
10007
10008 if (chaincb < 0)
10009 SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
10010
10011 p = rawWaveCBAdr(chaincb);
10012
10013 chaincb = chainGetCB(cb);
10014
10015 if (chaincb < 0)
10016 SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
10017
10018 chainSetVal(cb-1, waveCbPOadr(chaincb));
10019
10020
10021
10022 p->info = NORMAL_DMA;
10023 p->src = chainGetValPadr(cb-1);
10024 p->dst = waveCbPOadr(waveInfo[wid].topCB) + 20;
10025 p->length = 4;
10026 p->next = waveCbPOadr(waveInfo[wid].botCB+1);
10027
10028 i += 1;
10029 }
10030 }
10031
10032 chaincb = chainGetCB(cb++);
10033
10034 if (chaincb < 0)
10035 SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
10036
10037 p = rawWaveCBAdr(chaincb);
10038
10039 p->info = NORMAL_DMA;
10040 p->src = (uint32_t) (&dmaOBus[0]->periphData);
10041 p->dst = (uint32_t) (&dmaOBus[0]->periphData);
10042 p->length = 4;
10043 p->next = 0;
10044
10045 if (!endPtr) endPtr = &p->next;
10046
10047 initDMAgo((uint32_t *)dmaOut, waveCbPOadr(chainGetCB(0)));
10048
10049 waveEndPtr = endPtr;
10050
10051 return 0;
10052 }
10053
10054
10055
10056 int gpioWaveTxBusy(void)
10057 {
10058 DBG(DBG_USER, "");
10059
10060 CHECK_INITED;
10061
10062 if (dmaOut[DMA_CONBLK_AD])
10063 return 1;
10064 else
10065 return 0;
10066 }
10067
10068
10069
10070 int gpioWaveTxAt(void)
10071 {
10072 int i, cb;
10073
10074 DBG(DBG_USER, "");
10075
10076 CHECK_INITED;
10077
10078 cb = dmaNowAtOCB();
10079
10080 if (cb < 0) return -cb;
10081
10082 for (i=0; i<PI_MAX_WAVES; i++)
10083 {
10084 if ( !waveInfo[i].deleted &&
10085 (cb >= waveInfo[i].botCB) &&
10086 (cb <= waveInfo[i].topCB) ) return i;
10087 }
10088
10089 return PI_WAVE_NOT_FOUND;
10090 }
10091
10092
10093
10094 int gpioWaveTxStop(void)
10095 {
10096 DBG(DBG_USER, "");
10097
10098 CHECK_INITED;
10099
10100 dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
10101 dmaOut[DMA_CONBLK_AD] = 0;
10102
10103 waveEndPtr = NULL;
10104
10105 return 0;
10106 }
10107
10108
10109
10110 int gpioWaveGetMicros(void)
10111 {
10112 DBG(DBG_USER, "");
10113
10114 CHECK_INITED;
10115
10116 return wfStats.micros;
10117 }
10118
10119
10120
10121 int gpioWaveGetHighMicros(void)
10122 {
10123 DBG(DBG_USER, "");
10124
10125 CHECK_INITED;
10126
10127 return wfStats.highMicros;
10128 }
10129
10130
10131
10132 int gpioWaveGetMaxMicros(void)
10133 {
10134 DBG(DBG_USER, "");
10135
10136 CHECK_INITED;
10137
10138 return wfStats.maxMicros;
10139 }
10140
10141
10142
10143 int gpioWaveGetPulses(void)
10144 {
10145 DBG(DBG_USER, "");
10146
10147 CHECK_INITED;
10148
10149 return wfStats.pulses;
10150 }
10151
10152
10153
10154 int gpioWaveGetHighPulses(void)
10155 {
10156 DBG(DBG_USER, "");
10157
10158 CHECK_INITED;
10159
10160 return wfStats.highPulses;
10161 }
10162
10163
10164
10165 int gpioWaveGetMaxPulses(void)
10166 {
10167 DBG(DBG_USER, "");
10168
10169 CHECK_INITED;
10170
10171 return wfStats.maxPulses;
10172 }
10173
10174
10175
10176 int gpioWaveGetCbs(void)
10177 {
10178 DBG(DBG_USER, "");
10179
10180 CHECK_INITED;
10181
10182 return wfStats.cbs;
10183 }
10184
10185
10186
10187 int gpioWaveGetHighCbs(void)
10188 {
10189 DBG(DBG_USER, "");
10190
10191 CHECK_INITED;
10192
10193 return wfStats.highCbs;
10194 }
10195
10196
10197
10198 int gpioWaveGetMaxCbs(void)
10199 {
10200 DBG(DBG_USER, "");
10201
10202 CHECK_INITED;
10203
10204 return wfStats.maxCbs;
10205 }
10206
10207
10208
10209 static int read_SDA(wfRx_t *w)
10210 {
10211 myGpioSetMode(w->I.SDA, PI_INPUT);
10212 return myGpioRead(w->I.SDA);
10213 }
10214
10215 static void set_SDA(wfRx_t *w)
10216 {
10217 myGpioSetMode(w->I.SDA, PI_INPUT);
10218 }
10219
10220 static void clear_SDA(wfRx_t *w)
10221 {
10222 myGpioSetMode(w->I.SDA, PI_OUTPUT);
10223 myGpioWrite(w->I.SDA, 0);
10224 }
10225
10226 static void clear_SCL(wfRx_t *w)
10227 {
10228 myGpioSetMode(w->I.SCL, PI_OUTPUT);
10229 myGpioWrite(w->I.SCL, 0);
10230 }
10231
10232 static void I2C_delay(wfRx_t *w)
10233 {
10234 myGpioDelay(w->I.delay);
10235 }
10236
10237 static void I2C_clock_stretch(wfRx_t *w)
10238 {
10239 uint32_t now, max_stretch=100000;
10240
10241 myGpioSetMode(w->I.SCL, PI_INPUT);
10242 now = gpioTick();
10243 while ((myGpioRead(w->I.SCL) == 0) && ((gpioTick()-now) < max_stretch));
10244 }
10245
10246 static void I2CStart(wfRx_t *w)
10247 {
10248 if (w->I.started)
10249 {
10250 set_SDA(w);
10251 I2C_delay(w);
10252 I2C_clock_stretch(w);
10253 I2C_delay(w);
10254 }
10255
10256 clear_SDA(w);
10257 I2C_delay(w);
10258 clear_SCL(w);
10259 I2C_delay(w);
10260
10261 w->I.started = 1;
10262 }
10263
10264 static void I2CStop(wfRx_t *w)
10265 {
10266 clear_SDA(w);
10267 I2C_delay(w);
10268 I2C_clock_stretch(w);
10269 I2C_delay(w);
10270 set_SDA(w);
10271 I2C_delay(w);
10272
10273 w->I.started = 0;
10274 }
10275
10276 static void I2CPutBit(wfRx_t *w, int bit)
10277 {
10278 if (bit) set_SDA(w);
10279 else clear_SDA(w);
10280
10281 I2C_delay(w);
10282 I2C_clock_stretch(w);
10283 I2C_delay(w);
10284 clear_SCL(w);
10285 }
10286
10287 static int I2CGetBit(wfRx_t *w)
10288 {
10289 int bit;
10290
10291 set_SDA(w);
10292 I2C_delay(w);
10293 I2C_clock_stretch(w);
10294 bit = read_SDA(w);
10295 I2C_delay(w);
10296 clear_SCL(w);
10297
10298 return bit;
10299 }
10300
10301 static int I2CPutByte(wfRx_t *w, int byte)
10302 {
10303 int bit, nack;
10304
10305 for(bit=0; bit<8; bit++)
10306 {
10307 I2CPutBit(w, byte & 0x80);
10308 byte <<= 1;
10309 }
10310
10311 nack = I2CGetBit(w);
10312
10313 return nack;
10314 }
10315
10316 static uint8_t I2CGetByte(wfRx_t *w, int nack)
10317 {
10318 int bit, byte=0;
10319
10320 for (bit=0; bit<8; bit++)
10321 {
10322 byte = (byte << 1) | I2CGetBit(w);
10323 }
10324
10325 I2CPutBit(w, nack);
10326
10327 return byte;
10328 }
10329
10330
10331
10332 int bbI2COpen(unsigned SDA, unsigned SCL, unsigned baud)
10333 {
10334 DBG(DBG_USER, "SDA=%d SCL=%d baud=%d", SDA, SCL, baud);
10335
10336 CHECK_INITED;
10337
10338 if (SDA > PI_MAX_USER_GPIO)
10339 SOFT_ERROR(PI_BAD_USER_GPIO, "bad SDA (%d)", SDA);
10340
10341 if (SCL > PI_MAX_USER_GPIO)
10342 SOFT_ERROR(PI_BAD_USER_GPIO, "bad SCL (%d)", SCL);
10343
10344 if ((baud < PI_BB_I2C_MIN_BAUD) || (baud > PI_BB_I2C_MAX_BAUD))
10345 SOFT_ERROR(PI_BAD_I2C_BAUD,
10346 "SDA %d, bad baud rate (%d)", SDA, baud);
10347
10348 if (wfRx[SDA].mode != PI_WFRX_NONE)
10349 SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SDA);
10350
10351 if ((wfRx[SCL].mode != PI_WFRX_NONE) || (SCL == SDA))
10352 SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SCL);
10353
10354 wfRx[SDA].gpio = SDA;
10355 wfRx[SDA].mode = PI_WFRX_I2C_SDA;
10356 wfRx[SDA].baud = baud;
10357
10358 wfRx[SDA].I.started = 0;
10359 wfRx[SDA].I.SDA = SDA;
10360 wfRx[SDA].I.SCL = SCL;
10361 wfRx[SDA].I.delay = 500000 / baud;
10362 wfRx[SDA].I.SDAMode = gpioGetMode(SDA);
10363 wfRx[SDA].I.SCLMode = gpioGetMode(SCL);
10364
10365 wfRx[SCL].gpio = SCL;
10366 wfRx[SCL].mode = PI_WFRX_I2C_SCL;
10367
10368 myGpioSetMode(SDA, PI_INPUT);
10369 myGpioSetMode(SCL, PI_INPUT);
10370
10371 return 0;
10372 }
10373
10374
10375
10376 int bbI2CClose(unsigned SDA)
10377 {
10378 DBG(DBG_USER, "SDA=%d", SDA);
10379
10380 CHECK_INITED;
10381
10382 if (SDA > PI_MAX_USER_GPIO)
10383 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA);
10384
10385 switch(wfRx[SDA].mode)
10386 {
10387 case PI_WFRX_I2C_SDA:
10388
10389 myGpioSetMode(wfRx[SDA].I.SDA, wfRx[SDA].I.SDAMode);
10390 myGpioSetMode(wfRx[SDA].I.SCL, wfRx[SDA].I.SCLMode);
10391
10392 wfRx[wfRx[SDA].I.SDA].mode = PI_WFRX_NONE;
10393 wfRx[wfRx[SDA].I.SCL].mode = PI_WFRX_NONE;
10394
10395 break;
10396
10397 default:
10398
10399 SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA);
10400
10401 break;
10402
10403 }
10404
10405 return 0;
10406 }
10407
10408
10409
10410 int bbI2CZip(
10411 unsigned SDA,
10412 char *inBuf,
10413 unsigned inLen,
10414 char *outBuf,
10415 unsigned outLen)
10416 {
10417 int i, ack, inPos, outPos, status, bytes;
10418 int addr, flags, esc, setesc;
10419 wfRx_t *w;
10420
10421 DBG(DBG_USER, "gpio=%d inBuf=%s outBuf=%08X len=%d",
10422 SDA, myBuf2Str(inLen, (char *)inBuf), (int)outBuf, outLen);
10423
10424 CHECK_INITED;
10425
10426 if (SDA > PI_MAX_USER_GPIO)
10427 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA);
10428
10429 if (wfRx[SDA].mode != PI_WFRX_I2C_SDA)
10430 SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA);
10431
10432 if (!inBuf || !inLen)
10433 SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
10434
10435 if (!outBuf && outLen)
10436 SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
10437
10438 w = &wfRx[SDA];
10439
10440 inPos = 0;
10441 outPos = 0;
10442 status = 0;
10443
10444 addr = 0;
10445 flags = 0;
10446 esc = 0;
10447 setesc = 0;
10448
10449 wfRx_lock(SDA);
10450
10451 while (!status && (inPos < inLen))
10452 {
10453 DBG(DBG_INTERNAL, "status=%d inpos=%d inlen=%d cmd=%d addr=%d flags=%x",
10454 status, inPos, inLen, inBuf[inPos], addr, flags);
10455
10456 switch (inBuf[inPos++])
10457 {
10458 case PI_I2C_END:
10459 status = 1;
10460 break;
10461
10462 case PI_I2C_START:
10463 I2CStart(w);
10464 break;
10465
10466 case PI_I2C_STOP:
10467 I2CStop(w);
10468 break;
10469
10470 case PI_I2C_ADDR:
10471 addr = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10472 if (addr < 0) status = PI_BAD_I2C_CMD;
10473 break;
10474
10475 case PI_I2C_FLAGS:
10476
10477 esc = 1;
10478 flags = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10479 if (flags < 0) status = PI_BAD_I2C_CMD;
10480 break;
10481
10482 case PI_I2C_ESC:
10483 setesc = 1;
10484 break;
10485
10486 case PI_I2C_READ:
10487
10488 bytes = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10489
10490 if (bytes >= 0) ack = I2CPutByte(w, (addr<<1)|1);
10491
10492 if (bytes > 0)
10493 {
10494 if (!ack)
10495 {
10496 if ((bytes + outPos) <= outLen)
10497 {
10498 for (i=0; i<(bytes-1); i++)
10499 {
10500 outBuf[outPos++] = I2CGetByte(w, 0);
10501 }
10502 outBuf[outPos++] = I2CGetByte(w, 1);
10503 }
10504 else status = PI_BAD_I2C_RLEN;
10505 }
10506 else status = PI_I2C_READ_FAILED;
10507 }
10508 else status = PI_BAD_I2C_CMD;
10509 break;
10510
10511 case PI_I2C_WRITE:
10512
10513 bytes = myI2CGetPar(inBuf, &inPos, inLen, &esc);
10514
10515 if (bytes >= 0) ack = I2CPutByte(w, addr<<1);
10516
10517 if (bytes > 0)
10518 {
10519 if (!ack)
10520 {
10521 if ((bytes + inPos) <= inLen)
10522 {
10523 for (i=0; i<(bytes-1); i++)
10524 {
10525 ack = I2CPutByte(w, inBuf[inPos++]);
10526 if (ack) status = PI_I2C_WRITE_FAILED;
10527 }
10528 ack = I2CPutByte(w, inBuf[inPos++]);
10529 }
10530 else status = PI_BAD_I2C_WLEN;
10531 } else status = PI_I2C_WRITE_FAILED;
10532 }
10533 else status = PI_BAD_I2C_CMD;
10534 break;
10535
10536 default:
10537 status = PI_BAD_I2C_CMD;
10538 }
10539
10540 if (setesc) esc = 1; else esc = 0;
10541
10542 setesc = 0;
10543 }
10544
10545 wfRx_unlock(SDA);
10546
10547 if (status >= 0) status = outPos;
10548
10549 return status;
10550 }
10551
10552
10553
10554 void bscInit(int mode)
10555 {
10556 bscsReg[BSC_CR]=0;
10557 bscsReg[BSC_RSR]=0;
10558 bscsReg[BSC_SLV]=0;
10559 bscsReg[BSC_IMSC]=0xf;
10560 bscsReg[BSC_ICR]=0x0f;
10561
10562 gpioSetMode(BSC_SDA_MOSI, PI_ALT3);
10563 gpioSetMode(BSC_SCL_SCLK, PI_ALT3);
10564
10565 if (mode > 1)
10566 {
10567 gpioSetMode(BSC_MISO, PI_ALT3);
10568 gpioSetMode(BSC_CE_N, PI_ALT3);
10569 }
10570 }
10571
10572 void bscTerm(int mode)
10573 {
10574 bscsReg[BSC_CR] = 0;
10575 bscsReg[BSC_RSR]=0;
10576 bscsReg[BSC_SLV]=0;
10577
10578 gpioSetMode(BSC_SDA_MOSI, PI_INPUT);
10579 gpioSetMode(BSC_SCL_SCLK, PI_INPUT);
10580
10581 if (mode > 1)
10582 {
10583 gpioSetMode(BSC_MISO, PI_INPUT);
10584 gpioSetMode(BSC_CE_N, PI_INPUT);
10585 }
10586 }
10587
10588 int bscXfer(bsc_xfer_t *xfer)
10589 {
10590 static int bscMode = 0;
10591
10592 int copied=0;
10593 int active, mode;
10594
10595 DBG(DBG_USER, "control=0x%X (sa=0x%X, cr=0x%X) tx=%d [%s]",
10596 xfer->control,
10597 ((xfer->control)>>16) & 127,
10598 (xfer->control) & 0x3fff,
10599 xfer->txCnt,
10600 myBuf2Str(xfer->txCnt, (char *)xfer->txBuf));
10601
10602 CHECK_INITED;
10603
10604 eventAlert[PI_EVENT_BSC].ignore = 1;
10605
10606 if (xfer->control)
10607 {
10608
10609
10610
10611
10612 if (xfer->control & 2) mode = 2;
10613 else mode = 1;
10614
10615 if (mode > bscMode)
10616 {
10617 bscInit(bscMode);
10618 bscMode = mode;
10619 }
10620 }
10621 else
10622 {
10623 if (bscMode) bscTerm(bscMode);
10624 bscMode = 0;
10625 return 0;
10626 }
10627
10628 xfer->rxCnt = 0;
10629
10630 bscsReg[BSC_SLV] = ((xfer->control)>>16) & 127;
10631 bscsReg[BSC_CR] = (xfer->control) & 0x3fff;
10632 bscsReg[BSC_RSR]=0;
10633
10634 active = 1;
10635
10636 while (active)
10637 {
10638 active = 0;
10639
10640 while ((copied < xfer->txCnt) &&
10641 (!(bscsReg[BSC_FR] & BSC_FR_TXFF)))
10642 {
10643 bscsReg[BSC_DR] = xfer->txBuf[copied++];
10644 active = 1;
10645 }
10646
10647 while ((xfer->rxCnt < BSC_FIFO_SIZE) &&
10648 (!(bscsReg[BSC_FR] & BSC_FR_RXFE)))
10649 {
10650 xfer->rxBuf[xfer->rxCnt++] = bscsReg[BSC_DR];
10651 active = 1;
10652 }
10653
10654 if (!active)
10655 {
10656 active = bscsReg[BSC_FR] & (BSC_FR_RXBUSY | BSC_FR_TXBUSY);
10657 }
10658
10659 if (active) myGpioSleep(0, 20);
10660 }
10661
10662 bscFR = bscsReg[BSC_FR] & 0xffff;
10663
10664 eventAlert[PI_EVENT_BSC].ignore = 0;
10665
10666 return (copied<<16) | bscFR;
10667 }
10668
10669
10670
10671 static void set_CS(wfRx_t *w)
10672 {
10673 myGpioWrite(w->S.CS, PI_SPI_FLAGS_GET_CSPOL(w->S.spiFlags));
10674 }
10675
10676 static void clear_CS(wfRx_t *w)
10677 {
10678 myGpioWrite(w->S.CS, !PI_SPI_FLAGS_GET_CSPOL(w->S.spiFlags));
10679 }
10680
10681 static void set_SCLK(wfRx_t *w)
10682 {
10683 myGpioWrite(w->S.SCLK, !PI_SPI_FLAGS_GET_CPOL(w->S.spiFlags));
10684 }
10685
10686 static void clear_SCLK(wfRx_t *w)
10687 {
10688 myGpioWrite(w->S.SCLK, PI_SPI_FLAGS_GET_CPOL(w->S.spiFlags));
10689 }
10690
10691 static void SPI_delay(wfRx_t *w)
10692 {
10693 myGpioDelay(w->S.delay);
10694 }
10695
10696 static void bbSPIStart(wfRx_t *w)
10697 {
10698 clear_SCLK(w);
10699
10700 SPI_delay(w);
10701
10702 set_CS(w);
10703
10704 SPI_delay(w);
10705 }
10706
10707 static void bbSPIStop(wfRx_t *w)
10708 {
10709 SPI_delay(w);
10710
10711 clear_CS(w);
10712
10713 SPI_delay(w);
10714
10715 clear_SCLK(w);
10716 }
10717
10718 static uint8_t bbSPIXferByte(wfRx_t *w, char txByte)
10719 {
10720 uint8_t bit, rxByte=0;
10721
10722 if (PI_SPI_FLAGS_GET_CPHA(w->S.spiFlags))
10723 {
10724
10725
10726
10727
10728
10729
10730 for (bit=0; bit<8; bit++)
10731 {
10732 set_SCLK(w);
10733
10734 if (PI_SPI_FLAGS_GET_TX_LSB(w->S.spiFlags))
10735 {
10736 myGpioWrite(w->S.MOSI, txByte & 0x01);
10737 txByte >>= 1;
10738 }
10739 else
10740 {
10741 myGpioWrite(w->S.MOSI, txByte & 0x80);
10742 txByte <<= 1;
10743 }
10744
10745 SPI_delay(w);
10746
10747 clear_SCLK(w);
10748
10749 if (PI_SPI_FLAGS_GET_RX_LSB(w->S.spiFlags))
10750 {
10751 rxByte = (rxByte >> 1) | myGpioRead(w->S.MISO) << 7;
10752 }
10753 else
10754 {
10755 rxByte = (rxByte << 1) | myGpioRead(w->S.MISO);
10756 }
10757
10758 SPI_delay(w);
10759 }
10760 }
10761 else
10762 {
10763
10764
10765
10766
10767
10768
10769 for (bit=0; bit<8; bit++)
10770 {
10771 if (PI_SPI_FLAGS_GET_TX_LSB(w->S.spiFlags))
10772 {
10773 myGpioWrite(w->S.MOSI, txByte & 0x01);
10774 txByte >>= 1;
10775 }
10776 else
10777 {
10778 myGpioWrite(w->S.MOSI, txByte & 0x80);
10779 txByte <<= 1;
10780 }
10781
10782 SPI_delay(w);
10783
10784 set_SCLK(w);
10785
10786 if (PI_SPI_FLAGS_GET_RX_LSB(w->S.spiFlags))
10787 {
10788 rxByte = (rxByte >> 1) | myGpioRead(w->S.MISO) << 7;
10789 }
10790 else
10791 {
10792 rxByte = (rxByte << 1) | myGpioRead(w->S.MISO);
10793 }
10794
10795 SPI_delay(w);
10796
10797 clear_SCLK(w);
10798 }
10799 }
10800
10801 return rxByte;
10802 }
10803
10804
10805
10806 int bbSPIOpen(
10807 unsigned CS, unsigned MISO, unsigned MOSI, unsigned SCLK,
10808 unsigned baud, unsigned spiFlags)
10809 {
10810 int valid;
10811 uint32_t bits;
10812
10813 DBG(DBG_USER, "CS=%d MISO=%d MOSI=%d SCLK=%d baud=%d flags=%d",
10814 CS, MISO, MOSI, SCLK, baud, spiFlags);
10815
10816 CHECK_INITED;
10817
10818 if (CS > PI_MAX_USER_GPIO)
10819 SOFT_ERROR(PI_BAD_USER_GPIO, "bad CS (%d)", CS);
10820
10821 if (MISO > PI_MAX_USER_GPIO)
10822 SOFT_ERROR(PI_BAD_USER_GPIO, "bad MISO (%d)", MISO);
10823
10824 if (MOSI > PI_MAX_USER_GPIO)
10825 SOFT_ERROR(PI_BAD_USER_GPIO, "bad MOSI (%d)", MOSI);
10826
10827 if (SCLK > PI_MAX_USER_GPIO)
10828 SOFT_ERROR(PI_BAD_USER_GPIO, "bad SCLK (%d)", SCLK);
10829
10830 if ((baud < PI_BB_SPI_MIN_BAUD) || (baud > PI_BB_SPI_MAX_BAUD))
10831 SOFT_ERROR(PI_BAD_SPI_BAUD, "CS %d, bad baud (%d)", CS, baud);
10832
10833 if (wfRx[CS].mode != PI_WFRX_NONE)
10834 SOFT_ERROR(PI_GPIO_IN_USE,
10835 "CS %d is already being used, mode %d", CS, wfRx[CS].mode);
10836
10837 valid = 0;
10838
10839
10840
10841 bits = (1<<CS) | (1<<MISO) | (1<<MOSI) | (1<<SCLK);
10842
10843 if (__builtin_popcount(bits) == 4)
10844 {
10845 if ((wfRx[MISO].mode == PI_WFRX_NONE) &&
10846 (wfRx[MOSI].mode == PI_WFRX_NONE) &&
10847 (wfRx[SCLK].mode == PI_WFRX_NONE))
10848 {
10849 valid = 1;
10850 }
10851 else
10852 {
10853 if ((wfRx[MISO].mode == PI_WFRX_SPI_MISO) &&
10854 (wfRx[MOSI].mode == PI_WFRX_SPI_MOSI) &&
10855 (wfRx[SCLK].mode == PI_WFRX_SPI_SCLK))
10856 {
10857 valid = 2;
10858 }
10859 }
10860 }
10861
10862 if (!valid)
10863 {
10864 SOFT_ERROR(PI_GPIO_IN_USE,
10865 "GPIO already being used (%d=%d %d=%d, %d=%d %d=%d)",
10866 CS, wfRx[CS].mode,
10867 MISO, wfRx[MISO].mode,
10868 MOSI, wfRx[MOSI].mode,
10869 SCLK, wfRx[SCLK].mode);
10870 }
10871
10872 wfRx[CS].mode = PI_WFRX_SPI_CS;
10873 wfRx[CS].baud = baud;
10874
10875 wfRx[CS].S.CS = CS;
10876 wfRx[CS].S.SCLK = SCLK;
10877
10878 wfRx[CS].S.CSMode = gpioGetMode(CS);
10879 wfRx[CS].S.delay = (500000 / baud) - 1;
10880 wfRx[CS].S.spiFlags = spiFlags;
10881
10882
10883
10884 if (PI_SPI_FLAGS_GET_CSPOL(spiFlags))
10885 gpioWrite(CS, 0);
10886 else
10887 gpioWrite(CS, 1);
10888
10889
10890
10891 if (valid == 1)
10892 {
10893 wfRx[SCLK].S.usage = 1;
10894
10895 wfRx[SCLK].S.SCLKMode = gpioGetMode(SCLK);
10896 wfRx[SCLK].S.MISOMode = gpioGetMode(MISO);
10897 wfRx[SCLK].S.MOSIMode = gpioGetMode(MOSI);
10898
10899 wfRx[SCLK].mode = PI_WFRX_SPI_SCLK;
10900 wfRx[MISO].mode = PI_WFRX_SPI_MISO;
10901 wfRx[MOSI].mode = PI_WFRX_SPI_MOSI;
10902
10903 wfRx[SCLK].S.SCLK = SCLK;
10904 wfRx[SCLK].S.MISO = MISO;
10905 wfRx[SCLK].S.MOSI = MOSI;
10906
10907 myGpioSetMode(MISO, PI_INPUT);
10908 myGpioSetMode(SCLK, PI_OUTPUT);
10909 gpioWrite(MOSI, 0);
10910 }
10911 else
10912 {
10913 wfRx[SCLK].S.usage++;
10914 }
10915
10916 return 0;
10917 }
10918
10919
10920
10921 int bbSPIClose(unsigned CS)
10922 {
10923 int SCLK;
10924
10925 DBG(DBG_USER, "CS=%d", CS);
10926
10927 CHECK_INITED;
10928
10929 if (CS > PI_MAX_USER_GPIO)
10930 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", CS);
10931
10932 switch(wfRx[CS].mode)
10933 {
10934 case PI_WFRX_SPI_CS:
10935
10936 myGpioSetMode(wfRx[CS].S.CS, wfRx[CS].S.CSMode);
10937 wfRx[CS].mode = PI_WFRX_NONE;
10938
10939 SCLK = wfRx[CS].S.SCLK;
10940
10941 if (--wfRx[SCLK].S.usage <= 0)
10942 {
10943 myGpioSetMode(wfRx[SCLK].S.MISO, wfRx[SCLK].S.MISOMode);
10944 myGpioSetMode(wfRx[SCLK].S.MOSI, wfRx[SCLK].S.MOSIMode);
10945 myGpioSetMode(wfRx[SCLK].S.SCLK, wfRx[SCLK].S.SCLKMode);
10946
10947 wfRx[wfRx[SCLK].S.MISO].mode = PI_WFRX_NONE;
10948 wfRx[wfRx[SCLK].S.MOSI].mode = PI_WFRX_NONE;
10949 wfRx[wfRx[SCLK].S.SCLK].mode = PI_WFRX_NONE;
10950 }
10951
10952 break;
10953
10954 default:
10955
10956 SOFT_ERROR(PI_NOT_SPI_GPIO, "no SPI on gpio (%d)", CS);
10957
10958 break;
10959
10960 }
10961
10962 return 0;
10963 }
10964
10965
10966
10967 int bbSPIXfer(
10968 unsigned CS,
10969 char *inBuf,
10970 char *outBuf,
10971 unsigned count)
10972 {
10973 int SCLK;
10974 int pos;
10975 wfRx_t *w;
10976
10977 DBG(DBG_USER, "CS=%d inBuf=%s outBuf=%08X count=%d",
10978 CS, myBuf2Str(count, (char *)inBuf), (int)outBuf, count);
10979
10980 CHECK_INITED;
10981
10982 if (CS > PI_MAX_USER_GPIO)
10983 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", CS);
10984
10985 if (wfRx[CS].mode != PI_WFRX_SPI_CS)
10986 SOFT_ERROR(PI_NOT_SPI_GPIO, "no SPI on gpio (%d)", CS);
10987
10988 if (!inBuf || !count)
10989 SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL");
10990
10991 if (!outBuf && count)
10992 SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL");
10993
10994 SCLK = wfRx[CS].S.SCLK;
10995
10996 wfRx[SCLK].S.CS = CS;
10997 wfRx[SCLK].baud = wfRx[CS].baud;
10998 wfRx[SCLK].S.delay = wfRx[CS].S.delay;
10999 wfRx[SCLK].S.spiFlags = wfRx[CS].S.spiFlags;
11000
11001 w = &wfRx[SCLK];
11002
11003 wfRx_lock(SCLK);
11004
11005 bbSPIStart(w);
11006
11007 for (pos=0; pos < count; pos++)
11008 {
11009 outBuf[pos] = bbSPIXferByte(w, inBuf[pos]);
11010 }
11011
11012 bbSPIStop(w);
11013
11014 wfRx_unlock(SCLK);
11015
11016 return count;
11017 }
11018
11019
11020
11021 int gpioSerialReadOpen(unsigned gpio, unsigned baud, unsigned data_bits)
11022 {
11023 int bitTime, timeout;
11024
11025 DBG(DBG_USER, "gpio=%d baud=%d data_bits=%d", gpio, baud, data_bits);
11026
11027 CHECK_INITED;
11028
11029 if (gpio > PI_MAX_USER_GPIO)
11030 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11031
11032 if ((baud < PI_BB_SER_MIN_BAUD) || (baud > PI_BB_SER_MAX_BAUD))
11033 SOFT_ERROR(PI_BAD_WAVE_BAUD,
11034 "gpio %d, bad baud rate (%d)", gpio, baud);
11035
11036 if ((data_bits < PI_MIN_WAVE_DATABITS) ||
11037 (data_bits > PI_MAX_WAVE_DATABITS))
11038 SOFT_ERROR(PI_BAD_DATABITS,
11039 "gpio %d, bad data bits (%d)", gpio, data_bits);
11040
11041 if (wfRx[gpio].mode != PI_WFRX_NONE)
11042 SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", gpio);
11043
11044 bitTime = (1000 * MILLION) / baud;
11045
11046 timeout = ((data_bits+2) * bitTime)/MILLION;
11047
11048 if (timeout < 1) timeout = 1;
11049
11050 wfRx[gpio].gpio = gpio;
11051 wfRx[gpio].mode = PI_WFRX_SERIAL;
11052 wfRx[gpio].baud = baud;
11053
11054 wfRx[gpio].s.buf = malloc(SRX_BUF_SIZE);
11055 wfRx[gpio].s.bufSize = SRX_BUF_SIZE;
11056 wfRx[gpio].s.timeout = timeout;
11057 wfRx[gpio].s.fullBit = bitTime;
11058 wfRx[gpio].s.halfBit = (bitTime/2)+500;
11059 wfRx[gpio].s.readPos = 0;
11060 wfRx[gpio].s.writePos = 0;
11061 wfRx[gpio].s.bit = -1;
11062 wfRx[gpio].s.dataBits = data_bits;
11063 wfRx[gpio].s.invert = PI_BB_SER_NORMAL;
11064
11065 if (data_bits < 9) wfRx[gpio].s.bytes = 1;
11066 else if (data_bits < 17) wfRx[gpio].s.bytes = 2;
11067 else wfRx[gpio].s.bytes = 4;
11068
11069 gpioSetAlertFunc(gpio, waveRxBit);
11070
11071 return 0;
11072 }
11073
11074
11075
11076 int gpioSerialReadInvert(unsigned gpio, unsigned invert)
11077 {
11078 DBG(DBG_USER, "gpio=%d invert=%d", gpio, invert);
11079
11080 CHECK_INITED;
11081
11082 if (gpio > PI_MAX_USER_GPIO)
11083 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11084
11085 if (wfRx[gpio].mode != PI_WFRX_SERIAL)
11086 SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
11087
11088 if ((invert < PI_BB_SER_NORMAL) ||
11089 (invert > PI_BB_SER_INVERT))
11090 SOFT_ERROR(PI_BAD_SER_INVERT,
11091 "bad invert level for gpio %d (%d)", gpio, invert);
11092
11093 wfRx[gpio].s.invert = invert;
11094
11095 return 0;
11096 }
11097
11098
11099
11100 int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize)
11101 {
11102 unsigned bytes=0, wpos;
11103 volatile wfRx_t *w;
11104
11105 DBG(DBG_USER, "gpio=%d buf=%08X bufSize=%d", gpio, (int)buf, bufSize);
11106
11107 CHECK_INITED;
11108
11109 if (gpio > PI_MAX_USER_GPIO)
11110 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11111
11112 if (bufSize == 0)
11113 SOFT_ERROR(PI_BAD_SERIAL_COUNT, "buffer size can't be zero");
11114
11115 if (wfRx[gpio].mode != PI_WFRX_SERIAL)
11116 SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
11117
11118 w = &wfRx[gpio];
11119
11120 if (w->s.readPos != w->s.writePos)
11121 {
11122 wpos = w->s.writePos;
11123
11124 if (wpos > w->s.readPos) bytes = wpos - w->s.readPos;
11125 else bytes = w->s.bufSize - w->s.readPos;
11126
11127 if (bytes > bufSize) bytes = bufSize;
11128
11129
11130
11131 bytes = (bytes / w->s.bytes) * w->s.bytes;
11132
11133 if (buf) memcpy(buf, w->s.buf+w->s.readPos, bytes);
11134
11135 w->s.readPos += bytes;
11136
11137 if (w->s.readPos >= w->s.bufSize) w->s.readPos = 0;
11138 }
11139 return bytes;
11140 }
11141
11142
11143
11144
11145 int gpioSerialReadClose(unsigned gpio)
11146 {
11147 DBG(DBG_USER, "gpio=%d", gpio);
11148
11149 CHECK_INITED;
11150
11151 if (gpio > PI_MAX_USER_GPIO)
11152 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11153
11154 switch(wfRx[gpio].mode)
11155 {
11156 case PI_WFRX_NONE:
11157
11158 SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio);
11159
11160 break;
11161
11162 case PI_WFRX_SERIAL:
11163
11164 free(wfRx[gpio].s.buf);
11165
11166 gpioSetWatchdog(gpio, 0);
11167
11168 gpioSetAlertFunc(gpio, NULL);
11169
11170 wfRx[gpio].mode = PI_WFRX_NONE;
11171
11172 break;
11173 }
11174
11175 return 0;
11176 }
11177
11178
11179
11180
11181 static int intEventSetFunc(
11182 unsigned event,
11183 void * f,
11184 int user,
11185 void * userdata)
11186 {
11187 DBG(DBG_INTERNAL, "event=%d function=%08X, user=%d, userdata=%08X",
11188 event, (uint32_t)f, user, (uint32_t)userdata);
11189
11190 eventAlert[event].ex = user;
11191 eventAlert[event].userdata = userdata;
11192
11193 eventAlert[event].func = f;
11194
11195 return 0;
11196 }
11197
11198
11199
11200
11201 int eventSetFunc(unsigned event, eventFunc_t f)
11202 {
11203 DBG(DBG_USER, "event=%d function=%08X", event, (uint32_t)f);
11204
11205 CHECK_INITED;
11206
11207 if (event > PI_MAX_EVENT)
11208 SOFT_ERROR(PI_BAD_EVENT_ID, "bad event (%d)", event);
11209
11210 intEventSetFunc(event, f, 0, NULL);
11211
11212 return 0;
11213 }
11214
11215
11216
11217
11218 int eventSetFuncEx(unsigned event, eventFuncEx_t f, void *userdata)
11219 {
11220 DBG(DBG_USER, "event=%d function=%08X userdata=%08X",
11221 event, (uint32_t)f, (uint32_t)userdata);
11222
11223 CHECK_INITED;
11224
11225 if (event > PI_MAX_EVENT)
11226 SOFT_ERROR(PI_BAD_EVENT_ID, "bad event (%d)", event);
11227
11228 intEventSetFunc(event, f, 1, userdata);
11229
11230 return 0;
11231 }
11232
11233
11234
11235
11236 int eventMonitor(unsigned handle, uint32_t bits)
11237 {
11238 DBG(DBG_USER, "handle=%d bits=%08X", handle, bits);
11239
11240 CHECK_INITED;
11241
11242 if (handle >= PI_NOTIFY_SLOTS)
11243 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11244
11245 if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11246 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11247
11248 gpioNotify[handle].eventBits = bits;
11249
11250 return 0;
11251 }
11252
11253
11254
11255
11256 int eventTrigger(unsigned event)
11257 {
11258 DBG(DBG_USER, "event=%d", event);
11259
11260 CHECK_INITED;
11261
11262 if (event > PI_MAX_EVENT)
11263 SOFT_ERROR(PI_BAD_EVENT_ID, "bad event (%d)", event);
11264
11265 eventAlert[event].fired = 1;
11266
11267 return 0;
11268 }
11269
11270
11271
11272
11273 static int intGpioSetAlertFunc(
11274 unsigned gpio,
11275 void * f,
11276 int user,
11277 void * userdata)
11278 {
11279 DBG(DBG_INTERNAL, "gpio=%d function=%08X, user=%d, userdata=%08X",
11280 gpio, (uint32_t)f, user, (uint32_t)userdata);
11281
11282 gpioAlert[gpio].ex = user;
11283 gpioAlert[gpio].userdata = userdata;
11284
11285 gpioAlert[gpio].func = f;
11286
11287 if (f)
11288 {
11289 alertBits |= BIT;
11290 }
11291 else
11292 {
11293 alertBits &= ~BIT;
11294 }
11295
11296 monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11297
11298 return 0;
11299 }
11300
11301
11302
11303 int gpioSetAlertFunc(unsigned gpio, gpioAlertFunc_t f)
11304 {
11305 DBG(DBG_USER, "gpio=%d function=%08X", gpio, (uint32_t)f);
11306
11307 CHECK_INITED;
11308
11309 if (gpio > PI_MAX_USER_GPIO)
11310 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11311
11312 intGpioSetAlertFunc(gpio, f, 0, NULL);
11313
11314 return 0;
11315 }
11316
11317
11318
11319
11320 int gpioSetAlertFuncEx(unsigned gpio, gpioAlertFuncEx_t f, void *userdata)
11321 {
11322 DBG(DBG_USER, "gpio=%d function=%08X userdata=%08X",
11323 gpio, (uint32_t)f, (uint32_t)userdata);
11324
11325 CHECK_INITED;
11326
11327 if (gpio > PI_MAX_USER_GPIO)
11328 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11329
11330 intGpioSetAlertFunc(gpio, f, 1, userdata);
11331
11332 return 0;
11333 }
11334
11335 static void *pthISRThread(void *x)
11336 {
11337 gpioISR_t *isr = x;
11338 int fd;
11339 int retval;
11340 uint32_t tick;
11341 int level;
11342 uint32_t levels;
11343 struct pollfd pfd;
11344 char buf[64];
11345
11346 DBG(DBG_USER, "gpio=%d edge=%d timeout=%d f=%x u=%d data=%x",
11347 isr->gpio, isr->edge, isr->timeout, (uint32_t)isr->func,
11348 isr->ex, (uint32_t)isr->userdata);
11349
11350 sprintf(buf, "/sys/class/gpio/gpio%d/value", isr->gpio);
11351
11352 if ((fd = open(buf, O_RDONLY)) < 0)
11353 {
11354 DBG(DBG_ALWAYS, "gpio %d not exported", isr->gpio);
11355 return NULL;
11356 }
11357
11358 pfd.fd = fd;
11359
11360 pfd.events = POLLPRI;
11361
11362 lseek(fd, 0, SEEK_SET);
11363 if (read(fd, buf, sizeof buf) == -1) { }
11364
11365 while (1)
11366 {
11367 retval = poll(&pfd, 1, isr->timeout);
11368
11369 tick = systReg[SYST_CLO];
11370
11371 levels = *(gpioReg + GPLEV0);
11372
11373 if (retval >= 0)
11374 {
11375 lseek(fd, 0, SEEK_SET);
11376 if (read(fd, buf, sizeof buf) == -1) { }
11377
11378 if (retval)
11379 {
11380 if (levels & (1<<isr->gpio)) level = PI_ON; else level = PI_OFF;
11381 }
11382 else level = PI_TIMEOUT;
11383
11384 if (isr->ex) (isr->func)(isr->gpio, level, tick, isr->userdata);
11385 else (isr->func)(isr->gpio, level, tick);
11386 }
11387 }
11388
11389 return NULL;
11390 }
11391
11392
11393
11394
11395 static int intGpioSetISRFunc(
11396 unsigned gpio,
11397 unsigned edge,
11398 int timeout,
11399 void *f,
11400 int user,
11401 void *userdata)
11402 {
11403 char buf[64];
11404
11405 char *edge_str[]={"rising\n", "falling\n", "both\n"};
11406 int fd;
11407 int err;
11408
11409 DBG(DBG_INTERNAL,
11410 "gpio=%d edge=%d timeout=%d function=%08X user=%d userdata=%08X",
11411 gpio, edge, timeout, (uint32_t)f, user, (uint32_t)userdata);
11412
11413 if (f)
11414 {
11415 if (!gpioISR[gpio].inited)
11416 {
11417 fd = open("/sys/class/gpio/export", O_WRONLY);
11418 if (fd < 0) return PI_BAD_ISR_INIT;
11419
11420
11421 sprintf(buf, "%d\n", gpio);
11422 err = write(fd, buf, strlen(buf));
11423 close(fd);
11424
11425 sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
11426 fd = open(buf, O_WRONLY);
11427 if (fd < 0) return PI_BAD_ISR_INIT;
11428
11429 err = write(fd, "in\n", 3);
11430 close(fd);
11431 if (err != 3) return PI_BAD_ISR_INIT;
11432
11433 gpioISR[gpio].gpio = gpio;
11434 gpioISR[gpio].edge = -1;
11435 gpioISR[gpio].timeout = -1;
11436
11437 gpioISR[gpio].inited = 1;
11438 }
11439
11440 if (gpioISR[gpio].edge != edge)
11441 {
11442 sprintf(buf, "/sys/class/gpio/gpio%d/edge", gpio);
11443 fd = open(buf, O_WRONLY);
11444 if (fd < 0) return PI_BAD_ISR_INIT;
11445
11446 err = write(fd, edge_str[edge], strlen(edge_str[edge]));
11447 close(fd);
11448 if (err != strlen(edge_str[edge])) return PI_BAD_ISR_INIT;
11449
11450 gpioISR[gpio].edge = edge;
11451
11452 if (gpioISR[gpio].pth != NULL)
11453 pthread_kill(*gpioISR[gpio].pth, SIGCHLD);
11454 }
11455
11456 if (timeout <= 0) timeout = -1;
11457 if (gpioISR[gpio].timeout != timeout)
11458 {
11459 gpioISR[gpio].timeout = timeout;
11460
11461 if (gpioISR[gpio].pth != NULL)
11462 pthread_kill(*gpioISR[gpio].pth, SIGCHLD);
11463 }
11464
11465 gpioISR[gpio].func = f;
11466 gpioISR[gpio].ex = user;
11467 gpioISR[gpio].userdata = userdata;
11468
11469 if (gpioISR[gpio].pth == NULL)
11470 gpioISR[gpio].pth = gpioStartThread(pthISRThread, &gpioISR[gpio]);
11471 }
11472 else
11473 {
11474 if (gpioISR[gpio].pth)
11475 {
11476 gpioStopThread(gpioISR[gpio].pth);
11477 gpioISR[gpio].func = NULL;
11478 gpioISR[gpio].pth = NULL;
11479 }
11480
11481 if (gpioISR[gpio].inited)
11482 {
11483 fd = open("/sys/class/gpio/unexport", O_WRONLY);
11484 if (fd < 0) return PI_BAD_ISR_INIT;
11485 sprintf(buf, "%d\n", gpio);
11486 err = write(fd, buf, strlen(buf));
11487 close(fd);
11488 if (err != strlen(buf)) return PI_BAD_ISR_INIT;
11489 gpioISR[gpio].inited = 0;
11490 }
11491 }
11492
11493 return 0;
11494 }
11495
11496
11497
11498 int gpioSetISRFunc(
11499 unsigned gpio,
11500 unsigned edge,
11501 int timeout,
11502 gpioISRFunc_t f)
11503 {
11504 DBG(DBG_USER, "gpio=%d edge=%d timeout=%d function=%08X",
11505 gpio, edge, timeout, (uint32_t)f);
11506
11507 CHECK_INITED;
11508
11509 if (gpio > PI_MAX_GPIO)
11510 SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
11511
11512 if (edge > EITHER_EDGE)
11513 SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
11514
11515 return intGpioSetISRFunc(gpio, edge, timeout, f, 0, NULL);
11516 }
11517
11518
11519
11520
11521 int gpioSetISRFuncEx(
11522 unsigned gpio,
11523 unsigned edge,
11524 int timeout,
11525 gpioAlertFuncEx_t f,
11526 void *userdata)
11527 {
11528 DBG(DBG_USER, "gpio=%d edge=%d timeout=%d function=%08X userdata=%08X",
11529 gpio, edge, timeout, (uint32_t)f, (uint32_t)userdata);
11530
11531 CHECK_INITED;
11532
11533 if (gpio > PI_MAX_GPIO)
11534 SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
11535
11536 if (edge > EITHER_EDGE)
11537 SOFT_ERROR(PI_BAD_EDGE, "bad ISR edge (%d)", edge);
11538
11539 return intGpioSetISRFunc(gpio, edge, timeout, f, 1, userdata);
11540 }
11541
11542 static void closeOrphanedNotifications(int slot, int fd)
11543 {
11544 int i;
11545
11546
11547
11548 for (i=0; i<PI_NOTIFY_SLOTS; i++)
11549 {
11550 if ((i != slot) &&
11551 (gpioNotify[i].state >= PI_NOTIFY_OPENED) &&
11552 (gpioNotify[i].fd == fd))
11553 {
11554 DBG(DBG_USER, "closed orphaned fd=%d (handle=%d)", fd, i);
11555 gpioNotify[i].state = PI_NOTIFY_CLOSED;
11556 intNotifyBits();
11557 }
11558 }
11559 }
11560
11561
11562
11563 static void notifyMutex(int lock)
11564 {
11565 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
11566 if (lock) pthread_mutex_lock(&mutex);
11567 else pthread_mutex_unlock(&mutex);
11568 }
11569
11570
11571
11572 int gpioNotifyOpenWithSize(int bufSize)
11573 {
11574 int i, slot, fd;
11575 char name[32];
11576
11577 DBG(DBG_USER, "bufSize=%d", bufSize);
11578
11579 CHECK_INITED;
11580
11581 slot = -1;
11582
11583 notifyMutex(1);
11584
11585 for (i=0; i<PI_NOTIFY_SLOTS; i++)
11586 {
11587 if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
11588 {
11589 slot = i;
11590 gpioNotify[slot].state = PI_NOTIFY_RESERVED;
11591 break;
11592 }
11593 }
11594
11595 notifyMutex(0);
11596
11597 if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
11598
11599 sprintf(name, "/dev/pigpio%d", slot);
11600
11601 myCreatePipe(name, 0664);
11602
11603 fd = open(name, O_RDWR|O_NONBLOCK);
11604
11605 if (fd < 0)
11606 {
11607 gpioNotify[slot].state = PI_NOTIFY_CLOSED;
11608 SOFT_ERROR(PI_BAD_PATHNAME, "open %s failed (%m)", name);
11609 }
11610
11611 if (bufSize != 0)
11612 {
11613 i = fcntl(fd, F_SETPIPE_SZ, bufSize);
11614 if (i != bufSize)
11615 {
11616 gpioNotify[slot].state = PI_NOTIFY_CLOSED;
11617 SOFT_ERROR(PI_BAD_PATHNAME,
11618 "fcntl %s size %d failed (%m)", name, bufSize);
11619 }
11620 }
11621
11622 gpioNotify[slot].seqno = 0;
11623 gpioNotify[slot].bits = 0;
11624 gpioNotify[slot].fd = fd;
11625 gpioNotify[slot].pipe = 1;
11626 gpioNotify[slot].max_emits = MAX_EMITS;
11627 gpioNotify[slot].lastReportTick = gpioTick();
11628 gpioNotify[i].state = PI_NOTIFY_OPENED;
11629
11630 closeOrphanedNotifications(slot, fd);
11631
11632 return slot;
11633 }
11634
11635 int gpioNotifyOpen(void)
11636 {
11637 return gpioNotifyOpenWithSize(0);
11638 }
11639
11640
11641
11642 static int gpioNotifyOpenInBand(int fd)
11643 {
11644 int i, slot;
11645
11646 DBG(DBG_USER, "fd=%d", fd);
11647
11648 CHECK_INITED;
11649
11650 slot = -1;
11651
11652 notifyMutex(1);
11653
11654 for (i=0; i<PI_NOTIFY_SLOTS; i++)
11655 {
11656 if (gpioNotify[i].state == PI_NOTIFY_CLOSED)
11657 {
11658 slot = i;
11659 gpioNotify[slot].state = PI_NOTIFY_RESERVED;
11660 break;
11661 }
11662 }
11663
11664 notifyMutex(0);
11665
11666 if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no handle");
11667
11668 gpioNotify[slot].seqno = 0;
11669 gpioNotify[slot].bits = 0;
11670 gpioNotify[slot].fd = fd;
11671 gpioNotify[slot].pipe = 0;
11672 gpioNotify[slot].max_emits = MAX_EMITS;
11673 gpioNotify[slot].lastReportTick = gpioTick();
11674 gpioNotify[slot].state = PI_NOTIFY_OPENED;
11675
11676 closeOrphanedNotifications(slot, fd);
11677
11678 return slot;
11679 }
11680
11681
11682
11683
11684 static void intScriptBits(void)
11685 {
11686 int i;
11687 uint32_t bits;
11688
11689 bits = 0;
11690
11691 for (i=0; i<PI_MAX_SCRIPTS; i++)
11692 {
11693 if (gpioScript[i].state == PI_SCRIPT_IN_USE)
11694 {
11695 bits |= gpioScript[i].waitBits;
11696 }
11697 }
11698
11699 scriptBits = bits;
11700
11701 monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11702 }
11703
11704
11705 static void intScriptEventBits(void)
11706 {
11707 int i;
11708 uint32_t bits;
11709
11710 bits = 0;
11711
11712 for (i=0; i<PI_MAX_SCRIPTS; i++)
11713 {
11714 if (gpioScript[i].state == PI_SCRIPT_IN_USE)
11715 {
11716 bits |= gpioScript[i].eventBits;
11717 }
11718 }
11719
11720 scriptEventBits = bits;
11721 }
11722
11723
11724 static void intNotifyBits(void)
11725 {
11726 int i;
11727 uint32_t bits;
11728
11729 bits = 0;
11730
11731 for (i=0; i<PI_NOTIFY_SLOTS; i++)
11732 {
11733 if (gpioNotify[i].state == PI_NOTIFY_RUNNING)
11734 {
11735 bits |= gpioNotify[i].bits;
11736 }
11737 }
11738
11739 notifyBits = bits;
11740
11741 monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11742 }
11743
11744
11745
11746
11747 int gpioNotifyBegin(unsigned handle, uint32_t bits)
11748 {
11749 DBG(DBG_USER, "handle=%d bits=%08X", handle, bits);
11750
11751 CHECK_INITED;
11752
11753 if (handle >= PI_NOTIFY_SLOTS)
11754 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11755
11756 if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11757 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11758
11759 gpioNotify[handle].bits = bits;
11760
11761 gpioNotify[handle].state = PI_NOTIFY_RUNNING;
11762
11763 intNotifyBits();
11764
11765 return 0;
11766 }
11767
11768
11769
11770
11771 int gpioNotifyPause (unsigned handle)
11772 {
11773 DBG(DBG_USER, "handle=%d", handle);
11774
11775 CHECK_INITED;
11776
11777 if (handle >= PI_NOTIFY_SLOTS)
11778 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11779
11780 if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11781 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11782
11783 gpioNotify[handle].bits = 0;
11784
11785 gpioNotify[handle].state = PI_NOTIFY_PAUSED;
11786
11787 intNotifyBits();
11788
11789 return 0;
11790 }
11791
11792
11793
11794
11795 int gpioNotifyClose(unsigned handle)
11796 {
11797 DBG(DBG_USER, "handle=%d", handle);
11798
11799 CHECK_INITED;
11800
11801 if (handle >= PI_NOTIFY_SLOTS)
11802 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11803
11804 if (gpioNotify[handle].state <= PI_NOTIFY_CLOSING)
11805 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
11806
11807 gpioNotify[handle].bits = 0;
11808
11809 gpioNotify[handle].state = PI_NOTIFY_CLOSING;
11810
11811 intNotifyBits();
11812
11813
11814
11815 return 0;
11816 }
11817
11818
11819
11820 int gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level)
11821 {
11822 DBG(DBG_USER, "gpio=%d pulseLen=%d level=%d", gpio, pulseLen, level);
11823
11824 CHECK_INITED;
11825
11826 if (gpio > PI_MAX_USER_GPIO)
11827 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11828
11829 if (level > PI_ON)
11830 SOFT_ERROR(PI_BAD_LEVEL, "gpio %d, bad level (%d)", gpio, level);
11831
11832 if ((pulseLen > PI_MAX_BUSY_DELAY) || (!pulseLen))
11833 SOFT_ERROR(PI_BAD_PULSELEN,
11834 "gpio %d, bad pulseLen (%d)", gpio, pulseLen);
11835
11836 if (level == PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
11837 else *(gpioReg + GPSET0 + BANK) = BIT;
11838
11839 myGpioDelay(pulseLen);
11840
11841 if (level != PI_OFF) *(gpioReg + GPCLR0 + BANK) = BIT;
11842 else *(gpioReg + GPSET0 + BANK) = BIT;
11843
11844 return 0;
11845 }
11846
11847
11848
11849
11850 int gpioSetWatchdog(unsigned gpio, unsigned timeout)
11851 {
11852 DBG(DBG_USER, "gpio=%d timeout=%d", gpio, timeout);
11853
11854 CHECK_INITED;
11855
11856 if (gpio > PI_MAX_USER_GPIO)
11857 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11858
11859 if (timeout > PI_MAX_WDOG_TIMEOUT)
11860 SOFT_ERROR(PI_BAD_WDOG_TIMEOUT,
11861 "gpio %d, bad timeout (%d)", gpio, timeout);
11862
11863 gpioAlert[gpio].wdTick = systReg[SYST_CLO];
11864 gpioAlert[gpio].wdSteadyUs = timeout*1000;
11865
11866 if (timeout) wdogBits |= (1<<gpio);
11867 else wdogBits &= (~(1<<gpio));
11868
11869 return 0;
11870 }
11871
11872
11873
11874 int gpioNoiseFilter(unsigned gpio, unsigned steady, unsigned active)
11875 {
11876 DBG(DBG_USER, "gpio=%d steady=%d active=%d", gpio, steady, active);
11877
11878 CHECK_INITED;
11879
11880 if (gpio > PI_MAX_USER_GPIO)
11881 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11882
11883 if (steady > PI_MAX_STEADY)
11884 SOFT_ERROR(PI_BAD_FILTER, "bad steady (%d)", steady);
11885
11886 if (active > PI_MAX_ACTIVE)
11887 SOFT_ERROR(PI_BAD_FILTER, "bad active (%d)", active);
11888
11889 gpioAlert[gpio].nfTick1 = systReg[SYST_CLO];
11890 gpioAlert[gpio].nfTick2 = gpioAlert[gpio].nfTick1;
11891 gpioAlert[gpio].nfSteadyUs = steady;
11892 gpioAlert[gpio].nfActiveUs = active;
11893 gpioAlert[gpio].nfActive = 0;
11894
11895 if (steady) nFilterBits |= (1<<gpio);
11896 else nFilterBits &= (~(1<<gpio));
11897
11898 return 0;
11899 }
11900
11901
11902
11903
11904 int gpioGlitchFilter(unsigned gpio, unsigned steady)
11905 {
11906 DBG(DBG_USER, "gpio=%d steady=%d", gpio, steady);
11907
11908 CHECK_INITED;
11909
11910 if (gpio > PI_MAX_USER_GPIO)
11911 SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
11912
11913 if (steady > PI_MAX_STEADY)
11914 SOFT_ERROR(PI_BAD_FILTER, "bad steady (%d)", steady);
11915
11916 if (steady)
11917 {
11918 gpioAlert[gpio].gfTick = systReg[SYST_CLO];
11919
11920 if (gpioRead_Bits_0_31() & (1<<gpio))
11921 {
11922 gpioAlert[gpio].gfLBitV = (1<<gpio);
11923 gpioAlert[gpio].gfRBitV = 0 ;
11924 }
11925 else
11926 {
11927 gpioAlert[gpio].gfLBitV = 0 ;
11928 gpioAlert[gpio].gfRBitV = (1<<gpio);
11929 }
11930 }
11931
11932 gpioAlert[gpio].gfSteadyUs = steady;
11933
11934 if (steady) gFilterBits |= (1<<gpio);
11935 else gFilterBits &= (~(1<<gpio));
11936
11937 return 0;
11938 }
11939
11940
11941
11942 int gpioSetGetSamplesFunc(gpioGetSamplesFunc_t f, uint32_t bits)
11943 {
11944 DBG(DBG_USER, "function=%08X bits=%08X", (uint32_t)f, bits);
11945
11946 CHECK_INITED;
11947
11948 gpioGetSamples.ex = 0;
11949 gpioGetSamples.userdata = NULL;
11950 gpioGetSamples.func = f;
11951
11952 if (f) gpioGetSamples.bits = bits;
11953 else gpioGetSamples.bits = 0;
11954
11955 monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11956
11957 return 0;
11958 }
11959
11960
11961
11962
11963 int gpioSetGetSamplesFuncEx(gpioGetSamplesFuncEx_t f,
11964 uint32_t bits,
11965 void * userdata)
11966 {
11967 DBG(DBG_USER, "function=%08X bits=%08X", (uint32_t)f, bits);
11968
11969 CHECK_INITED;
11970
11971 gpioGetSamples.ex = 1;
11972 gpioGetSamples.userdata = userdata;
11973 gpioGetSamples.func = f;
11974
11975 if (f) gpioGetSamples.bits = bits;
11976 else gpioGetSamples.bits = 0;
11977
11978 monitorBits = alertBits | notifyBits | scriptBits | gpioGetSamples.bits;
11979
11980 return 0;
11981 }
11982
11983
11984
11985
11986 static int intGpioSetTimerFunc(unsigned id,
11987 unsigned millis,
11988 void *f,
11989 int user,
11990 void *userdata)
11991 {
11992 pthread_attr_t pthAttr;
11993
11994 DBG(DBG_INTERNAL, "id=%d millis=%d function=%08X user=%d userdata=%08X",
11995 id, millis, (uint32_t)f, user, (uint32_t)userdata);
11996
11997 gpioTimer[id].id = id;
11998
11999 if (f)
12000 {
12001 gpioTimer[id].func = f;
12002 gpioTimer[id].ex = user;
12003 gpioTimer[id].userdata = userdata;
12004 gpioTimer[id].millis = millis;
12005
12006 if (!gpioTimer[id].running)
12007 {
12008 if (pthread_attr_init(&pthAttr))
12009 SOFT_ERROR(PI_TIMER_FAILED,
12010 "pthread_attr_init failed (%m)");
12011
12012 if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE))
12013 SOFT_ERROR(PI_TIMER_FAILED,
12014 "pthread_attr_setstacksize failed (%m)");
12015
12016 if (pthread_create(
12017 &gpioTimer[id].pthId, &pthAttr, pthTimerTick, &gpioTimer[id]))
12018 SOFT_ERROR(PI_TIMER_FAILED,
12019 "timer %d, create failed (%m)", id);
12020
12021 gpioTimer[id].running = 1;
12022 }
12023 }
12024 else
12025 {
12026 if (gpioTimer[id].running)
12027 {
12028
12029
12030
12031 if (pthread_self() == gpioTimer[id].pthId)
12032 {
12033 gpioTimer[id].running = 0;
12034 gpioTimer[id].func = 0;
12035 pthread_exit(NULL);
12036 }
12037 else
12038 {
12039 if (pthread_cancel(gpioTimer[id].pthId))
12040 SOFT_ERROR(PI_TIMER_FAILED, "timer %d, cancel failed (%m)", id);
12041
12042 if (pthread_join(gpioTimer[id].pthId, NULL))
12043 SOFT_ERROR(PI_TIMER_FAILED, "timer %d, join failed (%m)", id);
12044
12045 gpioTimer[id].running = 0;
12046 gpioTimer[id].func = 0;
12047 }
12048 }
12049 }
12050
12051 return 0;
12052 }
12053
12054
12055
12056
12057 int gpioSetTimerFunc(unsigned id, unsigned millis, gpioTimerFunc_t f)
12058 {
12059 DBG(DBG_USER, "id=%d millis=%d function=%08X", id, millis, (uint32_t)f);
12060
12061 CHECK_INITED;
12062
12063 if (id > PI_MAX_TIMER)
12064 SOFT_ERROR(PI_BAD_TIMER, "bad timer id (%d)", id);
12065
12066 if ((millis < PI_MIN_MS) || (millis > PI_MAX_MS))
12067 SOFT_ERROR(PI_BAD_MS, "timer %d, bad millis (%d)", id, millis);
12068
12069 intGpioSetTimerFunc(id, millis, f, 0, NULL);
12070
12071 return 0;
12072 }
12073
12074
12075
12076
12077 int gpioSetTimerFuncEx(unsigned id, unsigned millis, gpioTimerFuncEx_t f,
12078 void * userdata)
12079 {
12080 DBG(DBG_USER, "id=%d millis=%d function=%08X, userdata=%08X",
12081 id, millis, (uint32_t)f, (uint32_t)userdata);
12082
12083 CHECK_INITED;
12084
12085 if (id > PI_MAX_TIMER)
12086 SOFT_ERROR(PI_BAD_TIMER, "bad timer id (%d)", id);
12087
12088 if ((millis < PI_MIN_MS) || (millis > PI_MAX_MS))
12089 SOFT_ERROR(PI_BAD_MS, "timer %d, bad millis (%d)", id, millis);
12090
12091 intGpioSetTimerFunc(id, millis, f, 1, userdata);
12092
12093 return 0;
12094 }
12095
12096
12097
12098 pthread_t *gpioStartThread(gpioThreadFunc_t f, void *userdata)
12099 {
12100 pthread_t *pth;
12101 pthread_attr_t pthAttr;
12102
12103 DBG(DBG_USER, "f=%08X, userdata=%08X", (uint32_t)f, (uint32_t)userdata);
12104
12105 CHECK_INITED_RET_NULL_PTR;
12106
12107 pth = malloc(sizeof(pthread_t));
12108
12109 if (pth)
12110 {
12111 if (pthread_attr_init(&pthAttr))
12112 {
12113 free(pth);
12114 SOFT_ERROR(NULL, "pthread_attr_init failed");
12115 }
12116
12117 if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE))
12118 {
12119 free(pth);
12120 SOFT_ERROR(NULL, "pthread_attr_setstacksize failed");
12121 }
12122
12123 if (pthread_create(pth, &pthAttr, f, userdata))
12124 {
12125 free(pth);
12126 SOFT_ERROR(NULL, "pthread_create failed");
12127 }
12128 }
12129 return pth;
12130 }
12131
12132
12133
12134 void gpioStopThread(pthread_t *pth)
12135 {
12136 DBG(DBG_USER, "pth=%08X", (uint32_t)pth);
12137
12138 CHECK_INITED_RET_NIL;
12139
12140 if (pth)
12141 {
12142 if (pthread_self() == *pth)
12143 {
12144 free(pth);
12145 pthread_exit(NULL);
12146 }
12147 else
12148 {
12149 pthread_cancel(*pth);
12150 pthread_join(*pth, NULL);
12151 free(pth);
12152 }
12153 }
12154 }
12155
12156
12157
12158 int gpioStoreScript(char *script)
12159 {
12160 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
12161 gpioScript_t *s;
12162 int status, slot, i;
12163
12164 DBG(DBG_USER, "script=[%s]", script);
12165
12166 CHECK_INITED;
12167
12168 slot = -1;
12169
12170 pthread_mutex_lock(&mutex);
12171
12172 for (i=0; i<PI_MAX_SCRIPTS; i++)
12173 {
12174 if (gpioScript[i].state == PI_SCRIPT_FREE)
12175 {
12176 slot = i;
12177 gpioScript[slot].state = PI_SCRIPT_RESERVED;
12178 break;
12179 }
12180 }
12181
12182 pthread_mutex_unlock(&mutex);
12183
12184 if (slot < 0) SOFT_ERROR(PI_NO_SCRIPT_ROOM, "no room for scripts");
12185
12186 s = &gpioScript[slot];
12187
12188 status = cmdParseScript(script, &s->script, 0);
12189
12190 if (status == 0)
12191 {
12192 s->request = PI_SCRIPT_HALT;
12193 s->run_state = PI_SCRIPT_INITING;
12194
12195 pthread_cond_init(&s->pthCond, NULL);
12196 pthread_mutex_init(&s->pthMutex, NULL);
12197
12198 s->id = slot;
12199
12200 gpioScript[slot].state = PI_SCRIPT_IN_USE;
12201
12202 s->pthIdp = gpioStartThread(pthScript, s);
12203
12204 status = slot;
12205 }
12206 else
12207 {
12208 if (s->script.par) free(s->script.par);
12209 s->script.par = NULL;
12210 gpioScript[slot].state = PI_SCRIPT_FREE;
12211 }
12212
12213 return status;
12214 }
12215
12216
12217
12218
12219 int gpioRunScript(unsigned script_id, unsigned numParam, uint32_t *param)
12220 {
12221 int status = 0;
12222
12223 DBG(DBG_USER, "script_id=%d numParam=%d param=%08X",
12224 script_id, numParam, (uint32_t)param);
12225
12226 CHECK_INITED;
12227
12228 if (script_id >= PI_MAX_SCRIPTS)
12229 SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12230
12231 if (numParam > PI_MAX_SCRIPT_PARAMS)
12232 SOFT_ERROR(PI_TOO_MANY_PARAM, "bad number of parameters(%d)", numParam);
12233
12234 if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12235 {
12236 pthread_mutex_lock(&gpioScript[script_id].pthMutex);
12237
12238 if (gpioScript[script_id].run_state != PI_SCRIPT_INITING)
12239 {
12240 if ((numParam > 0) && (param != 0))
12241 {
12242 memcpy(gpioScript[script_id].script.par, param,
12243 sizeof(uint32_t) * numParam);
12244 }
12245
12246 gpioScript[script_id].request = PI_SCRIPT_RUN;
12247
12248 pthread_cond_signal(&gpioScript[script_id].pthCond);
12249 }
12250 else
12251 {
12252 status = PI_SCRIPT_NOT_READY;
12253 }
12254
12255 pthread_mutex_unlock(&gpioScript[script_id].pthMutex);
12256
12257 return status;
12258 }
12259 else
12260 {
12261 return PI_BAD_SCRIPT_ID;
12262 }
12263 }
12264
12265
12266
12267
12268 int gpioUpdateScript(unsigned script_id, unsigned numParam, uint32_t *param)
12269 {
12270 DBG(DBG_USER, "script_id=%d numParam=%d param=%08X",
12271 script_id, numParam, (uint32_t)param);
12272
12273 CHECK_INITED;
12274
12275 if (script_id >= PI_MAX_SCRIPTS)
12276 SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12277
12278 if (numParam > PI_MAX_SCRIPT_PARAMS)
12279 SOFT_ERROR(PI_TOO_MANY_PARAM, "bad number of parameters(%d)", numParam);
12280
12281 if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12282 {
12283 if ((numParam > 0) && (param != 0))
12284 {
12285 memcpy(gpioScript[script_id].script.par, param,
12286 sizeof(uint32_t) * numParam);
12287 }
12288 }
12289 else
12290 {
12291 return PI_BAD_SCRIPT_ID;
12292 }
12293
12294 return 0;
12295 }
12296
12297
12298
12299
12300 int gpioScriptStatus(unsigned script_id, uint32_t *param)
12301 {
12302 DBG(DBG_USER, "script_id=%d param=%08X", script_id, (uint32_t)param);
12303
12304 CHECK_INITED;
12305
12306 if (script_id >= PI_MAX_SCRIPTS)
12307 SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12308
12309 if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12310 {
12311 if (param != NULL)
12312 {
12313 memcpy(param, gpioScript[script_id].script.par,
12314 sizeof(uint32_t) * PI_MAX_SCRIPT_PARAMS);
12315 }
12316
12317 return gpioScript[script_id].run_state;
12318 }
12319 else return PI_BAD_SCRIPT_ID;
12320 }
12321
12322
12323
12324
12325 int gpioStopScript(unsigned script_id)
12326 {
12327 DBG(DBG_USER, "script_id=%d", script_id);
12328
12329 CHECK_INITED;
12330
12331 if (script_id >= PI_MAX_SCRIPTS)
12332 SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12333
12334 if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12335 {
12336 pthread_mutex_lock(&gpioScript[script_id].pthMutex);
12337
12338 gpioScript[script_id].request = PI_SCRIPT_HALT;
12339
12340 if (gpioScript[script_id].run_state == PI_SCRIPT_WAITING)
12341 {
12342 pthread_cond_signal(&gpioScript[script_id].pthCond);
12343 }
12344
12345 pthread_mutex_unlock(&gpioScript[script_id].pthMutex);
12346
12347 return 0;
12348 }
12349 else return PI_BAD_SCRIPT_ID;
12350 }
12351
12352
12353
12354 int gpioDeleteScript(unsigned script_id)
12355 {
12356 DBG(DBG_USER, "script_id=%d", script_id);
12357
12358 CHECK_INITED;
12359
12360 if (script_id >= PI_MAX_SCRIPTS)
12361 SOFT_ERROR(PI_BAD_SCRIPT_ID, "bad script id(%d)", script_id);
12362
12363 if (gpioScript[script_id].state == PI_SCRIPT_IN_USE)
12364 {
12365 gpioScript[script_id].state = PI_SCRIPT_DYING;
12366
12367 pthread_mutex_lock(&gpioScript[script_id].pthMutex);
12368
12369 gpioScript[script_id].request = PI_SCRIPT_HALT;
12370
12371 if (gpioScript[script_id].run_state == PI_SCRIPT_WAITING)
12372 {
12373 pthread_cond_signal(&gpioScript[script_id].pthCond);
12374 }
12375
12376 pthread_mutex_unlock(&gpioScript[script_id].pthMutex);
12377
12378 while (gpioScript[script_id].run_state == PI_SCRIPT_RUNNING)
12379 {
12380 myGpioSleep(0, 5000);
12381 }
12382
12383 gpioStopThread(gpioScript[script_id].pthIdp);
12384
12385 if (gpioScript[script_id].script.par)
12386 free(gpioScript[script_id].script.par);
12387
12388 gpioScript[script_id].script.par = NULL;
12389
12390 gpioScript[script_id].state = PI_SCRIPT_FREE;
12391
12392 return 0;
12393 }
12394 else return PI_BAD_SCRIPT_ID;
12395 }
12396
12397
12398
12399
12400
12401 int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
12402 {
12403 DBG(DBG_USER, "signum=%d function=%08X", signum, (uint32_t)f);
12404
12405 CHECK_INITED;
12406
12407 if (signum > PI_MAX_SIGNUM)
12408 SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
12409
12410 gpioSignal[signum].ex = 0;
12411 gpioSignal[signum].userdata = NULL;
12412
12413 gpioSignal[signum].func = f;
12414
12415 return 0;
12416 }
12417
12418
12419
12420
12421 int gpioSetSignalFuncEx(unsigned signum, gpioSignalFuncEx_t f,
12422 void *userdata)
12423 {
12424 DBG(DBG_USER, "signum=%d function=%08X userdata=%08X",
12425 signum, (uint32_t)f, (uint32_t)userdata);
12426
12427 CHECK_INITED;
12428
12429 if (signum > PI_MAX_SIGNUM)
12430 SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
12431
12432 gpioSignal[signum].ex = 1;
12433 gpioSignal[signum].userdata = userdata;
12434
12435 gpioSignal[signum].func = f;
12436
12437 return 0;
12438 }
12439
12440
12441
12442
12443 uint32_t gpioRead_Bits_0_31(void)
12444 {
12445 DBG(DBG_USER, "");
12446
12447 CHECK_INITED;
12448
12449 return (*(gpioReg + GPLEV0));
12450 }
12451
12452
12453
12454
12455 uint32_t gpioRead_Bits_32_53(void)
12456 {
12457 DBG(DBG_USER, "");
12458
12459 CHECK_INITED;
12460
12461 return (*(gpioReg + GPLEV1));
12462 }
12463
12464
12465
12466
12467 int gpioWrite_Bits_0_31_Clear(uint32_t bits)
12468 {
12469 DBG(DBG_USER, "bits=%08X", bits);
12470
12471 CHECK_INITED;
12472
12473 *(gpioReg + GPCLR0) = bits;
12474
12475 return 0;
12476 }
12477
12478
12479
12480
12481 int gpioWrite_Bits_32_53_Clear(uint32_t bits)
12482 {
12483 DBG(DBG_USER, "bits=%08X", bits);
12484
12485 CHECK_INITED;
12486
12487 *(gpioReg + GPCLR1) = bits;
12488
12489 return 0;
12490 }
12491
12492
12493
12494
12495 int gpioWrite_Bits_0_31_Set(uint32_t bits)
12496 {
12497 DBG(DBG_USER, "bits=%08X", bits);
12498
12499 CHECK_INITED;
12500
12501 *(gpioReg + GPSET0) = bits;
12502
12503 return 0;
12504 }
12505
12506
12507
12508
12509 int gpioWrite_Bits_32_53_Set(uint32_t bits)
12510 {
12511 DBG(DBG_USER, "bits=%08X", bits);
12512
12513 CHECK_INITED;
12514
12515 *(gpioReg + GPSET1) = bits;
12516
12517 return 0;
12518 }
12519
12520
12521
12522 int gpioHardwareClock(unsigned gpio, unsigned frequency)
12523 {
12524 int cctl[] = {CLK_GP0_CTL, CLK_GP1_CTL, CLK_GP2_CTL};
12525 int cdiv[] = {CLK_GP0_DIV, CLK_GP1_DIV, CLK_GP2_DIV};
12526 int csrc[CLK_SRCS] = {CLK_CTL_SRC_OSC, CLK_CTL_SRC_PLLD};
12527 uint32_t cfreq[CLK_SRCS]={CLK_OSC_FREQ, CLK_PLLD_FREQ};
12528 unsigned clock, mode, mash;
12529 int password = 0;
12530 double f;
12531 clkInf_t clkInf={0,0,0};
12532
12533 DBG(DBG_USER, "gpio=%d frequency=%d", gpio, frequency);
12534
12535 CHECK_INITED;
12536
12537 if ((gpio >> 24) == 0x5A) password = 1;
12538
12539 gpio &= 0xFFFFFF;
12540
12541 if (gpio > PI_MAX_GPIO)
12542 SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
12543
12544 if (!clkDef[gpio])
12545 SOFT_ERROR(PI_NOT_HCLK_GPIO, "bad gpio for clock (%d)", gpio);
12546
12547 if (((frequency < PI_HW_CLK_MIN_FREQ) ||
12548 (frequency > PI_HW_CLK_MAX_FREQ)) &&
12549 (frequency))
12550 SOFT_ERROR(PI_BAD_HCLK_FREQ,
12551 "bad hardware clock frequency (%d)", frequency);
12552
12553 clock = (clkDef[gpio] >> 4) & 3;
12554
12555 if ((clock == 1) && (!password))
12556 SOFT_ERROR(PI_BAD_HCLK_PASS,
12557 "Need password to use clock 1 (%d)", gpio);
12558
12559 mode = clkDef[gpio] & 7;
12560 mash = frequency < PI_MASH_MAX_FREQ ? 1 : 0;
12561
12562 if (frequency)
12563 {
12564 if (chooseBestClock(&clkInf, frequency, CLK_SRCS, cfreq))
12565 {
12566 if (clkInf.frac == 0) mash = 0;
12567
12568 initHWClk(cctl[clock], cdiv[clock],
12569 csrc[clkInf.clock], clkInf.div, clkInf.frac, mash);
12570
12571 myGpioSetMode(gpio, mode);
12572
12573 gpioInfo[gpio].is = GPIO_HW_CLK;
12574
12575 f = (double) cfreq[clkInf.clock] /
12576 ((double)clkInf.div + ((double)clkInf.frac / 4096.0));
12577
12578 hw_clk_freq[clock] = (f + 0.5);
12579
12580 DBG(DBG_USER, "cf=%d div=%d frac=%d mash=%d",
12581 cfreq[clkInf.clock], clkInf.div, clkInf.frac, mash);
12582 }
12583 else
12584 {
12585 SOFT_ERROR(PI_BAD_HCLK_FREQ,
12586 "bad hardware clock frequency (%d)", frequency);
12587 }
12588 }
12589 else
12590 {
12591
12592 clkReg[cctl[clock]] = BCM_PASSWD | CLK_CTL_KILL;
12593
12594 if (gpioInfo[gpio].is == GPIO_HW_CLK)
12595 gpioInfo[gpio].is = GPIO_UNDEFINED;
12596 }
12597
12598 return 0;
12599 }
12600
12601
12602
12603 int gpioHardwarePWM(
12604 unsigned gpio, unsigned frequency, unsigned dutycycle)
12605 {
12606 uint32_t old_PWM_CTL;
12607 unsigned pwm, mode;
12608 uint32_t real_range, real_dutycycle;
12609
12610 DBG(DBG_USER, "gpio=%d frequency=%d dutycycle=%d",
12611 gpio, frequency, dutycycle);
12612
12613 CHECK_INITED;
12614
12615 if (gpio > PI_MAX_GPIO)
12616 SOFT_ERROR(PI_BAD_GPIO, "bad gpio (%d)", gpio);
12617
12618 if (!PWMDef[gpio])
12619 SOFT_ERROR(PI_NOT_HPWM_GPIO, "bad gpio for PWM (%d)", gpio);
12620
12621 if (dutycycle > PI_HW_PWM_RANGE)
12622 SOFT_ERROR(PI_BAD_HPWM_DUTY, "bad PWM dutycycle (%d)", dutycycle);
12623
12624 if (((frequency < PI_HW_PWM_MIN_FREQ) ||
12625 (frequency > PI_HW_PWM_MAX_FREQ)) &&
12626 (frequency))
12627 SOFT_ERROR(PI_BAD_HPWM_FREQ,
12628 "bad hardware PWM frequency (%d)", frequency);
12629
12630 if (gpioCfg.clockPeriph == PI_CLOCK_PWM)
12631 SOFT_ERROR(PI_HPWM_ILLEGAL, "illegal, PWM in use for main clock");
12632
12633 pwm = (PWMDef[gpio] >> 4) & 3;
12634 mode = PWMDef[gpio] & 7;
12635
12636 if (frequency)
12637 {
12638 real_range = ((double)CLK_PLLD_FREQ / (2.0 * frequency)) + 0.5;
12639 real_dutycycle = ((uint64_t)dutycycle * real_range) / PI_HW_PWM_RANGE;
12640
12641
12642
12643 hw_pwm_freq[pwm] =
12644 ((double)CLK_PLLD_FREQ / ( 2.0 * real_range)) + 0.5;
12645
12646 hw_pwm_duty[pwm] = dutycycle;
12647
12648 hw_pwm_real_range[pwm] = real_range;
12649
12650
12651
12652 if (gpioWaveTxBusy()) gpioWaveTxStop();
12653
12654 waveClockInited = 0;
12655
12656
12657
12658 old_PWM_CTL = pwmReg[PWM_CTL] &
12659 (PWM_CTL_PWEN1 | PWM_CTL_MSEN1 | PWM_CTL_PWEN2 | PWM_CTL_MSEN2);
12660
12661 if (!PWMClockInited)
12662 {
12663 pwmReg[PWM_CTL] = 0;
12664
12665 myGpioDelay(10);
12666
12667 initHWClk(CLK_PWMCTL, CLK_PWMDIV, CLK_CTL_SRC_PLLD, 2, 0, 0);
12668
12669 PWMClockInited = 1;
12670 }
12671
12672 if (pwm == 0)
12673 {
12674 pwmReg[PWM_RNG1] = real_range;
12675 myGpioDelay(10);
12676 pwmReg[PWM_DAT1] = real_dutycycle;
12677 myGpioDelay(10);
12678
12679 pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN1 | PWM_CTL_MSEN1);
12680 }
12681 else
12682 {
12683 pwmReg[PWM_RNG2] = real_range;
12684 myGpioDelay(10);
12685 pwmReg[PWM_DAT2] = real_dutycycle;
12686 myGpioDelay(10);
12687
12688 pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN2 | PWM_CTL_MSEN2);
12689 }
12690
12691 if (gpioInfo[gpio].is != GPIO_HW_PWM)
12692 {
12693 switchFunctionOff(gpio);
12694
12695 myGpioSetMode(gpio, mode);
12696
12697 gpioInfo[gpio].is = GPIO_HW_PWM;
12698 }
12699 }
12700 else
12701 {
12702
12703
12704 if (gpioInfo[gpio].is == GPIO_HW_PWM)
12705 {
12706 if (pwm == 0) pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN1);
12707 else pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN2);
12708
12709 gpioInfo[gpio].is = GPIO_UNDEFINED;
12710 }
12711 }
12712
12713 return 0;
12714 }
12715
12716
12717 int gpioSetPad(unsigned pad, unsigned padStrength)
12718 {
12719 DBG(DBG_USER, "pad=%d padStrength=%d", pad, padStrength);
12720
12721 CHECK_INITED;
12722
12723 if (pad > PI_MAX_PAD)
12724 SOFT_ERROR(PI_BAD_PAD, "bad pad number (%d)", pad);
12725
12726 if ((padStrength < PI_MIN_PAD_STRENGTH) ||
12727 (padStrength > PI_MAX_PAD_STRENGTH))
12728 SOFT_ERROR(PI_BAD_STRENGTH, "bad pad drive strength (%d)", pad);
12729
12730
12731
12732 padStrength += 1;
12733 padStrength /= 2;
12734 padStrength -= 1;
12735
12736 padsReg[11+pad] = BCM_PASSWD | 0x18 | (padStrength & 7) ;
12737
12738 return 0;
12739 }
12740
12741 int gpioGetPad(unsigned pad)
12742 {
12743 int strength;
12744
12745 DBG(DBG_USER, "pad=%d", pad);
12746
12747 CHECK_INITED;
12748
12749 if (pad > PI_MAX_PAD)
12750 SOFT_ERROR(PI_BAD_PAD, "bad pad (%d)", pad);
12751
12752 strength = padsReg[11+pad] & 7;
12753
12754 strength *= 2;
12755 strength += 2;
12756
12757 return strength;
12758 }
12759
12760 int shell(char *scriptName, char *scriptString)
12761 {
12762 int status;
12763 char buf[4096];
12764
12765 DBG(DBG_USER, "name=%s string=%s", scriptName, scriptString);
12766
12767 CHECK_INITED;
12768
12769 if (!myScriptNameValid(scriptName))
12770 SOFT_ERROR(PI_BAD_SCRIPT_NAME, "bad script name (%s)", scriptName);
12771
12772 snprintf(buf, sizeof(buf),
12773 "/opt/pigpio/cgi/%s %s", scriptName, scriptString);
12774
12775 DBG(DBG_USER, "%s", buf);
12776
12777 status = system(buf);
12778
12779 if (status < 0) status = PI_BAD_SHELL_STATUS;
12780
12781 return status;
12782 }
12783
12784
12785 int fileApprove(char *filename)
12786 {
12787 char match[PI_MAX_PATH];
12788 char buffer[PI_MAX_PATH];
12789 char line[PI_MAX_PATH];
12790 char mperm=0;
12791 char perm;
12792 char term;
12793 FILE *f;
12794
12795 buffer[0] = 0;
12796 match[0] = 0;
12797
12798 f = fopen("/opt/pigpio/access", "r");
12799
12800 if (!f) return PI_FILE_NONE;
12801
12802 while (!feof(f))
12803 {
12804 buffer[0] = 0;
12805 perm = 0;
12806 term = 0;
12807 if (fgets(line, sizeof(line), f))
12808 {
12809 sscanf(line, " %511s %c%c", buffer, &perm, &term);
12810 if (term == 10)
12811 {
12812 if (myPathBad(buffer)) continue;
12813
12814 if (fnmatch(buffer, filename, 0) == 0)
12815 {
12816 if (match[0])
12817 {
12818 if (fnmatch(match, buffer, 0) == 0)
12819 {
12820 strcpy(match, buffer);
12821 mperm = perm;
12822 }
12823 }
12824 else
12825 {
12826 strcpy(match, buffer);
12827 mperm = perm;
12828 }
12829 }
12830 }
12831 }
12832 }
12833
12834 fclose(f);
12835
12836 if (match[0])
12837 {
12838 switch (toupper(mperm))
12839 {
12840 case 'R': return PI_FILE_READ;
12841 case 'W': return PI_FILE_WRITE;
12842 case 'U': return PI_FILE_RW;
12843 default : return PI_FILE_NONE;
12844 }
12845 }
12846
12847 return PI_FILE_NONE;
12848 }
12849
12850 int fileOpen(char *file, unsigned mode)
12851 {
12852 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
12853 int fd=-1;
12854 int i, slot, oflag, omode;
12855 struct stat statbuf;
12856
12857 DBG(DBG_USER, "file=%s mode=%d", file, mode);
12858
12859 CHECK_INITED;
12860
12861 if ( (mode < PI_FILE_MIN) ||
12862 (mode > PI_FILE_MAX) ||
12863 ((mode & PI_FILE_RW) == 0) )
12864 SOFT_ERROR(PI_BAD_FILE_MODE, "bad mode (%d)", mode);
12865
12866 if ((fileApprove(file) & mode) == PI_FILE_NONE)
12867 SOFT_ERROR(PI_NO_FILE_ACCESS, "no permission to access file (%s)", file);
12868
12869 slot = -1;
12870
12871 pthread_mutex_lock(&mutex);
12872
12873 for (i=0; i<PI_FILE_SLOTS; i++)
12874 {
12875 if (fileInfo[i].state == PI_FILE_CLOSED)
12876 {
12877 slot = i;
12878 fileInfo[slot].state = PI_FILE_RESERVED;
12879 break;
12880 }
12881 }
12882
12883 pthread_mutex_unlock(&mutex);
12884
12885 if (slot < 0) SOFT_ERROR(PI_NO_HANDLE, "no file handles");
12886
12887 omode = 0;
12888 oflag = 0;
12889
12890 if (mode & PI_FILE_APPEND)
12891 {
12892 mode |= PI_FILE_WRITE;
12893 oflag |= O_APPEND;
12894 }
12895
12896 if (mode & PI_FILE_CREATE)
12897 {
12898 oflag |= O_CREAT;
12899 omode |= (S_IRUSR|S_IWUSR);
12900 }
12901
12902 if (mode & PI_FILE_TRUNC)
12903 {
12904 mode |= PI_FILE_WRITE;
12905 oflag |= O_TRUNC;
12906 }
12907
12908 switch(mode&PI_FILE_RW)
12909 {
12910 case PI_FILE_READ:
12911 fd = open(file, O_RDONLY|oflag, omode);
12912 break;
12913
12914 case PI_FILE_WRITE:
12915 fd = open(file, O_WRONLY|oflag, omode);
12916 break;
12917
12918 case PI_FILE_RW:
12919 fd = open(file, O_RDWR|oflag, omode);
12920 break;
12921 }
12922
12923 if (fd == -1)
12924 {
12925 fileInfo[slot].state = PI_FILE_CLOSED;
12926 return PI_FIL_OPEN_FAILED;
12927 }
12928 else
12929 {
12930 if (stat(file, &statbuf) == 0)
12931 {
12932 if (S_ISDIR(statbuf.st_mode))
12933 {
12934 close(fd);
12935 fileInfo[slot].state = PI_FILE_CLOSED;
12936 SOFT_ERROR(PI_FILE_IS_A_DIR, "file is a directory (%s)", file);
12937 }
12938 }
12939 }
12940
12941 fileInfo[slot].fd = fd;
12942 fileInfo[slot].mode = mode;
12943 fileInfo[slot].state = PI_FILE_OPENED;
12944
12945 return slot;
12946 }
12947
12948 int fileClose(unsigned handle)
12949 {
12950 DBG(DBG_USER, "handle=%d", handle);
12951
12952 CHECK_INITED;
12953
12954 if (handle >= PI_FILE_SLOTS)
12955 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12956
12957 if (fileInfo[handle].state != PI_FILE_OPENED)
12958 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12959
12960 if (fileInfo[handle].fd >= 0) close(fileInfo[handle].fd);
12961
12962 fileInfo[handle].fd = -1;
12963 fileInfo[handle].state = PI_FILE_CLOSED;
12964
12965 return 0;
12966 }
12967
12968 int fileWrite(unsigned handle, char *buf, unsigned count)
12969 {
12970 int w;
12971
12972 DBG(DBG_USER, "handle=%d count=%d [%s]",
12973 handle, count, myBuf2Str(count, buf));
12974
12975 CHECK_INITED;
12976
12977 if (handle >= PI_FILE_SLOTS)
12978 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12979
12980 if (fileInfo[handle].state != PI_FILE_OPENED)
12981 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
12982
12983 if (!count)
12984 SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
12985
12986 if (!(fileInfo[handle].mode & PI_FILE_WRITE))
12987 SOFT_ERROR(PI_FILE_NOT_WOPEN, "file not opened for write");
12988
12989 w = write(fileInfo[handle].fd, buf, count);
12990
12991 if (w != count)
12992 {
12993 if (w == -1) DBG(DBG_USER, "write failed with errno %d", errno);
12994
12995 return PI_BAD_FILE_WRITE;
12996 }
12997 return 0;
12998 }
12999
13000 int fileRead(unsigned handle, char *buf, unsigned count)
13001 {
13002 int r;
13003
13004 DBG(DBG_USER, "handle=%d count=%d buf=0x%X", handle, count, (unsigned)buf);
13005
13006 CHECK_INITED;
13007
13008 if (handle >= PI_FILE_SLOTS)
13009 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13010
13011 if (fileInfo[handle].state != PI_FILE_OPENED)
13012 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13013
13014 if (!count)
13015 SOFT_ERROR(PI_BAD_PARAM, "bad count (%d)", count);
13016
13017 if (!(fileInfo[handle].mode & PI_FILE_READ))
13018 SOFT_ERROR(PI_FILE_NOT_ROPEN, "file not opened for read");
13019
13020 r = read(fileInfo[handle].fd, buf, count);
13021
13022 if (r == -1)
13023 {
13024 DBG(DBG_USER, "read failed with errno %d", errno);
13025 return PI_BAD_FILE_READ;
13026 }
13027 else
13028 {
13029 buf[r] = 0;
13030 return r;
13031 }
13032 }
13033
13034
13035 int fileSeek(unsigned handle, int32_t seekOffset, int seekFrom)
13036 {
13037 int whence, s;
13038
13039 DBG(DBG_USER, "handle=%d offset=%d from=%d",
13040 handle, seekOffset, seekFrom);
13041
13042 CHECK_INITED;
13043
13044 if (handle >= PI_FILE_SLOTS)
13045 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13046
13047 if (fileInfo[handle].state != PI_FILE_OPENED)
13048 SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle);
13049
13050 switch (seekFrom)
13051 {
13052 case PI_FROM_START:
13053 whence = SEEK_SET;
13054 break;
13055
13056 case PI_FROM_CURRENT:
13057 whence = SEEK_CUR;
13058 break;
13059
13060 case PI_FROM_END:
13061 whence = SEEK_END;
13062 break;
13063
13064 default:
13065 SOFT_ERROR(PI_BAD_FILE_SEEK, "bad seek from (%d)", seekFrom);
13066 }
13067
13068 s = lseek(fileInfo[handle].fd, seekOffset, whence);
13069
13070 if (s == -1)
13071 {
13072 DBG(DBG_USER, "seek failed with errno %d", errno);
13073 return PI_BAD_FILE_SEEK;
13074 }
13075
13076 return s;
13077 }
13078
13079 int fileList(char *fpat, char *buf, unsigned count)
13080 {
13081 int len, bufpos;
13082 glob_t pglob;
13083 int i;
13084
13085 DBG(DBG_USER, "fpat=%s count=%d buf=%x", fpat, count, (unsigned)buf);
13086
13087 CHECK_INITED;
13088
13089 if (fileApprove(fpat) == PI_FILE_NONE)
13090 SOFT_ERROR(PI_NO_FILE_ACCESS, "no permission to access file (%s)", fpat);
13091
13092 bufpos = 0;
13093
13094 if (glob(fpat, GLOB_MARK, NULL, &pglob) == 0)
13095 {
13096 for (i=0; i<pglob.gl_pathc; i++)
13097 {
13098 len = strlen(pglob.gl_pathv[i]);
13099 if ((bufpos + len + 1) < count)
13100 {
13101 strcpy(buf+bufpos, pglob.gl_pathv[i]);
13102 bufpos += len;
13103 buf[bufpos++] = '\n';
13104 }
13105 }
13106 }
13107 else
13108 {
13109 bufpos = PI_NO_FILE_MATCH;
13110 }
13111
13112 globfree(&pglob);
13113
13114 return bufpos;
13115 }
13116
13117
13118
13119
13120
13121 int gpioTime(unsigned timetype, int *seconds, int *micros)
13122 {
13123 struct timespec ts;
13124
13125 DBG(DBG_USER, "timetype=%d &seconds=%08X µs=%08X",
13126 timetype, (uint32_t)seconds, (uint32_t)micros);
13127
13128 CHECK_INITED;
13129
13130 if (timetype > PI_TIME_ABSOLUTE)
13131 SOFT_ERROR(PI_BAD_TIMETYPE, "bad timetype (%d)", timetype);
13132
13133 if (timetype == PI_TIME_ABSOLUTE)
13134 {
13135 clock_gettime(CLOCK_REALTIME, &ts);
13136 *seconds = ts.tv_sec;
13137 *micros = ts.tv_nsec/1000;
13138 }
13139 else
13140 {
13141 clock_gettime(CLOCK_REALTIME, &ts);
13142
13143 TIMER_SUB(&ts, &libStarted, &ts);
13144
13145 *seconds = ts.tv_sec;
13146 *micros = ts.tv_nsec/1000;
13147 }
13148
13149 return 0;
13150 }
13151
13152
13153
13154
13155 int gpioSleep(unsigned timetype, int seconds, int micros)
13156 {
13157 struct timespec ts, rem;
13158
13159 DBG(DBG_USER, "timetype=%d seconds=%d micros=%d",
13160 timetype, seconds, micros);
13161
13162 CHECK_INITED;
13163
13164 if (timetype > PI_TIME_ABSOLUTE)
13165 SOFT_ERROR(PI_BAD_TIMETYPE, "bad timetype (%d)", timetype);
13166
13167 if (seconds < 0)
13168 SOFT_ERROR(PI_BAD_SECONDS, "bad seconds (%d)", seconds);
13169
13170 if ((micros < 0) || (micros > 999999))
13171 SOFT_ERROR(PI_BAD_MICROS, "bad micros (%d)", micros);
13172
13173 ts.tv_sec = seconds;
13174 ts.tv_nsec = micros * 1000;
13175
13176 if (timetype == PI_TIME_ABSOLUTE)
13177 {
13178 while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &ts, &rem));
13179 }
13180 else
13181 {
13182 while (clock_nanosleep(CLOCK_REALTIME, 0, &ts, &rem))
13183 {
13184
13185 ts.tv_sec = rem.tv_sec;
13186 ts.tv_nsec = rem.tv_nsec;
13187 }
13188 }
13189
13190 return 0;
13191 }
13192
13193
13194
13195
13196 uint32_t gpioDelay(uint32_t micros)
13197 {
13198 uint32_t start;
13199
13200 DBG(DBG_USER, "microseconds=%u", micros);
13201
13202 CHECK_INITED;
13203
13204 start = systReg[SYST_CLO];
13205
13206 if (micros <= PI_MAX_BUSY_DELAY)
13207 while ((systReg[SYST_CLO] - start) <= micros);
13208 else
13209 gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION));
13210
13211 return (systReg[SYST_CLO] - start);
13212 }
13213
13214
13215
13216
13217 uint32_t gpioTick(void)
13218 {
13219 CHECK_INITED;
13220
13221 return systReg[SYST_CLO];
13222 }
13223
13224
13225
13226
13227 unsigned gpioVersion(void)
13228 {
13229 DBG(DBG_USER, "");
13230
13231 return PIGPIO_VERSION;
13232 }
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259 unsigned gpioHardwareRevision(void)
13260 {
13261 static unsigned rev = 0;
13262
13263 FILE * filp;
13264 char buf[512];
13265 char term;
13266
13267 DBG(DBG_USER, "");
13268
13269 if (rev) return rev;
13270
13271 piCores = 0;
13272
13273 filp = fopen ("/proc/cpuinfo", "r");
13274
13275 if (filp != NULL)
13276 {
13277 while (fgets(buf, sizeof(buf), filp) != NULL)
13278 {
13279 if (piCores == 0)
13280 {
13281 if (!strncasecmp("model name", buf, 10))
13282 {
13283 if (strstr (buf, "ARMv6") != NULL)
13284 {
13285 piCores = 1;
13286 pi_peri_phys = 0x20000000;
13287 pi_dram_bus = 0x40000000;
13288 pi_mem_flag = 0x0C;
13289 }
13290 else if (strstr (buf, "ARMv7") != NULL)
13291 {
13292 piCores = 4;
13293 pi_peri_phys = 0x3F000000;
13294 pi_dram_bus = 0xC0000000;
13295 pi_mem_flag = 0x04;
13296 }
13297 else if (strstr (buf, "ARMv8") != NULL)
13298 {
13299 piCores = 4;
13300 pi_peri_phys = 0x3F000000;
13301 pi_dram_bus = 0xC0000000;
13302 pi_mem_flag = 0x04;
13303 }
13304 }
13305 }
13306
13307 if (!strncasecmp("revision\t:", buf, 10))
13308 {
13309 if (sscanf(buf+10, "%x%c", &rev, &term) == 2)
13310 {
13311 if (term != '\n') rev = 0;
13312 else rev &= 0xFFFFFF;
13313 }
13314 }
13315 }
13316
13317 fclose(filp);
13318 }
13319 return rev;
13320 }
13321
13322
13323
13324
13325 int gpioCfgBufferSize(unsigned millis)
13326 {
13327 DBG(DBG_USER, "millis=%d", millis);
13328
13329 CHECK_NOT_INITED;
13330
13331 if ((millis < PI_BUF_MILLIS_MIN) || (millis > PI_BUF_MILLIS_MAX))
13332 SOFT_ERROR(PI_BAD_BUF_MILLIS, "bad millis (%d)", millis);
13333
13334 gpioCfg.bufferMilliseconds = millis;
13335
13336 return 0;
13337 }
13338
13339
13340
13341
13342 int gpioCfgClock(unsigned micros, unsigned peripheral, unsigned source)
13343 {
13344 DBG(DBG_USER, "micros=%d peripheral=%d", micros, peripheral);
13345
13346 CHECK_NOT_INITED;
13347
13348 if ((micros < 1) || (micros > 10))
13349 SOFT_ERROR(PI_BAD_CLK_MICROS, "bad micros (%d)", micros);
13350
13351 if (!clkCfg[micros].valid)
13352 SOFT_ERROR(PI_BAD_CLK_MICROS, "bad micros (%d)", micros);
13353
13354 if (peripheral > PI_CLOCK_PCM)
13355 SOFT_ERROR(PI_BAD_CLK_PERIPH, "bad peripheral (%d)", peripheral);
13356
13357 gpioCfg.clockMicros = micros;
13358 gpioCfg.clockPeriph = peripheral;
13359
13360 return 0;
13361 }
13362
13363
13364
13365
13366 int gpioCfgDMAchannel(unsigned DMAchannel)
13367 {
13368 DBG(DBG_USER, "channel=%d", DMAchannel);
13369
13370 CHECK_NOT_INITED;
13371
13372 if ((DMAchannel < PI_MIN_DMA_CHANNEL) || (DMAchannel > PI_MAX_DMA_CHANNEL))
13373 SOFT_ERROR(PI_BAD_CHANNEL, "bad channel (%d)", DMAchannel);
13374
13375 gpioCfg.DMAprimaryChannel = DMAchannel;
13376
13377 return 0;
13378 }
13379
13380
13381
13382
13383 int gpioCfgDMAchannels(unsigned primaryChannel, unsigned secondaryChannel)
13384 {
13385 DBG(DBG_USER, "primary channel=%d, secondary channel=%d",
13386 primaryChannel, secondaryChannel);
13387
13388 CHECK_NOT_INITED;
13389
13390 if (primaryChannel > PI_MAX_DMA_CHANNEL)
13391 SOFT_ERROR(PI_BAD_PRIM_CHANNEL, "bad primary channel (%d)",
13392 primaryChannel);
13393
13394 if ((secondaryChannel > PI_MAX_DMA_CHANNEL) ||
13395 (secondaryChannel == primaryChannel))
13396 SOFT_ERROR(PI_BAD_SECO_CHANNEL, "bad secondary channel (%d)",
13397 secondaryChannel);
13398
13399 gpioCfg.DMAprimaryChannel = primaryChannel;
13400 gpioCfg.DMAsecondaryChannel = secondaryChannel;
13401
13402 return 0;
13403 }
13404
13405
13406
13407
13408 int gpioCfgPermissions(uint64_t updateMask)
13409 {
13410 DBG(DBG_USER, "gpio update mask=%llX", updateMask);
13411
13412 CHECK_NOT_INITED;
13413
13414 gpioMask = updateMask;
13415
13416 gpioMaskSet = 1;
13417
13418 return 0;
13419 }
13420
13421
13422
13423
13424 int gpioCfgInterfaces(unsigned ifFlags)
13425 {
13426 DBG(DBG_USER, "ifFlags=%X", ifFlags);
13427
13428 CHECK_NOT_INITED;
13429
13430 if (ifFlags > 15)
13431 SOFT_ERROR(PI_BAD_IF_FLAGS, "bad ifFlags (%X)", ifFlags);
13432
13433 gpioCfg.ifFlags = ifFlags;
13434
13435 return 0;
13436 }
13437
13438
13439
13440 int gpioCfgSocketPort(unsigned port)
13441 {
13442 DBG(DBG_USER, "port=%d", port);
13443
13444 CHECK_NOT_INITED;
13445
13446 if ((port < PI_MIN_SOCKET_PORT) || (port > PI_MAX_SOCKET_PORT))
13447 SOFT_ERROR(PI_BAD_SOCKET_PORT, "bad port (%d)", port);
13448
13449 gpioCfg.socketPort = port;
13450
13451 return 0;
13452 }
13453
13454
13455
13456
13457 int gpioCfgMemAlloc(unsigned memAllocMode)
13458 {
13459 DBG(DBG_USER, "memAllocMode=%d", memAllocMode);
13460
13461 CHECK_NOT_INITED;
13462
13463 if (memAllocMode > PI_MEM_ALLOC_MAILBOX)
13464 SOFT_ERROR(
13465 PI_BAD_MALLOC_MODE, "bad mem alloc mode (%d)", memAllocMode);
13466
13467 gpioCfg.memAllocMode = memAllocMode;
13468
13469 return 0;
13470 }
13471
13472
13473
13474 int gpioCfgNetAddr(int numSockAddr, uint32_t *sockAddr)
13475 {
13476 int i;
13477
13478 DBG(DBG_USER, "numSockAddr=%d sockAddr=%08X",
13479 numSockAddr, (unsigned)sockAddr);
13480
13481 CHECK_NOT_INITED;
13482
13483 if (numSockAddr <= 0) numSockNetAddr = 0;
13484 else
13485 {
13486 if (numSockAddr >= MAX_CONNECT_ADDRESSES)
13487 numSockAddr = MAX_CONNECT_ADDRESSES;
13488
13489 for (i=0; i<numSockAddr; i++) sockNetAddr[i] = sockAddr[i];
13490
13491 numSockNetAddr = numSockAddr;
13492 }
13493 return 0;
13494 }
13495
13496
13497
13498
13499 uint32_t gpioCfgGetInternals(void)
13500 {
13501 return gpioCfg.internals;
13502 }
13503
13504 int gpioCfgSetInternals(uint32_t cfgVal)
13505 {
13506 gpioCfg.internals = cfgVal;
13507 gpioCfg.dbgLevel = cfgVal & 0xF;
13508 gpioCfg.alertFreq = (cfgVal>>4) & 0xF;
13509 return 0;
13510 }
13511
13512 int gpioCfgInternals(unsigned cfgWhat, unsigned cfgVal)
13513 {
13514 int retVal = PI_BAD_CFG_INTERNAL;
13515
13516 DBG(DBG_USER, "cfgWhat=%u, cfgVal=%d", cfgWhat, cfgVal);
13517
13518 switch(cfgWhat)
13519 {
13520 case 562484977:
13521
13522 if (cfgVal) gpioCfg.internals |= PI_CFG_STATS;
13523 else gpioCfg.internals &= (~PI_CFG_STATS);
13524
13525 DBG(DBG_ALWAYS, "show stats is %u", cfgVal);
13526
13527 retVal = 0;
13528
13529 break;
13530
13531 case 984762879:
13532
13533 if ((cfgVal >= DBG_ALWAYS) && (cfgVal <= DBG_MAX_LEVEL))
13534 {
13535
13536 gpioCfg.dbgLevel = cfgVal;
13537 gpioCfg.internals = (gpioCfg.internals & (~0xF)) | cfgVal;
13538
13539 DBG(DBG_ALWAYS, "Debug level is %u", cfgVal);
13540
13541 retVal = 0;
13542 }
13543
13544 break;
13545 }
13546
13547 return retVal;
13548 }
13549
13550
13551
13552
13553 #include "custom.cext"
13554