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
This commit is contained in:
MaxineMuster
2026-01-20 14:38:40 +01:00
committed by GitHub
parent eee7ac2f8e
commit ff0941016b
25 changed files with 222 additions and 50 deletions

View File

@@ -836,6 +836,7 @@
<ClCompile Include="src\selftest\selftest_multiplePinsOnChannel.c" />
<ClCompile Include="src\selftest\selftest_ntp.c" />
<ClCompile Include="src\selftest\selftest_ntp_DST.c" />
<ClCompile Include="src\selftest\selftest_pins.c" />
<ClCompile Include="src\selftest\selftest_repeatingEvents.c" />
<ClCompile Include="src\selftest\selftest_role_toggleAll.c" />
<ClCompile Include="src\selftest\selftest_script.c" />

View File

@@ -277,6 +277,7 @@
<ClCompile Include="src\selftest\selftest_multiplePinsOnChannel.c" />
<ClCompile Include="src\selftest\selftest_ntp.c" />
<ClCompile Include="src\selftest\selftest_ntp_DST.c" />
<ClCompile Include="src\selftest\selftest_pins.c" />
<ClCompile Include="src\selftest\selftest_repeatingEvents.c" />
<ClCompile Include="src\selftest\selftest_role_toggleAll.c" />
<ClCompile Include="src\selftest\selftest_script.c" />
@@ -671,4 +672,4 @@
<CustomBuild Include="src\rgb2hsv.h" />
<CustomBuild Include="..\..\platforms\bk7231t\bk7231t_os\application.mk" />
</ItemGroup>
</Project>
</Project>

View File

@@ -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);

View File

@@ -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":"",

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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
#endif

View File

@@ -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);

View File

@@ -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);

View File

@@ -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":"",

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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";
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -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",

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -291,6 +291,7 @@ void Win_DoUnitTests()
Test_LFS();
Test_Scripting();
Test_Tokenizer();
Test_Pins();
Test_Http();
Test_Http_LED();
Test_DeviceGroups();