Compare commits

..

No commits in common. "1d8f6d6b4fa1446d1823ea9fec55f27fb3fe19d7" and "7ccde7933ff9dd5bd80b5378c81680171f9405fc" have entirely different histories.

6 changed files with 599 additions and 1029 deletions

View File

@ -65,8 +65,9 @@ typedef struct
* Global variable declarations * Global variable declarations
******************************************************************************/ ******************************************************************************/
static uint8 currentNode_gu8 = 0u; static uint8 currentNode_gu8 = 0u;
static uint8 batchCompleted_u8 = 1u;
static uint32 readPosition_gu32 = 0u; static uint32 readPosition_gu32 = 0u;
static uint8 targetPositionStoredFlag_u8 = 0u;
static TestBenchData_en testBenchData_en; static TestBenchData_en testBenchData_en;
static SdlTestBenchState_en testBenchState_en = TEST_BENCH_IDLE; static SdlTestBenchState_en testBenchState_en = TEST_BENCH_IDLE;
@ -75,7 +76,7 @@ static uint64 writeTime_u64;
/****************************************************************************** /******************************************************************************
* Public Function Definitions * Public Function Definitions
******************************************************************************/ ******************************************************************************/
void EnduranceTestBenchRun(bool *testBenchStarted_pb) void EnduranceTestBenchRun(void)
{ {
static uint64 startTime_u64 = 0uLL; static uint64 startTime_u64 = 0uLL;
static uint8 alternate_u8 = 0u; static uint8 alternate_u8 = 0u;
@ -116,6 +117,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
else else
{ {
/* After 10 seconds, move to endurance test */ /* After 10 seconds, move to endurance test */
batchCompleted_u8 = 1u;
testBenchState_en = TEST_BENCH_IDLE; testBenchState_en = TEST_BENCH_IDLE;
} }
@ -126,45 +128,43 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
case TEST_BENCH_IDLE: case TEST_BENCH_IDLE:
{ {
*testBenchStarted_pb = true; if (batchCompleted_u8)
uint8 max_u8 = NMS_UINT8_MAX; /* Fully open (255) */ {
uint8 min_u8 = 0u; /* Fully closed (0) */ batchCompleted_u8 = 0u; /* Lock batch update until all nodes confirm their positions */
uint8 currentGroup_u8 = alternate_u8 % 2; /* Alternates between two patterns */
/* Check if it's a random cycle */ uint8 max_u8 = NMS_UINT8_MAX; /* Fully open (255) */
if ((alternate_u8 % 2) == 1) uint8 min_u8 = 0u; /* Fully closed (0) */
{ uint8 currentGroup_u8 = alternate_u8 % 2; /* Alternates between two patterns */
/* Randomized cycle */
for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++) /* Check if it's a random cycle */
{ if ((alternate_u8 % 2) == 1)
testBenchData_en.targetPositions_gau8[i_u8] = (uint8)(rand() % 256); /* Assign random value between 0-255 */ {
} /* Randomized cycle */
} for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++)
else {
{ testBenchData_en.targetPositions_gau8[i_u8] = (uint8)(rand() % 256); /* Assign random value between 0-255 */
/* Normal alternating open-close cycle */ }
for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++) }
{ else
if (((i_u8 / 5) % 2) == currentGroup_u8) {
{ /* Normal alternating open-close cycle */
testBenchData_en.targetPositions_gau8[i_u8] = max_u8; /* Fully open */ for (uint8 i_u8 = 0u; i_u8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i_u8++)
} {
else if (((i_u8 / 5) % 2) == currentGroup_u8)
{ {
if (i_u8 % 5u == 4u) /* Last node of the group */ testBenchData_en.targetPositions_gau8[i_u8] = max_u8; /* Fully open */
{ }
testBenchData_en.targetPositions_gau8[i_u8] = max_u8; /* 255 for the last node */ else
} {
else testBenchData_en.targetPositions_gau8[i_u8] = min_u8; /* Fully closed */
{ }
testBenchData_en.targetPositions_gau8[i_u8] = min_u8; /* 0 for the other nodes */ }
} }
}
} alternate_u8++; /* Switch to the next cycle pattern */
} currentNode_gu8 = 0u;
alternate_u8++; /* Switch to the next cycle pattern */ testBenchState_en = TEST_BENCH_BATCH_WRITE;
currentNode_gu8 = 0u; }
testBenchState_en = TEST_BENCH_BATCH_WRITE;
} }
break; break;
@ -173,18 +173,24 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
{ {
if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT) if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT)
{ {
if (targetPositionStoredFlag_u8 == 0u)
{
uint8 value_u8 = (uint8)(rand() % 256);
RET_T retVal_en = coSdoWrite( RET_T retVal_en = coSdoWrite(
(currentNode_gu8 + 1), (currentNode_gu8 + 1),
ENDURANCE_TEST_BENCH_POSITION_SETPOINT_INDEX, ENDURANCE_TEST_BENCH_POSITION_SETPOINT_INDEX,
ENDURANCE_TEST_BENCH_POSITION_SETPOINT_SUB_INDEX, ENDURANCE_TEST_BENCH_POSITION_SETPOINT_SUB_INDEX,
&testBenchData_en.targetPositions_gau8[currentNode_gu8], &value_u8,
sizeof(uint8), sizeof(value_u8),
CO_FALSE, CO_FALSE,
ENDURANCE_TEST_BENCH_TIMEOUT ENDURANCE_TEST_BENCH_TIMEOUT
); );
if (retVal_en == RET_OK) if (retVal_en == RET_OK)
{ {
testBenchData_en.targetPositions_gau8[currentNode_gu8] = value_u8;
targetPositionStoredFlag_u8 = 1; /* Mark that target is written for this node */
HalSystemGetRunTimeMs(&writeTime_u64); HalSystemGetRunTimeMs(&writeTime_u64);
retries_u8 = 0u; retries_u8 = 0u;
testBenchState_en = TEST_BENCH_BATCH_WRITE_WAIT; testBenchState_en = TEST_BENCH_BATCH_WRITE_WAIT;
@ -199,11 +205,12 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
/* Mark node as skipped and move on */ /* Mark node as skipped and move on */
currentNode_gu8++; currentNode_gu8++;
retries_u8 = 0u; retries_u8 = 0u;
targetPositionStoredFlag_u8 = 0u;
testBenchState_en = TEST_BENCH_BATCH_WRITE; testBenchState_en = TEST_BENCH_BATCH_WRITE;
} }
} }
} }
}
else else
{ {
/* Finished writing to all nodes */ /* Finished writing to all nodes */
@ -220,6 +227,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
{ {
/* Move to next node write */ /* Move to next node write */
currentNode_gu8++; currentNode_gu8++;
targetPositionStoredFlag_u8 = 0u; /* Reset for next node */
testBenchState_en = TEST_BENCH_BATCH_WRITE; testBenchState_en = TEST_BENCH_BATCH_WRITE;
} }
break; break;
@ -292,7 +300,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
if (testBenchData_en.status_en[currentNode_gu8] != TEST_BENCH_DATA_NODE_SKIPPED) if (testBenchData_en.status_en[currentNode_gu8] != TEST_BENCH_DATA_NODE_SKIPPED)
{ {
if (abs(testBenchData_en.targetPositions_gau8[currentNode_gu8] - if (abs(testBenchData_en.targetPositions_gau8[currentNode_gu8] -
testBenchData_en.readPosition_gau8[currentNode_gu8]) <= 5u) /* Accepted difference between read and write for successful operation */ testBenchData_en.readPosition_gau8[currentNode_gu8]) <= 5) /* Accepted difference between read and write for successful operation */
{ {
testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_VERIF_SUCCESS; testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_VERIF_SUCCESS;
} }
@ -327,8 +335,9 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
/* Reset everything and Start next cycle */ /* Reset everything and Start next cycle */
currentNode_gu8 = 0u; currentNode_gu8 = 0u;
targetPositionStoredFlag_u8 = 0u;
retries_u8 = 0u; retries_u8 = 0u;
testBenchState_en = TEST_BENCH_IDLE; testBenchState_en = TEST_BENCH_BATCH_WRITE;
break; break;
} }

View File

@ -24,7 +24,7 @@
* @return void * @return void
* *
*/ */
void EnduranceTestBenchRun(bool *testBenchStarted_b); void EnduranceTestBenchRun(void);
void EnduranceTestBenchWriteInd(uint8 sdoNr_u8, uint16 index_u16, uint8 subIndex_u8, uint32 errorVal_u32); void EnduranceTestBenchWriteInd(uint8 sdoNr_u8, uint16 index_u16, uint8 subIndex_u8, uint32 errorVal_u32);

View File

@ -19,7 +19,6 @@
#include "od_entries.h" #include "od_entries.h"
#include "nms_can.h" #include "nms_can.h"
#include "analogMeasurement.h" #include "analogMeasurement.h"
#include "hal_system.h"
/****************************************************************************** /******************************************************************************
* Type declarations * Type declarations
******************************************************************************/ ******************************************************************************/
@ -35,14 +34,6 @@
#define PU_CANOPEN_SLAVE_LINE 0u #define PU_CANOPEN_SLAVE_LINE 0u
#define PU_CANOPEN_MASTER_LINE 1u #define PU_CANOPEN_MASTER_LINE 1u
#define PU_PUMP_SPEED_CHANGE_INTERVAL 900000uLL
#define PU_PUMP_MAX_SPEED 10u
#define PU_PUMP_MIN_SPEED 0u
#define PU_PMP_ENABLE 1u
#define PU_PMP_DISABLE 0u
/****************************************************************************** /******************************************************************************
* Global variables * Global variables
******************************************************************************/ ******************************************************************************/
@ -92,8 +83,6 @@ static void ProcessBoardGrundfosPumpHandler(void);
******************************************************************************/ ******************************************************************************/
void ProcessBoardInit(void) void ProcessBoardInit(void)
{ {
HalSystemInit();
AnalogMeasurementInit();
motorCmd_gu8 = 0u; motorCmd_gu8 = 0u;
/* Initializing the structures (Pressure sensor, Flow /* Initializing the structures (Pressure sensor, Flow
@ -171,50 +160,88 @@ void ProcessBoardRun(void)
/****************************************************************************** /******************************************************************************
* Private function definitions * Private function definitions
******************************************************************************/ ******************************************************************************/
//static void ProcessBoardGrundfosPumpHandler(void)
//{
// uint32 pmpSpeed_u32 = 0uL;
// uint8 mode_u8 = 0u;
// uint8 speed_u8 = 0u;
//
// NmsCanGetObj_u8(OD_ENTRY_PU_GRUNDFOS_PUMP_CONTROL_INDEX, OD_ENTRY_PU_GRUNDFOS_PUMP_ENABLE_SUB_INDEX, &mode_u8);
// NmsCanGetObj_u8(OD_ENTRY_PU_GRUNDFOS_PUMP_CONTROL_INDEX, OD_ENTRY_PU_GRUNDFOS_PUMP_SET_SPEED_SUB_INDEX, &speed_u8);
//
// GrundfosPmpEnable(mode_u8);
// if(mode_u8 == 1u)
// {
// GrundfosPmpSetSpeed(speed_u8);
// /* Grundfos Pump feedback speed OUT */
// pmpSpeed_u32 = GrundfosPmpFeedbackSpeed(PMP_ADC_CHANNEL);
// }
// else
// {
// pmpSpeed_u32 = 0uL;
// }
// ProcessBoardPumpSpeedDataOUT(pmpSpeed_u32);
//}
static void ProcessBoardGrundfosPumpHandler(void) static void ProcessBoardGrundfosPumpHandler(void)
{ {
static uint32 pmpSpeed_u32 = 0uL; uint32 pmpSpeed_u32 = 0uL;
static uint8 speed_u8 = 0u; uint8 mode_u8 = 0u;
static uint64 startTime_u64 = 0uLL; static uint8 speed_u8 = 0u;
uint64 currentTimeMs_u64; static uint32 elapsedTime_s = 0u;
static enum { INCREASING, DECREASING } speedState = INCREASING;
HalSystemGetRunTimeMs(&currentTimeMs_u64); NmsCanGetObj_u8(OD_ENTRY_PU_GRUNDFOS_PUMP_CONTROL_INDEX, OD_ENTRY_PU_GRUNDFOS_PUMP_ENABLE_SUB_INDEX, &mode_u8);
if (startTime_u64 == 0uLL) // Only modify speed every 15 minutes (900 seconds)
if (elapsedTime_s >= 900)
{ {
HalSystemGetRunTimeMs(&startTime_u64); elapsedTime_s = 0; // Reset time counter
if (speedState == INCREASING)
{
if (speed_u8 < 10)
{
speed_u8 += 2;
}
if (speed_u8 >= 10)
{
speedState = DECREASING; // Switch to decreasing mode
}
}
else // DECREASING
{
if (speed_u8 > 0)
{
speed_u8 -= 2;
}
if (speed_u8 == 0)
{
speedState = INCREASING; // Switch back to increasing mode
}
}
}
else
{
elapsedTime_s++; // Increment elapsed time
} }
GrundfosPmpEnable(PU_PMP_ENABLE); GrundfosPmpEnable(mode_u8);
if (mode_u8 == 1u)
if ((currentTimeMs_u64 - startTime_u64) >= PU_PUMP_SPEED_CHANGE_INTERVAL)
{ {
// Update speed
if (speed_u8 < PU_PUMP_MAX_SPEED)
{
speed_u8 += 2u;
}
else
{
speed_u8 = PU_PUMP_MIN_SPEED;
}
GrundfosPmpSetSpeed(speed_u8); GrundfosPmpSetSpeed(speed_u8);
startTime_u64 = currentTimeMs_u64;
/* Grundfos Pump feedback speed OUT */ /* Grundfos Pump feedback speed OUT */
pmpSpeed_u32 = GrundfosPmpFeedbackSpeed(PMP_ADC_CHANNEL); pmpSpeed_u32 = GrundfosPmpFeedbackSpeed(PMP_ADC_CHANNEL);
/* To be verified */
if (pmpSpeed_u32 > PU_PUMP_MAX_SPEED)
{
GrundfosPmpEnable(PU_PMP_DISABLE);
}
} }
else
{
pmpSpeed_u32 = 0uL;
}
ProcessBoardPumpSpeedDataOUT(pmpSpeed_u32);
} }
static void ProcessBoardTriggerMvPosCtrl(uint8 motorId_u8, uint8 posData_u8) static void ProcessBoardTriggerMvPosCtrl(uint8 motorId_u8, uint8 posData_u8)
{ {

View File

@ -1,17 +1,17 @@
///** /**
// * @file nms_can.c * @file nms_can.c
// * *
// * @copyright Nehemis SARL reserves all rights even in the event of industrial * @copyright Nehemis SARL reserves all rights even in the event of industrial
// * property rights. We reserve all rights of disposal such as * property rights. We reserve all rights of disposal such as
// * copying and passing on to third parties. * copying and passing on to third parties.
// * *
// * @brief Source code for CANOpen files abstracted for furthur use in the project. * @brief Source code for CANOpen files abstracted for furthur use in the project.
// * *
// */ */
//
///****************************************************************************** /******************************************************************************
// * Include Header Files * Include Header Files
// ******************************************************************************/ ******************************************************************************/
#include "nms_can.h" #include "nms_can.h"
#include "enduranceTestBench.h" #include "enduranceTestBench.h"
@ -21,14 +21,14 @@
#include "co_sdo.h" #include "co_sdo.h"
#include "co_pdo.h" #include "co_pdo.h"
#include "co_odaccess.h" #include "co_odaccess.h"
//
///****************************************************************************** /******************************************************************************
// * Global Variable Declaration * Global Variable Declaration
// ******************************************************************************/ ******************************************************************************/
//
///****************************************************************************** /******************************************************************************
// * Macro constant declarations * Macro constant declarations
// ******************************************************************************/ ******************************************************************************/
#define NMS_CAN_CANOPEN_SLAVE_LINE 0u #define NMS_CAN_CANOPEN_SLAVE_LINE 0u
#define NMS_CAN_CANOPEN_MASTER_LINE 1u #define NMS_CAN_CANOPEN_MASTER_LINE 1u
@ -50,103 +50,103 @@
#define NMS_CAN_SDO_RECEIVE 0x600u #define NMS_CAN_SDO_RECEIVE 0x600u
#define NMS_CAN_SDO_PARAM_INDEX 0x1280u #define NMS_CAN_SDO_PARAM_INDEX 0x1280u
#define NMS_LSS_NODE_COUNT 20u #define NMS_LSS_NODE_COUNT 20u
///****************************************************************************** /******************************************************************************
// * Type Declarations * Type Declarations
// ******************************************************************************/ ******************************************************************************/
//typedef struct typedef struct
//{ {
// uint32 vendorId_u32; uint32 vendorId_u32;
// uint32 productId_u32; uint32 productId_u32;
// uint32 versionNbr_u32; uint32 versionNbr_u32;
// uint32 serialNbr_u32; uint32 serialNbr_u32;
// uint8 nodeId_u8; uint8 nodeId_u8;
//} SdlLssNodeInfo_t; } SdlLssNodeInfo_t;
///****************************************************************************** /******************************************************************************
// * Global Declarations * Global Declarations
// ******************************************************************************/ ******************************************************************************/
//SdlLssNodeInfo_t var_gst; SdlLssNodeInfo_t var_gst;
//static CO_TIMER_T monitorTimer_gst; /**< application timer */ static CO_TIMER_T monitorTimer_gst; /**< application timer */
//static bool monitorSleep_gb = CO_FALSE; /**< sleep flag */ static bool monitorSleep_gb = CO_FALSE; /**< sleep flag */
//static bool masterStarted_gb; /**< master started flag */ static bool masterStarted_gb; /**< master started flag */
//static const SdlLssNodeInfo_t nodeLookupTable_gast[NMS_LSS_NODE_COUNT] = static const SdlLssNodeInfo_t nodeLookupTable_gast[NMS_LSS_NODE_COUNT] =
//{ {
// {0x319, 0x4d2, 0x1, 0x01, 0x5} , {0x319, 0x4d2, 0x1, 0x01, 0x5} ,
// {0x319, 0x4d2, 0x1, 0x02, 0x6} , {0x319, 0x4d2, 0x1, 0x02, 0x6} ,
// {0x319, 0x4d2, 0x1, 0x03, 0x7} , {0x319, 0x4d2, 0x1, 0x03, 0x7} ,
// {0x319, 0x4d2, 0x1, 0x04, 0x8} , {0x319, 0x4d2, 0x1, 0x04, 0x8} ,
// {0x319, 0x4d2, 0x1, 0x05, 0x9} , {0x319, 0x4d2, 0x1, 0x05, 0x9} ,
// {0x319, 0x4d2, 0x1, 0x06, 0xA} , {0x319, 0x4d2, 0x1, 0x06, 0xA} ,
// {0x319, 0x4d2, 0x1, 0x07, 0xB} , {0x319, 0x4d2, 0x1, 0x07, 0xB} ,
// {0x319, 0x4d2, 0x1, 0x08, 0xC} , {0x319, 0x4d2, 0x1, 0x08, 0xC} ,
// {0x319, 0x4d2, 0x1, 0x09, 0xD} , {0x319, 0x4d2, 0x1, 0x09, 0xD} ,
// {0x319, 0x4d2, 0x1, 0x0A, 0xE} , {0x319, 0x4d2, 0x1, 0x0A, 0xE} ,
// {0x319, 0x4d2, 0x1, 0x0B, 0xF} , {0x319, 0x4d2, 0x1, 0x0B, 0xF} ,
// {0x319, 0x4d2, 0x1, 0x0C, 0x10}, {0x319, 0x4d2, 0x1, 0x0C, 0x10},
// {0x319, 0x4d2, 0x1, 0x0D, 0x11}, {0x319, 0x4d2, 0x1, 0x0D, 0x11},
// {0x319, 0x4d2, 0x1, 0x0E, 0x12}, {0x319, 0x4d2, 0x1, 0x0E, 0x12},
// {0x319, 0x4d2, 0x1, 0x0F, 0x13}, {0x319, 0x4d2, 0x1, 0x0F, 0x13},
// {0x319, 0x4d2, 0x1, 0x10, 0x14}, {0x319, 0x4d2, 0x1, 0x10, 0x14},
// {0x319, 0x4d2, 0x1, 0x11, 0x15}, {0x319, 0x4d2, 0x1, 0x11, 0x15},
// {0x319, 0x4d2, 0x1, 0x12, 0x16}, {0x319, 0x4d2, 0x1, 0x12, 0x16},
// {0x319, 0x4d2, 0x1, 0x13, 0x17}, {0x319, 0x4d2, 0x1, 0x13, 0x17},
// {0x319, 0x4d2, 0x1, 0x14, 0x18} {0x319, 0x4d2, 0x1, 0x14, 0x18}
//}; };
//static CO_NMT_STATE_T nodeNMTState_gaen[NMS_LSS_NODE_COUNT]; static CO_NMT_STATE_T nodeNMTState_gaen[NMS_LSS_NODE_COUNT];
///****************************************************************************** /******************************************************************************
// * Private Function Definition * Private Function Definition
// ******************************************************************************/ ******************************************************************************/
//
//static RET_T NmsCanOverwriteLoadIndication(uint8 index_u8); static RET_T NmsCanOverwriteLoadIndication(uint8 index_u8);
//static void NmsCanLssIndCallback( CO_LSS_MASTER_SERVICE_T service_en, uint16 errorCode_u16, uint8 errorSpec_u8, uint32 *pIdentity_pu32); static void NmsCanLssIndCallback( CO_LSS_MASTER_SERVICE_T service_en, uint16 errorCode_u16, uint8 errorSpec_u8, uint32 *pIdentity_pu32);
//static void NmsCanLssHbMonitorCallback(uint8 nodeID_u8, CO_ERRCTRL_T state_en, CO_NMT_STATE_T nmtState_en); static void NmsCanLssHbMonitorCallback(uint8 nodeID_u8, CO_ERRCTRL_T state_en, CO_NMT_STATE_T nmtState_en);
//static void NmsCanLssResetNodesCallback(void *pData_pv); /**< callback of reset handler */ static void NmsCanLssResetNodesCallback(void *pData_pv); /**< callback of reset handler */
//static uint8 NmsCanLssGetNodeIndex(uint8 nodeId_u8); static uint8 NmsCanLssGetNodeIndex(uint8 nodeId_u8);
//static void NmsCanLssToggleMonitorFlag(void *pData_pv); static void NmsCanLssToggleMonitorFlag(void *pData_pv);
//static void NmsCanLssNodeHandlerRun(void); static void NmsCanLssNodeHandlerRun(void);
//static uint32 NmsCanLssConfigureNode(uint8 arrIndex_u8); static uint32 NmsCanLssConfigureNode(uint8 arrIndex_u8);
//static RET_T NmsCanLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8); static RET_T NmsCanLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8);
///* Supress warnings for implicit declaration. /* Supress warnings for implicit declaration.
// * Need this function for overwriting the manual COB ids * Need this function for overwriting the manual COB ids
// * for the TPDO. */ * for the TPDO. */
//extern void userOverwriteCobIdSettings(void); extern void userOverwriteCobIdSettings(void);
///****************************************************************************** /******************************************************************************
// * Extern Function Declarations * Extern Function Declarations
// ******************************************************************************/ ******************************************************************************/
//void NmsCanInit() void NmsCanInit()
//{ {
// codrvHardwareInit(); codrvHardwareInit();
// codrvCanInit(NMS_CANOPEN_BITRATE); codrvCanInit(NMS_CANOPEN_BITRATE);
// codrvTimerSetup(CO_TIMER_INTERVAL); codrvTimerSetup(CO_TIMER_INTERVAL);
//
// /* CANopen Initialization */ /* CANopen Initialization */
// coCanOpenStackInit(NmsCanOverwriteLoadIndication); coCanOpenStackInit(NmsCanOverwriteLoadIndication);
// coEventRegister_LSS_MASTER(NmsCanLssIndCallback); coEventRegister_LSS_MASTER(NmsCanLssIndCallback);
// coEventRegister_ERRCTRL(NmsCanLssHbMonitorCallback); coEventRegister_ERRCTRL(NmsCanLssHbMonitorCallback);
//
// /* Register SDO event handlers */ /* Register SDO event handlers */
// coEventRegister_SDO_CLIENT_READ(EnduranceTestBenchReadInd); coEventRegister_SDO_CLIENT_READ(EnduranceTestBenchReadInd);
// coEventRegister_SDO_CLIENT_WRITE(EnduranceTestBenchWriteInd); coEventRegister_SDO_CLIENT_WRITE(EnduranceTestBenchWriteInd);
//
// /* enable CAN communication */ /* enable CAN communication */
// codrvCanEnable(); codrvCanEnable();
//
// coTimerStart(&monitorTimer_gst, NMS_CAN_APPL_TIMER_TIME, NmsCanLssToggleMonitorFlag, NULL, CO_TIMER_ATTR_ROUNDUP_CYCLIC); coTimerStart(&monitorTimer_gst, NMS_CAN_APPL_TIMER_TIME, NmsCanLssToggleMonitorFlag, NULL, CO_TIMER_ATTR_ROUNDUP_CYCLIC);
// coLssIdentifyNonConfiguredSlaves(NMS_CAN_LSS_CONFIG_TIMEOUT, NMS_CAN_LSS_CONFIG_INTERVAL); coLssIdentifyNonConfiguredSlaves(NMS_CAN_LSS_CONFIG_TIMEOUT, NMS_CAN_LSS_CONFIG_INTERVAL);
//
// /* node == 0, the NMT request is sent to all nodes. */ /* node == 0, the NMT request is sent to all nodes. */
// coNmtStateReq(NMS_CAN_PU_MASTER_NODE_ID, CO_NMT_STATE_OPERATIONAL, CO_TRUE); coNmtStateReq(NMS_CAN_PU_MASTER_NODE_ID, CO_NMT_STATE_OPERATIONAL, CO_TRUE);
//} }
//
//
//void NmsCanRun(void) void NmsCanRun(void)
//{ {
// coCommTask(); coCommTask();
//
// /* LSS main runner */ /* LSS main runner */
// NmsCanLssNodeHandlerRun(); NmsCanLssNodeHandlerRun();
//} }
//
//
uint32 NmsCanGetObj_u8(uint16 index_u16, uint8 subIndex_u8, uint8 *pObj_pu8) uint32 NmsCanGetObj_u8(uint16 index_u16, uint8 subIndex_u8, uint8 *pObj_pu8)
{ {
uint32 error_u32 = NMS_ERR_DEFAULT; uint32 error_u32 = NMS_ERR_DEFAULT;
@ -229,346 +229,346 @@ uint32 NmsCanPutObj_f32(uint16 index_u16, uint8 subIndex_u8, uint32 newVal_u32)
return error_u32; return error_u32;
} }
///****************************************************************************** /******************************************************************************
// * Private Function Definitions * Private Function Definitions
// ******************************************************************************/ ******************************************************************************/
///** /**
// * @brief Handler for the defined nodes in the network. * @brief Handler for the defined nodes in the network.
// * This function starts the configuration of a node if needed * This function starts the configuration of a node if needed
// * *
// * @return void * @return void
// * *
// */ */
//static void NmsCanLssNodeHandlerRun(void) static void NmsCanLssNodeHandlerRun(void)
//{ {
// if (monitorSleep_gb != CO_TRUE) if (monitorSleep_gb != CO_TRUE)
// { {
// for (uint8 i_u8 = 0u; i_u8 < NMS_CAN_LSS_NODE_COUNT; i_u8++) for (uint8 i_u8 = 0u; i_u8 < NMS_CAN_LSS_NODE_COUNT; i_u8++)
// { {
// if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_PREOP) if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_PREOP)
// { {
// NmsCanLssConfigureNode(i_u8); NmsCanLssConfigureNode(i_u8);
// } }
// if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_OPERATIONAL) if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_OPERATIONAL)
// { {
// /* Do nothing */ /* Do nothing */
// } }
// } }
// } }
// monitorSleep_gb = CO_TRUE; monitorSleep_gb = CO_TRUE;
//} }
//
//
///** /**
// * @brief Load function for overwriting the TPDO COB id values. * @brief Load function for overwriting the TPDO COB id values.
// * *
// * @param index_u8 Subindex parameter to point parameter area(unused) * @param index_u8 Subindex parameter to point parameter area(unused)
// * canLine_u8 The canline MASTER or SLAVE * canLine_u8 The canline MASTER or SLAVE
// * *
// * @return Error Code * @return Error Code
// */ */
//static RET_T NmsCanOverwriteLoadIndication(uint8 index_u8) static RET_T NmsCanOverwriteLoadIndication(uint8 index_u8)
//{ {
// userOverwriteCobIdSettings(); userOverwriteCobIdSettings();
//
// return RET_OK; return RET_OK;
//} }
//
//
///** /**
// * @brief This function is called if a new NMT state of a node, * @brief This function is called if a new NMT state of a node,
// * is recordnized by the CANopen stack. * is recordnized by the CANopen stack.
// * *
// * @param nodeID_u8 Node id of the node that has registered a change. * @param nodeID_u8 Node id of the node that has registered a change.
// * state_en Error control state * state_en Error control state
// * nmtState_en NMT state of the particular node. * nmtState_en NMT state of the particular node.
// * *
// * @return Array index of the node in the network. * @return Array index of the node in the network.
// * *
// */ */
//static uint8 NmsCanLssGetNodeIndex(uint8 nodeId_u8) static uint8 NmsCanLssGetNodeIndex(uint8 nodeId_u8)
//{ {
// uint8 arrIndex_u8; uint8 arrIndex_u8;
//
// /* find node ID array arrIndex_u8 */ /* find node ID array arrIndex_u8 */
// for (arrIndex_u8 = 0u; arrIndex_u8 < NMS_CAN_LSS_NODE_COUNT; arrIndex_u8++) for (arrIndex_u8 = 0u; arrIndex_u8 < NMS_CAN_LSS_NODE_COUNT; arrIndex_u8++)
// { {
// if (nodeId_u8 == nodeLookupTable_gast[arrIndex_u8].nodeId_u8) if (nodeId_u8 == nodeLookupTable_gast[arrIndex_u8].nodeId_u8)
// { {
// return arrIndex_u8; return arrIndex_u8;
// } }
// } }
//
// return NMS_UINT8_MAX; return NMS_UINT8_MAX;
//} }
//
//
///** /**
// * @brief This function is called when a new NMT state of a node * @brief This function is called when a new NMT state of a node
// * is recognized by the CANopen stack. * is recognized by the CANopen stack.
// * *
// * @param canLine_u8 Indicates whether the node is on the MASTER or SLAVE CAN line. * @param canLine_u8 Indicates whether the node is on the MASTER or SLAVE CAN line.
// * pData Pointer to additional data (unused). * pData Pointer to additional data (unused).
// */ */
//static void NmsCanLssToggleMonitorFlag(void *pData_pv) static void NmsCanLssToggleMonitorFlag(void *pData_pv)
//{ {
// (void)pData_pv; (void)pData_pv;
//
// /* deactivate application sleep flag */ /* deactivate application sleep flag */
// monitorSleep_gb = CO_FALSE; monitorSleep_gb = CO_FALSE;
//} }
//
//
///** /**
//* @brief Configure a specific node. * @brief Configure a specific node.
//* This function adds the defined node to heartbeat consumers, * This function adds the defined node to heartbeat consumers,
//* and sets its heartbeat interval. * and sets its heartbeat interval.
//* *
//* @param arrIndex_u8 Index of the node in the array which is to be configured. * @param arrIndex_u8 Index of the node in the array which is to be configured.
//* *
//* @return Status of the operation. * @return Status of the operation.
//* *
//*/ */
//static uint32 NmsCanLssConfigureNode(uint8 arrIndex_u8) static uint32 NmsCanLssConfigureNode(uint8 arrIndex_u8)
//{ {
// uint32 error_u32 = NMS_ERR_DEFAULT; uint32 error_u32 = NMS_ERR_DEFAULT;
// RET_T retVal_en = RET_INTERNAL_ERROR; RET_T retVal_en = RET_INTERNAL_ERROR;
//
// /* Get the node ID from the lookup table using arrIndex_u8 */ /* Get the node ID from the lookup table using arrIndex_u8 */
// uint8 nodeId_u8 = nodeLookupTable_gast[arrIndex_u8].nodeId_u8; uint8 nodeId_u8 = nodeLookupTable_gast[arrIndex_u8].nodeId_u8;
//
// /* Add node to hb consumers with +25% tolerance /* Add node to hb consumers with +25% tolerance
// * Rationale - Allows some flexibility in detecting timeouts due to minor clock drifts, * Rationale - Allows some flexibility in detecting timeouts due to minor clock drifts,
// * bus delays, or transmission issues.*/ * bus delays, or transmission issues.*/
// retVal_en = coHbConsumerSet(nodeId_u8, retVal_en = coHbConsumerSet(nodeId_u8,
// ((NMS_CAN_LSS_NODE_HB_MS / 100 * 25) + NMS_CAN_LSS_NODE_HB_MS)); ((NMS_CAN_LSS_NODE_HB_MS / 100 * 25) + NMS_CAN_LSS_NODE_HB_MS));
// retVal_en = coHbConsumerStart(nodeId_u8); retVal_en = coHbConsumerStart(nodeId_u8);
//
// /* setup SDO channel */ /* setup SDO channel */
// retVal_en = NmsCanLssSetSdoCobID((arrIndex_u8 + 1), nodeLookupTable_gast[arrIndex_u8].nodeId_u8); retVal_en = NmsCanLssSetSdoCobID((arrIndex_u8 + 1), nodeLookupTable_gast[arrIndex_u8].nodeId_u8);
//
// //retVal_en = coSdoWrite(NmsCan_CANOPEN_MASTER_LINE, (arrIndex_u8 + 1), 0x1017u, 0u, (uint8*)(&nodeHBs[0]), 2u, CO_FALSE, 1000u); //retVal_en = coSdoWrite(NmsCan_CANOPEN_MASTER_LINE, (arrIndex_u8 + 1), 0x1017u, 0u, (uint8*)(&nodeHBs[0]), 2u, CO_FALSE, 1000u);
//
// /* start node */ /* start node */
// retVal_en = coNmtStateReq(nodeId_u8, CO_NMT_STATE_OPERATIONAL, CO_FALSE); retVal_en = coNmtStateReq(nodeId_u8, CO_NMT_STATE_OPERATIONAL, CO_FALSE);
// if (retVal_en != RET_OK) if (retVal_en != RET_OK)
// { {
// error_u32 = NMS_LSS_NODE_CONFIG_ERROR; error_u32 = NMS_LSS_NODE_CONFIG_ERROR;
// } }
// /* set local state to operational, if not operational yet */ /* set local state to operational, if not operational yet */
// if (masterStarted_gb == CO_FALSE) if (masterStarted_gb == CO_FALSE)
// { {
// /* set local state */ /* set local state */
// coNmtLocalStateReq(CO_NMT_STATE_OPERATIONAL); coNmtLocalStateReq(CO_NMT_STATE_OPERATIONAL);
//
// /* save started flag */ /* save started flag */
// masterStarted_gb = CO_TRUE; masterStarted_gb = CO_TRUE;
// } }
//
// return error_u32; return error_u32;
//} }
//
//
///****************************************************************************** /******************************************************************************
// * Callback Function Definitions * Callback Function Definitions
// ******************************************************************************/ ******************************************************************************/
///** /**
// * @brief LSS indication function for handling the LSS api calls for dynamic * @brief LSS indication function for handling the LSS api calls for dynamic
// * setup of node ids. * setup of node ids.
// * *
// * @param canLine_u8 The canline MASTER or SLAVE * @param canLine_u8 The canline MASTER or SLAVE
// * service_en LSS master services for indication functions * service_en LSS master services for indication functions
// * errorCode_u16 Error code in the module * errorCode_u16 Error code in the module
// * errorSpec_u8 Specific error case that has occured * errorSpec_u8 Specific error case that has occured
// * pIdentity_pu32 LSS slave identity. * pIdentity_pu32 LSS slave identity.
// * *
// */ */
//static void NmsCanLssIndCallback(CO_LSS_MASTER_SERVICE_T service_en, uint16 errorCode_u16, uint8 errorSpec_u8, uint32 *pIdentity_pu32) static void NmsCanLssIndCallback(CO_LSS_MASTER_SERVICE_T service_en, uint16 errorCode_u16, uint8 errorSpec_u8, uint32 *pIdentity_pu32)
//{ {
// static uint8 matchedIndex_u8 = NMS_UINT8_MAX; static uint8 matchedIndex_u8 = NMS_UINT8_MAX;
//
// if (errorCode_u16 != 0u) if (errorCode_u16 != 0u)
// { {
// if (errorCode_u16 == NMS_UINT16_MAX) if (errorCode_u16 == NMS_UINT16_MAX)
// { {
// /* ERROR */ /* ERROR */
// } }
// else else
// { {
// /* ERROR */ /* ERROR */
// } }
//
// if (service_en == CO_LSS_MASTER_SERVICE_STORE) if (service_en == CO_LSS_MASTER_SERVICE_STORE)
// { {
// /* DEBUG INFO */ /* DEBUG INFO */
// coLssSwitchGlobal(CO_LSS_STATE_WAITING); coLssSwitchGlobal(CO_LSS_STATE_WAITING);
// } }
// return; return;
// } }
//
// switch (service_en) switch (service_en)
// { {
// case CO_LSS_MASTER_SERVICE_NON_CONFIG_SLAVE: case CO_LSS_MASTER_SERVICE_NON_CONFIG_SLAVE:
// /* DEBUG INFO */ /* DEBUG INFO */
// coLssFastScan(NMS_CAN_LSS_TIMEOUT); coLssFastScan(NMS_CAN_LSS_TIMEOUT);
// break; break;
//
// case CO_LSS_MASTER_SERVICE_FASTSCAN: case CO_LSS_MASTER_SERVICE_FASTSCAN:
// /* Match detected node with lookup table */ /* Match detected node with lookup table */
// for (uint8 i_u8 = 0; i_u8 < NMS_CAN_LSS_NODE_COUNT; i_u8++) for (uint8 i_u8 = 0; i_u8 < NMS_CAN_LSS_NODE_COUNT; i_u8++)
// { {
// if (pIdentity_pu32[0] == nodeLookupTable_gast[i_u8].vendorId_u32 && if (pIdentity_pu32[0] == nodeLookupTable_gast[i_u8].vendorId_u32 &&
// pIdentity_pu32[1] == nodeLookupTable_gast[i_u8].productId_u32 && pIdentity_pu32[1] == nodeLookupTable_gast[i_u8].productId_u32 &&
// pIdentity_pu32[2] == nodeLookupTable_gast[i_u8].versionNbr_u32 && pIdentity_pu32[2] == nodeLookupTable_gast[i_u8].versionNbr_u32 &&
// pIdentity_pu32[3] == nodeLookupTable_gast[i_u8].serialNbr_u32) pIdentity_pu32[3] == nodeLookupTable_gast[i_u8].serialNbr_u32)
// { {
// coLssSwitchSelective(pIdentity_pu32[0], pIdentity_pu32[1], coLssSwitchSelective(pIdentity_pu32[0], pIdentity_pu32[1],
// pIdentity_pu32[2], pIdentity_pu32[3], 20); pIdentity_pu32[2], pIdentity_pu32[3], 20);
// matchedIndex_u8 = i_u8; matchedIndex_u8 = i_u8;
// break; break;
// } }
// } }
// break; break;
//
// case CO_LSS_MASTER_SERVICE_SWITCH_SELECTIVE: case CO_LSS_MASTER_SERVICE_SWITCH_SELECTIVE:
// if (matchedIndex_u8 < NMS_CAN_LSS_NODE_COUNT) if (matchedIndex_u8 < NMS_CAN_LSS_NODE_COUNT)
// { {
// coLssSetNodeId(nodeLookupTable_gast[matchedIndex_u8].nodeId_u8, NMS_CAN_LSS_TIMEOUT); coLssSetNodeId(nodeLookupTable_gast[matchedIndex_u8].nodeId_u8, NMS_CAN_LSS_TIMEOUT);
// matchedIndex_u8 = NMS_UINT8_MAX; matchedIndex_u8 = NMS_UINT8_MAX;
// } }
// else else
// { {
// /* ERROR */ /* ERROR */
// } }
// break; break;
//
// case CO_LSS_MASTER_SERVICE_SET_NODEID: case CO_LSS_MASTER_SERVICE_SET_NODEID:
// /* DEBUG INFO */ /* DEBUG INFO */
// coLssInquireNodeId(NMS_CAN_LSS_TIMEOUT); coLssInquireNodeId(NMS_CAN_LSS_TIMEOUT);
// break; break;
//
// case CO_LSS_MASTER_SERVICE_INQUIRE_NODEID: case CO_LSS_MASTER_SERVICE_INQUIRE_NODEID:
// /* DEBUG INFO */ /* DEBUG INFO */
// coLssStoreConfig( 200); coLssStoreConfig( 200);
// break; break;
//
// case CO_LSS_MASTER_SERVICE_STORE: case CO_LSS_MASTER_SERVICE_STORE:
// /* DEBUG INFO */ /* DEBUG INFO */
// coLssSwitchGlobal(CO_LSS_STATE_WAITING); coLssSwitchGlobal(CO_LSS_STATE_WAITING);
// break; break;
//
// default: default:
// /* ERROR */ /* ERROR */
// break; break;
// } }
//} }
//
//
///** /**
// * @brief This function is called if a new NMT state of a node, * @brief This function is called if a new NMT state of a node,
// * is recordnized by the CANopen stack. * is recordnized by the CANopen stack.
// * *
// * @param nodeID_u8 Node id of the node that has registered a change. * @param nodeID_u8 Node id of the node that has registered a change.
// * state_en Error control state * state_en Error control state
// * nmtState_en NMT state of the particular node. * nmtState_en NMT state of the particular node.
// * *
// * @return void * @return void
// * *
// */ */
//static void NmsCanLssHbMonitorCallback(uint8 nodeID_u8, CO_ERRCTRL_T state_en, CO_NMT_STATE_T nmtState_en) static void NmsCanLssHbMonitorCallback(uint8 nodeID_u8, CO_ERRCTRL_T state_en, CO_NMT_STATE_T nmtState_en)
//{ {
// uint8 arrIndex_u8; uint8 arrIndex_u8;
//
// /* look if node is monitored */ /* look if node is monitored */
// arrIndex_u8 = NmsCanLssGetNodeIndex(nodeID_u8); arrIndex_u8 = NmsCanLssGetNodeIndex(nodeID_u8);
//
// /* handle monitored node */ /* handle monitored node */
// if (arrIndex_u8 != NMS_UINT16_MAX) if (arrIndex_u8 != NMS_UINT16_MAX)
// { {
// /* save states */ /* save states */
// nodeNMTState_gaen[arrIndex_u8] = nmtState_en; nodeNMTState_gaen[arrIndex_u8] = nmtState_en;
//
// /* indicate if monitored node lost heartbeat */ /* indicate if monitored node lost heartbeat */
// if (nmtState_en == CO_NMT_STATE_UNKNOWN) if (nmtState_en == CO_NMT_STATE_UNKNOWN)
// { {
// /* To be transmitted via CAN */ /* To be transmitted via CAN */
// /* ERROR */ /* ERROR */
// } }
//
// /* indicate if monitored node sent a bootup message */ /* indicate if monitored node sent a bootup message */
// if (state_en == CO_ERRCTRL_BOOTUP) if (state_en == CO_ERRCTRL_BOOTUP)
// { {
// /* INFO */ /* INFO */
// } }
//
// /* handle unmonitored node */ /* handle unmonitored node */
// } }
// else else
// { {
// /* ERROR */ /* ERROR */
// } }
//} }
//
//
///** /**
//* @brief This function tries to reset nodes with unknown NMT state. * @brief This function tries to reset nodes with unknown NMT state.
//* *
//* @param pData_pv Data. * @param pData_pv Data.
//*/ */
//static void NmsCanLssResetNodesCallback(void *pData_pv) static void NmsCanLssResetNodesCallback(void *pData_pv)
//{ {
// uint8 arrIndex_u8; uint8 arrIndex_u8;
//
// (void)pData_pv; (void)pData_pv;
//
// /* reset defined nodes without known state */ /* reset defined nodes without known state */
// for (arrIndex_u8 = 0u; arrIndex_u8 < 3; arrIndex_u8++) for (arrIndex_u8 = 0u; arrIndex_u8 < 3; arrIndex_u8++)
// { {
// if ((nodeNMTState_gaen[arrIndex_u8] != CO_NMT_STATE_PREOP) && if ((nodeNMTState_gaen[arrIndex_u8] != CO_NMT_STATE_PREOP) &&
// (nodeNMTState_gaen[arrIndex_u8] != CO_NMT_STATE_OPERATIONAL)) (nodeNMTState_gaen[arrIndex_u8] != CO_NMT_STATE_OPERATIONAL))
// { {
// /* reset node */ /* reset node */
// coNmtStateReq(nodeLookupTable_gast[arrIndex_u8].nodeId_u8, CO_NMT_STATE_RESET_NODE, CO_FALSE); coNmtStateReq(nodeLookupTable_gast[arrIndex_u8].nodeId_u8, CO_NMT_STATE_RESET_NODE, CO_FALSE);
// } }
// } }
//} }
//
//
///** /**
//* @brief This function configures a SDO client for the * @brief This function configures a SDO client for the
//* given node ID and SDO number. * given node ID and SDO number.
//* *
//* @param sdoNr_u8 Sdo number * @param sdoNr_u8 Sdo number
//* nodeId_u8 Node id of the node. * nodeId_u8 Node id of the node.
//* *
//* @return Error state. * @return Error state.
//* *
//*/ */
//static RET_T NmsCanLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8) static RET_T NmsCanLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8)
//{ {
// uint16 cobIndex_u16; uint16 cobIndex_u16;
// uint32 newCobId_u32; uint32 newCobId_u32;
// RET_T retVal = RET_INTERNAL_ERROR; RET_T retVal = RET_INTERNAL_ERROR;
//
// /* get od index of sdoNr */ /* get od index of sdoNr */
// cobIndex_u16 = NMS_CAN_SDO_PARAM_INDEX + sdoNr_u8 - 1u; cobIndex_u16 = NMS_CAN_SDO_PARAM_INDEX + sdoNr_u8 - 1u;
//
// /* set cobID for client to server direction (request) */ /* set cobID for client to server direction (request) */
// newCobId_u32 = NMS_CAN_SDO_RECEIVE + nodeId_u8; newCobId_u32 = NMS_CAN_SDO_RECEIVE + nodeId_u8;
// retVal = coOdSetCobid(cobIndex_u16, 1u, newCobId_u32); retVal = coOdSetCobid(cobIndex_u16, 1u, newCobId_u32);
//
// if (retVal == RET_OK) if (retVal == RET_OK)
// { {
// /* set cobID for server to client direction (response) */ /* set cobID for server to client direction (response) */
// newCobId_u32 = NMS_CAN_SDO_TRANSMIT + nodeId_u8; newCobId_u32 = NMS_CAN_SDO_TRANSMIT + nodeId_u8;
// retVal = coOdSetCobid(cobIndex_u16, 2u, newCobId_u32); retVal = coOdSetCobid(cobIndex_u16, 2u, newCobId_u32);
// } }
//
// /* print failed setup details */ /* print failed setup details */
// if (retVal != RET_OK) if (retVal != RET_OK)
// { {
// /* ERROR */ /* ERROR */
// } }
//
// return retVal; return retVal;
//} }

View File

@ -18,13 +18,13 @@
#include "nms_types.h" #include "nms_types.h"
#include "co_datatype.h" #include "co_datatype.h"
#include "co_nmt.h" #include "co_nmt.h"
///****************************************************************************** /******************************************************************************
// * Macro constant declarations * Macro constant declarations
// ******************************************************************************/ ******************************************************************************/
//#define NMS_CANOPEN_BITRATE 250u #define NMS_CANOPEN_BITRATE 250u
///****************************************************************************** /******************************************************************************
// * Extern Function Declarations * Extern Function Declarations
// ******************************************************************************/ ******************************************************************************/
/** /**
* @brief Initializes the CAN controller and CANopen stack. * @brief Initializes the CAN controller and CANopen stack.
*/ */

View File

@ -17,105 +17,29 @@
/****************************************************************************** /******************************************************************************
* Include Header Files * Include Header Files
******************************************************************************/ ******************************************************************************/
/* CANopen includes */
#include <co_canopen.h>
#include <gen_define.h>
#include <co_canopen.h>
#include "co_sdo.h"
#include "co_odaccess.h"
/* User includes */ /* User includes */
#include "sdl.h" #include "sdl.h"
#include "nms_can.h"
#include "processBoard.h" #include "processBoard.h"
#include "enduranceTestBench.h" #include "enduranceTestBench.h"
#include "hal_system.h"
#include "stdlib.h" #include "stdlib.h"
#include "hal_system.h"
/****************************************************************************** /******************************************************************************
* Macro constant declarations * Macro constant declarations
******************************************************************************/ ******************************************************************************/
#define SDL_CANOPEN_BITRATE 250u
#define SDL_PU_MASTER_NODE_ID 1u
#define SDL_LSS_TIMEOUT 20u /* Defined in stack examples */
#define SDL_LSS_CONFIG_TIMEOUT 1000u
#define SDL_LSS_CONFIG_INTERVAL 4u
#define SDL_APPL_TIMER_TIME 250000uL
#define SDL_LSS_NODE_COUNT 20u
#define SDL_LSS_NODE_HB_MS 1000uL
#define SDL_LSS_NODE_STATE_RESET_INTERVAL 3u
#define SDL_TEST_BENCH_SDO_TIMEOUT 1000u
#define SDL_TEST_BENCH_STARTUP_TIMEOUT 10000uLL
#define SDL_POSITION_SETPOINT_INDEX 0x6002
#define SDL_POSITION_SETPOINT_SUB_INDEX 0x0
#define SDL_POSITION_FEEDBACK_INDEX 0x6004
#define SDL_POSITION_FEEDBACK_SUB_INDEX 0x0
#define SDL_SDO_CLIENT_COB 0x1280
#define SDL_SDO_CLIENT_TO_SERVER_COB 0x600
#define SDL_SDO_SERVER_TO_CLIENT_COB 0x580
#define SDL_MIN_OPERATIONAL_NODES 18u /* To be 20, one node not in working state currently */ #define SDL_MIN_OPERATIONAL_NODES 18u /* To be 20, one node not in working state currently */
#define SDL_LSS_NODE_COUNT 20u
/****************************************************************************** /******************************************************************************
* Type Declarations * Type Declarations
******************************************************************************/ ******************************************************************************/
typedef struct
{
uint32 vendorId_u32;
uint32 productId_u32;
uint32 versionNbr_u32;
uint32 serialNbr_u32;
uint8 nodeId_u8;
} SdlLssNodeInfo_t;
/****************************************************************************** /******************************************************************************
* Global Declarations * Global Declarations
******************************************************************************/ ******************************************************************************/
static bool testBenchStarted_b;
SdlLssNodeInfo_t var_gst;
static CO_TIMER_T monitorTimer_gst; /**< application timer */
static bool monitorSleep_gb = CO_FALSE; /**< sleep flag */
static bool masterStarted_gb; /**< master started flag */
static const SdlLssNodeInfo_t nodeLookupTable_gast[SDL_LSS_NODE_COUNT] =
{
{0x319, 0x4d2, 0x1, 0x01, 0x5} ,
{0x319, 0x4d2, 0x1, 0x02, 0x6} ,
{0x319, 0x4d2, 0x1, 0x03, 0x7} ,
{0x319, 0x4d2, 0x1, 0x04, 0x8} ,
{0x319, 0x4d2, 0x1, 0x05, 0x9} ,
{0x319, 0x4d2, 0x1, 0x06, 0xA} ,
{0x319, 0x4d2, 0x1, 0x07, 0xB} ,
{0x319, 0x4d2, 0x1, 0x08, 0xC} ,
{0x319, 0x4d2, 0x1, 0x09, 0xD} ,
{0x319, 0x4d2, 0x1, 0x0A, 0xE} ,
{0x319, 0x4d2, 0x1, 0x0B, 0xF} ,
{0x319, 0x4d2, 0x1, 0x0C, 0x10},
{0x319, 0x4d2, 0x1, 0x0D, 0x11},
{0x319, 0x4d2, 0x1, 0x0E, 0x12},
{0x319, 0x4d2, 0x1, 0x0F, 0x13},
{0x319, 0x4d2, 0x1, 0x10, 0x14},
{0x319, 0x4d2, 0x1, 0x11, 0x15},
{0x319, 0x4d2, 0x1, 0x12, 0x16},
{0x319, 0x4d2, 0x1, 0x13, 0x17},
{0x319, 0x4d2, 0x1, 0x14, 0x18}
};
static CO_NMT_STATE_T nodeNMTState_gaen[SDL_LSS_NODE_COUNT]; static CO_NMT_STATE_T nodeNMTState_gaen[SDL_LSS_NODE_COUNT];
/****************************************************************************** /******************************************************************************
* Static function Declarations * Static function Declarations
******************************************************************************/ ******************************************************************************/
static void SdlInitCanopen(void);
static void SdlRunCanopen(void);
static RET_T SdlOverwriteLoadIndication(uint8 index_u8);
static void SdlLssIndCallback(CO_LSS_MASTER_SERVICE_T service_en, uint16 errorCode_u16, uint8 errorSpec_u8, uint32 *pIdentity_pu32);
static void SdlLssHbMonitorCallback(uint8 nodeID_u8, CO_ERRCTRL_T state_en, CO_NMT_STATE_T nmtState_en);
static void SdlLssResetNodesCallback(void *pData_pv); /**< callback of reset handler */
static uint8 SdlLssGetNodeIndex(uint8 nodeId_u8);
static void SdlLssToggleMonitorFlag(void *pData);
static void SdlLssNodeHandlerRun(void);
static uint32 SdlLssConfigureNode(uint8 arrIndex_u8);
static RET_T SdlLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8);
/* Supress warnings for implicit declaration. /* Supress warnings for implicit declaration.
* Need this function for overwriting the manual COB ids * Need this function for overwriting the manual COB ids
* for the TPDO. */ * for the TPDO. */
@ -127,251 +51,24 @@ static bool SdlAreAllNodesOperational(void);
******************************************************************************/ ******************************************************************************/
void SdlInit(void) void SdlInit(void)
{ {
testBenchStarted_b = false; HalSystemInit();
SdlInitCanopen(); NmsCanInit();
} }
void SdlRun(void) void SdlRun(void)
{ {
SdlRunCanopen(); NmsCanRun();
SdlLssNodeHandlerRun();
if (SdlAreAllNodesOperational()) if (SdlAreAllNodesOperational())
{ {
EnduranceTestBenchRun(&testBenchStarted_b); EnduranceTestBenchRun();
if (testBenchStarted_b == true) ProcessBoardRun();
{
ProcessBoardRun();
}
} }
} }
/******************************************************************************
* Private Function Declarations
******************************************************************************/
/**
* @brief Init the CANopen stack.
*
*/
static void SdlInitCanopen(void)
{
RET_T retval;
HalSystemInit();
codrvHardwareInit();
retval = codrvCanInit(SDL_CANOPEN_BITRATE);
retval = codrvTimerSetup(CO_TIMER_INTERVAL);
/* CANopen Initialization */
retval = coCanOpenStackInit(SdlOverwriteLoadIndication);
retval = coEventRegister_LSS_MASTER(SdlLssIndCallback);
retval = coEventRegister_ERRCTRL(SdlLssHbMonitorCallback);
/* Register SDO event handlers */
coEventRegister_SDO_CLIENT_READ(EnduranceTestBenchReadInd);
coEventRegister_SDO_CLIENT_WRITE(EnduranceTestBenchWriteInd);
/* enable CAN communication */
retval = codrvCanEnable();
retval = coTimerStart(&monitorTimer_gst, SDL_APPL_TIMER_TIME, SdlLssToggleMonitorFlag, NULL, CO_TIMER_ATTR_ROUNDUP_CYCLIC);
//retval = coTimerStart(&nodeResetTimer_gst, (SDL_LSS_NODE_STATE_RESET_INTERVAL * 1000000uLL), SdlLssResetNodesCallback, NULL, CO_TIMER_ATTR_ROUNDUP_CYCLIC);
coLssIdentifyNonConfiguredSlaves(SDL_LSS_CONFIG_TIMEOUT, SDL_LSS_CONFIG_INTERVAL);
retval = coNmtStateReq(SDL_PU_MASTER_NODE_ID, CO_NMT_STATE_OPERATIONAL, CO_TRUE);
}
/**
* @brief Runs the CANopen stack.
*
*/
static void SdlRunCanopen(void)
{
coCommTask();
SdlLssNodeHandlerRun();
}
/****************************************************************************** /******************************************************************************
* Private Function Definitions * Private Function Definitions
******************************************************************************/ ******************************************************************************/
/**
* @brief Handler for the defined nodes in the network.
* This function starts the configuration of a node if needed
*
* @return void
*
*/
static void SdlLssNodeHandlerRun(void)
{
if (monitorSleep_gb != CO_TRUE)
{
for (uint8 i_u8 = 0u; i_u8 < SDL_LSS_NODE_COUNT; i_u8++)
{
if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_PREOP)
{
SdlLssConfigureNode(i_u8);
}
if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_OPERATIONAL)
{
/* Do nothing */
}
}
}
monitorSleep_gb = CO_TRUE;
}
/**
* @brief Load function for overwriing the TPDO COB id values.
*
* @param index_u8 Subindex parameter to point parameter area(unused)
*
* @return Error Code
*/
static RET_T SdlOverwriteLoadIndication(uint8 index_u8)
{
userOverwriteCobIdSettings();
return RET_OK;
}
/**
* @brief This function is called if a new NMT state of a node,
* is recordnized by the CANopen stack.
*
* @param nodeID_u8 Node id of the node that has registered a change.
* state_en Error control state
* nmtState_en NMT state of the particular node.
*
* @return Array index of the node in the network.
*
*/
static uint8 SdlLssGetNodeIndex(uint8 nodeId_u8)
{
uint8 arrIndex_u8;
/* find node ID array arrIndex_u8 */
for (arrIndex_u8 = 0u; arrIndex_u8 < SDL_LSS_NODE_COUNT; arrIndex_u8++)
{
if (nodeId_u8 == nodeLookupTable_gast[arrIndex_u8].nodeId_u8)
{
return arrIndex_u8;
}
}
return NMS_UINT8_MAX;
}
/**
* @brief This function is called if a new NMT state of a node,
* is recordnized by the CANopen stack.
*
* @param nodeID_u8 Node id of the node that has registered a change.
* state_en Error control state
* nmtState_en NMT state of the particular node.
*
* @return Array index of the node in the network.
*
*/
static void SdlLssToggleMonitorFlag(void *pData)
{
(void)pData;
/* deactivate application sleep flag */
monitorSleep_gb = CO_FALSE;
}
/**
* @brief Configure a specific node.
* This function adds the defined node to heartbeat consumers,
* and sets its heartbeat interval.
*
* @param arrIndex_u8 Index of the node in the array which is to be configured.
*
* @return Status of the operation.
*
*/
static uint32 SdlLssConfigureNode(uint8 arrIndex_u8)
{
uint32 error_u32 = SDL_DEFAULT_ERROR;
RET_T retVal_en = RET_INTERNAL_ERROR;
/* Get the node ID from the lookup table using the index passed */
uint8 nodeId_u8 = nodeLookupTable_gast[arrIndex_u8].nodeId_u8;
/* Add node to heartbeat consumers with +25% tolerance
* Rationale - Allows some flexibility in detecting timeouts due to minor clock drifts,
* bus delays, or transmission issues.*/
retVal_en = coHbConsumerSet(nodeId_u8,
((SDL_LSS_NODE_HB_MS / 100u * 25u) + SDL_LSS_NODE_HB_MS));
retVal_en = coHbConsumerStart(nodeId_u8);
/* setup SDO channel */
retVal_en = SdlLssSetSdoCobID((arrIndex_u8 + 1u), nodeLookupTable_gast[arrIndex_u8].nodeId_u8);
/* start node */
retVal_en = coNmtStateReq(nodeId_u8, CO_NMT_STATE_OPERATIONAL, CO_FALSE);
if (retVal_en != RET_OK)
{
error_u32 = SDL_LSS_NODE_CONFIG_ERROR;
}
/* set local state to operational, if not operational yet */
if (masterStarted_gb == CO_FALSE)
{
/* set local state */
coNmtLocalStateReq(CO_NMT_STATE_OPERATIONAL);
/* save started flag */
masterStarted_gb = CO_TRUE;
}
return error_u32;
}
/**
* @brief This function configures a SDO client for the
* given node ID and SDO number.
*
* @param sdoNr_u8 Sdo number
* nodeId_u8 Node id of the node.
*
* @return Error state.
*
*/
static RET_T SdlLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8)
{
uint16 cobIndex_u16;
uint32 newCobId_u32;
RET_T retVal_en = RET_INTERNAL_ERROR;
/* get od index of sdoNr */
cobIndex_u16 = SDL_SDO_CLIENT_COB + sdoNr_u8 - 1u; /* SDO starts from 1280 index */
/* set cobID for client to server direction (request) */
newCobId_u32 = SDL_SDO_CLIENT_TO_SERVER_COB + nodeId_u8;
retVal_en = coOdSetCobid(cobIndex_u16, 1u, newCobId_u32);
if (retVal_en == RET_OK)
{
/* set cobID for server to client direction (response) */
newCobId_u32 = SDL_SDO_SERVER_TO_CLIENT_COB + nodeId_u8;
retVal_en = coOdSetCobid(cobIndex_u16, 2u, newCobId_u32);
}
/* print failed setup details */
if (retVal_en != RET_OK)
{
/* ERROR */
}
return retVal_en;
}
/** /**
* @brief Checks if all nodes are in OPERATIONAL state. * @brief Checks if all nodes are in OPERATIONAL state.
@ -392,166 +89,3 @@ static bool SdlAreAllNodesOperational(void)
return (operationalNodeNb_u8 >= SDL_MIN_OPERATIONAL_NODES) ? CO_TRUE : CO_FALSE; return (operationalNodeNb_u8 >= SDL_MIN_OPERATIONAL_NODES) ? CO_TRUE : CO_FALSE;
} }
/******************************************************************************
* Callback Function Definitions
******************************************************************************/
/**
* @brief LSS indication function for handling the LSS api calls for dynamic
* setup of node ids.
*
* @param service_en LSS master services for indication functions
* errorCode_u16 Error code in the module
* errorSpec_u8 Specific error case that has occured
* pIdentity_pu32 LSS slave identity.
*
*/
static void SdlLssIndCallback(CO_LSS_MASTER_SERVICE_T service_en, uint16 errorCode_u16, uint8 errorSpec_u8, uint32 *pIdentity_pu32)
{
static uint8 matchedIndex_u8 = NMS_UINT8_MAX;
if (errorCode_u16 != 0u)
{
if (errorCode_u16 == NMS_UINT16_MAX)
{
/* ERROR */
}
else
{
/* ERROR */
}
if (service_en == CO_LSS_MASTER_SERVICE_STORE)
{
/* DEBUG INFO */
coLssSwitchGlobal(CO_LSS_STATE_WAITING);
}
return;
}
switch (service_en)
{
case CO_LSS_MASTER_SERVICE_NON_CONFIG_SLAVE:
/* DEBUG INFO */
coLssFastScan(SDL_LSS_TIMEOUT);
break;
case CO_LSS_MASTER_SERVICE_FASTSCAN:
/* Match detected node with lookup table */
for (uint8 i_u8 = 0u; i_u8 < SDL_LSS_NODE_COUNT; i_u8++)
{
if (pIdentity_pu32[0] == nodeLookupTable_gast[i_u8].vendorId_u32 &&
pIdentity_pu32[1] == nodeLookupTable_gast[i_u8].productId_u32 &&
pIdentity_pu32[2] == nodeLookupTable_gast[i_u8].versionNbr_u32 &&
pIdentity_pu32[3] == nodeLookupTable_gast[i_u8].serialNbr_u32)
{
coLssSwitchSelective(pIdentity_pu32[0], pIdentity_pu32[1],
pIdentity_pu32[2], pIdentity_pu32[3], 20);
matchedIndex_u8 = i_u8;
break;
}
}
break;
case CO_LSS_MASTER_SERVICE_SWITCH_SELECTIVE:
if (matchedIndex_u8 < SDL_LSS_NODE_COUNT)
{
coLssSetNodeId(nodeLookupTable_gast[matchedIndex_u8].nodeId_u8, SDL_LSS_TIMEOUT);
matchedIndex_u8 = NMS_UINT8_MAX;
}
else
{
/* ERROR */
}
break;
case CO_LSS_MASTER_SERVICE_SET_NODEID:
/* DEBUG INFO */
coLssInquireNodeId(SDL_LSS_TIMEOUT);
break;
case CO_LSS_MASTER_SERVICE_INQUIRE_NODEID:
/* DEBUG INFO */
coLssStoreConfig(200);
break;
case CO_LSS_MASTER_SERVICE_STORE:
/* DEBUG INFO */
coLssSwitchGlobal(CO_LSS_STATE_WAITING);
break;
default:
/* ERROR */
break;
}
}
/**
* @brief This function is called if a new NMT state of a node,
* is recordnized by the CANopen stack.
*
* @param nodeID_u8 Node id of the node that has registered a change.
* state_en Error control state
* nmtState_en NMT state of the particular node.
*
* @return void
*
*/
static void SdlLssHbMonitorCallback(uint8 nodeID_u8, CO_ERRCTRL_T state_en, CO_NMT_STATE_T nmtState_en)
{
uint8 arrIndex_u8;
/* look if node is monitored */
arrIndex_u8 = SdlLssGetNodeIndex(nodeID_u8);
/* handle monitored node */
if (arrIndex_u8 != NMS_UINT16_MAX)
{
/* save states */
nodeNMTState_gaen[arrIndex_u8] = nmtState_en;
/* indicate if monitored node lost heartbeat */
if (nmtState_en == CO_NMT_STATE_UNKNOWN)
{
/* To be transmitted via CAN */
/* ERROR */
}
/* indicate if monitored node sent a bootup message */
if (state_en == CO_ERRCTRL_BOOTUP)
{
/* INFO */
}
/* handle unmonitored node */
}
else
{
/* ERROR */
}
}
/**
* @brief This function tries to reset nodes with unknown NMT state.
*
* @param pData_pv Data.
*/
static void SdlLssResetNodesCallback(void *pData_pv)
{
uint8 arrIndex_u8;
(void)pData_pv;
/* reset defined nodes without known state */
for (arrIndex_u8 = 0u; arrIndex_u8 < SDL_LSS_NODE_COUNT; arrIndex_u8++)
{
if ((nodeNMTState_gaen[arrIndex_u8] != CO_NMT_STATE_PREOP) &&
(nodeNMTState_gaen[arrIndex_u8] != CO_NMT_STATE_OPERATIONAL))
{
/* reset node */
coNmtStateReq(nodeLookupTable_gast[arrIndex_u8].nodeId_u8, CO_NMT_STATE_RESET_NODE, CO_FALSE);
}
}
}