APM:Libraries
GPIO_BBB.cpp
Go to the documentation of this file.
1 #include <AP_HAL/AP_HAL.h>
2 
3 #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || \
4  CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD || \
5  CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
6  CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE || \
7  CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET
8 
9 #include "GPIO.h"
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <poll.h>
17 #include <sys/mman.h>
18 #include <sys/stat.h>
19 
20 using namespace Linux;
21 
23 {}
24 
26 {
27 #if LINUX_GPIO_NUM_BANKS == 4
28  int mem_fd;
29  // Enable all GPIO banks
30  // Without this, access to deactivated banks (i.e. those with no clock source set up) will (logically) fail with SIGBUS
31  // Idea taken from https://groups.google.com/forum/#!msg/beagleboard/OYFp4EXawiI/Mq6s3sg14HoJ
32 
33  uint8_t bank_enable[3] = { 5, 65, 105 };
34  int export_fd = open("/sys/class/gpio/export", O_WRONLY | O_CLOEXEC);
35  if (export_fd == -1) {
36  AP_HAL::panic("unable to open /sys/class/gpio/export");
37  }
38  for (uint8_t i=0; i<3; i++) {
39  dprintf(export_fd, "%u\n", (unsigned)bank_enable[i]);
40  }
41  close(export_fd);
42 
43 
44  /* open /dev/mem */
45  if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC|O_CLOEXEC)) < 0) {
46  printf("can't open /dev/mem \n");
47  exit (-1);
48  }
49 
50  /* mmap GPIO */
52  for (uint8_t i=0; i<LINUX_GPIO_NUM_BANKS; i++) {
53  gpio_bank[i].base = (volatile unsigned *)mmap(0, GPIO_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, offsets[i]);
54  if ((char *)gpio_bank[i].base == MAP_FAILED) {
55  AP_HAL::panic("unable to map GPIO bank");
56  }
57  gpio_bank[i].oe = gpio_bank[i].base + GPIO_OE;
58  gpio_bank[i].in = gpio_bank[i].base + GPIO_IN;
60  }
61 
62  close(mem_fd);
63 #endif // LINUX_GPIO_NUM_BANKS
64 }
65 
66 void GPIO_BBB::pinMode(uint8_t pin, uint8_t output)
67 {
68  uint8_t bank = pin/32;
69  uint8_t bankpin = pin & 0x1F;
70  if (bank >= LINUX_GPIO_NUM_BANKS) {
71  return;
72  }
73  if (output == HAL_GPIO_INPUT) {
74  *gpio_bank[bank].oe |= (1U<<bankpin);
75  } else {
76  *gpio_bank[bank].oe &= ~(1U<<bankpin);
77  }
78 }
79 
81 {
82  return -1;
83 }
84 
85 
86 uint8_t GPIO_BBB::read(uint8_t pin) {
87 
88  uint8_t bank = pin/32;
89  uint8_t bankpin = pin & 0x1F;
90  if (bank >= LINUX_GPIO_NUM_BANKS) {
91  return 0;
92  }
93  return *gpio_bank[bank].in & (1U<<bankpin) ? HIGH : LOW;
94 
95 }
96 
97 void GPIO_BBB::write(uint8_t pin, uint8_t value)
98 {
99  uint8_t bank = pin/32;
100  uint8_t bankpin = pin & 0x1F;
101  if (bank >= LINUX_GPIO_NUM_BANKS) {
102  return;
103  }
104  if (value == LOW) {
105  *gpio_bank[bank].out &= ~(1U<<bankpin);
106  } else {
107  *gpio_bank[bank].out |= 1U<<bankpin;
108  }
109 }
110 
111 void GPIO_BBB::toggle(uint8_t pin)
112 {
113  write(pin, !read(pin));
114 }
115 
116 /* Alternative interface: */
118  return new DigitalSource(n);
119 }
120 
121 /* Interrupt interface: */
122 bool GPIO_BBB::attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode)
123 {
124  return true;
125 }
126 
128 {
129  return false;
130 }
131 
132 #endif // CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF ||
133  // CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD ||
134  // CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI ||
135  // CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE ||
136  // CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET
int8_t analogPinToDigitalPin(uint8_t pin)
Definition: GPIO_BBB.cpp:80
void pinMode(uint8_t pin, uint8_t output)
Definition: GPIO_BBB.cpp:66
int printf(const char *fmt,...)
Definition: stdio.c:113
volatile uint32_t * base
Definition: GPIO_BBB.h:115
int open(const char *pathname, int flags)
POSIX Open a file with integer mode flags.
Definition: posix.c:885
void toggle(uint8_t pin)
Definition: GPIO_BBB.cpp:111
#define LINUX_GPIO_NUM_BANKS
Definition: GPIO_BBB.h:31
uint8_t read(uint8_t pin)
Definition: GPIO_BBB.cpp:86
volatile uint32_t * oe
Definition: GPIO_BBB.h:116
#define GPIO1_BASE
Definition: GPIO_BBB.h:8
void(* Proc)(void)
#define GPIO_SIZE
Definition: GPIO_BBB.h:12
#define HIGH
Definition: board.h:34
#define GPIO_IN
Definition: GPIO_BBB.h:16
bool attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode)
Definition: GPIO_BBB.cpp:122
bool usb_connected(void)
Definition: GPIO_BBB.cpp:127
AP_HAL::DigitalSource * channel(uint16_t n)
Definition: GPIO_BBB.cpp:117
int close(int fileno)
POSIX Close a file with fileno handel.
Definition: posix.c:675
#define LOW
Definition: board.h:31
#define GPIO3_BASE
Definition: GPIO_BBB.h:10
#define GPIO0_BASE
Definition: GPIO_BBB.h:7
#define HAL_GPIO_INPUT
Definition: GPIO.h:7
void write(uint8_t pin, uint8_t value)
Definition: GPIO_BBB.cpp:97
#define GPIO_OUT
Definition: GPIO_BBB.h:17
float value
volatile uint32_t * in
Definition: GPIO_BBB.h:117
void panic(const char *errormsg,...) FMT_PRINTF(1
Definition: system.cpp:140
#define GPIO2_BASE
Definition: GPIO_BBB.h:9
static int8_t pin
Definition: AnalogIn.cpp:15
#define GPIO_OE
Definition: GPIO_BBB.h:15
struct Linux::GPIO_BBB::GPIO gpio_bank[LINUX_GPIO_NUM_BANKS]
volatile uint32_t * out
Definition: GPIO_BBB.h:118