Skip to content

Commit

Permalink
Implement basic vsense monitoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreasdahlberg committed Jan 24, 2024
1 parent d3f8044 commit d4be81a
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 16 deletions.
12 changes: 6 additions & 6 deletions firmware/src/modules/device_monitoring/device_monitoring.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@ along with SillyCat firmware. If not, see <http://www.gnu.org/licenses/>.

enum device_monitoring_reboot_reason
{
DEV_MON_REBOOT_REAS_USER_RESET = 1,
DEV_MON_REBOOT_REAS_FW_UPDATE,
DEV_MON_REBOOT_REAS_SW_RESET,
DEV_MON_REBOOT_REAS_USER_RESET = 1,
DEV_MON_REBOOT_REAS_FW_UPDATE,
DEV_MON_REBOOT_REAS_SW_RESET,
};

enum device_monitoring_metric_id
{
DEV_MON_METRIC_CAN_TX_ERROR = 1,
DEV_MON_METRIC_EMERGENCY_STOP,
DEV_MON_METRIC_MAIN_TASK_TIME,
DEV_MON_METRIC_CAN_TX_ERROR = 1,
DEV_MON_METRIC_EMERGENCY_STOP,
DEV_MON_METRIC_MAIN_TASK_TIME,
};

typedef void (*device_monitoring_timer_cb_t)(void);
Expand Down
3 changes: 2 additions & 1 deletion firmware/src/modules/system_monitor/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ env.Append(CPPPATH=[
'#src/modules/logging',
'#src/modules/systime',
'#src/modules/system_monitor',
'#src/modules/nvcom'
'#src/modules/nvcom',
'#src/modules/filter'

])

Expand Down
105 changes: 98 additions & 7 deletions firmware/src/modules/system_monitor/system_monitor.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @file system_monitor.c
* @Author Andreas Dahlberg (andreas.dahlberg90@gmail.com)
* @author Andreas Dahlberg (andreas.dahlberg90@gmail.com)
* @brief System monitor module.
*/

Expand Down Expand Up @@ -33,6 +33,8 @@ along with CANDrive firmware. If not, see <http://www.gnu.org/licenses/>.
#include "board.h"
#include "systime.h"
#include "nvcom.h"
#include "adc.h"
#include "filter.h"
#include "system_monitor.h"

//////////////////////////////////////////////////////////////////////////
Expand All @@ -49,18 +51,38 @@ along with CANDrive firmware. If not, see <http://www.gnu.org/licenses/>.
#define MAGIC_NUMBER 0xABCD
#define CONTROL_INACTIVITY_PERIOD_MS 200

#define VSENSE_OFF 1000
#define VSENSE_MIN 10000
#define VSENSE_MAX 14000
#define VSENSE_HYST 100

//////////////////////////////////////////////////////////////////////////
//TYPE DEFINITIONS
//////////////////////////////////////////////////////////////////////////

enum vsense_status_t
{
VSENSE_STATUS_UNKNOWN = 0,
VSENSE_STATUS_OK,
VSENSE_STATUS_LOW,
VSENSE_STATUS_HIGH,
VSENSE_STATUS_OFF,
/* No new states after VSENSE_STATUS_END!*/
VSENSE_STATUS_END
};

struct module_t
{
logging_logger_t *logger;
uint32_t number_of_handles;
uint32_t flags;
uint32_t control_activity_timer;
uint32_t timer;
enum system_monitor_state_t state;
struct nvcom_data_t *restart_information_p;
adc_input_t adc_input;
struct filter_t filter;
enum vsense_status_t vsense_status;
};

//////////////////////////////////////////////////////////////////////////
Expand All @@ -73,6 +95,9 @@ static struct module_t module;
//LOCAL FUNCTION PROTOTYPES
//////////////////////////////////////////////////////////////////////////

static void InitializeVsenseMonitoring(void);
static void UpdateVsenseFilter(void);
static void UpdateVsenseStatus(void);
static inline bool IsColdRestart(void);
static inline uint32_t GetRequiredFlags(void);
static inline bool IsWatchdogRestart(void);
Expand Down Expand Up @@ -104,6 +129,8 @@ void SystemMonitor_Init(void)
iwdg_set_period_ms(WATCHDOG_PERIOD_MS);
iwdg_start();

InitializeVsenseMonitoring();

Logging_Info(module.logger, "SystemMonitor initialized {state: SYSTEM_MONITOR_INACTIVE}");
}

Expand All @@ -117,6 +144,15 @@ void SystemMonitor_Update(void)
module.flags = 0;
}

const uint32_t update_period_ms = 100;
if (SysTime_GetDifference(module.timer) >= update_period_ms)
{
UpdateVsenseFilter();
UpdateVsenseStatus();

module.timer = SysTime_GetSystemTime();
}

