V68+: Changes for Pi4B (base address, default DMA channels, PUD)

This commit is contained in:
joan2937 2019-07-02 18:04:12 +01:00
parent 4985f93f67
commit 3ea6fd94fd
4 changed files with 177 additions and 71 deletions

View File

@ -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

167
pigpio.c
View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* pigpio version 68 */
/* pigpio version 69 */
/* include ------------------------------------------------------- */
@ -114,6 +114,11 @@ For more information, please refer to <http://unlicense.org/>
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<<channel);
spiDefaults = AUXSPI_CNTL0_SPEED(125000000/speed) |
spiDefaults = AUXSPI_CNTL0_SPEED((125000000/speed)-1)|
AUXSPI_CNTL0_IN_RISING(bit_ir[mode]) |
AUXSPI_CNTL0_OUT_RISING(bit_or[mode]) |
AUXSPI_CNTL0_INVERT_CLK(bit_ic[mode]) |
@ -7259,36 +7274,41 @@ static int initCheckPermitted(void)
static int initPeripherals(void)
{
uint32_t dmaBase;
DBG(DBG_STARTUP, "");
gpioReg = initMapMem(fdMem, GPIO_BASE, GPIO_LEN);
if (gpioReg == MAP_FAILED)
SOFT_ERROR(PI_INIT_FAILED, "mmap gpio failed (%m) GPIO_BASE=%08X GPIO_LEN=%08X REV=%08X",GPIO_BASE,GPIO_LEN,gpioHardwareRevision());
SOFT_ERROR(PI_INIT_FAILED, "mmap gpio failed (%m)");
/* dma channels 0-14 share one page, 15 has another */
if (gpioCfg.DMAprimaryChannel < 15)
{
dmaBase = DMA_BASE;
}
else dmaBase = DMA15_BASE;
dmaReg = initMapMem(fdMem, dmaBase, DMA_LEN);
dmaReg = initMapMem(fdMem, DMA_BASE, DMA_LEN);
if (dmaReg == MAP_FAILED)
SOFT_ERROR(PI_INIT_FAILED, "mmap dma failed (%m)");
if (gpioCfg.DMAprimaryChannel < 15)
/* we should know if we are running on a BCM2711 by now */
if (gpioCfg.DMAprimaryChannel == PI_DEFAULT_DMA_NOT_SET)
{
dmaIn = dmaReg + (gpioCfg.DMAprimaryChannel * 0x40);
dmaOut = dmaReg + (gpioCfg.DMAsecondaryChannel * 0x40);
if (pi_is_2711)
gpioCfg.DMAprimaryChannel = PI_DEFAULT_DMA_PRIMARY_CH_2711;
else
gpioCfg.DMAprimaryChannel = PI_DEFAULT_DMA_PRIMARY_CHANNEL;
}
DBG(DBG_STARTUP, "DMA #%d @ %08X @ %08"PRIXPTR,
gpioCfg.DMAprimaryChannel, dmaBase, (uintptr_t)dmaIn);
if (gpioCfg.DMAsecondaryChannel == PI_DEFAULT_DMA_NOT_SET)
{
if (pi_is_2711)
gpioCfg.DMAsecondaryChannel = PI_DEFAULT_DMA_SECONDARY_CH_2711;
else
gpioCfg.DMAsecondaryChannel = PI_DEFAULT_DMA_SECONDARY_CHANNEL;
}
dmaIn = dmaReg + (gpioCfg.DMAprimaryChannel * 0x40);
dmaOut = dmaReg + (gpioCfg.DMAsecondaryChannel * 0x40);
DBG(DBG_STARTUP, "DMA #%d @ %08"PRIXPTR,
gpioCfg.DMAprimaryChannel, (uintptr_t)dmaIn);
DBG(DBG_STARTUP, "debug reg is %08X", dmaIn[DMA_DEBUG]);
@ -7780,7 +7800,7 @@ static void initClock(int mainClock)
}
clkSrc = CLK_CTL_SRC_PLLD;
clkDivI = 50 * micros; /* 10 MHz - 1 MHz */
clkDivI = clk_plld_freq / (10000000 / micros); /* 10 MHz - 1 MHz */
clkBits = BITS; /* 10/BITS MHz - 1/BITS MHz */
clkDivF = 0;
clkMash = 0;
@ -8732,6 +8752,10 @@ int gpioGetMode(unsigned gpio)
int gpioSetPullUpDown(unsigned gpio, unsigned pud)
{
int shift = (gpio & 0xf) << 1;
uint32_t bits;
uint32_t pull;
DBG(DBG_USER, "gpio=%d pud=%d", gpio, pud);
CHECK_INITED;
@ -8742,17 +8766,34 @@ int gpioSetPullUpDown(unsigned gpio, unsigned pud)
if (pud > 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);

View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h>
#include <pthread.h>
#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

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 65+
This version is for pigpio version 69+
*/
#include <sys/types.h>
@ -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;