From adb8c8dbf657f674849d4fe71aae416db6c6d786 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 25 Feb 2015 20:34:52 +0000 Subject: [PATCH] V30 --- EXAMPLES/C/IR_RECEIVER/test_ir_hasher.c | 2 +- EXAMPLES/CPP/IR_RECEIVER/test_ir_hasher.cpp | 2 +- README | 6 + command.c | 18 +- pigpio.3 | 365 ++++-- pigpio.c | 1170 ++++++++++++------- pigpio.h | 252 ++-- pigpio.py | 210 ++-- pigpiod.1 | 19 +- pigpiod.c | 15 +- pigpiod_if.3 | 252 +++- pigpiod_if.c | 2 +- pigpiod_if.h | 164 ++- pigs.1 | 157 ++- setup.py | 2 +- x_pigs | 10 +- x_pipe | 12 +- 17 files changed, 1810 insertions(+), 848 deletions(-) diff --git a/EXAMPLES/C/IR_RECEIVER/test_ir_hasher.c b/EXAMPLES/C/IR_RECEIVER/test_ir_hasher.c index 878bdb8..28673b7 100644 --- a/EXAMPLES/C/IR_RECEIVER/test_ir_hasher.c +++ b/EXAMPLES/C/IR_RECEIVER/test_ir_hasher.c @@ -12,7 +12,7 @@ An IR receiver output pin connected to a Pi gpio. TO BUILD -gcc -o ir_hash_c test_ir_hasher.c ir_hasher.c -lpigpio -lrt +gcc -o ir_hash_c test_ir_hasher.c ir_hasher.c -lpigpio -lrt -lpthread TO RUN diff --git a/EXAMPLES/CPP/IR_RECEIVER/test_ir_hasher.cpp b/EXAMPLES/CPP/IR_RECEIVER/test_ir_hasher.cpp index a852220..40788cc 100644 --- a/EXAMPLES/CPP/IR_RECEIVER/test_ir_hasher.cpp +++ b/EXAMPLES/CPP/IR_RECEIVER/test_ir_hasher.cpp @@ -12,7 +12,7 @@ An IR receiver output pin connected to a Pi gpio. TO BUILD -g++ -o ir_hash_cpp test_ir_hasher.cpp ir_hasher.cpp -lpigpio -lrt +g++ -o ir_hash_cpp test_ir_hasher.cpp ir_hasher.cpp -lpigpio -lrt -lpthread TO RUN diff --git a/README b/README index 381a237..8b975e2 100644 --- a/README +++ b/README @@ -1,3 +1,9 @@ +NOTE + +The initial part of the make, the compilation of pigpio.c, +takes 100 seconds on early model Pis. Be patient. The overall +install takes just over 3 minutes. + INSTALL Extract the archive to a directory. diff --git a/command.c b/command.c index 53b8074..b875d11 100644 --- a/command.c +++ b/command.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 26+ +This version is for pigpio version 30+ */ #include @@ -345,7 +345,7 @@ WVTXR wid Transmit wave repeatedly\n\ bits = a mask where (1<=0)\n\ @@ -359,8 +359,8 @@ num = number of bytes to read\n\ o = offset (>=0)\n\ p = pud (ODU)\n\ pars = 0 to 10 parameters for script\n\ -pdc = hardware PWM dutycycle (0-5000)\n\ -pf = hardware PWM frequency (5-50K)\n\ +pdc = hardware PWM dutycycle (0-1M)\n\ +pf = hardware PWM frequency (1-125M)\n\ pl = pulse length (1-100)\n\ r = register\n\ sid = script id (>=0)\n\ @@ -486,14 +486,14 @@ static errInfo_t errInfo[]= {PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"}, {PI_NOT_HCLK_GPIO , "gpio has no hardware clock"}, {PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"}, - {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-50K"}, - {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-5000"}, - {PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"}, + {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 1-125M"}, + {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1M"}, + {PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-250M"}, {PI_BAD_HCLK_PASS , "need password to use hardware clock 1"}, {PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"}, {PI_BAD_DATABITS , "serial data bits not 1-32"}, - {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"}, }; diff --git a/pigpio.3 b/pigpio.3 index 1d0231c..b766fb5 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -154,7 +154,7 @@ All the functions which return an int return < 0 on error. .br .br -If the library isn't initialised all but the \fBgpioCfg*\fP, \fBgpioVersion\fP, +If the library is not initialised all but the \fBgpioCfg*\fP, \fBgpioVersion\fP, and \fBgpioHardwareRevision\fP functions will return PI_NOT_INITIALISED. .br @@ -230,7 +230,7 @@ Call before program exit. .br .br -This function resets the DMA and PWM peripherals, releases memory, and +This function resets the used DMA channels, releases memory, and terminates any running threads. .br @@ -531,10 +531,19 @@ PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. .br For normal PWM the dutycycle will be out of the defined range -for the gpio (see \fBgpioGetPWMrange\fP). If a hardware clock is -active on the gpio the reported dutycycle will be 500 (out of 1000). +for the gpio (see \fBgpioGetPWMrange\fP). + +.br + +.br +If a hardware clock is active on the gpio the reported dutycycle +will be 500000 (500k) out of 1000000 (1M). + +.br + +.br If hardware PWM is active on the gpio the reported dutycycle -will be out of a 1000. +will be out of a 1000000 (1M). .br @@ -628,7 +637,7 @@ user_gpio: 0-31 .br If a hardware clock or hardware PWM is active on the gpio -the reported range will be 1000. +the reported range will be 1000000 (1M). .br @@ -660,8 +669,14 @@ user_gpio: 0-31 .br .br -If a hardware clock or hardware PWM is active on the gpio -the reported real range will be 1000. +If a hardware clock is active on the gpio the reported real +range will be 1000000 (1M). + +.br + +.br +If hardware PWM is active on the gpio the reported real range +will be approximately 250M divided by the set PWM frequency. .br @@ -807,8 +822,17 @@ user_gpio: 0-31 .br For normal PWM the frequency will be that defined for the gpio by -\fBgpioSetPWMfrequency\fP. If a hardware clock is active on the gpio -the reported frequency will be that set by \fBgpioHardwareClock\fP. +\fBgpioSetPWMfrequency\fP. + +.br + +.br +If a hardware clock is active on the gpio the reported frequency +will be that set by \fBgpioHardwareClock\fP. + +.br + +.br If hardware PWM is active on the gpio the reported frequency will be that set by \fBgpioHardwarePWM\fP. @@ -1985,7 +2009,9 @@ data bits \fBbbBits\fP specified in the \fBgpioSerialReadOpen\fP command. .br For \fBbbBits\fP 1-8 there will be one byte per character. +.br For \fBbbBits\fP 9-16 there will be two bytes per character. +.br For \fBbbBits\fP 17-32 there will be four bytes per character. .IP "\fBint gpioSerialReadClose(unsigned user_gpio)\fP" @@ -2500,7 +2526,7 @@ active low chip select. .br .br -An auxiliary SPI device is available on the B+ and may be +An auxiliary SPI device is available on the A+/B+/Pi2 and may be selected by setting the A bit in the flags. The auxiliary device has 3 chip selects and a selectable word size in bits. @@ -2509,7 +2535,7 @@ device has 3 chip selects and a selectable word size in bits. .br .EX - spiChan: 0-1 (0-2 for B+ auxiliary device) + spiChan: 0-1 (0-2 for A+/B+/Pi2 auxiliary device) .br spiBaud: 32K-125M (values above 30M are unlikely to work) .br @@ -2548,6 +2574,11 @@ mm defines the SPI mode. .br +.br +Warning: modes 1 and 3 do not appear to work on the auxiliary device. + +.br + .br .EX @@ -2578,7 +2609,7 @@ ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise. .br A is 0 for the standard SPI device, 1 for the auxiliary SPI. The -auxiliary device is only present on the B+. +auxiliary device is only present on the A+/B+/Pi2. .br @@ -3641,6 +3672,7 @@ gpioWrite_Bits_32_53_Set((1<<(32-32)) | (1<<(40-32)) | (1<<(53-32))); .IP "\fBint gpioHardwareClock(unsigned gpio, unsigned clkfreq)\fP" .IP "" 4 Starts a hardware clock on a gpio at the specified frequency. +Frequencies above 30MHz are unlikely to work. .br @@ -3649,7 +3681,7 @@ Starts a hardware clock on a gpio at the specified frequency. .EX gpio: see description .br -clkfreq: 0 (off) or 4689-250M +clkfreq: 0 (off) or 4689-250000000 (250M) .br .EE @@ -3678,11 +3710,11 @@ The gpio must be one of the following. .EX 4 clock 0 All models .br -5 clock 1 A+/B+ and compute module only (reserved for system use) +5 clock 1 A+/B+/Pi2 and compute module only (reserved for system use) .br -6 clock 2 A+/B+ and compute module only +6 clock 2 A+/B+/Pi2 and compute module only .br -20 clock 0 A+/B+ and compute module only +20 clock 0 A+/B+/Pi2 and compute module only .br 21 clock 1 All models but Rev.2 B (reserved for system use) .br @@ -3711,6 +3743,7 @@ gpio number. .IP "\fBint gpioHardwarePWM(unsigned gpio, unsigned PWMfreq, unsigned PWMduty)\fP" .IP "" 4 Starts hardware PWM on a gpio at the specified frequency and dutycycle. +Frequencies above 30MHz are unlikely to work. .br @@ -3732,9 +3765,9 @@ main clock defaults to PCM but may be overridden by a call to .EX gpio: see description .br -PWMfreq: 0 (off) or 5-250K +PWMfreq: 0 (off) or 1-125000000 (125M) .br -PWMduty: 0 (off) to 1000 (fully on). +PWMduty: 0 (off) to 1000000 (1M)(fully on) .br .EE @@ -3748,10 +3781,9 @@ PI_BAD_HPWM_DUTY, PI_BAD_HPWM_FREQ, or PI_HPWM_ILLEGAL. .br .br -Both PWM channels share the same clock and the same update frequency. -The latest frequency setting will be used by both PWM channels. The -same PWM channel is available on multiple gpios. The latest -dutycycle setting will be used by all gpios which share a PWM channel. +The same PWM channel is available on multiple gpios. The latest +frequency and dutycycle setting will be used by all gpios which +share a PWM channel. .br @@ -3763,13 +3795,13 @@ The gpio must be one of the following. .br .EX -12 PWM channel 0 A+/B+ and compute module only +12 PWM channel 0 A+/B+/Pi2 and compute module only .br -13 PWM channel 1 A+/B+ and compute module only +13 PWM channel 1 A+/B+/Pi2 and compute module only .br 18 PWM channel 0 All models .br -19 PWM channel 1 A+/B+ and compute module only +19 PWM channel 1 A+/B+/Pi2 and compute module only .br .br @@ -3998,14 +4030,14 @@ number the function returns 0. .br .br -The hardware revision is the last 4 characters on the Revision line of +The hardware revision is the last few characters on the Revision line of /proc/cpuinfo. .br .br The revision number can be used to determine the assignment of gpios -to pins. +to pins (see \fBgpio\fP). .br @@ -4014,23 +4046,6 @@ There are at least three types of board. .br -.br -Type 1 has gpio 0 on P1-3, gpio 1 on P1-5, and gpio 21 on P1-13. - -.br - -.br -Type 2 has gpio 2 on P1-3, gpio 3 on P1-5, gpio 27 on P1-13, and -gpios 28-31 on P5. - -.br - -.br -Type 3 has a 40 pin connector rather than the 26 pin connector of -the earlier boards. Gpios 0 to 27 are brought out to the connector. - -.br - .br Type 1 boards have hardware revision numbers of 2 and 3. @@ -4042,7 +4057,7 @@ Type 2 boards have hardware revision numbers of 4, 5, 6, and 15. .br .br -Type 3 boards have hardware revision number 16. +Type 3 boards have hardware revision numbers of 16 or greater. .br @@ -4121,7 +4136,7 @@ sample 4 8 12 18 31 55 107 --- .IP "\fBint gpioCfgClock(unsigned cfgMicros, unsigned cfgPeripheral, unsigned cfgSource)\fP" .IP "" 4 -Configures pigpio to use a particualar sample rate timed by a specified +Configures pigpio to use a particular sample rate timed by a specified peripheral. .br @@ -4309,7 +4324,50 @@ The default setting (0) is that both interfaces are enabled. Or in PI_DISABLE_FIFO_IF to disable the pipe interface. Or in PI_DISABLE_SOCK_IF to disable the socket interface. -.IP "\fBint gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned count)\fP" +.IP "\fBint gpioCfgMemAlloc(unsigned memAllocMode)\fP" +.IP "" 4 +Selects the method of DMA memory allocation. + +.br + +.br + +.EX +memAllocMode: 0-2 +.br + +.EE + +.br + +.br +There are two methods of DMA memory allocation. The original method +uses the /proc/self/pagemap file to allocate bus memory. The new +method uses the mailbox property interface to allocate bus memory. + +.br + +.br +Auto will use the mailbox method unless a larger than default buffer +size is requested with \fBgpioCfgBufferSize\fP. + +.IP "\fBint gpioCfgInternals(unsigned cfgWhat, int cfgVal)\fP" +.IP "" 4 +Used to tune internal settings. + +.br + +.br + +.EX +cfgWhat: see source code +.br + cfgVal: see source code +.br + +.EE + +.IP "\fBint gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned argc)\fP" .IP "" 4 This function is available for user customisation. @@ -4323,13 +4381,13 @@ It returns a single integer value. .br .EX - arg1: >=0 +arg1: >=0 .br - arg2: >=0 +arg2: >=0 .br - argx: extra (byte) arguments +argx: extra (byte) arguments .br -count: number of extra arguments +argc: number of extra arguments .br .EE @@ -4339,7 +4397,7 @@ count: number of extra arguments .br Returns >= 0 if OK, less than 0 indicates a user defined error. -.IP "\fBint gpioCustom2(unsigned arg1, char *argx, unsigned count, char *retBuf, unsigned retMax)\fP" +.IP "\fBint gpioCustom2(unsigned arg1, char *argx, unsigned argc, char *retBuf, unsigned retMax)\fP" .IP "" 4 This function is available for user customisation. @@ -4359,7 +4417,7 @@ The returned value is an integer indicating the number of returned bytes. .br argx: extra (byte) arguments .br - count: number of extra arguments + argc: number of extra arguments .br retBuf: buffer for returned bytes .br @@ -4378,27 +4436,6 @@ Returns >= 0 if OK, less than 0 indicates a user defined error. .br The number of returned bytes must be retMax or less. -.IP "\fBint gpioCfgInternals(unsigned cfgWhat, int cfgVal)\fP" -.IP "" 4 -Used to tune internal settings. - -.br - -.br - -.EX -cfgWhat: see source code -.br - cfgVal: see source code -.br - -.EE - -.br - -.br -Not intended for general use. - .IP "\fBint rawWaveAddSPI(rawSPI_t *spi, unsigned offset, unsigned spiSS, char *buf, unsigned spiTxBits, unsigned spiBitFirst, unsigned spiBitLast, unsigned spiBits)\fP" .IP "" 4 This function adds a waveform representing SPI data to the @@ -4724,6 +4761,53 @@ A pointer to a void object passed to a thread started by gpioStartThread. .br +.IP "\fBarg1\fP" 0 + +.br + +.br +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +.br + +.br + +.IP "\fBarg2\fP" 0 + +.br + +.br +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +.br + +.br + +.IP "\fBargc\fP" 0 + +.br + +.br +The count of bytes passed to a user customised function. + +.br + +.br + +.IP "\fB*argx\fP" 0 + +.br + +.br +A pointer to an array of bytes passed to a user customised function. +Its meaning and content is defined by the customiser. + +.br + +.br + .IP "\fBbbBaud\fP" 0 .br @@ -5086,6 +5170,61 @@ A Broadcom numbered gpio, in the range 0-53. .br +.br +There are 54 General Purpose Input Outputs (gpios) named gpio0 through +gpio53. + +.br + +.br +They are split into two banks. Bank 1 consists of gpio0 through +gpio31. Bank 2 consists of gpio32 through gpio53. + +.br + +.br +All the gpios which are safe for the user to read and write are in +bank 1. Not all gpios in bank 1 are safe though. Type 1 boards +have 17 safe gpios. Type 2 boards have 21. Type 3 boards have 26. + +.br + +.br +See \fBgpioHardwareRevision\fP. + +.br + +.br +The user gpios are marked with an X in the following table. + +.br + +.br + +.EX + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +.br +Type 1 X X - - X - - X X X X X - - X X +.br +Type 2 - - X X X - - X X X X X - - X X +.br +Type 3 X X X X X X X X X X X X X X +.br + +.br + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +.br +Type 1 - X X - - X X X X X - - - - - - +.br +Type 2 - X X - - - X X X X - X X X X X +.br +Type 3 X X X X X X X X X X X X - - - - +.br + +.EE + +.br + .br .IP "\fBgpioAlertFunc_t\fP" 0 @@ -5139,6 +5278,8 @@ One of \fBgpioCfgInternals\fP .br \fBgpioCfgSocketPort\fP +.br +\fBgpioCfgMemAlloc\fP .br @@ -5451,6 +5592,31 @@ A 32-bit word value. .br +.IP "\fBmemAllocMode\fP: 0-2" 0 + +.br + +.br +The DMA memory allocation mode. + +.br + +.br + +.EX +PI_MEM_ALLOC_AUTO 0 +.br +PI_MEM_ALLOC_PAGEMAP 1 +.br +PI_MEM_ALLOC_MAILBOX 2 +.br + +.EE + +.br + +.br + .IP "\fB*micros\fP" 0 .br @@ -5704,7 +5870,7 @@ PI_MAX_SERVO_PULSEWIDTH 2500 .br -.IP "\fBPWMduty\fP: 0-1000" 0 +.IP "\fBPWMduty\fP: 0-1000000 (1M)" 0 The hardware PWM dutycycle. .br @@ -5712,7 +5878,7 @@ The hardware PWM dutycycle. .br .EX -#define PI_HW_PWM_RANGE 5000 +#define PI_HW_PWM_RANGE 1000000 .br .EE @@ -5729,9 +5895,9 @@ The hardware PWM frequency. .br .EX -#define PI_HW_PWM_MIN_FREQ 5 +#define PI_HW_PWM_MIN_FREQ 1 .br -#define PI_HW_PWM_MAX_FREQ 50000 +#define PI_HW_PWM_MAX_FREQ 125000000 .br .EE @@ -5864,6 +6030,28 @@ typedef struct .br +.IP "\fB*retBuf\fP" 0 + +.br + +.br +A buffer to hold a number of bytes returned to a used customised function, + +.br + +.br + +.IP "\fBretMax\fP" 0 + +.br + +.br +The maximum number of bytes a user customised function should return. + +.br + +.br + .IP "\fB*rxBuf\fP" 0 .br @@ -6221,6 +6409,11 @@ If gpio#n may be written then bit (1< */ -/* pigpio version 29 */ +/* pigpio version 30 */ #include #include @@ -283,23 +283,23 @@ bit 0 READ_LAST_NOT_SET_ERROR } \ while (0) -#define PI_PERI_PHYS 0x7E000000 - static volatile uint32_t piModel = 1; -static volatile uint32_t PI_PERI_BASE = 0x20000000; -static volatile uint32_t DMA_BUS_ADR = 0x40000000; -static volatile uint32_t DMA_BUS_CACHE = 0x00000000; +#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_BASE + 0x00215000) -#define CLK_BASE (PI_PERI_BASE + 0x00101000) -#define DMA_BASE (PI_PERI_BASE + 0x00007000) -#define DMA15_BASE (PI_PERI_BASE + 0x00E05000) -#define GPIO_BASE (PI_PERI_BASE + 0x00200000) -#define PCM_BASE (PI_PERI_BASE + 0x00203000) -#define PWM_BASE (PI_PERI_BASE + 0x0020C000) -#define SPI_BASE (PI_PERI_BASE + 0x00204000) -#define SYST_BASE (PI_PERI_BASE + 0x00003000) +#define AUX_BASE (pi_peri_phys + 0x00215000) +#define CLK_BASE (pi_peri_phys + 0x00101000) +#define DMA_BASE (pi_peri_phys + 0x00007000) +#define DMA15_BASE (pi_peri_phys + 0x00E05000) +#define GPIO_BASE (pi_peri_phys + 0x00200000) +#define PCM_BASE (pi_peri_phys + 0x00203000) +#define PWM_BASE (pi_peri_phys + 0x0020C000) +#define SPI_BASE (pi_peri_phys + 0x00204000) +#define SYST_BASE (pi_peri_phys + 0x00003000) #define AUX_LEN 0xD8 #define CLK_LEN 0xA8 @@ -742,6 +742,22 @@ static volatile uint32_t DMA_BUS_CACHE = 0x00000000; #define FLUSH_PAGES 1024 +#define MB_DEV_MAJOR 100 + +#define MB_IOCTL _IOWR(MB_DEV_MAJOR, 0, char *) + +#define MB_DEV "/dev/pigpio-mb" + +#define BUS_TO_PHYS(x) ((x)&~0xC0000000) + +#define MB_END_TAG 0 +#define MB_PROCESS_REQUEST 0 + +#define MB_ALLOCATE_MEMORY_TAG 0x3000C +#define MB_LOCK_MEMORY_TAG 0x3000D +#define MB_UNLOCK_MEMORY_TAG 0x3000E +#define MB_RELEASE_MEMORY_TAG 0x3000F + /* --------------------------------------------------------------- */ typedef void (*callbk_t) (); @@ -915,6 +931,7 @@ typedef struct unsigned ifFlags; int dbgLevel; unsigned showStats; + unsigned memAllocMode; } gpioCfg_t; typedef struct @@ -973,6 +990,14 @@ typedef struct unsigned clock; } clkInf_t; +typedef struct +{ + unsigned handle; /* mbAllocateMemory() */ + uintptr_t bus_addr; /* mbLockMemory() */ + uintptr_t *virtual_addr; /* mbMapMem() */ + unsigned size; /* in bytes */ +} DMAMem_t; + /* --------------------------------------------------------------- */ /* initialise once then preserve */ @@ -988,6 +1013,7 @@ static volatile gpioCfg_t gpioCfg = PI_DEFAULT_IF_FLAGS, 0, 0, + PI_DEFAULT_MEM_ALLOC_MODE, }; static volatile gpioStats_t gpioStats; @@ -1081,16 +1107,19 @@ static FILE * outFifo = NULL; static int fdLock = -1; static int fdMem = -1; static int fdSock = -1; +static int fdPmap = -1; +static int fdMbox = -1; -static dmaPage_t * * dmaBloc = MAP_FAILED; +static DMAMem_t *dmaMboxBlk = MAP_FAILED; +static uintptr_t * * dmaPMapBlk = MAP_FAILED; static dmaPage_t * * dmaVirt = MAP_FAILED; -static dmaPage_t * * dmaPhys = MAP_FAILED; +static dmaPage_t * * dmaBus = MAP_FAILED; static dmaIPage_t * * dmaIVirt = MAP_FAILED; -static dmaIPage_t * * dmaIPhys = MAP_FAILED; +static dmaIPage_t * * dmaIBus = MAP_FAILED; static dmaOPage_t * * dmaOVirt = MAP_FAILED; -static dmaOPage_t * * dmaOPhys = MAP_FAILED; +static dmaOPage_t * * dmaOBus = MAP_FAILED; static volatile uint32_t * auxReg = MAP_FAILED; static volatile uint32_t * clkReg = MAP_FAILED; @@ -1161,6 +1190,7 @@ uint8_t clkDef[PI_MAX_GPIO + 1] = 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] = { @@ -1337,8 +1367,6 @@ static void myOffPageSlot(int pos, int * page, int * slot) static void myLvsPageSlot(int pos, int * page, int * slot) { -// *page = pos%DMAI_PAGES; -// *slot = pos/DMAI_PAGES; *page = pos/LVS_PER_IPAGE; *slot = pos%LVS_PER_IPAGE; } @@ -1347,8 +1375,6 @@ static void myLvsPageSlot(int pos, int * page, int * slot) static void myTckPageSlot(int pos, int * page, int * slot) { -// *page = pos%DMAI_PAGES; -// *slot = pos/DMAI_PAGES; *page = pos/TCK_PER_IPAGE; *slot = pos%TCK_PER_IPAGE; } @@ -2078,6 +2104,159 @@ static void myGpioSetServo(unsigned gpio, int oldVal, int newVal) } } +/* ======================================================================= */ + +/* +https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface +*/ + +int mbCreate(void) +{ + /* <0 error */ + + unlink(MB_DEV); + + return mknod(MB_DEV, S_IFCHR|0600, makedev(MB_DEV_MAJOR, 0)); +} + +int mbOpen(void) +{ + /* <0 error */ + + return open(MB_DEV, 0); +} + +void mbClose(int fd) +{ + close(fd); +} + +static int mbProperty(int fd, void *buf) +{ + return ioctl(fd, MB_IOCTL, buf); +} + +unsigned mbAllocateMemory( + int fd, unsigned size, unsigned align, unsigned flags) +{ + int i=1; + unsigned p[32]; + + p[i++] = MB_PROCESS_REQUEST; + p[i++] = MB_ALLOCATE_MEMORY_TAG; + p[i++] = 12; + p[i++] = 12; + p[i++] = size; + p[i++] = align; + p[i++] = flags; + p[i++] = MB_END_TAG; + p[0] = i*sizeof *p; + + mbProperty(fd, p); + + return p[5]; +} + +unsigned mbLockMemory(int fd, unsigned handle) +{ + int i=1; + unsigned p[32]; + + p[i++] = MB_PROCESS_REQUEST; + p[i++] = MB_LOCK_MEMORY_TAG; + p[i++] = 4; + p[i++] = 4; + p[i++] = handle; + p[i++] = MB_END_TAG; + p[0] = i*sizeof *p; + + mbProperty(fd, p); + + return p[5]; +} + +unsigned mbUnlockMemory(int fd, unsigned handle) +{ + int i=1; + unsigned p[32]; + + p[i++] = MB_PROCESS_REQUEST; + p[i++] = MB_UNLOCK_MEMORY_TAG; + p[i++] = 4; + p[i++] = 4; + p[i++] = handle; + p[i++] = MB_END_TAG; + p[0] = i*sizeof *p; + + mbProperty(fd, p); + + return p[5]; +} + +unsigned mbReleaseMemory(int fd, unsigned handle) +{ + int i=1; + unsigned p[32]; + + p[i++] = MB_PROCESS_REQUEST; + p[i++] = MB_RELEASE_MEMORY_TAG; + p[i++] = 4; + p[i++] = 4; + p[i++] = handle; + p[i++] = MB_END_TAG; + p[0] = i*sizeof *p; + + mbProperty(fd, p); + + return p[5]; +} + +void *mbMapMem(unsigned base, unsigned size) +{ + void *mem = MAP_FAILED; + + mem = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fdMem, base); + + return mem; +} + +int mbUnmapMem(void *addr, unsigned size) +{ + /* 0 okay, -1 fail */ + return munmap(addr, size); +} + +void mbDMAFree(DMAMem_t *DMAMemP) +{ + if (DMAMemP->handle) + { + mbUnmapMem(DMAMemP->virtual_addr, DMAMemP->size); + mbUnlockMemory(fdMbox, DMAMemP->handle); + mbReleaseMemory(fdMbox, DMAMemP->handle); + DMAMemP->handle = 0; + } +} + +int mbDMAAlloc(DMAMem_t *DMAMemP, unsigned size, uint32_t pi_mem_flag) +{ + DMAMemP->size = size; + + DMAMemP->handle = + mbAllocateMemory(fdMbox, size, PAGE_SIZE, pi_mem_flag); + + if (DMAMemP->handle) + { + DMAMemP->bus_addr = mbLockMemory(fdMbox, DMAMemP->handle); + + DMAMemP->virtual_addr = + mbMapMem(BUS_TO_PHYS(DMAMemP->bus_addr), size); + + return 1; + } + return 0; +} + + /* ======================================================================= */ rawCbs_t * rawWaveCBAdr(int cbNum) @@ -2100,7 +2279,7 @@ static uint32_t waveCbPOadr(int pos) page = pos/CBS_PER_OPAGE; slot = pos%CBS_PER_OPAGE; - return (uint32_t) &dmaOPhys[page]->cb[slot]; + return (uint32_t) &dmaOBus[page]->cb[slot]; } /* ----------------------------------------------------------------------- */ @@ -2131,7 +2310,7 @@ static uint32_t waveOOLPOadr(int pos) waveOOLPageSlot(pos, &page, &slot); - return (uint32_t) &dmaOPhys[page]->OOL[slot]; + return (uint32_t) &dmaOBus[page]->OOL[slot]; } @@ -2224,19 +2403,19 @@ static int wave2Cbs(unsigned wave_mode) p->info = NORMAL_DMA | DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(2); - p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS; + p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS; } else { p->info = NORMAL_DMA | DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(5); - p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS; + p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS; } - p->src = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR; + p->src = (uint32_t) (&dmaOBus[0]->periphData); p->length = 4 * 20 / PI_WF_MICROS; /* 20 micros delay */ - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); repeatCB = botCB; @@ -2251,10 +2430,10 @@ static int wave2Cbs(unsigned wave_mode) p = rawWaveCBAdr(botCB++); p->info = NORMAL_DMA; - p->src = waveOOLPOadr(botOOL++) | DMA_BUS_ADR; - p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_PHYS; + p->src = waveOOLPOadr(botOOL++); + p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_BUS; p->length = 4; - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); } if (waves[i].gpioOff) @@ -2266,10 +2445,10 @@ static int wave2Cbs(unsigned wave_mode) p = rawWaveCBAdr(botCB++); p->info = NORMAL_DMA; - p->src = waveOOLPOadr(botOOL++) | DMA_BUS_ADR; - p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_PHYS; + p->src = waveOOLPOadr(botOOL++); + p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_BUS; p->length = 4; - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); } if (waves[i].flags & WAVE_FLAG_READ) @@ -2279,10 +2458,10 @@ static int wave2Cbs(unsigned wave_mode) p = rawWaveCBAdr(botCB++); p->info = NORMAL_DMA; - p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_PHYS; - p->dst = waveOOLPOadr(--topOOL) | DMA_BUS_ADR; + p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_BUS; + p->dst = waveOOLPOadr(--topOOL); p->length = 4; - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); } if (waves[i].flags & WAVE_FLAG_TICK) @@ -2292,10 +2471,10 @@ static int wave2Cbs(unsigned wave_mode) p = rawWaveCBAdr(botCB++); p->info = NORMAL_DMA; - p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_PHYS; - p->dst = waveOOLPOadr(--topOOL) | DMA_BUS_ADR; + p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_BUS; + p->dst = waveOOLPOadr(--topOOL); p->length = 4; - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); } if (waves[i].flags & WAVE_FLAG_COUNT) @@ -2304,7 +2483,7 @@ static int wave2Cbs(unsigned wave_mode) baseCB = botCB; - def_next = waveCbPOadr(baseCB+(3*PI_WAVE_COUNT_BLOCKS)) | DMA_BUS_ADR; + def_next = waveCbPOadr(baseCB+(3*PI_WAVE_COUNT_BLOCKS)); /* set up all the OOLs */ for (b=0; b < (PI_WAVE_COUNT_BLOCKS*(PI_WAVE_COUNT_LENGTH+1)); b++) @@ -2312,7 +2491,7 @@ static int wave2Cbs(unsigned wave_mode) for (b=0; binfo = NORMAL_DMA; p->src = waveOOLPOadr - (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1))) | DMA_BUS_ADR; - p->dst = (waveCbPOadr(botCB+1) + 20) | DMA_BUS_ADR; + (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1))); + p->dst = (waveCbPOadr(botCB+1) + 20); p->length = 4; - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); /* copy BOTTOM to TOP */ @@ -2339,12 +2518,12 @@ static int wave2Cbs(unsigned wave_mode) p->info = NORMAL_DMA; p->src = waveOOLPOadr - (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1))) | DMA_BUS_ADR; + (topOOL-((b+1)*(PI_WAVE_COUNT_LENGTH+1))); p->dst = waveOOLPOadr - (topOOL-(1+(b*(PI_WAVE_COUNT_LENGTH+1)))) | DMA_BUS_ADR; + (topOOL-(1+(b*(PI_WAVE_COUNT_LENGTH+1)))); p->length = 4; - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); /* shift all down one */ @@ -2353,13 +2532,13 @@ static int wave2Cbs(unsigned wave_mode) p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC; p->src = waveOOLPOadr - (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-1)) | DMA_BUS_ADR; + (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-1)); p->dst = waveOOLPOadr - (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-0)) | DMA_BUS_ADR; + (topOOL-(((b+1)*(PI_WAVE_COUNT_LENGTH+1))-0)); p->length = PI_WAVE_COUNT_LENGTH*4; p->next = waveCbPOadr - (baseCB+(3*PI_WAVE_COUNT_BLOCKS)) | DMA_BUS_ADR; + (baseCB+(3*PI_WAVE_COUNT_BLOCKS)); } topOOL -= PI_WAVE_COUNT_BLOCKS * (PI_WAVE_COUNT_LENGTH+1); @@ -2379,7 +2558,7 @@ static int wave2Cbs(unsigned wave_mode) DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(2); - p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS; + p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS; } else { @@ -2387,12 +2566,12 @@ static int wave2Cbs(unsigned wave_mode) DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(5); - p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS; + p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS; } - p->src = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR; + p->src = (uint32_t) (&dmaOBus[0]->periphData); p->length = 4 * ((waves[i].usDelay+half)/PI_WF_MICROS); - p->next = waveCbPOadr(botCB) | DMA_BUS_ADR; + p->next = waveCbPOadr(botCB); } } @@ -2400,7 +2579,7 @@ static int wave2Cbs(unsigned wave_mode) { if (wave_mode == PI_WAVE_MODE_ONE_SHOT) p->next = 0; - else p->next = waveCbPOadr(repeatCB) | DMA_BUS_ADR; + else p->next = waveCbPOadr(repeatCB); } status = botCB - waveOutBotCB; @@ -4003,24 +4182,52 @@ int serDataAvailable(unsigned handle) static int chooseBestClock (clkInf_t *clkInf, unsigned f, unsigned numc, unsigned *cf) { - unsigned c; - unsigned div, frac, basef, offby, best_offby, valid; + int c, valid, offby, offby2, best_offby; + uint32_t div; + uint64_t frac; valid = 0; best_offby = 0; for (c=0; c 1) && (div < 4096)) { - if ((!valid) || (offby < best_offby)) + if (f < PI_MASH_MAX_FREQ) + { + frac = cf[c] - (div * f); + frac = (frac * 4096) / f; + offby = cf[c] - (div * f) - ((frac * f) / 4096); + if (frac < 4095) + { + offby2 = cf[c] - (div * f) - (((frac+1) * f) / 4096); + if (offby2 < 0) offby2 = -offby2; + if (offby2 < offby) + { + offby = offby2; + frac++; + } + } + } + else + { + frac = 0; + offby = cf[c] - (div * f); + if (div < 4095) + { + offby2 = cf[c] - ((div+1) * f); + if (offby2 < 0) offby2 = -offby2; + if (offby2 < offby) + { + offby = offby2; + div++; + } + } + } + + if ((!valid) || (offby <= best_offby)) { valid = 1; clkInf->div = div; @@ -4077,7 +4284,7 @@ static unsigned dmaNowAtICB(void) while (1) { - cb = (cbAddr - ((int)dmaIPhys[page] | DMA_BUS_ADR)) / 32; + cb = (cbAddr - ((int)dmaIBus[page])) / 32; if (cb < CBS_PER_IPAGE) { @@ -4120,7 +4327,7 @@ unsigned rawWaveCB(void) while (1) { - cb = (cbAddr - ((int)dmaOPhys[page] | DMA_BUS_ADR)) / 32; + cb = (cbAddr - ((int)dmaOBus[page])) / 32; if (cb < CBS_PER_OPAGE) { @@ -4155,7 +4362,7 @@ static unsigned dmaCurrentSlot(unsigned pos) static uint32_t dmaPwmDataAdr(int pos) { - return (uint32_t) &dmaIPhys[pos]->periphData; + return (uint32_t) &dmaIBus[pos]->periphData; } /* ----------------------------------------------------------------------- */ @@ -4167,7 +4374,7 @@ static uint32_t dmaGpioOnAdr(int pos) page = pos/ON_PER_IPAGE; slot = pos%ON_PER_IPAGE; - return (uint32_t) &dmaIPhys[page]->gpioOn[slot]; + return (uint32_t) &dmaIBus[page]->gpioOn[slot]; } /* ----------------------------------------------------------------------- */ @@ -4178,7 +4385,7 @@ static uint32_t dmaGpioOffAdr(int pos) myOffPageSlot(pos, &page, &slot); - return (uint32_t) &dmaIPhys[page]->gpioOff[slot]; + return (uint32_t) &dmaIBus[page]->gpioOff[slot]; } /* ----------------------------------------------------------------------- */ @@ -4189,7 +4396,7 @@ static uint32_t dmaTickAdr(int pos) myTckPageSlot(pos, &page, &slot); - return (uint32_t) &dmaIPhys[page]->tick[slot]; + return (uint32_t) &dmaIBus[page]->tick[slot]; } /* ----------------------------------------------------------------------- */ @@ -4200,7 +4407,7 @@ static uint32_t dmaReadLevelsAdr(int pos) myLvsPageSlot(pos, &page, &slot); - return (uint32_t) &dmaIPhys[page]->level[slot]; + return (uint32_t) &dmaIBus[page]->level[slot]; } /* ----------------------------------------------------------------------- */ @@ -4212,7 +4419,7 @@ static uint32_t dmaCbAdr(int pos) page = (pos/CBS_PER_IPAGE); slot = (pos%CBS_PER_IPAGE); - return (uint32_t) &dmaIPhys[page]->cb[slot]; + return (uint32_t) &dmaIBus[page]->cb[slot]; } /* ----------------------------------------------------------------------- */ @@ -4224,10 +4431,10 @@ static void dmaGpioOnCb(int b, int pos) p = dmaCB2adr(b); p->info = NORMAL_DMA; - p->src = dmaGpioOnAdr(pos) | DMA_BUS_ADR; - p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_PHYS; + p->src = dmaGpioOnAdr(pos); + p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_BUS; p->length = 4; - p->next = dmaCbAdr(b+1) | DMA_BUS_ADR; + p->next = dmaCbAdr(b+1); } /* ----------------------------------------------------------------------- */ @@ -4239,10 +4446,10 @@ static void dmaTickCb(int b, int pos) p = dmaCB2adr(b); p->info = NORMAL_DMA; - p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_PHYS; - p->dst = dmaTickAdr(pos) | DMA_BUS_ADR; + p->src = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_BUS; + p->dst = dmaTickAdr(pos); p->length = 4; - p->next = dmaCbAdr(b+1) | DMA_BUS_ADR; + p->next = dmaCbAdr(b+1); } /* ----------------------------------------------------------------------- */ @@ -4254,10 +4461,10 @@ static void dmaGpioOffCb(int b, int pos) p = dmaCB2adr(b); p->info = NORMAL_DMA; - p->src = dmaGpioOffAdr(pos) | DMA_BUS_ADR; - p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_PHYS; + p->src = dmaGpioOffAdr(pos); + p->dst = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_BUS; p->length = 4; - p->next = dmaCbAdr(b+1) | DMA_BUS_ADR; + p->next = dmaCbAdr(b+1); } /* ----------------------------------------------------------------------- */ @@ -4269,10 +4476,10 @@ static void dmaReadLevelsCb(int b, int pos) p = dmaCB2adr(b); p->info = NORMAL_DMA; - p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_PHYS; - p->dst = dmaReadLevelsAdr(pos) | DMA_BUS_ADR; + p->src = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_BUS; + p->dst = dmaReadLevelsAdr(pos); p->length = 4; - p->next = dmaCbAdr(b+1) | DMA_BUS_ADR; + p->next = dmaCbAdr(b+1); } /* ----------------------------------------------------------------------- */ @@ -4286,17 +4493,17 @@ static void dmaDelayCb(int b) if (gpioCfg.clockPeriph == PI_CLOCK_PCM) { p->info = NORMAL_DMA | TIMED_DMA(2); - p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS; + p->dst = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS; } else { p->info = NORMAL_DMA | TIMED_DMA(5); - p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS; + p->dst = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS; } - p->src = dmaPwmDataAdr(b%DMAI_PAGES) | DMA_BUS_ADR; + p->src = dmaPwmDataAdr(b%DMAI_PAGES); p->length = 4; - p->next = dmaCbAdr(b+1) | DMA_BUS_ADR; + p->next = dmaCbAdr(b+1); } /* ----------------------------------------------------------------------- */ @@ -4338,7 +4545,7 @@ static void dmaInitCbs(void) p = dmaCB2adr(b); - p->next = dmaCbAdr(0) | DMA_BUS_ADR; + p->next = dmaCbAdr(0); DBG(DBG_STARTUP, "DMA page type count = %d", sizeof(dmaIPage_t)); @@ -4469,19 +4676,19 @@ static void * pthAlertThread(void *x) } else { - if (!stopped) - { - DBG(DBG_STARTUP, "****** STOPPED ******"); - stopped = 1; - } + stopped = 1; myGpioDelay(5000); if (DMAstarted) { + /* should never be executed, leave code just in case */ + + gpioCfg.showStats = 1; + dmaInitCbs(); flushMemory(); - initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]); + initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIBus[0]); myGpioDelay(5000); /* let DMA run for a while */ oldSlot = dmaCurrentSlot(dmaNowAtICB()); gpioStats.DMARestarts++; @@ -4544,10 +4751,23 @@ static void * pthAlertThread(void *x) diff += (TICKSLOTS/2); - if (diff < 0) gpioStats.diffTick[0]++; + if (diff < 0) + { + /* shouldn't happen */ + + gpioCfg.showStats = 1; + + gpioStats.diffTick[0]++; + } else if (diff >= TICKSLOTS) + { + /* shouldn't happen */ + + gpioCfg.showStats = 1; + gpioStats.diffTick[TICKSLOTS-1]++; + } else gpioStats.diffTick[diff]++; } @@ -5524,66 +5744,6 @@ static int initGrabLockFile(void) /* ----------------------------------------------------------------------- */ -static int initZaps -( - int pmapFd, - dmaPage_t *dmaV1, - dmaPage_t *dmaV2[], - dmaPage_t *dmaP[], - int pages) -{ - int n; - long index; - off_t offset; - ssize_t t; - int status; - uint32_t pageAdr2; - unsigned long long pa; - - DBG(DBG_STARTUP, ""); - - status = 0; - - pageAdr2 = (uint32_t) dmaV2[0]; - - index = ((uint32_t)dmaV1 / PAGE_SIZE) * 8; - - offset = lseek(pmapFd, index, SEEK_SET); - - if (offset != index) - SOFT_ERROR(PI_INIT_FAILED, "lseek pagemap failed (%m)"); - - for (n=0; n PI_DEFAULT_BUFFER_MILLIS))) + { + /* pagemap allocation of DMA memory */ - sprintf(str, "/proc/%d/pagemap", pid); + dmaPMapBlk = mmap( + 0, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *), + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, + -1, 0); - pagemapFd = open(str, O_RDONLY); - - if (pagemapFd < 0) - SOFT_ERROR(PI_INIT_FAILED, "open pagemap failed(%m)"); + if (dmaPMapBlk == MAP_FAILED) + SOFT_ERROR(PI_INIT_FAILED, "pagemap mmap block failed (%m)"); + + fdPmap = open("/proc/self/pagemap", O_RDONLY); + + if (fdPmap < 0) + SOFT_ERROR(PI_INIT_FAILED, "pagemap open failed(%m)"); + + for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++) + { + status = initPagemapBlock(i); + if (status < 0) + { + close(fdPmap); + return status; + } + } + + close(fdPmap); + + DBG(DBG_STARTUP, "dmaPMapBlk=%08X dmaIn=%08X", + (uint32_t)dmaPMapBlk, (uint32_t)dmaIn); + } + else + { + /* mailbox allocation of DMA memory */ + + dmaMboxBlk = mmap( + 0, (bufferBlocks+PI_WAVE_BLOCKS)*sizeof(DMAMem_t), + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, + -1, 0); - for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++) initDMAblock(pagemapFd, i); + if (dmaMboxBlk == MAP_FAILED) + SOFT_ERROR(PI_INIT_FAILED, "mmap mbox block failed (%m)"); - close(pagemapFd); + if (mbCreate() < 0) + SOFT_ERROR(PI_INIT_FAILED, "mbox create failed(%m)"); - DBG(DBG_STARTUP, "dmaBloc=%08X dmaIn=%08X", - (uint32_t)dmaBloc, (uint32_t)dmaIn); + fdMbox = mbOpen(); + + if (fdMbox < 0) + SOFT_ERROR(PI_INIT_FAILED, "mbox open failed(%m)"); + + for (i=0; i<(bufferBlocks+PI_WAVE_BLOCKS); i++) + { + status = initMboxBlock(i); + if (status < 0) + { + mbClose(fdMbox); + return status; + } + } + + mbClose(fdMbox); + + DBG(DBG_STARTUP, "dmaMboxBlk=%08X dmaIn=%08X", + (uint32_t)dmaMboxBlk, (uint32_t)dmaIn); + } DBG(DBG_STARTUP, "gpioReg=%08X pwmReg=%08X pcmReg=%08X clkReg=%08X auxReg=%08X", @@ -5828,7 +6122,7 @@ static int initDMAcbs(void) (uint32_t)pcmReg, (uint32_t)clkReg, (uint32_t)auxReg); for (i=0; i= DBG_DMACBS) { @@ -6019,7 +6313,7 @@ static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr) dmaAddr[DMA_CS] = DMA_INTERRUPT_STATUS | DMA_END_FLAG; - dmaAddr[DMA_CONBLK_AD] = cbAddr | DMA_BUS_ADR; + dmaAddr[DMA_CONBLK_AD] = cbAddr; /* clear READ/FIFO/READ_LAST_NOT_SET error bits */ @@ -6129,9 +6423,10 @@ static void initClearGlobals(void) fdMem = -1; fdSock = -1; - dmaBloc = MAP_FAILED; + dmaMboxBlk = MAP_FAILED; + dmaPMapBlk = MAP_FAILED; dmaVirt = MAP_FAILED; - dmaPhys = MAP_FAILED; + dmaBus = MAP_FAILED; auxReg = MAP_FAILED; clkReg = MAP_FAILED; @@ -6206,6 +6501,14 @@ static void initReleaseResources(void) systReg = MAP_FAILED; spiReg = MAP_FAILED; + if (dmaBus != MAP_FAILED) + { + munmap(dmaBus, + PAGES_PER_BLOCK*(bufferBlocks+PI_WAVE_BLOCKS)*sizeof(dmaPage_t *)); + } + + dmaBus = MAP_FAILED; + if (dmaVirt != MAP_FAILED) { for (i=0; i> 4) & 3; + return hw_pwm_real_range[pwm]; + case GPIO_HW_CLK: return PI_HW_PWM_RANGE; @@ -7552,7 +7901,7 @@ int gpioWaveTxStart(unsigned wave_mode) for (i=0; inext = 0; - else p->next = waveCbPOadr(waveInfo[wave_id].botCB+1) | DMA_BUS_ADR; + else p->next = waveCbPOadr(waveInfo[wave_id].botCB+1); dmaOut[DMA_CS] = DMA_CHANNEL_RESET; @@ -8698,6 +9047,7 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) uint32_t cfreq[CLK_SRCS]={CLK_OSC_FREQ, CLK_PLLD_FREQ}; unsigned clock, mode, mash; int password = 0; + double f; clkInf_t clkInf={0,0,0}; DBG(DBG_USER, "gpio=%d frequency=%d", gpio, frequency); @@ -8733,9 +9083,7 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) { if (chooseBestClock(&clkInf, frequency, CLK_SRCS, cfreq)) { - /* record the clock frequency */ - - hw_clk_freq[clock] = frequency; + if (clkInf.frac == 0) mash = 0; initHWClk(cctl[clock], cdiv[clock], csrc[clkInf.clock], clkInf.div, clkInf.frac, mash); @@ -8743,6 +9091,14 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) gpioSetMode(gpio, mode); gpioInfo[gpio].is = GPIO_HW_CLK; + + f = (double) cfreq[clkInf.clock] / + ((double)clkInf.div + ((double)clkInf.frac / 4096.0)); + + hw_clk_freq[clock] = (f + 0.5); + + DBG(DBG_USER, "cf=%d div=%d frac=%d mash=%d", + cfreq[clkInf.clock], clkInf.div, clkInf.frac, mash); } else { @@ -8767,11 +9123,9 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) int gpioHardwarePWM( unsigned gpio, unsigned frequency, unsigned dutycycle) { - int csrc[CLK_SRCS] = {CLK_CTL_SRC_OSC, CLK_CTL_SRC_PLLD}; - uint32_t cfreq[CLK_SRCS]={CLK_OSC_FREQ, CLK_PLLD_FREQ}; uint32_t old_PWM_CTL; - unsigned pwm, mode,mash; - clkInf_t clkInf={0,0,0}; + unsigned pwm, mode; + uint32_t real_range, real_dutycycle; DBG(DBG_USER, "gpio=%d frequency=%d dutycycle=%d", gpio, frequency, dutycycle); @@ -8799,73 +9153,63 @@ int gpioHardwarePWM( pwm = (PWMDef[gpio] >> 4) & 3; mode = PWMDef[gpio] & 7; - frequency *= PI_HW_PWM_RANGE; - - mash = frequency < PI_MASH_MAX_FREQ ? 1 : 0; - if (frequency) { - if (chooseBestClock(&clkInf, frequency, CLK_SRCS, cfreq)) - { - /* record the PWM frequency and dutycycle */ + real_range = ((double)CLK_PLLD_FREQ / (2.0 * frequency)) + 0.5; + real_dutycycle = ((uint64_t)dutycycle * real_range) / PI_HW_PWM_RANGE; - /* currently both channels must use the same update rate */ + /* record the set PWM frequency and dutycycle */ - hw_pwm_freq[0] = frequency / PI_HW_PWM_RANGE; - hw_pwm_freq[1] = frequency / PI_HW_PWM_RANGE; + hw_pwm_freq[pwm] = + ((double)CLK_PLLD_FREQ / ( 2.0 * real_range)) + 0.5; - hw_pwm_duty[pwm] = dutycycle; + hw_pwm_duty[pwm] = dutycycle; - /* Abort any waveform transmission in progress */ + hw_pwm_real_range[pwm] = real_range; - if (gpioWaveTxBusy()) gpioWaveTxStop(); + /* Abort any waveform transmission in progress */ - waveClockInited = 0; + if (gpioWaveTxBusy()) gpioWaveTxStop(); - /* preserve channel enable only and mark space mode */ + waveClockInited = 0; - old_PWM_CTL = pwmReg[PWM_CTL] & - (PWM_CTL_PWEN1 | PWM_CTL_MSEN1 | PWM_CTL_PWEN2 | PWM_CTL_MSEN2); + /* preserve channel enable only and mark space mode */ - pwmReg[PWM_CTL] = 0; + old_PWM_CTL = pwmReg[PWM_CTL] & + (PWM_CTL_PWEN1 | PWM_CTL_MSEN1 | PWM_CTL_PWEN2 | PWM_CTL_MSEN2); - myGpioDelay(10); - - initHWClk(CLK_PWMCTL, CLK_PWMDIV, - csrc[clkInf.clock], clkInf.div, clkInf.frac, mash); - - if (pwm == 0) - { - pwmReg[PWM_RNG1] = PI_HW_PWM_RANGE; - myGpioDelay(10); - pwmReg[PWM_DAT1] = dutycycle; - myGpioDelay(10); + pwmReg[PWM_CTL] = 0; - pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN1 | PWM_CTL_MSEN1); - } - else - { - pwmReg[PWM_RNG2] = PI_HW_PWM_RANGE; - myGpioDelay(10); - pwmReg[PWM_DAT2] = dutycycle; - myGpioDelay(10); - - pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN2 | PWM_CTL_MSEN2); - } + myGpioDelay(10); - if (gpioInfo[gpio].is != GPIO_HW_PWM) - { - switchFunctionOff(gpio); + initHWClk(CLK_PWMCTL, CLK_PWMDIV, CLK_CTL_SRC_PLLD, 2, 0, 0); - gpioSetMode(gpio, mode); + if (pwm == 0) + { + pwmReg[PWM_RNG1] = real_range; + myGpioDelay(10); + pwmReg[PWM_DAT1] = real_dutycycle; + myGpioDelay(10); - gpioInfo[gpio].is = GPIO_HW_PWM; - } + pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN1 | PWM_CTL_MSEN1); } else { - SOFT_ERROR(PI_BAD_HPWM_FREQ, - "bad hardware PWM frequency (%d)", frequency/PI_HW_PWM_RANGE); + pwmReg[PWM_RNG2] = real_range; + myGpioDelay(10); + pwmReg[PWM_DAT2] = real_dutycycle; + myGpioDelay(10); + + pwmReg[PWM_CTL] = (old_PWM_CTL | PWM_CTL_PWEN2 | PWM_CTL_MSEN2); + } + + if (gpioInfo[gpio].is != GPIO_HW_PWM) + { + switchFunctionOff(gpio); + + gpioSetMode(gpio, mode); + + gpioInfo[gpio].is = GPIO_HW_PWM; } } else @@ -9031,17 +9375,17 @@ unsigned gpioHardwareRevision(void) { piModel = 1; chars = 4; - PI_PERI_BASE = 0x20000000; - DMA_BUS_ADR = 0x40000000; - DMA_BUS_CACHE = 0x40000000; + pi_peri_phys = 0x20000000; + pi_dram_bus = 0x40000000; + pi_mem_flag = 0x0c; } else if (strstr (buf, "ARMv7") != NULL) { piModel = 2; chars = 6; - PI_PERI_BASE = 0x3F000000; - DMA_BUS_ADR = 0xC0000000; - DMA_BUS_CACHE = 0x00000000; + pi_peri_phys = 0x3F000000; + pi_dram_bus = 0xC0000000; + pi_mem_flag = 0x04; } } } @@ -9193,6 +9537,24 @@ int gpioCfgSocketPort(unsigned port) } +/* ----------------------------------------------------------------------- */ + +int gpioCfgMemAlloc(unsigned memAllocMode) +{ + DBG(DBG_USER, "memAllocMode=%d", memAllocMode); + + CHECK_NOT_INITED; + + if (memAllocMode > PI_MEM_ALLOC_MAILBOX) + SOFT_ERROR( + PI_BAD_MALLOC_MODE, "bad mem alloc mode (%d)", memAllocMode); + + gpioCfg.memAllocMode = memAllocMode; + + return 0; +} + + /* ----------------------------------------------------------------------- */ int gpioCfgInternals(unsigned cfgWhat, int cfgVal) diff --git a/pigpio.h b/pigpio.h index 53c6b06..be6e813 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 29 +#define PIGPIO_VERSION 30 /*TEXT @@ -93,7 +93,7 @@ For examples of usage see the C programs within the pigpio archive file. All the functions which return an int return < 0 on error. -If the library isn't initialised all but the [*gpioCfg**], [*gpioVersion*], +If the library is not initialised all but the [*gpioCfg**], [*gpioVersion*], and [*gpioHardwareRevision*] functions will return PI_NOT_INITIALISED. If the library is initialised the [*gpioCfg**] functions will @@ -211,9 +211,9 @@ gpioWaveGetPulses Length in pulses of the current waveform gpioWaveGetHighPulses Length of longest waveform so far gpioWaveGetMaxPulses Absolute maximum allowed pulses -gpioWaveGetCbs Length in cbs of the current waveform +gpioWaveGetCbs Length in control blocks of the current waveform gpioWaveGetHighCbs Length of longest waveform so far -gpioWaveGetMaxCbs Absolute maximum allowed cbs +gpioWaveGetMaxCbs Absolute maximum allowed control blocks gpioWaveTxStart Creates/transmits a waveform (DEPRECATED) @@ -271,6 +271,12 @@ gpioCfgPermissions Configure the gpio access permissions gpioCfgInterfaces Configure user interfaces gpioCfgInternals Configure miscellaneous internals gpioCfgSocketPort Configure socket port +gpioCfgMemAlloc Configure DMA memory allocation mode + +CUSTOM + +gpioCustom1 User custom function 1 +gpioCustom2 User custom function 2 UTILITIES @@ -441,7 +447,7 @@ typedef void *(gpioThreadFunc_t) (void *); #define PI_LOW 0 #define PI_HIGH 1 -/* level: only reported for gpio timeout, see gpioSetWatchdog */ +/* level: only reported for gpio time-out, see gpioSetWatchdog */ #define PI_TIMEOUT 2 @@ -479,9 +485,9 @@ typedef void *(gpioThreadFunc_t) (void *); /* hardware PWM */ -#define PI_HW_PWM_MIN_FREQ 5 -#define PI_HW_PWM_MAX_FREQ 50000 -#define PI_HW_PWM_RANGE 5000 +#define PI_HW_PWM_MIN_FREQ 1 +#define PI_HW_PWM_MAX_FREQ 125000000 +#define PI_HW_PWM_RANGE 1000000 /* hardware clock */ @@ -620,6 +626,11 @@ typedef void *(gpioThreadFunc_t) (void *); #define PI_DISABLE_FIFO_IF 1 #define PI_DISABLE_SOCK_IF 2 +/* memAllocMode */ + +#define PI_MEM_ALLOC_AUTO 0 +#define PI_MEM_ALLOC_PAGEMAP 1 +#define PI_MEM_ALLOC_MAILBOX 2 /*F*/ int gpioInitialise(void); @@ -654,7 +665,7 @@ Returns nothing. Call before program exit. -This function resets the DMA and PWM peripherals, releases memory, and +This function resets the used DMA channels, releases memory, and terminates any running threads. ... @@ -814,10 +825,13 @@ Returns between 0 (off) and range (fully on) if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. For normal PWM the dutycycle will be out of the defined range -for the gpio (see [*gpioGetPWMrange*]). If a hardware clock is -active on the gpio the reported dutycycle will be 500 (out of 1000). +for the gpio (see [*gpioGetPWMrange*]). + +If a hardware clock is active on the gpio the reported dutycycle +will be 500000 (500k) out of 1000000 (1M). + If hardware PWM is active on the gpio the reported dutycycle -will be out of a 1000. +will be out of a 1000000 (1M). Normal PWM range defaults to 255. D*/ @@ -869,7 +883,7 @@ user_gpio: 0-31 . . If a hardware clock or hardware PWM is active on the gpio -the reported range will be 1000. +the reported range will be 1000000 (1M). ... r = gpioGetPWMrange(23); @@ -887,8 +901,11 @@ PI_BAD_USER_GPIO. user_gpio: 0-31 . . -If a hardware clock or hardware PWM is active on the gpio -the reported real range will be 1000. +If a hardware clock is active on the gpio the reported real +range will be 1000000 (1M). + +If hardware PWM is active on the gpio the reported real range +will be approximately 250M divided by the set PWM frequency. ... rr = gpioGetPWMrealRange(17); @@ -964,8 +981,11 @@ user_gpio: 0-31 . . For normal PWM the frequency will be that defined for the gpio by -[*gpioSetPWMfrequency*]. If a hardware clock is active on the gpio -the reported frequency will be that set by [*gpioHardwareClock*]. +[*gpioSetPWMfrequency*]. + +If a hardware clock is active on the gpio the reported frequency +will be that set by [*gpioHardwareClock*]. + If hardware PWM is active on the gpio the reported frequency will be that set by [*gpioHardwarePWM*]. @@ -1661,8 +1681,8 @@ or PI_NOT_SERIAL_GPIO. The bytes returned for each character depend upon the number of data bits [*bbBits*] specified in the [*gpioSerialReadOpen*] command. -For [*bbBits*] 1-8 there will be one byte per character. -For [*bbBits*] 9-16 there will be two bytes per character. +For [*bbBits*] 1-8 there will be one byte per character. +For [*bbBits*] 9-16 there will be two bytes per character. For [*bbBits*] 17-32 there will be four bytes per character. D*/ @@ -2001,12 +2021,12 @@ Data will be transferred at baud bits per second. The flags may be used to modify the default behaviour of 4-wire operation, mode 0, active low chip select. -An auxiliary SPI device is available on the B+ and may be +An auxiliary SPI device is available on the A+/B+/Pi2 and may be selected by setting the A bit in the flags. The auxiliary device has 3 chip selects and a selectable word size in bits. . . - spiChan: 0-1 (0-2 for B+ auxiliary device) + spiChan: 0-1 (0-2 for A+/B+/Pi2 auxiliary device) spiBaud: 32K-125M (values above 30M are unlikely to work) spiFlags: see below . . @@ -2023,6 +2043,8 @@ spiFlags consists of the least significant 22 bits. mm defines the SPI mode. +Warning: modes 1 and 3 do not appear to work on the auxiliary device. + . . Mode POL PHA 0 0 0 @@ -2036,7 +2058,7 @@ px is 0 if CEx is active low (default) and 1 for active high. ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise. A is 0 for the standard SPI device, 1 for the auxiliary SPI. The -auxiliary device is only present on the B+. +auxiliary device is only present on the A+/B+/Pi2. W is 0 if the device is not 3-wire, 1 if the device is 3-wire. Standard SPI device only. @@ -2678,10 +2700,11 @@ D*/ int gpioHardwareClock(unsigned gpio, unsigned clkfreq); /*D Starts a hardware clock on a gpio at the specified frequency. +Frequencies above 30MHz are unlikely to work. . . gpio: see description -clkfreq: 0 (off) or 4689-250M +clkfreq: 0 (off) or 4689-250000000 (250M) . . Returns 0 if OK, otherwise PI_BAD_GPIO, PI_NOT_HCLK_GPIO, @@ -2694,9 +2717,9 @@ The gpio must be one of the following. . . 4 clock 0 All models -5 clock 1 A+/B+ and compute module only (reserved for system use) -6 clock 2 A+/B+ and compute module only -20 clock 0 A+/B+ and compute module only +5 clock 1 A+/B+/Pi2 and compute module only (reserved for system use) +6 clock 2 A+/B+/Pi2 and compute module only +20 clock 0 A+/B+/Pi2 and compute module only 21 clock 1 All models but Rev.2 B (reserved for system use) 32 clock 0 Compute module only @@ -2715,6 +2738,7 @@ D*/ int gpioHardwarePWM(unsigned gpio, unsigned PWMfreq, unsigned PWMduty); /*D Starts hardware PWM on a gpio at the specified frequency and dutycycle. +Frequencies above 30MHz are unlikely to work. NOTE: Any waveform started by [*gpioWaveTxSend*] or [*gpioWaveTxStart*] will be cancelled. @@ -2725,25 +2749,24 @@ main clock defaults to PCM but may be overridden by a call to . . gpio: see description -PWMfreq: 0 (off) or 5-250K -PWMduty: 0 (off) to 1000 (fully on). +PWMfreq: 0 (off) or 1-125000000 (125M) +PWMduty: 0 (off) to 1000000 (1M)(fully on) . . Returns 0 if OK, otherwise PI_BAD_GPIO, PI_NOT_HPWM_GPIO, PI_BAD_HPWM_DUTY, PI_BAD_HPWM_FREQ, or PI_HPWM_ILLEGAL. -Both PWM channels share the same clock and the same update frequency. -The latest frequency setting will be used by both PWM channels. The -same PWM channel is available on multiple gpios. The latest -dutycycle setting will be used by all gpios which share a PWM channel. +The same PWM channel is available on multiple gpios. The latest +frequency and dutycycle setting will be used by all gpios which +share a PWM channel. The gpio must be one of the following. . . -12 PWM channel 0 A+/B+ and compute module only -13 PWM channel 1 A+/B+ and compute module only +12 PWM channel 0 A+/B+/Pi2 and compute module only +13 PWM channel 1 A+/B+/Pi2 and compute module only 18 PWM channel 0 All models -19 PWM channel 1 A+/B+ and compute module only +19 PWM channel 1 A+/B+/Pi2 and compute module only 40 PWM channel 0 Compute module only 41 PWM channel 1 Compute module only @@ -2871,27 +2894,19 @@ Returns the hardware revision. If the hardware revision can not be found or is not a valid hexadecimal number the function returns 0. -The hardware revision is the last 4 characters on the Revision line of +The hardware revision is the last few characters on the Revision line of /proc/cpuinfo. The revision number can be used to determine the assignment of gpios -to pins. +to pins (see [*gpio*]). There are at least three types of board. -Type 1 has gpio 0 on P1-3, gpio 1 on P1-5, and gpio 21 on P1-13. - -Type 2 has gpio 2 on P1-3, gpio 3 on P1-5, gpio 27 on P1-13, and -gpios 28-31 on P5. - -Type 3 has a 40 pin connector rather than the 26 pin connector of -the earlier boards. Gpios 0 to 27 are brought out to the connector. - Type 1 boards have hardware revision numbers of 2 and 3. Type 2 boards have hardware revision numbers of 4, 5, 6, and 15. -Type 3 boards have hardware revision number 16. +Type 3 boards have hardware revision numbers of 16 or greater. for "Revision : 0002" the function returns 2. for "Revision : 000f" the function returns 15. @@ -2943,7 +2958,7 @@ D*/ int gpioCfgClock( unsigned cfgMicros, unsigned cfgPeripheral, unsigned cfgSource); /*D -Configures pigpio to use a particualar sample rate timed by a specified +Configures pigpio to use a particular sample rate timed by a specified peripheral. . . @@ -3054,17 +3069,45 @@ D*/ /*F*/ -int gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned count); +int gpioCfgMemAlloc(unsigned memAllocMode); +/*D +Selects the method of DMA memory allocation. + +. . +memAllocMode: 0-2 +. . + +There are two methods of DMA memory allocation. The original method +uses the /proc/self/pagemap file to allocate bus memory. The new +method uses the mailbox property interface to allocate bus memory. + +Auto will use the mailbox method unless a larger than default buffer +size is requested with [*gpioCfgBufferSize*]. +D*/ + +/*F*/ +int gpioCfgInternals(unsigned cfgWhat, int cfgVal); +/*D +Used to tune internal settings. + +. . +cfgWhat: see source code + cfgVal: see source code +. . +D*/ + +/*F*/ +int gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned argc); /*D This function is available for user customisation. It returns a single integer value. . . - arg1: >=0 - arg2: >=0 - argx: extra (byte) arguments -count: number of extra arguments +arg1: >=0 +arg2: >=0 +argx: extra (byte) arguments +argc: number of extra arguments . . Returns >= 0 if OK, less than 0 indicates a user defined error. @@ -3072,7 +3115,7 @@ D*/ /*F*/ -int gpioCustom2(unsigned arg1, char *argx, unsigned count, +int gpioCustom2(unsigned arg1, char *argx, unsigned argc, char *retBuf, unsigned retMax); /*D This function is available for user customisation. @@ -3084,7 +3127,7 @@ The returned value is an integer indicating the number of returned bytes. . . arg1: >=0 argx: extra (byte) arguments - count: number of extra arguments + argc: number of extra arguments retBuf: buffer for returned bytes retMax: maximum number of bytes to return . . @@ -3095,20 +3138,6 @@ The number of returned bytes must be retMax or less. D*/ -/*F*/ -int gpioCfgInternals(unsigned cfgWhat, int cfgVal); -/*D -Used to tune internal settings. - -. . -cfgWhat: see source code - cfgVal: see source code -. . - -Not intended for general use. -D*/ - - /*F*/ int rawWaveAddSPI( rawSPI_t *spi, @@ -3329,6 +3358,25 @@ D*/ A pointer to a void object passed to a thread started by gpioStartThread. +arg1:: + +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +arg2:: + +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +argc:: + +The count of bytes passed to a user customised function. + +*argx:: + +A pointer to an array of bytes passed to a user customised function. +Its meaning and content is defined by the customiser. + bbBaud:: The baud rate used for the transmission and reception of bit banged @@ -3475,6 +3523,32 @@ gpio:: A Broadcom numbered gpio, in the range 0-53. +There are 54 General Purpose Input Outputs (gpios) named gpio0 through +gpio53. + +They are split into two banks. Bank 1 consists of gpio0 through +gpio31. Bank 2 consists of gpio32 through gpio53. + +All the gpios which are safe for the user to read and write are in +bank 1. Not all gpios in bank 1 are safe though. Type 1 boards +have 17 safe gpios. Type 2 boards have 21. Type 3 boards have 26. + +See [*gpioHardwareRevision*]. + +The user gpios are marked with an X in the following table. + +. . + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +Type 1 X X - - X - - X X X X X - - X X +Type 2 - - X X X - - X X X X X - - X X +Type 3 X X X X X X X X X X X X X X + + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +Type 1 - X X - - X X X X X - - - - - - +Type 2 - X X - - - X X X X - X X X X X +Type 3 X X X X X X X X X X X X - - - - +. . + gpioAlertFunc_t:: . . typedef void (*gpioAlertFunc_t) (int gpio, int level, uint32_t tick); @@ -3497,7 +3571,8 @@ One of [*gpioCfgPermissions*] [*gpioCfgInterfaces*] [*gpioCfgInternals*] -[*gpioCfgSocketPort*] +[*gpioCfgSocketPort*] +[*gpioCfgMemAlloc*] gpioGetSamplesFunc_t:: . . @@ -3625,6 +3700,16 @@ lVal::0-4294967295 (Hex 0x0-0xFFFFFFFF, Octal 0-37777777777) A 32-bit word value. +memAllocMode:: 0-2 + +The DMA memory allocation mode. + +. . +PI_MEM_ALLOC_AUTO 0 +PI_MEM_ALLOC_PAGEMAP 1 +PI_MEM_ALLOC_MAILBOX 2 +. . + *micros:: A value representing microseconds. @@ -3725,19 +3810,19 @@ PI_MIN_SERVO_PULSEWIDTH 500 PI_MAX_SERVO_PULSEWIDTH 2500 . . -PWMduty::0-1000 +PWMduty::0-1000000 (1M) The hardware PWM dutycycle. . . -#define PI_HW_PWM_RANGE 5000 +#define PI_HW_PWM_RANGE 1000000 . . PWMfreq::5-250K The hardware PWM frequency. . . -#define PI_HW_PWM_MIN_FREQ 5 -#define PI_HW_PWM_MAX_FREQ 50000 +#define PI_HW_PWM_MIN_FREQ 1 +#define PI_HW_PWM_MAX_FREQ 125000000 . . range::25-40000 @@ -3797,6 +3882,14 @@ typedef struct } rawWaveInfo_t; . . +*retBuf:: + +A buffer to hold a number of bytes returned to a used customised function, + +retMax:: + +The maximum number of bytes a user customised function should return. + *rxBuf:: A pointer to a buffer to receive data. @@ -3933,6 +4026,8 @@ user_gpio:: 0-31, a Broadcom numbered gpio. +See [*gpio*]. + *userdata:: A pointer to arbitrary user data. This may be used to identify the instance. @@ -4214,19 +4309,20 @@ after this command is issued. #define PI_UNKNOWN_COMMAND -88 // unknown command #define PI_SPI_XFER_FAILED -89 // spi xfer/read/write failed #define PI_BAD_POINTER -90 // bad (NULL) pointer -#define PI_NO_AUX_SPI -91 // need a B+ for auxiliary SPI +#define PI_NO_AUX_SPI -91 // need a A+/B+/Pi2 for auxiliary SPI #define PI_NOT_PWM_GPIO -92 // gpio is not in use for PWM #define PI_NOT_SERVO_GPIO -93 // gpio is not in use for servo pulses #define PI_NOT_HCLK_GPIO -94 // gpio has no hardware clock #define PI_NOT_HPWM_GPIO -95 // gpio has no hardware PWM -#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 5-50K -#define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-5000 -#define PI_BAD_HCLK_FREQ -98 // hardware clock frequency not 4689-25M +#define PI_BAD_HPWM_FREQ -96 // hardware PWM frequency not 1-125M +#define PI_BAD_HPWM_DUTY -97 // hardware PWM dutycycle not 0-1M +#define PI_BAD_HCLK_FREQ -98 // hardware clock frequency not 4689-250M #define PI_BAD_HCLK_PASS -99 // need password to use hardware clock 1 #define PI_HPWM_ILLEGAL -100 // illegal, PWM in use for main clock #define PI_BAD_DATABITS -101 // serial data bits not 1-32 #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_PIGIF_ERR_0 -2000 #define PI_PIGIF_ERR_99 -2099 @@ -4253,6 +4349,8 @@ after this command is issued. #define PI_DEFAULT_UPDATE_MASK_R2 0xFBC7CF9C #define PI_DEFAULT_UPDATE_MASK_R3 0x0080400FFFFFFCLL #define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL +#define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO + /*DEF_E*/ #endif diff --git a/pigpio.py b/pigpio.py index a4f2061..42518fc 100644 --- a/pigpio.py +++ b/pigpio.py @@ -257,7 +257,7 @@ import threading import os import atexit -VERSION = "1.15" +VERSION = "1.16" exceptions = True @@ -517,6 +517,8 @@ PI_BAD_HCLK_PASS =-99 PI_HPWM_ILLEGAL =-100 PI_BAD_DATABITS =-101 PI_BAD_STOPBITS =-102 +PI_MSG_TOOBIG =-103 +PI_BAD_MALLOC_MODE =-104 # pigpio error text @@ -609,18 +611,20 @@ _errors=[ [PI_UNKNOWN_COMMAND , "unknown command"], [PI_SPI_XFER_FAILED , "SPI xfer/read/write failed"], [_PI_BAD_POINTER , "bad (NULL) pointer"], - [PI_NO_AUX_SPI , "need a B+ for auxiliary SPI"], + [PI_NO_AUX_SPI , "need a A+/B+/Pi2 for auxiliary SPI"], [PI_NOT_PWM_GPIO , "gpio is not in use for PWM"], [PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"], [PI_NOT_HCLK_GPIO , "gpio has no hardware clock"], [PI_NOT_HPWM_GPIO , "gpio has no hardware PWM"], - [PI_BAD_HPWM_FREQ , "hardware PWM frequency not 5-50K"], - [PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-5000"], - [PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-25M"], + [PI_BAD_HPWM_FREQ , "hardware PWM frequency not 1-125M"], + [PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1M"], + [PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-250M"], [PI_BAD_HCLK_PASS , "need password to use hardware clock 1"], [PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"], [PI_BAD_DATABITS , "serial data bits not 1-32"], [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"], ] @@ -1059,10 +1063,13 @@ class pi(): For normal PWM the dutycycle will be out of the defined range - for the gpio (see [*get_PWM_range*]). If a hardware clock is - active on the gpio the reported dutycycle will be 500 - (out of 1000). If hardware PWM is active on the gpio the - reported dutycycle will be out of a 1000. + for the gpio (see [*get_PWM_range*]). + + If a hardware clock is active on the gpio the reported + dutycycle will be 500000 (500k) out of 1000000 (1M). + + If hardware PWM is active on the gpio the reported dutycycle + will be out of a 1000000 (1M). ... pi.set_PWM_dutycycle(4, 25) @@ -1098,7 +1105,7 @@ class pi(): user_gpio:= 0-31. If a hardware clock or hardware PWM is active on the gpio - the reported range will be 1000. + the reported range will be 1000000 (1M). ... pi.set_PWM_range(9, 500) @@ -1115,8 +1122,11 @@ class pi(): user_gpio:= 0-31. - If a hardware clock or hardware PWM is active on the gpio - the reported real range will be 1000. + If a hardware clock is active on the gpio the reported + real range will be 1000000 (1M). + + If hardware PWM is active on the gpio the reported real range + will be approximately 250M divided by the set PWM frequency. ... pi.set_PWM_frequency(4, 800) @@ -1157,8 +1167,11 @@ class pi(): Returns the frequency (in Hz) used for the gpio. For normal PWM the frequency will be that defined for the gpio - by [*set_PWM_frequency*]. If a hardware clock is active on the - gpio the reported frequency will be that set by [*hardware_clock*]. + by [*set_PWM_frequency*]. + + If a hardware clock is active on the gpio the reported frequency + will be that set by [*hardware_clock*]. + If hardware PWM is active on the gpio the reported frequency will be that set by [*hardware_PWM*]. @@ -1441,9 +1454,10 @@ class pi(): def hardware_clock(self, gpio, clkfreq): """ Starts a hardware clock on a gpio at the specified frequency. + Frequencies above 30MHz are unlikely to work. gpio:= see description - clkfreq:= 0 (off) or 4689-250M + clkfreq:= 0 (off) or 4689-250000000 (250M) Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, @@ -1456,9 +1470,10 @@ class pi(): . . 4 clock 0 All models - 5 clock 1 A+/B+ and compute module only (reserved for system use) - 6 clock 2 A+/B+ and compute module only - 20 clock 0 A+/B+ and compute module only + 5 clock 1 A+/B+/Pi2 and compute module only + (reserved for system use) + 6 clock 2 A+/B+/Pi2 and compute module only + 20 clock 0 A+/B+/Pi2 and compute module only 21 clock 1 All models but Rev.2 B (reserved for system use) 32 clock 0 Compute module only @@ -1482,8 +1497,8 @@ class pi(): def hardware_PWM(self, gpio, PWMfreq, PWMduty): """ - Starts hardware PWM on a gpio at the specified - frequency and dutycycle. + Starts hardware PWM on a gpio at the specified frequency + and dutycycle. Frequencies above 30MHz are unlikely to work. NOTE: Any waveform started by [*wave_send_once*], [*wave_send_repeat*], [*wave_tx_start*], or @@ -1494,25 +1509,23 @@ class pi(): pigpio daemon is started (option -t). gpio:= see descripton - PWMfreq:= 0 (off) or 5-50K - PWMduty:= 0 (off) to 5000 (fully on). + PWMfreq:= 0 (off) or 1-125000000 (125M). + PWMduty:= 0 (off) to 1000000 (1M)(fully on). Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, PI_NOT_HPWM_GPIO, PI_BAD_HPWM_DUTY, PI_BAD_HPWM_FREQ. - Both PWM channels share the same clock and the same update - frequency. The latest frequency setting will be used by - both PWM channels. The same PWM channel is available on - multiple gpios. The latest dutycycle setting will be used + The same PWM channel is available on multiple gpios. + The latest frequency and dutycycle setting will be used by all gpios which share a PWM channel. The gpio must be one of the following. . . - 12 PWM channel 0 A+/B+ and compute module only - 13 PWM channel 1 A+/B+ and compute module only + 12 PWM channel 0 A+/B+/Pi2 and compute module only + 13 PWM channel 1 A+/B+/Pi2 and compute module only 18 PWM channel 0 All models - 19 PWM channel 1 A+/B+ and compute module only + 19 PWM channel 1 A+/B+/Pi2 and compute module only 40 PWM channel 0 Compute module only 41 PWM channel 1 Compute module only @@ -1522,9 +1535,9 @@ class pi(): . . ... - pi.hardware_PWM(18, 800, 1250) # 800Hz 25% dutycycle + pi.hardware_PWM(18, 800, 250000) # 800Hz 25% dutycycle - pi.hardware_PWM(18, 2000, 3750) # 2000Hz 75% dutycycle + pi.hardware_PWM(18, 2000, 750000) # 2000Hz 75% dutycycle ... """ # pigpio message format @@ -1559,23 +1572,19 @@ class pi(): """ Returns the Pi's hardware revision number. - The hardware revision is the last 4 characters on the Revision - line of /proc/cpuinfo. + The hardware revision is the last few characters on the + Revision line of /proc/cpuinfo. The revision number can be used to determine the assignment - of gpios to pins. + of gpios to pins (see [*gpio*]). There are at least three types of board. - Type 1 has gpio 0 on P1-3, gpio 1 on P1-5, and gpio 21 on P1-13 - (revision numbers 2 and 3). + Type 1 boards have hardware revision numbers of 2 and 3. - Type 2 has gpio 2 on P1-3, gpio 3 on P1-5, gpio 27 on P1-13, - and gpios 28-31 on P5 (revision numbers of 4, 5, 6, and 15). + Type 2 boards have hardware revision numbers of 4, 5, 6, and 15. - Type 3 has a 40 pin connector rather than the 26 pin connector - of the earlier boards. Gpios 0 to 27 are brought out to the - connector (revision number 16). + Type 3 boards have hardware revision numbers of 16 or greater. If the hardware revision can not be found or is not a valid hexadecimal number the function returns 0. @@ -2424,12 +2433,12 @@ class pi(): modify the default behaviour of 4-wire operation, mode 0, active low chip select. - An auxiliary SPI device is available on the B+ and may be + An auxiliary SPI device is available on the A+/B+/Pi2 and may be selected by setting the A bit in the flags. The auxiliary device has 3 chip selects and a selectable word size in bits. - spi_channel:= 0-1 (0-2 for B+ auxiliary device). + spi_channel:= 0-1 (0-2 for A+/B+/Pi2 auxiliary device). spi_baud:= 32K-125M (values above 30M are unlikely to work). spi_flags:= see below. @@ -2447,6 +2456,9 @@ class pi(): mm defines the SPI mode. + WARNING: modes 1 and 3 do not appear to work on + the auxiliary device. + . . Mode POL PHA 0 0 0 @@ -2461,7 +2473,7 @@ class pi(): and 1 otherwise. A is 0 for the standard SPI device, 1 for the auxiliary SPI. - The auxiliary device is only present on the B+. + The auxiliary device is only present on the A+/B+/Pi2. W is 0 if the device is not 3-wire, 1 if the device is 3-wire. Standard SPI device only. @@ -2930,8 +2942,8 @@ class pi(): data bits [*bb_bits*] specified in the [*bb_serial_read_open*] command. - For [*bb_bits*] 1-8 there will be one byte per character. - For [*bb_bits*] 9-16 there will be two bytes per character. + For [*bb_bits*] 1-8 there will be one byte per character. + For [*bb_bits*] 9-16 there will be two bytes per character. For [*bb_bits*] 17-32 there will be four bytes per character. ... @@ -3183,6 +3195,18 @@ class pi(): def xref(): """ + arg1: + An unsigned argument passed to a user customised function. Its + meaning is defined by the customiser. + + arg2: + An unsigned argument passed to a user customised function. Its + meaning is defined by the customiser. + + argx: + An array of bytes passed to a user customised function. + Its meaning and content is defined by the customiser. + bb_baud: 100 - 250000 The baud rate used for the transmission of bit bang serial data. @@ -3242,34 +3266,35 @@ def xref(): RISING_EDGE = 0 errnum: <0 - PI_BAD_DATABITS = -101 - PI_BAD_DUTYCYCLE = -8 - PI_BAD_DUTYRANGE = -21 - PI_BAD_FLAGS = -77 - PI_BAD_GPIO = -3 - PI_BAD_HANDLE = -25 - PI_BAD_HCLK_FREQ = -98 - PI_BAD_HCLK_PASS = -99 - PI_BAD_HPWM_DUTY = -97 - PI_BAD_HPWM_FREQ = -96 - PI_BAD_I2C_ADDR = -75 - PI_BAD_I2C_BUS = -74 - PI_BAD_LEVEL = -5 - PI_BAD_MICS_DELAY = -64 - PI_BAD_MILS_DELAY = -65 - PI_BAD_MODE = -4 - PI_BAD_PARAM = -81 - PI_BAD_PARAM_NUM = -52 - PI_BAD_PUD = -6 - PI_BAD_PULSELEN = -46 - PI_BAD_PULSEWIDTH = -7 - PI_BAD_SCRIPT = -47 - PI_BAD_SCRIPT_CMD = -55 - PI_BAD_SCRIPT_ID = -48 - PI_BAD_SERIAL_COUNT = -51 - PI_BAD_SER_DEVICE = -79 - PI_BAD_SER_OFFSET = -49 - PI_BAD_SER_SPEED = -80 + . . + PI_BAD_DATABITS = -101 + PI_BAD_DUTYCYCLE = -8 + PI_BAD_DUTYRANGE = -21 + PI_BAD_FLAGS = -77 + PI_BAD_GPIO = -3 + PI_BAD_HANDLE = -25 + PI_BAD_HCLK_FREQ = -98 + PI_BAD_HCLK_PASS = -99 + PI_BAD_HPWM_DUTY = -97 + PI_BAD_HPWM_FREQ = -96 + PI_BAD_I2C_ADDR = -75 + PI_BAD_I2C_BUS = -74 + PI_BAD_LEVEL = -5 + PI_BAD_MICS_DELAY = -64 + PI_BAD_MILS_DELAY = -65 + PI_BAD_MODE = -4 + PI_BAD_PARAM = -81 + PI_BAD_PARAM_NUM = -52 + PI_BAD_PUD = -6 + PI_BAD_PULSELEN = -46 + PI_BAD_PULSEWIDTH = -7 + PI_BAD_SCRIPT = -47 + PI_BAD_SCRIPT_CMD = -55 + PI_BAD_SCRIPT_ID = -48 + PI_BAD_SERIAL_COUNT = -51 + PI_BAD_SER_DEVICE = -79 + PI_BAD_SER_OFFSET = -49 + PI_BAD_SER_SPEED = -80 PI_BAD_SPI_CHANNEL = -76 PI_BAD_SPI_COUNT = -84 PI_BAD_SPI_SPEED = -78 @@ -3323,6 +3348,7 @@ def xref(): PI_TOO_MANY_PULSES = -36 PI_TOO_MANY_TAGS = -54 PI_UNKNOWN_COMMAND = -88 + . . frequency: 0-40000 Defines the frequency to be used for PWM on a gpio. @@ -3334,6 +3360,32 @@ def xref(): gpio: 0-53 A Broadcom numbered gpio. All the user gpios are in the range 0-31. + There are 54 General Purpose Input Outputs (gpios) named gpio0 + through gpio53. + + They are split into two banks. Bank 1 consists of gpio0 + through gpio31. Bank 2 consists of gpio32 through gpio53. + + All the gpios which are safe for the user to read and write are in + bank 1. Not all gpios in bank 1 are safe though. Type 1 boards + have 17 safe gpios. Type 2 boards have 21. Type 3 boards have 26. + + See [*get_hardware_revision*]. + + The user gpios are marked with an X in the following table. + + . . + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + Type 1 X X - - X - - X X X X X - - X X + Type 2 - - X X X - - X X X X X - - X X + Type 3 X X X X X X X X X X X X X X + + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + Type 1 - X X - - X X X X X - - - - - - + Type 2 - X X - - - X X X X - X X X X X + Type 3 X X X X X X X X X X X X - - - - + . . + gpio_off: A mask used to select gpios to be operated on. See [*bits*]. @@ -3410,10 +3462,10 @@ def xref(): pulsewidth: The servo pulsewidth in microseconds. 0 switches pulses off. - PWMduty: 0-1000 + PWMduty: 0-1000000 (1M) The hardware PWM dutycycle. - PWMfreq: 5-250K + PWMfreq: 1-125000000 (125M) The hardware PWM frequency. range_: 25-40000 @@ -3425,6 +3477,10 @@ def xref(): An I2C device register. The usable registers depend on the actual device. + retMax: >=0 + The maximum number of bytes a user customised function + should return, default 8192. + script: The text of a script to store on the pigpio daemon. @@ -3476,6 +3532,8 @@ def xref(): Not all the gpios within this range are usable, some are reserved for system use. + See [*gpio*]. + wait_timeout: 0.0 - The number of seconds to wait in wait_for_edge before timing out. diff --git a/pigpiod.1 b/pigpiod.1 index d5b495a..3152b16 100644 --- a/pigpiod.1 +++ b/pigpiod.1 @@ -29,6 +29,11 @@ pigpiod accepts the following configuration options .br .SH OPTIONS +.IP "\fB-a value\fP" +DMA memory allocation mode +0=AUTO, 1=PMAP, 2=MBOX +default AUTO + .IP "\fB-b value\fP" gpio sample buffer in milliseconds 100-10000 @@ -110,18 +115,18 @@ All gpios may be read. .br .br -Only the default gpios for the board revision or those specified by the -x option may be updated. +Only the user gpios for the board type or those specified by the -x option may be updated. .br .br .EX -Revision 1 boards 0x03E6CF93 +Type 1 boards 0x03E6CF93 .br -Revision 2 boards 0xFBC6CF9C +Type 2 boards 0xFBC6CF9C .br -Revision 3 boards 0x0FFFFFFC +Type 3 boards 0x0FFFFFFC .br .EE @@ -158,13 +163,13 @@ There are two special cases. .br .br -The activity LED may be written (gpio 16 for Rev.1/2 -boards, gpio 47 for Rev.3 boards). +The activity LED may be written (gpio 16 for type 1 and 2 +boards, gpio 47 for type 3 boards). .br .br -The high USB power mode gpio may be written (gpio 38 for Rev.3 boards). +The high USB power mode gpio may be written (gpio 38 for type 3 boards). .SH SEE ALSO diff --git a/pigpiod.c b/pigpiod.c index d744560..da4fb8a 100644 --- a/pigpiod.c +++ b/pigpiod.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 24+ +This version is for pigpio version 30+ */ #include @@ -56,6 +56,7 @@ static unsigned ifFlags = PI_DEFAULT_IF_FLAGS; static unsigned DMAprimaryChannel = PI_DEFAULT_DMA_PRIMARY_CHANNEL; static unsigned DMAsecondaryChannel = PI_DEFAULT_DMA_SECONDARY_CHANNEL; static unsigned socketPort = PI_DEFAULT_SOCKET_PORT; +static unsigned memAllocMode = PI_DEFAULT_MEM_ALLOC_MODE; static uint64_t updateMask = -1; static int updateMaskSet = 0; @@ -82,6 +83,7 @@ void usage() { fprintf(stderr, "\n" \ "Usage: sudo pigpiod [OPTION] ...\n" \ + " -a value, DMA mode, 0=AUTO, 1=PMAP, 2=MBOX, default AUTO\n" \ " -b value, gpio sample buffer in milliseconds, default 120\n" \ " -d value, primary DMA channel, 0-14, default 14\n" \ " -e value, secondary DMA channel, 0-6, default 5\n" \ @@ -104,12 +106,19 @@ static void initOpts(int argc, char *argv[]) uint64_t mask; char * endptr; - while ((opt = getopt(argc, argv, "b:d:e:fkp:s:t:x:")) != -1) + while ((opt = getopt(argc, argv, "a:b:d:e:fkp:s:t:x:")) != -1) { i = -1; switch (opt) { + case 'a': + i = atoi(optarg); + if ((i >= PI_MEM_ALLOC_AUTO) && (i <= PI_MEM_ALLOC_MAILBOX)) + memAllocMode = i; + else fatal("invalid -a option (%d)", i); + break; + case 'b': i = atoi(optarg); if ((i >= PI_BUF_MILLIS_MIN) && (i <= PI_BUF_MILLIS_MAX)) @@ -260,6 +269,8 @@ int main(int argc, char **argv) gpioCfgSocketPort(socketPort); + gpioCfgMemAlloc(memAllocMode); + if (updateMaskSet) gpioCfgPermissions(updateMask); /* start library */ diff --git a/pigpiod_if.3 b/pigpiod_if.3 index c639793..4b639c3 100644 --- a/pigpiod_if.3 +++ b/pigpiod_if.3 @@ -461,10 +461,19 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. .br For normal PWM the dutycycle will be out of the defined range -for the gpio (see \fBget_PWM_range\fP). If a hardware clock is -active on the gpio the reported dutycycle will be 500 (out of 1000). +for the gpio (see \fBget_PWM_range\fP). + +.br + +.br +If a hardware clock is active on the gpio the reported dutycycle +will be 500000 (500k) out of 1000000 (1M). + +.br + +.br If hardware PWM is active on the gpio the reported dutycycle -will be out of a 1000. +will be out of a 1000000 (1M). .IP "\fBint set_PWM_range(unsigned user_gpio, unsigned range)\fP" .IP "" 4 @@ -548,7 +557,7 @@ otherwise PI_BAD_USER_GPIO. .br If a hardware clock or hardware PWM is active on the gpio the -reported range will be 1000. +reported range will be 1000000 (1M). .IP "\fBint get_PWM_real_range(unsigned user_gpio)\fP" .IP "" 4 @@ -573,8 +582,18 @@ otherwise PI_BAD_USER_GPIO. .br .br -If a hardware clock or hardware PWM is active on the gpio the -reported real range will be 1000. +If a hardware clock is active on the gpio the reported +real range will be 1000000 (1M). + +.br + +.br +If hardware PWM is active on the gpio the reported real range +will be approximately 250M divided by the set PWM frequency. + +.br + +.br .IP "\fBint set_PWM_frequency(unsigned user_gpio, unsigned frequency)\fP" .IP "" 4 @@ -677,10 +696,19 @@ user_gpio: 0-31. .br For normal PWM the frequency will be that defined for the gpio by -\fBset_PWM_frequency\fP. If a hardware clock is active on the gpio the -reported frequency will be that set by \fBhardware_clock\fP. If hardware -PWM is active on the gpio the reported frequency will be that set by -\fBhardware_PWM\fP. +\fBset_PWM_frequency\fP. + +.br + +.br +If a hardware clock is active on the gpio the reported frequency +will be that set by \fBhardware_clock\fP. + +.br + +.br +If hardware PWM is active on the gpio the reported frequency +will be that set by \fBhardware_PWM\fP. .br @@ -1117,6 +1145,7 @@ allowed to write to one or more of the gpios. .IP "\fBint hardware_clock(unsigned gpio, unsigned clkfreq)\fP" .IP "" 4 Starts a hardware clock on a gpio at the specified frequency. +Frequencies above 30MHz are unlikely to work. .br @@ -1125,7 +1154,7 @@ Starts a hardware clock on a gpio at the specified frequency. .EX gpio: see description .br -frequency: 0 (off) or 4689-250M +frequency: 0 (off) or 4689-250000000 (250M) .br .EE @@ -1154,11 +1183,11 @@ The gpio must be one of the following. .EX 4 clock 0 All models .br -5 clock 1 A+/B+ and compute module only (reserved for system use) +5 clock 1 A+/B+/Pi2 and compute module only (reserved for system use) .br -6 clock 2 A+/B+ and compute module only +6 clock 2 A+/B+/Pi2 and compute module only .br -20 clock 0 A+/B+ and compute module only +20 clock 0 A+/B+/Pi2 and compute module only .br 21 clock 1 All models but Rev.2 B (reserved for system use) .br @@ -1187,6 +1216,7 @@ gpio number. .IP "\fBint hardware_PWM(unsigned gpio, unsigned PWMfreq, uint32_t PWMduty)\fP" .IP "" 4 Starts hardware PWM on a gpio at the specified frequency and dutycycle. +Frequencies above 30MHz are unlikely to work. .br @@ -1207,9 +1237,9 @@ daemon is started (option -t). .EX gpio: see descripton .br -PWMfreq: 0 (off) or 5-50K +PWMfreq: 0 (off) or 1-125000000 (125M) .br -PWMduty: 0 (off) to 5000 (fully on). +PWMduty: 0 (off) to 1000000 (1M)(fully on) .br .EE @@ -1224,10 +1254,9 @@ or PI_HPWM_ILLEGAL. .br .br -Both PWM channels share the same clock and the same update frequency. -The latest frequency setting will be used by both PWM channels. The -same PWM channel is available on multiple gpios. The latest -dutycycle setting will be used by all gpios which share a PWM channel. +The same PWM channel is available on multiple gpios. The latest +frequency and dutycycle setting will be used by all gpios which +share a PWM channel. .br @@ -1239,13 +1268,13 @@ The gpio must be one of the following. .br .EX -12 PWM channel 0 A+/B+ and compute module only +12 PWM channel 0 A+/B+/Pi2 and compute module only .br -13 PWM channel 1 A+/B+ and compute module only +13 PWM channel 1 A+/B+/Pi2 and compute module only .br 18 PWM channel 0 All models .br -19 PWM channel 1 A+/B+ and compute module only +19 PWM channel 1 A+/B+/Pi2 and compute module only .br .br @@ -1288,7 +1317,7 @@ Get the Pi's hardware revision number. .br .br -The hardware revision is the last 4 characters on the Revision line +The hardware revision is the last few characters on the Revision line of /proc/cpuinfo. .br @@ -1301,29 +1330,12 @@ hexadecimal number the function returns 0. .br The revision number can be used to determine the assignment of gpios -to pins. - -.br - -.br -There are currently three types of board. - -.br +to pins (see \fBgpio\fP). .br -Type 1 has gpio 0 on P1-3, gpio 1 on P1-5, and gpio 21 on P1-13. .br - -.br -Type 2 has gpio 2 on P1-3, gpio 3 on P1-5, gpio 27 on P1-13, and -gpios 28-31 on P5. - -.br - -.br -Type 3 has a 40 pin connector rather than the 26 pin connector of -the earlier boards. Gpios 0 to 27 are brought out to the connector. +There are at least three types of board. .br @@ -1338,7 +1350,7 @@ Type 2 boards have hardware revision numbers of 4, 5, 6, and 15. .br .br -Type 3 boards have hardware revision number 16. +Type 3 boards have hardware revision numbers of 16 or greater. .IP "\fBuint32_t get_pigpio_version(void)\fP" .IP "" 4 @@ -1993,7 +2005,9 @@ data bits \fBbbBits\fP specified in the \fBbb_serial_read_open\fP command. .br For \fBbbBits\fP 1-8 there will be one byte per character. +.br For \fBbbBits\fP 9-16 there will be two bytes per character. +.br For \fBbbBits\fP 17-32 there will be four bytes per character. .IP "\fBint bb_serial_read_close(unsigned user_gpio)\fP" @@ -2512,7 +2526,7 @@ active low chip select. .br .br -An auxiliary SPI device is available on the B+ and may be +An auxiliary SPI device is available on the A+/B+/Pi2 and may be selected by setting the A bit in the flags. The auxiliary device has 3 chip selects and a selectable word size in bits. @@ -2521,7 +2535,7 @@ device has 3 chip selects and a selectable word size in bits. .br .EX -spi_channel: 0-1 (0-2 for B+ auxiliary device). +spi_channel: 0-1 (0-2 for A+/B+/Pi2 auxiliary device). .br spi_baud: 32K-125M (values above 30M are unlikely to work). .br @@ -2560,6 +2574,11 @@ mm defines the SPI mode. .br +.br +Warning: modes 1 and 3 do not appear to work on the auxiliary device. + +.br + .br .EX @@ -2590,7 +2609,7 @@ ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise. .br A is 0 for the standard SPI device, 1 for the auxiliary SPI. The -auxiliary device is only present on the B+. +auxiliary device is only present on the A+/B+/Pi2. .br @@ -2887,7 +2906,7 @@ handle: >=0, as returned by a call to \fBserial_open\fP. Returns the number of bytes of data available (>=0) if OK, otherwise PI_BAD_HANDLE. -.IP "\fBint custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned count)\fP" +.IP "\fBint custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned argc)\fP" .IP "" 4 This function is available for user customisation. @@ -2901,13 +2920,13 @@ It returns a single integer value. .br .EX - arg1: >=0 +arg1: >=0 .br - arg2: >=0 +arg2: >=0 .br - argx: extra (byte) arguments +argx: extra (byte) arguments .br -count: number of extra arguments +argc: number of extra arguments .br .EE @@ -2917,7 +2936,7 @@ count: number of extra arguments .br Returns >= 0 if OK, less than 0 indicates a user defined error. -.IP "\fBint custom_2(unsigned arg1, char *argx, unsigned count, char *retBuf, unsigned retMax)\fP" +.IP "\fBint custom_2(unsigned arg1, char *argx, unsigned argc, char *retBuf, unsigned retMax)\fP" .IP "" 4 This function is available for user customisation. @@ -2935,7 +2954,7 @@ The return value is an integer indicating the number of returned bytes. .EX arg1: >=0 .br - argx: extra (byte) arguments + argc: extra (byte) arguments .br count: number of extra arguments .br @@ -3086,6 +3105,41 @@ variable. .br +.IP "\fBarg1\fP" 0 +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +.br + +.br + +.IP "\fBarg2\fP" 0 +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +.br + +.br + +.IP "\fBargc\fP" 0 +The count of bytes passed to a user customised function. + +.br + +.br + +.IP "\fB*argx\fP" 0 +A pointer to an array of bytes passed to a user customised function. +Its meaning and content is defined by the customiser. + +.br + +.br + +.br + +.br + .IP "\fBbbBaud\fP" 0 The baud rate used for the transmission and reception of bit banged serial data. @@ -3247,7 +3301,7 @@ A single character, an 8 bit quantity able to store 0-255. .br -.IP "\fBclkfreq\fP: 4689-250M" 0 +.IP "\fBclkfreq\fP: 4689-250000000 (250M)" 0 The hardware clock frequency. .br @@ -3338,6 +3392,61 @@ A Broadcom numbered gpio, in the range 0-53. .br +.br +There are 54 General Purpose Input Outputs (gpios) named gpio0 through +gpio53. + +.br + +.br +They are split into two banks. Bank 1 consists of gpio0 through +gpio31. Bank 2 consists of gpio32 through gpio53. + +.br + +.br +All the gpios which are safe for the user to read and write are in +bank 1. Not all gpios in bank 1 are safe though. Type 1 boards +have 17 safe gpios. Type 2 boards have 21. Type 3 boards have 26. + +.br + +.br +See \fBget_hardware_revision\fP. + +.br + +.br +The user gpios are marked with an X in the following table. + +.br + +.br + +.EX + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +.br +Type 1 X X - - X - - X X X X X - - X X +.br +Type 2 - - X X X - - X X X X X - - X X +.br +Type 3 X X X X X X X X X X X X X X +.br + +.br + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +.br +Type 1 - X X - - X X X X X - - - - - - +.br +Type 2 - X X - - - X X X X - X X X X X +.br +Type 3 X X X X X X X X X X X X - - - - +.br + +.EE + +.br + .br .IP "\fBgpioPulse_t\fP" 0 @@ -3621,7 +3730,7 @@ PI_MAX_SERVO_PULSEWIDTH 2500 .br -.IP "\fBPWMduty\fP: 0-1000" 0 +.IP "\fBPWMduty\fP: 0-1000000 (1M)" 0 The hardware PWM dutycycle. .br @@ -3629,7 +3738,7 @@ The hardware PWM dutycycle. .br .EX -#define PI_HW_PWM_RANGE 1000 +#define PI_HW_PWM_RANGE 1000000 .br .EE @@ -3638,7 +3747,7 @@ The hardware PWM dutycycle. .br -.IP "\fBPWMfreq\fP: 5-250K" 0 +.IP "\fBPWMfreq\fP: 1-125000000 (125M)" 0 The hardware PWM frequency. .br @@ -3646,9 +3755,9 @@ The hardware PWM frequency. .br .EX -#define PI_HW_PWM_MIN_FREQ 5 +#define PI_HW_PWM_MIN_FREQ 1 .br -#define PI_HW_PWM_MAX_FREQ 250000 +#define PI_HW_PWM_MAX_FREQ 125000000 .br .EE @@ -3672,6 +3781,24 @@ PI_MAX_DUTYCYCLE_RANGE 40000 .br +.IP "\fB*retBuf\fP" 0 +A buffer to hold a number of bytes returned to a used customised function, + +.br + +.br + +.IP "\fBretMax\fP" 0 +The maximum number of bytes a user customised function should return. + +.br + +.br + +.br + +.br + .IP "\fB*rxBuf\fP" 0 A pointer to a buffer to receive data. @@ -3815,6 +3942,11 @@ A whole number >= 0. .br +.br +See \fBgpio\fP. + +.br + .br .IP "\fB*userdata\fP" 0 diff --git a/pigpiod_if.c b/pigpiod_if.c index 95866b2..0f5020c 100644 --- a/pigpiod_if.c +++ b/pigpiod_if.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* PIGPIOD_IF_VERSION 13 */ +/* PIGPIOD_IF_VERSION 14 */ #include #include diff --git a/pigpiod_if.h b/pigpiod_if.h index b256d46..4db7071 100644 --- a/pigpiod_if.h +++ b/pigpiod_if.h @@ -30,7 +30,7 @@ For more information, please refer to #include "pigpio.h" -#define PIGPIOD_IF_VERSION 13 +#define PIGPIOD_IF_VERSION 14 /*TEXT @@ -471,10 +471,13 @@ user_gpio: 0-31. Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO. For normal PWM the dutycycle will be out of the defined range -for the gpio (see [*get_PWM_range*]). If a hardware clock is -active on the gpio the reported dutycycle will be 500 (out of 1000). +for the gpio (see [*get_PWM_range*]). + +If a hardware clock is active on the gpio the reported dutycycle +will be 500000 (500k) out of 1000000 (1M). + If hardware PWM is active on the gpio the reported dutycycle -will be out of a 1000. +will be out of a 1000000 (1M). D*/ /*F*/ @@ -520,7 +523,7 @@ Returns the dutycycle range used for the gpio if OK, otherwise PI_BAD_USER_GPIO. If a hardware clock or hardware PWM is active on the gpio the -reported range will be 1000. +reported range will be 1000000 (1M). D*/ /*F*/ @@ -535,8 +538,12 @@ user_gpio: 0-31. Returns the real range used for the gpio if OK, otherwise PI_BAD_USER_GPIO. -If a hardware clock or hardware PWM is active on the gpio the -reported real range will be 1000. +If a hardware clock is active on the gpio the reported +real range will be 1000000 (1M). + +If hardware PWM is active on the gpio the reported real range +will be approximately 250M divided by the set PWM frequency. + D*/ /*F*/ @@ -593,10 +600,13 @@ user_gpio: 0-31. . . For normal PWM the frequency will be that defined for the gpio by -[*set_PWM_frequency*]. If a hardware clock is active on the gpio the -reported frequency will be that set by [*hardware_clock*]. If hardware -PWM is active on the gpio the reported frequency will be that set by -[*hardware_PWM*]. +[*set_PWM_frequency*]. + +If a hardware clock is active on the gpio the reported frequency +will be that set by [*hardware_clock*]. + +If hardware PWM is active on the gpio the reported frequency +will be that set by [*hardware_PWM*]. Returns the frequency (in hertz) used for the gpio if OK, otherwise PI_BAD_USER_GPIO. @@ -854,10 +864,11 @@ D*/ int hardware_clock(unsigned gpio, unsigned clkfreq); /*D Starts a hardware clock on a gpio at the specified frequency. +Frequencies above 30MHz are unlikely to work. . . gpio: see description -frequency: 0 (off) or 4689-250M +frequency: 0 (off) or 4689-250000000 (250M) . . Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, @@ -870,9 +881,9 @@ The gpio must be one of the following. . . 4 clock 0 All models -5 clock 1 A+/B+ and compute module only (reserved for system use) -6 clock 2 A+/B+ and compute module only -20 clock 0 A+/B+ and compute module only +5 clock 1 A+/B+/Pi2 and compute module only (reserved for system use) +6 clock 2 A+/B+/Pi2 and compute module only +20 clock 0 A+/B+/Pi2 and compute module only 21 clock 1 All models but Rev.2 B (reserved for system use) 32 clock 0 Compute module only @@ -892,6 +903,7 @@ D*/ int hardware_PWM(unsigned gpio, unsigned PWMfreq, uint32_t PWMduty); /*D Starts hardware PWM on a gpio at the specified frequency and dutycycle. +Frequencies above 30MHz are unlikely to work. NOTE: Any waveform started by [*wave_send_once*], [*wave_send_repeat*], [*wave_tx_start*], or [*wave_tx_repeat*] will be cancelled. @@ -901,26 +913,25 @@ daemon is started (option -t). . . gpio: see descripton -PWMfreq: 0 (off) or 5-50K -PWMduty: 0 (off) to 5000 (fully on). +PWMfreq: 0 (off) or 1-125000000 (125M) +PWMduty: 0 (off) to 1000000 (1M)(fully on) . . Returns 0 if OK, otherwise PI_NOT_PERMITTED, PI_BAD_GPIO, PI_NOT_HPWM_GPIO, PI_BAD_HPWM_DUTY, PI_BAD_HPWM_FREQ, or PI_HPWM_ILLEGAL. -Both PWM channels share the same clock and the same update frequency. -The latest frequency setting will be used by both PWM channels. The -same PWM channel is available on multiple gpios. The latest -dutycycle setting will be used by all gpios which share a PWM channel. +The same PWM channel is available on multiple gpios. The latest +frequency and dutycycle setting will be used by all gpios which +share a PWM channel. The gpio must be one of the following. . . -12 PWM channel 0 A+/B+ and compute module only -13 PWM channel 1 A+/B+ and compute module only +12 PWM channel 0 A+/B+/Pi2 and compute module only +13 PWM channel 1 A+/B+/Pi2 and compute module only 18 PWM channel 0 All models -19 PWM channel 1 A+/B+ and compute module only +19 PWM channel 1 A+/B+/Pi2 and compute module only 40 PWM channel 0 Compute module only 41 PWM channel 1 Compute module only @@ -948,30 +959,22 @@ uint32_t get_hardware_revision(void); /*D Get the Pi's hardware revision number. -The hardware revision is the last 4 characters on the Revision line +The hardware revision is the last few characters on the Revision line of /proc/cpuinfo. If the hardware revision can not be found or is not a valid hexadecimal number the function returns 0. The revision number can be used to determine the assignment of gpios -to pins. - -There are currently three types of board. +to pins (see [*gpio*]). -Type 1 has gpio 0 on P1-3, gpio 1 on P1-5, and gpio 21 on P1-13. - -Type 2 has gpio 2 on P1-3, gpio 3 on P1-5, gpio 27 on P1-13, and -gpios 28-31 on P5. - -Type 3 has a 40 pin connector rather than the 26 pin connector of -the earlier boards. Gpios 0 to 27 are brought out to the connector. +There are at least three types of board. Type 1 boards have hardware revision numbers of 2 and 3. Type 2 boards have hardware revision numbers of 4, 5, 6, and 15. -Type 3 boards have hardware revision number 16. +Type 3 boards have hardware revision numbers of 16 or greater. D*/ /*F*/ @@ -1404,8 +1407,8 @@ or PI_NOT_SERIAL_GPIO. The bytes returned for each character depend upon the number of data bits [*bbBits*] specified in the [*bb_serial_read_open*] command. -For [*bbBits*] 1-8 there will be one byte per character. -For [*bbBits*] 9-16 there will be two bytes per character. +For [*bbBits*] 1-8 there will be one byte per character. +For [*bbBits*] 9-16 there will be two bytes per character. For [*bbBits*] 17-32 there will be four bytes per character. D*/ @@ -1727,12 +1730,12 @@ Data will be transferred at baud bits per second. The flags may be used to modify the default behaviour of 4-wire operation, mode 0, active low chip select. -An auxiliary SPI device is available on the B+ and may be +An auxiliary SPI device is available on the A+/B+/Pi2 and may be selected by setting the A bit in the flags. The auxiliary device has 3 chip selects and a selectable word size in bits. . . -spi_channel: 0-1 (0-2 for B+ auxiliary device). +spi_channel: 0-1 (0-2 for A+/B+/Pi2 auxiliary device). spi_baud: 32K-125M (values above 30M are unlikely to work). spi_flags: see below. . . @@ -1749,6 +1752,8 @@ spi_flags consists of the least significant 22 bits. mm defines the SPI mode. +Warning: modes 1 and 3 do not appear to work on the auxiliary device. + . . Mode POL PHA 0 0 0 @@ -1762,7 +1767,7 @@ px is 0 if CEx is active low (default) and 1 for active high. ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise. A is 0 for the standard SPI device, 1 for the auxiliary SPI. The -auxiliary device is only present on the B+. +auxiliary device is only present on the A+/B+/Pi2. W is 0 if the device is not 3-wire, 1 if the device is 3-wire. Standard SPI device only. @@ -1950,17 +1955,17 @@ otherwise PI_BAD_HANDLE. D*/ /*F*/ -int custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned count); +int custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned argc); /*D This function is available for user customisation. It returns a single integer value. . . - arg1: >=0 - arg2: >=0 - argx: extra (byte) arguments -count: number of extra arguments +arg1: >=0 +arg2: >=0 +argx: extra (byte) arguments +argc: number of extra arguments . . Returns >= 0 if OK, less than 0 indicates a user defined error. @@ -1968,7 +1973,7 @@ D*/ /*F*/ -int custom_2(unsigned arg1, char *argx, unsigned count, +int custom_2(unsigned arg1, char *argx, unsigned argc, char *retBuf, unsigned retMax); /*D This function is available for user customisation. @@ -1979,7 +1984,7 @@ rather than just an integer. The return value is an integer indicating the number of returned bytes. . . arg1: >=0 - argx: extra (byte) arguments + argc: extra (byte) arguments count: number of extra arguments retBuf: buffer for returned data retMax: maximum number of bytes to return @@ -2068,6 +2073,22 @@ the pigpio daemon. It may be NULL in which case localhost is used unless overridden by the PIGPIO_ADDR environment variable. +arg1:: +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +arg2:: +An unsigned argument passed to a user customised function. Its +meaning is defined by the customiser. + +argc:: +The count of bytes passed to a user customised function. + +*argx:: +A pointer to an array of bytes passed to a user customised function. +Its meaning and content is defined by the customiser. + + bbBaud:: The baud rate used for the transmission and reception of bit banged serial data. @@ -2137,7 +2158,7 @@ typedef void (*CBFuncEx_t) char:: A single character, an 8 bit quantity able to store 0-255. -clkfreq::4689-250M +clkfreq::4689-250000000 (250M) The hardware clock frequency. count:: @@ -2180,6 +2201,32 @@ by its dutycycle. gpio:: A Broadcom numbered gpio, in the range 0-53. +There are 54 General Purpose Input Outputs (gpios) named gpio0 through +gpio53. + +They are split into two banks. Bank 1 consists of gpio0 through +gpio31. Bank 2 consists of gpio32 through gpio53. + +All the gpios which are safe for the user to read and write are in +bank 1. Not all gpios in bank 1 are safe though. Type 1 boards +have 17 safe gpios. Type 2 boards have 21. Type 3 boards have 26. + +See [*get_hardware_revision*]. + +The user gpios are marked with an X in the following table. + +. . + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +Type 1 X X - - X - - X X X X X - - X X +Type 2 - - X X X - - X X X X X - - X X +Type 3 X X X X X X X X X X X X X X + + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +Type 1 - X X - - X X X X X - - - - - - +Type 2 - X X - - - X X X X - X X X X X +Type 3 X X X X X X X X X X X X - - - - +. . + gpioPulse_t:: . . typedef struct @@ -2305,19 +2352,19 @@ PI_MIN_SERVO_PULSEWIDTH 500 PI_MAX_SERVO_PULSEWIDTH 2500 . . -PWMduty::0-1000 +PWMduty::0-1000000 (1M) The hardware PWM dutycycle. . . -#define PI_HW_PWM_RANGE 1000 +#define PI_HW_PWM_RANGE 1000000 . . -PWMfreq::5-250K +PWMfreq::1-125000000 (125M) The hardware PWM frequency. . . -#define PI_HW_PWM_MIN_FREQ 5 -#define PI_HW_PWM_MAX_FREQ 250000 +#define PI_HW_PWM_MIN_FREQ 1 +#define PI_HW_PWM_MAX_FREQ 125000000 . . range::25-40000 @@ -2327,6 +2374,13 @@ PI_MIN_DUTYCYCLE_RANGE 25 PI_MAX_DUTYCYCLE_RANGE 40000 . . +*retBuf:: +A buffer to hold a number of bytes returned to a used customised function, + +retMax:: +The maximum number of bytes a user customised function should return. + + *rxBuf:: A pointer to a buffer to receive data. @@ -2390,6 +2444,8 @@ A whole number >= 0. user_gpio:: 0-31, a Broadcom numbered gpio. +See [*gpio*]. + *userdata:: A pointer to arbitrary user data. This may be used to identify the instance. diff --git a/pigs.1 b/pigs.1 index 78ff421..0afa9c5 100644 --- a/pigs.1 +++ b/pigs.1 @@ -236,7 +236,7 @@ will be returned. .br .EX -$ pigs bc2 0x8000 # clear gpio 47 (activity LED on B+) +$ pigs bc2 0x8000 # clear gpio 47 (activity LED on A+/B+/Pi2) .br .br @@ -336,7 +336,7 @@ will be returned. .br .EX -$ pigs bs2 0x40 # set gpio 38 (enable high current mode B+) +$ pigs bs2 0x40 # set gpio 38 (enable high current mode A+/B+/Pi2) .br .br @@ -351,6 +351,26 @@ ERROR: no permission to update one or more gpios .br +.IP "\fBCF1 uvs\fP - Custom function 1" +.IP "" 4 + +.br +This command calls a user customised function. The meaning of +any paramaters and the returned value is defined by the +customiser. + +.br + +.IP "\fBCF2 uvs\fP - Custom function 2" +.IP "" 4 + +.br +This command calls a user customised function. The meaning of +any paramaters and the returned value is defined by the +customiser. + +.br + .IP "\fBGDC u\fP - Get gpio PWM dutycycle" .IP "" 4 @@ -363,10 +383,15 @@ status code will be returned. .br For normal PWM the dutycycle will be out of the defined range -for the gpio (see \fBPRG\fP). If a hardware clock is active on -the gpio the reported dutycycle will be 500 (out of 1000). +for the gpio (see \fBPRG\fP). + +.br +If a hardware clock is active on the gpio the reported +dutycycle will be 500000 (500k) out of 1000000 (1M). + +.br If hardware PWM is active on the gpio the reported dutycycle -will be out of a 1000. +will be out of a 1000000 (1M). .br @@ -452,7 +477,7 @@ $ pigs help .IP "\fBHC g cf\fP - Set hardware clock frequency" .IP "" 4 This command sets the hardware clock associated with gpio \fBg\fP to -frequency \fBcf\fP. +frequency \fBcf\fP. Frequencies above 30MHz are unlikely to work. .br Upon success nothing is returned. On error a negative status code @@ -488,10 +513,10 @@ The gpio must be one of the following. .EX 4 clock 0 All models -5 clock 1 A+/B+ and compute module only (reserved for system use) -6 clock 2 A+/B+ and compute module only -20 clock 0 A+/B+ and compute module only -21 clock 1 All models but Rev.2 B (reserved for system use) +5 clock 1 A+/B+/Pi2 and compute module only (reserved for system use) +6 clock 2 A+/B+/Pi2 and compute module only +20 clock 0 A+/B+/Pi2 and compute module only +21 clock 1 All models but Type 2 B (reserved for system use) .EE @@ -516,7 +541,8 @@ with the gpio number. .IP "\fBHP g pf pdc\fP - Set hardware PWM frequency and dutycycle" .IP "" 4 This command sets the hardware PWM associated with gpio \fBg\fP to -frequency \fBpf\fP with dutycycle \fBpdc\fP. +frequency \fBpf\fP with dutycycle \fBpdc\fP. Frequencies above 30MHz +are unlikely to work. .br NOTE: Any waveform started by \fBWVGO\fP, \fBWVGOR\fP, \fBWVTX\fP or @@ -534,28 +560,27 @@ will be returned. .br .EX -$ pigs hp 18 100 4000 # 80% dutycycle +$ pigs hp 18 100 800000 # 80% dutycycle .br .br -$ pigs hp 19 100 1000 # 20% dutycycle +$ pigs hp 19 100 200000 # 20% dutycycle .br .br -$ pigs hp 19 1 100 +$ pigs hp 19 125000001 100000 .br -96 .br -ERROR: hardware PWM frequency not 5-50K +ERROR: hardware PWM frequency not 1-125M .br .EE .br -Both PWM channels share the same clock and the same update frequency. -The latest frequency setting will be used by both PWM channels. The -same PWM channel is available on multiple gpios. The latest -dutycycle setting will be used by all gpios which share a PWM channel. +The same PWM channel is available on multiple gpios. The latest +frequency and dutycycle setting will be used by all gpios which +share a PWM channel. .br The gpio must be one of the following. @@ -563,10 +588,10 @@ The gpio must be one of the following. .br .EX -12 PWM channel 0 A+/B+ and compute module only -13 PWM channel 1 A+/B+ and compute module only +12 PWM channel 0 A+/B+/Pi2 and compute module only +13 PWM channel 1 A+/B+/Pi2 and compute module only 18 PWM channel 0 All models -19 PWM channel 1 A+/B+ and compute module only +19 PWM channel 1 A+/B+/Pi2 and compute module only .EE @@ -588,7 +613,7 @@ The gpio must be one of the following. This command returns the hardware revision of the Pi. .br -The hardware revision is found in the last 4 characters on the Revision +The hardware revision is found in the last 4 characters on the Type sion line of /proc/cpuinfo. .br @@ -596,23 +621,12 @@ If the hardware revision can not be found or is not a valid hexadecimal number the command returns 0. .br -The revision number can be used to determine the assignment of gpios to pins. +The revision number can be used to determine the assignment of gpios +to pins (see \fBg\fP). .br There are currently three types of board. -.br -Type 1 has gpio 0 on P1-3, gpio 1 on P1-5, and gpio 21 on P1-13. - -.br -Type 2 has gpio 2 on P1-3, gpio 3 on P1-5, gpio 27 on P1-13, and -gpios 28-31 on P5. - -.br -Type 3 has a 40 pin connector rather than the 26 pin connector of -the earlier boards. Gpios 0 to 27 are brought out to the connector -(although gpios 0 and 1 are reserved). - .br Type 1 boards have hardware revision numbers of 2 and 3. @@ -620,7 +634,7 @@ Type 1 boards have hardware revision numbers of 2 and 3. Type 2 boards have hardware revision numbers of 4, 5, 6, and 15. .br -Type 3 boards have hardware revision number 16. +Type 3 boards have hardware revision numbers of 16 or greater. .br for "Revision : 0002" the command returns 2. @@ -1491,8 +1505,13 @@ status code will be returned. .br For normal PWM the frequency will be that defined for the gpio -by \fBPFS\fP. If a hardware clock is active on the gpio -the reported frequency will be that set by \fBHC\fP. +by \fBPFS\fP. + +.br +If a hardware clock is active on the gpio the reported frequency +will be that set by \fBHC\fP. + +.br If hardware PWM is active on the gpio the reported frequency will be that set by \fBHP\fP. @@ -1626,7 +1645,7 @@ will be returned. .br If a hardware clock or hardware PWM is active on the gpio the reported -range will be 1000. +range will be 1000000 (1M). .br @@ -1857,12 +1876,15 @@ ERROR: unknown script id This command returns the real underlying range used by gpio \fBu\fP. .br -If a hardware clock or hardware PWM is active on the gpio the -reported range will be 1000. +If a hardware clock is active on the gpio the reported +real range will be 1000000 (1M). .br -Upon success the real range is returned. On error a negative status code -will be returned. +If hardware PWM is active on the gpio the reported real range +will be approximately 250M divided by the set PWM frequency. + +.br +On error a negative status code will be returned. .br See \fBPRS\fP. @@ -2412,7 +2434,7 @@ may be used to modify the default behaviour of 4-wire operation, mode 0, active low chip select. .br -An auxiliary SPI device is available on the B+ and may be +An auxiliary SPI device is available on the A+/B+/Pi2 and may be selected by setting the A bit in the flags. The auxiliary device has 3 chip selects and a selectable word size in bits. @@ -2432,6 +2454,9 @@ The flags consists of the least significant 22 bits. .br mm defines the SPI mode. +.br +Warning: modes 1 and 3 do not appear to work on the auxiliary device. + .br .EX @@ -2456,7 +2481,7 @@ ux is 0 if the CEx gpio is reserved for SPI (default) and 1 otherwise. .br A is 0 for the standard SPI device, 1 for the auxiliary SPI. The -auxiliary device is only present on the B+. +auxiliary device is only present on the A+/B+/Pi2. .br W is 0 if the device is not 3-wire, 1 if the device is 3-wire. Standard @@ -3334,8 +3359,11 @@ Bank 2 consists of gpio32 through gpio53. .br All the gpios which are safe for the user to read and write are in bank 1. -Not all gpios in bank 1 are safe though. Rev.1 boards have 17 safe gpios. -Rev.2 boards have 21. Rev.3 boards have 26. +Not all gpios in bank 1 are safe though. Type 1 boards have 17 safe gpios. +Type 2 boards have 21. Type 3 boards have 26. + +.br +See \fBHWVER\fP. .br The user gpios are marked with an X in the following table. @@ -3343,15 +3371,15 @@ The user gpios are marked with an X in the following table. .br .EX - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -Rev.1 X X - - X - - X X X X X - - X X -Rev.2 - - X X X - - X X X X X - - X X -Rev.3 X X X X X X X X X X X X X X - - 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -Rev.1 - X X - - X X X X X - - - - - - -Rev.2 - X X - - - X X X X - X X X X X -Rev.3 X X X X X X X X X X X X - - - - + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +Type 1 X X - - X - - X X X X X - - X X +Type 2 - - X X X - - X X X X X - - X X +Type 3 X X X X X X X X X X X X X X + + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +Type 1 - X X - - X X X X X - - - - - - +Type 2 - X X - - - X X X X - X X X X X +Type 3 X X X X X X X X X X X X - - - - .EE @@ -3466,17 +3494,17 @@ The command expects 0 to 10 numbers as parameters to be passed to the script. .br -.IP "\fBpdc\fP - hardware PWM dutycycle (0-1000)" 0 +.IP "\fBpdc\fP - hardware PWM dutycycle (0-1000000)" 0 The command expects a dutycycle. .br -.IP "\fBpf\fP - hardware PWM frequency (5-250K)" 0 +.IP "\fBpf\fP - hardware PWM frequency (1-125M)" 0 The command expects a frequency. .br -.IP "\fBpl\fP - pulse length (1-50)" 0 +.IP "\fBpl\fP - pulse length (1-100)" 0 The command expects a pulse length in microseconds. .br @@ -3545,6 +3573,12 @@ See \fBg\fP .br +.IP "\fBuvs\fP - values" 0 +The command expects an arbitrary number of >=0 values (possibly none). +Any after the first two must be <= 255. + +.br + .IP "\fBv\fP - value" 0 The command expects a number. @@ -3766,7 +3800,8 @@ Each script has .br .SS Commands .br -All the normal pigs commands may be used within a script. +All the normal pigs commands may be used within a script. However +commands which return more than an integer will be of little use. .br The following commands are only legal within a script. diff --git a/setup.py b/setup.py index 6e6be8a..8fec0ac 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from distutils.core import setup setup(name='pigpio', - version='1.15', + version='1.16', author='joan', author_email='joan@abyz.co.uk', maintainer='joan', diff --git a/x_pigs b/x_pigs index f4242fb..143ff4e 100755 --- a/x_pigs +++ b/x_pigs @@ -1,7 +1,5 @@ #!/bin/bash -VERSION=29 - GPIO=4 # @@ -21,6 +19,11 @@ GPIO=4 # of tests indicate a problem. # +echo "Testing pigs I/F" + +s=$(pigs pigpv) +echo "pigpio version $s" + s=$(pigs bc1 0) if [[ $s = "" ]]; then echo "BC1 ok"; else echo "BC1 fail ($s)"; fi @@ -91,9 +94,6 @@ if [[ $s = 10 ]]; then echo "PFS-a ok"; else echo "PFS-a fail ($s)"; fi s=$(pigs pfs $GPIO 800) if [[ $s = 800 ]]; then echo "PFS-b ok"; else echo "PFS-b fail ($s)"; fi -s=$(pigs pigpv) -if [[ $s = $VERSION ]]; then echo "PIGPV ok"; else echo "PIGPV fail ($s)"; fi - s=$(pigs prs $GPIO 255) if [[ $s = 250 ]]; then echo "PRG-a ok"; else echo "PRG-a fail ($s)"; fi s=$(pigs prg $GPIO) diff --git a/x_pipe b/x_pipe index f83a3e9..0697b24 100755 --- a/x_pipe +++ b/x_pipe @@ -1,7 +1,5 @@ #!/bin/bash -VERSION=29 - GPIO=4 # @@ -20,6 +18,12 @@ GPIO=4 # of tests indicate a problem. # +echo "Testing pipe I/F" + +echo "pigpv" >/dev/pigpio +read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio -read -t 1 s /dev/pigpio read -t 1 s