if (Board_GetEmergencyPinState())
{
if (module.state != SYSTEM_MONITOR_EMERGENCY)
Expand All @@ -127,12 +163,22 @@ void SystemMonitor_Update(void)
}
else
{

if ((module.state != SYSTEM_MONITOR_INACTIVE) &&
(SysTime_GetDifference(module.control_activity_timer) > CONTROL_INACTIVITY_PERIOD_MS))
if ((module.vsense_status != VSENSE_STATUS_OK) && (module.vsense_status != VSENSE_STATUS_UNKNOWN))
{
if (module.state != SYSTEM_MONITOR_FAIL)
{
Logging_Info(module.logger, "{state: SYSTEM_MONITOR_FAIL}");
module.state = SYSTEM_MONITOR_FAIL;
}
}
else
{
Logging_Info(module.logger, "{state: SYSTEM_MONITOR_INACTIVE}");
module.state = SYSTEM_MONITOR_INACTIVE;
if ((module.state != SYSTEM_MONITOR_INACTIVE) &&
(SysTime_GetDifference(module.control_activity_timer) > CONTROL_INACTIVITY_PERIOD_MS))
{
Logging_Info(module.logger, "{state: SYSTEM_MONITOR_INACTIVE}");
module.state = SYSTEM_MONITOR_INACTIVE;
}
}
}
}
Expand All @@ -157,7 +203,8 @@ void SystemMonitor_FeedWatchdog(uint32_t handle)

void SystemMonitor_ReportActivity(void)
{
if (!Board_GetEmergencyPinState())
if ((!Board_GetEmergencyPinState()) &&
((module.vsense_status == VSENSE_STATUS_UNKNOWN) || (module.vsense_status == VSENSE_STATUS_OK)))
{
module.state = SYSTEM_MONITOR_ACTIVE;
}
Expand All @@ -179,6 +226,50 @@ uint32_t SystemMonitor_GetResetFlags(void)
//LOCAL FUNCTIONS
//////////////////////////////////////////////////////////////////////////

static void InitializeVsenseMonitoring(void)
{
const uint8_t channel = 14;
ADC_InitChannel(&module.adc_input, channel);
}

static void UpdateVsenseFilter(void)
{
const uint32_t voltage = Board_VSenseToVoltage(ADC_GetVoltage(&module.adc_input));

if (Filter_IsInitialized(&module.filter))
{
Filter_Process(&module.filter, voltage);
}
else
{
Filter_Init(&module.filter, voltage, FILTER_ALPHA(0.5));
}
}

static void UpdateVsenseStatus(void)
{
uint32_t vsense = Filter_Output(&module.filter);

if (vsense < VSENSE_OFF)
{
module.vsense_status = VSENSE_STATUS_OFF;
}
else if (vsense < VSENSE_MIN)
{
module.vsense_status = VSENSE_STATUS_LOW;
}
else if (vsense > VSENSE_MAX)
{
module.vsense_status = VSENSE_STATUS_HIGH;
}
else if (vsense > VSENSE_MIN + VSENSE_HYST)
{
module.vsense_status = VSENSE_STATUS_OK;
} else {
/* No change to Vsense status*/
}
}

static inline bool IsColdRestart(void)
{
return module.restart_information_p->number_of_restarts == 0;
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/modules/system_monitor/test/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Import(['*'])
test_env = env.Clone()
test_env['CCFLAGS'].remove('--coverage')
test_env.Append(CPPPATH=[
'#src/modules/system_monitor',
'#src/modules/system_monitor'
])

source = Glob('*.c')
Expand Down
13 changes: 12 additions & 1 deletion firmware/src/modules/system_monitor/test/test_system_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ static void test_SystemMonitor_Update(void **state)
handles[i] = SystemMonitor_GetWatchdogHandle();
}

will_return_always(SysTime_GetDifference, 0);
will_return_always(Board_GetEmergencyPinState, false);

/* Expect watchdog reset since the watchdog is feed when getting the handles*/
Expand All @@ -215,6 +216,8 @@ static void test_SystemMonitor_Update(void **state)

static void test_SystemMonitor_ControlActivity(void **state)
{
will_return(SysTime_GetDifference, 0);

SystemMonitor_GetWatchdogHandle();
assert_int_equal(SystemMonitor_GetState(), SYSTEM_MONITOR_INACTIVE);

Expand All @@ -229,8 +232,14 @@ static void test_SystemMonitor_ControlActivity(void **state)
SystemMonitor_Update();
assert_int_equal(SystemMonitor_GetState(), SYSTEM_MONITOR_ACTIVE);

will_return(SysTime_GetSystemTime, 0);
will_return_always(ADC_GetVoltage, 100);
will_return_always(Board_VSenseToVoltage, 12000);
will_return_always(Filter_IsInitialized, true);
will_return_always(Filter_Output, 12000);

will_return(Board_GetEmergencyPinState, false);
will_return(SysTime_GetDifference, 201);
will_return_count(SysTime_GetDifference, 201, 2);
SystemMonitor_Update();
assert_int_equal(SystemMonitor_GetState(), SYSTEM_MONITOR_INACTIVE);

Expand All @@ -243,6 +252,8 @@ static void test_SystemMonitor_ControlActivity(void **state)

static void test_SystemMonitor_Emergency(void **state)
{
will_return_always(SysTime_GetDifference, 0);

SystemMonitor_GetWatchdogHandle();

expect_function_call(iwdg_reset);
Expand Down

0 comments on commit d4be81a

Please sign in to comment.