Analog modules reading and pump set speed implemented (untested)
This commit is contained in:
parent
200cdc48c7
commit
7ccde7933f
|
|
@ -71,6 +71,8 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/scheduler}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/log}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms-hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_can}""/>
|
||||
</option>
|
||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.1637079955" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
|
||||
</tool>
|
||||
|
|
@ -126,6 +128,8 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/scheduler}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/log}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms-hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_can}""/>
|
||||
</option>
|
||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.197736294" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
|
||||
</tool>
|
||||
|
|
@ -159,7 +163,8 @@
|
|||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="coappl"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="common"/>
|
||||
<entry excluding="lss.c|lss.h" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nehemis"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nms-hal"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nms_can"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nms_hal"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="scheduler"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
|
|
@ -233,6 +238,8 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/scheduler}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/log}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms-hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_can}""/>
|
||||
</option>
|
||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.957070642" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
|
||||
</tool>
|
||||
|
|
@ -287,6 +294,8 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/scheduler}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/log}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms-hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_hal}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/nms_can}""/>
|
||||
</option>
|
||||
<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c.1211672677" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.input.c"/>
|
||||
</tool>
|
||||
|
|
@ -313,10 +322,10 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nms_hal"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nehemis"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nehemis"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="nms-hal"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
|
|
|||
|
|
@ -40,11 +40,25 @@
|
|||
<type>2</type>
|
||||
<locationURI>copy_PARENT/common</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>nms_can</name>
|
||||
<type>2</type>
|
||||
<locationURI>PROJECT_LOC/nms_can</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>nms_hal</name>
|
||||
<type>2</type>
|
||||
<locationURI>copy_PROJECT_LOC/nms_hal</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
<variableList>
|
||||
<variable>
|
||||
<name>copy_PARENT</name>
|
||||
<value>$%7BPARENT-3-PROJECT_LOC%7D/Documents/NorthStar-Endurance-TestBench</value>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>copy_PROJECT_LOC</name>
|
||||
<value>$%7BPARENT-1-copy_PARENT%7D/NorthStar-Production-Unit-Board-Firmware/ProcessBoardV1</value>
|
||||
</variable>
|
||||
</variableList>
|
||||
</projectDescription>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
92
EnduranceTestBench/nehemis/analogMeasurement.c
Normal file
92
EnduranceTestBench/nehemis/analogMeasurement.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
53
EnduranceTestBench/nehemis/analogMeasurement.h
Normal file
53
EnduranceTestBench/nehemis/analogMeasurement.h
Normal file
|
|
@ -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_ */
|
||||
42
EnduranceTestBench/nehemis/appl.h
Normal file
42
EnduranceTestBench/nehemis/appl.h
Normal file
|
|
@ -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);
|
||||
|
|
@ -13,12 +13,12 @@
|
|||
* Include Header Files
|
||||
******************************************************************************/
|
||||
#include "enduranceTestBench.h"
|
||||
#include "hal_system.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
/* CANopen includes */
|
||||
#include <gen_define.h>
|
||||
#include <co_canopen.h>
|
||||
#include "hal_system.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Macro constant declarations
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
298
EnduranceTestBench/nehemis/test.c
Normal file
298
EnduranceTestBench/nehemis/test.c
Normal file
|
|
@ -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 <gen_define.h>
|
||||
#include <co_canopen.h>
|
||||
#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;
|
||||
}
|
||||
32
EnduranceTestBench/nehemis/test.h
Normal file
32
EnduranceTestBench/nehemis/test.h
Normal file
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
574
EnduranceTestBench/nms_can/nms_can.c
Normal file
574
EnduranceTestBench/nms_can/nms_can.c
Normal file
|
|
@ -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 <gen_define.h>
|
||||
#include <co_canopen.h>
|
||||
#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;
|
||||
}
|
||||
108
EnduranceTestBench/nms_can/nms_can.h
Normal file
108
EnduranceTestBench/nms_can/nms_can.h
Normal file
|
|
@ -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_ */
|
||||
|
|
@ -17,105 +17,29 @@
|
|||
/******************************************************************************
|
||||
* Include Header Files
|
||||
******************************************************************************/
|
||||
/* CANopen includes */
|
||||
#include <co_canopen.h>
|
||||
#include <gen_define.h>
|
||||
#include <co_canopen.h>
|
||||
#include "co_sdo.h"
|
||||
#include "co_odaccess.h"
|
||||
|
||||
/* User includes */
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user