This commit is contained in:
joan 2015-03-02 22:38:55 +00:00
parent adb8c8dbf6
commit 68553c1ed6
5 changed files with 504 additions and 192 deletions

View File

@ -118,6 +118,8 @@ Pi_Hasher_t *Pi_Hasher(int gpio, Pi_Hasher_CB_t callback, int timeout)
gpioSetMode(gpio, PI_INPUT);
gpioSetAlertFuncEx(gpio, _cb, hasher);
return hasher;
}
void Pi_Hasher_cancel(Pi_Hasher_t *hasher)
@ -127,6 +129,8 @@ void Pi_Hasher_cancel(Pi_Hasher_t *hasher)
gpioSetAlertFunc(hasher->gpio, 0);
free(hasher);
hasher = NULL;
}
}

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 30+
This version is for pigpio version 31+
*/
#include <stdio.h>
@ -494,6 +494,8 @@ static errInfo_t errInfo[]=
{PI_BAD_DATABITS , "serial data bits not 1-32"},
{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"},
};

206
pigpio.3
View File

@ -2062,6 +2062,42 @@ 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.
.br
.br
For the smbus commands the low level transactions are shown at the end
of the function description. The following abbreviations are used.
.br
.br
.EX
S (1 bit) : Start bit
.br
P (1 bit) : Stop bit
.br
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
.br
A, NA (1 bit) : Accept and not accept bit.
.br
.br
.br
Addr (7 bits): I2C 7 bit address.
.br
Comm (8 bits): Command byte, a data byte which often selects a register.
.br
Data (8 bits): A data byte.
.br
Count (8 bits): A data byte containing the length of a block operation.
.br
.br
[..]: Data sent by the device.
.br
.EE
.IP "\fBint i2cClose(unsigned handle)\fP"
.IP "" 4
This closes the I2C device associated with the handle.
@ -2157,6 +2193,12 @@ PI_I2C_WRITE_FAILED.
.br
Quick command. smbus 2.0 5.5.1
.EX
S Addr Rd/Wr [A] P
.br
.EE
.IP "\fBint i2cWriteByte(unsigned handle, unsigned bVal)\fP"
.IP "" 4
This sends a single byte to the device associated with handle.
@ -2184,6 +2226,12 @@ PI_I2C_WRITE_FAILED.
.br
Send byte. smbus 2.0 5.5.2
.EX
S Addr Wr [A] Data [A] P
.br
.EE
.IP "\fBint i2cReadByte(unsigned handle)\fP"
.IP "" 4
This reads a single byte from the device associated with handle.
@ -2209,6 +2257,12 @@ or PI_I2C_READ_FAILED.
.br
Receive byte. smbus 2.0 5.5.3
.EX
S Addr Rd [A] [Data] NA P
.br
.EE
.IP "\fBint i2cWriteByteData(unsigned handle, unsigned i2cReg, unsigned bVal)\fP"
.IP "" 4
This writes a single byte to the specified register of the device
@ -2239,6 +2293,12 @@ PI_I2C_WRITE_FAILED.
.br
Write byte. smbus 2.0 5.5.4
.EX
S Addr Wr [A] Comm [A] Data [A] P
.br
.EE
.IP "\fBint i2cWriteWordData(unsigned handle, unsigned i2cReg, unsigned wVal)\fP"
.IP "" 4
This writes a single 16 bit word to the specified register of the device
@ -2269,6 +2329,12 @@ PI_I2C_WRITE_FAILED.
.br
Write word. smbus 2.0 5.5.4
.EX
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
.br
.EE
.IP "\fBint i2cReadByteData(unsigned handle, unsigned i2cReg)\fP"
.IP "" 4
This reads a single byte from the specified register of the device
@ -2297,6 +2363,12 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
Read byte. smbus 2.0 5.5.5
.EX
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
.br
.EE
.IP "\fBint i2cReadWordData(unsigned handle, unsigned i2cReg)\fP"
.IP "" 4
This reads a single 16 bit word from the specified register of the device
@ -2325,6 +2397,12 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
Read word. smbus 2.0 5.5.5
.EX
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
.br
.EE
.IP "\fBint i2cProcessCall(unsigned handle, unsigned i2cReg, unsigned wVal)\fP"
.IP "" 4
This writes 16 bits of data to the specified register of the device
@ -2355,6 +2433,14 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
Process call. smbus 2.0 5.5.6
.EX
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
.br
S Addr Rd [A] [DataLow] A [DataHigh] NA P
.br
.EE
.IP "\fBint i2cWriteBlockData(unsigned handle, unsigned i2cReg, char *buf, unsigned count)\fP"
.IP "" 4
This writes up to 32 bytes to the specified register of the device
@ -2387,6 +2473,12 @@ PI_I2C_WRITE_FAILED.
.br
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
.br
.EE
.IP "\fBint i2cReadBlockData(unsigned handle, unsigned i2cReg, char *buf)\fP"
.IP "" 4
This reads a block of up to 32 bytes from the specified register of
@ -2422,6 +2514,14 @@ PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
Block read. smbus 2.0 5.5.7
.EX
S Addr Wr [A] Comm [A]
.br
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
.br
.EE
.IP "\fBint i2cBlockProcessCall(unsigned handle, unsigned i2cReg, char *buf, unsigned count)\fP"
.IP "" 4
This writes data bytes to the specified register of the device
@ -2462,6 +2562,14 @@ bytes sent/received must be 32 or less.
.br
Block write-block read. smbus 2.0 5.5.8
.EX
S Addr Wr [A] Comm [A] Count [A] Data [A] ...
.br
S Addr Rd [A] [Count] A [Data] ... A P
.br
.EE
.IP "\fBint i2cReadI2CBlockData(unsigned handle, unsigned i2cReg, char *buf, unsigned count)\fP"
.IP "" 4
This reads count bytes from the specified register of the device
@ -2489,6 +2597,18 @@ i2cReg: 0-255, the register to read
Returns the number of bytes read (>0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
.br
.br
.EX
S Addr Wr [A] Comm [A]
.br
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
.br
.EE
.IP "\fBint i2cWriteI2CBlockData(unsigned handle, unsigned i2cReg, char *buf, unsigned count)\fP"
.IP "" 4
This writes 1 to 32 bytes to the specified register of the device
@ -2516,6 +2636,16 @@ i2cReg: 0-255, the register to write
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
.br
.br
.EX
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
.br
.EE
.IP "\fBint spiOpen(unsigned spiChan, unsigned spiBaud, unsigned spiFlags)\fP"
.IP "" 4
This function returns a handle for the SPI device on the channel.
@ -5697,10 +5827,6 @@ The number of bits stored in a buffer.
.br
.IP "\fBnumBytes\fP" 0
.br
.br
The number of bytes used to store characters in a string. Depending
on the number of bits per character there may be 1, 2, or 4 bytes
per character.
@ -5710,21 +5836,20 @@ per character.
.br
.IP "\fBnumPar\fP: 0-10" 0
.br
.br
The number of parameters passed to a script.
.br
.br
.IP "\fBnumParts\fP" 0
The number of parts in a combined I2C transaction.
.br
.br
.IP "\fBnumPulses\fP" 0
.br
.br
The number of pulses to be added to a waveform.
.br
@ -5732,10 +5857,6 @@ The number of pulses to be added to a waveform.
.br
.IP "\fBoffset\fP" 0
.br
.br
The associated data starts this number of microseconds from the start of
tghe waveform.
@ -5744,21 +5865,44 @@ tghe waveform.
.br
.IP "\fB*param\fP" 0
.br
.br
An array of script parameters.
.br
.br
.IP "\fB*parts\fP" 0
An array of the part transactions which make up a combined I2C transaction.
.br
.br
.IP "\fBpi_i2c_msg_t\fP" 0
.EX
typedef struct
.br
{
.br
uint16_t addr; // slave address
.br
uint16_t flags;
.br
uint16_t len; // msg length
.br
uint8_t *buf; // pointer to msg data
.br
} pi_i2c_msg_t;
.br
.EE
.br
.br
.IP "\fBport\fP: 1024-32000" 0
.br
.br
The port used to bind to the pigpio socket. Defaults to 8888.
.br
@ -5766,10 +5910,6 @@ The port used to bind to the pigpio socket. Defaults to 8888.
.br
.IP "\fBpos\fP" 0
.br
.br
The position of an item.
.br
@ -5777,10 +5917,6 @@ The position of an item.
.br
.IP "\fBprimaryChannel\fP: 0-14" 0
.br
.br
The DMA channel used to time the sampling of gpios and to time servo and
PWM pulses.
@ -6902,6 +7038,12 @@ A 16-bit word value.
#define PI_MSG_TOOBIG -103 // socket/pipe message too big
.br
#define PI_BAD_MALLOC_MODE -104 // bad memory allocation mode
.br
#define PI_TOO_MANY_PARTS -105 // too many I2C transaction parts
.br
#define PI_BAD_I2C_PART -106 // a combined I2C transaction failed
.br
.br
.br

353
pigpio.c
View File

@ -25,7 +25,9 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* pigpio version 30 */
/* pigpio version 31 */
/* include ------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
@ -178,7 +180,7 @@ bit 0 READ_LAST_NOT_SET_ERROR
6 C3 System Timer Compare 3
*/
/* --------------------------------------------------------------- */
/* define -------------------------------------------------------- */
#define THOUSAND 1000
#define MILLION 1000000
@ -283,14 +285,8 @@ bit 0 READ_LAST_NOT_SET_ERROR
} \
while (0)
static volatile uint32_t piModel = 1;
#define PI_PERI_BUS 0x7E000000
static volatile uint32_t pi_peri_phys = 0x20000000;
static volatile uint32_t pi_dram_bus = 0x40000000;
static volatile uint32_t pi_mem_flag = 0x00000004;
#define AUX_BASE (pi_peri_phys + 0x00215000)
#define CLK_BASE (pi_peri_phys + 0x00101000)
#define DMA_BASE (pi_peri_phys + 0x00007000)
@ -720,6 +716,7 @@ static volatile uint32_t pi_mem_flag = 0x00000004;
#define SRX_BUF_SIZE 8192
#define PI_I2C_SLAVE 0x0703
#define PI_I2C_RDWR 0x0707
#define PI_I2C_SMBUS 0x0720
#define PI_I2C_SMBUS_READ 1
@ -758,7 +755,31 @@ static volatile uint32_t pi_mem_flag = 0x00000004;
#define MB_UNLOCK_MEMORY_TAG 0x3000E
#define MB_RELEASE_MEMORY_TAG 0x3000F
/* --------------------------------------------------------------- */
#define PI_SCRIPT_FREE 0
#define PI_SCRIPT_RESERVED 1
#define PI_SCRIPT_IN_USE 2
#define PI_SCRIPT_DYING 3
#define PI_SCRIPT_HALT 0
#define PI_SCRIPT_RUN 1
#define PI_SCRIPT_DELETE 2
#define PI_SCRIPT_STACK_SIZE 256
#define PI_SPI_FLAGS_CHANNEL(x) ((x&7)<<29)
#define PI_SPI_FLAGS_GET_CHANNEL(x) (((x)>>29)&7)
#define PI_SPI_FLAGS_GET_BITLEN(x) (((x)>>16)&63)
#define PI_SPI_FLAGS_GET_RX_LSB(x) (((x)>>15)&1)
#define PI_SPI_FLAGS_GET_TX_LSB(x) (((x)>>14)&1)
#define PI_SPI_FLAGS_GET_3WREN(x) (((x)>>10)&15)
#define PI_SPI_FLAGS_GET_3WIRE(x) (((x)>>9)&1)
#define PI_SPI_FLAGS_GET_AUX_SPI(x) (((x)>>8)&1)
#define PI_SPI_FLAGS_GET_RESVD(x) (((x)>>5)&7)
#define PI_SPI_FLAGS_GET_CSPOLS(x) (((x)>>2)&7)
#define PI_SPI_FLAGS_GET_MODE(x) ((x)&3)
/* typedef ------------------------------------------------------- */
typedef void (*callbk_t) ();
@ -830,17 +851,6 @@ typedef struct
pthread_t pthId;
} gpioTimer_t;
#define PI_SCRIPT_FREE 0
#define PI_SCRIPT_RESERVED 1
#define PI_SCRIPT_IN_USE 2
#define PI_SCRIPT_DYING 3
#define PI_SCRIPT_HALT 0
#define PI_SCRIPT_RUN 1
#define PI_SCRIPT_DELETE 2
#define PI_SCRIPT_STACK_SIZE 256
typedef struct
{
unsigned id;
@ -892,19 +902,6 @@ typedef struct
uint32_t flags;
} spiInfo_t;
#define PI_SPI_FLAGS_CHANNEL(x) ((x&7)<<29)
#define PI_SPI_FLAGS_GET_CHANNEL(x) (((x)>>29)&7)
#define PI_SPI_FLAGS_GET_BITLEN(x) (((x)>>16)&63)
#define PI_SPI_FLAGS_GET_RX_LSB(x) (((x)>>15)&1)
#define PI_SPI_FLAGS_GET_TX_LSB(x) (((x)>>14)&1)
#define PI_SPI_FLAGS_GET_3WREN(x) (((x)>>10)&15)
#define PI_SPI_FLAGS_GET_3WIRE(x) (((x)>>9)&1)
#define PI_SPI_FLAGS_GET_AUX_SPI(x) (((x)>>8)&1)
#define PI_SPI_FLAGS_GET_RESVD(x) (((x)>>5)&7)
#define PI_SPI_FLAGS_GET_CSPOLS(x) (((x)>>2)&7)
#define PI_SPI_FLAGS_GET_MODE(x) ((x)&3)
typedef struct
{
uint32_t startTick;
@ -983,6 +980,12 @@ struct my_smbus_ioctl_data
union my_smbus_data *data;
};
typedef struct
{
pi_i2c_msg_t *msgs; /* pointers to pi_i2c_msgs */
uint32_t nmsgs; /* number of pi_i2c_msgs */
} my_i2c_rdwr_ioctl_data_t;
typedef struct
{
unsigned div;
@ -998,34 +1001,27 @@ typedef struct
unsigned size; /* in bytes */
} DMAMem_t;
/* --------------------------------------------------------------- */
/* global -------------------------------------------------------- */
/* initialise once then preserve */
static volatile gpioCfg_t gpioCfg =
{
PI_DEFAULT_BUFFER_MILLIS,
PI_DEFAULT_CLK_MICROS,
PI_DEFAULT_CLK_PERIPHERAL,
PI_DEFAULT_DMA_PRIMARY_CHANNEL,
PI_DEFAULT_DMA_SECONDARY_CHANNEL,
PI_DEFAULT_SOCKET_PORT,
PI_DEFAULT_IF_FLAGS,
0,
0,
PI_DEFAULT_MEM_ALLOC_MODE,
};
static volatile uint32_t piModel = 1;
static volatile uint32_t pi_peri_phys = 0x20000000;
static volatile uint32_t pi_dram_bus = 0x40000000;
static volatile uint32_t pi_mem_flag = 0x0C;
static volatile gpioStats_t gpioStats;
static int gpioMaskSet = 0;
static int libInitialised = 0;
/* initialise every gpioInitialise */
static struct timespec libStarted;
static int waveClockInited = 0;
/* initialse if not libInitialised */
static volatile gpioStats_t gpioStats;
static int gpioMaskSet = 0;
/* initialise if not libInitialised */
static uint64_t gpioMask;
@ -1058,8 +1054,7 @@ static volatile uint32_t notifyBits = 0;
static volatile uint32_t scriptBits = 0;
static volatile int DMAstarted = 0;
static int libInitialised = 0;
static volatile int terminating = 0;
static int pthAlertRunning = 0;
static int pthFifoRunning = 0;
@ -1085,19 +1080,7 @@ static gpioTimer_t gpioTimer [PI_MAX_TIMER+1];
static int pwmFreq[PWM_FREQS];
/* no initialisation required */
static unsigned bufferBlocks; /* number of blocks in buffer */
static unsigned bufferCycles; /* number of cycles */
static pthread_attr_t pthAttr;
static pthread_t pthAlert;
static pthread_t pthFifo;
static pthread_t pthSocket;
static gpioSample_t gpioSample[DATUMS];
static gpioReport_t gpioReport[DATUMS];
/* reset after gpioTerminated */
/* resources which must be released on gpioTerminate */
@ -1133,7 +1116,70 @@ static volatile uint32_t * systReg = MAP_FAILED;
static volatile uint32_t * dmaIn = MAP_FAILED;
static volatile uint32_t * dmaOut = MAP_FAILED;
/* constant data */
static uint32_t hw_clk_freq[3];
static uint32_t hw_pwm_freq[2];
static uint32_t hw_pwm_duty[2];
static uint32_t hw_pwm_real_range[2];
static volatile gpioCfg_t gpioCfg =
{
PI_DEFAULT_BUFFER_MILLIS,
PI_DEFAULT_CLK_MICROS,
PI_DEFAULT_CLK_PERIPHERAL,
PI_DEFAULT_DMA_PRIMARY_CHANNEL,
PI_DEFAULT_DMA_SECONDARY_CHANNEL,
PI_DEFAULT_SOCKET_PORT,
PI_DEFAULT_IF_FLAGS,
DBG_MIN_LEVEL,
0,
PI_DEFAULT_MEM_ALLOC_MODE,
};
/* no initialisation required */
static unsigned bufferBlocks; /* number of blocks in buffer */
static unsigned bufferCycles; /* number of cycles */
static pthread_t pthAlert;
static pthread_t pthFifo;
static pthread_t pthSocket;
static gpioSample_t gpioSample[DATUMS];
static gpioReport_t gpioReport[DATUMS];
static uint32_t spi_dummy;
static unsigned old_mode_ce0;
static unsigned old_mode_ce1;
static unsigned old_mode_sclk;
static unsigned old_mode_miso;
static unsigned old_mode_mosi;
static uint32_t old_spi_cs;
static uint32_t old_spi_clk;
static unsigned old_mode_ace0;
static unsigned old_mode_ace1;
static unsigned old_mode_ace2;
static unsigned old_mode_asclk;
static unsigned old_mode_amiso;
static unsigned old_mode_amosi;
static uint32_t old_spi_cntl0;
static uint32_t old_spi_cntl1;
/* const --------------------------------------------------------- */
static const uint8_t clkDef[PI_MAX_GPIO + 1] =
{
/* 0 1 2 3 4 5 6 7 8 9 */
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x84, 0x94, 0xA4, 0x00, 0x00, 0x00,
/* 1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 2 */ 0x82, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 3 */ 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 4 */ 0x00, 0x00, 0x94, 0xA4, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 5 */ 0x00, 0x00, 0x00, 0x00,
};
/*
7 6 5 4 3 2 1 0
@ -1156,17 +1202,15 @@ CC: 00 CLK0, 01 CLK1, 10 CLK2
gpio44 GPCLK1 ALT0 Compute module only (reserved for system use)
*/
uint32_t hw_clk_freq[3];
uint8_t clkDef[PI_MAX_GPIO + 1] =
static const uint8_t PWMDef[PI_MAX_GPIO + 1] =
{
/* 0 1 2 3 4 5 6 7 8 9 */
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x84, 0x94, 0xA4, 0x00, 0x00, 0x00,
/* 1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 2 */ 0x82, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 3 */ 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 4 */ 0x00, 0x00, 0x94, 0xA4, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 5 */ 0x00, 0x00, 0x00, 0x00,
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 1 */ 0x00, 0x00, 0x84, 0x94, 0x00, 0x00, 0x00, 0x00, 0x82, 0x92,
/* 2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 4 */ 0x84, 0x94, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00,
/* 5 */ 0x00, 0x00, 0x85, 0x95,
};
/*
@ -1188,21 +1232,6 @@ uint8_t clkDef[PI_MAX_GPIO + 1] =
gpio53 pwm1 ALT1
*/
uint32_t hw_pwm_freq[2];
uint32_t hw_pwm_duty[2];
uint32_t hw_pwm_real_range[2];
uint8_t PWMDef[PI_MAX_GPIO + 1] =
{
/* 0 1 2 3 4 5 6 7 8 9 */
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 1 */ 0x00, 0x00, 0x84, 0x94, 0x00, 0x00, 0x00, 0x00, 0x82, 0x92,
/* 2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 4 */ 0x84, 0x94, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00,
/* 5 */ 0x00, 0x00, 0x85, 0x95,
};
static const clkCfg_t clkCfg[]=
{
/* valid servo */
@ -1227,18 +1256,18 @@ static const uint16_t pwmRealRange[PWM_FREQS]=
{ 25, 50, 100, 125, 200, 250, 400, 500, 625,
800, 1000, 1250, 2000, 2500, 4000, 5000, 10000, 20000};
/* ======================================================================= */
/* Internal prototypes.
*/
/* prototype ----------------------------------------------------- */
static void intNotifyBits(void);
static void intScriptBits(void);
static int gpioNotifyOpenInBand(int fd);
static void initHWClk
(int clkCtl, int clkDiv, int clkSrc, int divI, int divF, int MASH);
static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr);
static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr);
/* ======================================================================= */
@ -1444,7 +1473,7 @@ static void flushMemory(void)
static void waitForDMAstarted(void)
{
while (!DMAstarted)
while ((!DMAstarted) && (!terminating))
{
if (piModel == 1) myGpioDelay(1000);
else flushMemory();
@ -1531,7 +1560,7 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
case PI_CMD_CF2:
/* a couple of extra precautions for untruested code */
/* a couple of extra precautions for untrusted code */
if (p[2] > bufSize) p[2] = bufSize;
res = gpioCustom2(p[1], buf, p[3], buf, p[2]);
if (res > p[2]) res = p[2];
@ -2110,7 +2139,7 @@ static void myGpioSetServo(unsigned gpio, int oldVal, int newVal)
https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
*/
int mbCreate(void)
static int mbCreate(void)
{
/* <0 error */
@ -2119,14 +2148,14 @@ int mbCreate(void)
return mknod(MB_DEV, S_IFCHR|0600, makedev(MB_DEV_MAJOR, 0));
}
int mbOpen(void)
static int mbOpen(void)
{
/* <0 error */
return open(MB_DEV, 0);
}
void mbClose(int fd)
static void mbClose(int fd)
{
close(fd);
}
@ -2136,7 +2165,7 @@ static int mbProperty(int fd, void *buf)
return ioctl(fd, MB_IOCTL, buf);
}
unsigned mbAllocateMemory(
static unsigned mbAllocateMemory(
int fd, unsigned size, unsigned align, unsigned flags)
{
int i=1;
@ -2157,7 +2186,7 @@ unsigned mbAllocateMemory(
return p[5];
}
unsigned mbLockMemory(int fd, unsigned handle)
static unsigned mbLockMemory(int fd, unsigned handle)
{
int i=1;
unsigned p[32];
@ -2175,7 +2204,7 @@ unsigned mbLockMemory(int fd, unsigned handle)
return p[5];
}
unsigned mbUnlockMemory(int fd, unsigned handle)
static unsigned mbUnlockMemory(int fd, unsigned handle)
{
int i=1;
unsigned p[32];
@ -2193,7 +2222,7 @@ unsigned mbUnlockMemory(int fd, unsigned handle)
return p[5];
}
unsigned mbReleaseMemory(int fd, unsigned handle)
static unsigned mbReleaseMemory(int fd, unsigned handle)
{
int i=1;
unsigned p[32];
@ -2211,7 +2240,7 @@ unsigned mbReleaseMemory(int fd, unsigned handle)
return p[5];
}
void *mbMapMem(unsigned base, unsigned size)
static void *mbMapMem(unsigned base, unsigned size)
{
void *mem = MAP_FAILED;
@ -2220,13 +2249,13 @@ void *mbMapMem(unsigned base, unsigned size)
return mem;
}
int mbUnmapMem(void *addr, unsigned size)
static int mbUnmapMem(void *addr, unsigned size)
{
/* 0 okay, -1 fail */
return munmap(addr, size);
}
void mbDMAFree(DMAMem_t *DMAMemP)
static void mbDMAFree(DMAMem_t *DMAMemP)
{
if (DMAMemP->handle)
{
@ -2237,7 +2266,7 @@ void mbDMAFree(DMAMem_t *DMAMemP)
}
}
int mbDMAAlloc(DMAMem_t *DMAMemP, unsigned size, uint32_t pi_mem_flag)
static int mbDMAAlloc(DMAMem_t *DMAMemP, unsigned size, uint32_t pi_mem_flag)
{
DMAMemP->size = size;
@ -3388,31 +3417,51 @@ int i2cClose(unsigned handle)
return 0;
}
int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts)
{
int retval, fd;
my_i2c_rdwr_ioctl_data_t rdwr;
DBG(DBG_USER, "handle=%d", handle);
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 (parts == NULL)
SOFT_ERROR(PI_BAD_POINTER, "null parts");
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;
retval = ioctl(i2cInfo[handle].fd, PI_I2C_RDWR, &rdwr);
DBG(0, "i2cTransaction retval=%d", retval);
if (retval >= 0) return retval;
else return PI_BAD_I2C_PART;
}
/* ======================================================================= */
/*SPI */
static uint32_t spi_dummy; /* only used to prevent warning */
static unsigned old_mode_ce0;
static unsigned old_mode_ce1;
static unsigned old_mode_sclk;
static unsigned old_mode_miso;
static unsigned old_mode_mosi;
static uint32_t old_spi_cs;
static uint32_t old_spi_clk;
static unsigned old_mode_ace0;
static unsigned old_mode_ace1;
static unsigned old_mode_ace2;
static unsigned old_mode_asclk;
static unsigned old_mode_amiso;
static unsigned old_mode_amosi;
static uint32_t old_spi_cntl0;
static uint32_t old_spi_cntl1;
static uint32_t _spiTXBits(char *buf, int pos, int bitlen, int msbf)
{
uint32_t bits=0;
@ -3767,7 +3816,7 @@ static void spiInit(uint32_t flags)
}
}
void spiTerm(uint32_t flags)
static void spiTerm(uint32_t flags)
{
int resvd;
@ -6343,6 +6392,7 @@ static void initClearGlobals(void)
libInitialised = 0;
DMAstarted = 0;
terminating = 0;
pthAlertRunning = 0;
pthFifoRunning = 0;
@ -6598,19 +6648,22 @@ static void initReleaseResources(void)
int initInitialise(void)
{
int i;
int rev, i;
struct sockaddr_in server;
char * portStr;
unsigned port;
struct sched_param param;
pthread_attr_t pthAttr;
DBG(DBG_STARTUP, "");
if (libInitialised) return PIGPIO_VERSION;
waveClockInited = 0;
clock_gettime(CLOCK_REALTIME, &libStarted);
DBG(DBG_STARTUP, "");
if (libInitialised) return PIGPIO_VERSION;
rev = gpioHardwareRevision();
initClearGlobals();
@ -6623,12 +6676,10 @@ int initInitialise(void)
if (!gpioMaskSet)
{
i = gpioHardwareRevision();
if (i == 0) gpioMask = PI_DEFAULT_UPDATE_MASK_R0;
else if (i == 17) gpioMask = PI_DEFAULT_UPDATE_MASK_COMPUTE;
else if (i < 4) gpioMask = PI_DEFAULT_UPDATE_MASK_R1;
else if (i < 16) gpioMask = PI_DEFAULT_UPDATE_MASK_R2;
if (rev == 0) gpioMask = PI_DEFAULT_UPDATE_MASK_R0;
else if (rev == 17) gpioMask = PI_DEFAULT_UPDATE_MASK_COMPUTE;
else if (rev < 4) gpioMask = PI_DEFAULT_UPDATE_MASK_R1;
else if (rev < 16) gpioMask = PI_DEFAULT_UPDATE_MASK_R2;
else gpioMask = PI_DEFAULT_UPDATE_MASK_R3;
gpioMaskSet = 1;
@ -6937,10 +6988,14 @@ void gpioTerminate(void)
DBG(DBG_USER, "");
gpioMaskSet = 0;
terminating = 1;
if (libInitialised)
{
libInitialised = 0;
gpioMaskSet = 0;
/* reset DMA */
DMAstarted = 0;
@ -6948,8 +7003,6 @@ void gpioTerminate(void)
dmaIn[DMA_CS] = DMA_CHANNEL_RESET;
dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
libInitialised = 0;
if (gpioCfg.showStats)
{
fprintf(stderr,
@ -8573,6 +8626,8 @@ static int intGpioSetTimerFunc(unsigned id,
int user,
void *userdata)
{
pthread_attr_t pthAttr;
DBG(DBG_INTERNAL, "id=%d millis=%d function=%08X user=%d userdata=%08X",
id, millis, (uint32_t)f, user, (uint32_t)userdata);
@ -8587,6 +8642,14 @@ static int intGpioSetTimerFunc(unsigned id,
if (!gpioTimer[id].running)
{
if (pthread_attr_init(&pthAttr))
SOFT_ERROR(PI_TIMER_FAILED,
"pthread_attr_init failed (%m)");
if (pthread_attr_setstacksize(&pthAttr, STACK_SIZE))
SOFT_ERROR(PI_TIMER_FAILED,
"pthread_attr_setstacksize failed (%m)");
if (pthread_create(
&gpioTimer[id].pthId, &pthAttr, pthTimerTick, &gpioTimer[id]))
SOFT_ERROR(PI_TIMER_FAILED,
@ -9377,7 +9440,7 @@ unsigned gpioHardwareRevision(void)
chars = 4;
pi_peri_phys = 0x20000000;
pi_dram_bus = 0x40000000;
pi_mem_flag = 0x0c;
pi_mem_flag = 0x0C;
}
else if (strstr (buf, "ARMv7") != NULL)
{

121
pigpio.h
View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h>
#include <pthread.h>
#define PIGPIO_VERSION 30
#define PIGPIO_VERSION 31
/*TEXT
@ -319,6 +319,8 @@ OVERVIEW*/
#define PI_LOCKFILE "/var/run/pigpio.pid"
#define PI_I2C_COMBINED "/sys/module/i2c_bcm2708/parameters/combined"
#ifdef __cplusplus
extern "C" {
#endif
@ -399,6 +401,29 @@ 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 */
uint16_t flags;
uint16_t len; /* msg length */
uint8_t *buf; /* pointer to msg data */
} pi_i2c_msg_t;
typedef void (*gpioAlertFunc_t) (int gpio,
int level,
uint32_t tick);
@ -1699,7 +1724,6 @@ user_gpio: 0-31, previously opened with [*gpioSerialReadOpen*]
Returns 0 if OK, otherwise PI_BAD_USER_GPIO, or PI_NOT_SERIAL_GPIO.
D*/
/*F*/
int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags);
/*D
@ -1715,6 +1739,22 @@ 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
of the function description. The following abbreviations are used.
. .
S (1 bit) : Start bit
P (1 bit) : Stop bit
Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
A, NA (1 bit) : Accept and not accept bit.
Addr (7 bits): I2C 7 bit address.
Comm (8 bits): Command byte, a data byte which often selects a register.
Data (8 bits): A data byte.
Count (8 bits): A data byte containing the length of a block operation.
[..]: Data sent by the device.
. .
D*/
@ -1762,6 +1802,10 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
D*/
int i2cTransaction(unsigned handle, pi_i2c_msg_t *parts, unsigned numParts);
/*
This performs a combined I2C transction made up of count parts.
*/
/*F*/
int i2cWriteQuick(unsigned handle, unsigned bit);
@ -1778,6 +1822,9 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
Quick command. smbus 2.0 5.5.1
. .
S Addr Rd/Wr [A] P
. .
D*/
@ -1795,6 +1842,9 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
Send byte. smbus 2.0 5.5.2
. .
S Addr Wr [A] Data [A] P
. .
D*/
@ -1811,6 +1861,9 @@ Returns the byte read (>=0) if OK, otherwise PI_BAD_HANDLE,
or PI_I2C_READ_FAILED.
Receive byte. smbus 2.0 5.5.3
. .
S Addr Rd [A] [Data] NA P
. .
D*/
@ -1830,6 +1883,9 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
Write byte. smbus 2.0 5.5.4
. .
S Addr Wr [A] Comm [A] Data [A] P
. .
D*/
@ -1849,6 +1905,9 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
Write word. smbus 2.0 5.5.4
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
. .
D*/
@ -1867,6 +1926,9 @@ 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
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P
. .
D*/
@ -1885,6 +1947,9 @@ 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
. .
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
. .
D*/
@ -1904,6 +1969,10 @@ 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
. .
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A]
S Addr Rd [A] [DataLow] A [DataHigh] NA P
. .
D*/
@ -1925,6 +1994,9 @@ Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
Block write. smbus 2.0 5.5.7
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
. .
D*/
@ -1946,6 +2018,10 @@ 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
. .
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
. .
D*/
@ -1972,6 +2048,10 @@ 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
. .
S Addr Wr [A] Comm [A] Count [A] Data [A] ...
S Addr Rd [A] [Count] A [Data] ... A P
. .
D*/
@ -1991,6 +2071,11 @@ i2cReg: 0-255, the register to read
Returns the number of bytes read (>0) if OK, otherwise PI_BAD_HANDLE,
PI_BAD_PARAM, or PI_I2C_READ_FAILED.
. .
S Addr Wr [A] Comm [A]
S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
. .
D*/
@ -2010,6 +2095,10 @@ i2cReg: 0-255, the register to write
Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_PARAM, or
PI_I2C_WRITE_FAILED.
. .
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
. .
D*/
@ -3742,38 +3831,47 @@ numBits::
The number of bits stored in a buffer.
numBytes::
The number of bytes used to store characters in a string. Depending
on the number of bits per character there may be 1, 2, or 4 bytes
per character.
numPar:: 0-10
The number of parameters passed to a script.
numPulses::
numParts::
The number of parts in a combined I2C transaction.
numPulses::
The number of pulses to be added to a waveform.
offset::
The associated data starts this number of microseconds from the start of
tghe waveform.
*param::
An array of script parameters.
port:: 1024-32000
*parts::
An array of the part transactions which make up a combined I2C transaction.
pi_i2c_msg_t::
. .
typedef struct
{
uint16_t addr; // slave address
uint16_t flags;
uint16_t len; // msg length
uint8_t *buf; // pointer to msg data
} pi_i2c_msg_t;
. .
port:: 1024-32000
The port used to bind to the pigpio socket. Defaults to 8888.
pos::
The position of an item.
primaryChannel:: 0-14
The DMA channel used to time the sampling of gpios and to time servo and
PWM pulses.
@ -4323,6 +4421,9 @@ after this command is issued.
#define PI_BAD_STOPBITS -102 // serial (half) stop bits not 2-8
#define PI_MSG_TOOBIG -103 // socket/pipe message too big
#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_PIGIF_ERR_0 -2000
#define PI_PIGIF_ERR_99 -2099