2018-12-18 20:50:29 -08:00
|
|
|
/*
|
|
|
|
* digital_input_exti.cpp
|
|
|
|
*
|
|
|
|
* Created on: Dec 18, 2018
|
2021-01-31 19:10:10 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2021
|
2018-12-18 20:50:29 -08:00
|
|
|
*/
|
|
|
|
|
2021-07-25 22:05:17 -07:00
|
|
|
#include "pch.h"
|
2018-12-18 20:50:29 -08:00
|
|
|
|
2019-04-12 17:52:51 -07:00
|
|
|
#if HAL_USE_PAL && EFI_PROD_CODE
|
2019-01-03 21:16:08 -08:00
|
|
|
#include "digital_input_exti.h"
|
2018-12-18 20:50:29 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* EXTI is a funny thing: you can only use same pin on one port. For example, you can use
|
|
|
|
* PA0 PB5 PE2 PD7
|
|
|
|
* but you cannot use
|
|
|
|
* PA0 PB0 PE2 PD7
|
|
|
|
* because pin '0' would be used on two different ports
|
|
|
|
*/
|
|
|
|
|
2019-04-21 06:28:49 -07:00
|
|
|
static ioportmask_t ext_used = 0;
|
|
|
|
|
2018-12-18 20:50:29 -08:00
|
|
|
// EXT is not able to give you the front direction but you could read the pin in the callback.
|
2020-05-16 16:28:49 -07:00
|
|
|
void efiExtiEnablePin(const char *msg, brain_pin_e brainPin, uint32_t mode, palcallback_t cb, void *cb_data) {
|
2019-04-21 06:28:49 -07:00
|
|
|
|
2019-04-21 07:00:14 -07:00
|
|
|
/* paranoid check, in case of GPIO_UNASSIGNED getHwPort will return NULL
|
2019-04-21 06:28:49 -07:00
|
|
|
* and we will fail on next check */
|
2021-01-31 19:02:01 -08:00
|
|
|
if (!isBrainPinValid(brainPin)) {
|
2020-05-16 16:28:49 -07:00
|
|
|
return;
|
2021-01-31 19:02:01 -08:00
|
|
|
}
|
2019-04-21 06:28:49 -07:00
|
|
|
|
2019-04-21 07:00:14 -07:00
|
|
|
ioportid_t port = getHwPort(msg, brainPin);
|
2021-01-31 19:02:01 -08:00
|
|
|
if (port == NULL) {
|
2020-05-16 16:28:49 -07:00
|
|
|
return;
|
2021-01-31 19:02:01 -08:00
|
|
|
}
|
2019-04-21 06:28:49 -07:00
|
|
|
|
2020-12-22 17:54:28 -08:00
|
|
|
bool wasUsed = brain_pin_markUsed(brainPin, msg);
|
2020-12-22 17:42:30 -08:00
|
|
|
if (wasUsed) {
|
|
|
|
// error condition we shall bail
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-21 07:00:14 -07:00
|
|
|
int index = getHwPin(msg, brainPin);
|
2018-12-18 20:50:29 -08:00
|
|
|
|
2019-04-21 06:28:49 -07:00
|
|
|
/* is this index already used? */
|
|
|
|
if (ext_used & PAL_PORT_BIT(index)) {
|
|
|
|
firmwareError(CUSTOM_ERR_PIN_ALREADY_USED_2, "%s: pin %d: exti index already used", msg, brainPin);
|
2020-05-16 16:28:49 -07:00
|
|
|
return;
|
2019-04-21 06:28:49 -07:00
|
|
|
}
|
2018-12-18 20:50:29 -08:00
|
|
|
|
2019-04-21 07:00:14 -07:00
|
|
|
ioline_t line = PAL_LINE(port, index);
|
2019-02-05 15:36:25 -08:00
|
|
|
palEnableLineEvent(line, mode);
|
2019-04-21 06:28:49 -07:00
|
|
|
palSetLineCallback(line, cb, cb_data);
|
|
|
|
|
|
|
|
/* mark used */
|
|
|
|
ext_used |= PAL_PORT_BIT(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void efiExtiDisablePin(brain_pin_e brainPin)
|
|
|
|
{
|
2019-04-21 07:00:14 -07:00
|
|
|
/* paranoid check, in case of GPIO_UNASSIGNED getHwPort will return NULL
|
2019-04-21 06:28:49 -07:00
|
|
|
* and we will fail on next check */
|
2021-01-08 17:01:26 -08:00
|
|
|
if (!isBrainPinValid(brainPin))
|
2019-04-21 06:28:49 -07:00
|
|
|
return;
|
|
|
|
|
2019-04-21 07:00:14 -07:00
|
|
|
ioportid_t port = getHwPort("exti", brainPin);
|
2019-04-21 06:28:49 -07:00
|
|
|
if (port == NULL)
|
|
|
|
return;
|
2020-12-22 17:42:30 -08:00
|
|
|
brain_pin_markUnused(brainPin);
|
2019-04-21 06:28:49 -07:00
|
|
|
|
2019-04-21 07:00:14 -07:00
|
|
|
int index = getHwPin("exti", brainPin);
|
2019-04-21 06:28:49 -07:00
|
|
|
|
|
|
|
/* is this index was used? */
|
|
|
|
if (!(ext_used & PAL_PORT_BIT(index))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-21 07:00:14 -07:00
|
|
|
ioline_t line = PAL_LINE(port, index);
|
2019-04-21 06:28:49 -07:00
|
|
|
palDisableLineEvent(line);
|
|
|
|
|
|
|
|
/* mark unused */
|
|
|
|
ext_used &= ~PAL_PORT_BIT(index);
|
2018-12-18 20:50:29 -08:00
|
|
|
}
|
|
|
|
|
2019-02-05 15:36:25 -08:00
|
|
|
#endif /* HAL_USE_PAL && EFI_PROD_CODE */
|