diff --git a/EnduranceTestBench/.cproject b/EnduranceTestBench/.cproject index 19b7ec6..3073a88 100644 --- a/EnduranceTestBench/.cproject +++ b/EnduranceTestBench/.cproject @@ -151,14 +151,14 @@ - + - + diff --git a/EnduranceTestBench/nehemis/enduranceTestBench.c b/EnduranceTestBench/nehemis/enduranceTestBench.c new file mode 100644 index 0000000..0f97b31 --- /dev/null +++ b/EnduranceTestBench/nehemis/enduranceTestBench.c @@ -0,0 +1,261 @@ +/** + * @file monitoring.c + * + * @copyright Nehemis SARL reserves all rights even in the event of industrial + * property rights. We reserve all rights of disposal such as + * copying and passing on to third parties. + * + * @brief + * + */ + +/****************************************************************************** + * Include Header Files + ******************************************************************************/ +#include "enduranceTestBench.h" +#include "hal_system.h" + +/* CANopen includes */ +#include +#include + +/****************************************************************************** + * Macro constant declarations + ******************************************************************************/ +#define ENDURANCE_TEST_BENCH_MAX_RETRY_CNT 5u +#define ENDURANCE_TEST_BENCH_TIMEOUT 1000u +#define ENDURANCE_TEST_BENCH_LSS_NODE_COUNT 20u +#define ENDURANCE_TEST_BENCH_POSITION_SETPOINT_INDEX 0x6002 +#define ENDURANCE_TEST_BENCH_POSITION_SETPOINT_SUB_INDEX 0x0 +#define ENDURANCE_TEST_BENCH_POSITION_FEEDBACK_INDEX 0x6004 +#define ENDURANCE_TEST_BENCH_POSITION_FEEDBACK_SUB_INDEX 0x0 +/****************************************************************************** + * Type Declarations + ******************************************************************************/ +typedef enum +{ + TEST_BENCH_STARTUP, + TEST_BENCH_IDLE, + TEST_BENCH_WRITE_REQUEST, + TEST_BENCH_WAIT_BEFORE_READ, + TEST_BENCH_WAIT_FOR_FEEDBACK, + TEST_BENCH_DELAY_BEFORE_NEXT +} SdlTestBenchState_en; +/****************************************************************************** + * Global variable declarations + ******************************************************************************/ +static uint8 currentNode_gu8 = 0u; +static SdlTestBenchState_en testBenchState_en = TEST_BENCH_IDLE; +static uint8 targetPositions_gau8[ENDURANCE_TEST_BENCH_LSS_NODE_COUNT]; + +/****************************************************************************** + * Public Function Definitions + ******************************************************************************/ + +void EnduranceTestBenchRun(void) +{ + static uint64 startTime_u64 = 0uLL; + static uint8 alternate_u8 = 0u; + static uint8 batchCompleted_u8 = 1u; /* Indicates if we need to populate a new batch */ + static uint8 retries_u8 = 0u; + uint64 currentTime_u64; + + HalSystemGetRunTimeMs(¤tTime_u64); + + if (startTime_u64 == 0uLL) + { + HalSystemGetRunTimeMs(&startTime_u64); + testBenchState_en = TEST_BENCH_STARTUP; + } + + switch (testBenchState_en) + { + case TEST_BENCH_STARTUP: + { + uint8 max_u8 = NMS_UINT8_MAX; /* Fully open (255) */ + uint8 min_u8 = 0u; /* Fully closed (0) */ + + if ((currentTime_u64 - startTime_u64) < 5000uLL) + { + /* First 5 seconds: First 10 open, rest closed */ + for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++) + { + targetPositions_gau8[i_u8] = (i_u8 < 10u) ? max_u8 : min_u8; + } + } + else if ((currentTime_u64 - startTime_u64) < 10000uLL) + { + /* Next 5 seconds: First 10 closed, rest open */ + for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++) + { + targetPositions_gau8[i_u8] = (i_u8 < 10) ? min_u8 : max_u8; + } + } + else + { + /* After 10 seconds, move to endurance test */ + batchCompleted_u8 = 1u; + testBenchState_en = TEST_BENCH_IDLE; + } + + currentNode_gu8 = 0u; + testBenchState_en = TEST_BENCH_WRITE_REQUEST; + } + break; + + case TEST_BENCH_IDLE: + { + if (batchCompleted_u8) + { + batchCompleted_u8 = 0u; /* Lock batch update until all nodes confirm their positions */ + + uint8 max_u8 = NMS_UINT8_MAX; /* Fully open (255) */ + uint8 min_u8 = 0u; /* Fully closed (0) */ + uint8 currentGroup_u8 = alternate_u8 % 2; /* Alternates between two patterns */ + + /* Check if it's a random cycle */ + if ((alternate_u8 % 2) == 1) + { + /* Randomized cycle */ + for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++) + { + targetPositions_gau8[i_u8] = (uint8)(rand() % 256); /* Assign random value between 0-255 */ + } + } + else + { + /* Normal alternating open-close cycle */ + for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++) + { + if (((i_u8 / 5) % 2) == currentGroup_u8) + { + targetPositions_gau8[i_u8] = max_u8; /* Fully open */ + } + else + { + targetPositions_gau8[i_u8] = min_u8; /* Fully closed */ + } + } + } + + alternate_u8++; /* Switch to the next cycle pattern */ + currentNode_gu8 = 0u; + testBenchState_en = TEST_BENCH_WRITE_REQUEST; + } + } + break; + + + case TEST_BENCH_WRITE_REQUEST: + { + if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT) + { + RET_T retVal_en = coSdoWrite((currentNode_gu8 + 1), ENDURANCE_TEST_BENCH_POSITION_SETPOINT_INDEX, ENDURANCE_TEST_BENCH_POSITION_SETPOINT_SUB_INDEX, + &targetPositions_gau8[currentNode_gu8], sizeof(targetPositions_gau8[currentNode_gu8]), + CO_FALSE, ENDURANCE_TEST_BENCH_TIMEOUT); + + if (retVal_en == RET_OK) + { + retries_u8 = 0u; + HalSystemGetRunTimeMs(&startTime_u64); + testBenchState_en = TEST_BENCH_WAIT_BEFORE_READ; + } + else if (retVal_en == RET_SERVICE_BUSY) + { + retries_u8++; + if (retries_u8 < 5u) + { + printf("SDO Busy for node %d, retrying...\n", currentNode_gu8 + 1); + } + else + { + currentNode_gu8++; /* Skip this node */ + testBenchState_en = TEST_BENCH_WRITE_REQUEST; + } + } + else + { + currentNode_gu8++; /* Skip this node */ + testBenchState_en = TEST_BENCH_WRITE_REQUEST; + } + } + else + { + batchCompleted_u8 = 1u; + testBenchState_en = TEST_BENCH_IDLE; + } + } + break; + + case TEST_BENCH_WAIT_BEFORE_READ: + { + HalSystemGetRunTimeMs(¤tTime_u64); + + if ((currentTime_u64 - startTime_u64) >= 2000uLL) /* Wait for a predefined settling time */ + { + testBenchState_en = TEST_BENCH_WAIT_FOR_FEEDBACK; + } + } + break; + + case TEST_BENCH_WAIT_FOR_FEEDBACK: + { + uint8 readPos_u8 = 0u; + RET_T retVal_en = coSdoRead((currentNode_gu8 + 1), ENDURANCE_TEST_BENCH_POSITION_FEEDBACK_INDEX, ENDURANCE_TEST_BENCH_POSITION_FEEDBACK_SUB_INDEX, + &readPos_u8, sizeof(readPos_u8), CO_FALSE, ENDURANCE_TEST_BENCH_TIMEOUT); + + if (retVal_en == RET_OK) + { + if (readPos_u8 == targetPositions_gau8[currentNode_gu8]) + { + printf("Node %d reached target position %d\n", currentNode_gu8 + 1, readPos_u8); + currentNode_gu8++; + retries_u8 = 0u; /* Reset retries */ + + if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT) + { + HalSystemGetRunTimeMs(&startTime_u64); /* Store time before sending the next command */ + testBenchState_en = TEST_BENCH_DELAY_BEFORE_NEXT; + } + else + { + batchCompleted_u8 = 1u; + testBenchState_en = TEST_BENCH_IDLE; + } + } + } + else + { + retries_u8++; + if (retries_u8 >= ENDURANCE_TEST_BENCH_MAX_RETRY_CNT) + { + currentNode_gu8++; + + if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT) + { + HalSystemGetRunTimeMs(&startTime_u64); + testBenchState_en = TEST_BENCH_DELAY_BEFORE_NEXT; + } + else + { + batchCompleted_u8 = 1u; + testBenchState_en = TEST_BENCH_IDLE; + } + } + } + } + break; + + case TEST_BENCH_DELAY_BEFORE_NEXT: + { + HalSystemGetRunTimeMs(¤tTime_u64); + + if ((currentTime_u64 - startTime_u64) >= ENDURANCE_TEST_BENCH_TIMEOUT) + { + testBenchState_en = TEST_BENCH_WRITE_REQUEST; + } + } + break; + + } +} diff --git a/EnduranceTestBench/nehemis/monitoring.h b/EnduranceTestBench/nehemis/enduranceTestBench.h similarity index 66% rename from EnduranceTestBench/nehemis/monitoring.h rename to EnduranceTestBench/nehemis/enduranceTestBench.h index 23e0270..2186d83 100644 --- a/EnduranceTestBench/nehemis/monitoring.h +++ b/EnduranceTestBench/nehemis/enduranceTestBench.h @@ -9,15 +9,22 @@ * */ -#ifndef MONITORING_H_ -#define MONITORING_H_ +#ifndef ENDURANCETESTBENCH_H_ +#define ENDURANCETESTBENCH_H_ /****************************************************************************** * Include Header Files ******************************************************************************/ #include "nms_types.h" -void MonitoringRun(void); +/** +* @brief This is the main function that runs the endurance +* test bench. +* +* @return void +* +*/ +void EnduranceTestBenchRun(void); -#endif /* MONITORING_H_ */ +#endif /* ENDURANCETESTBENCH_H_ */ diff --git a/EnduranceTestBench/nehemis/monitoring.c b/EnduranceTestBench/nehemis/monitoring.c deleted file mode 100644 index 1e33bce..0000000 --- a/EnduranceTestBench/nehemis/monitoring.c +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file monitoring.c - * - * @copyright Nehemis SARL reserves all rights even in the event of industrial - * property rights. We reserve all rights of disposal such as - * copying and passing on to third parties. - * - * @brief - * - */ - -/****************************************************************************** - * Include Header Files - ******************************************************************************/ -#include "monitoring.h" - -/* CANopen includes */ -#include -#include -/****************************************************************************** - * Macro constant declarations - ******************************************************************************/ - -/****************************************************************************** - * Global variable declarations - ******************************************************************************/ -static bool appSleep_b = CO_FALSE; /**< application sleep flag */ -static CO_NMT_STATE_T nodeNMTState_gau[3]; /**< saved NMT states */ -/****************************************************************************** - * Public Function Definitions - ******************************************************************************/ -void MonitoringRun(void) -{ - uint8 arrIndex_u8; - if (appSleep_b != CO_TRUE) - { - for (arrIndex_u8 = 0u; arrIndex_u8 < 3; arrIndex_u8++) - { - if (nodeNMTState_gau[arrIndex_u8] == CO_NMT_STATE_PREOP) - { - LssConfigureNode(arrIndex_u8); - } - if (nodeNMTState[arrIndex] == CO_NMT_STATE_OPERATIONAL) - { - /* Do nothing */ - } - } - } - appSleep_b = CO_TRUE; -} diff --git a/EnduranceTestBench/scheduler/sdl.c b/EnduranceTestBench/scheduler/sdl.c index cf9d77f..19560ea 100644 --- a/EnduranceTestBench/scheduler/sdl.c +++ b/EnduranceTestBench/scheduler/sdl.c @@ -24,6 +24,7 @@ /* User includes */ #include "sdl.h" #include "processBoard.h" +#include "enduranceTestBench.h" #include "hal_system.h" #include "stdlib.h" @@ -51,15 +52,6 @@ #define SDL_SDO_CLIENT_COB 0x1280 #define SDL_SDO_CLIENT_TO_SERVER_COB 0x600 #define SDL_SDO_SERVER_TO_CLIENT_COB 0x580 - - -#define TEST_BENCH_MAX_RETRY_CNT 5u -#define TEST_BENCH_TIMEOUT 1000u -#define TEST_BENCH_LSS_NODE_COUNT 20u -#define TEST_BENCH_POSITION_SETPOINT_INDEX 0x6002 -#define TEST_BENCH_POSITION_SETPOINT_SUB_INDEX 0x0 -#define TEST_BENCH_POSITION_FEEDBACK_INDEX 0x6004 -#define TEST_BENCH_POSITION_FEEDBACK_SUB_INDEX 0x0 /****************************************************************************** * Type Declarations ******************************************************************************/ @@ -72,16 +64,6 @@ typedef struct uint8 nodeId_u8; } SdlLssNodeInfo_t; -typedef enum -{ - TEST_BENCH_STARTUP, - TEST_BENCH_IDLE, - TEST_BENCH_WRITE_REQUEST, - TEST_BENCH_WAIT_BEFORE_READ, - TEST_BENCH_WAIT_FOR_FEEDBACK, - TEST_BENCH_DELAY_BEFORE_NEXT -} SdlTestBenchState_en; - /****************************************************************************** * Global Declarations ******************************************************************************/ @@ -114,9 +96,7 @@ static const SdlLssNodeInfo_t nodeLookupTable_gast[SDL_LSS_NODE_COUNT] = {0x319, 0x4d2, 0x1, 0x14, 0x18} }; static CO_NMT_STATE_T nodeNMTState_gaen[SDL_LSS_NODE_COUNT]; -static SdlTestBenchState_en testBenchState_en = TEST_BENCH_IDLE; -static uint8 targetPositions_gau8[SDL_LSS_NODE_COUNT]; -static uint8 currentNode_gu8 = 0u; + /****************************************************************************** * Static function Declarations ******************************************************************************/ @@ -136,7 +116,7 @@ static RET_T SdlLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8); * for the TPDO. */ extern void userOverwriteCobIdSettings(void); static bool SdlAreAllNodesOperational(void); -static void SdlEnduranceTestBenchRun(void); + /****************************************************************************** * Public Function Definitions ******************************************************************************/ @@ -152,7 +132,7 @@ void SdlRun(void) SdlLssNodeHandlerRun(); if (SdlAreAllNodesOperational()) { - SdlEnduranceTestBenchRun(); + EnduranceTestBenchRun(); } } @@ -195,11 +175,6 @@ static void SdlRunCanopen(void) { coCommTask(); SdlLssNodeHandlerRun(); - if(SdlAreAllNodesOperational()) - { - SdlEnduranceTestBenchRun(); - } - } @@ -384,222 +359,6 @@ static RET_T SdlLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8) } -/** -* @brief This is the main function that runs the endurance -* test bench. -* -* @return void -* -*/ -void SdlEnduranceTestBenchRun(void) -{ - static uint64 startTime_u64 = 0uLL; - static uint8 alternate_u8 = 0u; - static uint8 batchCompleted_u8 = 1u; /* Indicates if we need to populate a new batch */ - static uint8 retries_u8 = 0u; - uint64 currentTime_u64; - - HalSystemGetRunTimeMs(¤tTime_u64); - - if (startTime_u64 == 0uLL) - { - HalSystemGetRunTimeMs(&startTime_u64); - testBenchState_en = TEST_BENCH_STARTUP; - } - - switch (testBenchState_en) - { - case TEST_BENCH_STARTUP: - { - uint8 max_u8 = NMS_UINT8_MAX; /* Fully open (255) */ - uint8 min_u8 = 0u; /* Fully closed (0) */ - - if ((currentTime_u64 - startTime_u64) < 5000uLL) - { - /* First 5 seconds: First 10 open, rest closed */ - for (uint8 i_u8 = 0u; i_u8 < TEST_BENCH_LSS_NODE_COUNT; i_u8++) - { - targetPositions_gau8[i_u8] = (i_u8 < 10u) ? max_u8 : min_u8; - } - } - else if ((currentTime_u64 - startTime_u64) < 10000uLL) - { - /* Next 5 seconds: First 10 closed, rest open */ - for (uint8 i_u8 = 0u; i_u8 < TEST_BENCH_LSS_NODE_COUNT; i_u8++) - { - targetPositions_gau8[i_u8] = (i_u8 < 10) ? min_u8 : max_u8; - } - } - else - { - /* After 10 seconds, move to endurance test */ - batchCompleted_u8 = 1u; - testBenchState_en = TEST_BENCH_IDLE; - } - - currentNode_gu8 = 0u; - testBenchState_en = TEST_BENCH_WRITE_REQUEST; - } - break; - - case TEST_BENCH_IDLE: - { - if (batchCompleted_u8) - { - batchCompleted_u8 = 0u; /* Lock batch update until all nodes confirm their positions */ - - uint8 max_u8 = NMS_UINT8_MAX; /* Fully open (255) */ - uint8 min_u8 = 0u; /* Fully closed (0) */ - uint8 currentGroup_u8 = alternate_u8 % 2; /* Alternates between two patterns */ - - /* Check if it's a random cycle */ - if ((alternate_u8 % 2) == 1) - { - /* Randomized cycle */ - for (uint8 i_u8 = 0u; i_u8 < TEST_BENCH_LSS_NODE_COUNT; i_u8++) - { - targetPositions_gau8[i_u8] = (uint8)(rand() % 256); /* Assign random value between 0-255 */ - } - } - else - { - /* Normal alternating open-close cycle */ - for (uint8 i_u8 = 0u; i_u8 < TEST_BENCH_LSS_NODE_COUNT; i_u8++) - { - if (((i_u8 / 5) % 2) == currentGroup_u8) - { - targetPositions_gau8[i_u8] = max_u8; /* Fully open */ - } - else - { - targetPositions_gau8[i_u8] = min_u8; /* Fully closed */ - } - } - } - - alternate_u8++; /* Switch to the next cycle pattern */ - currentNode_gu8 = 0u; - testBenchState_en = TEST_BENCH_WRITE_REQUEST; - } - } - break; - - - case TEST_BENCH_WRITE_REQUEST: - { - if (currentNode_gu8 < TEST_BENCH_LSS_NODE_COUNT) - { - RET_T retVal_en = coSdoWrite((currentNode_gu8 + 1), SDL_POSITION_SETPOINT_INDEX, SDL_POSITION_SETPOINT_SUB_INDEX, - &targetPositions_gau8[currentNode_gu8], sizeof(targetPositions_gau8[currentNode_gu8]), - CO_FALSE, TEST_BENCH_TIMEOUT); - - if (retVal_en == RET_OK) - { - retries_u8 = 0u; - HalSystemGetRunTimeMs(&startTime_u64); - testBenchState_en = TEST_BENCH_WAIT_BEFORE_READ; - } - else if (retVal_en == RET_SERVICE_BUSY) - { - retries_u8++; - if (retries_u8 < 5u) - { - printf("SDO Busy for node %d, retrying...\n", currentNode_gu8 + 1); - } - else - { - currentNode_gu8++; /* Skip this node */ - testBenchState_en = TEST_BENCH_WRITE_REQUEST; - } - } - else - { - currentNode_gu8++; /* Skip this node */ - testBenchState_en = TEST_BENCH_WRITE_REQUEST; - } - } - else - { - batchCompleted_u8 = 1u; - testBenchState_en = TEST_BENCH_IDLE; - } - } - break; - - case TEST_BENCH_WAIT_BEFORE_READ: - { - HalSystemGetRunTimeMs(¤tTime_u64); - - if ((currentTime_u64 - startTime_u64) >= 2000uLL) /* Wait for a predefined settling time */ - { - testBenchState_en = TEST_BENCH_WAIT_FOR_FEEDBACK; - } - } - break; - - case TEST_BENCH_WAIT_FOR_FEEDBACK: - { - uint8 readPos_u8 = 0u; - RET_T retVal_en = coSdoRead((currentNode_gu8 + 1), TEST_BENCH_POSITION_FEEDBACK_INDEX, TEST_BENCH_POSITION_FEEDBACK_SUB_INDEX, - &readPos_u8, sizeof(readPos_u8), CO_FALSE, TEST_BENCH_TIMEOUT); - - if (retVal_en == RET_OK) - { - if (readPos_u8 == targetPositions_gau8[currentNode_gu8]) - { - printf("Node %d reached target position %d\n", currentNode_gu8 + 1, readPos_u8); - currentNode_gu8++; - retries_u8 = 0u; /* Reset retries */ - - if (currentNode_gu8 < TEST_BENCH_LSS_NODE_COUNT) - { - HalSystemGetRunTimeMs(&startTime_u64); /* Store time before sending the next command */ - testBenchState_en = TEST_BENCH_DELAY_BEFORE_NEXT; - } - else - { - batchCompleted_u8 = 1u; - testBenchState_en = TEST_BENCH_IDLE; - } - } - } - else - { - retries_u8++; - if (retries_u8 >= TEST_BENCH_MAX_RETRY_CNT) - { - currentNode_gu8++; - - if (currentNode_gu8 < TEST_BENCH_LSS_NODE_COUNT) - { - HalSystemGetRunTimeMs(&startTime_u64); - testBenchState_en = TEST_BENCH_DELAY_BEFORE_NEXT; - } - else - { - batchCompleted_u8 = 1u; - testBenchState_en = TEST_BENCH_IDLE; - } - } - } - } - break; - - case TEST_BENCH_DELAY_BEFORE_NEXT: - { - HalSystemGetRunTimeMs(¤tTime_u64); - - if ((currentTime_u64 - startTime_u64) >= TEST_BENCH_TIMEOUT) - { - testBenchState_en = TEST_BENCH_WRITE_REQUEST; - } - } - break; - - } -} - - /** * @brief Checks if all nodes are in OPERATIONAL state. *