From ff0941016b9bc4a264fe5bdf41e0a2f69d152db2 Mon Sep 17 00:00:00 2001
From: MaxineMuster <146550015+MaxineMuster@users.noreply.github.com>
Date: Tue, 20 Jan 2026 14:38:40 +0100
Subject: [PATCH] Pinalias as arg (#1948)
* Add int HAL_PIN_Find(const char *name) for all platforms
add simple selftest (and added some alias strings to windows pins)
* fix ESP
* fix second occurence of isdigit for ESP by casting to unsigned char
* Moved code for HAL_PIN_Find to "src/hal/generic/hal_pins_generic.c" and removed it from the (few) platforms aleady implemented it.
Added some "complex" pin alias descriptions for windows to test
made function case insensitive - introducing "char *wal_stristr(const char *haystack, const char *needle);" as a case insensitiver version of "strstr" in new_common.c
* Try fix windows (by including src\hal\generic\hal_pins_generic.c)
Enable ENABLE_TEST_COMMANDS for all platforms to do some testing
* comment out weak functions for Windows
* including "../hal/hal_pins.h" in cmd_test.c to clear warning about HAL_PIN_Find()
* comment out StackOverflow test for ESP - it won't compile
* fix
* Moved code from hal_pins_generic.c to new_pins.c
reverted usage of hal_pins_generic.c in Windows build
changed Tokenizer_GetPin()
* Changed driver commands to use Tokenizer_GetPin() instead of Tokenizer_GetArgIntegerDefault() to get drivers pins
* Fix typo in drv_pinMutex.c
* Fix cmd_test.c and ds1820_full.c
Added debug output to Tokenizer_GetPin()
* Removed tesing and debugging code
* Also allow pin alias in SetPinRole command
* Fix typo
---
openBeken_win32_mvsc2017.vcxproj | 1 +
openBeken_win32_mvsc2017.vcxproj.filters | 3 +-
src/cmnds/cmd_channels.c | 6 +-
src/cmnds/cmd_test.c | 16 ++++++
src/cmnds/cmd_tokenizer.c | 8 ++-
src/driver/drv_bmpi2c.c | 6 +-
src/driver/drv_dmx512.c | 3 +-
src/driver/drv_ds1820_common.c | 4 +-
src/driver/drv_ds1820_full.c | 5 +-
src/driver/drv_ir2.c | 5 +-
src/driver/drv_mcp9808.c | 6 +-
src/driver/drv_pinMutex.c | 7 ++-
src/driver/drv_simpleEEPROM.c | 6 +-
src/driver/drv_tca9554.c | 6 +-
src/driver/drv_tm_gn_display_shared.c | 6 +-
src/hal/ln882h/hal_pins_ln882h.c | 13 -----
src/hal/w800/hal_pins_w800.c | 12 ----
src/hal/win32/hal_pins_win32.c | 14 +++--
src/new_common.c | 8 +++
src/new_common.h | 1 +
src/new_pins.c | 73 ++++++++++++++++++++++++
src/new_pins.h | 5 ++
src/selftest/selftest_local.h | 1 +
src/selftest/selftest_pins.c | 56 ++++++++++++++++++
src/win_main.c | 1 +
25 files changed, 222 insertions(+), 50 deletions(-)
create mode 100644 src/selftest/selftest_pins.c
diff --git a/openBeken_win32_mvsc2017.vcxproj b/openBeken_win32_mvsc2017.vcxproj
index a2f392436..541cdb09c 100644
--- a/openBeken_win32_mvsc2017.vcxproj
+++ b/openBeken_win32_mvsc2017.vcxproj
@@ -836,6 +836,7 @@
+
diff --git a/openBeken_win32_mvsc2017.vcxproj.filters b/openBeken_win32_mvsc2017.vcxproj.filters
index f8ef52887..688f44a64 100644
--- a/openBeken_win32_mvsc2017.vcxproj.filters
+++ b/openBeken_win32_mvsc2017.vcxproj.filters
@@ -277,6 +277,7 @@
+
@@ -671,4 +672,4 @@
-
\ No newline at end of file
+
diff --git a/src/cmnds/cmd_channels.c b/src/cmnds/cmd_channels.c
index 62baefe4a..b0e5e5fec 100644
--- a/src/cmnds/cmd_channels.c
+++ b/src/cmnds/cmd_channels.c
@@ -268,7 +268,11 @@ static commandResult_t CMD_SetPinRole(const void *context, const char *cmd, cons
return CMD_RES_NOT_ENOUGH_ARGUMENTS;
}
- pin = Tokenizer_GetArgInteger(0);
+ pin = Tokenizer_GetPin(0,-1);
+ if (pin==-1){
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Unknown pin %s",Tokenizer_GetArg(0));
+ return CMD_RES_BAD_ARGUMENT;
+ }
role = Tokenizer_GetArg(1);
roleIndex = PIN_ParsePinRoleName(role);
diff --git a/src/cmnds/cmd_test.c b/src/cmnds/cmd_test.c
index f3fe594cc..f115bb595 100644
--- a/src/cmnds/cmd_test.c
+++ b/src/cmnds/cmd_test.c
@@ -13,6 +13,12 @@
#if ENABLE_TEST_COMMANDS
+static commandResult_t CMD_getPin(const void* context, const char* cmd, const char* args, int cmdFlags) {
+ Tokenizer_TokenizeString(args,0);
+
+ ADDLOG_INFO(LOG_FEATURE_CMD, "Pin index for %s is %i", Tokenizer_GetArg(0), Tokenizer_GetPin(0,-1));
+ return CMD_RES_OK;
+}
static commandResult_t CMD_TimeSize(const void* context, const char* cmd, const char* args, int cmdFlags) {
ADDLOG_INFO(LOG_FEATURE_CMD, "sizeof(time_t) = %i, sizeof(int) = %i", sizeof(time_t), sizeof(int));
return CMD_RES_OK;
@@ -348,6 +354,8 @@ static commandResult_t cmnd_lfs_test3(const void * context, const char *cmd, con
}
return CMD_RES_OK;
}
+// ESP will refuse compilation ( error: infinite recursion detected [-Werror=infinite-recursion])
+#ifndef PLATFORM_ESPIDF
static void stackOverflow(int a) {
char lala[64];
int i;
@@ -364,6 +372,7 @@ static commandResult_t CMD_StackOverflow(const void* context, const char* cmd, c
return CMD_RES_OK;
}
+#endif
static commandResult_t CMD_CrashNull(const void* context, const char* cmd, const char* args, int cmdFlags) {
int *p = (int*)0;
@@ -478,6 +487,11 @@ static commandResult_t CMD_TestIPtoStr(const void* context, const char* cmd, con
int CMD_InitTestCommands(){
+ //cmddetail:{"name":"getPin","args":"string",
+ //cmddetail:"descr":"find pin index for a pin alias",
+ //cmddetail:"fn":"CMD_getPin","file":"cmnds/cmd_test.c","requires":"",
+ //cmddetail:"examples":""}
+ CMD_RegisterCommand("getPin", CMD_getPin, NULL);
//cmddetail:{"name":"testMallocFree","args":"",
//cmddetail:"descr":"Test malloc and free functionality to see if the device crashes",
//cmddetail:"fn":"testMallocFree","file":"cmnds/cmd_test.c","requires":"",
@@ -543,11 +557,13 @@ int CMD_InitTestCommands(){
//cmddetail:"fn":"CMD_TimeSize","file":"cmnds/cmd_test.c","requires":"",
//cmddetail:"examples":""}
CMD_RegisterCommand("TimeSize", CMD_TimeSize, NULL);
+#ifndef PLATFORM_ESPIDF
//cmddetail:{"name":"stackOverflow","args":"",
//cmddetail:"descr":"Causes a stack overflow",
//cmddetail:"fn":"CMD_StackOverflow","file":"cmnds/cmd_test.c","requires":"",
//cmddetail:"examples":""}
CMD_RegisterCommand("stackOverflow", CMD_StackOverflow, NULL);
+#endif
//cmddetail:{"name":"crashNull","args":"",
//cmddetail:"descr":"Causes a crash",
//cmddetail:"fn":"CMD_CrashNull","file":"cmnds/cmd_test.c","requires":"",
diff --git a/src/cmnds/cmd_tokenizer.c b/src/cmnds/cmd_tokenizer.c
index 2ff536e29..3e7492d4f 100644
--- a/src/cmnds/cmd_tokenizer.c
+++ b/src/cmnds/cmd_tokenizer.c
@@ -211,14 +211,20 @@ int Tokenizer_GetArgIntegerRange(int i, int rangeMin, int rangeMax) {
}
return ret;
}
+
int Tokenizer_GetPin(int i, int def) {
int r;
if (g_numArgs <= i) {
+// ADDLOG_DEBUG(LOG_FEATURE_CMD, "Tokenizer_GetPin: Argument %i not present - Returning default index %i",i,def);
return def;
}
- return HAL_PIN_Find(g_args[i]);
+ return Tokenizer_IsArgInteger(i) ? Tokenizer_GetArgInteger(i) : PIN_FindIndexFromString(g_args[i]);
+// r = Tokenizer_IsArgInteger(i) ? Tokenizer_GetArgInteger(i) : PIN_FindIndexFromString(g_args[i]);
+// ADDLOG_DEBUG(LOG_FEATURE_CMD, "Tokenizer_GetPin: Argument %i (%s) - Returning index %i",i,g_args[i],r);
+ return r;
}
+
int Tokenizer_GetArgIntegerDefault(int i, int def) {
int r;
diff --git a/src/driver/drv_bmpi2c.c b/src/driver/drv_bmpi2c.c
index 2c80d81fa..444bdac41 100644
--- a/src/driver/drv_bmpi2c.c
+++ b/src/driver/drv_bmpi2c.c
@@ -123,8 +123,10 @@ void BMPI2C_Measure()
// Adr8bit 0 for 0x77, 1 for 0x76
void BMPI2C_Init()
{
- g_softI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, 8);
- g_softI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, 14);
+// g_softI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, 8);
+// g_softI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, 14);
+ g_softI2C.pin_clk = Tokenizer_GetPin(1, 8);
+ g_softI2C.pin_data = Tokenizer_GetPin(2, 14);
g_targetChannelTemperature = Tokenizer_GetArgIntegerDefault(3, -1);
g_targetChannelPressure = Tokenizer_GetArgIntegerDefault(4, -1);
g_targetChannelHumidity = Tokenizer_GetArgIntegerDefault(5, -1);
diff --git a/src/driver/drv_dmx512.c b/src/driver/drv_dmx512.c
index 7ee5cf654..55409d7f4 100644
--- a/src/driver/drv_dmx512.c
+++ b/src/driver/drv_dmx512.c
@@ -98,7 +98,8 @@ void DMX_SetLEDCount(int pixel_count, int pixel_size) {
}
void DMX_Init() {
- dmx_pin = Tokenizer_GetArgIntegerDefault(1, dmx_pin);
+// dmx_pin = Tokenizer_GetArgIntegerDefault(1, dmx_pin);
+ dmx_pin = Tokenizer_GetPin(1, dmx_pin);
g_dmxBuffer = (byte*)malloc(DMX_BUFFER_SIZE);
memset(g_dmxBuffer, 0, DMX_BUFFER_SIZE);
diff --git a/src/driver/drv_ds1820_common.c b/src/driver/drv_ds1820_common.c
index 9756c087f..c8535d041 100644
--- a/src/driver/drv_ds1820_common.c
+++ b/src/driver/drv_ds1820_common.c
@@ -214,7 +214,9 @@ commandResult_t CMD_OW_testus(const void *context, const char *cmd, const char *
}
#define MAXUSTESTS 10
int testvals[MAXUSTESTS];
- int pin = Tokenizer_GetArgInteger(0);
+// int pin = Tokenizer_GetArgInteger(0);
+ int pin = Tokenizer_GetPin(0,-1);
+ if (pin==-1) return CMD_RES_BAD_ARGUMENT;
int pause = Tokenizer_GetArgInteger(1);
if (tests > MAXUSTESTS){
tests = MAXUSTESTS;
diff --git a/src/driver/drv_ds1820_full.c b/src/driver/drv_ds1820_full.c
index 6c8ffdc11..f9144ab07 100644
--- a/src/driver/drv_ds1820_full.c
+++ b/src/driver/drv_ds1820_full.c
@@ -661,9 +661,10 @@ commandResult_t CMD_DS18B20_setsensor(const void *context, const char *cmd, cons
}
const char *dev = Tokenizer_GetArg(0);
- int gpio = Tokenizer_IsArgInteger(1) ? Tokenizer_GetArgInteger(1) : HAL_PIN_Find(Tokenizer_GetArg(1));
+// int gpio = Tokenizer_IsArgInteger(1) ? Tokenizer_GetArgInteger(1) : HAL_PIN_Find(Tokenizer_GetArg(1));
+ int gpio = Tokenizer_GetPin(1,-1);
if (gpio < 0) {
- DS1820_LOG(ERROR, "DS18B20_setsensor: failed to find GPIO for '%s' (as int: %i)",Tokenizer_GetArg(1),gpio);
+ DS1820_LOG(ERROR, "DS18B20_setsensor: failed to find GPIO for '%s' (returned index: %i)",Tokenizer_GetArg(1),gpio);
return CMD_RES_ERROR;
}
const char *name = Tokenizer_GetArg(2);
diff --git a/src/driver/drv_ir2.c b/src/driver/drv_ir2.c
index 53607b35e..7afe540fa 100644
--- a/src/driver/drv_ir2.c
+++ b/src/driver/drv_ir2.c
@@ -272,7 +272,8 @@ static commandResult_t CMD_IR2_SetupIR2(const void* context, const char* cmd, co
myPeriodUs = Tokenizer_GetArgIntegerDefault(0, 50);
float duty_on_frac = Tokenizer_GetArgFloatDefault(1, 0.5f);
float duty_off_frac = Tokenizer_GetArgFloatDefault(2, 0.0f);
- txpin = Tokenizer_GetArgIntegerDefault(3, 26);
+// txpin = Tokenizer_GetArgIntegerDefault(3, 26);
+ txpin = Tokenizer_GetPin(3, 26);
#if DEBUG_WAVE_WITH_GPIO
bk_gpio_config_output(txpin);
@@ -365,4 +366,4 @@ void DRV_IR2_Init() {
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/driver/drv_mcp9808.c b/src/driver/drv_mcp9808.c
index 81f5db2ec..478229c62 100644
--- a/src/driver/drv_mcp9808.c
+++ b/src/driver/drv_mcp9808.c
@@ -241,8 +241,10 @@ void MCP9808_Init() {
//uint8_t buff[4];
- g_softI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, 26);
- g_softI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, 24);
+// g_softI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, 26);
+// g_softI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, 24);
+ g_softI2C.pin_clk = Tokenizer_GetPin(1, 26);
+ g_softI2C.pin_data = Tokenizer_GetPin(2, 24);
g_targetChannel = Tokenizer_GetArgIntegerDefault(3,-1);
Soft_I2C_PreInit(&g_softI2C);
diff --git a/src/driver/drv_pinMutex.c b/src/driver/drv_pinMutex.c
index e02baf03d..2c56b64e4 100644
--- a/src/driver/drv_pinMutex.c
+++ b/src/driver/drv_pinMutex.c
@@ -103,8 +103,11 @@ static commandResult_t CMD_setMutex(const void *context, const char *cmd, const
int idx = Tokenizer_GetArgInteger(0);
int channel = Tokenizer_GetArgInteger(1);
int delayMs = Tokenizer_GetArgInteger(2);
- int pinDown = Tokenizer_GetArgInteger(3);
- int pinUp = Tokenizer_GetArgInteger(4);
+// int pinDown = Tokenizer_GetArgInteger(3);
+// int pinUp = Tokenizer_GetArgInteger(4);
+ int pinDown = Tokenizer_GetPin(3,-1);
+ int pinUp = Tokenizer_GetPin(4,-1);
+ if (pinDown == -1 || pinUp == -1) return CMD_RES_BAD_ARGUMENT;
if (idx < 0 || idx >= MAX_PINMUTEX) {
addLogAdv(LOG_ERROR, LOG_FEATURE_GENERAL, "setMutex: index %d out of range (0..%d)", idx, MAX_PINMUTEX - 1);
diff --git a/src/driver/drv_simpleEEPROM.c b/src/driver/drv_simpleEEPROM.c
index d7ca7d805..75db345e8 100644
--- a/src/driver/drv_simpleEEPROM.c
+++ b/src/driver/drv_simpleEEPROM.c
@@ -160,8 +160,10 @@ commandResult_t EEPROM_DumpCmd(const void*ctx, const char*cmd, const char*args,
// EEPROM_Write 0 AABBCC
// EEPROM_Read 0 16
void EEPROM_Init() {
- g_eepI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, g_eepI2C.pin_clk);
- g_eepI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, g_eepI2C.pin_data);
+// g_eepI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, g_eepI2C.pin_clk);
+// g_eepI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, g_eepI2C.pin_data);
+ g_eepI2C.pin_clk = Tokenizer_GetPin(1, g_eepI2C.pin_clk);
+ g_eepI2C.pin_data = Tokenizer_GetPin(2, g_eepI2C.pin_data);
Soft_I2C_PreInit(&g_eepI2C);
//cmddetail:{"name":"EEPROM_Read","args":"TODO",
//cmddetail:"descr":"",
diff --git a/src/driver/drv_tca9554.c b/src/driver/drv_tca9554.c
index 4d944c30d..20653692c 100644
--- a/src/driver/drv_tca9554.c
+++ b/src/driver/drv_tca9554.c
@@ -35,8 +35,10 @@ setChannelType 7 Toggle
*/
void TCA9554_Init() {
- tcI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, 41);
- tcI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, 42);
+// tcI2C.pin_clk = Tokenizer_GetArgIntegerDefault(1, 41);
+// tcI2C.pin_data = Tokenizer_GetArgIntegerDefault(2, 42);
+ tcI2C.pin_clk = Tokenizer_GetPin(1, 41);
+ tcI2C.pin_data = Tokenizer_GetPin(2, 42);
tca_firstChannel = Tokenizer_GetArgIntegerDefault(3, 8);
tca_adr = Tokenizer_GetArgIntegerDefault(4, tca_adr);
diff --git a/src/driver/drv_tm_gn_display_shared.c b/src/driver/drv_tm_gn_display_shared.c
index ad91e4316..15c5aaa7d 100644
--- a/src/driver/drv_tm_gn_display_shared.c
+++ b/src/driver/drv_tm_gn_display_shared.c
@@ -607,8 +607,10 @@ void TM_GN_Display_SharedInit(tmGnType_t type) {
if (type == TMGN_HD2015) {
// startDriver HD2015 [CLK] [DAT]
// startDriver HD2015 11 24
- g_i2c.pin_clk = Tokenizer_GetArgIntegerDefault(1, 11); // A11
- g_i2c.pin_data = Tokenizer_GetArgIntegerDefault(2, 24); // B8
+// g_i2c.pin_clk = Tokenizer_GetArgIntegerDefault(1, 11); // A11
+// g_i2c.pin_data = Tokenizer_GetArgIntegerDefault(2, 24); // B8
+ g_i2c.pin_clk = Tokenizer_GetPin(1, 11); // A11
+ g_i2c.pin_data = Tokenizer_GetPin(2, 24); // B8
g_i2c.pin_stb = -1; // B3
g_totalDigits = 4;
// HD2015 has no remap
diff --git a/src/hal/ln882h/hal_pins_ln882h.c b/src/hal/ln882h/hal_pins_ln882h.c
index 0db3c6cdd..e4ad0b9f1 100644
--- a/src/hal/ln882h/hal_pins_ln882h.c
+++ b/src/hal/ln882h/hal_pins_ln882h.c
@@ -91,19 +91,6 @@ lnPinMapping_t g_pins[] = {
int g_numPins = sizeof(g_pins) / sizeof(g_pins[0]);
-int HAL_PIN_Find(const char *name) {
- if (isdigit(name[0])) {
- return atoi(name);
- }
- for (int i = 0; i < g_numPins; i++) {
- if (!stricmp(g_pins[i].name, name)) {
- return i;
- }
- }
- return -1;
-}
-
-
int PIN_GetPWMIndexForPinIndex(int pin) {
return -1;
}
diff --git a/src/hal/w800/hal_pins_w800.c b/src/hal/w800/hal_pins_w800.c
index 9810794d5..c0ebbf756 100644
--- a/src/hal/w800/hal_pins_w800.c
+++ b/src/hal/w800/hal_pins_w800.c
@@ -97,18 +97,6 @@ static wmPin_t g_pins[] = {
static int g_numPins = sizeof(g_pins) / sizeof(g_pins[0]);
-int HAL_PIN_Find(const char *name) {
- if (isdigit(name[0])) {
- return atoi(name);
- }
- for (int i = 0; i < g_numPins; i++) {
- if (!stricmp(g_pins[i].name, name)) {
- return i;
- }
- }
- return -1;
-}
-
static int IsPinIndexOk(int index) {
if (index < 0)
return 0;
diff --git a/src/hal/win32/hal_pins_win32.c b/src/hal/win32/hal_pins_win32.c
index fb2d7f4e6..2a86ce6d1 100644
--- a/src/hal/win32/hal_pins_win32.c
+++ b/src/hal/win32/hal_pins_win32.c
@@ -38,10 +38,6 @@ static int adcToGpio[] = {
};
static int c_adcToGpio = sizeof(adcToGpio)/sizeof(adcToGpio[0]);
-int HAL_PIN_Find(const char *name) {
- return atoi(name);
-}
-
static int gpioToAdc(int gpio) {
int i;
for (i = 0; i < c_adcToGpio; i++) {
@@ -177,6 +173,16 @@ const char *HAL_PIN_GetPinNameAlias(int index) {
return "RXD1";
if (index == 11)
return "TXD1";
+/*
+//######################### START TESTING PIN_Find only #########################
+ if (index == 13)
+ return "IO13/Test13/RRX13 XX13 15T";
+ if (index == 15)
+ return "IO15 151 X13(RX13)";
+ if (index == 14)
+ return "IO14 Test14 (X14/RX14/XX14)";
+//#########################' END TESTING PIN_Find only #'########################
+*/
return "N/A";
}
diff --git a/src/new_common.c b/src/new_common.c
index b9c850a86..0626f2679 100644
--- a/src/new_common.c
+++ b/src/new_common.c
@@ -301,6 +301,14 @@ int wal_strnicmp(const char* a, const char* b, int count) {
return ca - cb;
}
+char *wal_stristr(const char *haystack, const char *needle) {
+ size_t nlen = strlen(needle);
+ for (; *haystack; haystack++) {
+ if (wal_strnicmp(haystack, needle, nlen) == 0) return (char *)haystack;
+ }
+ return NULL;
+}
+
const char* skipToNextWord(const char* p) {
while (isWhiteSpace(*p) == false) {
if (*p == 0)
diff --git a/src/new_common.h b/src/new_common.h
index 6fbcd222f..7c2423b4e 100644
--- a/src/new_common.h
+++ b/src/new_common.h
@@ -1019,6 +1019,7 @@ char *strdup(const char *s);
const char* skipToNextWord(const char* p);
void stripDecimalPlaces(char *p, int maxDecimalPlaces);
int wal_stricmp(const char *a, const char *b);
+char *wal_stristr(const char *haystack, const char *needle);
int wal_strnicmp(const char *a, const char *b, int count);
int strcat_safe(char *tg, const char *src, int tgMaxLen);
int strcpy_safe(char *tg, const char *src, int tgMaxLen);
diff --git a/src/new_pins.c b/src/new_pins.c
index 9cda611c4..965cdfb33 100644
--- a/src/new_pins.c
+++ b/src/new_pins.c
@@ -2748,6 +2748,79 @@ int XJ_MovingAverage_int(int aprevvalue, int aactvalue) {
}
#endif
+
+// use "complete" search as default, only "simple" one for these platforms
+//#if !(PLATFORM_LN882H || PLATFORM_W800 || PLATFORM_TXW81X || (PLATFORM_ESPIDF && ! CONFIG_IDF_TARGET_ESP32C3))
+#if !(PLATFORM_LN882H || PLATFORM_TXW81X || (PLATFORM_ESPIDF && ! CONFIG_IDF_TARGET_ESP32C3))
+// start helpers for finding (su-)string in pinalias
+
+// code to find a pin index by name
+// we migth have "complex" or alternate names like
+// "IO0/A0" or even "IO2 (B2/TX1)" and would like all to match
+// so we need to make sure the substring is found an propperly "terminated"
+// by '\0', '/' , '(', ')' or ' '
+
+
+// Define valid start and end characters for a string (e.g. for "(RX1/IO10)" we would need "()/"
+int is_valid_start_end(char ch) {
+ // Check if character is in defined terminators
+ return strchr(" ()/\0", ch) != NULL;
+}
+
+// new version, case insensitive, use
+// wal_stricmp() and (new introduced) wal_stristr()
+// from new_common.c
+int str_match_in_alias(const char* alias, const char* str) {
+ size_t alen = strlen(alias), slen = strlen(str);
+
+ if (slen > alen) return 0; // No match
+
+ // found at start of alisa, no test for a valid "start"
+ if (wal_strnicmp(alias, str, slen) == 0) {
+ return (slen == alen || is_valid_start_end(alias[slen]));
+ }
+
+ // not at start, so found-1 is a valid position in string
+ for (char *found = wal_stristr(alias + 1, str); found; found = wal_stristr(found + 1, str)) {
+
+ if (is_valid_start_end(*(found - 1)) && (is_valid_start_end(found[slen]) || found[slen] == '\0')) {
+ return 1; // Match found
+ }
+ }
+
+ return 0; // No match
+}
+
+// END helpers
+
+int PIN_FindIndexFromString(const char *name) {
+ if (strIsInteger(name)) {
+ return atoi(name);
+ }
+ for (int i = 0; i < PLATFORM_GPIO_MAX; i++) {
+ if (str_match_in_alias(HAL_PIN_GetPinNameAlias(i), name)) {
+ return i;
+ }
+ }
+ return -1;
+}
+#else
+int PIN_FindIndexFromString(const char *name) {
+ if (strIsInteger(name)) {
+ return atoi(name);
+ }
+ for (int i = 0; i < PLATFORM_GPIO_MAX; i++) {
+ if (!stricmp(HAL_PIN_GetPinNameAlias(i), name)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+#endif
+
+
+
void PIN_AddCommands(void)
{
//cmddetail:{"name":"showgpi","args":"NULL",
diff --git a/src/new_pins.h b/src/new_pins.h
index 0761cbff7..85813558a 100644
--- a/src/new_pins.h
+++ b/src/new_pins.h
@@ -1665,4 +1665,9 @@ float XJ_MovingAverage_float(float aprevvalue, float aactvalue);
int XJ_MovingAverage_int(int aprevvalue, int aactvalue);
#endif
+// Find index of a pin from string.
+// Either a number or an alias for a pin.
+// used e.g. for Tokenizer_GetPin()
+int PIN_FindIndexFromString(const char *name);
+
#endif
diff --git a/src/selftest/selftest_local.h b/src/selftest/selftest_local.h
index a73d1c0e7..55989b512 100644
--- a/src/selftest/selftest_local.h
+++ b/src/selftest/selftest_local.h
@@ -155,6 +155,7 @@ void Test_PIR();
void Test_Driver_TCL_AC();
void Test_MAX72XX();
void Test_OpenWeatherMap();
+void Test_Pins();
void Test_GetJSONValue_Setup(const char *text);
void Test_FakeHTTPClientPacket_GET(const char *tg);
diff --git a/src/selftest/selftest_pins.c b/src/selftest/selftest_pins.c
new file mode 100644
index 000000000..536c8be7c
--- /dev/null
+++ b/src/selftest/selftest_pins.c
@@ -0,0 +1,56 @@
+#ifdef WINDOWS
+
+#include "selftest_local.h"
+
+void Test_Pins() {
+ // reset whole device
+ SIM_ClearOBK(0);
+
+/*
+we are testing against this alias definition
+
+const char *HAL_PIN_GetPinNameAlias(int index) {
+ // some of pins have special roles
+ if (index == 23)
+ return "ADC3";
+ if (index == 26)
+ return "PWM5";
+ if (index == 24)
+ return "PWM4";
+ if (index == 6)
+ return "PWM0";
+ if (index == 7)
+ return "PWM1";
+ if (index == 0)
+ return "TXD2";
+ if (index == 1)
+ return "RXD2";
+ if (index == 9)
+ return "PWM3";
+ if (index == 8)
+ return "PWM2";
+ if (index == 10)
+ return "RXD1";
+ if (index == 11)
+ return "TXD1";
+ return "N/A";
+}
+
+*/
+// printf("################################################################# Start Selftest PIN_FindIndexFromString() #################################################################\r\n");
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("TXD1"), 11);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("ADC3"), 23);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("TXD2"), 0);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("PWM0"), 6);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("PWM4"), 24);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("1"), 1);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("14"), 14);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("12A"), -1);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("A12"), -1);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("RXD"), -1);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("PWM"), -1);
+ SELFTEST_ASSERT_INTCOMPARE(PIN_FindIndexFromString("TDX2"),-1);
+// printf("################################################################## End Selftest PIN_FindIndexFromString() ##################################################################\r\n");
+}
+
+#endif
diff --git a/src/win_main.c b/src/win_main.c
index 24d1a6fba..4e70b6e37 100644
--- a/src/win_main.c
+++ b/src/win_main.c
@@ -291,6 +291,7 @@ void Win_DoUnitTests()
Test_LFS();
Test_Scripting();
Test_Tokenizer();
+ Test_Pins();
Test_Http();
Test_Http_LED();
Test_DeviceGroups();