HAL_Linux: add GPIO driver for Raspberry Pi
This commit is contained in:
parent
07ed93cea0
commit
2f0900b0a8
@ -15,7 +15,8 @@ namespace Linux {
|
|||||||
class LinuxAnalogSource;
|
class LinuxAnalogSource;
|
||||||
class LinuxAnalogIn;
|
class LinuxAnalogIn;
|
||||||
class LinuxStorage;
|
class LinuxStorage;
|
||||||
class LinuxGPIO;
|
class LinuxGPIO_BBB;
|
||||||
|
class LinuxGPIO_RPI;
|
||||||
class LinuxDigitalSource;
|
class LinuxDigitalSource;
|
||||||
class LinuxRCInput;
|
class LinuxRCInput;
|
||||||
class LinuxRCInput_PRU;
|
class LinuxRCInput_PRU;
|
||||||
|
@ -1,130 +1,11 @@
|
|||||||
#include <AP_HAL.h>
|
#include <AP_HAL.h>
|
||||||
|
#include "GPIO.h"
|
||||||
|
|
||||||
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
||||||
|
|
||||||
#include "GPIO.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
using namespace Linux;
|
using namespace Linux;
|
||||||
|
|
||||||
static const AP_HAL::HAL& hal = AP_HAL_BOARD_DRIVER;
|
static const AP_HAL::HAL& hal = AP_HAL_BOARD_DRIVER;
|
||||||
LinuxGPIO::LinuxGPIO()
|
|
||||||
{}
|
|
||||||
|
|
||||||
void LinuxGPIO::init()
|
|
||||||
{
|
|
||||||
#if LINUX_GPIO_NUM_BANKS == 4
|
|
||||||
int mem_fd;
|
|
||||||
// Enable all GPIO banks
|
|
||||||
// Without this, access to deactivated banks (i.e. those with no clock source set up) will (logically) fail with SIGBUS
|
|
||||||
// Idea taken from https://groups.google.com/forum/#!msg/beagleboard/OYFp4EXawiI/Mq6s3sg14HoJ
|
|
||||||
|
|
||||||
uint8_t bank_enable[3] = { 5, 65, 105 };
|
|
||||||
int export_fd = open("/sys/class/gpio/export", O_WRONLY);
|
|
||||||
if (export_fd == -1) {
|
|
||||||
hal.scheduler->panic("unable to open /sys/class/gpio/export");
|
|
||||||
}
|
|
||||||
for (uint8_t i=0; i<3; i++) {
|
|
||||||
dprintf(export_fd, "%u\n", (unsigned)bank_enable[i]);
|
|
||||||
}
|
|
||||||
close(export_fd);
|
|
||||||
|
|
||||||
|
|
||||||
/* open /dev/mem */
|
|
||||||
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
|
|
||||||
printf("can't open /dev/mem \n");
|
|
||||||
exit (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mmap GPIO */
|
|
||||||
off_t offsets[LINUX_GPIO_NUM_BANKS] = { GPIO0_BASE, GPIO1_BASE, GPIO2_BASE, GPIO3_BASE };
|
|
||||||
for (uint8_t i=0; i<LINUX_GPIO_NUM_BANKS; i++) {
|
|
||||||
gpio_bank[i].base = (volatile unsigned *)mmap(0, GPIO_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, offsets[i]);
|
|
||||||
if ((char *)gpio_bank[i].base == MAP_FAILED) {
|
|
||||||
hal.scheduler->panic("unable to map GPIO bank");
|
|
||||||
}
|
|
||||||
gpio_bank[i].oe = gpio_bank[i].base + GPIO_OE;
|
|
||||||
gpio_bank[i].in = gpio_bank[i].base + GPIO_IN;
|
|
||||||
gpio_bank[i].out = gpio_bank[i].base + GPIO_OUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(mem_fd);
|
|
||||||
#endif // LINUX_GPIO_NUM_BANKS
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinuxGPIO::pinMode(uint8_t pin, uint8_t output)
|
|
||||||
{
|
|
||||||
uint8_t bank = pin/32;
|
|
||||||
uint8_t bankpin = pin & 0x1F;
|
|
||||||
if (bank >= LINUX_GPIO_NUM_BANKS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (output == HAL_GPIO_INPUT) {
|
|
||||||
*gpio_bank[bank].oe |= (1U<<bankpin);
|
|
||||||
} else {
|
|
||||||
*gpio_bank[bank].oe &= ~(1U<<bankpin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t LinuxGPIO::analogPinToDigitalPin(uint8_t pin)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t LinuxGPIO::read(uint8_t pin) {
|
|
||||||
|
|
||||||
uint8_t bank = pin/32;
|
|
||||||
uint8_t bankpin = pin & 0x1F;
|
|
||||||
if (bank >= LINUX_GPIO_NUM_BANKS) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return *gpio_bank[bank].in & (1U<<bankpin) ? HIGH : LOW;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinuxGPIO::write(uint8_t pin, uint8_t value)
|
|
||||||
{
|
|
||||||
uint8_t bank = pin/32;
|
|
||||||
uint8_t bankpin = pin & 0x1F;
|
|
||||||
if (bank >= LINUX_GPIO_NUM_BANKS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (value == LOW) {
|
|
||||||
*gpio_bank[bank].out &= ~(1U<<bankpin);
|
|
||||||
} else {
|
|
||||||
*gpio_bank[bank].out |= 1U<<bankpin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinuxGPIO::toggle(uint8_t pin)
|
|
||||||
{
|
|
||||||
write(pin, !read(pin));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Alternative interface: */
|
|
||||||
AP_HAL::DigitalSource* LinuxGPIO::channel(uint16_t n) {
|
|
||||||
return new LinuxDigitalSource(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interrupt interface: */
|
|
||||||
bool LinuxGPIO::attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LinuxGPIO::usb_connected(void)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LinuxDigitalSource::LinuxDigitalSource(uint8_t v) :
|
LinuxDigitalSource::LinuxDigitalSource(uint8_t v) :
|
||||||
_v(v)
|
_v(v)
|
||||||
@ -152,4 +33,4 @@ void LinuxDigitalSource::toggle()
|
|||||||
write(!read());
|
write(!read());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CONFIG_HAL_BOARD
|
#endif
|
@ -1,139 +1,15 @@
|
|||||||
|
|
||||||
#ifndef __AP_HAL_LINUX_GPIO_H__
|
#ifndef __AP_HAL_LINUX_GPIO_H__
|
||||||
#define __AP_HAL_LINUX_GPIO_H__
|
#define __AP_HAL_LINUX_GPIO_H__
|
||||||
|
|
||||||
#include <AP_HAL_Linux.h>
|
#include <AP_HAL_Linux.h>
|
||||||
|
|
||||||
#define SYSFS_GPIO_DIR "/sys/class/gpio"
|
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
||||||
|
|
||||||
#define GPIO0_BASE 0x44E07000
|
|
||||||
#define GPIO1_BASE 0x4804C000
|
|
||||||
#define GPIO2_BASE 0x481AC000
|
|
||||||
#define GPIO3_BASE 0x481AE000
|
|
||||||
|
|
||||||
#define GPIO_SIZE 0x00000FFF
|
|
||||||
|
|
||||||
// OE: 0 is output, 1 is input
|
|
||||||
#define GPIO_OE 0x14d
|
|
||||||
#define GPIO_IN 0x14e
|
|
||||||
#define GPIO_OUT 0x14f
|
|
||||||
|
|
||||||
#define LED_AMBER 117
|
|
||||||
#define LED_BLUE 48
|
|
||||||
#define LED_SAFETY 61
|
|
||||||
#define SAFETY_SWITCH 116
|
|
||||||
#define LOW 0
|
|
||||||
#define HIGH 1
|
|
||||||
|
|
||||||
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLE
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLE
|
||||||
#define LINUX_GPIO_NUM_BANKS 4
|
#include "GPIO_BBB.h"
|
||||||
#else
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO
|
||||||
// disable GPIO
|
#include "GPIO_RPI.h"
|
||||||
#define LINUX_GPIO_NUM_BANKS 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BeagleBone Black GPIO mappings
|
|
||||||
#define BBB_USR0 53
|
|
||||||
#define BBB_USR1 54
|
|
||||||
#define BBB_USR2 55
|
|
||||||
#define BBB_USR3 56
|
|
||||||
#define BBB_P8_3 38
|
|
||||||
#define BBB_P8_4 39
|
|
||||||
#define BBB_P8_5 34
|
|
||||||
#define BBB_P8_6 35
|
|
||||||
#define BBB_P8_7 66
|
|
||||||
#define BBB_P8_8 67
|
|
||||||
#define BBB_P8_9 69
|
|
||||||
#define BBB_P8_10 68
|
|
||||||
#define BBB_P8_11 45
|
|
||||||
#define BBB_P8_12 44
|
|
||||||
#define BBB_P8_13 23
|
|
||||||
#define BBB_P8_14 26
|
|
||||||
#define BBB_P8_15 47
|
|
||||||
#define BBB_P8_16 46
|
|
||||||
#define BBB_P8_17 27
|
|
||||||
#define BBB_P8_18 65
|
|
||||||
#define BBB_P8_19 22
|
|
||||||
#define BBB_P8_20 63
|
|
||||||
#define BBB_P8_21 62
|
|
||||||
#define BBB_P8_22 37
|
|
||||||
#define BBB_P8_23 36
|
|
||||||
#define BBB_P8_24 33
|
|
||||||
#define BBB_P8_25 32
|
|
||||||
#define BBB_P8_26 61
|
|
||||||
#define BBB_P8_27 86
|
|
||||||
#define BBB_P8_28 88
|
|
||||||
#define BBB_P8_29 87
|
|
||||||
#define BBB_P8_30 89
|
|
||||||
#define BBB_P8_31 10
|
|
||||||
#define BBB_P8_32 11
|
|
||||||
#define BBB_P8_33 9
|
|
||||||
#define BBB_P8_34 81
|
|
||||||
#define BBB_P8_35 8
|
|
||||||
#define BBB_P8_36 80
|
|
||||||
#define BBB_P8_37 78
|
|
||||||
#define BBB_P8_38 79
|
|
||||||
#define BBB_P8_39 76
|
|
||||||
#define BBB_P8_40 77
|
|
||||||
#define BBB_P8_41 74
|
|
||||||
#define BBB_P8_42 75
|
|
||||||
#define BBB_P8_43 72
|
|
||||||
#define BBB_P8_44 73
|
|
||||||
#define BBB_P8_45 70
|
|
||||||
#define BBB_P8_46 71
|
|
||||||
#define BBB_P9_11 30
|
|
||||||
#define BBB_P9_12 60
|
|
||||||
#define BBB_P9_13 31
|
|
||||||
#define BBB_P9_14 50
|
|
||||||
#define BBB_P9_15 48
|
|
||||||
#define BBB_P9_16 51
|
|
||||||
#define BBB_P9_17 5
|
|
||||||
#define BBB_P9_18 4
|
|
||||||
#define BBB_P9_19 13
|
|
||||||
#define BBB_P9_20 12
|
|
||||||
#define BBB_P9_21 3
|
|
||||||
#define BBB_P9_22 2
|
|
||||||
#define BBB_P9_23 49
|
|
||||||
#define BBB_P9_24 15
|
|
||||||
#define BBB_P9_25 117
|
|
||||||
#define BBB_P9_26 14
|
|
||||||
#define BBB_P9_27 115
|
|
||||||
#define BBB_P9_28 113
|
|
||||||
#define BBB_P9_29 111
|
|
||||||
#define BBB_P9_30 112
|
|
||||||
#define BBB_P9_31 110
|
|
||||||
#define BBB_P9_41 20
|
|
||||||
#define BBB_P9_42 7
|
|
||||||
|
|
||||||
class Linux::LinuxGPIO : public AP_HAL::GPIO {
|
|
||||||
private:
|
|
||||||
struct GPIO {
|
|
||||||
volatile uint32_t *base;
|
|
||||||
volatile uint32_t *oe;
|
|
||||||
volatile uint32_t *in;
|
|
||||||
volatile uint32_t *out;
|
|
||||||
} gpio_bank[LINUX_GPIO_NUM_BANKS];
|
|
||||||
|
|
||||||
public:
|
|
||||||
LinuxGPIO();
|
|
||||||
void init();
|
|
||||||
void pinMode(uint8_t pin, uint8_t output);
|
|
||||||
int8_t analogPinToDigitalPin(uint8_t pin);
|
|
||||||
uint8_t read(uint8_t pin);
|
|
||||||
void write(uint8_t pin, uint8_t value);
|
|
||||||
void toggle(uint8_t pin);
|
|
||||||
|
|
||||||
/* Alternative interface: */
|
|
||||||
AP_HAL::DigitalSource* channel(uint16_t n);
|
|
||||||
|
|
||||||
/* Interrupt interface: */
|
|
||||||
bool attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p,
|
|
||||||
uint8_t mode);
|
|
||||||
|
|
||||||
/* return true if USB cable is connected */
|
|
||||||
bool usb_connected(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Linux::LinuxDigitalSource : public AP_HAL::DigitalSource {
|
class Linux::LinuxDigitalSource : public AP_HAL::DigitalSource {
|
||||||
public:
|
public:
|
||||||
LinuxDigitalSource(uint8_t v);
|
LinuxDigitalSource(uint8_t v);
|
||||||
@ -146,4 +22,5 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
||||||
#endif // __AP_HAL_LINUX_GPIO_H__
|
#endif // __AP_HAL_LINUX_GPIO_H__
|
||||||
|
131
libraries/AP_HAL_Linux/GPIO_BBB.cpp
Normal file
131
libraries/AP_HAL_Linux/GPIO_BBB.cpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#include <AP_HAL.h>
|
||||||
|
|
||||||
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || \
|
||||||
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLE
|
||||||
|
|
||||||
|
#include "GPIO.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
using namespace Linux;
|
||||||
|
|
||||||
|
static const AP_HAL::HAL& hal = AP_HAL_BOARD_DRIVER;
|
||||||
|
LinuxGPIO_BBB::LinuxGPIO_BBB()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void LinuxGPIO_BBB::init()
|
||||||
|
{
|
||||||
|
#if LINUX_GPIO_NUM_BANKS == 4
|
||||||
|
int mem_fd;
|
||||||
|
// Enable all GPIO banks
|
||||||
|
// Without this, access to deactivated banks (i.e. those with no clock source set up) will (logically) fail with SIGBUS
|
||||||
|
// Idea taken from https://groups.google.com/forum/#!msg/beagleboard/OYFp4EXawiI/Mq6s3sg14HoJ
|
||||||
|
|
||||||
|
uint8_t bank_enable[3] = { 5, 65, 105 };
|
||||||
|
int export_fd = open("/sys/class/gpio/export", O_WRONLY);
|
||||||
|
if (export_fd == -1) {
|
||||||
|
hal.scheduler->panic("unable to open /sys/class/gpio/export");
|
||||||
|
}
|
||||||
|
for (uint8_t i=0; i<3; i++) {
|
||||||
|
dprintf(export_fd, "%u\n", (unsigned)bank_enable[i]);
|
||||||
|
}
|
||||||
|
close(export_fd);
|
||||||
|
|
||||||
|
|
||||||
|
/* open /dev/mem */
|
||||||
|
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
|
||||||
|
printf("can't open /dev/mem \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mmap GPIO */
|
||||||
|
off_t offsets[LINUX_GPIO_NUM_BANKS] = { GPIO0_BASE, GPIO1_BASE, GPIO2_BASE, GPIO3_BASE };
|
||||||
|
for (uint8_t i=0; i<LINUX_GPIO_NUM_BANKS; i++) {
|
||||||
|
gpio_bank[i].base = (volatile unsigned *)mmap(0, GPIO_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, offsets[i]);
|
||||||
|
if ((char *)gpio_bank[i].base == MAP_FAILED) {
|
||||||
|
hal.scheduler->panic("unable to map GPIO bank");
|
||||||
|
}
|
||||||
|
gpio_bank[i].oe = gpio_bank[i].base + GPIO_OE;
|
||||||
|
gpio_bank[i].in = gpio_bank[i].base + GPIO_IN;
|
||||||
|
gpio_bank[i].out = gpio_bank[i].base + GPIO_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(mem_fd);
|
||||||
|
#endif // LINUX_GPIO_NUM_BANKS
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxGPIO_BBB::pinMode(uint8_t pin, uint8_t output)
|
||||||
|
{
|
||||||
|
uint8_t bank = pin/32;
|
||||||
|
uint8_t bankpin = pin & 0x1F;
|
||||||
|
if (bank >= LINUX_GPIO_NUM_BANKS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (output == HAL_GPIO_INPUT) {
|
||||||
|
*gpio_bank[bank].oe |= (1U<<bankpin);
|
||||||
|
} else {
|
||||||
|
*gpio_bank[bank].oe &= ~(1U<<bankpin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t LinuxGPIO_BBB::analogPinToDigitalPin(uint8_t pin)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t LinuxGPIO_BBB::read(uint8_t pin) {
|
||||||
|
|
||||||
|
uint8_t bank = pin/32;
|
||||||
|
uint8_t bankpin = pin & 0x1F;
|
||||||
|
if (bank >= LINUX_GPIO_NUM_BANKS) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return *gpio_bank[bank].in & (1U<<bankpin) ? HIGH : LOW;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxGPIO_BBB::write(uint8_t pin, uint8_t value)
|
||||||
|
{
|
||||||
|
uint8_t bank = pin/32;
|
||||||
|
uint8_t bankpin = pin & 0x1F;
|
||||||
|
if (bank >= LINUX_GPIO_NUM_BANKS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value == LOW) {
|
||||||
|
*gpio_bank[bank].out &= ~(1U<<bankpin);
|
||||||
|
} else {
|
||||||
|
*gpio_bank[bank].out |= 1U<<bankpin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxGPIO_BBB::toggle(uint8_t pin)
|
||||||
|
{
|
||||||
|
write(pin, !read(pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alternative interface: */
|
||||||
|
AP_HAL::DigitalSource* LinuxGPIO_BBB::channel(uint16_t n) {
|
||||||
|
return new LinuxDigitalSource(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interrupt interface: */
|
||||||
|
bool LinuxGPIO_BBB::attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxGPIO_BBB::usb_connected(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF ||
|
||||||
|
// CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLE
|
137
libraries/AP_HAL_Linux/GPIO_BBB.h
Normal file
137
libraries/AP_HAL_Linux/GPIO_BBB.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
|
||||||
|
#ifndef __AP_HAL_LINUX_GPIO_BBB_H__
|
||||||
|
#define __AP_HAL_LINUX_GPIO_BBB_H__
|
||||||
|
|
||||||
|
#include <AP_HAL_Linux.h>
|
||||||
|
|
||||||
|
#define SYSFS_GPIO_DIR "/sys/class/gpio"
|
||||||
|
|
||||||
|
#define GPIO0_BASE 0x44E07000
|
||||||
|
#define GPIO1_BASE 0x4804C000
|
||||||
|
#define GPIO2_BASE 0x481AC000
|
||||||
|
#define GPIO3_BASE 0x481AE000
|
||||||
|
|
||||||
|
#define GPIO_SIZE 0x00000FFF
|
||||||
|
|
||||||
|
// OE: 0 is output, 1 is input
|
||||||
|
#define GPIO_OE 0x14d
|
||||||
|
#define GPIO_IN 0x14e
|
||||||
|
#define GPIO_OUT 0x14f
|
||||||
|
|
||||||
|
#define LED_AMBER 117
|
||||||
|
#define LED_BLUE 48
|
||||||
|
#define LED_SAFETY 61
|
||||||
|
#define SAFETY_SWITCH 116
|
||||||
|
#define LOW 0
|
||||||
|
#define HIGH 1
|
||||||
|
|
||||||
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLE
|
||||||
|
#define LINUX_GPIO_NUM_BANKS 4
|
||||||
|
#else
|
||||||
|
// disable GPIO
|
||||||
|
#define LINUX_GPIO_NUM_BANKS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BeagleBone Black GPIO mappings
|
||||||
|
#define BBB_USR0 53
|
||||||
|
#define BBB_USR1 54
|
||||||
|
#define BBB_USR2 55
|
||||||
|
#define BBB_USR3 56
|
||||||
|
#define BBB_P8_3 38
|
||||||
|
#define BBB_P8_4 39
|
||||||
|
#define BBB_P8_5 34
|
||||||
|
#define BBB_P8_6 35
|
||||||
|
#define BBB_P8_7 66
|
||||||
|
#define BBB_P8_8 67
|
||||||
|
#define BBB_P8_9 69
|
||||||
|
#define BBB_P8_10 68
|
||||||
|
#define BBB_P8_11 45
|
||||||
|
#define BBB_P8_12 44
|
||||||
|
#define BBB_P8_13 23
|
||||||
|
#define BBB_P8_14 26
|
||||||
|
#define BBB_P8_15 47
|
||||||
|
#define BBB_P8_16 46
|
||||||
|
#define BBB_P8_17 27
|
||||||
|
#define BBB_P8_18 65
|
||||||
|
#define BBB_P8_19 22
|
||||||
|
#define BBB_P8_20 63
|
||||||
|
#define BBB_P8_21 62
|
||||||
|
#define BBB_P8_22 37
|
||||||
|
#define BBB_P8_23 36
|
||||||
|
#define BBB_P8_24 33
|
||||||
|
#define BBB_P8_25 32
|
||||||
|
#define BBB_P8_26 61
|
||||||
|
#define BBB_P8_27 86
|
||||||
|
#define BBB_P8_28 88
|
||||||
|
#define BBB_P8_29 87
|
||||||
|
#define BBB_P8_30 89
|
||||||
|
#define BBB_P8_31 10
|
||||||
|
#define BBB_P8_32 11
|
||||||
|
#define BBB_P8_33 9
|
||||||
|
#define BBB_P8_34 81
|
||||||
|
#define BBB_P8_35 8
|
||||||
|
#define BBB_P8_36 80
|
||||||
|
#define BBB_P8_37 78
|
||||||
|
#define BBB_P8_38 79
|
||||||
|
#define BBB_P8_39 76
|
||||||
|
#define BBB_P8_40 77
|
||||||
|
#define BBB_P8_41 74
|
||||||
|
#define BBB_P8_42 75
|
||||||
|
#define BBB_P8_43 72
|
||||||
|
#define BBB_P8_44 73
|
||||||
|
#define BBB_P8_45 70
|
||||||
|
#define BBB_P8_46 71
|
||||||
|
#define BBB_P9_11 30
|
||||||
|
#define BBB_P9_12 60
|
||||||
|
#define BBB_P9_13 31
|
||||||
|
#define BBB_P9_14 50
|
||||||
|
#define BBB_P9_15 48
|
||||||
|
#define BBB_P9_16 51
|
||||||
|
#define BBB_P9_17 5
|
||||||
|
#define BBB_P9_18 4
|
||||||
|
#define BBB_P9_19 13
|
||||||
|
#define BBB_P9_20 12
|
||||||
|
#define BBB_P9_21 3
|
||||||
|
#define BBB_P9_22 2
|
||||||
|
#define BBB_P9_23 49
|
||||||
|
#define BBB_P9_24 15
|
||||||
|
#define BBB_P9_25 117
|
||||||
|
#define BBB_P9_26 14
|
||||||
|
#define BBB_P9_27 115
|
||||||
|
#define BBB_P9_28 113
|
||||||
|
#define BBB_P9_29 111
|
||||||
|
#define BBB_P9_30 112
|
||||||
|
#define BBB_P9_31 110
|
||||||
|
#define BBB_P9_41 20
|
||||||
|
#define BBB_P9_42 7
|
||||||
|
|
||||||
|
class Linux::LinuxGPIO_BBB : public AP_HAL::GPIO {
|
||||||
|
private:
|
||||||
|
struct GPIO {
|
||||||
|
volatile uint32_t *base;
|
||||||
|
volatile uint32_t *oe;
|
||||||
|
volatile uint32_t *in;
|
||||||
|
volatile uint32_t *out;
|
||||||
|
} gpio_bank[LINUX_GPIO_NUM_BANKS];
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinuxGPIO_BBB();
|
||||||
|
void init();
|
||||||
|
void pinMode(uint8_t pin, uint8_t output);
|
||||||
|
int8_t analogPinToDigitalPin(uint8_t pin);
|
||||||
|
uint8_t read(uint8_t pin);
|
||||||
|
void write(uint8_t pin, uint8_t value);
|
||||||
|
void toggle(uint8_t pin);
|
||||||
|
|
||||||
|
/* Alternative interface: */
|
||||||
|
AP_HAL::DigitalSource* channel(uint16_t n);
|
||||||
|
|
||||||
|
/* Interrupt interface: */
|
||||||
|
bool attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p,
|
||||||
|
uint8_t mode);
|
||||||
|
|
||||||
|
/* return true if USB cable is connected */
|
||||||
|
bool usb_connected(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __AP_HAL_LINUX_GPIO_BBB_H__
|
100
libraries/AP_HAL_Linux/GPIO_RPI.cpp
Normal file
100
libraries/AP_HAL_Linux/GPIO_RPI.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include <AP_HAL.h>
|
||||||
|
|
||||||
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO
|
||||||
|
|
||||||
|
#include "GPIO.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
using namespace Linux;
|
||||||
|
|
||||||
|
static const AP_HAL::HAL& hal = AP_HAL_BOARD_DRIVER;
|
||||||
|
LinuxGPIO_RPI::LinuxGPIO_RPI()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void LinuxGPIO_RPI::init()
|
||||||
|
{
|
||||||
|
// open /dev/mem
|
||||||
|
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
|
||||||
|
printf("can't open /dev/mem \n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mmap GPIO
|
||||||
|
gpio_map = mmap(
|
||||||
|
NULL, // Any adddress in our space will do
|
||||||
|
BLOCK_SIZE, // Map length
|
||||||
|
PROT_READ|PROT_WRITE, // Enable reading & writting to mapped memory
|
||||||
|
MAP_SHARED, // Shared with other processes
|
||||||
|
mem_fd, // File to map
|
||||||
|
GPIO_BASE // Offset to GPIO peripheral
|
||||||
|
);
|
||||||
|
|
||||||
|
close(mem_fd); // No need to keep mem_fd open after mmap
|
||||||
|
|
||||||
|
if (gpio_map == MAP_FAILED) {
|
||||||
|
printf("mmap error %d\n", (int)gpio_map); // errno also set!
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio = (volatile unsigned *)gpio_map; // Always use volatile pointer!
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxGPIO_RPI::pinMode(uint8_t pin, uint8_t output)
|
||||||
|
{
|
||||||
|
if (output == HAL_GPIO_INPUT) {
|
||||||
|
GPIO_MODE_IN(pin);
|
||||||
|
} else {
|
||||||
|
GPIO_MODE_IN(pin);
|
||||||
|
GPIO_MODE_OUT(pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t LinuxGPIO_RPI::analogPinToDigitalPin(uint8_t pin)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LinuxGPIO_RPI::read(uint8_t pin)
|
||||||
|
{
|
||||||
|
return GPIO_GET(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxGPIO_RPI::write(uint8_t pin, uint8_t value)
|
||||||
|
{
|
||||||
|
if (value == LOW) {
|
||||||
|
GPIO_SET_LOW = 1 << pin;
|
||||||
|
} else {
|
||||||
|
GPIO_SET_HIGH = 1 << pin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxGPIO_RPI::toggle(uint8_t pin)
|
||||||
|
{
|
||||||
|
write(pin, !read(pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alternative interface: */
|
||||||
|
AP_HAL::DigitalSource* LinuxGPIO_RPI::channel(uint16_t n) {
|
||||||
|
return new LinuxDigitalSource(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interrupt interface: */
|
||||||
|
bool LinuxGPIO_RPI::attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxGPIO_RPI::usb_connected(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO
|
73
libraries/AP_HAL_Linux/GPIO_RPI.h
Normal file
73
libraries/AP_HAL_Linux/GPIO_RPI.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
#ifndef __AP_HAL_LINUX_GPIO_RPI_H__
|
||||||
|
#define __AP_HAL_LINUX_GPIO_RPI_H__
|
||||||
|
|
||||||
|
#include <AP_HAL_Linux.h>
|
||||||
|
|
||||||
|
#define LOW 0
|
||||||
|
#define HIGH 1
|
||||||
|
|
||||||
|
// Raspberry Pi GPIO memory
|
||||||
|
#define BCM2708_PERI_BASE 0x20000000
|
||||||
|
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
|
||||||
|
#define PAGE_SIZE (4*1024)
|
||||||
|
#define BLOCK_SIZE (4*1024)
|
||||||
|
|
||||||
|
// GPIO setup. Always use INP_GPIO(x) before OUT_GPIO(x) or SET_GPIO_ALT(x,y)
|
||||||
|
#define GPIO_MODE_IN(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
|
||||||
|
#define GPIO_MODE_OUT(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
|
||||||
|
#define GPIO_MODE_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
|
||||||
|
#define GPIO_SET_HIGH *(gpio+7) // sets bits which are 1
|
||||||
|
#define GPIO_SET_LOW *(gpio+10) // clears bits which are 1
|
||||||
|
#define GPIO_GET(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
|
||||||
|
|
||||||
|
// Raspberry Pi GPIO mapping
|
||||||
|
#define RPI_GPIO_2 2 // Pin 3 SDA
|
||||||
|
#define RPI_GPIO_3 3 // Pin 5 SCL
|
||||||
|
#define RPI_GPIO_4 4 // Pin 7 NAVIO_PPM_INPUT
|
||||||
|
#define RPI_GPIO_7 7 // Pin 26 CE1 NAVIO_MPU9250_CS
|
||||||
|
#define RPI_GPIO_8 8 // Pin 24 CE0 NAVIO_UBLOX_CS
|
||||||
|
#define RPI_GPIO_9 9 // Pin 21 MISO
|
||||||
|
#define RPI_GPIO_10 10 // Pin 19 MOSI
|
||||||
|
#define RPI_GPIO_11 11 // Pin 23 SCLK
|
||||||
|
#define RPI_GPIO_14 14 // Pin 8 TxD
|
||||||
|
#define RPI_GPIO_15 15 // Pin 10 RxD
|
||||||
|
#define RPI_GPIO_17 17 // Pin 11 NAVIO_UART_PORT_5
|
||||||
|
#define RPI_GPIO_18 18 // Pin 12 NAVIO_UART_PORT_4
|
||||||
|
#define RPI_GPIO_22 22 // Pin 15 NAVIO_UBLOX_PPS
|
||||||
|
#define RPI_GPIO_23 23 // Pin 16 NAVIO_MPU9250_DRDY
|
||||||
|
#define RPI_GPIO_24 24 // Pin 18 NAVIO_SPI_PORT_6
|
||||||
|
#define RPI_GPIO_25 25 // Pin 22 NAVIO_SPI_PORT_5
|
||||||
|
#define RPI_GPIO_27 27 // Pin 13 NAVIO_PCA9685_OE
|
||||||
|
#define RPI_GPIO_28 28 // Pin 3
|
||||||
|
#define RPI_GPIO_29 29 // Pin 4
|
||||||
|
#define RPI_GPIO_30 30 // Pin 5
|
||||||
|
#define RPI_GPIO_31 31 // Pin 6
|
||||||
|
|
||||||
|
class Linux::LinuxGPIO_RPI : public AP_HAL::GPIO {
|
||||||
|
private:
|
||||||
|
int mem_fd;
|
||||||
|
void *gpio_map;
|
||||||
|
volatile unsigned *gpio;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinuxGPIO_RPI();
|
||||||
|
void init();
|
||||||
|
void pinMode(uint8_t pin, uint8_t output);
|
||||||
|
int8_t analogPinToDigitalPin(uint8_t pin);
|
||||||
|
uint8_t read(uint8_t pin);
|
||||||
|
void write(uint8_t pin, uint8_t value);
|
||||||
|
void toggle(uint8_t pin);
|
||||||
|
|
||||||
|
/* Alternative interface: */
|
||||||
|
AP_HAL::DigitalSource* channel(uint16_t n);
|
||||||
|
|
||||||
|
/* Interrupt interface: */
|
||||||
|
bool attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p,
|
||||||
|
uint8_t mode);
|
||||||
|
|
||||||
|
/* return true if USB cable is connected */
|
||||||
|
bool usb_connected(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __AP_HAL_LINUX_GPIO_RPI_H__
|
@ -24,7 +24,20 @@ static LinuxI2CDriver i2cDriver(&i2cSemaphore, "/dev/i2c-1");
|
|||||||
static LinuxSPIDeviceManager spiDeviceManager;
|
static LinuxSPIDeviceManager spiDeviceManager;
|
||||||
static LinuxAnalogIn analogIn;
|
static LinuxAnalogIn analogIn;
|
||||||
static LinuxStorage storageDriver;
|
static LinuxStorage storageDriver;
|
||||||
static LinuxGPIO gpioDriver;
|
|
||||||
|
/*
|
||||||
|
use the BBB gpio driver on ERLE and PXF
|
||||||
|
*/
|
||||||
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLE
|
||||||
|
static LinuxGPIO_BBB gpioDriver;
|
||||||
|
/*
|
||||||
|
use the RPI gpio driver on Navio
|
||||||
|
*/
|
||||||
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO
|
||||||
|
static LinuxGPIO_RPI gpioDriver;
|
||||||
|
#else
|
||||||
|
static Empty::EmptyGPIO gpioDriver;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
use the PRU based RCInput driver on ERLE and PXF
|
use the PRU based RCInput driver on ERLE and PXF
|
||||||
|
Loading…
Reference in New Issue
Block a user