Browse Source

HAL_ChibiOS: added wait_pin() implementation

c415-sdk
Andrew Tridgell 5 years ago
parent
commit
450871cde1
  1. 71
      libraries/AP_HAL_ChibiOS/GPIO.cpp
  2. 7
      libraries/AP_HAL_ChibiOS/GPIO.h

71
libraries/AP_HAL_ChibiOS/GPIO.cpp

@ -30,6 +30,7 @@ static struct gpio_entry { @@ -30,6 +30,7 @@ static struct gpio_entry {
AP_HAL::GPIO::irq_handler_fn_t fn; // callback for GPIO interface
bool is_input;
uint8_t mode;
thread_reference_t thd_wait;
} _gpio_tab[] = HAL_GPIO_PINS;
#define NUM_PINS ARRAY_SIZE(_gpio_tab)
@ -219,7 +220,7 @@ bool GPIO::attach_interrupt(uint8_t pin, @@ -219,7 +220,7 @@ bool GPIO::attach_interrupt(uint8_t pin,
return _attach_interrupt(g->pal_line, proc, mode);
}
bool GPIO::_attach_interrupt(ioline_t line, palcallback_t cb, void *p, uint8_t mode)
bool GPIO::_attach_interruptI(ioline_t line, palcallback_t cb, void *p, uint8_t mode)
{
uint32_t chmode = 0;
switch(mode) {
@ -239,11 +240,9 @@ bool GPIO::_attach_interrupt(ioline_t line, palcallback_t cb, void *p, uint8_t m @@ -239,11 +240,9 @@ bool GPIO::_attach_interrupt(ioline_t line, palcallback_t cb, void *p, uint8_t m
break;
}
osalSysLock();
palevent_t *pep = pal_lld_get_line_event(line);
if (pep->cb && p != nullptr) {
// the pad is already being used for a callback
osalSysUnlock();
return false;
}
@ -254,11 +253,18 @@ bool GPIO::_attach_interrupt(ioline_t line, palcallback_t cb, void *p, uint8_t m @@ -254,11 +253,18 @@ bool GPIO::_attach_interrupt(ioline_t line, palcallback_t cb, void *p, uint8_t m
palDisableLineEventI(line);
palSetLineCallbackI(line, cb, p);
palEnableLineEventI(line, chmode);
osalSysUnlock();
return true;
}
bool GPIO::_attach_interrupt(ioline_t line, palcallback_t cb, void *p, uint8_t mode)
{
osalSysLock();
bool ret = _attach_interruptI(line, cb, p, mode);
osalSysUnlock();
return ret;
}
bool GPIO::usb_connected(void)
{
return _usb_connected;
@ -288,14 +294,14 @@ void DigitalSource::toggle() @@ -288,14 +294,14 @@ void DigitalSource::toggle()
palToggleLine(line);
}
void pal_interrupt_cb(void *arg)
static void pal_interrupt_cb(void *arg)
{
if (arg != nullptr) {
((AP_HAL::Proc)arg)();
}
}
void pal_interrupt_cb_functor(void *arg)
static void pal_interrupt_cb_functor(void *arg)
{
const uint32_t now = AP_HAL::micros();
@ -309,3 +315,56 @@ void pal_interrupt_cb_functor(void *arg) @@ -309,3 +315,56 @@ void pal_interrupt_cb_functor(void *arg)
}
(g->fn)(g->pin_num, palReadLine(g->pal_line), now);
}
/*
handle interrupt from pin change for wait_pin()
*/
static void pal_interrupt_wait(void *arg)
{
osalSysLockFromISR();
struct gpio_entry *g = (gpio_entry *)arg;
if (g == nullptr || g->thd_wait == nullptr) {
osalSysUnlockFromISR();
return;
}
osalThreadResumeI(&g->thd_wait, MSG_OK);
osalSysUnlockFromISR();
}
/*
block waiting for a pin to change. A timeout of 0 means wait
forever. Return true on pin change, false on timeout
*/
bool GPIO::wait_pin(uint8_t pin, INTERRUPT_TRIGGER_TYPE mode, uint32_t timeout_us)
{
struct gpio_entry *g = gpio_by_pin_num(pin);
if (!g) {
return false;
}
osalSysLock();
if (g->thd_wait) {
// only allow single waiter
osalSysUnlock();
return false;
}
g->thd_wait = chThdGetSelfX();
if (!_attach_interruptI(g->pal_line,
palcallback_t(pal_interrupt_wait),
g,
mode)) {
g->thd_wait = nullptr;
osalSysUnlock();
return false;
}
msg_t msg = osalThreadSuspendTimeoutS(&g->thd_wait, TIME_US2I(timeout_us));
g->thd_wait = nullptr;
_attach_interruptI(g->pal_line,
palcallback_t(nullptr),
g,
mode);
osalSysUnlock();
return msg != MSG_TIMEOUT;
}

7
libraries/AP_HAL_ChibiOS/GPIO.h

@ -56,10 +56,17 @@ public: @@ -56,10 +56,17 @@ public:
/* attach interrupt via ioline_t */
bool _attach_interrupt(ioline_t line, AP_HAL::Proc p, uint8_t mode);
/*
block waiting for a pin to change. A timeout of 0 means wait
forever. Return true on pin change, false on timeout
*/
bool wait_pin(uint8_t pin, INTERRUPT_TRIGGER_TYPE mode, uint32_t timeout_us) override;
private:
bool _usb_connected;
bool _ext_started;
bool _attach_interruptI(ioline_t line, palcallback_t cb, void *p, uint8_t mode);
bool _attach_interrupt(ioline_t line, palcallback_t cb, void *p, uint8_t mode);
#ifdef HAL_PIN_ALT_CONFIG
void setup_alt_config(void);

Loading…
Cancel
Save