diff --git a/firmware/controllers/system/efi_gpio.cpp b/firmware/controllers/system/efi_gpio.cpp index feb5eea406..6252dcc6a4 100644 --- a/firmware/controllers/system/efi_gpio.cpp +++ b/firmware/controllers/system/efi_gpio.cpp @@ -491,53 +491,6 @@ void turnAllPinsOff(void) { } } - -/** - * @deprecated - use hwPortname() instead - */ -const char *portname(ioportid_t GPIOx) { - if (GPIOx == GPIOA) - return "PA"; - if (GPIOx == GPIOB) - return "PB"; - if (GPIOx == GPIOC) - return "PC"; - if (GPIOx == GPIOD) - return "PD"; -#if STM32_HAS_GPIOE - if (GPIOx == GPIOE) - return "PE"; -#endif /* STM32_HAS_GPIOE */ -#if STM32_HAS_GPIOF - if (GPIOx == GPIOF) - return "PF"; -#endif /* STM32_HAS_GPIOF */ -#if STM32_HAS_GPIOG - if (GPIOx == GPIOG) - return "PG"; -#endif /* STM32_HAS_GPIOG */ -#if STM32_HAS_GPIOH - if (GPIOx == GPIOH) - return "PH"; -#endif /* STM32_HAS_GPIOH */ - return "unknown"; -} - -/** - * this method returns the numeric part of pin name. For instance, for PC13 this would return '13' - */ -ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin) -{ - if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID) - return EFI_ERROR_CODE; - - if (brain_pin_is_onchip(brainPin)) - return (brainPin - GPIOA_0) % PORT_SIZE; - - firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid on-chip brain_pin_e: %d", msg, brainPin); - return EFI_ERROR_CODE; -} - #else /* EFI_GPIO_HARDWARE */ const char *hwPortname(brain_pin_e brainPin) { (void)brainPin; diff --git a/firmware/hw_layer/io_pins.cpp b/firmware/hw_layer/io_pins.cpp index b95c63c200..8290208eb7 100644 --- a/firmware/hw_layer/io_pins.cpp +++ b/firmware/hw_layer/io_pins.cpp @@ -28,17 +28,6 @@ EXTERN_ENGINE; static LoggingWithStorage logger("io_pins"); extern EnginePins enginePins; -extern ioportid_t PORTS[]; - -ioportid_t getHwPort(const char *msg, brain_pin_e brainPin) { - if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID) - return GPIO_NULL; - if (brainPin < GPIOA_0 || brainPin > GPIOH_15) { - firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid brain_pin_e: %d", msg, brainPin); - return GPIO_NULL; - } - return PORTS[(brainPin - GPIOA_0)/ PORT_SIZE]; -} bool efiReadPin(brain_pin_e pin) { if (brain_pin_is_onchip(pin)) diff --git a/firmware/hw_layer/pin_repository.cpp b/firmware/hw_layer/pin_repository.cpp index 828c2ea3ae..79277c0d11 100644 --- a/firmware/hw_layer/pin_repository.cpp +++ b/firmware/hw_layer/pin_repository.cpp @@ -21,35 +21,6 @@ #define BOARD_EXT_PINREPOPINS 0 #endif -static ioportid_t ports[] = {GPIOA, - GPIOB, - GPIOC, - GPIOD, -#if STM32_HAS_GPIOE - GPIOE, -#else - nullptr, -#endif /* STM32_HAS_GPIOE */ -#if STM32_HAS_GPIOF - GPIOF, -#else - nullptr, -#endif /* STM32_HAS_GPIOF */ -#if STM32_HAS_GPIOG - GPIOG, -#else - nullptr, -#endif /* STM32_HAS_GPIOG */ -#if STM32_HAS_GPIOH - GPIOH, -#else - nullptr, -#endif /* STM32_HAS_GPIOH */ -}; - -#define PIN_REPO_SIZE (sizeof(ports) / sizeof(ports[0])) * PORT_SIZE -// todo: move this into PinRepository class -const char *PIN_USED[PIN_REPO_SIZE + BOARD_EXT_PINREPOPINS]; static int initialized = FALSE; static LoggingWithStorage logger("pin repos"); @@ -65,7 +36,7 @@ static int brainPin_to_index(brain_pin_e brainPin) index = brainPin - GPIOA_0; /* if index outside array boundary */ - if ((unsigned)index > (sizeof(PIN_USED) / sizeof(PIN_USED[0]))) + if ((unsigned)index >= getNumBrainPins() + BOARD_EXT_PINREPOPINS) return -1; return index; @@ -81,58 +52,28 @@ PinRepository::PinRepository() { static PinRepository instance; -static int getPortIndex(ioportid_t port) { - efiAssert(CUSTOM_ERR_ASSERT, port != NULL, "null port", -1); - if (port == GPIOA) - return 0; - if (port == GPIOB) - return 1; - if (port == GPIOC) - return 2; - if (port == GPIOD) - return 3; -#if STM32_HAS_GPIOE - if (port == GPIOE) - return 4; -#endif /* STM32_HAS_GPIOE */ -#if STM32_HAS_GPIOF - if (port == GPIOF) - return 5; -#endif /* STM32_HAS_GPIOF */ -#if STM32_HAS_GPIOG - if (port == GPIOG) - return 6; -#endif /* STM32_HAS_GPIOG */ -#if STM32_HAS_GPIOH - if (port == GPIOH) - return 7; -#endif /* STM32_HAS_GPIOH */ - firmwareError(CUSTOM_ERR_UNKNOWN_PORT, "unknown port"); - return -1; -} - static void reportPins(void) { - for (unsigned int i = 0; i < PIN_REPO_SIZE; i++) { - const char *pin_user = PIN_USED[i]; + for (unsigned int i = 0; i < getNumBrainPins(); i++) { + const char *pin_user = getBrainUsedPin(i); /* show used pins */ if (pin_user != NULL) { - int portIndex = i / PORT_SIZE; - int pin = i % PORT_SIZE; - ioportid_t port = ports[portIndex]; + brain_pin_e brainPin = index_to_brainPin(i); + int pin = getBrainPinIndex(brainPin); + ioportid_t port = getBrainPort(brainPin); scheduleMsg(&logger, "pin %s%d: %s", portname(port), pin, pin_user); } } #if (BOARD_EXT_GPIOCHIPS > 0) - for (unsigned int i = PIN_REPO_SIZE ; i < PIN_REPO_SIZE + BOARD_EXT_PINREPOPINS /* gpiochips_get_total_pins()*/ ; i++) { + for (unsigned int i = getNumBrainPins() ; i < getNumBrainPins() + BOARD_EXT_PINREPOPINS /* gpiochips_get_total_pins()*/ ; i++) { const char *pin_name; const char *pin_user; brain_pin_e brainPin = index_to_brainPin(i); pin_name = gpiochips_getPinName(brainPin); - pin_user = PIN_USED[i]; + pin_user = getBrainUsedPin(i); /* here show all pins, unused too */ if (pin_name != NULL) { @@ -152,32 +93,6 @@ static void reportPins(void) { static MemoryStream portNameStream; static char portNameBuffer[20]; -/** - * Parse string representation of physical pin into brain_pin_e ordinal. - * - * @return GPIO_UNASSIGNED for "none", GPIO_INVALID for invalid entry - */ -brain_pin_e parseBrainPin(const char *str) { - if (strEqual(str, "none")) - return GPIO_UNASSIGNED; - // todo: create method toLowerCase? - if (str[0] != 'p' && str[0] != 'P') { - return GPIO_INVALID; - } - char port = str[1]; - brain_pin_e basePin; - if (port >= 'a' && port <= 'z') { - basePin = (brain_pin_e) ((int) GPIOA_0 + 16 * (port - 'a')); - } else if (port >= 'A' && port <= 'Z') { - basePin = (brain_pin_e) ((int) GPIOA_0 + 16 * (port - 'A')); - } else { - return GPIO_INVALID; - } - const char *pinStr = str + 2; - int pin = atoi(pinStr); - return (brain_pin_e)(basePin + pin); -} - const char *hwPortname(brain_pin_e brainPin) { if (brainPin == GPIO_INVALID) { return "INVALID"; @@ -218,18 +133,13 @@ void initPinRepository(void) { msObjectInit(&portNameStream, (uint8_t*) portNameBuffer, sizeof(portNameBuffer), 0); - memset(PIN_USED, 0, sizeof(PIN_USED)); + initBrainUsedPins(); initialized = true; addConsoleAction("pins", reportPins); } -static int getIndex(ioportid_t port, ioportmask_t pin) { - int portIndex = getPortIndex(port); - return portIndex * PORT_SIZE + pin; -} - bool brain_pin_is_onchip(brain_pin_e brainPin) { if ((brainPin < GPIOA_0) || (brainPin > BRAIN_PIN_LAST_ONCHIP)) @@ -265,18 +175,18 @@ bool brain_pin_markUsed(brain_pin_e brainPin, const char *msg) { if (index < 0) return true; - if (PIN_USED[index] != NULL) { + if (getBrainUsedPin(index) != NULL) { /* TODO: get readable name of brainPin... */ /** * todo: the problem is that this warning happens before the console is even * connected, so the warning is never displayed on the console and that's quite a problem! */ -// warning(OBD_PCM_Processor_Fault, "brain pin %d req by %s used by %s", brainPin, msg, PIN_USED[index]); - firmwareError(CUSTOM_ERR_PIN_ALREADY_USED_1, "brain pin %s req by %s used by %s", hwPortname(brainPin), msg, PIN_USED[index]); +// warning(OBD_PCM_Processor_Fault, "brain pin %d req by %s used by %s", brainPin, msg, getBrainUsedPin(index)); + firmwareError(CUSTOM_ERR_PIN_ALREADY_USED_1, "brain pin %s req by %s used by %s", hwPortname(brainPin), msg, getBrainUsedPin(index)); return true; } - PIN_USED[index] = msg; + getBrainUsedPin(index) = msg; totalPinsUsed++; return false; } @@ -298,9 +208,9 @@ void brain_pin_markUnused(brain_pin_e brainPin) if (index < 0) return; - if (PIN_USED[index] != NULL) + if (getBrainUsedPin(index) != NULL) totalPinsUsed--; - PIN_USED[index] = NULL; + getBrainUsedPin(index) = NULL; } /** @@ -313,18 +223,18 @@ bool gpio_pin_markUsed(ioportid_t port, ioportmask_t pin, const char *msg) { firmwareError(CUSTOM_ERR_PIN_REPO, "repository not initialized"); return false; } - int index = getIndex(port, pin); + int index = getBrainIndex(port, pin); - if (PIN_USED[index] != NULL) { + if (getBrainUsedPin(index) != NULL) { /** * todo: the problem is that this warning happens before the console is even * connected, so the warning is never displayed on the console and that's quite a problem! */ -// warning(OBD_PCM_Processor_Fault, "%s%d req by %s used by %s", portname(port), pin, msg, PIN_USED[index]); - firmwareError(CUSTOM_ERR_PIN_ALREADY_USED_1, "%s%d req by %s used by %s", portname(port), pin, msg, PIN_USED[index]); +// warning(OBD_PCM_Processor_Fault, "%s%d req by %s used by %s", portname(port), pin, msg, getBrainUsedPin(index)); + firmwareError(CUSTOM_ERR_PIN_ALREADY_USED_1, "%s%d req by %s used by %s", portname(port), pin, msg, getBrainUsedPin(index)); return true; } - PIN_USED[index] = msg; + getBrainUsedPin(index) = msg; totalPinsUsed++; return false; } @@ -339,11 +249,11 @@ void gpio_pin_markUnused(ioportid_t port, ioportmask_t pin) { firmwareError(CUSTOM_ERR_PIN_REPO, "repository not initialized"); return; } - int index = getIndex(port, pin); + int index = getBrainIndex(port, pin); - if (PIN_USED[index] != NULL) + if (getBrainUsedPin(index) != NULL) totalPinsUsed--; - PIN_USED[index] = NULL; + getBrainUsedPin(index) = NULL; } const char *getPinFunction(brain_input_pin_e brainPin) { @@ -353,7 +263,7 @@ const char *getPinFunction(brain_input_pin_e brainPin) { if (index < 0) return NULL; - return PIN_USED[index]; + return getBrainUsedPin(index); } #endif diff --git a/firmware/hw_layer/pin_repository.h b/firmware/hw_layer/pin_repository.h index fbc8f08497..2ad2b7ed87 100644 --- a/firmware/hw_layer/pin_repository.h +++ b/firmware/hw_layer/pin_repository.h @@ -25,8 +25,6 @@ class PinRepository { #endif /* __cplusplus */ -#define PORT_SIZE 16 - void initPinRepository(void); EXTERNC bool brain_pin_is_onchip(brain_pin_e brainPin); EXTERNC bool brain_pin_is_ext(brain_pin_e brainPin); @@ -46,4 +44,15 @@ EXTERNC bool gpio_pin_markUsed(ioportid_t port, ioportmask_t pin, const char *ms EXTERNC void gpio_pin_markUnused(ioportid_t port, ioportmask_t pin); #endif /* EFI_PROD_CODE*/ +/* defined in ports/ */ +int getBrainIndex(ioportid_t port, ioportmask_t pin); +ioportid_t getBrainPort(brain_pin_e brainPin); +int getBrainPinIndex(brain_pin_e brainPin); +unsigned int getNumBrainPins(void); +void initBrainUsedPins(void); + +#ifdef __cplusplus +const char* & getBrainUsedPin(unsigned int idx); +#endif + #endif /* PIN_REPOSITORY_H_ */ diff --git a/firmware/hw_layer/ports/stm32/stm32_pins.cpp b/firmware/hw_layer/ports/stm32/stm32_pins.cpp new file mode 100644 index 0000000000..0a670e76f8 --- /dev/null +++ b/firmware/hw_layer/ports/stm32/stm32_pins.cpp @@ -0,0 +1,190 @@ +/** + * @file stm32_pins.cpp + * @brief STM32-compatible GPIO code + * + * @date Jun 02, 2019 + * @author Andrey Belomutskiy, (c) 2012-2019 + */ + +#include "global.h" +#include "engine.h" +#include "efi_gpio.h" + + +#define PORT_SIZE 16 + +static ioportid_t ports[] = {GPIOA, + GPIOB, + GPIOC, + GPIOD, +#if STM32_HAS_GPIOE + GPIOE, +#else + nullptr, +#endif /* STM32_HAS_GPIOE */ +#if STM32_HAS_GPIOF + GPIOF, +#else + nullptr, +#endif /* STM32_HAS_GPIOF */ +#if STM32_HAS_GPIOG + GPIOG, +#else + nullptr, +#endif /* STM32_HAS_GPIOG */ +#if STM32_HAS_GPIOH + GPIOH, +#else + nullptr, +#endif /* STM32_HAS_GPIOH */ +}; + +#define PIN_REPO_SIZE (sizeof(ports) / sizeof(ports[0])) * PORT_SIZE +// todo: move this into PinRepository class +static const char *PIN_USED[PIN_REPO_SIZE + BOARD_EXT_PINREPOPINS]; + +#if EFI_GPIO_HARDWARE + +#include "pin_repository.h" +#include "io_pins.h" + +extern ioportid_t PORTS[]; + +/** + * @deprecated - use hwPortname() instead + */ +const char *portname(ioportid_t GPIOx) { + if (GPIOx == GPIOA) + return "PA"; + if (GPIOx == GPIOB) + return "PB"; + if (GPIOx == GPIOC) + return "PC"; + if (GPIOx == GPIOD) + return "PD"; +#if STM32_HAS_GPIOE + if (GPIOx == GPIOE) + return "PE"; +#endif /* STM32_HAS_GPIOE */ +#if STM32_HAS_GPIOF + if (GPIOx == GPIOF) + return "PF"; +#endif /* STM32_HAS_GPIOF */ +#if STM32_HAS_GPIOG + if (GPIOx == GPIOG) + return "PG"; +#endif /* STM32_HAS_GPIOG */ +#if STM32_HAS_GPIOH + if (GPIOx == GPIOH) + return "PH"; +#endif /* STM32_HAS_GPIOH */ + return "unknown"; +} + +static int getPortIndex(ioportid_t port) { + efiAssert(CUSTOM_ERR_ASSERT, port != NULL, "null port", -1); + if (port == GPIOA) + return 0; + if (port == GPIOB) + return 1; + if (port == GPIOC) + return 2; + if (port == GPIOD) + return 3; +#if STM32_HAS_GPIOE + if (port == GPIOE) + return 4; +#endif /* STM32_HAS_GPIOE */ +#if STM32_HAS_GPIOF + if (port == GPIOF) + return 5; +#endif /* STM32_HAS_GPIOF */ +#if STM32_HAS_GPIOG + if (port == GPIOG) + return 6; +#endif /* STM32_HAS_GPIOG */ +#if STM32_HAS_GPIOH + if (port == GPIOH) + return 7; +#endif /* STM32_HAS_GPIOH */ + firmwareError(CUSTOM_ERR_UNKNOWN_PORT, "unknown port"); + return -1; +} + +ioportid_t getBrainPort(brain_pin_e brainPin) { + return ports[(brainPin - GPIOA_0) / PORT_SIZE]; +} + +int getBrainPinIndex(brain_pin_e brainPin) { + return (brainPin - GPIOA_0) % PORT_SIZE; +} + +int getBrainIndex(ioportid_t port, ioportmask_t pin) { + int portIndex = getPortIndex(port); + return portIndex * PORT_SIZE + pin; +} + +ioportid_t getHwPort(const char *msg, brain_pin_e brainPin) { + if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID) + return GPIO_NULL; + if (brainPin < GPIOA_0 || brainPin > BRAIN_PIN_LAST_ONCHIP) { + firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid brain_pin_e: %d", msg, brainPin); + return GPIO_NULL; + } + return PORTS[(brainPin - GPIOA_0) / PORT_SIZE]; +} + +/** + * this method returns the numeric part of pin name. For instance, for PC13 this would return '13' + */ +ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin) +{ + if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID) + return EFI_ERROR_CODE; + + if (brain_pin_is_onchip(brainPin)) + return getBrainPinIndex(brainPin); + + firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid on-chip brain_pin_e: %d", msg, brainPin); + return EFI_ERROR_CODE; +} + +/** + * Parse string representation of physical pin into brain_pin_e ordinal. + * + * @return GPIO_UNASSIGNED for "none", GPIO_INVALID for invalid entry + */ +brain_pin_e parseBrainPin(const char *str) { + if (strEqual(str, "none")) + return GPIO_UNASSIGNED; + // todo: create method toLowerCase? + if (str[0] != 'p' && str[0] != 'P') { + return GPIO_INVALID; + } + char port = str[1]; + brain_pin_e basePin; + if (port >= 'a' && port <= 'z') { + basePin = (brain_pin_e) ((int) GPIOA_0 + PORT_SIZE * (port - 'a')); + } else if (port >= 'A' && port <= 'Z') { + basePin = (brain_pin_e) ((int) GPIOA_0 + PORT_SIZE * (port - 'A')); + } else { + return GPIO_INVALID; + } + const char *pinStr = str + 2; + int pin = atoi(pinStr); + return (brain_pin_e)(basePin + pin); +} + +unsigned int getNumBrainPins(void) { + return PIN_REPO_SIZE; +} + +void initBrainUsedPins(void) { + memset(PIN_USED, 0, sizeof(PIN_USED)); +} + +const char* & getBrainUsedPin(unsigned int idx) { + return PIN_USED[idx]; +} + +#endif /* EFI_GPIO_HARDWARE */ diff --git a/firmware/hw_layer/ports/stm32/stm32f1/hw_ports.mk b/firmware/hw_layer/ports/stm32/stm32f1/hw_ports.mk index 0e18e72619..fb4278b501 100644 --- a/firmware/hw_layer/ports/stm32/stm32f1/hw_ports.mk +++ b/firmware/hw_layer/ports/stm32/stm32f1/hw_ports.mk @@ -1,4 +1,5 @@ HW_LAYER_EMS += $(PROJECT_DIR)/hw_layer/ports/stm32/flash.c HW_LAYER_EMS_CPP += $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f1/mpu_util.cpp \ + $(PROJECT_DIR)/hw_layer/ports/stm32/stm32_pins.cpp \ $(PROJECT_DIR)/hw_layer/ports/stm32/stm32_common.cpp diff --git a/firmware/hw_layer/ports/stm32/stm32f4/hw_ports.mk b/firmware/hw_layer/ports/stm32/stm32f4/hw_ports.mk index 218704b7c4..1dc371ab53 100644 --- a/firmware/hw_layer/ports/stm32/stm32f4/hw_ports.mk +++ b/firmware/hw_layer/ports/stm32/stm32f4/hw_ports.mk @@ -3,5 +3,6 @@ HW_LAYER_EMS += $(PROJECT_DIR)/hw_layer/ports/stm32/flash.c \ $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f4/stm32f4xx_hal_flash_ex.c HW_LAYER_EMS_CPP += $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f4/mpu_util.cpp \ + $(PROJECT_DIR)/hw_layer/ports/stm32/stm32_pins.cpp \ $(PROJECT_DIR)/hw_layer/ports/stm32/stm32_common.cpp \ No newline at end of file diff --git a/firmware/hw_layer/ports/stm32/stm32f7/hw_ports.mk b/firmware/hw_layer/ports/stm32/stm32f7/hw_ports.mk index 84ff98f145..31c5f29db8 100644 --- a/firmware/hw_layer/ports/stm32/stm32f7/hw_ports.mk +++ b/firmware/hw_layer/ports/stm32/stm32f7/hw_ports.mk @@ -3,5 +3,6 @@ HW_LAYER_EMS += $(PROJECT_DIR)/hw_layer/ports/stm32/flash.c \ $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f7/stm32f7xx_hal_flash_ex.c HW_LAYER_EMS_CPP += $(PROJECT_DIR)/hw_layer/ports/stm32/stm32f7/mpu_util.cpp \ + $(PROJECT_DIR)/hw_layer/ports/stm32/stm32_pins.cpp \ $(PROJECT_DIR)/hw_layer/ports/stm32/stm32_common.cpp \ No newline at end of file