diff --git a/EnduranceTestBench/.cproject b/EnduranceTestBench/.cproject
index 3073a88..c91aa0f 100644
--- a/EnduranceTestBench/.cproject
+++ b/EnduranceTestBench/.cproject
@@ -71,6 +71,8 @@
+
+
@@ -126,6 +128,8 @@
+
+
@@ -159,7 +163,8 @@
-
+
+
@@ -233,6 +238,8 @@
+
+
@@ -287,6 +294,8 @@
+
+
@@ -313,10 +322,10 @@
+
+
-
-
diff --git a/EnduranceTestBench/.project b/EnduranceTestBench/.project
index 9641c51..75885d9 100644
--- a/EnduranceTestBench/.project
+++ b/EnduranceTestBench/.project
@@ -40,11 +40,25 @@
2
copy_PARENT/common
+
+ nms_can
+ 2
+ PROJECT_LOC/nms_can
+
+
+ nms_hal
+ 2
+ copy_PROJECT_LOC/nms_hal
+
copy_PARENT
$%7BPARENT-3-PROJECT_LOC%7D/Documents/NorthStar-Endurance-TestBench
+
+ copy_PROJECT_LOC
+ $%7BPARENT-1-copy_PARENT%7D/NorthStar-Production-Unit-Board-Firmware/ProcessBoardV1
+
diff --git a/EnduranceTestBench/Core/Src/adc.c b/EnduranceTestBench/Core/Src/adc.c
index 3b14772..03575a0 100644
--- a/EnduranceTestBench/Core/Src/adc.c
+++ b/EnduranceTestBench/Core/Src/adc.c
@@ -51,13 +51,13 @@ void MX_ADC1_Init(void)
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
- hadc1.Init.ContinuousConvMode = DISABLE;
+ hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
- hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
+ hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
diff --git a/EnduranceTestBench/Core/Src/main.c b/EnduranceTestBench/Core/Src/main.c
index bebc87e..d76251c 100644
--- a/EnduranceTestBench/Core/Src/main.c
+++ b/EnduranceTestBench/Core/Src/main.c
@@ -78,7 +78,7 @@ int main(void)
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
+ HAL_Init();
/* USER CODE BEGIN Init */
diff --git a/EnduranceTestBench/EnduranceTestBench.ioc b/EnduranceTestBench/EnduranceTestBench.ioc
index d94d3f7..19d2376 100644
--- a/EnduranceTestBench/EnduranceTestBench.ioc
+++ b/EnduranceTestBench/EnduranceTestBench.ioc
@@ -1,9 +1,11 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_1
ADC1.CommonPathInternal=null|null|null|null
-ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,CommonPathInternal
+ADC1.ContinuousConvMode=ENABLE
+ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,Overrun,ContinuousConvMode,CommonPathInternal
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.Overrun=ADC_OVR_DATA_OVERWRITTEN
ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
ADC1.master=1
@@ -206,8 +208,8 @@ ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=STM32CubeIDE
ProjectManager.ProjectBuild=false
-ProjectManager.ProjectFileName=ProcessBoardV1.ioc
-ProjectManager.ProjectName=ProcessBoardV1
+ProjectManager.ProjectFileName=EnduranceTestBench.ioc
+ProjectManager.ProjectName=EnduranceTestBench
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
diff --git a/EnduranceTestBench/nehemis/analogMeasurement.c b/EnduranceTestBench/nehemis/analogMeasurement.c
new file mode 100644
index 0000000..aea7159
--- /dev/null
+++ b/EnduranceTestBench/nehemis/analogMeasurement.c
@@ -0,0 +1,92 @@
+/**
+ * @file analogMeasurement.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 Source code for ADC data reading module.
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "analogMeasurement.h"
+#include "hal_adc.h"
+
+/******************************************************************************
+ * Macro Constant Declarations
+ ******************************************************************************/
+#define ADC_BUFFER_SIZE 9u
+
+/******************************************************************************
+ * Module Global Variable Declarations
+ ******************************************************************************/
+static uint16 adcBuffer_u32[ADC_BUFFER_SIZE];
+
+/******************************************************************************
+ * Private Function Declarations
+ ******************************************************************************/
+static void AnalogMeasurementInitBuffer(void);
+
+/******************************************************************************
+ * Function Definitions
+ ******************************************************************************/
+void AnalogMeasurementInit(void)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ AnalogMeasurementInitBuffer();
+
+ HalAdcCalibrate(MAP_HAL_ADC_1);
+ error_u32 = HalAdcStartDMA(MAP_HAL_ADC_1, (uint32 *)adcBuffer_u32, ADC_BUFFER_SIZE);
+
+ if (error_u32 != NMS_ERR_NONE)
+ {
+ /* Handle the error (DMA start failed) */
+ }
+}
+
+void AnalogMesaurementRun(void)
+{
+ HalAdcStartDMA(MAP_HAL_ADC_1, (uint32 *)adcBuffer_u32, sizeof(adcBuffer_u32));
+}
+
+
+void AnalogMeasurementReadData(uint32 channel_u32, uint32 *adcValue_pu32)
+{
+
+ if (adcValue_pu32 == NULL)
+ {
+ return; /* Prevent dereferencing NULL pointer */
+ }
+ __disable_irq();
+ switch (channel_u32)
+ {
+ case PS1_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[0]; break;
+ case PS2_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[1]; break;
+ case PS3_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[2]; break;
+ case PS4_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[3]; break;
+
+ case PMP_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[4]; break;
+
+ case FM1_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[5]; break;
+ case FM2_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[6]; break;
+ case FM3_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[7]; break;
+ case FM4_ADC_CHANNEL: *adcValue_pu32 = adcBuffer_u32[8]; break;
+ default: *adcValue_pu32 = 0uL; break;
+ }
+ __enable_irq();
+}
+
+/******************************************************************************
+ * Private Function Definitions
+ ******************************************************************************/
+/* @brief Initialize buffer with default values*/
+static void AnalogMeasurementInitBuffer(void)
+{
+ for (uint8 i_u8 = 0u; i_u8 < ADC_BUFFER_SIZE; i_u8++)
+ {
+ adcBuffer_u32[i_u8] = 0uL;
+ }
+}
diff --git a/EnduranceTestBench/nehemis/analogMeasurement.h b/EnduranceTestBench/nehemis/analogMeasurement.h
new file mode 100644
index 0000000..14d4db0
--- /dev/null
+++ b/EnduranceTestBench/nehemis/analogMeasurement.h
@@ -0,0 +1,53 @@
+/**
+ * @file analogMeasurement.h
+ *
+ * @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 ADC measurement module interface.
+ * This file provides function declarations and necessary definitions
+ * for reading analog sensor values using ADC with DMA. It defines
+ * ADC channel mappings, reference voltage, and resolution to ensure
+ * consistent data acquisition across multiple modules.
+ *
+ */
+#ifndef ANALOGMEASUREMENT_H_
+#define ANALOGMEASUREMENT_H_
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+/******************************************************************************
+ * Type declarations
+ ******************************************************************************/
+#define PS1_ADC_CHANNEL 1u
+#define PS2_ADC_CHANNEL 2u
+#define PS3_ADC_CHANNEL 3u
+#define PS4_ADC_CHANNEL 4u
+#define PMP_ADC_CHANNEL 5u
+#define FM1_ADC_CHANNEL 6u
+#define FM2_ADC_CHANNEL 7u
+#define FM3_ADC_CHANNEL 8u
+#define FM4_ADC_CHANNEL 9u
+
+#define ANALOG_MEAS_ADC_REF_VOLTAGE 3.3f
+#define ANALOG_MEAS_ADC_RESOLUTION 4095.0f /* 12-bit ADC */
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+/* @brief initialize the ADC, calibrate and Start the ADC in DMA mode */
+void AnalogMeasurementInit(void);
+
+void AnalogMesaurementRun(void);
+
+/**
+ * @brief Reads the latest ADC value for the specified channel.
+ *
+ * @param channel_u32 The ADC channel to read from.
+ * adcValue Pointer to store the retrieved ADC value.
+ */
+void AnalogMeasurementReadData(uint32 channel_u32, uint32 * adcValue_pu32);
+
+#endif /* ANALOGMEASUREMENT_H_ */
diff --git a/EnduranceTestBench/nehemis/appl.h b/EnduranceTestBench/nehemis/appl.h
new file mode 100644
index 0000000..dbe430f
--- /dev/null
+++ b/EnduranceTestBench/nehemis/appl.h
@@ -0,0 +1,42 @@
+#include "nms_types.h"
+
+extern char string1[];
+extern char string2[];
+
+extern OCTET_STRING octet1[];
+extern OCTET_STRING octet2[];
+
+extern CO_DOMAIN_PTR pDomain1;
+extern CO_DOMAIN_PTR pDomain2;
+
+#ifdef xxx
+RET_T sdoServInd(CO_LINE_TYPE, BOOL_T, UNSIGNED8, UNSIGNED16, UNSIGNED8);
+RET_T sdoServWrInd(CO_LINE_TYPE, BOOL_T, UNSIGNED8, UNSIGNED16, UNSIGNED8);
+RET_T sdoServChkInd(CO_LINE_TYPE, BOOL_T, UNSIGNED8, UNSIGNED16, UNSIGNED8, const UNSIGNED8 *);
+void errCtrl(CO_LINE_DECL, UNSIGNED8, CO_ERRCTRL_T, CO_NMT_STATE_T);
+RET_T nmtInd(CO_LINE_DECL, BOOL_T, CO_NMT_STATE_T);
+void pdoInd(CO_LINE_TYPE, UNSIGNED16);
+void pdoRecInd(CO_LINE_TYPE, UNSIGNED16);
+void pdoSyncInd(CO_LINE_TYPE, UNSIGNED16);
+void syncInd(CO_LINE_TYPE);
+void syncFinishedInd(CO_LINE_TYPE);
+void ledRedInd(CO_LINE_TYPE, BOOL_T);
+void ledGreenInd(CO_LINE_TYPE, BOOL_T);
+void canInd(CO_LINE_TYPE, CO_CAN_STATE_T);
+void commInd(CO_LINE_TYPE, CO_COMM_STATE_EVENT_T);
+void sdoClRd(CO_LINE_TYPE, UNSIGNED8, UNSIGNED16, UNSIGNED8, UNSIGNED32, UNSIGNED32);
+void sdoClWr(CO_LINE_TYPE, UNSIGNED8, UNSIGNED16, UNSIGNED8, UNSIGNED32);
+void sdoQuInd(CO_LINE_TYPE, void *pData, UNSIGNED32 result);
+RET_T emcyInd(CO_LINE_TYPE, UNSIGNED16 errCode, const UNSIGNED8 *addErrorCode);
+void emcyConsInd(CO_LINE_TYPE, UNSIGNED8 node, UNSIGNED16 errCode, UNSIGNED8 errorRegister, UNSIGNED8 const *addErrorCode);
+void timeInd(CO_LINE_TYPE, CO_TIME_T *pTime);
+RET_T storeInd(CO_LINE_DECL, UNSIGNED8 subIndex);
+#endif
+
+
+void sdoClientReadInd(UNSIGNED8 canLine, UNSIGNED8 sdoNr, UNSIGNED16 index,
+ UNSIGNED8 subIndex, UNSIGNED32 size, UNSIGNED32 result);
+void sdoClientWriteInd(UNSIGNED8 canLine, UNSIGNED8 sdoNr,
+ UNSIGNED16 index, UNSIGNED8 subIndex, UNSIGNED32 result);
+
+uint8 getMyNodeId(CO_LINE_DECL);
diff --git a/EnduranceTestBench/nehemis/enduranceTestBench.c b/EnduranceTestBench/nehemis/enduranceTestBench.c
index 425d3a7..fe74149 100644
--- a/EnduranceTestBench/nehemis/enduranceTestBench.c
+++ b/EnduranceTestBench/nehemis/enduranceTestBench.c
@@ -13,12 +13,12 @@
* Include Header Files
******************************************************************************/
#include "enduranceTestBench.h"
-#include "hal_system.h"
#include "stdlib.h"
/* CANopen includes */
#include
#include
+#include "hal_system.h"
/******************************************************************************
* Macro constant declarations
diff --git a/EnduranceTestBench/nehemis/flowmeter.c b/EnduranceTestBench/nehemis/flowmeter.c
index b0f3ddb..a743cca 100644
--- a/EnduranceTestBench/nehemis/flowmeter.c
+++ b/EnduranceTestBench/nehemis/flowmeter.c
@@ -14,6 +14,7 @@
******************************************************************************/
#include "nms_types.h"
#include "flowmeter.h"
+#include "analogMeasurement.h"
/******************************************************************************
* Type declarations
@@ -22,38 +23,34 @@
/******************************************************************************
* Macro Constant Declarations
******************************************************************************/
-#define FLOWMETER_ADC_REF_VOLTAGE 3.3f
-#define FLOWMETER_ADC_RESOLUTION 4095.0f /* 12-bit ADC */
+
/******************************************************************************
* Private function Declarations
******************************************************************************/
-static float32 FlowmeterReadVoltage(FlowmeterMain_st *flowmeter_pst);
-
+static void FlowmeterReadVoltage(FlowmeterMain_st * flowmeter_pst);
+FlowmeterMain_st *flowmeter_gpst;
/******************************************************************************
* Extern Function Definitions
******************************************************************************/
-void FlowmeterInit(FlowmeterMain_st *flowmeter_pst, ADC_HandleTypeDef *adcHandle_pst, uint32 channel_u32)
+void FlowmeterInit(FlowmeterMain_st *flowmeter_pst)
{
- if (flowmeter_pst == NULL || adcHandle_pst == NULL)
+ if (flowmeter_pst == NULL)
{
/* ERROR */
}
- flowmeter_pst->adcHandle_pst = adcHandle_pst;
- flowmeter_pst->channel_u32 = channel_u32;
flowmeter_pst->mKu_f32 = 5.0f; // Default value
}
-
void FlowmeterGetFlow(FlowmeterMain_st *flowmeter_pst)
{
if (flowmeter_pst == NULL)
{
/* ERROR */
}
-
- flowmeter_pst->rawQ_f32 = flowmeter_pst->mKu_f32 * FlowmeterReadVoltage(flowmeter_pst);
+ FlowmeterReadVoltage(flowmeter_pst);
+ flowmeter_pst->rawQ_f32 = flowmeter_pst->mKu_f32 * flowmeter_pst->voltage_f32;
}
@@ -88,40 +85,11 @@ void FlowmeterSetKu(FlowmeterMain_st *flowmeter_pst, float32 ku_f32)
* @return ADC output voltage based on sensor reading.
*
*/
-static float32 FlowmeterReadVoltage(FlowmeterMain_st *flowmeter_pst)
+static void FlowmeterReadVoltage(FlowmeterMain_st *flowmeter_pst)
{
- uint32 adcVal_u32 = 0uL;
- if (flowmeter_pst == NULL || flowmeter_pst->adcHandle_pst == NULL)
- {
- return 0.0f; /* Error Case */
- }
-
- ADC_ChannelConfTypeDef sConfig = {0};
- sConfig.Channel = flowmeter_pst->channel_u32; /* Set the channel specific to this flowmeter */
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
-
- if (HAL_ADC_ConfigChannel(flowmeter_pst->adcHandle_pst, &sConfig) != HAL_OK)
- {
- return 0.0f; /* ERROR */
- }
-
- /* Start ADC conversion and poll for completion */
- if (HAL_ADC_Start(flowmeter_pst->adcHandle_pst) == HAL_OK)
- {
- if (HAL_ADC_PollForConversion(flowmeter_pst->adcHandle_pst, HAL_MAX_DELAY) == HAL_OK)
- {
- adcVal_u32 = HAL_ADC_GetValue(flowmeter_pst->adcHandle_pst);
- }
- HAL_ADC_Stop(flowmeter_pst->adcHandle_pst);
- }
- else
- {
- /* ERROR */
- }
-
/* Convert ADC value to voltage (assuming 12-bit resolution and 3.3V reference) */
- float32 voltage_f32 = (float)adcVal_u32 * (FLOWMETER_ADC_REF_VOLTAGE / FLOWMETER_ADC_RESOLUTION);
+ uint32 adcVal_u32 = 0uL;
+ AnalogMeasurementReadData(flowmeter_pst->channel_u32, &adcVal_u32);
- return voltage_f32;
+ flowmeter_pst->voltage_f32 = (float32)adcVal_u32 * (ANALOG_MEAS_ADC_REF_VOLTAGE / ANALOG_MEAS_ADC_RESOLUTION);
}
diff --git a/EnduranceTestBench/nehemis/flowmeter.h b/EnduranceTestBench/nehemis/flowmeter.h
index eecb209..4431c4c 100644
--- a/EnduranceTestBench/nehemis/flowmeter.h
+++ b/EnduranceTestBench/nehemis/flowmeter.h
@@ -22,19 +22,16 @@
******************************************************************************/
typedef struct
{
- ADC_HandleTypeDef *adcHandle_pst;
float32 mKu_f32;
uint32 channel_u32;
float32 rawQ_f32;
+ float32 voltage_f32;
} FlowmeterMain_st; /* HubaFlowmeter structure definition */
/******************************************************************************
* Macro Constant Declarations
******************************************************************************/
-#define FLOWMETER_FM1_ADC_CHANNEL 6u
-#define FLOWMETER_FM2_ADC_CHANNEL 7u
-#define FLOWMETER_FM3_ADC_CHANNEL 8u
-#define FLOWMETER_FM4_ADC_CHANNEL 9u
+
/******************************************************************************
* Extern Function Declarations
******************************************************************************/
@@ -42,13 +39,11 @@ typedef struct
* @brief Init function of the Flowmeter module.
*
* @param flowmeter_pst : Pointer to main strucutre of the module.
- * adcHandle_pst : ADC handler f the flowmeter.
- * channel_u32 : ADC channel of the connected sensor to use.
*
* @return Flow rate value.
*
*/
-void FlowmeterInit(FlowmeterMain_st *flowmeter_pst, ADC_HandleTypeDef *adcHandle_pst, uint32 channel_u32);
+void FlowmeterInit(FlowmeterMain_st *flowmeter_pst);
/**
* @brief Function to get flow value
diff --git a/EnduranceTestBench/nehemis/grundfos.c b/EnduranceTestBench/nehemis/grundfos.c
index d9ec135..406e23e 100644
--- a/EnduranceTestBench/nehemis/grundfos.c
+++ b/EnduranceTestBench/nehemis/grundfos.c
@@ -13,8 +13,9 @@
* Include Header Files
******************************************************************************/
#include "grundfos.h"
-#include "gpio.h"
-#include "i2c.h"
+#include "analogMeasurement.h"
+#include "hal_gpio.h"
+#include "hal_i2c.h"
/******************************************************************************
* Type declarations
******************************************************************************/
@@ -22,40 +23,31 @@
/******************************************************************************
* Macro Constant Declarations
******************************************************************************/
-#define GRUNDFOS_PMP_ADC_CHANNEL 5u
-#define GRUNDFOS_PMP_ADC_REF_VOLTAGE 3.3f
-#define GRUNDFOS_PMP_ADC_RESOLUTION 4095.0f /* 12-bit ADC */
-#define GRUNDFOS_PMP_ADC_MODULE &hadc1
-
-#define GRUNDFOS_PMP_ENABLE_GPIO_PORT GPIOB
-#define GRUNDFOS_PMP_ENABLE_GPIO_PIN GPIO_PIN_15
-
-#define GRUNDFOS_PMP_I2C_HANDLE &hi2c4
-#define GRUNDFOS_PMP_INTERNAL_DAC_ADDR 0x61
+#define GRUNDFOS_PMP_INTERNAL_DAC_ADDR (0x61 << 1)
/******************************************************************************
* Private function Declarations
******************************************************************************/
-static uint32 GrundfosPmpReadVoltage(void);
+static uint32 GrundfosPmpReadVoltage(uint8 channel_u8);
/******************************************************************************
* Extern Function Definitions
******************************************************************************/
void GrundfosPmpEnable(uint8 state_u8)
{
- if(state_u8 == 1u)
+ if(state_u8 == 0u)
{
- HAL_GPIO_WritePin(GRUNDFOS_PMP_ENABLE_GPIO_PORT, GRUNDFOS_PMP_ENABLE_GPIO_PIN, GPIO_PIN_SET);
+ HalGpioWrite(MAP_HAL_PMP_ENABLE, HAL_GPIO_STATE_HIGH); /* Pulling the line high stops the pump */
}
else
{
- HAL_GPIO_WritePin(GRUNDFOS_PMP_ENABLE_GPIO_PORT, GRUNDFOS_PMP_ENABLE_GPIO_PIN, GPIO_PIN_RESET);
+ HalGpioWrite(MAP_HAL_PMP_ENABLE, HAL_GPIO_STATE_LOW);
}
}
-uint32 GrundfosPmpFeedbackSpeed(void)
+uint32 GrundfosPmpFeedbackSpeed(uint8 channel_u8)
{
- uint32 feedbackSpeed_u32 = (GrundfosPmpReadVoltage()) * 360uL;
+ uint32 feedbackSpeed_u32 = (GrundfosPmpReadVoltage(channel_u8)) * 360uL;
return feedbackSpeed_u32;
}
@@ -64,29 +56,31 @@ uint32 GrundfosPmpFeedbackSpeed(void)
bool GrundfosPmpSetSpeed(float32 setSpeed_f32)
{
uint8 data_au8[2];
- uint16 dacVal_u16;
+ static volatile uint16 dacVal_u16 = 0u;
+ /* Limit the input range to 0V - 10V */
if (setSpeed_f32 < 0.0f)
{
- setSpeed_f32 = 0.0f;
+ setSpeed_f32 = 0.0f;
}
else if (setSpeed_f32 > 10.0f)
{
- setSpeed_f32 = 10.0f;
- }
- else
- {
- /* Do nothing. */
+ setSpeed_f32 = 10.0f;
}
- dacVal_u16 = (uint16)(setSpeed_f32 * (GRUNDFOS_PMP_ADC_RESOLUTION / 10.0f));
+ /* Convert pump speed (0-10V) to DAC value (0-5V output) */
+ dacVal_u16 = (uint16)((setSpeed_f32 * 4095.0f) / 10.0f);
- data_au8[0] = (uint8)(dacVal_u16 >> 4); /* Upper 8 bits */
- data_au8[1] = (uint8)((dacVal_u16 & 0x0F) << 4); /* Lower 4 bits shifted to the upper nibble */
+ /* Format the 12-bit DAC value into the correct byte format */
+ data_au8[0] = (uint8)(dacVal_u16 >> 8); /* Upper 8 bits */
+ data_au8[1] = (uint8)(dacVal_u16 & 0xFF); /* Lower 8 bits */
- return HAL_I2C_Master_Transmit(GRUNDFOS_PMP_I2C_HANDLE, GRUNDFOS_PMP_INTERNAL_DAC_ADDR, data_au8, 2u, HAL_MAX_DELAY) == HAL_OK;
+ return HalI2CMasterTransmit(MAP_HAL_GRUNDFOS_PMP_I2C_HANDLE,
+ GRUNDFOS_PMP_INTERNAL_DAC_ADDR,
+ data_au8, 2u) == NMS_ERR_NONE;
}
+
/******************************************************************************
* Private function Definitions
******************************************************************************/
@@ -96,33 +90,13 @@ bool GrundfosPmpSetSpeed(float32 setSpeed_f32)
* @return ADC output voltage based on sensor reading.
*
*/
-static uint32 GrundfosPmpReadVoltage(void)
+static uint32 GrundfosPmpReadVoltage(uint8 channel_u8)
{
- uint32_t adcVal_u32 = 0uL;
- ADC_ChannelConfTypeDef sConfig = {0};
- sConfig.Channel = GRUNDFOS_PMP_ADC_CHANNEL; /* Set the channel specific to this flowmeter */
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
+ /* Convert ADC value to voltage (assuming 12-bit resolution and 3.3V reference) */
+ uint32 adcVal_u32 = 0uL;
+ AnalogMeasurementReadData(channel_u8, &adcVal_u32);
+ float32 voltage_f32 = (float32)adcVal_u32 * (ANALOG_MEAS_ADC_REF_VOLTAGE / ANALOG_MEAS_ADC_RESOLUTION);
- if (HAL_ADC_ConfigChannel(GRUNDFOS_PMP_ADC_MODULE, &sConfig) != HAL_OK)
- {
- return 0.0f; /* ERROR */
- }
-
- if (HAL_ADC_Start(GRUNDFOS_PMP_ADC_MODULE) == HAL_OK)
- {
- if (HAL_ADC_PollForConversion(GRUNDFOS_PMP_ADC_MODULE, HAL_MAX_DELAY) == HAL_OK)
- {
- adcVal_u32 = HAL_ADC_GetValue(GRUNDFOS_PMP_ADC_MODULE);
- }
- HAL_ADC_Stop(GRUNDFOS_PMP_ADC_MODULE);
- }
- else
- {
- /* ERROR */
- }
-
- uint32 voltage_u32 = adcVal_u32 * (GRUNDFOS_PMP_ADC_REF_VOLTAGE / GRUNDFOS_PMP_ADC_RESOLUTION);
-
- return voltage_u32;
+ return voltage_f32;
}
+
diff --git a/EnduranceTestBench/nehemis/grundfos.h b/EnduranceTestBench/nehemis/grundfos.h
index 75a8da7..941a988 100644
--- a/EnduranceTestBench/nehemis/grundfos.h
+++ b/EnduranceTestBench/nehemis/grundfos.h
@@ -21,6 +21,11 @@
/******************************************************************************
* Type declarations
******************************************************************************/
+typedef struct
+{
+ uint32 channel_u32;
+ float32 rawQ_f32;
+} GrundfosMain_st; /* Grundfos structure definition */
/******************************************************************************
* Macro Constant Declarations
@@ -29,7 +34,7 @@
/******************************************************************************
* Extern Function Declarations
******************************************************************************/
-extern uint32_t GrundfosPmpFeedbackSpeed(void);
-extern void GrundfosPmpEnable(uint8_t state_u8);
-extern bool GrundfosPmpSetSpeed(float setSpeed_f);
+uint32 GrundfosPmpFeedbackSpeed(uint8 channel_u8);
+void GrundfosPmpEnable(uint8_t state_u8);
+bool GrundfosPmpSetSpeed(float setSpeed_f);
#endif /* GRUNDFOS_H_ */
diff --git a/EnduranceTestBench/nehemis/od_entries.h b/EnduranceTestBench/nehemis/od_entries.h
index 3e2a08b..7fffee4 100644
--- a/EnduranceTestBench/nehemis/od_entries.h
+++ b/EnduranceTestBench/nehemis/od_entries.h
@@ -13,44 +13,49 @@
#define OD_ENTRIES_H_
/* Device Indexes */
-#define OD_ENTRY_PU_MOTOR_CTRL_INDEX 0x6000
-#define OD_ENTRY_PU_COND_DATA_IN_INDEX 0x6001
-#define OD_ENTRY_PU_COND_DATA_OUT_INDEX 0x6002
-#define OD_ENTRY_PU_MOTOR_DATA_OUT_INDEX 0x6003
-#define OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX 0x6004
-#define OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX 0x6005
+#define OD_ENTRY_PU_MOTOR_CTRL_INDEX 0x6000
+#define OD_ENTRY_PU_COND_DATA_IN_INDEX 0x6001
+#define OD_ENTRY_PU_COND_DATA_OUT_INDEX 0x6002
+#define OD_ENTRY_PU_MOTOR_DATA_OUT_INDEX 0x6003
+#define OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX 0x6004
+#define OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX 0x6005
+#define OD_ENTRY_PU_GRUNDFOS_PUMP_CONTROL_INDEX 0x6006
/* Device Sub-indexes */
-#define OD_ENTRY_PU_MOTOR_CTRL_ID_SUB_INDEX 0x01
-#define OD_ENTRY_PU_MOTOR_CTRL_CMD_SUB_INDEX 0x02
-#define OD_ENTRY_PU_MOTOR_CTRL_POS_SUB_INDEX 0x03
-#define OD_ENTRY_PU_MOTOR_CTRL_PRESSURE_SUB_INDEX 0x04
-#define OD_ENTRY_PU_MOTOR_CTRL_FLOW_SUB_INDEX 0x05
+#define OD_ENTRY_PU_MOTOR_CTRL_ID_SUB_INDEX 0x01
+#define OD_ENTRY_PU_MOTOR_CTRL_CMD_SUB_INDEX 0x02
+#define OD_ENTRY_PU_MOTOR_CTRL_POS_SUB_INDEX 0x03
+#define OD_ENTRY_PU_MOTOR_CTRL_PRESSURE_SUB_INDEX 0x04
+#define OD_ENTRY_PU_MOTOR_CTRL_FLOW_SUB_INDEX 0x05
-#define OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX 0x01
-#define OD_ENTRY_PU_COND2_DATA_IN_SUB_INDEX 0x03
-#define OD_ENTRY_PU_COND3_DATA_IN_SUB_INDEX 0x05
+#define OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX 0x01
+#define OD_ENTRY_PU_COND2_DATA_IN_SUB_INDEX 0x03
+#define OD_ENTRY_PU_COND3_DATA_IN_SUB_INDEX 0x05
-#define OD_ENTRY_PU_TEMP1_DATA_IN_SUB_INDEX 0x02
-#define OD_ENTRY_PU_TEMP2_DATA_IN_SUB_INDEX 0x04
-#define OD_ENTRY_PU_TEMP3_DATA_IN_SUB_INDEX 0x06
+#define OD_ENTRY_PU_TEMP1_DATA_IN_SUB_INDEX 0x02
+#define OD_ENTRY_PU_TEMP2_DATA_IN_SUB_INDEX 0x04
+#define OD_ENTRY_PU_TEMP3_DATA_IN_SUB_INDEX 0x06
-#define OD_ENTRY_PU_COND1_DATA_OUT_SUB_INDEX 0x01
-#define OD_ENTRY_PU_COND2_DATA_OUT_SUB_INDEX 0x03
-#define OD_ENTRY_PU_COND3_DATA_OUT_SUB_INDEX 0x05
+#define OD_ENTRY_PU_COND1_DATA_OUT_SUB_INDEX 0x01
+#define OD_ENTRY_PU_COND2_DATA_OUT_SUB_INDEX 0x03
+#define OD_ENTRY_PU_COND3_DATA_OUT_SUB_INDEX 0x05
-#define OD_ENTRY_PU_TEMP1_DATA_OUT_SUB_INDEX 0x02
-#define OD_ENTRY_PU_TEMP2_DATA_OUT_SUB_INDEX 0x04
-#define OD_ENTRY_PU_TEMP3_DATA_OUT_SUB_INDEX 0x06
+#define OD_ENTRY_PU_TEMP1_DATA_OUT_SUB_INDEX 0x02
+#define OD_ENTRY_PU_TEMP2_DATA_OUT_SUB_INDEX 0x04
+#define OD_ENTRY_PU_TEMP3_DATA_OUT_SUB_INDEX 0x06
-#define OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX 0x01
-#define OD_ENTRY_PU_FLOWMETER2_DATA_OUT_SUB_INDEX 0x02
-#define OD_ENTRY_PU_FLOWMETER3_DATA_OUT_SUB_INDEX 0x03
-#define OD_ENTRY_PU_FLOWMETER4_DATA_OUT_SUB_INDEX 0x04
+#define OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX 0x01
+#define OD_ENTRY_PU_FLOWMETER2_DATA_OUT_SUB_INDEX 0x02
+#define OD_ENTRY_PU_FLOWMETER3_DATA_OUT_SUB_INDEX 0x03
+#define OD_ENTRY_PU_FLOWMETER4_DATA_OUT_SUB_INDEX 0x04
-#define OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX 0x01
-#define OD_ENTRY_PU_PRESSURE2_DATA_OUT_SUB_INDEX 0x02
-#define OD_ENTRY_PU_PRESSURE3_DATA_OUT_SUB_INDEX 0x03
-#define OD_ENTRY_PU_PRESSURE4_DATA_OUT_SUB_INDEX 0x04
+#define OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX 0x01
+#define OD_ENTRY_PU_PRESSURE2_DATA_OUT_SUB_INDEX 0x02
+#define OD_ENTRY_PU_PRESSURE3_DATA_OUT_SUB_INDEX 0x03
+#define OD_ENTRY_PU_PRESSURE4_DATA_OUT_SUB_INDEX 0x04
+
+#define OD_ENTRY_PU_GRUNDFOS_PUMP_ENABLE_SUB_INDEX 0x01
+#define OD_ENTRY_PU_GRUNDFOS_PUMP_SET_SPEED_SUB_INDEX 0x02
+#define OD_ENTRY_PU_GRUNDFOS_PUMP_FEEDBACK_SUB_INDEX 0x03
#endif /* OD_ENTRIES_H_ */
diff --git a/EnduranceTestBench/nehemis/pressureSensor.c b/EnduranceTestBench/nehemis/pressureSensor.c
index 9f8ea92..1415b5e 100644
--- a/EnduranceTestBench/nehemis/pressureSensor.c
+++ b/EnduranceTestBench/nehemis/pressureSensor.c
@@ -13,6 +13,7 @@
* Include Header Files
******************************************************************************/
#include "pressureSensor.h"
+#include "analogMeasurement.h"
/******************************************************************************
* Type declarations
@@ -21,27 +22,21 @@
/******************************************************************************
* Macro Constant Declarations
******************************************************************************/
-#define PRESSURE_SENSOR_ADC_REF_VOLTAGE 3.3f
-#define PRESSURE_SENSOR_ADC_RESOLUTION 4095.0f /* 12-bit ADC */
/******************************************************************************
* Private function Declarations
******************************************************************************/
-static float PressureSensorReadVoltage(PressureSensorMain_st *pressureSensor_pst);
+static float PressureSensorReadVoltage(uint32 channel_u32);
/******************************************************************************
* Extern Function Definitions
******************************************************************************/
-void PressureSensorInit(PressureSensorMain_st *pressureSensor_pst,
- ADC_HandleTypeDef *adcHandle_pst, uint32_t channel_u32)
+void PressureSensorInit(PressureSensorMain_st *pressureSensor_pst)
{
- if (pressureSensor_pst == NULL || adcHandle_pst == NULL)
+ if (pressureSensor_pst == NULL)
{
/* ERROR */
}
-
- pressureSensor_pst->adcHandle_pst = adcHandle_pst;
- pressureSensor_pst->channel_u32 = channel_u32;
}
@@ -52,7 +47,7 @@ void PressureSensorGetVal(PressureSensorMain_st *pressureSensor_pst)
/* ERROR */
}
- pressureSensor_pst->rawT_f32 = (PressureSensorReadVoltage(pressureSensor_pst) - 0.5f) / 0.2f;
+ pressureSensor_pst->rawT_f32 = (PressureSensorReadVoltage(pressureSensor_pst->channel_u32) - 0.5f) / 0.2f;
}
@@ -67,40 +62,12 @@ void PressureSensorGetVal(PressureSensorMain_st *pressureSensor_pst)
* @return ADC output voltage based on sensor reading.
*
*/
-static float32 PressureSensorReadVoltage(PressureSensorMain_st *pressureSensor_pst)
+static float32 PressureSensorReadVoltage(uint32 channel_u32)
{
- uint32 adcVal_u32 = 0uL;
- if (pressureSensor_pst == NULL || pressureSensor_pst->adcHandle_pst == NULL)
- {
- return 0.0f; /* Error Case */
- }
-
- ADC_ChannelConfTypeDef sConfig = {0};
- sConfig.Channel = pressureSensor_pst->channel_u32; /* Set the channel specific to this flowmeter */
- sConfig.Rank = ADC_REGULAR_RANK_1;
- sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
-
- if (HAL_ADC_ConfigChannel(pressureSensor_pst->adcHandle_pst, &sConfig) != HAL_OK)
- {
- return 0.0f; /* ERROR */
- }
-
- /* Start ADC conversion and poll for completion */
- if (HAL_ADC_Start(pressureSensor_pst->adcHandle_pst) == HAL_OK)
- {
- if (HAL_ADC_PollForConversion(pressureSensor_pst->adcHandle_pst, HAL_MAX_DELAY) == HAL_OK)
- {
- adcVal_u32 = HAL_ADC_GetValue(pressureSensor_pst->adcHandle_pst);
- }
- HAL_ADC_Stop(pressureSensor_pst->adcHandle_pst);
- }
- else
- {
- /* ERROR */
- }
-
/* Convert ADC value to voltage (assuming 12-bit resolution and 3.3V reference) */
- float32 voltage_f32 = (float32)adcVal_u32 * (PRESSURE_SENSOR_ADC_REF_VOLTAGE / PRESSURE_SENSOR_ADC_RESOLUTION);
+ uint32 adcVal_u32 = 0uL;
+ AnalogMeasurementReadData(channel_u32, &adcVal_u32);
+ float32 voltage_f32 = (float32)adcVal_u32 * (ANALOG_MEAS_ADC_REF_VOLTAGE / ANALOG_MEAS_ADC_RESOLUTION);
return voltage_f32;
}
diff --git a/EnduranceTestBench/nehemis/pressureSensor.h b/EnduranceTestBench/nehemis/pressureSensor.h
index 3907271..7148bb8 100644
--- a/EnduranceTestBench/nehemis/pressureSensor.h
+++ b/EnduranceTestBench/nehemis/pressureSensor.h
@@ -19,7 +19,6 @@
******************************************************************************/
typedef struct
{
- ADC_HandleTypeDef *adcHandle_pst;
uint32 channel_u32;
float32 rawT_f32;
} PressureSensorMain_st; /* HubaPressure sensor structure definition */
@@ -27,10 +26,7 @@ typedef struct
/******************************************************************************
* Macro Constant Declarations
******************************************************************************/
-#define PRESSURE_SENSOR_PS1_ADC_CHANNEL 1u
-#define PRESSURE_SENSOR_PS2_ADC_CHANNEL 2u
-#define PRESSURE_SENSOR_PS3_ADC_CHANNEL 3u
-#define PRESSURE_SENSOR_PS4_ADC_CHANNEL 4u
+
/******************************************************************************
* Extern Function Declarations
******************************************************************************/
@@ -38,14 +34,11 @@ typedef struct
* @brief Init function of the Pressure sensor module.
*
* @param pressureSensor_pst : Pointer to main strucutre of the module.
- * adcHandle_pst : ADC handler f the flowmeter.
- * channel_u32 : ADC channel of the connected sensor to use.
*
* @return Pressure value.
*
*/
-void PressureSensorInit(PressureSensorMain_st *pressureSensor_pst,
- ADC_HandleTypeDef *adcHandle_pst, uint32 channel_u32);
+void PressureSensorInit(PressureSensorMain_st *pressureSensor_pst);
/**
* @brief Function to get pressure value.
diff --git a/EnduranceTestBench/nehemis/processBoard.c b/EnduranceTestBench/nehemis/processBoard.c
index 3696d5b..278ceaa 100644
--- a/EnduranceTestBench/nehemis/processBoard.c
+++ b/EnduranceTestBench/nehemis/processBoard.c
@@ -15,8 +15,10 @@
#include "processBoard.h"
#include "flowmeter.h"
#include "pressureSensor.h"
+#include "grundfos.h"
#include "od_entries.h"
-#include "co_odaccess.h"
+#include "nms_can.h"
+#include "analogMeasurement.h"
/******************************************************************************
* Type declarations
******************************************************************************/
@@ -24,14 +26,14 @@
/******************************************************************************
* Macro Constant Declarations
******************************************************************************/
-#define PROCESS_BOARD_VALVE_POS_INDEX 0x6002
-#define PROCESS_BOARD_VALVE_FLOW_INDEX 0x6006
-#define PROCESS_BOARD_VALVE_PRESSURE_INDEX 0x6001
+#define PROCESS_BOARD_VALVE_POS_INDEX 0x6002
+#define PROCESS_BOARD_VALVE_FLOW_INDEX 0x6006
+#define PROCESS_BOARD_VALVE_PRESSURE_INDEX 0x6001
-#define PROCESS_BOARD_VALVE_SUB_INDEX 0x0
+#define PROCESS_BOARD_VALVE_SUB_INDEX 0x0
-#define PROCESS_BOARD_FLOWMETER_ADC_MODULE &hadc1
-#define PROCESS_BOARD_PRESSURE_SENSOR_ADC_MODULE &hadc1
+#define PU_CANOPEN_SLAVE_LINE 0u
+#define PU_CANOPEN_MASTER_LINE 1u
/******************************************************************************
* Global variables
******************************************************************************/
@@ -49,6 +51,8 @@ PressureSensorMain_st pressureSensorPS2_gst;
PressureSensorMain_st pressureSensorPS3_gst;
PressureSensorMain_st pressureSensorPS4_gst;
+GrundfosMain_st grundfosPMP_gst;
+
ProcessBoardCondDataSt condBoard1_gst;
ProcessBoardCondDataSt condBoard2_gst;
ProcessBoardCondDataSt condBoard3_gst;
@@ -70,9 +74,10 @@ static void ProcessBoardTriggerMvCartCtrl(uint8 motorId_u8, uint8 flowRate_u8, u
static void ProcessBoardReadCondDataIN(void);
static void ProcessBoardWriteCondDataOUT(void);
static void ProcessBoardReadMvDataIN(void);
-static void ProcessBoardFlowmeterDataOUT(FlowmeterMain_st flowmeter_st);
-static void ProcessBoardPressureSensorDataOUT(PressureSensorMain_st pressureSensor_st);
-
+static void ProcessBoardFlowmeterDataOUT(float32 rawQ_f32);
+static void ProcessBoardPressureSensorDataOUT(float32 rawT_f32);
+static void ProcessBoardPumpSpeedDataOUT(uint32 pmpSpeed_u32);
+static void ProcessBoardGrundfosPumpHandler(void);
/******************************************************************************
* Extern Function Declarations
******************************************************************************/
@@ -80,48 +85,73 @@ void ProcessBoardInit(void)
{
motorCmd_gu8 = 0u;
- FlowmeterInit(&flowmeterFM1_gst, PROCESS_BOARD_FLOWMETER_ADC_MODULE, FLOWMETER_FM1_ADC_CHANNEL);
- PressureSensorInit(&pressureSensorPS1_gst, PROCESS_BOARD_PRESSURE_SENSOR_ADC_MODULE, PRESSURE_SENSOR_PS1_ADC_CHANNEL);
+ /* Initializing the structures (Pressure sensor, Flow
+ * meter, and Grundfos) with their respective ADC channel */
+ pressureSensorPS1_gst.channel_u32 = PS1_ADC_CHANNEL;
+ pressureSensorPS2_gst.channel_u32 = PS2_ADC_CHANNEL;
+ pressureSensorPS3_gst.channel_u32 = PS3_ADC_CHANNEL;
+ pressureSensorPS4_gst.channel_u32 = PS4_ADC_CHANNEL;
- FlowmeterInit(&flowmeterFM2_gst, PROCESS_BOARD_FLOWMETER_ADC_MODULE, FLOWMETER_FM2_ADC_CHANNEL);
- PressureSensorInit(&pressureSensorPS2_gst, PROCESS_BOARD_PRESSURE_SENSOR_ADC_MODULE, PRESSURE_SENSOR_PS2_ADC_CHANNEL);
+ grundfosPMP_gst.channel_u32 = PMP_ADC_CHANNEL;
- FlowmeterInit(&flowmeterFM3_gst, PROCESS_BOARD_FLOWMETER_ADC_MODULE, FLOWMETER_FM3_ADC_CHANNEL);
- PressureSensorInit(&pressureSensorPS3_gst, PROCESS_BOARD_PRESSURE_SENSOR_ADC_MODULE, PRESSURE_SENSOR_PS3_ADC_CHANNEL);
-
- FlowmeterInit(&flowmeterFM4_gst, PROCESS_BOARD_FLOWMETER_ADC_MODULE, FLOWMETER_FM4_ADC_CHANNEL);
- PressureSensorInit(&pressureSensorPS4_gst, PROCESS_BOARD_PRESSURE_SENSOR_ADC_MODULE, PRESSURE_SENSOR_PS4_ADC_CHANNEL);
+ flowmeterFM1_gst.channel_u32 = FM1_ADC_CHANNEL;
+ flowmeterFM2_gst.channel_u32 = FM2_ADC_CHANNEL;
+ flowmeterFM3_gst.channel_u32 = FM3_ADC_CHANNEL;
+ flowmeterFM4_gst.channel_u32 = FM4_ADC_CHANNEL;
+ FlowmeterInit(&flowmeterFM1_gst);
+ FlowmeterInit(&flowmeterFM2_gst);
+ FlowmeterInit(&flowmeterFM3_gst);
+ FlowmeterInit(&flowmeterFM4_gst);
}
void ProcessBoardRun(void)
{
- uint8 id_u8;
- uint8 motorCmd_u8;
- uint8 posData_u8;
- uint8 flowRate_u8;
- uint8 pressure_u8;
-
- coOdGetObj_u8(OD_ENTRY_PU_MOTOR_CTRL_INDEX, OD_ENTRY_PU_MOTOR_CTRL_ID_SUB_INDEX, &id_u8);
- coOdGetObj_u8(OD_ENTRY_PU_MOTOR_CTRL_INDEX, OD_ENTRY_PU_MOTOR_CTRL_CMD_SUB_INDEX, &motorCmd_u8);
- coOdGetObj_u8(OD_ENTRY_PU_MOTOR_CTRL_INDEX, OD_ENTRY_PU_MOTOR_CTRL_POS_SUB_INDEX, &posData_u8);
- coOdGetObj_u8(OD_ENTRY_PU_MOTOR_CTRL_INDEX, OD_ENTRY_PU_MOTOR_CTRL_PRESSURE_SUB_INDEX, &flowRate_u8);
- coOdGetObj_u8(OD_ENTRY_PU_MOTOR_CTRL_INDEX, OD_ENTRY_PU_MOTOR_CTRL_FLOW_SUB_INDEX, &pressure_u8);
+ uint8 id_u8 = 0u;
+ uint8 motorCmd_u8 = 0u;
+ uint8 posData_u8 = 0u;
+ uint8 flowRate_u8 = 0u;
+ uint8 pressure_u8 = 0u;
+ AnalogMesaurementRun();
+ /* DEBUG code to be replaced. Logic to be changed based on state machine
+ * implementation. */
if(motorCmd_u8 == 1u)
{
- ProcessBoardTriggerMvPosCtrl(11, posData_u8);
+ ProcessBoardTriggerMvPosCtrl(11, posData_u8); /* DEBUG */
}
else
{
ProcessBoardTriggerMvCartCtrl(id_u8, flowRate_u8, pressure_u8);
}
+ /* Flowmeter data IN */
+ FlowmeterGetFlow(&flowmeterFM1_gst);
+ FlowmeterGetFlow(&flowmeterFM2_gst);
+ FlowmeterGetFlow(&flowmeterFM3_gst);
FlowmeterGetFlow(&flowmeterFM4_gst);
+
+ /* Pressure sensor data IN */
PressureSensorGetVal(&pressureSensorPS1_gst);
- ProcessBoardFlowmeterDataOUT(flowmeterFM4_gst);
- ProcessBoardPressureSensorDataOUT(pressureSensorPS1_gst);
+ PressureSensorGetVal(&pressureSensorPS2_gst);
+ PressureSensorGetVal(&pressureSensorPS3_gst);
+ PressureSensorGetVal(&pressureSensorPS4_gst);
+
+ /* Flowmeter data OUT */
+ ProcessBoardFlowmeterDataOUT(flowmeterFM1_gst.rawQ_f32);
+ ProcessBoardFlowmeterDataOUT(flowmeterFM2_gst.rawQ_f32);
+ ProcessBoardFlowmeterDataOUT(flowmeterFM3_gst.rawQ_f32);
+ ProcessBoardFlowmeterDataOUT(flowmeterFM4_gst.rawQ_f32);
+
+ /* Pressure sensor data OUT */
+ ProcessBoardPressureSensorDataOUT(pressureSensorPS1_gst.rawT_f32);
+ ProcessBoardPressureSensorDataOUT(pressureSensorPS2_gst.rawT_f32);
+ ProcessBoardPressureSensorDataOUT(pressureSensorPS3_gst.rawT_f32);
+ ProcessBoardPressureSensorDataOUT(pressureSensorPS4_gst.rawT_f32);
+
+ ProcessBoardGrundfosPumpHandler();
+
ProcessBoardReadCondDataIN();
ProcessBoardWriteCondDataOUT();
}
@@ -130,6 +160,88 @@ void ProcessBoardRun(void)
/******************************************************************************
* 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)
+{
+ uint32 pmpSpeed_u32 = 0uL;
+ uint8 mode_u8 = 0u;
+ static uint8 speed_u8 = 0u;
+ static uint32 elapsedTime_s = 0u;
+ static enum { INCREASING, DECREASING } speedState = INCREASING;
+
+ NmsCanGetObj_u8(OD_ENTRY_PU_GRUNDFOS_PUMP_CONTROL_INDEX, OD_ENTRY_PU_GRUNDFOS_PUMP_ENABLE_SUB_INDEX, &mode_u8);
+
+ // Only modify speed every 15 minutes (900 seconds)
+ if (elapsedTime_s >= 900)
+ {
+ 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(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 ProcessBoardTriggerMvPosCtrl(uint8 motorId_u8, uint8 posData_u8)
{
@@ -144,49 +256,55 @@ static void ProcessBoardTriggerMvCartCtrl(uint8 motorId_u8, uint8 flowRate_u8, u
static void ProcessBoardReadCondDataIN(void)
{
- coOdGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, &condBoard1_gst.conductivityData_u32);
- coOdGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_TEMP1_DATA_IN_SUB_INDEX, &condBoard1_gst.temperature_u32);
+ NmsCanGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, &condBoard1_gst.conductivityData_u32);
+ NmsCanGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_TEMP1_DATA_IN_SUB_INDEX, &condBoard1_gst.temperature_u32);
- coOdGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, &condBoard2_gst.conductivityData_u32);
- coOdGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_TEMP2_DATA_IN_SUB_INDEX, &condBoard2_gst.temperature_u32);
+ NmsCanGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, &condBoard2_gst.conductivityData_u32);
+ NmsCanGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_TEMP2_DATA_IN_SUB_INDEX, &condBoard2_gst.temperature_u32);
- coOdGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, &condBoard3_gst.conductivityData_u32);
- coOdGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_TEMP3_DATA_IN_SUB_INDEX, &condBoard3_gst.temperature_u32);
+ NmsCanGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, &condBoard3_gst.conductivityData_u32);
+ NmsCanGetObj_u32(OD_ENTRY_PU_COND_DATA_IN_INDEX, OD_ENTRY_PU_TEMP3_DATA_IN_SUB_INDEX, &condBoard3_gst.temperature_u32);
}
static void ProcessBoardWriteCondDataOUT(void)
{
- coOdPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, condBoard1_gst.conductivityData_u32);
- coOdPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_TEMP1_DATA_IN_SUB_INDEX, condBoard1_gst.temperature_u32);
+ NmsCanPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_COND1_DATA_IN_SUB_INDEX, condBoard1_gst.conductivityData_u32);
+ NmsCanPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_TEMP1_DATA_IN_SUB_INDEX, condBoard1_gst.temperature_u32);
- coOdPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_COND2_DATA_IN_SUB_INDEX, condBoard2_gst.conductivityData_u32);
- coOdPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_TEMP2_DATA_IN_SUB_INDEX, condBoard2_gst.temperature_u32);
+ NmsCanPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_COND2_DATA_IN_SUB_INDEX, condBoard2_gst.conductivityData_u32);
+ NmsCanPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_TEMP2_DATA_IN_SUB_INDEX, condBoard2_gst.temperature_u32);
- coOdPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_COND3_DATA_IN_SUB_INDEX, condBoard3_gst.conductivityData_u32);
- coOdPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_TEMP3_DATA_IN_SUB_INDEX, condBoard3_gst.temperature_u32);
+ NmsCanPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_COND3_DATA_IN_SUB_INDEX, condBoard3_gst.conductivityData_u32);
+ NmsCanPutObj_u32(OD_ENTRY_PU_COND_DATA_OUT_INDEX, OD_ENTRY_PU_TEMP3_DATA_IN_SUB_INDEX, condBoard3_gst.temperature_u32);
}
-static void ProcessBoardFlowmeterDataOUT(FlowmeterMain_st flowmeter_st)
+static void ProcessBoardFlowmeterDataOUT(float32 rawQ_f32)
{
- coOdPutObj_r32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, flowmeterFM1_gst.rawQ_f32);
- coOdPutObj_r32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, flowmeterFM2_gst.rawQ_f32);
- coOdPutObj_r32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, flowmeterFM3_gst.rawQ_f32);
- coOdPutObj_r32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, flowmeterFM4_gst.rawQ_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, rawQ_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, rawQ_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, rawQ_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_FLOWMETER_DATA_OUT_INDEX, OD_ENTRY_PU_FLOWMETER1_DATA_OUT_SUB_INDEX, rawQ_f32);
}
-static void ProcessBoardPressureSensorDataOUT(PressureSensorMain_st pressureSensor_st)
+static void ProcessBoardPressureSensorDataOUT(float32 rawT_f32)
{
- coOdPutObj_r32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, pressureSensorPS1_gst.rawT_f32);
- coOdPutObj_r32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, pressureSensorPS2_gst.rawT_f32);
- coOdPutObj_r32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, pressureSensorPS3_gst.rawT_f32);
- coOdPutObj_r32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, pressureSensorPS4_gst.rawT_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, rawT_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, rawT_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, rawT_f32);
+ NmsCanPutObj_f32(OD_ENTRY_PU_PRESSURE_DATA_OUT_INDEX, OD_ENTRY_PU_PRESSURE1_DATA_OUT_SUB_INDEX, rawT_f32);
+}
+
+
+static void ProcessBoardPumpSpeedDataOUT(uint32 pmpSpeed_u32)
+{
+ NmsCanPutObj_u32(OD_ENTRY_PU_GRUNDFOS_PUMP_CONTROL_INDEX, OD_ENTRY_PU_GRUNDFOS_PUMP_FEEDBACK_SUB_INDEX, pmpSpeed_u32);
}
static void ProcessBoardReadMvDataIN(void)
{
- /* To be implemented */
+// NmsCanGetObj_u8(uint8 canLine_u8, uint16 index_u16, uint8 subIndex_u8, uint8 *pObj_pu8);
}
diff --git a/EnduranceTestBench/nehemis/test.c b/EnduranceTestBench/nehemis/test.c
new file mode 100644
index 0000000..11b79f8
--- /dev/null
+++ b/EnduranceTestBench/nehemis/test.c
@@ -0,0 +1,298 @@
+/**
+ * @file batch_endurance_testbench.c
+ *
+ * @brief Batch mode test bench:
+ * 1. Write to all nodes (at 100ms intervals)
+ * 2. Read all nodes
+ * 3. Verify positions (retry mismatch up to 2 times)
+ * 4. Cycle complete – reset for next iteration
+ *
+ * @copyright
+ */
+
+#include "enduranceTestBench.h"
+#include "stdlib.h"
+
+/* CANopen includes */
+#include
+#include
+#include "../nms_hal/hal_system.h"
+
+/******************************************************************************
+ * Macro constant declarations
+ ******************************************************************************/
+#define ENDURANCE_TEST_BENCH_MAX_RETRY_CNT 3u
+#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
+
+/* Batch delay between node operations (in ms) */
+#define NODE_OP_DELAY_MS 100u
+
+/******************************************************************************
+ * Type Declarations
+ ******************************************************************************/
+typedef enum
+{
+ TEST_BENCH_BATCH_WRITE, /* Write to nodes in batch */
+ TEST_BENCH_BATCH_WRITE_WAIT, /* Wait between writes */
+ TEST_BENCH_BATCH_READ, /* Read all nodes */
+ TEST_BENCH_BATCH_READ_WAIT, /* Wait between reads */
+ TEST_BENCH_BATCH_VERIFY, /* Verify all nodes */
+ TEST_BENCH_CYCLE_COMPLETE, /* End of cycle, reset for next iteration */
+ TEST_BENCH_IDLE /* Idle state (optional) */
+} SdlTestBenchState_en;
+
+typedef enum
+{
+ TEST_BENCH_DATA_VERIF_DEFAULT,
+ TEST_BENCH_DATA_VERIF_SUCCESS,
+ TEST_BENCH_DATA_VERIF_FAILURE,
+ TEST_BENCH_DATA_VERIF_SKIPPED,
+} TestBenchStatus_en;
+
+typedef struct
+{
+ uint8 targetPositions_gau8[ENDURANCE_TEST_BENCH_LSS_NODE_COUNT];
+ uint8 readPosition_gau8[ENDURANCE_TEST_BENCH_LSS_NODE_COUNT];
+ TestBenchStatus_en status_en[ENDURANCE_TEST_BENCH_LSS_NODE_COUNT];
+} TestBenchData_en;
+
+/******************************************************************************
+ * Global variable declarations
+ ******************************************************************************/
+static TestBenchData_en testBenchData_en;
+static uint8 currentNode_gu8 = 0u;
+static SdlTestBenchState_en testBenchState_en = TEST_BENCH_IDLE;
+static uint32 readPosition_gu32;
+static uint8 storedTargetPos = 0u; /* Flag: target written to current node */
+static uint8 readMismatchRetries_u8 = 0u; /* Retry count for verify mismatches */
+
+static uint64 writeTime_u64 = 0uLL;
+static uint64 readExecutedTime_u64 = 0uLL;
+static uint64 cycleStartTime_u64 = 0uLL;
+static uint8 retries_u8 = 0u; /* General retry counter for SDO communication */
+
+/******************************************************************************
+ * Public Function Definitions
+ ******************************************************************************/
+void TestRun(void)
+{
+ uint64 currentTime_u64;
+ HalSystemGetRunTimeMs(¤tTime_u64);
+
+ /* Initialization: start new cycle if in idle or cycle complete state */
+ if (testBenchState_en == TEST_BENCH_IDLE || testBenchState_en == TEST_BENCH_CYCLE_COMPLETE)
+ {
+ /* Prepare new cycle: reset all node statuses and choose new target positions */
+ for (uint8 i = 0u; i < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i++)
+ {
+ testBenchData_en.targetPositions_gau8[i] = (uint8)(rand() % 256);
+ testBenchData_en.readPosition_gau8[i] = 0u;
+ testBenchData_en.status_en[i] = TEST_BENCH_DATA_VERIF_DEFAULT;
+ }
+ currentNode_gu8 = 0u;
+ storedTargetPos = 0u;
+ retries_u8 = 0u;
+ readMismatchRetries_u8 = 0u;
+ cycleStartTime_u64 = currentTime_u64;
+ testBenchState_en = TEST_BENCH_BATCH_WRITE;
+ }
+
+ switch (testBenchState_en)
+ {
+ /* -------------------- Batch Write -------------------- */
+ case TEST_BENCH_BATCH_WRITE:
+ {
+ if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT)
+ {
+ if (storedTargetPos == 0)
+ {
+ /* Use the pre-assigned target value for this node */
+ uint8 value_u8 = testBenchData_en.targetPositions_gau8[currentNode_gu8];
+
+ RET_T retVal_en = coSdoWrite(
+ (currentNode_gu8 + 1),
+ ENDURANCE_TEST_BENCH_POSITION_SETPOINT_INDEX,
+ ENDURANCE_TEST_BENCH_POSITION_SETPOINT_SUB_INDEX,
+ &value_u8,
+ sizeof(uint8),
+ CO_FALSE,
+ ENDURANCE_TEST_BENCH_TIMEOUT
+ );
+
+ if (retVal_en == RET_OK)
+ {
+ storedTargetPos = 1; /* Mark that target is written for this node */
+ HalSystemGetRunTimeMs(&writeTime_u64);
+ retries_u8 = 0u;
+ testBenchState_en = TEST_BENCH_BATCH_WRITE_WAIT;
+ }
+ else
+ {
+ retries_u8++;
+ if (retries_u8 >= ENDURANCE_TEST_BENCH_MAX_RETRY_CNT)
+ {
+ testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_VERIF_SKIPPED;
+ /* Mark node as skipped and move on */
+ currentNode_gu8++;
+ retries_u8 = 0u;
+ storedTargetPos = 0u;
+ testBenchState_en = TEST_BENCH_BATCH_WRITE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Finished writing to all nodes */
+ currentNode_gu8 = 0u; /* Reset index for read phase */
+ testBenchState_en = TEST_BENCH_BATCH_READ;
+ }
+ break;
+ }
+
+ case TEST_BENCH_BATCH_WRITE_WAIT:
+ {
+ /* Wait 100ms between writes */
+ if ((currentTime_u64 - writeTime_u64) >= 500)
+ {
+ /* Move to next node write */
+ currentNode_gu8++;
+ storedTargetPos = 0u; /* Reset for next node */
+ testBenchState_en = TEST_BENCH_BATCH_WRITE;
+ }
+ break;
+ }
+
+ /* -------------------- Batch Read -------------------- */
+ case TEST_BENCH_BATCH_READ:
+ {
+ if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT)
+ {
+ RET_T retVal_en = coSdoRead(
+ (currentNode_gu8 + 1),
+ ENDURANCE_TEST_BENCH_POSITION_FEEDBACK_INDEX,
+ ENDURANCE_TEST_BENCH_POSITION_FEEDBACK_SUB_INDEX,
+ (uint8*)&readPosition_gu32,
+ sizeof(uint32),
+ CO_FALSE,
+ ENDURANCE_TEST_BENCH_TIMEOUT
+ );
+
+ if (retVal_en == RET_OK)
+ {
+ retries_u8 = 0u;
+ /* The read indication callback is assumed to update
+ * testBenchData_en.readPosition_gau8[currentNode_gu8] and
+ * then we simply continue to next node after a small delay.
+ */
+ HalSystemGetRunTimeMs(&readExecutedTime_u64);
+ testBenchData_en.readPosition_gau8[currentNode_gu8] = (uint8)readPosition_gu32;
+ testBenchState_en = TEST_BENCH_BATCH_READ_WAIT;
+ }
+ else if (retVal_en == RET_SERVICE_BUSY && retries_u8 < ENDURANCE_TEST_BENCH_MAX_RETRY_CNT)
+ {
+ retries_u8++;
+ }
+ else
+ {
+ /* If read fails, mark as skipped and move on */
+ testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_VERIF_SKIPPED;
+ currentNode_gu8++;
+ retries_u8 = 0u;
+ }
+ }
+ else
+ {
+ /* Finished reading all nodes */
+ currentNode_gu8 = 0u; /* Reset for verification phase */
+ testBenchState_en = TEST_BENCH_BATCH_VERIFY;
+ }
+ break;
+ }
+
+ case TEST_BENCH_BATCH_READ_WAIT:
+ {
+ /* Wait 100ms between node reads */
+ if ((currentTime_u64 - readExecutedTime_u64) >= 10)
+ {
+ currentNode_gu8++;
+ testBenchState_en = TEST_BENCH_BATCH_READ;
+ }
+ break;
+ }
+
+ /* -------------------- Batch Verify -------------------- */
+ case TEST_BENCH_BATCH_VERIFY:
+ {
+ if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT)
+ {
+ /* Process only if the node was not already skipped */
+ if (testBenchData_en.status_en[currentNode_gu8] != TEST_BENCH_DATA_VERIF_SKIPPED)
+ {
+ uint8 diff = abs(testBenchData_en.targetPositions_gau8[currentNode_gu8] -
+ testBenchData_en.readPosition_gau8[currentNode_gu8]);
+
+ if (diff <= 1)
+ {
+ testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_VERIF_SUCCESS;
+ }
+ else
+ {
+ testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_VERIF_FAILURE;
+ }
+ }
+ /* Move to the next node in any case */
+ currentNode_gu8++;
+ testBenchState_en = TEST_BENCH_BATCH_VERIFY;
+ }
+ else
+ {
+ /* All nodes verified; complete cycle */
+ testBenchState_en = TEST_BENCH_CYCLE_COMPLETE;
+ }
+ break;
+ }
+
+ /* -------------------- Cycle Complete -------------------- */
+ case TEST_BENCH_CYCLE_COMPLETE:
+ {
+ /* Optionally, you can log or process the batch results here */
+ /* Reset all node data for the next cycle */
+ for (uint8 i = 0u; i < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT; i++)
+ {
+ testBenchData_en.targetPositions_gau8[i] = 0u;
+ testBenchData_en.readPosition_gau8[i] = 0u;
+ testBenchData_en.status_en[i] = TEST_BENCH_DATA_VERIF_DEFAULT;
+ }
+ currentNode_gu8 = 0u;
+ storedTargetPos = 0u;
+ retries_u8 = 0u;
+ readMismatchRetries_u8 = 0u;
+ /* Start next cycle */
+ testBenchState_en = TEST_BENCH_IDLE;
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+/******************************************************************************
+ * Callback Functions
+ ******************************************************************************/
+void TestReadInd(uint8 sdoNr_u8, uint16 index_u16, uint8 subIndex_u8, uint32 errorVal_u32)
+{
+ HalSystemGetRunTimeMs(&writeTime_u64);
+}
+
+void TestWriteInd(uint8 sdoNr_u8, uint16 index_u16, uint8 subIndex_u8, uint32 size, uint32 errorVal_u32)
+{
+ HalSystemGetRunTimeMs(&readExecutedTime_u64);
+ //testBenchData_en.readPosition_gau8[currentNode_gu8] = (uint8)readPosition_gu32;
+}
diff --git a/EnduranceTestBench/nehemis/test.h b/EnduranceTestBench/nehemis/test.h
new file mode 100644
index 0000000..03acdcc
--- /dev/null
+++ b/EnduranceTestBench/nehemis/test.h
@@ -0,0 +1,32 @@
+/**
+ * @file test.h
+ *
+ * @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
+ *
+ */
+#ifndef TEST_H_
+#define TEST_H_
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+
+/******************************************************************************
+ * Type declarations
+ ******************************************************************************/
+
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+void TestRun(void);
+
+void TestInit(void);
+
+void TestWriteInd(uint8 sdoNr, UNSIGNED16 index, uint8 subIndex, UNSIGNED32 errorVal);
+
+void TestReadInd(uint8 sdoNr, UNSIGNED16 index, uint8 subIndex, UNSIGNED32 size, UNSIGNED32 errorVal);
+#endif /* TEST_H_ */
diff --git a/EnduranceTestBench/nms-hal/hal_system.c b/EnduranceTestBench/nms-hal/hal_system.c
deleted file mode 100644
index b69b1af..0000000
--- a/EnduranceTestBench/nms-hal/hal_system.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * @file hal_system.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 HAL layer for the SYSTEM module.
- * - The system reset cause such as :
- * 1. Software reset
- * 2. Watchdog reset
- * 3. Power on reset
- * 4. Optional byte load reset
- * 5. Low power reset
- * 6. Pin reset
- * - The NVIC enable/disable interrupts.
- * - The serial number of the MCU.
- */
-
-/******************************************************************************
- * Include Header Files
- ******************************************************************************/
-#include "hal_system.h"
-
-/* cubeMX */
-#include "main.h"
-/******************************************************************************
- * Macro Constant Declarations
- ******************************************************************************/
-#define HAL_SYSTEM_STACK_GUARD 0xCDu
-
-/******************************************************************************
- * Module Global Variable Declarations
- ******************************************************************************/
-static uint64 systemStepCounter_gu64;
-static uint64 systemPeriodMsToUs_gu64;
-static uint64 systemTickLoadValue_gu64;
-static uint32 resetStatusRegister_gu32;
-
-/******************************************************************************
- * Static Function Declarations
- ******************************************************************************/
-
-/******************************************************************************
- * Extern Function Definitions
- ******************************************************************************/
-uint32 HalSystemInit(void)
-{
- uint32 error_u32 = NMS_ERR_NONE;
-
- resetStatusRegister_gu32 = RCC->CSR;
- RCC->CSR |= RCC_CSR_RMVF; /* RMVF = ReMoVe Flag. Reset the reset cause register for the next reboot. */
-
- systemPeriodMsToUs_gu64 = HAL_GetTickFreq() * 1000uLL;
- systemTickLoadValue_gu64 = (uint64)(SysTick->LOAD);
- systemStepCounter_gu64 = 0uLL;
-
- return error_u32;
-}
-
-
-uint32 HalSystemGetRunTimeUs(uint64 * resultUs_pu64)
-{
- static uint64 previousTimeUs_u64 = 0uLL;
- uint32 error_u32 = NMS_ERR_NONE;
- uint64 timeUs_u64 = 0uLL;
-
- /* Make a copy in case of multiple function instance at the same time */
- uint64 copySystemStepCounter_u64 = systemStepCounter_gu64;
-
- /* First make a copy of the systemStepCounter to be able to check rollback further on.
- * Also copy current value of the System Tick Timer to avoid any dynamic update during calculation.
- * Then translate in microsecond & sum both timing information (step counter + tick value) to get the most
- * accurate resolution of the system runtime.
- */
- uint64 copyPreviousTimeUs_u64 = previousTimeUs_u64;
- uint64 tickValue_u64 = (uint64)(SysTick->VAL);
- timeUs_u64 = copySystemStepCounter_u64 * systemPeriodMsToUs_gu64;
- timeUs_u64 += ((systemTickLoadValue_gu64 - tickValue_u64) * systemPeriodMsToUs_gu64) / systemTickLoadValue_gu64;
-
- /* We check here if the interruption of the systick happened during our operations and correct it accordingly */
- if(timeUs_u64 <= (uint64)(systemStepCounter_gu64 * systemPeriodMsToUs_gu64))
- {
- copySystemStepCounter_u64 = systemStepCounter_gu64;
- tickValue_u64 = (uint64)(SysTick->VAL);
- timeUs_u64 = copySystemStepCounter_u64 * systemPeriodMsToUs_gu64;
- timeUs_u64 += ((systemTickLoadValue_gu64 - tickValue_u64) * systemPeriodMsToUs_gu64) / systemTickLoadValue_gu64;
-
- /* The timer interruption is too fast, no time to process */
- if(timeUs_u64 <= (uint64)(systemStepCounter_gu64 * systemPeriodMsToUs_gu64))
- {
- error_u32 = NMS_ERR_OVERRUN;
- }
- }
-
- /* Should never happen if this timer interruption is set to highest priority */
- if(copyPreviousTimeUs_u64 > timeUs_u64)
- {
- error_u32 = NMS_ERR_UNKNOWN;
- }
- else
- {
- *resultUs_pu64 = previousTimeUs_u64;
- }
-
- /* This condition has been added to prevent trouble overflow with interruptions
- on the medium and high optimizations options */
- *resultUs_pu64 = (timeUs_u64 > previousTimeUs_u64) ? timeUs_u64 : *resultUs_pu64;
-
- return error_u32;
-}
-
-
-/* This function should not call the log, since it uses the system runtime. */
-uint32 HalSystemGetRunTimeMs(uint64 * resultMs_pu64)
-{
- *resultMs_pu64 = systemStepCounter_gu64;
-
- return NMS_ERR_NONE;
-}
-
-
-void HalSystemGetSerialId(uint8 * serialIdBuffer_pu8)
-{
- uint32 serialIdW0_u32, serialIdW1_u32, serialIdW2_u32;
-
- /* Get the three parts of the UID */
- serialIdW0_u32 = HAL_GetUIDw0();
- serialIdW1_u32 = HAL_GetUIDw1();
- serialIdW2_u32 = HAL_GetUIDw2();
-
- /* Copy the values into the serial ID buffer */
- memcpy(&serialIdBuffer_pu8[0], &serialIdW0_u32, sizeof(serialIdW0_u32));
- memcpy(&serialIdBuffer_pu8[4], &serialIdW1_u32, sizeof(serialIdW1_u32));
- memcpy(&serialIdBuffer_pu8[8], &serialIdW2_u32, sizeof(serialIdW2_u32));
-}
-
-
-uint32 HalSystemGetResetCause( HalSystemResetCauseEn resetCauseSelector_en, uint32 * causes_pu32 )
-{
- uint32 error_u32 = NMS_ERR_DEFAULT;
- uint32 mask_u32 = 0uL;
-
- if (causes_pu32 == NULL)
- {
- error_u32 = NMS_ERR_NULL_POINTER;
- }
- else
- {
- switch(resetCauseSelector_en)
- {
- case HAL_SYSTEM_RESET_CAUSE_OPTION_BYTE_LOADER:
- mask_u32 = RCC_CSR_OBLRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- case HAL_SYSTEM_RESET_CAUSE_EXTERNAL_PIN_RESET:
- mask_u32 = RCC_CSR_PINRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- case HAL_SYSTEM_RESET_CAUSE_BROWNOUT_RESET:
- mask_u32 = RCC_CSR_BORRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- case HAL_SYSTEM_RESET_CAUSE_SOFTWARE_RESET:
- mask_u32 = RCC_CSR_SFTRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- case HAL_SYSTEM_RESET_CAUSE_WATCH_DOG_TIMER:
- mask_u32 = RCC_CSR_IWDGRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- case HAL_SYSTEM_RESET_CAUSE_WINDOW_WATCH_DOG:
- mask_u32 = RCC_CSR_WWDGRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- case HAL_SYSTEM_RESET_CAUSE_LOW_POWER:
- mask_u32 = RCC_CSR_LPWRRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- case HAL_SYSTEM_RESET_CAUSE_ALL_CAUSES:
- mask_u32 = RCC_CSR_IWDGRSTF_Msk
- | RCC_CSR_WWDGRSTF_Msk
- | RCC_CSR_SFTRSTF_Msk
- | RCC_CSR_PINRSTF_Msk
- | RCC_CSR_LPWRRSTF_Msk
- | RCC_CSR_BORRSTF_Msk;
- error_u32 = NMS_ERR_NONE;
- break;
-
- default:
-
- error_u32 = NMS_ERR_UNKNOWN;
- break;
- }
-
- *causes_pu32 = resetStatusRegister_gu32 & mask_u32;
- }
-
- return error_u32;
-}
-
-
-void HalSystemDisableInterrupts(void)
-{
- __disable_irq();
-}
-
-
-void HalSystemEnableInterrupts(void)
-{
- __enable_irq();
-}
-
-
-void HalSystemReset(void)
-{
- HAL_NVIC_SystemReset();
-}
-
-/******************************************************************************
- * Callback Function Definitions
- ******************************************************************************/
-/**
-* @brief Count the number of milliseconds that elapsed since the start
-*
-* @note Function called by low-level functions of cubeMX
-*/
-void HAL_IncTick(void)
-{
- systemStepCounter_gu64++;
-}
-
-
-/**
-* @brief Provides a tick value in millisecond.
-*
-* @return The number of elapsed tick.
-*/
-uint32 HAL_GetTick(void)
-{
- return (uint32)systemStepCounter_gu64;
-}
diff --git a/EnduranceTestBench/nms-hal/hal_system.h b/EnduranceTestBench/nms-hal/hal_system.h
deleted file mode 100644
index daa1fc1..0000000
--- a/EnduranceTestBench/nms-hal/hal_system.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * @file hal_system.h
- * @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 Header file for HAL layer for the SYSTEM module.
- *
- */
-
-#ifndef INCLUDED_HAL_SYSTEM_H
-#define INCLUDED_HAL_SYSTEM_H
-
-/******************************************************************************
- * Include Header Files
- ******************************************************************************/
-#include "nms_types.h"
-
-/******************************************************************************
- * Macros Constant Declarations
- ******************************************************************************/
-#define SERIAL_ID_BUFFER_SIZE 12
-
-/******************************************************************************
- * Types Declarations
- ******************************************************************************/
-typedef enum
-{
- HAL_SYSTEM_RESET_CAUSE_OPTION_BYTE_LOADER,
- HAL_SYSTEM_RESET_CAUSE_EXTERNAL_PIN_RESET,
- HAL_SYSTEM_RESET_CAUSE_BROWNOUT_RESET,
- HAL_SYSTEM_RESET_CAUSE_SOFTWARE_RESET,
- HAL_SYSTEM_RESET_CAUSE_WATCH_DOG_TIMER,
- HAL_SYSTEM_RESET_CAUSE_WINDOW_WATCH_DOG,
- HAL_SYSTEM_RESET_CAUSE_LOW_POWER,
- HAL_SYSTEM_RESET_CAUSE_ALL_CAUSES
-} HalSystemResetCauseEn; /**< Enumeration used to analyze the reset cause location. */
-
-/******************************************************************************
- * Global Variables Declarations
- ******************************************************************************/
-
-/******************************************************************************
- * Extern Functions Declarations
- ******************************************************************************/
-
-/**
- * @brief Initializes the system HAL.
- *
- * @note CAUTION: This function must be called immediately after
- * SystemClock_Config() in the main function to ensure correct
- * operation and prevent potential software issues.
- *
- * @return Error code: 0 if successful, nonzero otherwise.
- */
-uint32 HalSystemInit(void);
-
-/**
- * @brief Retrieves the system runtime in microseconds.
- *
- * @param resultUs_pu64 Pointer to store the system runtime in microseconds.
- *
- * @note The tick resolution depends on the system tick frequency.
- *
- * @return Error code: 0 if successful, nonzero otherwise.
- */
-uint32 HalSystemGetRunTimeUs(uint64 *resultUs_pu64);
-
-/**
- * @brief Retrieves the system runtime in milliseconds.
- *
- * @param resultMs_pu64 Pointer to store the system runtime in milliseconds.
- *
- * @note The tick resolution depends on the system tick frequency.
- *
- * @return Error code: 0 if successful, nonzero otherwise.
- */
-uint32 HalSystemGetRunTimeMs(uint64 *resultMs_pu64);
-
-/**
- * @brief Disables all system interrupts.
- */
-void HalSystemDisableInterrupts(void);
-
-/**
- * @brief Enables all system interrupts.
- */
-void HalSystemEnableInterrupts(void);
-
-/**
- * @brief Retrieves the cause of the last system reset from the MCU registers.
- *
- * @param resetCauseSelector_en Enum specifying the reset cause type.
- * causes_pu32 Pointer to store the corresponding bitmask value.
- *
- * @return Error code: 0 if successful, nonzero otherwise.
- */
-uint32 HalSystemGetResetCause(HalSystemResetCauseEn resetCauseSelector_en, uint32 *causes_pu32);
-
-/**
- * @brief Retrieves the system's unique serial ID.
- *
- * @param serialIdBuffer_pu8 Pointer to the buffer where the serial ID will be stored.
- */
-void HalSystemGetSerialId(uint8 *serialIdBuffer_pu8);
-
-/**
- * @brief Performs a software reset of the system.
- */
-void HalSystemReset(void);
-
-
-#endif /* INCLUDED_HAL_SYSTEM_H */
diff --git a/EnduranceTestBench/nms_can/nms_can.c b/EnduranceTestBench/nms_can/nms_can.c
new file mode 100644
index 0000000..a3ae4ab
--- /dev/null
+++ b/EnduranceTestBench/nms_can/nms_can.c
@@ -0,0 +1,574 @@
+/**
+ * @file nms_can.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 Source code for CANOpen files abstracted for furthur use in the project.
+ *
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_can.h"
+#include "enduranceTestBench.h"
+
+/* CANopen includes */
+#include
+#include
+#include "co_sdo.h"
+#include "co_pdo.h"
+#include "co_odaccess.h"
+
+/******************************************************************************
+ * Global Variable Declaration
+ ******************************************************************************/
+
+/******************************************************************************
+ * Macro constant declarations
+ ******************************************************************************/
+#define NMS_CAN_CANOPEN_SLAVE_LINE 0u
+#define NMS_CAN_CANOPEN_MASTER_LINE 1u
+
+#define NMS_CAN_CANOPEN_BITRATE 250u
+
+#define NMS_CAN_PU_MASTER_NODE_ID 1u
+#define NMS_CAN_PU_SLAVE_NODE_ID 3u
+
+#define NMS_CAN_LSS_TIMEOUT 20u /* Defined in stack examples */
+#define NMS_CAN_LSS_CONFIG_TIMEOUT 1000u
+#define NMS_CAN_LSS_CONFIG_INTERVAL 4u
+#define NMS_CAN_APPL_TIMER_TIME 250000uL
+
+#define NMS_CAN_LSS_NODE_COUNT 10u
+#define NMS_CAN_LSS_NODE_HB_MS 1000uL
+#define NMS_CAN_LSS_NODE_STATE_RESET_INTERVAL 3u
+
+#define NMS_CAN_SDO_TRANSMIT 0x580u
+#define NMS_CAN_SDO_RECEIVE 0x600u
+#define NMS_CAN_SDO_PARAM_INDEX 0x1280u
+#define NMS_LSS_NODE_COUNT 20u
+/******************************************************************************
+ * Type Declarations
+ ******************************************************************************/
+typedef struct
+{
+ uint32 vendorId_u32;
+ uint32 productId_u32;
+ uint32 versionNbr_u32;
+ uint32 serialNbr_u32;
+ uint8 nodeId_u8;
+} SdlLssNodeInfo_t;
+/******************************************************************************
+ * Global Declarations
+ ******************************************************************************/
+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[NMS_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[NMS_LSS_NODE_COUNT];
+/******************************************************************************
+ * Private Function Definition
+ ******************************************************************************/
+
+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 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 uint8 NmsCanLssGetNodeIndex(uint8 nodeId_u8);
+static void NmsCanLssToggleMonitorFlag(void *pData_pv);
+static void NmsCanLssNodeHandlerRun(void);
+static uint32 NmsCanLssConfigureNode(uint8 arrIndex_u8);
+static RET_T NmsCanLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8);
+/* Supress warnings for implicit declaration.
+ * Need this function for overwriting the manual COB ids
+ * for the TPDO. */
+extern void userOverwriteCobIdSettings(void);
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+void NmsCanInit()
+{
+ codrvHardwareInit();
+ codrvCanInit(NMS_CANOPEN_BITRATE);
+ codrvTimerSetup(CO_TIMER_INTERVAL);
+
+ /* CANopen Initialization */
+ coCanOpenStackInit(NmsCanOverwriteLoadIndication);
+ coEventRegister_LSS_MASTER(NmsCanLssIndCallback);
+ coEventRegister_ERRCTRL(NmsCanLssHbMonitorCallback);
+
+ /* Register SDO event handlers */
+ coEventRegister_SDO_CLIENT_READ(EnduranceTestBenchReadInd);
+ coEventRegister_SDO_CLIENT_WRITE(EnduranceTestBenchWriteInd);
+
+ /* enable CAN communication */
+ codrvCanEnable();
+
+ 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);
+
+ /* node == 0, the NMT request is sent to all nodes. */
+ coNmtStateReq(NMS_CAN_PU_MASTER_NODE_ID, CO_NMT_STATE_OPERATIONAL, CO_TRUE);
+}
+
+
+void NmsCanRun(void)
+{
+ coCommTask();
+
+ /* LSS main runner */
+ NmsCanLssNodeHandlerRun();
+}
+
+
+uint32 NmsCanGetObj_u8(uint16 index_u16, uint8 subIndex_u8, uint8 *pObj_pu8)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ RET_T retVal_en = coOdGetObj_u8(index_u16, subIndex_u8, pObj_pu8);
+ if ( retVal_en == RET_OK)
+ {
+ error_u32 = NMS_ERR_NONE;
+ }
+
+ return error_u32;
+}
+
+
+uint32 NmsCanGetObj_u32(uint16 index_u16, uint8 subIndex_u8, uint32 *pObj_pu32)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ RET_T retVal_en = coOdGetObj_u32(index_u16, subIndex_u8, pObj_pu32);
+ if ( retVal_en == RET_OK)
+ {
+ error_u32 = NMS_ERR_NONE;
+ }
+
+ return error_u32;
+}
+
+
+uint32 NmsCanGetObj_f32(uint16 index_u16, uint8 subIndex_u8, float32 *pObj_pf32)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ RET_T retVal_en = coOdGetObj_r32(index_u16, subIndex_u8, pObj_pf32);
+ if ( retVal_en == RET_OK)
+ {
+ error_u32 = NMS_ERR_NONE;
+ }
+
+ return error_u32;
+}
+
+
+uint32 NmsCanPutObj_u8(uint16 index_u16, uint8 subIndex_u8, uint8 newVal_u8)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ RET_T retVal_en = coOdPutObj_u8(index_u16, subIndex_u8, newVal_u8);
+ if ( retVal_en == RET_OK)
+ {
+ error_u32 = NMS_ERR_NONE;
+ }
+
+ return error_u32;
+}
+
+
+uint32 NmsCanPutObj_u32(uint16 index_u16, uint8 subIndex_u8, uint32 newVal_u32)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ RET_T retVal_en = coOdPutObj_u32(index_u16, subIndex_u8, newVal_u32);
+ if ( retVal_en == RET_OK)
+ {
+ error_u32 = NMS_ERR_NONE;
+ }
+
+ return error_u32;
+}
+
+
+uint32 NmsCanPutObj_f32(uint16 index_u16, uint8 subIndex_u8, uint32 newVal_u32)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ RET_T retVal_en = coOdPutObj_r32(index_u16, subIndex_u8, newVal_u32);
+ if ( retVal_en == RET_OK)
+ {
+ error_u32 = NMS_ERR_NONE;
+ }
+
+ return error_u32;
+}
+/******************************************************************************
+ * 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 NmsCanLssNodeHandlerRun(void)
+{
+ if (monitorSleep_gb != CO_TRUE)
+ {
+ for (uint8 i_u8 = 0u; i_u8 < NMS_CAN_LSS_NODE_COUNT; i_u8++)
+ {
+ if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_PREOP)
+ {
+ NmsCanLssConfigureNode(i_u8);
+ }
+ if (nodeNMTState_gaen[i_u8] == CO_NMT_STATE_OPERATIONAL)
+ {
+ /* Do nothing */
+ }
+ }
+ }
+ monitorSleep_gb = CO_TRUE;
+}
+
+
+/**
+ * @brief Load function for overwriting the TPDO COB id values.
+ *
+ * @param index_u8 Subindex parameter to point parameter area(unused)
+ * canLine_u8 The canline MASTER or SLAVE
+ *
+ * @return Error Code
+ */
+static RET_T NmsCanOverwriteLoadIndication(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 NmsCanLssGetNodeIndex(uint8 nodeId_u8)
+{
+ uint8 arrIndex_u8;
+
+ /* find node ID array arrIndex_u8 */
+ for (arrIndex_u8 = 0u; arrIndex_u8 < NMS_CAN_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 when a new NMT state of a node
+ * is recognized by the CANopen stack.
+ *
+ * @param canLine_u8 Indicates whether the node is on the MASTER or SLAVE CAN line.
+ * pData Pointer to additional data (unused).
+ */
+static void NmsCanLssToggleMonitorFlag(void *pData_pv)
+{
+ (void)pData_pv;
+
+ /* 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 NmsCanLssConfigureNode(uint8 arrIndex_u8)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ RET_T retVal_en = RET_INTERNAL_ERROR;
+
+ /* Get the node ID from the lookup table using arrIndex_u8 */
+ uint8 nodeId_u8 = nodeLookupTable_gast[arrIndex_u8].nodeId_u8;
+
+ /* Add node to hb 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,
+ ((NMS_CAN_LSS_NODE_HB_MS / 100 * 25) + NMS_CAN_LSS_NODE_HB_MS));
+ retVal_en = coHbConsumerStart(nodeId_u8);
+
+ /* setup SDO channel */
+ 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);
+
+ /* start node */
+ retVal_en = coNmtStateReq(nodeId_u8, CO_NMT_STATE_OPERATIONAL, CO_FALSE);
+ if (retVal_en != RET_OK)
+ {
+ error_u32 = NMS_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;
+}
+
+
+/******************************************************************************
+ * Callback Function Definitions
+ ******************************************************************************/
+/**
+ * @brief LSS indication function for handling the LSS api calls for dynamic
+ * setup of node ids.
+ *
+ * @param canLine_u8 The canline MASTER or SLAVE
+ * 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 NmsCanLssIndCallback(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(NMS_CAN_LSS_TIMEOUT);
+ break;
+
+ case CO_LSS_MASTER_SERVICE_FASTSCAN:
+ /* Match detected node with lookup table */
+ for (uint8 i_u8 = 0; i_u8 < NMS_CAN_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 < NMS_CAN_LSS_NODE_COUNT)
+ {
+ coLssSetNodeId(nodeLookupTable_gast[matchedIndex_u8].nodeId_u8, NMS_CAN_LSS_TIMEOUT);
+ matchedIndex_u8 = NMS_UINT8_MAX;
+ }
+ else
+ {
+ /* ERROR */
+ }
+ break;
+
+ case CO_LSS_MASTER_SERVICE_SET_NODEID:
+ /* DEBUG INFO */
+ coLssInquireNodeId(NMS_CAN_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 NmsCanLssHbMonitorCallback(uint8 nodeID_u8, CO_ERRCTRL_T state_en, CO_NMT_STATE_T nmtState_en)
+{
+ uint8 arrIndex_u8;
+
+ /* look if node is monitored */
+ arrIndex_u8 = NmsCanLssGetNodeIndex(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 NmsCanLssResetNodesCallback(void *pData_pv)
+{
+ uint8 arrIndex_u8;
+
+ (void)pData_pv;
+
+ /* reset defined nodes without known state */
+ for (arrIndex_u8 = 0u; arrIndex_u8 < 3; 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);
+ }
+ }
+}
+
+
+/**
+* @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 NmsCanLssSetSdoCobID(uint8 sdoNr_u8, uint8 nodeId_u8)
+{
+ uint16 cobIndex_u16;
+ uint32 newCobId_u32;
+ RET_T retVal = RET_INTERNAL_ERROR;
+
+ /* get od index of sdoNr */
+ cobIndex_u16 = NMS_CAN_SDO_PARAM_INDEX + sdoNr_u8 - 1u;
+
+ /* set cobID for client to server direction (request) */
+ newCobId_u32 = NMS_CAN_SDO_RECEIVE + nodeId_u8;
+ retVal = coOdSetCobid(cobIndex_u16, 1u, newCobId_u32);
+
+ if (retVal == RET_OK)
+ {
+ /* set cobID for server to client direction (response) */
+ newCobId_u32 = NMS_CAN_SDO_TRANSMIT + nodeId_u8;
+ retVal = coOdSetCobid(cobIndex_u16, 2u, newCobId_u32);
+ }
+
+ /* print failed setup details */
+ if (retVal != RET_OK)
+ {
+ /* ERROR */
+ }
+
+ return retVal;
+}
diff --git a/EnduranceTestBench/nms_can/nms_can.h b/EnduranceTestBench/nms_can/nms_can.h
new file mode 100644
index 0000000..a0a270f
--- /dev/null
+++ b/EnduranceTestBench/nms_can/nms_can.h
@@ -0,0 +1,108 @@
+/**
+ * @file nms_can.h
+ *
+ * @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 CANOpen files abstracted for furthur use in the project.
+ *
+ */
+
+#ifndef NMS_CAN_H_
+#define NMS_CAN_H_
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+#include "co_datatype.h"
+#include "co_nmt.h"
+/******************************************************************************
+ * Macro constant declarations
+ ******************************************************************************/
+#define NMS_CANOPEN_BITRATE 250u
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+/**
+ * @brief Initializes the CAN controller and CANopen stack.
+ */
+void NmsCanInit(void);
+
+/**
+ * @brief Runs the CAN communication tasks.
+ *
+ * @param canLine_u8 Can line selected.
+ */
+void NmsCanRun(void);
+
+/**
+ * @brief Retrieves a 8-bit object from the CANopen object dictionary.
+ *
+ * @param index_u16 The object dictionary index.
+ * subIndex_u8 The sub-index of the object.
+ * pObj_pu8 Pointer to store the retrieved object value.
+ * canLine_u8 Can line selected.
+ *
+ * @return Error code. (NMS_ERR_NONE if successful, or an error code).
+ */
+uint32 NmsCanGetObj_u8(uint16 index_u16, uint8 subIndex_u8, uint8 *pObj_pu8);
+
+/**
+ * @brief Retrieves a 32-bit object from the CANopen object dictionary.
+ *
+ * @param index_u16 The object dictionary index.
+ * subIndex_u8 The sub-index of the object.
+ * pObj_pu8 Pointer to store the retrieved object value.
+ *
+ * @return Error code. (NMS_ERR_NONE if successful, or an error code).
+ */
+uint32 NmsCanGetObj_u32(uint16 index_u16, uint8 subIndex_u8, uint32 *pObj_pu32);
+
+/**
+ * @brief Retrieves a float object from the CANopen object dictionary.
+ *
+ * @param index_u16 The object dictionary index.
+ * subIndex_u8 The sub-index of the object.
+ * pObj_f32 Pointer to store the retrieved object value.
+ *
+ * @return Error code. (NMS_ERR_NONE if successful, or an error code).
+ */
+uint32 NmsCanGetObj_f32(uint16 index_u16, uint8 subIndex_u8, float32 *pObj_pf32);
+
+/**
+ * @brief Puts a 8-bit object in the CANopen object dictionary.
+ *
+ * @param index_u16 The object dictionary index.
+ * subIndex_u8 The sub-index of the object.
+ * newVal_u32 The new value to be set.
+ *
+ * @return Error code. (NMS_ERR_NONE if successful, or an error code).
+ */
+uint32 NmsCanPutObj_u8(uint16 index_u16, uint8 subIndex_u8, uint8 newVal_u8);
+
+/**
+ * @brief Puts a 32-bit object in the CANopen object dictionary.
+ *
+ * @param index_u16 The object dictionary index.
+ * subIndex_u8 The sub-index of the object.
+ * newVal_u32 The new value to be set.
+ *
+ * @return Error code. (NMS_ERR_NONE if successful, or an error code).
+ */
+uint32 NmsCanPutObj_u32(uint16 index_u16, uint8 subIndex_u8, uint32 newVal_u32);
+
+/**
+ * @brief Puts a float object in the CANopen object dictionary.
+ *
+ * @param index_u16 The object dictionary index.
+ * subIndex_u8 The sub-index of the object.
+ * newVal_u32 The new value to be set.
+ *
+ * @return Error code. (NMS_ERR_NONE if successful, or an error code).
+ */
+uint32 NmsCanPutObj_f32(uint16 index_u16, uint8 subIndex_u8, uint32 newVal_u32);
+
+
+#endif /* NMS_CAN_H_ */
diff --git a/EnduranceTestBench/scheduler/sdl.c b/EnduranceTestBench/scheduler/sdl.c
index 16316aa..5d37a70 100644
--- a/EnduranceTestBench/scheduler/sdl.c
+++ b/EnduranceTestBench/scheduler/sdl.c
@@ -17,105 +17,29 @@
/******************************************************************************
* Include Header Files
******************************************************************************/
-/* CANopen includes */
-#include
-#include
-#include
-#include "co_sdo.h"
-#include "co_odaccess.h"
-
/* User includes */
#include "sdl.h"
+#include "nms_can.h"
#include "processBoard.h"
#include "enduranceTestBench.h"
-#include "hal_system.h"
-
#include "stdlib.h"
+#include "hal_system.h"
/******************************************************************************
* 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_LSS_NODE_COUNT 20u
/******************************************************************************
* Type Declarations
******************************************************************************/
-typedef struct
-{
- uint32 vendorId_u32;
- uint32 productId_u32;
- uint32 versionNbr_u32;
- uint32 serialNbr_u32;
- uint8 nodeId_u8;
-} SdlLssNodeInfo_t;
/******************************************************************************
* Global Declarations
******************************************************************************/
-SdlLssNodeInfo_t var_gst;
-static CO_TIMER_T monitorTimer_gst; /**< application timer */
-static CO_TIMER_T nodeResetTimer_gst; /**< node reset 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 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.
* Need this function for overwriting the manual COB ids
* for the TPDO. */
@@ -127,246 +51,24 @@ static bool SdlAreAllNodesOperational(void);
******************************************************************************/
void SdlInit(void)
{
- SdlInitCanopen();
+ HalSystemInit();
+ NmsCanInit();
}
void SdlRun(void)
{
- SdlRunCanopen();
- SdlLssNodeHandlerRun();
+ NmsCanRun();
if (SdlAreAllNodesOperational())
{
EnduranceTestBenchRun();
+ 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
******************************************************************************/
-/**
- * @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.
@@ -387,166 +89,3 @@ static bool SdlAreAllNodesOperational(void)
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);
- }
- }
-}
-
diff --git a/common/nms_types.h b/common/nms_types.h
index c798e12..4c3a929 100644
--- a/common/nms_types.h
+++ b/common/nms_types.h
@@ -76,7 +76,10 @@ typedef enum
NMS_ERR_NOT_INITIALIZED, /* The initialization was unsuccessful */
NMS_ERR_NOT_RUNNING, /* Module has not been started */
NMS_ERR_BUS_ERROR, /* Memory cannot be physically addressed (e.g. invalid bus address) */
- NMS_ERR_NULL_POINTER
+ NMS_ERR_NULL_POINTER,
+ NMS_ERR_INVALID_MODULE,
+ NMS_ERR_INVALID_POINTER,
+ NMS_LSS_NODE_CONFIG_ERROR,
} NMSErrorEn;
#endif /* NMS_TYPES_H_INCLUDED */