mirror of https://github.com/ArduPilot/ardupilot
170 lines
6.9 KiB
C
170 lines
6.9 KiB
C
|
#pragma once
|
||
|
|
||
|
#include <cstdint>
|
||
|
#include "GPIO_RPI_HAL.h"
|
||
|
|
||
|
namespace Linux {
|
||
|
|
||
|
/**
|
||
|
* @brief Class for Raspberry PI 5 GPIO control
|
||
|
*
|
||
|
* For more information:
|
||
|
* - RP1 datasheet: https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf
|
||
|
* - gpiomem0: https://github.com/raspberrypi/linux/blob/1e53604087930e7cf42eee3d42572d0d6f54c86a/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi#L178
|
||
|
* - Address: 0x400d'0000, Size: 0x3'0000
|
||
|
*
|
||
|
*/
|
||
|
class GPIO_RPI_RP1 : public GPIO_RPI_HAL {
|
||
|
public:
|
||
|
GPIO_RPI_RP1();
|
||
|
void init() override;
|
||
|
void pinMode(uint8_t pin, uint8_t mode) override;
|
||
|
void pinMode(uint8_t pin, uint8_t mode, uint8_t alt) override;
|
||
|
|
||
|
uint8_t read(uint8_t pin) override;
|
||
|
void write(uint8_t pin, uint8_t value) override;
|
||
|
void toggle(uint8_t pin) override;
|
||
|
|
||
|
enum class PadsPull : uint8_t {
|
||
|
Off = 0,
|
||
|
Down = 1,
|
||
|
Up = 2,
|
||
|
};
|
||
|
|
||
|
void set_pull(uint8_t pin, PadsPull mode);
|
||
|
|
||
|
private:
|
||
|
// gpiomem0 already maps the 0x400d'0000 address for us
|
||
|
static constexpr const char* PATH_DEV_GPIOMEM = "/dev/gpiomem0";
|
||
|
static constexpr uint32_t MEM_SIZE = 0x30000;
|
||
|
static constexpr uint32_t REG_SIZE = sizeof(uint32_t);
|
||
|
|
||
|
// Register offsets from RP1 datasheet 'Table 2. Peripheral Address Map'
|
||
|
// E.g:
|
||
|
// - IO_BANK0_OFFSET: 0x0'0000 result in 0x400d'0000
|
||
|
// - SYS_RIO0_OFFSET: 0x1'0000 result in 0x400e'0000
|
||
|
// ...
|
||
|
static constexpr uint32_t IO_BANK0_OFFSET = 0x00000;
|
||
|
static constexpr uint32_t SYS_RIO0_OFFSET = 0x10000;
|
||
|
static constexpr uint32_t PADS_BANK0_OFFSET = 0x20000;
|
||
|
|
||
|
// GPIO control from https://github.com/raspberrypi/linux/blob/21012295fe87a7ccc1c356d1e268fd289aafbad1/drivers/pinctrl/pinctrl-rp1.c
|
||
|
static constexpr uint32_t RIO_OUT = 0x00;
|
||
|
static constexpr uint32_t RIO_OE = 0x04;
|
||
|
static constexpr uint32_t RIO_IN = 0x08;
|
||
|
|
||
|
// GPIO control from '2.4. Atomic register access'
|
||
|
static constexpr uint32_t RW_OFFSET = 0x0000;
|
||
|
static constexpr uint32_t XOR_OFFSET = 0x1000;
|
||
|
static constexpr uint32_t SET_OFFSET = 0x2000;
|
||
|
static constexpr uint32_t CLR_OFFSET = 0x3000;
|
||
|
|
||
|
static constexpr uint32_t GPIO_CTRL = 0x0004;
|
||
|
static constexpr uint32_t GPIO_OFFSET = 8;
|
||
|
|
||
|
static constexpr uint32_t PADS_GPIO = 0x04;
|
||
|
static constexpr uint32_t PADS_OFFSET = 4;
|
||
|
|
||
|
/**
|
||
|
* GPIO control from 'Table 8. GPI0_CTRL, GPI1_CTRL, ...'
|
||
|
*
|
||
|
* 0b0000'0000'0000'0000'0000'0000'0001'1101
|
||
|
* ├┘│├─┘├┘├─┘├┘├─┘├┘├─┘├┘│ ├──────┘└────┴─ Bits 4:0 FUNCSEL: Function select
|
||
|
* │ ││ │ │ │ │ │ │ │ │ └────────────── Bits 11:5 F_M: Filter/debounce time constant M
|
||
|
* │ ││ │ │ │ │ │ │ │ └──────────────── Bits 13:12 OUTOVER: Output control
|
||
|
* │ ││ │ │ │ │ │ │ └────────────────── Bits 15:14 OEOVER: Output enable control
|
||
|
* │ ││ │ │ │ │ │ └───────────────────── Bits 17:16 INOVER: Input control
|
||
|
* │ ││ │ │ │ │ └─────────────────────── Bits 19:18 Reserved
|
||
|
* │ ││ │ │ │ └────────────────────────── Bits 20:21 IRQMASK_EDGE_LOW/HIGH
|
||
|
* │ ││ │ │ └──────────────────────────── Bits 22:23 IRQMASK_LEVEL_LOW/HIGH
|
||
|
* │ ││ │ └─────────────────────────────── Bits 24:25 IRQMASK_F_EDGE_LOW/HIGH
|
||
|
* │ ││ └───────────────────────────────── Bits 26:27 IRQMASK_DB_LEVEL_LOW/HIGH
|
||
|
* │ │└──────────────────────────────────── Bit 28 IRQRESET: Interrupt edge detector reset
|
||
|
* │ └───────────────────────────────────── Bit 29 Reserved
|
||
|
* └─────────────────────────────────────── Bits 31:30 IRQOVER: Interrupt control
|
||
|
*/
|
||
|
static constexpr uint32_t CTRL_FUNCSEL_MASK = 0x001f;
|
||
|
static constexpr uint32_t CTRL_FUNCSEL_LSB = 0;
|
||
|
static constexpr uint32_t CTRL_OUTOVER_MASK = 0x3000;
|
||
|
static constexpr uint32_t CTRL_OUTOVER_LSB = 12;
|
||
|
static constexpr uint32_t CTRL_OEOVER_MASK = 0xc000;
|
||
|
static constexpr uint32_t CTRL_OEOVER_LSB = 14;
|
||
|
static constexpr uint32_t CTRL_INOVER_MASK = 0x30000;
|
||
|
static constexpr uint32_t CTRL_INOVER_LSB = 16;
|
||
|
static constexpr uint32_t CTRL_IRQOVER_MASK = 0xc0000000;
|
||
|
static constexpr uint32_t CTRL_IRQOVER_LSB = 30;
|
||
|
|
||
|
/**
|
||
|
* Mask for PADS_BANK control from 'Table 21.'
|
||
|
*
|
||
|
* 0b0...001'1101
|
||
|
* ├──┘││├─┘││└─ Bit 1 SLEWFAST: Slew rate control. 1 = Fast, 0 = Slow
|
||
|
* │ │││ │└── Bit 2 SCHMITT: Enable schmitt trigger
|
||
|
* │ │││ └─── Bit 3 PDE: Pull down enable
|
||
|
* │ ││└────── Bits 4:5 DRIVE: Drive strength
|
||
|
* │ │└─────── Bit 6 IE: Input enable
|
||
|
* │ └──────── Bit 7 OD: Output disable. Has priority over output enable from
|
||
|
* └──────────── Bits 31:8 Reserved
|
||
|
*/
|
||
|
static constexpr uint32_t PADS_IN_ENABLE_MASK = 0x40;
|
||
|
static constexpr uint32_t PADS_OUT_DISABLE_MASK = 0x80;
|
||
|
static constexpr uint32_t PADS_PULL_MASK = 0x0c;
|
||
|
static constexpr uint32_t PADS_PULL_LSB = 2;
|
||
|
|
||
|
enum class FunctionSelect : uint8_t {
|
||
|
Alt0 = 0,
|
||
|
Alt1 = 1,
|
||
|
Alt2 = 2,
|
||
|
Alt3 = 3,
|
||
|
Alt4 = 4,
|
||
|
Alt5 = 5,
|
||
|
Alt6 = 6,
|
||
|
Alt7 = 7,
|
||
|
Alt8 = 8,
|
||
|
Null = 31
|
||
|
};
|
||
|
|
||
|
enum Mode {
|
||
|
Input,
|
||
|
Output,
|
||
|
Alt0,
|
||
|
Alt1,
|
||
|
Alt2,
|
||
|
Alt3,
|
||
|
Alt4,
|
||
|
Alt5,
|
||
|
Alt6,
|
||
|
Alt7,
|
||
|
Alt8,
|
||
|
Null
|
||
|
};
|
||
|
|
||
|
enum Bias {
|
||
|
Off,
|
||
|
PullDown,
|
||
|
PullUp
|
||
|
};
|
||
|
|
||
|
volatile uint32_t* _gpio;
|
||
|
int _system_memory_device;
|
||
|
uint32_t _gpio_output_port_status = 0;
|
||
|
|
||
|
bool openMemoryDevice();
|
||
|
void closeMemoryDevice();
|
||
|
volatile uint32_t* get_memory_pointer(uint32_t address, uint32_t range) const;
|
||
|
|
||
|
uint32_t read_register(uint32_t offset) const;
|
||
|
void write_register(uint32_t offset, uint32_t value);
|
||
|
|
||
|
Mode direction(uint8_t pin) const;
|
||
|
void set_direction(uint8_t pin, Mode mode);
|
||
|
void input_enable(uint8_t pin);
|
||
|
void input_disable(uint8_t pin);
|
||
|
void output_enable(uint8_t pin);
|
||
|
void output_disable(uint8_t pin);
|
||
|
|
||
|
void set_mode(uint8_t pin, Mode mode);
|
||
|
};
|
||
|
|
||
|
}
|