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