diff --git a/src/shared/drivers/interrupt/external_interrupts.cpp b/src/shared/drivers/interrupt/external_interrupts.cpp
index 56aad8e2b5d9b7bb85664635f735b7de60b2101e..e3ea873b6223c8b15298fe615ddd328783b511c2 100644
--- a/src/shared/drivers/interrupt/external_interrupts.cpp
+++ b/src/shared/drivers/interrupt/external_interrupts.cpp
@@ -1,5 +1,5 @@
/* Copyright (c) 2019 Skyward Experimental Rocketry
- * Author: Alvise de'Faveri Tron
+ * Author: Alvise de'Faveri Tron, Luca Erbetta, Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -358,29 +358,73 @@ constexpr unsigned GetEXTICR_register_value(unsigned P, unsigned N)
return (ConvertGPIO_BASEtoUnsigned(P) << ((N % 4) * 4));
}
-void enableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNumber,
+constexpr unsigned GetEXTICR_register_mask(unsigned P, unsigned N)
+{
+ return (0b1111 << ((N % 4) * 4));
+}
+
+void enableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum,
InterruptTrigger trigger, unsigned int priority)
{
- auto exitcrRegValue = GetEXTICR_register_value(gpioPort, gpioNumber);
+ auto exticrRegValue = GetEXTICR_register_value(gpioPort, gpioNum);
{
FastInterruptDisableLock dLock;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
- SYSCFG->EXTICR[int(gpioNumber / 4)] |= exitcrRegValue;
+ SYSCFG->EXTICR[int(gpioNum / 4)] |= exticrRegValue;
}
- EXTI->IMR |= 1 << gpioNumber;
+ EXTI->IMR |= 1 << gpioNum;
if (trigger == InterruptTrigger::RISING_EDGE ||
trigger == InterruptTrigger::RISING_FALLING_EDGE)
- EXTI->RTSR |= 1 << gpioNumber;
+ EXTI->RTSR |= 1 << gpioNum;
if (trigger == InterruptTrigger::FALLING_EDGE ||
trigger == InterruptTrigger::RISING_FALLING_EDGE)
- EXTI->FTSR |= 1 << gpioNumber;
+ EXTI->FTSR |= 1 << gpioNum;
+
+ NVIC_EnableIRQ(static_cast<IRQn_Type>(GetEXTI_IRQn(gpioNum)));
+ NVIC_SetPriority(static_cast<IRQn_Type>(GetEXTI_IRQn(gpioNum)), priority);
+}
+
+void disableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum)
+{
+
+ NVIC_DisableIRQ(static_cast<IRQn_Type>(GetEXTI_IRQn(gpioNum)));
+
+ EXTI->RTSR &= ~(1 << gpioNum);
+ EXTI->FTSR &= ~(1 << gpioNum);
+ EXTI->IMR &= ~(1 << gpioNum);
- NVIC_EnableIRQ(static_cast<IRQn_Type>(GetEXTI_IRQn(gpioNumber)));
- NVIC_SetPriority(static_cast<IRQn_Type>(GetEXTI_IRQn(gpioNumber)),
- priority);
+ auto exticrRegMask = GetEXTICR_register_mask(gpioPort, gpioNum);
+
+ {
+ FastInterruptDisableLock dLock;
+
+ SYSCFG->EXTICR[int(gpioNum / 4)] &= ~exticrRegMask;
+ }
}
+
+void changeInterruptTrigger(unsigned int gpioPort, unsigned int gpioNum,
+ InterruptTrigger trigger)
+{
+ switch (trigger)
+ {
+ case InterruptTrigger::RISING_EDGE:
+ EXTI->RTSR |= 1 << gpioNum;
+ EXTI->FTSR &= ~(1 << gpioNum);
+ break;
+
+ case InterruptTrigger::FALLING_EDGE:
+ EXTI->RTSR &= ~(1 << gpioNum);
+ EXTI->FTSR |= 1 << gpioNum;
+ break;
+
+ case InterruptTrigger::RISING_FALLING_EDGE:
+ EXTI->RTSR |= 1 << gpioNum;
+ EXTI->FTSR |= 1 << gpioNum;
+ break;
+ }
+}
\ No newline at end of file
diff --git a/src/shared/drivers/interrupt/external_interrupts.h b/src/shared/drivers/interrupt/external_interrupts.h
index 733d2c1b4edaf3422c12fc4f2e99e2aa833f2ac7..faf8c2f957a8dd181e6cbabed59164522e7df117 100644
--- a/src/shared/drivers/interrupt/external_interrupts.h
+++ b/src/shared/drivers/interrupt/external_interrupts.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2020 Skyward Experimental Rocketry
- * Author: Luca Erbetta
+ * Author: Luca Erbetta, Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,8 @@
#pragma once
+#include <interfaces/gpio.h>
+
enum class InterruptTrigger
{
RISING_EDGE,
@@ -41,3 +43,59 @@ enum class InterruptTrigger
void enableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum,
InterruptTrigger trigger,
unsigned int priority = 15);
+
+/**
+ * @brief Enables external interrupts on the provided pin.
+ * Remember to set the GPIO to input mode!
+ *
+ * @param gpio Pin (eg: PC4)
+ * @param trigger Interrupt detection trigger (rising edge, falling or both)
+ * @param priority Interrupt priority [0-15], 0 = Highest priority
+ */
+inline void enableExternalInterrupt(miosix::GpioPin gpio,
+ InterruptTrigger trigger,
+ unsigned int priority = 15)
+{
+ enableExternalInterrupt(gpio.getPort(), gpio.getNumber(), trigger,
+ priority);
+}
+
+/**
+ * @brief Disables external interrupts on the provided pin.
+ *
+ * @param gpioPort Port of the pin (eg: GPIOC_BASE)
+ * @param gpioNum Pin number (eg: 4 for PC4)
+ */
+void disableExternalInterrupt(unsigned int gpioPort, unsigned int gpioNum);
+
+/**
+ * @brief Disables external interrupts on the provided pin.
+ *
+ * @param gpio Pin (eg: PC4)
+ */
+inline void disableExternalInterrupt(miosix::GpioPin gpio)
+{
+ disableExternalInterrupt(gpio.getPort(), gpio.getNumber());
+}
+
+/**
+ * @brief Changes interrupt trigger on an enabled interrupt.
+ *
+ * @param gpioPort Port of the pin (eg: GPIOC_BASE)
+ * @param gpioNum Pin number (eg: 4 for PC4)
+ * @param trigger Interrupt detection trigger (rising edge, falling or both)
+ */
+void changeInterruptTrigger(unsigned int gpioPort, unsigned int gpioNum,
+ InterruptTrigger trigger);
+
+/**
+ * @brief Changes interrupt trigger on an enabled interrupt.
+ *
+ * @param gpio Pin (eg: PC4)
+ * @param trigger Interrupt detection trigger (rising edge, falling or both)
+ */
+inline void changeInterruptTrigger(miosix::GpioPin gpio,
+ InterruptTrigger trigger)
+{
+ changeInterruptTrigger(gpio.getPort(), gpio.getNumber(), trigger);
+}
\ No newline at end of file