mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-13 03:20:00 +03:00
101 lines
2.7 KiB
C
101 lines
2.7 KiB
C
/*
|
|
* This file is part of Betaflight.
|
|
*
|
|
* Betaflight is free software. You can redistribute this software
|
|
* and/or modify this software under the terms of the GNU General
|
|
* Public License as published by the Free Software Foundation,
|
|
* either version 3 of the License, or (at your option) any later
|
|
* version.
|
|
*
|
|
* Betaflight is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this software.
|
|
*
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include "drivers/exti.h"
|
|
#include "common/utils.h"
|
|
#include "drivers/io_impl.h"
|
|
|
|
#include "hardware/gpio.h"
|
|
|
|
typedef struct {
|
|
extiCallbackRec_t* handler;
|
|
} extiChannelRec_t;
|
|
|
|
static extiChannelRec_t extiChannelRecs[DEFIO_USED_COUNT];
|
|
static uint32_t extiEventMask[DEFIO_USED_COUNT];
|
|
|
|
void EXTIConfig(IO_t io, extiCallbackRec_t *cb, int irqPriority, ioConfig_t config, extiTrigger_t trigger)
|
|
{
|
|
uint32_t gpio = IO_Pin(io);
|
|
|
|
UNUSED(irqPriority); // Just stick with default GPIO irq priority for now
|
|
UNUSED(config); // TODO consider pullup/pulldown etc. Needs fixing first in platform.h
|
|
|
|
// Ensure the GPIO is initialised and not being used for some other function
|
|
gpio_init(gpio);
|
|
|
|
extiChannelRec_t *rec = &extiChannelRecs[gpio];
|
|
rec->handler = cb;
|
|
|
|
switch(trigger) {
|
|
case BETAFLIGHT_EXTI_TRIGGER_RISING:
|
|
default:
|
|
extiEventMask[gpio] = GPIO_IRQ_EDGE_RISE;
|
|
break;
|
|
|
|
case BETAFLIGHT_EXTI_TRIGGER_FALLING:
|
|
extiEventMask[gpio] = GPIO_IRQ_EDGE_FALL;
|
|
break;
|
|
|
|
case BETAFLIGHT_EXTI_TRIGGER_BOTH:
|
|
extiEventMask[gpio] = GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void EXTI_IRQHandler(uint gpio, uint32_t event_mask)
|
|
{
|
|
// Call the registered handler for this GPIO
|
|
if (extiChannelRecs[gpio].handler) {
|
|
extiChannelRecs[gpio].handler->fn(extiChannelRecs[gpio].handler);
|
|
}
|
|
|
|
// Acknowledge the interrupt
|
|
gpio_acknowledge_irq(gpio, event_mask);
|
|
}
|
|
|
|
void EXTIInit(void)
|
|
{
|
|
// Clear all the callbacks
|
|
memset(extiChannelRecs, 0, sizeof(extiChannelRecs));
|
|
|
|
// Register the shared handler for GPIO interrupts
|
|
gpio_set_irq_callback(EXTI_IRQHandler);
|
|
|
|
// Enable the interrupt
|
|
irq_set_enabled(IO_IRQ_BANK0, true);
|
|
}
|
|
|
|
void EXTIHandlerInit(extiCallbackRec_t *self, extiHandlerCallback *fn)
|
|
{
|
|
self->fn = fn;
|
|
}
|
|
|
|
void EXTIEnable(IO_t io)
|
|
{
|
|
gpio_set_irq_enabled(IO_Pin(io), extiEventMask[IO_Pin(io)], true);
|
|
}
|
|
|
|
void EXTIDisable(IO_t io)
|
|
{
|
|
gpio_set_irq_enabled(IO_Pin(io), 0, false);
|
|
}
|