mirror of
https://github.com/richardghirst/PiBits.git
synced 2025-02-26 19:54:16 +01:00
Add support for Pi 4B, and fix to build on latest Raspbian
This commit is contained in:
parent
4309bab2ca
commit
ff1d383a37
@ -120,10 +120,13 @@ card use. This is expected, because the pulse generation is effectively
|
|||||||
handled in hardware and not influenced by interrupt latency or scheduling
|
handled in hardware and not influenced by interrupt latency or scheduling
|
||||||
effects.
|
effects.
|
||||||
|
|
||||||
The driver uses DMA channel 14, and PWM channel 1. It makes no attempt to
|
The DMA channel used depends on the SOC type. If the Pi has a BCM2711
|
||||||
protect against other code using those peripherals. It sets the relevant GPIO
|
(Pi4B only, at present) then it uses channel 7; otherwise it uses channel 14.
|
||||||
pins to be outputs when the driver is loaded, so please ensure that you are not
|
|
||||||
driving those pins externally.
|
It uses PWM channel 1. It makes no attempt to protect against other code using
|
||||||
|
those peripherals. It sets the relevant GPIO pins to be outputs when the
|
||||||
|
driver is loaded, so please ensure that you are not driving those pins
|
||||||
|
externally.
|
||||||
|
|
||||||
I would of course recommend some buffering between the GPIO outputs and the
|
I would of course recommend some buffering between the GPIO outputs and the
|
||||||
servo controls, to protect the Pi. That said, I'm living dangerously and doing
|
servo controls, to protect the Pi. That said, I'm living dangerously and doing
|
||||||
|
@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
|
|
||||||
#include "mailbox.h"
|
#include "mailbox.h"
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
#define DMA_CHAN_MIN 0
|
#define DMA_CHAN_MIN 0
|
||||||
#define DMA_CHAN_MAX 14
|
#define DMA_CHAN_MAX 14
|
||||||
#define DMA_CHAN_DEFAULT 14
|
#define DMA_CHAN_DEFAULT 14
|
||||||
|
#define DMA_CHAN_PI4 7
|
||||||
|
|
||||||
#define DMA_BASE_OFFSET 0x00007000
|
#define DMA_BASE_OFFSET 0x00007000
|
||||||
#define DMA_LEN DMA_CHAN_SIZE * (DMA_CHAN_MAX+1)
|
#define DMA_LEN DMA_CHAN_SIZE * (DMA_CHAN_MAX+1)
|
||||||
@ -144,6 +145,9 @@
|
|||||||
#define PCMCLK_CNTL 38
|
#define PCMCLK_CNTL 38
|
||||||
#define PCMCLK_DIV 39
|
#define PCMCLK_DIV 39
|
||||||
|
|
||||||
|
#define PLLDFREQ_MHZ_DEFAULT 500
|
||||||
|
#define PLLDFREQ_MHZ_PI4 750
|
||||||
|
|
||||||
#define DELAY_VIA_PWM 0
|
#define DELAY_VIA_PWM 0
|
||||||
#define DELAY_VIA_PCM 1
|
#define DELAY_VIA_PCM 1
|
||||||
|
|
||||||
@ -290,6 +294,13 @@ static uint8_t bplus_p1pin2gpio_map[] = {
|
|||||||
21, // P1-40 GPIO 21
|
21, // P1-40 GPIO 21
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// bcm_host_get_model_type() return values to name mapping
|
||||||
|
static const char *model_names[] = {
|
||||||
|
"A", "B", "A+", "B+", "2B", "Alpha", "CM", "CM2", "3B", "Zero", "CM3",
|
||||||
|
"Custom", "ZeroW", "3B+", "3A+", "FPGA", "CM3+", "4B"
|
||||||
|
};
|
||||||
|
#define NUM_MODELS (sizeof(model_names)/sizeof(*model_names))
|
||||||
|
|
||||||
// cycle_time_us is the pulse cycle time per servo, in microseconds.
|
// cycle_time_us is the pulse cycle time per servo, in microseconds.
|
||||||
// Typically it should be 20ms, or 20000us.
|
// Typically it should be 20ms, or 20000us.
|
||||||
|
|
||||||
@ -320,6 +331,7 @@ static int delay_hw = DELAY_VIA_PWM;
|
|||||||
|
|
||||||
static struct timeval *servo_kill_time;
|
static struct timeval *servo_kill_time;
|
||||||
|
|
||||||
|
static uint32_t plldfreq_mhz;
|
||||||
static int dma_chan;
|
static int dma_chan;
|
||||||
static int idle_timeout;
|
static int idle_timeout;
|
||||||
static int invert = 0;
|
static int invert = 0;
|
||||||
@ -687,9 +699,9 @@ init_hardware(void)
|
|||||||
// Initialise PWM
|
// Initialise PWM
|
||||||
pwm_reg[PWM_CTL] = 0;
|
pwm_reg[PWM_CTL] = 0;
|
||||||
udelay(10);
|
udelay(10);
|
||||||
clk_reg[PWMCLK_CNTL] = 0x5A000006; // Source=PLLD (500MHz)
|
clk_reg[PWMCLK_CNTL] = 0x5A000006; // Source=PLLD (500MHz or 750MHz on Pi4)
|
||||||
udelay(100);
|
udelay(100);
|
||||||
clk_reg[PWMCLK_DIV] = 0x5A000000 | (500<<12); // set pwm div to 500, giving 1MHz
|
clk_reg[PWMCLK_DIV] = 0x5A000000 | (plldfreq_mhz<<12); // set pwm div to give 1MHz
|
||||||
udelay(100);
|
udelay(100);
|
||||||
clk_reg[PWMCLK_CNTL] = 0x5A000016; // Source=PLLD and enable
|
clk_reg[PWMCLK_CNTL] = 0x5A000016; // Source=PLLD and enable
|
||||||
udelay(100);
|
udelay(100);
|
||||||
@ -705,9 +717,9 @@ init_hardware(void)
|
|||||||
// Initialise PCM
|
// Initialise PCM
|
||||||
pcm_reg[PCM_CS_A] = 1; // Disable Rx+Tx, Enable PCM block
|
pcm_reg[PCM_CS_A] = 1; // Disable Rx+Tx, Enable PCM block
|
||||||
udelay(100);
|
udelay(100);
|
||||||
clk_reg[PCMCLK_CNTL] = 0x5A000006; // Source=PLLD (500MHz)
|
clk_reg[PCMCLK_CNTL] = 0x5A000006; // Source=PLLD (500MHz or 750MHz on Pi4)
|
||||||
udelay(100);
|
udelay(100);
|
||||||
clk_reg[PCMCLK_DIV] = 0x5A000000 | (500<<12); // Set pcm div to 500, giving 1MHz
|
clk_reg[PCMCLK_DIV] = 0x5A000000 | (plldfreq_mhz<<12); // Set pcm div to give 1MHz
|
||||||
udelay(100);
|
udelay(100);
|
||||||
clk_reg[PCMCLK_CNTL] = 0x5A000016; // Source=PLLD and enable
|
clk_reg[PCMCLK_CNTL] = 0x5A000016; // Source=PLLD and enable
|
||||||
udelay(100);
|
udelay(100);
|
||||||
@ -927,6 +939,8 @@ go_go_go(void)
|
|||||||
* digits of the Revision string and treat '00' and '01' as errors, '02' and
|
* digits of the Revision string and treat '00' and '01' as errors, '02' and
|
||||||
* '03' as rev 1, and any other hex value as rev 2. 'Pi1 and Pi2 are
|
* '03' as rev 1, and any other hex value as rev 2. 'Pi1 and Pi2 are
|
||||||
* differentiated by the Hardware being BCM2708 or BCM2709.
|
* differentiated by the Hardware being BCM2708 or BCM2709.
|
||||||
|
*
|
||||||
|
* NOTE: These days we should just use bcm_host_get_model_type().
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
get_model_and_revision(void)
|
get_model_and_revision(void)
|
||||||
@ -977,9 +991,18 @@ get_model_and_revision(void)
|
|||||||
else
|
else
|
||||||
gpio_cfg = 3;
|
gpio_cfg = 3;
|
||||||
|
|
||||||
|
if (bcm_host_is_model_pi4()) {
|
||||||
|
plldfreq_mhz = PLLDFREQ_MHZ_PI4;
|
||||||
|
dma_chan = DMA_CHAN_PI4;
|
||||||
|
} else {
|
||||||
|
plldfreq_mhz = PLLDFREQ_MHZ_DEFAULT;
|
||||||
|
dma_chan = DMA_CHAN_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
periph_virt_base = bcm_host_get_peripheral_address();
|
periph_virt_base = bcm_host_get_peripheral_address();
|
||||||
dram_phys_base = bcm_host_get_sdram_address();
|
dram_phys_base = bcm_host_get_sdram_address();
|
||||||
periph_phys_base = 0x7e000000;
|
periph_phys_base = 0x7e000000;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
|
* See https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
|
||||||
*
|
*
|
||||||
@ -1287,8 +1310,6 @@ main(int argc, char **argv)
|
|||||||
if (*dma_chan_arg < '0' || *dma_chan_arg > '9' ||
|
if (*dma_chan_arg < '0' || *dma_chan_arg > '9' ||
|
||||||
*p || dma_chan < DMA_CHAN_MIN || dma_chan > DMA_CHAN_MAX)
|
*p || dma_chan < DMA_CHAN_MIN || dma_chan > DMA_CHAN_MAX)
|
||||||
fatal("Invalid dma-chan specified\n");
|
fatal("Invalid dma-chan specified\n");
|
||||||
} else {
|
|
||||||
dma_chan = DMA_CHAN_DEFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idle_timeout_arg) {
|
if (idle_timeout_arg) {
|
||||||
@ -1358,7 +1379,15 @@ main(int argc, char **argv)
|
|||||||
fatal("min value is >= max value\n");
|
fatal("min value is >= max value\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nBoard model: %7d\n", board_model);
|
{
|
||||||
|
int bcm_model = bcm_host_get_model_type();
|
||||||
|
|
||||||
|
if (bcm_model < NUM_MODELS)
|
||||||
|
printf("\nBoard model: %7s\n", model_names[bcm_model]);
|
||||||
|
else
|
||||||
|
printf("\nBoard model: Unknown\n");
|
||||||
|
}
|
||||||
|
|
||||||
printf("GPIO configuration: %s\n", gpio_desc[gpio_cfg]);
|
printf("GPIO configuration: %s\n", gpio_desc[gpio_cfg]);
|
||||||
printf("Using hardware: %s\n", delay_hw == DELAY_VIA_PWM ? "PWM" : "PCM");
|
printf("Using hardware: %s\n", delay_hw == DELAY_VIA_PWM ? "PWM" : "PCM");
|
||||||
printf("Using DMA channel: %7d\n", dma_chan);
|
printf("Using DMA channel: %7d\n", dma_chan);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user