From 3ea6fd94fd770e331a4cf8ccfafc875bd1d85246 Mon Sep 17 00:00:00 2001 From: joan2937 Date: Tue, 2 Jul 2019 18:04:12 +0100 Subject: [PATCH] V68+: Changes for Pi4B (base address, default DMA channels, PUD) --- pigpio.3 | 36 +++++++++--- pigpio.c | 171 +++++++++++++++++++++++++++++++++++++++--------------- pigpio.h | 35 ++++++----- pigpiod.c | 6 +- 4 files changed, 177 insertions(+), 71 deletions(-) diff --git a/pigpio.3 b/pigpio.3 index 0bb28c8..b37f1e5 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -7029,8 +7029,20 @@ secondaryChannel: 0-14 .br .br -The default setting is to use channel 14 for the primary channel and -channel 6 for the secondary channel. +The default setting depends on whether the Pi has a BCM2711 chip or +not (currently only the Pi4B has a BCM2711). + +.br + +.br +The default setting for a non-BCM2711 is to use channel 14 for the +primary channel and channel 6 for the secondary channel. + +.br + +.br +The default setting for a BCM2711 is to use channel 7 for the +primary channel and channel 6 for the secondary channel. .br @@ -8022,12 +8034,12 @@ PI_MAX_WAVE_DATABITS 32 .br -.IP "\fBDMAchannel\fP: 0-14" 0 +.IP "\fBDMAchannel\fP: 0-15" 0 .EX PI_MIN_DMA_CHANNEL 0 .br -PI_MAX_DMA_CHANNEL 14 +PI_MAX_DMA_CHANNEL 15 .br .EE @@ -8928,7 +8940,7 @@ The position of an item. .br -.IP "\fBprimaryChannel\fP: 0-14" 0 +.IP "\fBprimaryChannel\fP: 0-15" 0 The DMA channel used to time the sampling of GPIO and to time servo and PWM pulses. @@ -10103,15 +10115,15 @@ A 16-bit word value. .br #define PI_BAD_IF_FLAGS -26 // ifFlags > 4 .br -#define PI_BAD_CHANNEL -27 // DMA channel not 0-14 +#define PI_BAD_CHANNEL -27 // DMA channel not 0-15 .br -#define PI_BAD_PRIM_CHANNEL -27 // DMA primary channel not 0-14 +#define PI_BAD_PRIM_CHANNEL -27 // DMA primary channel not 0-15 .br #define PI_BAD_SOCKET_PORT -28 // socket port not 1024-32000 .br #define PI_BAD_FIFO_COMMAND -29 // unrecognized fifo command .br -#define PI_BAD_SECO_CHANNEL -30 // DMA secondary channel not 0-6 +#define PI_BAD_SECO_CHANNEL -30 // DMA secondary channel not 0-15 .br #define PI_NOT_INITIALISED -31 // function called before gpioInitialise .br @@ -10380,6 +10392,12 @@ A 16-bit word value. .br #define PI_DEFAULT_DMA_SECONDARY_CHANNEL 6 .br +#define PI_DEFAULT_DMA_PRIMARY_CH_2711 7 +.br +#define PI_DEFAULT_DMA_SECONDARY_CH_2711 6 +.br +#define PI_DEFAULT_DMA_NOT_SET 15 +.br #define PI_DEFAULT_SOCKET_PORT 8888 .br #define PI_DEFAULT_SOCKET_PORT_STR "8888" @@ -10400,6 +10418,8 @@ A 16-bit word value. .br #define PI_DEFAULT_UPDATE_MASK_PI3B 0x0000000FFFFFFCLL .br +#define PI_DEFAULT_UPDATE_MASK_PI4B 0x0000000FFFFFFCLL +.br #define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL .br #define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO diff --git a/pigpio.c b/pigpio.c index 3102e32..1126ec3 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 68 */ +/* pigpio version 69 */ /* include ------------------------------------------------------- */ @@ -114,6 +114,11 @@ For more information, please refer to 39 GPPUDCLK1 GPIO Pin Pull-up/down Enable Clock 1 40 - Reserved 41 - Test +42-56 Reserved +57 GPPUPPDN1 Pin pull-up/down for pins 15:0 +58 GPPUPPDN1 Pin pull-up/down for pins 31:16 +59 GPPUPPDN2 Pin pull-up/down for pins 47:32 +60 GPPUPPDN3 Pin pull-up/down for pins 57:48 */ /* @@ -317,7 +322,7 @@ bit 0 READ_LAST_NOT_SET_ERROR #define BSCS_LEN 0x40 #define CLK_LEN 0xA8 #define DMA_LEN 0x1000 /* allow access to all channels */ -#define GPIO_LEN 0xB4 +#define GPIO_LEN 0xF4 /* 2711 has more registers */ #define PADS_LEN 0x38 #define PCM_LEN 0x24 #define PWM_LEN 0x28 @@ -357,6 +362,13 @@ bit 0 READ_LAST_NOT_SET_ERROR #define GPPUDCLK0 38 #define GPPUDCLK1 39 +/* BCM2711 has different pulls */ + +#define GPPUPPDN0 57 +#define GPPUPPDN1 58 +#define GPPUPPDN2 59 +#define GPPUPPDN3 60 + #define DMA_CS 0 #define DMA_CONBLK_AD 1 #define DMA_DEBUG 8 @@ -498,8 +510,9 @@ bit 0 READ_LAST_NOT_SET_ERROR #define CLK_CTL_SRC_OSC 1 #define CLK_CTL_SRC_PLLD 6 -#define CLK_OSC_FREQ 19200000 -#define CLK_PLLD_FREQ 500000000 +#define CLK_OSC_FREQ 19200000 +#define CLK_PLLD_FREQ 500000000 +#define CLK_PLLD_FREQ_2711 750000000 #define CLK_DIV_DIVI(x) ((x)<<12) #define CLK_DIV_DIVF(x) ((x)<< 0) @@ -1199,11 +1212,13 @@ typedef struct /* initialise once then preserve */ -static volatile uint32_t piCores = 0; -static volatile uint32_t pi_ispi = 0; -static volatile uint32_t pi_peri_phys = 0x20000000; -static volatile uint32_t pi_dram_bus = 0x40000000; -static volatile uint32_t pi_mem_flag = 0x0C; +static volatile uint32_t piCores = 0; +static volatile uint32_t pi_peri_phys = 0x20000000; +static volatile uint32_t pi_dram_bus = 0x40000000; +static volatile uint32_t pi_mem_flag = 0x0C; +static volatile uint32_t pi_ispi = 0; +static volatile uint32_t pi_is_2711 = 0; +static volatile uint32_t clk_plld_freq = CLK_PLLD_FREQ; static int libInitialised = 0; @@ -1341,8 +1356,8 @@ static volatile gpioCfg_t gpioCfg = PI_DEFAULT_BUFFER_MILLIS, PI_DEFAULT_CLK_MICROS, PI_DEFAULT_CLK_PERIPHERAL, - PI_DEFAULT_DMA_PRIMARY_CHANNEL, - PI_DEFAULT_DMA_SECONDARY_CHANNEL, + PI_DEFAULT_DMA_NOT_SET, /* primary DMA */ + PI_DEFAULT_DMA_NOT_SET, /* secondary DMA */ PI_DEFAULT_SOCKET_PORT, PI_DEFAULT_IF_FLAGS, PI_DEFAULT_MEM_ALLOC_MODE, @@ -4336,7 +4351,7 @@ static void spiGoA( cs = PI_SPI_FLAGS_GET_CSPOLS(flags) & (1< PI_PUD_UP) SOFT_ERROR(PI_BAD_PUD, "gpio %d, bad pud (%d)", gpio, pud); - *(gpioReg + GPPUD) = pud; + if (pi_is_2711) + { + switch (pud) + { + case PI_PUD_OFF: pull = 0; break; + case PI_PUD_UP: pull = 1; break; + case PI_PUD_DOWN: pull = 2; break; + } - myGpioDelay(1); + bits = *(gpioReg + GPPUPPDN0 + (gpio>>4)); + bits &= ~(3 << shift); + bits |= (pull << shift); + *(gpioReg + GPPUPPDN0 + (gpio>>4)) = bits; + } + else + { + *(gpioReg + GPPUD) = pud; - *(gpioReg + GPPUDCLK0 + BANK) = BIT; + myGpioDelay(1); - myGpioDelay(1); + *(gpioReg + GPPUDCLK0 + BANK) = BIT; - *(gpioReg + GPPUD) = 0; + myGpioDelay(1); - *(gpioReg + GPPUDCLK0 + BANK) = 0; + *(gpioReg + GPPUD) = 0; + + *(gpioReg + GPPUDCLK0 + BANK) = 0; + } return 0; } @@ -12611,7 +12652,7 @@ int gpioHardwareClock(unsigned gpio, unsigned frequency) int cctl[] = {CLK_GP0_CTL, CLK_GP1_CTL, CLK_GP2_CTL}; int cdiv[] = {CLK_GP0_DIV, CLK_GP1_DIV, CLK_GP2_DIV}; 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 cfreq[CLK_SRCS]={CLK_OSC_FREQ, clk_plld_freq}; unsigned clock, mode, mash; int password = 0; double f; @@ -12722,13 +12763,13 @@ int gpioHardwarePWM( if (frequency) { - real_range = ((double)CLK_PLLD_FREQ / (2.0 * frequency)) + 0.5; + real_range = ((double)clk_plld_freq / (2.0 * frequency)) + 0.5; real_dutycycle = ((uint64_t)dutycycle * real_range) / PI_HW_PWM_RANGE; /* record the set PWM frequency and dutycycle */ hw_pwm_freq[pwm] = - ((double)CLK_PLLD_FREQ / ( 2.0 * real_range)) + 0.5; + ((double)clk_plld_freq / ( 2.0 * real_range)) + 0.5; hw_pwm_duty[pwm] = dutycycle; @@ -13391,9 +13432,15 @@ unsigned gpioHardwareRevision(void) } } - if (!strncasecmp("hardware\t: BCM", buf, 14)) { + if (!strncasecmp("hardware\t: BCM", buf, 14)) + { int bcmno = atoi(buf+14); - if ((bcmno == 2708) || (bcmno == 2709) || (bcmno == 2710) || (bcmno == 2835) || (bcmno == 2836) || (bcmno == 2837)) + if ((bcmno == 2708) || + (bcmno == 2709) || + (bcmno == 2710) || + (bcmno == 2835) || + (bcmno == 2836) || + (bcmno == 2837)) { pi_ispi = 1; } @@ -13405,12 +13452,37 @@ unsigned gpioHardwareRevision(void) { if (term != '\n') rev = 0; else rev &= 0xFFFFFF; /* mask out warranty bit */ + switch (rev&0xFFF0) /* just interested in BCM model */ + { + case 0x3110: /* Pi4B */ + piCores = 4; + pi_peri_phys = 0xFE000000; + pi_dram_bus = 0xC0000000; + pi_mem_flag = 0x04; + pi_is_2711 = 1; + pi_ispi = 1; + clk_plld_freq = CLK_PLLD_FREQ_2711; + fclose(filp); + if (!gpioMaskSet) + { + gpioMaskSet = 1; + gpioMask = PI_DEFAULT_UPDATE_MASK_PI4B; + } + return rev; + break; + } } } } fclose(filp); - //raspberry pi 3 running arm64 don't put all the information we need in /proc/cpuinfo, but we can get it elsewhere. + + /* + Raspberry pi 3 running arm64 don't put all the + information we need in /proc/cpuinfo, but we can + get it elsewhere. + */ + if (!pi_ispi) { filp = fopen ("/proc/device-tree/model", "r"); @@ -13430,6 +13502,7 @@ unsigned gpioHardwareRevision(void) } fclose(filp); } + if (rev == 0) { filp = fopen ("/proc/device-tree/system/linux,revision", "r"); @@ -13438,8 +13511,11 @@ unsigned gpioHardwareRevision(void) uint32_t tmp; if (fread(&tmp,1 , 4, filp) == 4) { - // for some reason the value returned by reading this - // /proc entry seems to be big endian, convert it. + /* + for some reason the value returned by reading + this /proc entry seems to be big endian, + convert it. + */ rev = ntohl(tmp); rev &= 0xFFFFFF; /* mask out warranty bit */ } @@ -13523,7 +13599,8 @@ int gpioCfgDMAchannels(unsigned primaryChannel, unsigned secondaryChannel) primaryChannel); if ((secondaryChannel > PI_MAX_DMA_CHANNEL) || - (secondaryChannel == primaryChannel)) + ((secondaryChannel == primaryChannel) && + (secondaryChannel != PI_DEFAULT_DMA_NOT_SET))) SOFT_ERROR(PI_BAD_SECO_CHANNEL, "bad secondary channel (%d)", secondaryChannel); diff --git a/pigpio.h b/pigpio.h index 8c79d2c..03ebdca 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#define PIGPIO_VERSION 68 +#define PIGPIO_VERSION 6904 /*TEXT @@ -831,10 +831,10 @@ typedef void *(gpioThreadFunc_t) (void *); #define PI_CLOCK_PWM 0 #define PI_CLOCK_PCM 1 -/* DMA channel: 0-14 */ +/* DMA channel: 0-15, 15 is unset */ #define PI_MIN_DMA_CHANNEL 0 -#define PI_MAX_DMA_CHANNEL 14 +#define PI_MAX_DMA_CHANNEL 15 /* port */ @@ -4745,8 +4745,7 @@ D*/ /*F*/ -int gpioCfgDMAchannels( - unsigned primaryChannel, unsigned secondaryChannel); +int gpioCfgDMAchannels(unsigned primaryChannel, unsigned secondaryChannel); /*D Configures pigpio to use the specified DMA channels. @@ -4757,8 +4756,14 @@ This function is only effective if called before [*gpioInitialise*]. secondaryChannel: 0-14 . . -The default setting is to use channel 14 for the primary channel and -channel 6 for the secondary channel. +The default setting depends on whether the Pi has a BCM2711 chip or +not (currently only the Pi4B has a BCM2711). + +The default setting for a non-BCM2711 is to use channel 14 for the +primary channel and channel 6 for the secondary channel. + +The default setting for a BCM2711 is to use channel 7 for the +primary channel and channel 6 for the secondary channel. The secondary channel is only used for the transmission of waves. @@ -5331,10 +5336,10 @@ PI_MIN_WAVE_DATABITS 1 PI_MAX_WAVE_DATABITS 32 . . -DMAchannel::0-14 +DMAchannel::0-15 . . PI_MIN_DMA_CHANNEL 0 -PI_MAX_DMA_CHANNEL 14 +PI_MAX_DMA_CHANNEL 15 . . double:: @@ -5718,7 +5723,7 @@ The port used to bind to the pigpio socket. Defaults to 8888. pos:: The position of an item. -primaryChannel:: 0-14 +primaryChannel:: 0-15 The DMA channel used to time the sampling of GPIO and to time servo and PWM pulses. @@ -6301,11 +6306,11 @@ after this command is issued. #define PI_NO_HANDLE -24 // no handle available #define PI_BAD_HANDLE -25 // unknown handle #define PI_BAD_IF_FLAGS -26 // ifFlags > 4 -#define PI_BAD_CHANNEL -27 // DMA channel not 0-14 -#define PI_BAD_PRIM_CHANNEL -27 // DMA primary channel not 0-14 +#define PI_BAD_CHANNEL -27 // DMA channel not 0-15 +#define PI_BAD_PRIM_CHANNEL -27 // DMA primary channel not 0-15 #define PI_BAD_SOCKET_PORT -28 // socket port not 1024-32000 #define PI_BAD_FIFO_COMMAND -29 // unrecognized fifo command -#define PI_BAD_SECO_CHANNEL -30 // DMA secondary channel not 0-6 +#define PI_BAD_SECO_CHANNEL -30 // DMA secondary channel not 0-15 #define PI_NOT_INITIALISED -31 // function called before gpioInitialise #define PI_INITIALISED -32 // function called after gpioInitialise #define PI_BAD_WAVE_MODE -33 // waveform mode not 0-3 @@ -6440,6 +6445,9 @@ after this command is issued. #define PI_DEFAULT_DMA_CHANNEL 14 #define PI_DEFAULT_DMA_PRIMARY_CHANNEL 14 #define PI_DEFAULT_DMA_SECONDARY_CHANNEL 6 +#define PI_DEFAULT_DMA_PRIMARY_CH_2711 7 +#define PI_DEFAULT_DMA_SECONDARY_CH_2711 6 +#define PI_DEFAULT_DMA_NOT_SET 15 #define PI_DEFAULT_SOCKET_PORT 8888 #define PI_DEFAULT_SOCKET_PORT_STR "8888" #define PI_DEFAULT_SOCKET_ADDR_STR "127.0.0.1" @@ -6450,6 +6458,7 @@ after this command is issued. #define PI_DEFAULT_UPDATE_MASK_ZERO 0x0080000FFFFFFCLL #define PI_DEFAULT_UPDATE_MASK_PI2B 0x0080480FFFFFFCLL #define PI_DEFAULT_UPDATE_MASK_PI3B 0x0000000FFFFFFCLL +#define PI_DEFAULT_UPDATE_MASK_PI4B 0x0000000FFFFFFCLL #define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL #define PI_DEFAULT_MEM_ALLOC_MODE PI_MEM_ALLOC_AUTO diff --git a/pigpiod.c b/pigpiod.c index ce3833a..899ddf8 100644 --- a/pigpiod.c +++ b/pigpiod.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 65+ +This version is for pigpio version 69+ */ #include @@ -56,8 +56,8 @@ static unsigned clockMicros = PI_DEFAULT_CLK_MICROS; static unsigned clockPeripheral = PI_DEFAULT_CLK_PERIPHERAL; static unsigned ifFlags = PI_DEFAULT_IF_FLAGS; static int foreground = PI_DEFAULT_FOREGROUND; -static unsigned DMAprimaryChannel = PI_DEFAULT_DMA_PRIMARY_CHANNEL; -static unsigned DMAsecondaryChannel = PI_DEFAULT_DMA_SECONDARY_CHANNEL; +static unsigned DMAprimaryChannel = PI_DEFAULT_DMA_NOT_SET; +static unsigned DMAsecondaryChannel = PI_DEFAULT_DMA_NOT_SET; static unsigned socketPort = PI_DEFAULT_SOCKET_PORT; static unsigned memAllocMode = PI_DEFAULT_MEM_ALLOC_MODE; static uint64_t updateMask = -1;