diff --git a/Makefile b/Makefile index 08856bd..2cfc4b8 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,8 @@ install: $(LIB) sudo install -m 0755 pig2vcd /usr/local/bin sudo install -m 0755 pigpiod /usr/local/bin sudo install -m 0755 pigs /usr/local/bin - sudo python setup.py install + sudo python2 setup.py install + sudo python3 setup.py install sudo install -m 0755 -d /usr/local/man/man1 sudo install -m 0644 *.1 /usr/local/man/man1 sudo install -m 0755 -d /usr/local/man/man3 @@ -66,6 +67,12 @@ uninstall: sudo rm -f /usr/local/bin/pig2vcd sudo rm -f /usr/local/bin/pigpiod sudo rm -f /usr/local/bin/pigs + echo removing python2 files + sudo python2 setup.py install --record /tmp/pigpio >/dev/null + sudo xargs rm -f < /tmp/pigpio >/dev/null + echo removing python3 files + sudo python3 setup.py install --record /tmp/pigpio >/dev/null + sudo xargs rm -f < /tmp/pigpio >/dev/null sudo rm -f /usr/local/man/man1/pig*.1 sudo rm -f /usr/local/man/man3/pig*.3 diff --git a/command.c b/command.c index 06fc914..baa41eb 100644 --- a/command.c +++ b/command.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 31+ +This version is for pigpio version 32+ */ #include @@ -45,6 +45,10 @@ cmdInfo_t cmdInfo[]= {PI_CMD_BC1, "BC1", 111, 1}, // gpioWrite_Bits_0_31_Clear {PI_CMD_BC2, "BC2", 111, 1}, // gpioWrite_Bits_32_53_Clear + {PI_CMD_BI2CC, "BI2CC", 112, 0}, // bbI2CClose + {PI_CMD_BI2CO, "BI2CO", 131, 0}, // bbI2COpen + {PI_CMD_BI2CX, "BI2CX", 193, 6}, // bbI2CXfer + {PI_CMD_BR1, "BR1", 101, 3}, // gpioRead_Bits_0_31 {PI_CMD_BR2, "BR2", 101, 3}, // gpioRead_Bits_32_53 @@ -86,6 +90,8 @@ cmdInfo_t cmdInfo[]= {PI_CMD_I2CWS, "I2CWS", 121, 0}, // i2cWriteByte {PI_CMD_I2CWW, "I2CWW", 131, 0}, // i2cWriteWordData + {PI_CMD_I2CX, "I2CX", 131, 0}, // i2cXfer + {PI_CMD_MICS, "MICS", 112, 0}, // gpioDelay {PI_CMD_MILS, "MILS", 112, 0}, // gpioDelay @@ -243,23 +249,23 @@ HWVER Get hardware version\n\ I2CC h Close I2C handle\n\ I2CO ib id if Open I2C bus and device with flags\n\ \n\ -I2CPC h r wv smb Process Call: exchange register with word\n\ -I2CPK h r bvs smb Block Process Call: exchange data bytes with register\n\ +I2CPC h r wv SMBus Process Call: exchange register with word\n\ +I2CPK h r bvs SMBus Block Process Call: exchange data bytes with register\n\ \n\ -I2CRB h r smb Read Byte Data: read byte from register\n\ +I2CRB h r SMBus Read Byte Data: read byte from register\n\ I2CRD h num i2c Read bytes\n\ -I2CRI h r num smb Read I2C Block Data: read bytes from register\n\ -I2CRK h r smb Read Block Data: read data from register\n\ -I2CRS h smb Read Byte: read byte\n\ -I2CRW h r smb Read Word Data: read word from register\n\ +I2CRI h r num SMBus Read I2C Block Data: read bytes from register\n\ +I2CRK h r SMBus Read Block Data: read data from register\n\ +I2CRS h SMBus Read Byte: read byte\n\ +I2CRW h r SMBus Read Word Data: read word from register\n\ \n\ -I2CWB h r bv smb Write Byte Data: write byte to register\n\ +I2CWB h r bv SMBus Write Byte Data: write byte to register\n\ I2CWD h bvs i2c Write data\n\ -I2CWI h r bvs smb Write I2C Block Data\n\ -I2CWK h r bvs smb Write Block Data: write data to register\n\ -I2CWQ h bit smb Write Quick: write bit\n\ -I2CWS h bv smb Write Byte: write byte\n\ -I2CWW h r wv smb Write Word Data: write word to register\n\ +I2CWI h r bvs SMBus Write I2C Block Data\n\ +I2CWK h r bvs SMBus Write Block Data: write data to register\n\ +I2CWQ h bit SMBus Write Quick: write bit\n\ +I2CWS h bv SMBus Write Byte: write byte\n\ +I2CWW h r wv SMBus Write Word Data: write word to register\n\ \n\ M/MODES g m Set gpio mode\n\ MG/MODEG g Get gpio mode\n\ @@ -428,7 +434,7 @@ static errInfo_t errInfo[]= {PI_BAD_WAVE_BAUD , "baud rate not 50-250K(RX)/50-1M(TX)"}, {PI_TOO_MANY_PULSES , "waveform has too many pulses"}, {PI_TOO_MANY_CHARS , "waveform has too many chars"}, - {PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"}, + {PI_NOT_SERIAL_GPIO , "no bit bang serial read in progress on gpio"}, {PI_BAD_SERIAL_STRUC , "bad (null) serial structure parameter"}, {PI_BAD_SERIAL_BUF , "bad (null) serial buf parameter"}, {PI_NOT_PERMITTED , "no permission to update gpio"}, @@ -496,6 +502,8 @@ static errInfo_t errInfo[]= {PI_BAD_MALLOC_MODE , "bad memory allocation mode"}, {PI_TOO_MANY_PARTS , "too many I2C transaction parts"}, {PI_BAD_I2C_PART , "a combined I2C transaction failed"}, + {PI_BAD_SMBUS_CMD , "SMBus command not supported by driver"}, + {PI_NOT_I2C_GPIO , "no bit bang I2C in progress on gpio"}, }; @@ -616,7 +624,7 @@ int cmdParse( break; - case 112: /* GDC GPW I2CC + case 112: /* BI2CC GDC GPW I2CC I2CRB MG MICS MILS MODEG NC NP PFG PRG PROCD PROCP PROCS PRRG R READ SLRC SPIC WVDEL WVSC WVSM WVSP WVTX WVTXR @@ -787,7 +795,8 @@ int cmdParse( break; - case 131: /* HP I2CO I2CPC I2CRI I2CWB I2CWW SLRO SPIO TRIG + case 131: /* BI2CO HP I2CO I2CPC I2CRI I2CWB I2CWW SLRO + SPIO TRIG Three positive parameters. */ @@ -884,7 +893,7 @@ int cmdParse( break; - case 193: /* I2CWD SERW + case 193: /* BI2CX I2CWD SERW SPIW SPIX Two or more parameters, first >=0, rest 0-255. */ diff --git a/pigpio.3 b/pigpio.3 index 08c5dd9..38180c5 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -2065,7 +2065,7 @@ PI_BAD_FLAGS, PI_NO_HANDLE, or PI_I2C_OPEN_FAILED. .br .br -For the smbus commands the low level transactions are shown at the end +For the SMBus commands the low level transactions are shown at the end of the function description. The following abbreviations are used. .br @@ -2191,7 +2191,7 @@ PI_I2C_WRITE_FAILED. .br .br -Quick command. smbus 2.0 5.5.1 +Quick command. SMBus 2.0 5.5.1 .EX S Addr Rd/Wr [A] P @@ -2224,7 +2224,7 @@ PI_I2C_WRITE_FAILED. .br .br -Send byte. smbus 2.0 5.5.2 +Send byte. SMBus 2.0 5.5.2 .EX S Addr Wr [A] Data [A] P @@ -2255,7 +2255,7 @@ or PI_I2C_READ_FAILED. .br .br -Receive byte. smbus 2.0 5.5.3 +Receive byte. SMBus 2.0 5.5.3 .EX S Addr Rd [A] [Data] NA P @@ -2291,7 +2291,7 @@ PI_I2C_WRITE_FAILED. .br .br -Write byte. smbus 2.0 5.5.4 +Write byte. SMBus 2.0 5.5.4 .EX S Addr Wr [A] Comm [A] Data [A] P @@ -2327,7 +2327,7 @@ PI_I2C_WRITE_FAILED. .br .br -Write word. smbus 2.0 5.5.4 +Write word. SMBus 2.0 5.5.4 .EX S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P @@ -2361,7 +2361,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED. .br .br -Read byte. smbus 2.0 5.5.5 +Read byte. SMBus 2.0 5.5.5 .EX S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P @@ -2395,7 +2395,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED. .br .br -Read word. smbus 2.0 5.5.5 +Read word. SMBus 2.0 5.5.5 .EX S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P @@ -2431,7 +2431,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED. .br .br -Process call. smbus 2.0 5.5.6 +Process call. SMBus 2.0 5.5.6 .EX S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] @@ -2471,7 +2471,7 @@ PI_I2C_WRITE_FAILED. .br .br -Block write. smbus 2.0 5.5.7 +Block write. SMBus 2.0 5.5.7 .EX S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P @@ -2512,7 +2512,7 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED. .br .br -Block read. smbus 2.0 5.5.7 +Block read. SMBus 2.0 5.5.7 .EX S Addr Wr [A] Comm [A] @@ -2553,14 +2553,14 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED. .br .br -The smbus 2.0 documentation states that a minimum of 1 byte may be +The SMBus 2.0 documentation states that a minimum of 1 byte may be sent and a minimum of 1 byte may be received. The total number of bytes sent/received must be 32 or less. .br .br -Block write-block read. smbus 2.0 5.5.8 +Block write-block read. SMBus 2.0 5.5.8 .EX S Addr Wr [A] Comm [A] Count [A] Data [A] ... @@ -6815,6 +6815,18 @@ A 16-bit word value. #define PI_CMD_CF2 88 .br +.br +#define PI_CMD_BI2CC 89 +.br +#define PI_CMD_BI2CO 90 +.br +#define PI_CMD_BI2CX 91 +.br + +.br +#define PI_CMD_I2CX 92 +.br + .br #define PI_CMD_NOIB 99 .br @@ -6905,7 +6917,7 @@ A 16-bit word value. .br #define PI_TOO_MANY_CHARS -37 // waveform has too many chars .br -#define PI_NOT_SERIAL_GPIO -38 // no serial read in progress on gpio +#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read in progress on gpio .br #define PI_BAD_SERIAL_STRUC -39 // bad (null) serial structure parameter .br @@ -7043,7 +7055,15 @@ A 16-bit word value. .br #define PI_BAD_I2C_PART -106 // a combined I2C transaction failed .br - +#define PI_BAD_SMBUS_CMD -107 // SMBus command not supported by driver +.br +#define PI_NOT_I2C_GPIO -108 // no bit bang I2C in progress on gpio +.br +#define PI_BAD_BB_WLEN -109 // bad BB write length +.br +#define PI_BAD_BB_RLEN -110 // bad BB read length +.br +#define PI_BAD_BB_CMD -111 // bad BB command .br .br @@ -7092,7 +7112,7 @@ A 16-bit word value. .br #define PI_DEFAULT_UPDATE_MASK_R2 0xFBC7CF9C .br -#define PI_DEFAULT_UPDATE_MASK_R3 0x0080400FFFFFFCLL +#define PI_DEFAULT_UPDATE_MASK_R3 0x0080480FFFFFFCLL .br #define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL .br diff --git a/pigpio.c b/pigpio.c index 920cb2f..b0fcaae 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 31 */ +/* pigpio version 32 */ /* include ------------------------------------------------------- */ @@ -204,6 +204,7 @@ bit 0 READ_LAST_NOT_SET_ERROR } #define CHECK_INITED \ + do \ { \ if (!libInitialised) \ { \ @@ -212,8 +213,10 @@ bit 0 READ_LAST_NOT_SET_ERROR return PI_NOT_INITIALISED; \ } \ } \ + while (0) #define CHECK_INITED_RET_NULL_PTR \ + do \ { \ if (!libInitialised) \ { \ @@ -222,8 +225,10 @@ bit 0 READ_LAST_NOT_SET_ERROR return (NULL); \ } \ } \ + while (0) #define CHECK_INITED_RET_NIL \ + do \ { \ if (!libInitialised) \ { \ @@ -231,8 +236,10 @@ bit 0 READ_LAST_NOT_SET_ERROR "pigpio uninitialised, call gpioInitialise()"); \ } \ } \ + while (0) #define CHECK_NOT_INITED \ + do \ { \ if (libInitialised) \ { \ @@ -241,14 +248,18 @@ bit 0 READ_LAST_NOT_SET_ERROR return PI_INITIALISED; \ } \ } \ + while (0) #define SOFT_ERROR(x, format, arg...) \ + do \ { \ DBG(DBG_ALWAYS, format, ## arg); \ return x; \ } \ + while (0) #define TIMER_ADD(a, b, result) \ + do \ { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \ @@ -258,8 +269,10 @@ bit 0 READ_LAST_NOT_SET_ERROR (result)->tv_nsec -= BILLION; \ } \ } \ + while (0) #define TIMER_SUB(a, b, result) \ + do \ { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \ @@ -269,6 +282,7 @@ bit 0 READ_LAST_NOT_SET_ERROR (result)->tv_nsec += BILLION; \ } \ } \ + while (0) #define PI_PERI_BUS 0x7E000000 @@ -688,8 +702,11 @@ bit 0 READ_LAST_NOT_SET_ERROR #define PI_NOTIFY_RUNNING 3 #define PI_NOTIFY_PAUSED 4 -#define PI_WFRX_NONE 0 -#define PI_WFRX_SERIAL 1 +#define PI_WFRX_NONE 0 +#define PI_WFRX_SERIAL 1 +#define PI_WFRX_I2C 2 +#define PI_WFRX_I2C_CLK 3 + #define PI_WF_MICROS 1 #define DATUMS 2000 @@ -700,9 +717,12 @@ bit 0 READ_LAST_NOT_SET_ERROR #define SRX_BUF_SIZE 8192 -#define PI_I2C_SLAVE 0x0703 -#define PI_I2C_RDWR 0x0707 -#define PI_I2C_SMBUS 0x0720 +#define PI_I2C_RETRIES 0x0701 +#define PI_I2C_TIMEOUT 0x0702 +#define PI_I2C_SLAVE 0x0703 +#define PI_I2C_FUNCS 0x0705 +#define PI_I2C_RDWR 0x0707 +#define PI_I2C_SMBUS 0x0720 #define PI_I2C_SMBUS_READ 1 #define PI_I2C_SMBUS_WRITE 0 @@ -720,6 +740,19 @@ bit 0 READ_LAST_NOT_SET_ERROR #define PI_I2C_SMBUS_BLOCK_MAX 32 #define PI_I2C_SMBUS_I2C_BLOCK_MAX 32 +#define PI_I2C_FUNC_SMBUS_QUICK 0x00010000 +#define PI_I2C_FUNC_SMBUS_READ_BYTE 0x00020000 +#define PI_I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +#define PI_I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 +#define PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 +#define PI_I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 +#define PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 +#define PI_I2C_FUNC_SMBUS_PROC_CALL 0x00800000 +#define PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 +#define PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 +#define PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 +#define PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 + #define PI_MASH_MAX_FREQ 23800000 #define FLUSH_PAGES 1024 @@ -764,6 +797,10 @@ bit 0 READ_LAST_NOT_SET_ERROR #define PI_SPI_FLAGS_GET_CSPOLS(x) (((x)>>2)&7) #define PI_SPI_FLAGS_GET_MODE(x) ((x)&3) +#define PI_STARTING 0 +#define PI_RUNNING 1 +#define PI_ENDING 2 + /* typedef ------------------------------------------------------- */ typedef void (*callbk_t) (); @@ -862,6 +899,7 @@ typedef struct uint16_t seqno; uint16_t state; uint32_t bits; + uint32_t lastReportTick; int fd; int pipe; } gpioNotify_t; @@ -871,6 +909,7 @@ typedef struct uint16_t state; int16_t fd; uint32_t flags; + uint32_t funcs; } i2cInfo_t; typedef struct @@ -931,12 +970,10 @@ typedef struct typedef struct { - int gpio; char *buf; uint32_t bufSize; int readPos; int writePos; - uint32_t baud; /* 50-250000 */ uint32_t fullBit; /* nanoseconds */ uint32_t halfBit; /* nanoseconds */ int timeout; /* millisconds */ @@ -946,8 +983,29 @@ typedef struct uint32_t data; int bytes; /* 1, 2, 4 */ int level; - int mode; int dataBits; /* 1-32 */ +} wfRxSerial_t; + +typedef struct +{ + int SDA; + int SCL; + int delay; + int SDAMode; + int SCLMode; + int started; +} wfRxI2C_t; + +typedef struct +{ + int mode; + int gpio; + uint32_t baud; /* 50-250000 */ + union + { + wfRxSerial_t s; + wfRxI2C_t I; + }; } wfRx_t; union my_smbus_data @@ -1038,8 +1096,7 @@ static volatile uint32_t monitorBits = 0; static volatile uint32_t notifyBits = 0; static volatile uint32_t scriptBits = 0; -static volatile int DMAstarted = 0; -static volatile int terminating = 0; +static volatile int runState = PI_STARTING; static int pthAlertRunning = 0; static int pthFifoRunning = 0; @@ -1278,11 +1335,33 @@ static char * myTimeStamp() /* ----------------------------------------------------------------------- */ +static char *myBuf2Str(unsigned count, char *buf) +{ + static char str[128]; + int i, c; + + if (count && buf) + { + if (count > 40) c = 40; else c = count; + + for (i=0; ibyte+1, (char*)data)); + args.read_write = rw; args.command = cmd; args.size = size; @@ -1293,23 +1372,18 @@ static int my_smbus_access( /* ----------------------------------------------------------------------- */ -static char *myBuf2Str(unsigned count, char *buf) +static void myGpioSetMode(unsigned gpio, unsigned mode) { - static char str[64]; - int i, c; + int reg, shift; - if (count) - { - if (count > 10) c = 10; else c = count; + reg = gpio/10; + shift = (gpio%10) * 3; - for (i=0; i (bufSize/2)) p[3] = bufSize/2; + res = bbI2CXfer(p[1], buf, p[3], buf+(bufSize/2), bufSize/2); + if (res > 0) + { + memcpy(buf, buf+(bufSize/2), res); + } + break; + case PI_CMD_BR1: res = gpioRead_Bits_0_31(); break; case PI_CMD_BR2: res = gpioRead_Bits_32_53(); break; @@ -2164,7 +2255,7 @@ static unsigned mbAllocateMemory( p[i++] = align; p[i++] = flags; p[i++] = MB_END_TAG; - p[0] = i*sizeof *p; + p[0] = i*sizeof(*p); mbProperty(fd, p); @@ -2182,7 +2273,7 @@ static unsigned mbLockMemory(int fd, unsigned handle) p[i++] = 4; p[i++] = handle; p[i++] = MB_END_TAG; - p[0] = i*sizeof *p; + p[0] = i*sizeof(*p); mbProperty(fd, p); @@ -2200,7 +2291,7 @@ static unsigned mbUnlockMemory(int fd, unsigned handle) p[i++] = 4; p[i++] = handle; p[i++] = MB_END_TAG; - p[0] = i*sizeof *p; + p[0] = i*sizeof(*p); mbProperty(fd, p); @@ -2218,7 +2309,7 @@ static unsigned mbReleaseMemory(int fd, unsigned handle) p[i++] = 4; p[i++] = handle; p[i++] = MB_END_TAG; - p[0] = i*sizeof *p; + p[0] = i*sizeof(*p); mbProperty(fd, p); @@ -2608,56 +2699,57 @@ static int wave2Cbs(unsigned wave_mode) /* ----------------------------------------------------------------------- */ -static void waveRxSerial(wfRx_t *s, int level, uint32_t tick) +static void waveRxSerial(wfRx_t *w, int level, uint32_t tick) { int diffTicks, lastLevel; int newWritePos; - if (s->bit >= 0) + if (w->s.bit >= 0) { - diffTicks = tick - s->startBitTick; + diffTicks = tick - w->s.startBitTick; if (level != PI_TIMEOUT) { - s->level = level; + w->s.level = level; lastLevel = !level; } - else lastLevel = s->level; + else lastLevel = w->s.level; - while ((s->bit <= s->dataBits) && (diffTicks > (s->nextBitDiff/1000))) + while ((w->s.bit <= w->s.dataBits) && + (diffTicks > (w->s.nextBitDiff/1000))) { - if (s->bit) + if (w->s.bit) { - if (lastLevel) s->data |= (1<<(s->bit-1)); + if (lastLevel) w->s.data |= (1<<(w->s.bit-1)); } - else s->data = 0; + else w->s.data = 0; - ++(s->bit); + ++(w->s.bit); - s->nextBitDiff += s->fullBit; + w->s.nextBitDiff += w->s.fullBit; } - if (s->bit > s->dataBits) + if (w->s.bit > w->s.dataBits) { - memcpy(s->buf + s->writePos, &s->data, s->bytes); + memcpy(w->s.buf + w->s.writePos, &w->s.data, w->s.bytes); /* don't let writePos catch readPos */ - newWritePos = (s->writePos + s->bytes) % (s->bufSize); + newWritePos = (w->s.writePos + w->s.bytes) % (w->s.bufSize); - if (newWritePos != s->readPos) s->writePos = newWritePos; + if (newWritePos != w->s.readPos) w->s.writePos = newWritePos; if (level == 0) { - gpioSetWatchdog(s->gpio, s->timeout); - s->bit = 0; - s->startBitTick = tick; - s->nextBitDiff = s->halfBit; + gpioSetWatchdog(w->gpio, w->s.timeout); + w->s.bit = 0; + w->s.startBitTick = tick; + w->s.nextBitDiff = w->s.halfBit; } else { - s->bit = -1; - gpioSetWatchdog(s->gpio, 0); + w->s.bit = -1; + gpioSetWatchdog(w->gpio, 0); } } } @@ -2667,11 +2759,11 @@ static void waveRxSerial(wfRx_t *s, int level, uint32_t tick) if (level == 0) { - gpioSetWatchdog(s->gpio, s->timeout); - s->level = 0; - s->bit = 0; - s->startBitTick = tick; - s->nextBitDiff = s->halfBit; + gpioSetWatchdog(w->gpio, w->s.timeout); + w->s.level = 0; + w->s.bit = 0; + w->s.startBitTick = tick; + w->s.nextBitDiff = w->s.halfBit; } } } @@ -2683,9 +2775,6 @@ static void waveRxBit(int gpio, int level, uint32_t tick) { switch (wfRx[gpio].mode) { - case PI_WFRX_NONE: - break; - case PI_WFRX_SERIAL: waveRxSerial(&wfRx[gpio], level, tick); } @@ -2846,6 +2935,9 @@ int i2cWriteQuick(unsigned handle, unsigned bit) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_QUICK) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (bit > 1) SOFT_ERROR(PI_BAD_PARAM, "bad bit (%d)", bit); @@ -2871,6 +2963,9 @@ int i2cReadByte(unsigned handle) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (my_smbus_access( i2cInfo[handle].fd, PI_I2C_SMBUS_READ, 0, PI_I2C_SMBUS_BYTE, &data)) return PI_I2C_READ_FAILED; @@ -2893,6 +2988,9 @@ int i2cWriteByte(unsigned handle, unsigned bVal) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (bVal > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad bVal (%d)", bVal); @@ -2923,6 +3021,9 @@ int i2cReadByteData(unsigned handle, unsigned reg) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -2950,6 +3051,9 @@ int i2cWriteByteData(unsigned handle, unsigned reg, unsigned bVal) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BYTE_DATA) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -2985,11 +3089,18 @@ int i2cReadWordData(unsigned handle, unsigned reg) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_WORD_DATA) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); if (my_smbus_access( - i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, PI_I2C_SMBUS_WORD_DATA, &data)) + i2cInfo[handle].fd, + PI_I2C_SMBUS_READ, + reg, + PI_I2C_SMBUS_WORD_DATA, + &data)) return PI_I2C_READ_FAILED; else return 0xFFFF & data.word; @@ -3012,6 +3123,9 @@ int i2cWriteWordData(unsigned handle, unsigned reg, unsigned wVal) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_WORD_DATA) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -3047,6 +3161,9 @@ int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -3056,7 +3173,10 @@ int i2cProcessCall(unsigned handle, unsigned reg, unsigned wVal) data.word = wVal; if (my_smbus_access( - i2cInfo[handle].fd, PI_I2C_SMBUS_WRITE, reg, PI_I2C_SMBUS_PROC_CALL, &data)) + i2cInfo[handle].fd, + PI_I2C_SMBUS_WRITE, + reg, PI_I2C_SMBUS_PROC_CALL, + &data)) return PI_I2C_READ_FAILED; else return 0xFFFF & data.word; @@ -3079,11 +3199,18 @@ int i2cReadBlockData(unsigned handle, unsigned reg, char *buf) if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_BLOCK_DATA) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); if (my_smbus_access( - i2cInfo[handle].fd, PI_I2C_SMBUS_READ, reg, PI_I2C_SMBUS_BLOCK_DATA, &data)) + i2cInfo[handle].fd, + PI_I2C_SMBUS_READ, + reg, + PI_I2C_SMBUS_BLOCK_DATA, + &data)) return PI_I2C_READ_FAILED; else { @@ -3115,6 +3242,9 @@ int i2cWriteBlockData( if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -3155,6 +3285,9 @@ int i2cBlockProcessCall( if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_PROC_CALL) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -3198,6 +3331,9 @@ int i2cReadI2CBlockData( if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_READ_I2C_BLOCK) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -3243,6 +3379,9 @@ int i2cWriteI2CBlockData( if (i2cInfo[handle].state == PI_I2C_CLOSED) SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + if ((i2cInfo[handle].funcs & PI_I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) == 0) + SOFT_ERROR(PI_BAD_SMBUS_CMD, "SMBUS command not supported by driver"); + if (reg > 0xFF) SOFT_ERROR(PI_BAD_PARAM, "bad reg (%d)", reg); @@ -3321,6 +3460,7 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags) { char dev[32]; int i, slot, fd; + uint32_t funcs; DBG(DBG_USER, "i2cBus=%d i2cAddr=%d flags=0x%X", i2cBus, i2cAddr, i2cFlags); @@ -3330,8 +3470,8 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags) if (i2cBus >= PI_NUM_I2C_BUS) SOFT_ERROR(PI_BAD_I2C_BUS, "bad I2C bus (%d)", i2cBus); - if ((i2cAddr < 0x08) || (i2cAddr > 0x77)) - SOFT_ERROR(PI_BAD_I2C_ADDR, "bad I2C address (0x%X)", i2cAddr); +// if ((i2cAddr < 0x08) || (i2cAddr > 0x77)) +// SOFT_ERROR(PI_BAD_I2C_ADDR, "bad I2C address (0x%X)", i2cAddr); if (i2cFlags) SOFT_ERROR(PI_BAD_FLAGS, "bad flags (0x%X)", i2cFlags); @@ -3376,8 +3516,14 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags) return PI_I2C_OPEN_FAILED; } + if (ioctl(fd, PI_I2C_FUNCS, &funcs) < 0) + { + funcs = -1; /* assume all smbus commands allowed */ + } + i2cInfo[slot].fd = fd; i2cInfo[slot].flags = i2cFlags; + i2cInfo[slot].funcs = funcs; return slot; } @@ -3404,7 +3550,7 @@ int i2cClose(unsigned handle) int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts) { - int retval, fd; + int retval; my_i2c_rdwr_ioctl_data_t rdwr; DBG(DBG_USER, "handle=%d", handle); @@ -3423,14 +3569,6 @@ int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts) if (numParts > PI_I2C_RDRW_IOCTL_MAX_MSGS) SOFT_ERROR(PI_TOO_MANY_PARTS, "too many parts (%d)", numParts); - fd = open(PI_I2C_COMBINED, O_RDWR); - - if (fd >= 0) - { - write(fd, "1", 1); - close(fd); - } - rdwr.msgs = parts; rdwr.nmsgs = numParts; @@ -3442,6 +3580,129 @@ int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts) else return PI_BAD_I2C_PART; } +#ifdef ZZZZ + +int i2cXfer( + unsigned handle, + char *inBuf, unsigned inLen, char *outBuf, unsigned outLen) +{ + int i, parts, inPos, outPos, status, bytes, len_bytes,flags, addr; + pi_i2c_msg_t part[PI_I2C_RDRW_IOCTL_MAX_MSGS]; + + DBG(DBG_USER, "handle=%d inBuf=%s outBuf=%08X len=%d", + handle, myBuf2Str(inLen, (char *)inBuf), (int)outBuf, outLen); + + CHECK_INITED; + + if (handle >= PI_I2C_SLOTS) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (i2cInfo[handle].state != PI_I2C_OPENED) + SOFT_ERROR(PI_BAD_HANDLE, "bad handle (%d)", handle); + + if (!inBuf || !inLen) + SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL"); + + if (!outBuf && outLen) + SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL"); + + parts = 0; + inPos = 0; + outPos = 0; + status = 0; + flags = 0; + addr = 0; + + while (!status && (inPos < inLen) && (parts < PI_I2C_RDRW_IOCTL_MAX_MSGS)) + { + DBG(DBG_INTERNAL, "status=%d inpos=%d inlen=%d cmd=%d", + status, inPos, inLen, inBuf[inPos]); + + len_bytes = 1; + + switch (inBuf[inPos++]) + { + case PI_I2C_END: + status = 1; + break; + + case PI_I2C_READ16: + len_bytes = 2; + /* fall through */ + + case PI_I2C_READ: + if (inPos <= (inLen - len_bytes)) + { + if (len_bytes != 1) + { + bytes=inBuf[inPos] + (inBuf[inPos+1]<<8); + inPos += 2; + } + else + { + bytes=inBuf[inPos++]; + } + + if (bytes && ((bytes + outPos) < outLen)) + { + part[parts].addr = addr; + part[parts].flags = flags; + part[parts].len = + part[parts].buf = + + for (i=0; i<(bytes-1); i++) + { + outBuf[outPos++] = I2CGetByte(w, 0); + } + outBuf[outPos++] = I2CGetByte(w, 1); + } + else status = PI_BAD_BB_WLEN; + } + else status = PI_BAD_BB_WLEN; + break; + + case PI_I2C_WRITE16: + len_bytes = 2; + /* fall through */ + + case PI_I2C_WRITE: + if (inPos <= (inLen - len_bytes)) + { + if (len_bytes != 1) + { + bytes=inBuf[inPos] + (inBuf[inPos+1]<<8); + inPos += 2; + } + else + { + bytes=inBuf[inPos++]; + } + + if (bytes && ((bytes + inPos) < inLen)) + { + for (i=0; i<(bytes-1); i++) + { + ack = I2CPutByte(w, inBuf[inPos++]); + if (ack) status = PI_I2C_WRITE_FAILED; + } + ack = I2CPutByte(w, inBuf[inPos++]); + //if (ack) status = PI_I2C_WRITE_FAILED; + } + else status = PI_BAD_BB_RLEN; + } + else status = PI_BAD_BB_RLEN; + break; + + default: + status = PI_BAD_BB_CMD; + } + } + + if (status >= 0) status = outPos; + + return status; +} +#endif /* ======================================================================= */ @@ -4682,7 +4943,7 @@ static void * pthAlertThread(void *x) /* don't start until DMA started */ - waitForDMAstarted(); + spinWhileStarting(); reportedLevel = gpioReg[GPLEV0]; @@ -4714,7 +4975,7 @@ static void * pthAlertThread(void *x) myGpioDelay(5000); - if (DMAstarted) + if (runState == PI_RUNNING) { /* should never be executed, leave code just in case */ @@ -4897,11 +5158,13 @@ static void * pthAlertThread(void *x) { if (gpioAlert[b].ex) { - (gpioAlert[b].func)(b, 2, tick, gpioAlert[b].userdata); + (gpioAlert[b].func) + (b, PI_TIMEOUT, tick, gpioAlert[b].userdata); } else { - (gpioAlert[b].func)(b, 2, tick); + (gpioAlert[b].func) + (b, PI_TIMEOUT, tick); } } } @@ -4985,7 +5248,7 @@ static void * pthAlertThread(void *x) gpioReport[emit].seqno = seqno; gpioReport[emit].flags = PI_NTFY_FLAGS_WDOG | - PI_NTFY_FLAGS_BIT(b); + PI_NTFY_FLAGS_BIT(b); gpioReport[emit].tick = tick; gpioReport[emit].level = newLevel; @@ -4995,8 +5258,29 @@ static void * pthAlertThread(void *x) } } + if (!emit) + { + if ((tick - gpioNotify[n].lastReportTick) > 60000000) + { + if (numSamples) + newLevel = gpioSample[numSamples-1].level; + else + newLevel = reportedLevel; + + gpioReport[emit].seqno = seqno; + gpioReport[emit].flags = PI_NTFY_FLAGS_ALIVE; + gpioReport[emit].tick = tick; + gpioReport[emit].level = newLevel; + + emit++; + seqno++; + } + } + if (emit) { + gpioNotify[n].lastReportTick = tick; + if (emit > gpioStats.maxEmit) gpioStats.maxEmit = emit; emitted = 0; @@ -5496,7 +5780,7 @@ static void * pthFifoThread(void *x) /* don't start until DMA started */ - waitForDMAstarted(); + spinWhileStarting(); while (1) { @@ -5665,6 +5949,7 @@ static void *pthSocketThreadHandler(void *fdC) { /* extensions */ + case PI_CMD_BI2CX: case PI_CMD_CF2: case PI_CMD_I2CPK: case PI_CMD_I2CRD: @@ -5721,7 +6006,7 @@ static void * pthSocketThread(void *x) /* don't start until DMA started */ - waitForDMAstarted(); + spinWhileStarting(); while ((fdC = accept(fdSock, (struct sockaddr *)&client, (socklen_t*)&c))) @@ -5794,7 +6079,7 @@ static int initCheckPermitted(void) if ((fdMem = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) { - DBG(DBG_STARTUP, + DBG(DBG_ALWAYS, "\n" \ "+---------------------------------------------------------+\n" \ "|Sorry, you don't have permission to run this program. |\n" \ @@ -6375,10 +6660,6 @@ static void initClearGlobals(void) notifyBits = 0; scriptBits = 0; - libInitialised = 0; - DMAstarted = 0; - terminating = 0; - pthAlertRunning = 0; pthFifoRunning = 0; pthSocketRunning = 0; @@ -6642,8 +6923,6 @@ int initInitialise(void) DBG(DBG_STARTUP, ""); - if (libInitialised) return PIGPIO_VERSION; - waveClockInited = 0; clock_gettime(CLOCK_REALTIME, &libStarted); @@ -6692,8 +6971,6 @@ int initInitialise(void) initClock(1); /* initialise main clock */ - libInitialised = 1; - atexit(gpioTerminate); if (pthread_attr_init(&pthAttr)) @@ -6749,8 +7026,6 @@ int initInitialise(void) myGpioDelay(20000); - DMAstarted = 1; - return PIGPIO_VERSION; } @@ -6956,12 +7231,22 @@ int gpioInitialise(void) { int status; + if (libInitialised) return PIGPIO_VERSION; + + runState = PI_STARTING; + status = initInitialise(); if (status < 0) { + runState = PI_ENDING; initReleaseResources(); } + else + { + libInitialised = 1; + runState = PI_RUNNING; + } return status; } @@ -6975,58 +7260,54 @@ void gpioTerminate(void) DBG(DBG_USER, ""); - terminating = 1; + if (!libInitialised) return; - if (libInitialised) - { - libInitialised = 0; + runState = PI_ENDING; - gpioMaskSet = 0; + gpioMaskSet = 0; - /* reset DMA */ + /* reset DMA */ - DMAstarted = 0; - - dmaIn[DMA_CS] = DMA_CHANNEL_RESET; - dmaOut[DMA_CS] = DMA_CHANNEL_RESET; + if (dmaReg != MAP_FAILED) dmaIn[DMA_CS] = DMA_CHANNEL_RESET; + if (dmaReg != MAP_FAILED) dmaOut[DMA_CS] = DMA_CHANNEL_RESET; #ifndef EMBEDDED_IN_VM - if (gpioCfg.showStats) - { - fprintf(stderr, - "If you didn't request stats please cut & paste the\n" - "following and e-mail to pigpio@abyz.co.uk\n"); + if (gpioCfg.showStats) + { + fprintf(stderr, + "If you didn't request stats please cut & paste the\n" + "following and e-mail to pigpio@abyz.co.uk\n"); - fprintf(stderr, - "#####################################################\n"); + fprintf(stderr, + "micros=%d allocMode=%d dmaInitCbs=%d DMARestarts=%d\n", + gpioCfg.clockMicros, gpioCfg.memAllocMode, + gpioStats.dmaInitCbsCount, gpioStats.DMARestarts); - fprintf(stderr, - "micros=%d allocMode=%d dmaInitCbs=%d DMARestarts=%d\n", - gpioCfg.clockMicros, gpioCfg.memAllocMode, - gpioStats.dmaInitCbsCount, gpioStats.DMARestarts); + fprintf(stderr, + "samples %u maxSamples %u maxEmit %u emitFrags %u\n", + gpioStats.numSamples, gpioStats.maxSamples, + gpioStats.maxEmit, gpioStats.emitFrags); - fprintf(stderr, - "samples %u maxSamples %u maxEmit %u emitFrags %u\n", - gpioStats.numSamples, gpioStats.maxSamples, - gpioStats.maxEmit, gpioStats.emitFrags); + fprintf(stderr, "cbTicks %d, cbCalls %u alertTicks %u\n", + gpioStats.cbTicks, gpioStats.cbCalls, gpioStats.alertTicks); - fprintf(stderr, "cbTicks %d, cbCalls %u alertTicks %u\n", - gpioStats.cbTicks, gpioStats.cbCalls, gpioStats.alertTicks); + for (i=0; i< TICKSLOTS; i++) + fprintf(stderr, "%9u ", gpioStats.diffTick[i]); - for (i=0; i< TICKSLOTS; i++) - fprintf(stderr, "%9u ", gpioStats.diffTick[i]); + fprintf(stderr, "\n"); - fprintf(stderr, "\n"); + fprintf(stderr, "\n"); - fprintf(stderr, - "#####################################################\n"); - } -#endif + fprintf(stderr, + "#####################################################\n"); } +#endif initReleaseResources(); fflush(NULL); + + libInitialised = 0; } static void switchFunctionOff(unsigned gpio) @@ -8117,6 +8398,332 @@ int gpioWaveGetMaxCbs(void) return wfStats.maxCbs; } +static int read_SDA(wfRx_t *w) +{ + myGpioSetMode(w->I.SDA, PI_INPUT); + return gpioRead(w->I.SDA); +} + +static void set_SDA(wfRx_t *w) +{ + myGpioSetMode(w->I.SDA, PI_INPUT); +} + +static void clear_SDA(wfRx_t *w) +{ + myGpioSetMode(w->I.SDA, PI_OUTPUT); + myGpioWrite(w->I.SDA, 0); +} + +static void clear_SCL(wfRx_t *w) +{ + myGpioSetMode(w->I.SCL, PI_OUTPUT); + myGpioWrite(w->I.SCL, 0); +} + +static void I2C_delay(wfRx_t *w) +{ + myGpioDelay(w->I.delay); +} + +static void I2C_clock_stretch(wfRx_t *w) +{ + uint32_t now, max_stretch=10000; + + myGpioSetMode(w->I.SCL, PI_INPUT); + now = gpioTick(); + while ((gpioRead(w->I.SCL) == 0) && ((gpioTick()-now) < max_stretch)); +} + +static void I2CStart(wfRx_t *w) +{ + if (w->I.started) + { + set_SDA(w); + I2C_delay(w); + I2C_clock_stretch(w); + I2C_delay(w); + } + + clear_SDA(w); + I2C_delay(w); + clear_SCL(w); + I2C_delay(w); + + w->I.started = 1; +} + +static void I2CStop(wfRx_t *w) +{ + clear_SDA(w); + I2C_delay(w); + I2C_clock_stretch(w); + I2C_delay(w); + set_SDA(w); + I2C_delay(w); + + w->I.started = 0; +} + +static void I2CPutBit(wfRx_t *w, int bit) +{ + if (bit) set_SDA(w); + else clear_SDA(w); + + I2C_delay(w); + I2C_clock_stretch(w); + I2C_delay(w); + clear_SCL(w); +} + +static int I2CGetBit(wfRx_t *w) +{ + int bit; + + set_SDA(w); /* let SDA float */ + I2C_delay(w); + I2C_clock_stretch(w); + bit = read_SDA(w); + I2C_delay(w); + clear_SCL(w); + + return bit; +} + +static int I2CPutByte(wfRx_t *w, int byte) +{ + int bit, nack; + + for(bit=0; bit<8; bit++) + { + I2CPutBit(w, byte & 0x80); + byte <<= 1; + } + + nack = I2CGetBit(w); + + return nack; +} + +static uint8_t I2CGetByte(wfRx_t *w, int nack) +{ + int bit, byte=0; + + for (bit=0; bit<8; bit++) + { + byte = (byte << 1) | I2CGetBit(w); + } + + I2CPutBit(w, nack); + + return byte; +} + +int bbI2COpen(unsigned SDA, unsigned SCL, unsigned bbBaud) +{ + DBG(DBG_USER, "SDA=%d SCL=%d bbBaud=%d", SDA, SCL, bbBaud); + + CHECK_INITED; + + if (SDA > PI_MAX_USER_GPIO) + SOFT_ERROR(PI_BAD_USER_GPIO, "bad SDA (%d)", SDA); + + if (SCL > PI_MAX_USER_GPIO) + SOFT_ERROR(PI_BAD_USER_GPIO, "bad SCL (%d)", SCL); + + if ((bbBaud < PI_BB_MIN_BAUD) || (bbBaud > PI_BB_RX_MAX_BAUD)) + SOFT_ERROR(PI_BAD_WAVE_BAUD, + "SDA %d, bad baud rate (%d)", SDA, bbBaud); + + if (wfRx[SDA].mode != PI_WFRX_NONE) + SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SDA); + + if (wfRx[SCL].mode != PI_WFRX_NONE) + SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", SCL); + + wfRx[SDA].gpio = SDA; + wfRx[SDA].mode = PI_WFRX_I2C; + wfRx[SDA].baud = bbBaud; + + wfRx[SDA].I.started = 0; + wfRx[SDA].I.SDA = SDA; + wfRx[SDA].I.SCL = SCL; + wfRx[SDA].I.delay = 500000 / bbBaud; + wfRx[SDA].I.SDAMode = gpioGetMode(SDA); + wfRx[SDA].I.SCLMode = gpioGetMode(SCL); + + wfRx[SCL].gpio = SCL; + wfRx[SCL].mode = PI_WFRX_I2C_CLK; + + myGpioSetMode(SDA, PI_INPUT); + myGpioSetMode(SCL, PI_INPUT); + + return 0; +} + + +/* ----------------------------------------------------------------------- */ + + +int bbI2CClose(unsigned SDA) +{ + DBG(DBG_USER, "SDA=%d", SDA); + + CHECK_INITED; + + if (SDA > PI_MAX_USER_GPIO) + SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA); + + switch(wfRx[SDA].mode) + { + case PI_WFRX_I2C: + + gpioSetMode(wfRx[SDA].I.SDA, wfRx[SDA].I.SDAMode); + gpioSetMode(wfRx[SDA].I.SCL, wfRx[SDA].I.SCLMode); + + wfRx[wfRx[SDA].I.SDA].mode = PI_WFRX_NONE; + wfRx[wfRx[SDA].I.SCL].mode = PI_WFRX_NONE; + + break; + + default: + + SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA); + + break; + + } + + return 0; +} + + +/*-------------------------------------------------------------------------*/ + +int bbI2CXfer( + unsigned SDA, + char *inBuf, unsigned inLen, char *outBuf, unsigned outLen) +{ + int i, ack, inPos, outPos, status, bytes, len_bytes; + wfRx_t *w; + + DBG(DBG_USER, "gpio=%d inBuf=%s outBuf=%08X len=%d", + SDA, myBuf2Str(inLen, (char *)inBuf), (int)outBuf, outLen); + + CHECK_INITED; + + if (SDA > PI_MAX_USER_GPIO) + SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", SDA); + + if (wfRx[SDA].mode != PI_WFRX_I2C) + SOFT_ERROR(PI_NOT_I2C_GPIO, "no I2C on gpio (%d)", SDA); + + if (!inBuf || !inLen) + SOFT_ERROR(PI_BAD_POINTER, "input buffer can't be NULL"); + + if (!outBuf && outLen) + SOFT_ERROR(PI_BAD_POINTER, "output buffer can't be NULL"); + + w = &wfRx[SDA]; + + inPos = 0; + outPos = 0; + status = 0; + + while (!status && (inPos < inLen)) + { + DBG(DBG_INTERNAL, "status=%d inpos=%d inlen=%d cmd=%d", + status, inPos, inLen, inBuf[inPos]); + + len_bytes = 1; + + switch (inBuf[inPos++]) + { + case PI_I2C_END: + status = 1; + break; + + case PI_I2C_START: + I2CStart(w); + break; + + case PI_I2C_STOP: + I2CStop(w); + break; + + case PI_I2C_READ16: + len_bytes = 2; + /* fall through */ + + case PI_I2C_READ: + if (inPos <= (inLen - len_bytes)) + { + if (len_bytes != 1) + { + bytes=inBuf[inPos] + (inBuf[inPos+1]<<8); + inPos += 2; + } + else + { + bytes=inBuf[inPos++]; + } + + if (bytes && ((bytes + outPos) < outLen)) + { + for (i=0; i<(bytes-1); i++) + { + outBuf[outPos++] = I2CGetByte(w, 0); + } + outBuf[outPos++] = I2CGetByte(w, 1); + } + else status = PI_BAD_BB_WLEN; + } + else status = PI_BAD_BB_WLEN; + break; + + case PI_I2C_WRITE16: + len_bytes = 2; + /* fall through */ + + case PI_I2C_WRITE: + if (inPos <= (inLen - len_bytes)) + { + if (len_bytes != 1) + { + bytes=inBuf[inPos] + (inBuf[inPos+1]<<8); + inPos += 2; + } + else + { + bytes=inBuf[inPos++]; + } + + if (bytes && ((bytes + inPos) < inLen)) + { + for (i=0; i<(bytes-1); i++) + { + ack = I2CPutByte(w, inBuf[inPos++]); + if (ack) status = PI_I2C_WRITE_FAILED; + } + ack = I2CPutByte(w, inBuf[inPos++]); + //if (ack) status = PI_I2C_WRITE_FAILED; + } + else status = PI_BAD_BB_RLEN; + } + else status = PI_BAD_BB_RLEN; + break; + + default: + status = PI_BAD_BB_CMD; + } + } + + if (status >= 0) status = outPos; + + return status; +} + + /*-------------------------------------------------------------------------*/ int gpioSerialReadOpen(unsigned gpio, unsigned bbBaud, unsigned bbBits) @@ -8141,28 +8748,29 @@ int gpioSerialReadOpen(unsigned gpio, unsigned bbBaud, unsigned bbBits) if (wfRx[gpio].mode != PI_WFRX_NONE) SOFT_ERROR(PI_GPIO_IN_USE, "gpio %d is already being used", gpio); - bitTime = (1000 * MILLION) / bbBaud; /* nanoseconds */ + bitTime = (1000 * MILLION) / bbBaud; /* nanos */ - timeout = ((bbBits+2) * bitTime)/MILLION; /* milliseconds */ + timeout = ((bbBits+2) * bitTime)/MILLION; /* millis */ if (timeout < 1) timeout = 1; - wfRx[gpio].gpio = gpio; - wfRx[gpio].buf = malloc(SRX_BUF_SIZE); - wfRx[gpio].bufSize = SRX_BUF_SIZE; - wfRx[gpio].mode = PI_WFRX_SERIAL; - wfRx[gpio].baud = bbBaud; - wfRx[gpio].timeout = timeout; - wfRx[gpio].fullBit = bitTime; /* nanoseconds */ - wfRx[gpio].halfBit = (bitTime/2)+500; /* nanoseconds (500 for rounding) */ - wfRx[gpio].readPos = 0; - wfRx[gpio].writePos = 0; - wfRx[gpio].bit = -1; - wfRx[gpio].dataBits = bbBits; + wfRx[gpio].gpio = gpio; + wfRx[gpio].mode = PI_WFRX_SERIAL; + wfRx[gpio].baud = bbBaud; - if (bbBits < 9) wfRx[gpio].bytes = 1; - else if (bbBits < 17) wfRx[gpio].bytes = 2; - else wfRx[gpio].bytes = 4; + wfRx[gpio].s.buf = malloc(SRX_BUF_SIZE); + wfRx[gpio].s.bufSize = SRX_BUF_SIZE; + wfRx[gpio].s.timeout = timeout; + wfRx[gpio].s.fullBit = bitTime; /* nanos */ + wfRx[gpio].s.halfBit = (bitTime/2)+500; /* nanos (500 for rounding) */ + wfRx[gpio].s.readPos = 0; + wfRx[gpio].s.writePos = 0; + wfRx[gpio].s.bit = -1; + wfRx[gpio].s.dataBits = bbBits; + + if (bbBits < 9) wfRx[gpio].s.bytes = 1; + else if (bbBits < 17) wfRx[gpio].s.bytes = 2; + else wfRx[gpio].s.bytes = 4; gpioSetAlertFunc(gpio, waveRxBit); @@ -8174,7 +8782,7 @@ int gpioSerialReadOpen(unsigned gpio, unsigned bbBaud, unsigned bbBits) int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize) { unsigned bytes=0, wpos; - volatile wfRx_t *p; + volatile wfRx_t *w; DBG(DBG_USER, "gpio=%d buf=%08X bufSize=%d", gpio, (int)buf, bufSize); @@ -8189,26 +8797,26 @@ int gpioSerialRead(unsigned gpio, void *buf, size_t bufSize) if (wfRx[gpio].mode != PI_WFRX_SERIAL) SOFT_ERROR(PI_NOT_SERIAL_GPIO, "no serial read on gpio (%d)", gpio); - p = &wfRx[gpio]; + w = &wfRx[gpio]; - if (p->readPos != p->writePos) + if (w->s.readPos != w->s.writePos) { - wpos = p->writePos; + wpos = w->s.writePos; - if (wpos > p->readPos) bytes = wpos - p->readPos; - else bytes = p->bufSize - p->readPos; + if (wpos > w->s.readPos) bytes = wpos - w->s.readPos; + else bytes = w->s.bufSize - w->s.readPos; if (bytes > bufSize) bytes = bufSize; /* copy in multiples of the data size in bytes */ - bytes = (bytes / p->bytes) * p->bytes; + bytes = (bytes / w->s.bytes) * w->s.bytes; - if (buf) memcpy(buf, p->buf+p->readPos, bytes); + if (buf) memcpy(buf, w->s.buf+w->s.readPos, bytes); - p->readPos += bytes; + w->s.readPos += bytes; - if (p->readPos >= p->bufSize) p->readPos = 0; + if (w->s.readPos >= w->s.bufSize) w->s.readPos = 0; } return bytes; } @@ -8235,7 +8843,7 @@ int gpioSerialReadClose(unsigned gpio) case PI_WFRX_SERIAL: - free(wfRx[gpio].buf); + free(wfRx[gpio].s.buf); gpioSetWatchdog(gpio, 0); /* switch off timeouts */ @@ -8357,6 +8965,7 @@ int gpioNotifyOpen(void) gpioNotify[slot].bits = 0; gpioNotify[slot].fd = fd; gpioNotify[slot].pipe = 1; + gpioNotify[slot].lastReportTick = gpioTick(); return slot; } @@ -8390,6 +8999,7 @@ static int gpioNotifyOpenInBand(int fd) gpioNotify[slot].bits = 0; gpioNotify[slot].fd = fd; gpioNotify[slot].pipe = 0; + gpioNotify[slot].lastReportTick = gpioTick(); return slot; } @@ -9368,9 +9978,10 @@ uint32_t gpioDelay(uint32_t micros) start = systReg[SYST_CLO]; - if (micros <= PI_MAX_BUSY_DELAY) while ((systReg[SYST_CLO] - start) <= micros); - - else gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION)); + if (micros <= PI_MAX_BUSY_DELAY) + while ((systReg[SYST_CLO] - start) <= micros); + else + gpioSleep(PI_TIME_RELATIVE, (micros/MILLION), (micros%MILLION)); return (systReg[SYST_CLO] - start); } @@ -9663,3 +10274,4 @@ int gpioCfgInternals(unsigned cfgWhat, int cfgVal) /* include any user customisations */ #include "custom.cext" + diff --git a/pigpio.h b/pigpio.h index 69afbc8..d5c302d 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 31 +#define PIGPIO_VERSION 3202 /*TEXT @@ -225,20 +225,20 @@ i2cClose Closes an I2C device i2cReadDevice Reads the raw I2C device i2cWriteDevice Writes the raw I2C device -i2cWriteQuick smbus write quick -i2cWriteByte smbus write byte -i2cReadByte smbus read byte -i2cWriteByteData smbus write byte data -i2cWriteWordData smbus write word data -i2cReadByteData smbus read byte data -i2cReadWordData smbus read word data -i2cProcessCall smbus process call -i2cWriteBlockData smbus write block data -i2cReadBlockData smbus read block data -i2cBlockProcessCall smbus block process call +i2cWriteQuick SMBus write quick +i2cWriteByte SMBus write byte +i2cReadByte SMBus read byte +i2cWriteByteData SMBus write byte data +i2cWriteWordData SMBus write word data +i2cReadByteData SMBus read byte data +i2cReadWordData SMBus read word data +i2cProcessCall SMBus process call +i2cWriteBlockData SMBus write block data +i2cReadBlockData SMBus read block data +i2cBlockProcessCall SMBus block process call -i2cWriteI2CBlockData smbus write I2C block data -i2cReadI2CBlockData smbus read I2C block data +i2cWriteI2CBlockData SMBus write I2C block data +i2cReadI2CBlockData SMBus read I2C block data SPI @@ -327,36 +327,36 @@ extern "C" { typedef struct { -uint16_t func; -uint16_t size; + uint16_t func; + uint16_t size; } gpioHeader_t; typedef struct { -size_t size; -void *ptr; -uint32_t data; + size_t size; + void *ptr; + uint32_t data; } gpioExtent_t; typedef struct { -uint32_t tick; -uint32_t level; + uint32_t tick; + uint32_t level; } gpioSample_t; typedef struct { -uint16_t seqno; -uint16_t flags; -uint32_t tick; -uint32_t level; + uint16_t seqno; + uint16_t flags; + uint32_t tick; + uint32_t level; } gpioReport_t; typedef struct { -uint32_t gpioOn; -uint32_t gpioOff; -uint32_t usDelay; + uint32_t gpioOn; + uint32_t gpioOff; + uint32_t usDelay; } gpioPulse_t; #define WAVE_FLAG_READ 1 @@ -365,10 +365,10 @@ uint32_t usDelay; typedef struct { -uint32_t gpioOn; -uint32_t gpioOff; -uint32_t usDelay; -uint32_t flags; + uint32_t gpioOn; + uint32_t gpioOff; + uint32_t usDelay; + uint32_t flags; } rawWave_t; typedef struct @@ -381,41 +381,26 @@ typedef struct typedef struct { -int clk; /* gpio for clock */ -int mosi; /* gpio for MOSI */ -int miso; /* gpio for MISO */ -int ss_pol; /* slave select off state */ -int ss_us; /* delay after slave select */ -int clk_pol; /* clock off state */ -int clk_pha; /* clock phase */ -int clk_us; /* clock micros */ + int clk; /* gpio for clock */ + int mosi; /* gpio for MOSI */ + int miso; /* gpio for MISO */ + int ss_pol; /* slave select off state */ + int ss_us; /* delay after slave select */ + int clk_pol; /* clock off state */ + int clk_pha; /* clock phase */ + int clk_us; /* clock micros */ } rawSPI_t; typedef struct { /* linux/arch/arm/mach-bcm2708/include/mach/dma.h */ -uint32_t info; -uint32_t src; -uint32_t dst; -uint32_t length; -uint32_t stride; -uint32_t next; -uint32_t pad[2]; + uint32_t info; + uint32_t src; + uint32_t dst; + uint32_t length; + uint32_t stride; + uint32_t next; + uint32_t pad[2]; } rawCbs_t; -/* max pi_i2c_msg_t per transaction */ - -#define PI_I2C_RDRW_IOCTL_MAX_MSGS 42 - -/* flags for pi_i2c_msg_t */ - -#define PI_I2C_M_WR 0x0000 /* write data */ -#define PI_I2C_M_RD 0x0001 /* read data */ -#define PI_I2C_M_TEN 0x0010 /* ten bit chip address */ -#define PI_I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ -#define PI_I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ -#define PI_I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ -#define PI_I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ -#define PI_I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ - typedef struct { uint16_t addr; /* slave address */ @@ -521,6 +506,7 @@ typedef void *(gpioThreadFunc_t) (void *); #define PI_NOTIFY_SLOTS 32 +#define PI_NTFY_FLAGS_ALIVE (1 <<6) #define PI_NTFY_FLAGS_WDOG (1 <<5) #define PI_NTFY_FLAGS_BIT(x) (((x)<<0)&31) @@ -564,6 +550,43 @@ typedef void *(gpioThreadFunc_t) (void *); #define PI_MAX_I2C_DEVICE_COUNT (1<<16) #define PI_MAX_SPI_DEVICE_COUNT (1<<16) +/* max pi_i2c_msg_t per transaction */ + +#define PI_I2C_RDRW_IOCTL_MAX_MSGS 42 + +/* flags for pi_i2c_msg_t */ + +#define PI_I2C_M_WR 0x0000 /* write data */ +#define PI_I2C_M_RD 0x0001 /* read data */ +#define PI_I2C_M_TEN 0x0010 /* ten bit chip address */ +#define PI_I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ +#define PI_I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define PI_I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define PI_I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define PI_I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ + +/* bit bang I2C commands */ + +#define PI_I2C_END 0 +#define PI_I2C_START 1 +#define PI_I2C_STOP 2 +#define PI_I2C_READ 3 +#define PI_I2C_WRITE 4 +#define PI_I2C_READ16 5 +#define PI_I2C_WRITE16 6 + +/* combined transaction I2C flag commands */ + +#define PI_I2C_F_CLEAR 40 /* clear flags */ +#define PI_I2C_F_TEN 41 /* ten bit chip address */ +#define PI_I2C_F_RECV_LEN 42 /* length will be first received byte */ +#define PI_I2C_F_NO_RD_ACK 43 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define PI_I2C_F_IGNORE_NAK 44 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define PI_I2C_F_REV_DIR_ADDR 45 /* if I2C_FUNC_PROTOCOL_MANGLING */ +#define PI_I2C_F_NOSTART 46 /* if I2C_FUNC_PROTOCOL_MANGLING */ + +/* SPI */ + #define PI_SPI_FLAGS_BITLEN(x) ((x&63)<<16) #define PI_SPI_FLAGS_RX_LSB(x) ((x&1)<<15) #define PI_SPI_FLAGS_TX_LSB(x) ((x&1)<<14) @@ -1740,7 +1763,7 @@ No flags are currently defined. This parameter should be set to zero. Returns a handle (>=0) if OK, otherwise PI_BAD_I2C_BUS, PI_BAD_I2C_ADDR, PI_BAD_FLAGS, PI_NO_HANDLE, or PI_I2C_OPEN_FAILED. -For the smbus commands the low level transactions are shown at the end +For the SMBus commands the low level transactions are shown at the end of the function description. The following abbreviations are used. . . @@ -1821,7 +1844,7 @@ handle: >=0, as returned by a call to [*i2cOpen*] Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_WRITE_FAILED. -Quick command. smbus 2.0 5.5.1 +Quick command. SMBus 2.0 5.5.1 . . S Addr Rd/Wr [A] P . . @@ -1841,7 +1864,7 @@ handle: >=0, as returned by a call to [*i2cOpen*] Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_WRITE_FAILED. -Send byte. smbus 2.0 5.5.2 +Send byte. SMBus 2.0 5.5.2 . . S Addr Wr [A] Data [A] P . . @@ -1860,7 +1883,7 @@ handle: >=0, as returned by a call to [*i2cOpen*] Returns the byte read (>=0) if OK, otherwise PI_BAD_HANDLE, or PI_I2C_READ_FAILED. -Receive byte. smbus 2.0 5.5.3 +Receive byte. SMBus 2.0 5.5.3 . . S Addr Rd [A] [Data] NA P . . @@ -1882,7 +1905,7 @@ i2cReg: 0-255, the register to write Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_WRITE_FAILED. -Write byte. smbus 2.0 5.5.4 +Write byte. SMBus 2.0 5.5.4 . . S Addr Wr [A] Comm [A] Data [A] P . . @@ -1904,7 +1927,7 @@ i2cReg: 0-255, the register to write Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_WRITE_FAILED. -Write word. smbus 2.0 5.5.4 +Write word. SMBus 2.0 5.5.4 . . S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P . . @@ -1925,7 +1948,7 @@ i2cReg: 0-255, the register to read Returns the byte read (>=0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_READ_FAILED. -Read byte. smbus 2.0 5.5.5 +Read byte. SMBus 2.0 5.5.5 . . S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P . . @@ -1946,7 +1969,7 @@ i2cReg: 0-255, the register to read Returns the word read (>=0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_READ_FAILED. -Read word. smbus 2.0 5.5.5 +Read word. SMBus 2.0 5.5.5 . . S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P . . @@ -1968,7 +1991,7 @@ i2cReg: 0-255, the register to write/read Returns the word read (>=0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_READ_FAILED. -Process call. smbus 2.0 5.5.6 +Process call. SMBus 2.0 5.5.6 . . S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P @@ -1993,7 +2016,7 @@ i2cReg: 0-255, the register to write Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_WRITE_FAILED. -Block write. smbus 2.0 5.5.7 +Block write. SMBus 2.0 5.5.7 . . S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P . . @@ -2017,7 +2040,7 @@ The amount of returned data is set by the device. Returns the number of bytes read (>=0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_READ_FAILED. -Block read. smbus 2.0 5.5.7 +Block read. SMBus 2.0 5.5.7 . . S Addr Wr [A] Comm [A] S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P @@ -2043,11 +2066,11 @@ i2cReg: 0-255, the register to write/read Returns the number of bytes read (>=0) if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or PI_I2C_READ_FAILED. -The smbus 2.0 documentation states that a minimum of 1 byte may be +The SMBus 2.0 documentation states that a minimum of 1 byte may be sent and a minimum of 1 byte may be received. The total number of bytes sent/received must be 32 or less. -Block write-block read. smbus 2.0 5.5.8 +Block write-block read. SMBus 2.0 5.5.8 . . S Addr Wr [A] Comm [A] Count [A] Data [A] ... S Addr Rd [A] [Count] A [Data] ... A P @@ -2101,6 +2124,14 @@ S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P . . D*/ +int bbI2COpen(unsigned SDA, unsigned SCL, unsigned bbBaud); + +int bbI2CClose(unsigned SDA); + +int bbI2CXfer( + unsigned SDA, + char *inBuf, unsigned inLen, char *outBuf, unsigned outLen); + /*F*/ int spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags); @@ -4252,6 +4283,12 @@ PARAMS*/ #define PI_CMD_CF1 87 #define PI_CMD_CF2 88 +#define PI_CMD_BI2CC 89 +#define PI_CMD_BI2CO 90 +#define PI_CMD_BI2CX 91 + +#define PI_CMD_I2CX 92 + #define PI_CMD_NOIB 99 /*DEF_E*/ @@ -4354,7 +4391,7 @@ after this command is issued. #define PI_BAD_WAVE_BAUD -35 // baud rate not 50-250K(RX)/50-1M(TX) #define PI_TOO_MANY_PULSES -36 // waveform has too many pulses #define PI_TOO_MANY_CHARS -37 // waveform has too many chars -#define PI_NOT_SERIAL_GPIO -38 // no serial read in progress on gpio +#define PI_NOT_SERIAL_GPIO -38 // no bit bang serial read in progress on gpio #define PI_BAD_SERIAL_STRUC -39 // bad (null) serial structure parameter #define PI_BAD_SERIAL_BUF -40 // bad (null) serial buf parameter #define PI_NOT_PERMITTED -41 // gpio operation not permitted @@ -4423,7 +4460,11 @@ after this command is issued. #define PI_BAD_MALLOC_MODE -104 // bad memory allocation mode #define PI_TOO_MANY_PARTS -105 // too many I2C transaction parts #define PI_BAD_I2C_PART -106 // a combined I2C transaction failed - +#define PI_BAD_SMBUS_CMD -107 // SMBus command not supported by driver +#define PI_NOT_I2C_GPIO -108 // no bit bang I2C in progress on gpio +#define PI_BAD_BB_WLEN -109 // bad BB write length +#define PI_BAD_BB_RLEN -110 // bad BB read length +#define PI_BAD_BB_CMD -111 // bad BB command #define PI_PIGIF_ERR_0 -2000 #define PI_PIGIF_ERR_99 -2099 @@ -4448,7 +4489,7 @@ after this command is issued. #define PI_DEFAULT_UPDATE_MASK_R0 0xFFFFFFFF #define PI_DEFAULT_UPDATE_MASK_R1 0x03E7CF93 #define PI_DEFAULT_UPDATE_MASK_R2 0xFBC7CF9C -#define PI_DEFAULT_UPDATE_MASK_R3 0x0080400FFFFFFCLL +#define PI_DEFAULT_UPDATE_MASK_R3 0x0080480FFFFFFCLL #define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL #define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO diff --git a/pigpio.py b/pigpio.py index 42518fc..cc43e58 100644 --- a/pigpio.py +++ b/pigpio.py @@ -197,20 +197,20 @@ i2c_close Closes an I2C device i2c_read_device Reads the raw I2C device i2c_write_device Writes the raw I2C device -i2c_write_quick smbus write quick -i2c_write_byte smbus write byte -i2c_read_byte smbus read byte -i2c_write_byte_data smbus write byte data -i2c_write_word_data smbus write word data -i2c_read_byte_data smbus read byte data -i2c_read_word_data smbus read word data -i2c_process_call smbus process call -i2c_write_block_data smbus write block data -i2c_read_block_data smbus read block data -i2c_block_process_call smbus block process call +i2c_write_quick SMBus write quick +i2c_write_byte SMBus write byte +i2c_read_byte SMBus read byte +i2c_write_byte_data SMBus write byte data +i2c_write_word_data SMBus write word data +i2c_read_byte_data SMBus read byte data +i2c_read_word_data SMBus read word data +i2c_process_call SMBus process call +i2c_write_block_data SMBus write block data +i2c_read_block_data SMBus read block data +i2c_block_process_call SMBus block process call -i2c_read_i2c_block_data smbus read I2C block data -i2c_write_i2c_block_data smbus write I2C block data +i2c_read_i2c_block_data SMBus read I2C block data +i2c_write_i2c_block_data SMBus write I2C block data SPI @@ -257,7 +257,7 @@ import threading import os import atexit -VERSION = "1.16" +VERSION = "1.17" exceptions = True @@ -304,6 +304,12 @@ PI_SCRIPT_RUNNING=2 PI_SCRIPT_WAITING=3 PI_SCRIPT_FAILED =4 +# notification flags + +NTFY_FLAGS_ALIVE = (1 << 6) +NTFY_FLAGS_WDOG = (1 << 5) +NTFY_FLAGS_GPIO = 31 + # pigpio command numbers _PI_CMD_MODES= 0 @@ -519,6 +525,10 @@ PI_BAD_DATABITS =-101 PI_BAD_STOPBITS =-102 PI_MSG_TOOBIG =-103 PI_BAD_MALLOC_MODE =-104 +_PI_TOO_MANY_PARTS =-105 +_PI_BAD_I2C_PART =-106 +PI_BAD_SMBUS_CMD =-107 +PI_NOT_I2C_GPIO =-108 # pigpio error text @@ -560,7 +570,7 @@ _errors=[ [PI_BAD_WAVE_BAUD , "baud rate not 50-250000(RX)/1000000(TX)"], [PI_TOO_MANY_PULSES , "waveform has too many pulses"], [PI_TOO_MANY_CHARS , "waveform has too many chars"], - [PI_NOT_SERIAL_GPIO , "no serial read in progress on gpio"], + [PI_NOT_SERIAL_GPIO , "no bit bang serial read in progress on gpio"], [PI_NOT_PERMITTED , "no permission to update gpio"], [PI_SOME_PERMITTED , "no permission to update one or more gpios"], [PI_BAD_WVSC_COMMND , "bad WVSC subcommand"], @@ -625,6 +635,10 @@ _errors=[ [PI_BAD_STOPBITS , "serial (half) stop bits not 2-8"], [PI_MSG_TOOBIG , "socket/pipe message too big"], [PI_BAD_MALLOC_MODE , "bad memory allocation mode"], + [_PI_TOO_MANY_PARTS , "too many I2C transaction parts"], + [_PI_BAD_I2C_PART , "a combined I2C transaction failed"], + [PI_BAD_SMBUS_CMD , "SMBus command not supported"], + [PI_NOT_I2C_GPIO , "no bit bang I2C in progress on gpio"], ] @@ -867,10 +881,11 @@ class _callback_thread(threading.Thread): if (cb.edge ^ newLevel): cb.func(cb.gpio, newLevel, tick) else: - gpio = flags & 31 - for cb in self.callbacks: - if cb.gpio == gpio: - cb.func(cb.gpio, TIMEOUT, tick) + if flags & NTFY_FLAGS_WDOG: + gpio = flags & NTFY_FLAGS_GPIO + for cb in self.callbacks: + if cb.gpio == gpio: + cb.func(cb.gpio, TIMEOUT, tick) self.sl.s.close() @@ -1993,7 +2008,7 @@ class pi(): Normally you would only use the [*i2c_**] functions if you are or will be connecting to the Pi over a network. If - you will always run on the local Pi use the standard smbus + you will always run on the local Pi use the standard SMBus module instead. ... @@ -2080,7 +2095,7 @@ class pi(): """ Sends a single bit to the device associated with handle. - smbus 2.0 5.5.1 - Quick command. + SMBus 2.0 5.5.1 - Quick command. handle:= >=0 (as returned by a prior call to [*i2c_open*]). bit:= 0 or 1, the value to write. @@ -2096,7 +2111,7 @@ class pi(): """ Sends a single byte to the device associated with handle. - smbus 2.0 5.5.2 - Send byte. + SMBus 2.0 5.5.2 - Send byte. handle:= >=0 (as returned by a prior call to [*i2c_open*]). byte_val:= 0-255, the value to write. @@ -2113,7 +2128,7 @@ class pi(): """ Reads a single byte from the device associated with handle. - smbus 2.0 5.5.3 - Receive byte. + SMBus 2.0 5.5.3 - Receive byte. handle:= >=0 (as returned by a prior call to [*i2c_open*]). @@ -2128,7 +2143,7 @@ class pi(): Writes a single byte to the specified register of the device associated with handle. - smbus 2.0 5.5.4 - Write byte. + SMBus 2.0 5.5.4 - Write byte. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. @@ -2156,7 +2171,7 @@ class pi(): Writes a single 16 bit word to the specified register of the device associated with handle. - smbus 2.0 5.5.4 - Write word. + SMBus 2.0 5.5.4 - Write word. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. @@ -2184,7 +2199,7 @@ class pi(): Reads a single byte from the specified register of the device associated with handle. - smbus 2.0 5.5.5 - Read byte. + SMBus 2.0 5.5.5 - Read byte. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. @@ -2204,7 +2219,7 @@ class pi(): Reads a single 16 bit word from the specified register of the device associated with handle. - smbus 2.0 5.5.5 - Read word. + SMBus 2.0 5.5.5 - Read word. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. @@ -2224,7 +2239,7 @@ class pi(): Writes 16 bits of data to the specified register of the device associated with handle and reads 16 bits of data in return. - smbus 2.0 5.5.6 - Process call. + SMBus 2.0 5.5.6 - Process call. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. @@ -2249,7 +2264,7 @@ class pi(): Writes up to 32 bytes to the specified register of the device associated with handle. - smbus 2.0 5.5.7 - Block write. + SMBus 2.0 5.5.7 - Block write. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. @@ -2281,7 +2296,7 @@ class pi(): Reads a block of up to 32 bytes from the specified register of the device associated with handle. - smbus 2.0 5.5.7 - Block read. + SMBus 2.0 5.5.7 - Block read. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. @@ -2316,13 +2331,13 @@ class pi(): associated with handle and reads a device specified number of bytes of data in return. - smbus 2.0 5.5.8 - Block write-block read. + SMBus 2.0 5.5.8 - Block write-block read. handle:= >=0 (as returned by a prior call to [*i2c_open*]). reg:= >=0, the device register. data:= the bytes to write. - The smbus 2.0 documentation states that a minimum of 1 byte may + The SMBus 2.0 documentation states that a minimum of 1 byte may be sent and a minimum of 1 byte may be received. The total number of bytes sent/received must be 32 or less. diff --git a/pigs.c b/pigs.c index e4e2421..1869164 100644 --- a/pigs.c +++ b/pigs.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 26+ +This version is for pigpio version 32+ */ #include @@ -141,7 +141,7 @@ void print_result(int sock, int rv, cmdCmd_t cmd) printf(cmdUsage); break; - case 6: /* CF2 I2CPK I2CRD I2CRI I2CRK SERR SLR SPIX SPIR */ + case 6: /* BI2CX CF2 I2CPK I2CRD I2CRI I2CRK SERR SLR SPIX SPIR */ printf("%d", r); if (r < 0) fatal("ERROR: %s", cmdErrStr(r)); if (r > 0) @@ -178,6 +178,7 @@ void get_extensions(int sock, int command, int res) { switch (command) { + case PI_CMD_BI2CX: case PI_CMD_CF2: case PI_CMD_I2CPK: case PI_CMD_I2CRD: diff --git a/setup.py b/setup.py index 8fec0ac..b027567 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from distutils.core import setup setup(name='pigpio', - version='1.16', + version='1.17', author='joan', author_email='joan@abyz.co.uk', maintainer='joan',