Exti rework (#770)

* io_pins: implement efiSetPadUnused

When pin becomes unused it should be switched to safe mode and
disconnected from any IP block. Assume that gpio input mode with
pull-up is safe enough.

* trigger_input: switch triggers pins to safe mode on stop/reinit

* digital_input_exti: rework

* rename enableExti to efiExtiEnablePin
* add efiExtiDisablePin
* keep track of used exti channels

* trigger_input: use digital_input_exti functions
This commit is contained in:
dron0gus 2019-04-21 16:28:49 +03:00 committed by rusefi
parent 1599e34d57
commit def0123503
9 changed files with 104 additions and 40 deletions

View File

@ -43,8 +43,8 @@ void ionPostState(TunerStudioOutputChannels *tsOutputChannels) {
static CdmState instance;
static void extIonCallback(int pinIndex) {
UNUSED(pinIndex);
static void extIonCallback(void *arg) {
UNUSED(arg);
int currentRevolution = engine->triggerCentral.triggerState.getTotalRevolutionCounter();
@ -62,7 +62,7 @@ void cdmIonInit(void) {
return;
}
enableExti(CONFIGB(cdmInputPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)(void *)extIonCallback);
efiExtiEnablePin("ion", CONFIGB(cdmInputPin), PAL_EVENT_MODE_RISING_EDGE, extIonCallback, NULL);
}
#endif /* EFI_CDM_INTEGRATION */

View File

@ -10,6 +10,7 @@
#if HAL_USE_PAL && EFI_PROD_CODE
#include "digital_input_exti.h"
#include "efi_gpio.h"
#include "error_handling.h"
/**
* EXTI is a funny thing: you can only use same pin on one port. For example, you can use
@ -19,17 +20,67 @@
* because pin '0' would be used on two different ports
*/
static ioportmask_t ext_used = 0;
// EXT is not able to give you the front direction but you could read the pin in the callback.
void enableExti(brain_pin_e pin, uint32_t mode, palcallback_t cb) {
if (pin == GPIO_UNASSIGNED)
int efiExtiEnablePin(const char *msg, brain_pin_e brainPin, uint32_t mode, palcallback_t cb, void *cb_data) {
int index;
ioportid_t port;
ioline_t line;
/* paranoid chech, in case of GPIO_UNASSIGNED getHwPort will return NULL
* and we will fail on next check */
if (brainPin == GPIO_UNASSIGNED)
return -1;
port = getHwPort(msg, brainPin);
if (port == NULL)
return -1;
index = getHwPin(msg, brainPin);
/* 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);
return -1;
}
line = PAL_LINE(port, index);
palEnableLineEvent(line, mode);
palSetLineCallback(line, cb, cb_data);
/* mark used */
ext_used |= PAL_PORT_BIT(index);
return 0;
}
void efiExtiDisablePin(brain_pin_e brainPin)
{
int index;
ioportid_t port;
ioline_t line;
/* paranoid chech, in case of GPIO_UNASSIGNED getHwPort will return NULL
* and we will fail on next check */
if (brainPin == GPIO_UNASSIGNED)
return;
int index = getHwPin("joy", pin);
ioportid_t port = getHwPort("joy", pin);
port = getHwPort("exti", brainPin);
if (port == NULL)
return;
ioline_t line = PAL_LINE(port, index);
palEnableLineEvent(line, mode);
palSetLineCallback(line, cb, (void*)index);
index = getHwPin("exti", brainPin);
/* is this index was used? */
if (!(ext_used & PAL_PORT_BIT(index))) {
return;
}
palDisableLineEvent(line);
/* mark unused */
ext_used &= ~PAL_PORT_BIT(index);
}
#endif /* HAL_USE_PAL && EFI_PROD_CODE */

View File

@ -11,7 +11,8 @@
#include "global.h"
#if HAL_USE_PAL
void enableExti(brain_pin_e pin, uint32_t mode, palcallback_t cb);
int efiExtiEnablePin(const char *msg, brain_pin_e pin, uint32_t mode, palcallback_t cb, void *cb_data);
void efiExtiDisablePin(brain_pin_e brainPin);
#endif /* HAL_USE_PAL */
#endif /* HW_LAYER_DIGITAL_INPUT_EXTI_H_ */

View File

@ -205,6 +205,10 @@ void turnOnCapturePin(const char *msg, brain_pin_e brainPin) {
}
}
void turnOffCapturePin(brain_pin_e brainPin) {
efiSetPadUnused(brainPin);
}
/**
* takes next digital_input_s from the registeredIcus pool
*/

View File

@ -24,6 +24,7 @@ typedef struct {
} digital_input_s;
void turnOnCapturePin(const char *msg, brain_pin_e brainPin);
void turnOffCapturePin(brain_pin_e brainPin);
digital_input_s *addWaveAnalyzerDriver(const char *msg, brain_pin_e brainPin);
void startInputDriver(const char *msg, /*nullable*/digital_input_s *hw, bool isActiveHigh);

View File

@ -99,6 +99,27 @@ void efiSetPadMode(const char *msg, brain_pin_e brainPin, iomode_t mode)
}
}
void efiSetPadUnused(brain_pin_e brainPin)
{
/* input with pull up, is it safe? */
iomode_t mode = PAL_STM32_MODE_INPUT | PAL_STM32_PUPDR_PULLUP;
if (brain_pin_is_onchip(brainPin)) {
ioportid_t port = getHwPort("unused", brainPin);
ioportmask_t pin = getHwPin("unused", brainPin);
/* input with pull up, is it safe? */
palSetPadMode(port, pin, mode);
}
#if (BOARD_EXT_GPIOCHIPS > 0)
else {
gpiochips_setPadMode(brainPin, mode);
}
#endif
brain_pin_markUnused(brainPin);
}
iomode_t getInputMode(pin_input_mode_e mode) {
switch (mode) {
case PI_PULLUP:

View File

@ -53,6 +53,7 @@
#if EFI_GPIO_HARDWARE
void efiSetPadMode(const char *msg, brain_pin_e pin, iomode_t mode);
void efiSetPadUnused(brain_pin_e brainPin);
bool efiReadPin(brain_pin_e pin);

View File

@ -111,16 +111,20 @@ void startJoystickPins() {
}
void initJoystick(Logging *shared) {
int channel;
addConsoleAction("joystickinfo", joystickInfo);
if (!isJoystickEnabled())
return;
sharedLogger = shared;
enableExti(CONFIGB(joystickCenterPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)(void *)extCallback);
enableExti(CONFIGB(joystickAPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)(void *)extCallback);
channel = getHwPin("joy", CONFIGB(joystickCenterPin));
efiExtiEnablePin("joy", CONFIGB(joystickCenterPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)(void *)extCallback, (void *)channel);
channel = getHwPin("joy", CONFIGB(joystickAPin));
efiExtiEnablePin("joy", CONFIGB(joystickAPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)(void *)extCallback, (void *)channel);
// not used so far applyPin(CONFIGB(joystickBPin));
// not used so far applyPin(CONFIGB(joystickCPin));
enableExti(CONFIGB(joystickDPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)(void *)extCallback);
channel = getHwPin("joy", CONFIGB(joystickDPin));
efiExtiEnablePin("joy", CONFIGB(joystickDPin), PAL_EVENT_MODE_RISING_EDGE, (palcallback_t)(void *)extCallback, (void *)channel);
startJoystickPins();
}

View File

@ -23,6 +23,7 @@
#include "trigger_input.h"
#include "digital_input_hw.h"
#include "digital_input_exti.h"
#include "pin_repository.h"
#include "trigger_structure.h"
#include "trigger_central.h"
@ -100,41 +101,21 @@ static void cam_callback(void *arg)
static int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool is_shaft)
{
ioline_t pal_line;
(void)is_shaft;
/* check for on-chip? */
if (brainPin == GPIO_UNASSIGNED)
return -1;
scheduleMsg(logger, "turnOnTriggerInputPin(PAL) %s %s", msg, hwPortname(brainPin));
/* TODO:
* * do not set to both edges if we need only one
* * simplify callback in case of one edge */
pal_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin));
// todo efiSetPadMode(msg, brainPin, mode); or reuse joystick code? configurePalInputPin?
brain_pin_markUsed(brainPin, msg);
palEnableLineEvent(pal_line, PAL_EVENT_MODE_BOTH_EDGES);
if (is_shaft)
palSetLineCallback(pal_line, shaft_callback, (void*)pal_line);
else
palSetLineCallback(pal_line, cam_callback, (void*)pal_line);
return 0;
return efiExtiEnablePin(msg, brainPin, PAL_EVENT_MODE_BOTH_EDGES, is_shaft ? shaft_callback : cam_callback, (void *)pal_line);
}
static void turnOffTriggerInputPin(brain_pin_e brainPin)
{
uint32_t pal_line;
/* check for on-chip? */
if (brainPin == GPIO_UNASSIGNED)
return;
brain_pin_markUnused(brainPin);
pal_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin));
palDisableLineEvent(pal_line);
efiExtiDisablePin(brainPin);
}
static void setPrimaryChannel(brain_pin_e brainPin)
{
primary_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin));
@ -262,7 +243,7 @@ static void turnOffTriggerInputPin(brain_pin_e brainPin) {
icuStopCapture(driver);
icuStop(driver);
scheduleMsg(logger, "turnOffTriggerInputPin %s", hwPortname(brainPin));
brain_pin_markUnused(brainPin);
turnOffCapturePin(brainPin);
}
}