APM:Libraries
GPIO.cpp
Go to the documentation of this file.
1 #include <AP_HAL/AP_HAL.h>
2 
3 #if CONFIG_HAL_BOARD == HAL_BOARD_PX4
4 
5 #include "GPIO.h"
6 
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 
12 /* PX4 headers */
13 #include <drivers/drv_led.h>
14 #include <drivers/drv_tone_alarm.h>
15 #include <drivers/drv_gpio.h>
16 #include <modules/px4iofirmware/protocol.h>
17 #include <arch/board/board.h>
18 #include <board_config.h>
19 
20 #define LOW 0
21 #define HIGH 1
22 
23 extern const AP_HAL::HAL& hal;
24 
25 using namespace PX4;
26 
28 {}
29 
31 {
32 #if defined(CONFIG_ARCH_BOARD_PX4FMU_V1) || defined(CONFIG_ARCH_BOARD_PX4FMU_V4)
33  _led_fd = open(LED0_DEVICE_PATH, O_RDWR);
34  if (_led_fd == -1) {
35  AP_HAL::panic("Unable to open " LED0_DEVICE_PATH);
36  }
37  if (ioctl(_led_fd, LED_OFF, LED_BLUE) != 0) {
38  hal.console->printf("GPIO: Unable to setup GPIO LED BLUE\n");
39  }
40  if (ioctl(_led_fd, LED_OFF, LED_RED) != 0) {
41  hal.console->printf("GPIO: Unable to setup GPIO LED RED\n");
42  }
43 #ifdef CONFIG_ARCH_BOARD_PX4FMU_V4
44  if (ioctl(_led_fd, LED_OFF, LED_GREEN) != 0) {
45  hal.console->printf("GPIO: Unable to setup GPIO LED GREEN\n");
46  }
47 #endif
48 #endif
49 #if !defined(CONFIG_ARCH_BOARD_AEROFC_V1)
50  _tone_alarm_fd = open(TONEALARM0_DEVICE_PATH, O_WRONLY);
51  if (_tone_alarm_fd == -1) {
52  AP_HAL::panic("Unable to open " TONEALARM0_DEVICE_PATH);
53  }
54 
55  _gpio_fmu_fd = open(PX4FMU_DEVICE_PATH, 0);
56  if (_gpio_fmu_fd == -1) {
57  AP_HAL::panic("Unable to open GPIO");
58  }
59 #endif
60 #ifdef CONFIG_ARCH_BOARD_PX4FMU_V1
61  if (ioctl(_gpio_fmu_fd, GPIO_CLEAR, GPIO_EXT_1) != 0) {
62  hal.console->printf("GPIO: Unable to setup GPIO_1\n");
63  }
64 #endif
65 
66 #ifdef PX4IO_DEVICE_PATH
67  // also try to setup for the relay pins on the IO board
68  _gpio_io_fd = open(PX4IO_DEVICE_PATH, O_RDWR);
69  if (_gpio_io_fd == -1) {
70  hal.console->printf("GPIO: Unable to open px4io\n");
71  }
72 #endif
73 }
74 
75 void PX4GPIO::pinMode(uint8_t pin, uint8_t output)
76 {
77  switch (pin) {
79  uint32_t pinmask = 1U<<(pin-PX4_GPIO_FMU_SERVO_PIN(0));
80  if (output) {
81  uint8_t old_value = read(pin);
82  if (old_value) {
83  ioctl(_gpio_fmu_fd, GPIO_SET_OUTPUT_HIGH, pinmask);
84  } else {
85  ioctl(_gpio_fmu_fd, GPIO_SET_OUTPUT_LOW, pinmask);
86  }
87  } else {
88  ioctl(_gpio_fmu_fd, GPIO_SET_INPUT, pinmask);
89  }
90  break;
91  }
92 }
93 
95 {
96  switch (pin) {
98  // the only pins that can be mapped are the FMU servo rail pins */
99  return pin;
100  }
101  return -1;
102 }
103 
104 
105 uint8_t PX4GPIO::read(uint8_t pin) {
106  switch (pin) {
107 
108 #ifdef GPIO_EXT_1
110  uint32_t relays = 0;
111  ioctl(_gpio_fmu_fd, GPIO_GET, (unsigned long)&relays);
112  return (relays & GPIO_EXT_1)?HIGH:LOW;
113  }
114 #endif
115 
116 #ifdef GPIO_EXT_2
118  uint32_t relays = 0;
119  ioctl(_gpio_fmu_fd, GPIO_GET, (unsigned long)&relays);
120  return (relays & GPIO_EXT_2)?HIGH:LOW;
121  }
122 #endif
123 
124 #ifdef PX4IO_P_SETUP_RELAYS_POWER1
126  uint32_t relays = 0;
127  if (_gpio_io_fd == -1) {
128  return LOW;
129  }
130  ioctl(_gpio_io_fd, GPIO_GET, (unsigned long)&relays);
131  return (relays & PX4IO_P_SETUP_RELAYS_POWER1)?HIGH:LOW;
132  }
133 #endif
134 
135 #ifdef PX4IO_P_SETUP_RELAYS_POWER2
137  uint32_t relays = 0;
138  if (_gpio_io_fd == -1) {
139  return LOW;
140  }
141  ioctl(_gpio_io_fd, GPIO_GET, (unsigned long)&relays);
142  return (relays & PX4IO_P_SETUP_RELAYS_POWER2)?HIGH:LOW;
143  }
144 #endif
145 
146 #ifdef PX4IO_P_SETUP_RELAYS_ACC1
148  uint32_t relays = 0;
149  if (_gpio_io_fd == -1) {
150  return LOW;
151  }
152  ioctl(_gpio_io_fd, GPIO_GET, (unsigned long)&relays);
153  return (relays & PX4IO_P_SETUP_RELAYS_ACC1)?HIGH:LOW;
154  }
155 #endif
156 
157 #ifdef PX4IO_P_SETUP_RELAYS_ACC2
159  uint32_t relays = 0;
160  if (_gpio_io_fd == -1) {
161  return LOW;
162  }
163  ioctl(_gpio_io_fd, GPIO_GET, (unsigned long)&relays);
164  return (relays & PX4IO_P_SETUP_RELAYS_ACC2)?HIGH:LOW;
165  }
166 #endif
167 
169  uint32_t relays = 0;
170  ioctl(_gpio_fmu_fd, GPIO_GET, (unsigned long)&relays);
171  return (relays & (1U<<(pin-PX4_GPIO_FMU_SERVO_PIN(0))))?HIGH:LOW;
172  }
173  }
174  return LOW;
175 }
176 
177 void PX4GPIO::write(uint8_t pin, uint8_t value)
178 {
179  switch (pin) {
180 
181 #if defined(CONFIG_ARCH_BOARD_PX4FMU_V1) || defined(CONFIG_ARCH_BOARD_PX4FMU_V4)
182  case HAL_GPIO_A_LED_PIN: // Arming LED
183  if (value == LOW) {
184  ioctl(_led_fd, LED_OFF, LED_RED);
185  } else {
186  ioctl(_led_fd, LED_ON, LED_RED);
187  }
188  break;
189 
190  case HAL_GPIO_B_LED_PIN: // Green LED
191  if (value == LOW) {
192  ioctl(_led_fd, LED_OFF, LED_GREEN);
193  } else {
194  ioctl(_led_fd, LED_ON, LED_GREEN);
195  }
196  break;
197 
198  case HAL_GPIO_C_LED_PIN: // GPS LED
199  if (value == LOW) {
200  ioctl(_led_fd, LED_OFF, LED_BLUE);
201  } else {
202  ioctl(_led_fd, LED_ON, LED_BLUE);
203  }
204  break;
205 #endif
206 
207  case PX4_GPIO_PIEZO_PIN: // Piezo beeper
208  if (value == LOW) { // this is inverted
209  ioctl(_tone_alarm_fd, TONE_SET_ALARM, 3); // Alarm on !!
210  //::write(_tone_alarm_fd, &user_tune, sizeof(user_tune));
211  } else {
212  ioctl(_tone_alarm_fd, TONE_SET_ALARM, 0); // Alarm off !!
213  }
214  break;
215 
216 #ifdef GPIO_EXT_1
218  ioctl(_gpio_fmu_fd, value==LOW?GPIO_CLEAR:GPIO_SET, GPIO_EXT_1);
219  break;
220 #endif
221 
222 #ifdef GPIO_EXT_2
224  ioctl(_gpio_fmu_fd, value==LOW?GPIO_CLEAR:GPIO_SET, GPIO_EXT_2);
225  break;
226 #endif
227 
228 #ifdef PX4IO_P_SETUP_RELAYS_POWER1
230  if (_gpio_io_fd != -1) {
231  ioctl(_gpio_io_fd, value==LOW?GPIO_CLEAR:GPIO_SET, PX4IO_P_SETUP_RELAYS_POWER1);
232  }
233  break;
234 #endif
235 
236 #ifdef PX4IO_P_SETUP_RELAYS_POWER2
238  if (_gpio_io_fd != -1) {
239  ioctl(_gpio_io_fd, value==LOW?GPIO_CLEAR:GPIO_SET, PX4IO_P_SETUP_RELAYS_POWER2);
240  }
241  break;
242 #endif
243 
244 #ifdef PX4IO_P_SETUP_RELAYS_ACC1
246  if (_gpio_io_fd != -1) {
247  ioctl(_gpio_io_fd, value==LOW?GPIO_CLEAR:GPIO_SET, PX4IO_P_SETUP_RELAYS_ACC1);
248  }
249  break;
250 #endif
251 
252 #ifdef PX4IO_P_SETUP_RELAYS_ACC2
254  if (_gpio_io_fd != -1) {
255  ioctl(_gpio_io_fd, value==LOW?GPIO_CLEAR:GPIO_SET, PX4IO_P_SETUP_RELAYS_ACC2);
256  }
257  break;
258 #endif
259 
261  ioctl(_gpio_fmu_fd, value==LOW?GPIO_CLEAR:GPIO_SET, 1U<<(pin-PX4_GPIO_FMU_SERVO_PIN(0)));
262  break;
263  }
264 }
265 
266 void PX4GPIO::toggle(uint8_t pin)
267 {
268  write(pin, !read(pin));
269 }
270 
271 /* Alternative interface: */
273  return new PX4DigitalSource(0);
274 }
275 
276 /* Interrupt interface: */
277 bool PX4GPIO::attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode)
278 {
279  return true;
280 }
281 
282 /*
283  return true when USB connected
284  */
286 {
287  /*
288  we use a combination of voltage on the USB connector and the
289  open of the /dev/ttyACM0 character device. This copes with
290  systems where the VBUS may go high even with no USB connected
291  (such as AUAV-X2)
292  */
293  return stm32_gpioread(GPIO_OTGFS_VBUS) && _usb_connected;
294 }
295 
296 
298  _v(v)
299 {}
300 
301 void PX4DigitalSource::mode(uint8_t output)
302 {}
303 
305  return _v;
306 }
307 
309  _v = value;
310 }
311 
313  _v = !_v;
314 }
315 
316 #endif // CONFIG_HAL_BOARD
#define PX4_GPIO_FMU_SERVO_PIN(n)
Definition: GPIO.h:17
const AP_HAL::HAL & hal
Definition: AC_PID_test.cpp:14
AP_HAL::DigitalSource * channel(uint16_t n) override
Definition: GPIO.cpp:272
bool _usb_connected
Definition: GPIO.h:62
#define LED_OFF
Definition: Config.h:44
#define PX4_GPIO_EXT_FMU_RELAY1_PIN
Definition: GPIO.h:6
void init() override
Definition: GPIO.cpp:30
#define PX4_GPIO_EXT_IO_ACC2_PIN
Definition: GPIO.h:11
int open(const char *pathname, int flags)
POSIX Open a file with integer mode flags.
Definition: posix.c:885
AP_HAL::UARTDriver * console
Definition: HAL.h:110
int8_t analogPinToDigitalPin(uint8_t pin) override
Definition: GPIO.cpp:94
#define HIGH
Definition: GPIO.cpp:21
#define LED_BLUE
Definition: GPIO_BBB.h:20
#define HAL_GPIO_A_LED_PIN
Definition: chibios.h:9
uint8_t read(uint8_t pin) override
Definition: GPIO.cpp:105
#define HAL_GPIO_C_LED_PIN
Definition: chibios.h:15
void pinMode(uint8_t pin, uint8_t output) override
Definition: GPIO.cpp:75
void(* Proc)(void)
#define PX4_GPIO_EXT_IO_RELAY2_PIN
Definition: GPIO.h:9
void toggle(uint8_t pin) override
Definition: GPIO.cpp:266
int _led_fd
Definition: GPIO.h:58
virtual void printf(const char *,...) FMT_PRINTF(2
Definition: BetterStream.cpp:5
#define GPIO_GET(g)
Definition: GPIO_RPI.cpp:32
int _gpio_fmu_fd
Definition: GPIO.h:60
#define PX4_GPIO_EXT_FMU_RELAY2_PIN
Definition: GPIO.h:7
bool attach_interrupt(uint8_t interrupt_num, AP_HAL::Proc p, uint8_t mode) override
Definition: GPIO.cpp:277
#define PX4_GPIO_PIEZO_PIN
Definition: GPIO.h:5
void write(uint8_t pin, uint8_t value) override
Definition: GPIO.cpp:177
float v
Definition: Printf.cpp:15
int _gpio_io_fd
Definition: GPIO.h:61
int _tone_alarm_fd
Definition: GPIO.h:59
void mode(uint8_t output)
Definition: GPIO.cpp:301
float value
bool usb_connected(void) override
Definition: GPIO.cpp:285
#define HAL_GPIO_B_LED_PIN
Definition: chibios.h:12
#define LED_ON
Definition: Config.h:43
void panic(const char *errormsg,...) FMT_PRINTF(1
Definition: system.cpp:140
static int8_t pin
Definition: AnalogIn.cpp:15
void write(uint8_t value)
Definition: GPIO.cpp:308
#define PX4_GPIO_EXT_IO_RELAY1_PIN
Definition: GPIO.h:8
uint8_t read()
Definition: GPIO.cpp:304
#define PX4_GPIO_EXT_IO_ACC1_PIN
Definition: GPIO.h:10
PX4DigitalSource(uint8_t v)
Definition: GPIO.cpp:297
#define LOW
Definition: GPIO.cpp:20