diag.c (primary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag.c
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE
* @prefix DIAG
*
* @brief Diag driver implementation
*
* This diagnose module is responsible for error handling and reporting.
* Reported errors are logged into the global database and can be reviewed
* on user request.
*/
/*================== Includes =============================================*/
#include "diag.h"
#include "contactor.h"
#include "com.h"
#include "os.h"
#include "misc.h"
#include "nvramhandler.h"
#include "rtc.h"
/*================== Macros and Definitions ===============================*/
/*================== Constant and Variable Definitions ====================*/
static DIAG_s diag;
static DIAG_DEV_s *diag_devptr;
static uint32_t diagsysmonTimestamp = 0;
static uint8_t diag_locked = 0;
// FIXME unused
// FIXME do you really want to have global variables?
DIAG_CODE_s diag_err;
DIAG_CODE_s diag_warn;
DIAG_OCCURRENCE_COUNTERS_s diag_occurrence_counters;
//uint32_t diag_error;
DIAG_SYSMON_NOTIFICATION_s diag_sysmon[DIAG_SYSMON_MODULE_ID_MAX];
DIAG_SYSMON_NOTIFICATION_s diag_sysmon_last[DIAG_SYSMON_MODULE_ID_MAX];
uint32_t diag_sysmon_cnt[DIAG_SYSMON_MODULE_ID_MAX];
DIAG_ERROR_ENTRY_s MEM_BKP_SRAM diag_memory[DIAG_FAIL_ENTRY_LENGTH];
DIAG_ERROR_ENTRY_s MEM_BKP_SRAM *diag_entry_wrptr;
DIAG_ERROR_ENTRY_s MEM_BKP_SRAM *diag_entry_rdptr;
DIAG_CONTACTOR_ERROR_ENTRY_s MEM_BKP_SRAM diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH];
DIAG_CONTACTOR_ERROR_ENTRY_s MEM_BKP_SRAM *diagContactorError_entry_wrptr;
DIAG_CONTACTOR_ERROR_ENTRY_s MEM_BKP_SRAM *diagContactorError_entry_rdptr;
DIAG_FAILURECODE_s diag_fc;
/*================== Function Prototypes ==================================*/
static void DIAG_Reset(void);
static uint8_t DIAG_EntryWrite(uint8_t eventID, DIAG_EVENT_e event, uint32_t item_nr);
static DIAG_RETURNTYPE_e DIAG_GeneralHandler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr);
static DIAG_RETURNTYPE_e DIAG_ContHandler(DIAG_CH_ID_e eventID, uint32_t cont_nr, float* openingCur);
/*================== Function Implementations =============================*/
/**
* @brief DIAG_Reset resets/initalizes all needed strcutures/buffers.
*
* This function gets called during initialization of the diagnose module.
* It clears memory and counters used by diag later on.
*/
static void DIAG_Reset(void)
{
uint32_t i;
uint32_t *u32ptr = (uint32_t*)(&diag_memory[0]);
diag_locked = 1;
/* Delete memory */
for(i = 0; i < (sizeof(diag_memory))/4; i++)
*u32ptr++ = 0;
/* Reset counter */
for(i = 0; i < sizeof(diag.entry_cnt); i++)
diag.entry_cnt[i] = 0;
/* Set pointer to beginning of buffer */
diag_entry_wrptr = diag_entry_rdptr = &diag_memory[0];
diag.errcnttotal = 0;
/* Set pointer to beginning of buffer */
u32ptr = (uint32_t*)(&diagContactorErrorMemory[0]);
/* Delete memory */
for(i = 0; i < (sizeof(diagContactorErrorMemory))/4; i++)
*u32ptr++ = 0;
/* Set pointer to beginning of buffer */
diagContactorError_entry_wrptr = diagContactorError_entry_rdptr = &diagContactorErrorMemory[0];
diag_locked=0;
}
STD_RETURN_TYPE_e DIAG_Init(DIAG_DEV_s *diag_dev_pointer, STD_RETURN_TYPE_e bkpramValid) {
STD_RETURN_TYPE_e retval = E_OK;
uint8_t c = 0;
uint8_t id_nr = DIAG_ID_MAX;
uint32_t tmperr_Check[(DIAG_ID_MAX+31)/32];
diag_devptr = diag_dev_pointer;
diag.state = DIAG_STATE_UNINITIALIZED;
uint16_t checkfail = 0;
if( (diag_entry_rdptr<&diag_memory[0]) || (diag_entry_rdptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH]))
checkfail |= 0x01;
if( (diag_entry_wrptr<&diag_memory[0]) || (diag_entry_wrptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH]))
checkfail |= 0x02;
if(bkpramValid == E_NOT_OK)
checkfail |= 0x04;
if( (diagContactorError_entry_rdptr < &diagContactorErrorMemory[0]) ||
(diagContactorError_entry_rdptr >= &diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH]) )
checkfail |= 0x08;
if( (diagContactorError_entry_wrptr < &diagContactorErrorMemory[0]) ||
(diagContactorError_entry_wrptr >= &diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH]))
checkfail |= 0x10;
if(checkfail) {
DIAG_Reset();
}
/* Fill lookup table id2ch */
for(c = 0; c < diag_dev_pointer->nr_of_ch; c++) {
id_nr = diag_dev_pointer->ch_cfg[c].id;
if(id_nr < DIAG_ID_MAX) {
diag.id2ch[id_nr] = c; // e.g. diag.id2ch[DIAG_ID_90] = configured channel index
} else {
/* Configuration error -> set retval to E_NOT_OK */
checkfail |= 0x20;
retval = E_NOT_OK;
}
}
for(int i = 0; i < (DIAG_ID_MAX+31)/32; i++)
tmperr_Check[i] = 0;
/* Fill enable array err_enableflag */
for(int i = 0; i < diag_dev_pointer->nr_of_ch; i++) {
if(diag_dev_pointer->ch_cfg[i].state == DIAG_DISABLED) {
/* Disable diagnosis entry */
tmperr_Check[diag_dev_pointer->ch_cfg[i].id/32] |= 1 << (diag_dev_pointer->ch_cfg[i].id % 32);
}
}
/* take over configured error enable masks*/
for(c = 0; c < (DIAG_ID_MAX+31)/32; c++) {
diag.err_enableflag[c] = ~tmperr_Check[c];
}
diag.state = DIAG_STATE_INITIALIZED;
if(checkfail) {
/* make first entry after DIAG_Reset() */
(void)(DIAG_Handler(DIAG_CH_BKPDIAG_FAILURE, DIAG_EVENT_NOK, checkfail, NULL));
}
return retval;
}
void DIAG_PrintErrors(void) {
/* FIXME if read once, rdptr is on writeptr, therefore in the next call the errors aren't
* printed again. Maybe tmp save rdptr and set again at end of function. But when is the
* diag memory cleared then? */
uint8_t buf[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
if(diag_entry_rdptr == diag_entry_wrptr)
{
DEBUG_PRINTF((const uint8_t * )"no new entries in DIAG");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
else
{
DEBUG_PRINTF((const uint8_t * )"DIAG error entries:");
DEBUG_PRINTF((const uint8_t * )"\r\n");
DEBUG_PRINTF((const uint8_t * )"Date and Time: Error Code/Item Status Description");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
uint8_t c = 0;
while(diag_entry_rdptr != diag_entry_wrptr && c < 7)
{
if( diag_entry_rdptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH]) {
diag_entry_rdptr = &diag_memory[0];
}
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->DD, 2));
DEBUG_PRINTF((const uint8_t * )".");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->MM, 2));
DEBUG_PRINTF((const uint8_t * )".");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->YY, 2));
DEBUG_PRINTF((const uint8_t * )" - ");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->hh, 2));
DEBUG_PRINTF((const uint8_t * )":");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->mm, 2));
DEBUG_PRINTF((const uint8_t * )":");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->ss, 2));
DEBUG_PRINTF((const uint8_t * )" ");
DEBUG_PRINTF(U8ToDecascii(buf, (uint8_t*)(&diag_entry_rdptr->event_id), 2));
DEBUG_PRINTF((const uint8_t * )" / 0x");
DEBUG_PRINTF(U32ToHexascii(buf, &diag_entry_rdptr->item));
DEBUG_PRINTF((const uint8_t * )" ");
if(diag_entry_rdptr->event == DIAG_EVENT_OK)
DEBUG_PRINTF((const uint8_t * )"cleared ");
else if(diag_entry_rdptr->event == DIAG_EVENT_NOK)
DEBUG_PRINTF((const uint8_t * )"occurred ");
else
DEBUG_PRINTF((const uint8_t * )"reset ");
for(uint8_t i = 0; i < 24; i++)
buf[i] = diag_devptr->ch_cfg[diag.id2ch[diag_entry_rdptr->event_id]].description[i];
DEBUG_PRINTF((const uint8_t *)buf);
DEBUG_PRINTF((const uint8_t * )"\r\n");
diag_entry_rdptr++;
c++;
}
// More entries in diag buffer
if(diag_entry_rdptr != diag_entry_wrptr)
DEBUG_PRINTF((const uint8_t * )"Please repeat command. Additional error entries in DIAG buffer available!\r\n");
}
void DIAG_PrintContactorInfo(void)
{
/* FIXME if read once, rdptr is on writeptr, therefore in the next call the errors aren't
* printed again. Maybe tmp save rdptr and set again at end of function. But when is the
* diag memory cleared then? */
uint8_t buf[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int32_t tmp = 0;
DIAG_CONTACTOR_s diagContactor;
NVM_Get_contactorcnt(&diagContactor);
DEBUG_PRINTF((const uint8_t * )"Contactor switching entries:");
DEBUG_PRINTF((const uint8_t * )"\r\n");
for(uint8_t i = 0; i < BS_NR_OF_CONTACTORS; i++) {
DEBUG_PRINTF((const uint8_t * )"Contactor ");
DEBUG_PRINTF(U8ToDecascii(buf, &i, 2));
DEBUG_PRINTF((const uint8_t * )"\r\nOpening switches: ");
DEBUG_PRINTF(U16ToHexascii(buf, &diagContactor.cont_switch_opened[i]));
DEBUG_PRINTF((const uint8_t * )"\r\nClosing switches: ");
DEBUG_PRINTF(U16ToHexascii(buf, &diagContactor.cont_switch_closed[i]));
DEBUG_PRINTF((const uint8_t * )"\r\nOpening switches hard at current: ");
DEBUG_PRINTF(U16ToHexascii(buf, &diagContactor.cont_switch_opened_hard_at_current[i]));
DEBUG_PRINTF((const uint8_t * )"\r\n\n");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
DEBUG_PRINTF((const uint8_t * )"\r\n");
if(diagContactorError_entry_rdptr == diagContactorError_entry_wrptr)
{
DEBUG_PRINTF((const uint8_t * )"no entries in Contactor");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
else
{
DEBUG_PRINTF((const uint8_t * )"Contactor error entries:");
DEBUG_PRINTF((const uint8_t * )"\r\n");
DEBUG_PRINTF((const uint8_t * )"Date and Time Contactor Opening current");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
while(diagContactorError_entry_rdptr != diagContactorError_entry_wrptr)
{
if( diagContactorError_entry_rdptr >= &diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH]) {
diagContactorError_entry_rdptr = &diagContactorErrorMemory[0];
}
DEBUG_PRINTF(U8ToDecascii(buf, &diagContactorError_entry_rdptr->DD, 2));
DEBUG_PRINTF((const uint8_t * )".");
DEBUG_PRINTF(U8ToDecascii(buf, &diagContactorError_entry_rdptr->MM, 2));
DEBUG_PRINTF((const uint8_t * )".");
DEBUG_PRINTF(U8ToDecascii(buf, &diagContactorError_entry_rdptr->YY, 2));
DEBUG_PRINTF((const uint8_t * )" - ");
DEBUG_PRINTF(U8ToDecascii(buf, &diagContactorError_entry_rdptr->hh, 2));
DEBUG_PRINTF((const uint8_t * )":");
DEBUG_PRINTF(U8ToDecascii(buf, &diagContactorError_entry_rdptr->mm, 2));
DEBUG_PRINTF((const uint8_t * )":");
DEBUG_PRINTF(U8ToDecascii(buf, &diagContactorError_entry_rdptr->ss, 2));
DEBUG_PRINTF((const uint8_t * )" ");
DEBUG_PRINTF(U8ToDecascii(buf, (uint8_t*)(&diagContactorError_entry_rdptr->contactor), 2));
DEBUG_PRINTF((const uint8_t * )" ");
tmp = (int32_t)diagContactorError_entry_rdptr->openingCurrent;
DEBUG_PRINTF(I32ToDecascii(buf, &tmp));
DEBUG_PRINTF((const uint8_t * )"mA\r\n");
diagContactorError_entry_rdptr++;
}
/* Reset counter for open errors */
diagContactor.errcntreported = 0;
}
/**
* @brief DIAG_EntryWrite adds an error entry.
*
* This function adds an entry to the error buffer.
* It provides some functionality to prevent duplicates from being logged.
* Multiple occurring error doesn't get logged anymore after they reached a
* pre-defined error count.
*
* @param eventID: ID of entry
* @param event: OK, NOK or RESET
* @param item_nr: item number of event
*
* @return 0xFF if event is logged, otherwise 0
*/
static uint8_t DIAG_EntryWrite(uint8_t eventID, DIAG_EVENT_e event, uint32_t item_nr) {
uint8_t ret_val = 0;
uint8_t c;
RTC_Time_s currTime;
RTC_Date_s currDate;
uint8_t buf[25] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // max. description length = 24 + 1 to identify end of array
if(diag_locked)
return ret_val; // only locked when clearing the diagnosis memory
if(diag.entry_event[eventID] == event)
return ret_val; // same event of same error type already recorded before -> ignore until event toggles
if((diag.entry_event[eventID] == DIAG_EVENT_OK) && (event == DIAG_EVENT_RESET))
return ret_val; // do record DIAG_EVENT_RESET-event only if last event was an error (re-initialization)
// meaning: DIAG_EVENT_RESET-event at first time call or after DIAG_EVENT_OK-event will not be recorded
if(++diag.entry_cnt[eventID] > DIAG_MAX_ENTRIES_OF_ERROR){
diag.entry_cnt[eventID] = DIAG_MAX_ENTRIES_OF_ERROR;
return ret_val; // this type of error has been recorded too many times -> ignore to avoid filling buffer with same failurecodes
}
if( diag_entry_wrptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH] ) {
diag_entry_wrptr = &diag_memory[0];
}
// now record failurecode
ret_val=0xFF;
RTC_getTime(&currTime);
RTC_getDate(&currDate);
diag_entry_wrptr->YY = currDate.Year;
diag_entry_wrptr->MM = currDate.Month;
diag_entry_wrptr->DD = currDate.Date;
diag_entry_wrptr->hh = currTime.Hours;
diag_entry_wrptr->mm = currTime.Minutes;
diag_entry_wrptr->ss = currTime.Seconds;
diag_entry_wrptr->event_id = eventID; // Error Code 0... 4x32-1
diag_entry_wrptr->item = item_nr; //
diag_entry_wrptr->event = (uint8_t)event; // DIAG_EVENT_OK, DIAG_EVENT_NOK, DIAG_EVENT_RESET
diag_entry_wrptr->Val0 = diag_fc.Val0;
diag_entry_wrptr->Val1 = diag_fc.Val1;
diag_entry_wrptr->Val2 = diag_fc.Val2;
diag_entry_wrptr->Val3 = diag_fc.Val3;
++diag_entry_wrptr;
++diag.errcntreported; // counts of (new) diagnosis entry records which is still not been read by external Tool
// which will reset this value to 0 after having read all new entries which means <acknowledged by user>
++diag.errcnttotal; // total counts of diagnosis entry records
diag.entry_event[eventID] = event;
DEBUG_PRINTF((const uint8_t * )"New Error entry! (");
c = (uint8_t) diag.errcntreported;
DEBUG_PRINTF(U8ToDecascii(buf, &c,3));
DEBUG_PRINTF((const uint8_t * )"): Error Code/Item ");
DEBUG_PRINTF(U8ToDecascii(buf, &eventID, 3));
DEBUG_PRINTF((const uint8_t * )"/0x");
DEBUG_PRINTF(U32ToHexascii(buf, &item_nr));
DEBUG_PRINTF((const uint8_t * )" ");
// Copy error description in buffer, maximum description length = 24 characters
for(uint8_t i = 0; i < 24; i++)
buf[i] = diag_devptr->ch_cfg[diag.id2ch[eventID]].description[i];
DEBUG_PRINTF((const uint8_t *)buf);
if(event==DIAG_EVENT_OK)
DEBUG_PRINTF((const uint8_t * )" cleared");
else if (event==DIAG_EVENT_NOK)
DEBUG_PRINTF((const uint8_t * )" occurred");
else // DIAG_EVENT_RESET
DEBUG_PRINTF((const uint8_t * )" reset");
DEBUG_PRINTF((const uint8_t * )"\r\n");
return ret_val;
}
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr, void* data) {
DIAG_RETURNTYPE_e retVal = DIAG_HANDLER_RETURN_UNKNOWN;
/* Get diagnosis type */
DIAG_TYPE_e diagType = diag_dev.ch_cfg[diag.id2ch[diag_ch_id]].type;
switch(diagType) {
/* Call handler function depending on diagnosis type */
case DIAG_GENERAL_TYPE:
retVal = DIAG_GeneralHandler(diag_ch_id, event, item_nr);
break;
case DIAG_CELLMON_TYPE:
break;
case DIAG_COM_TYPE:
break;
case DIAG_ADC_TYPE:
break;
case DIAG_CONT_TYPE:
// item_nr is contactor number
retVal = DIAG_ContHandler(diag_ch_id, item_nr, (float*) data);
break;
default:
break;
}
return retVal;
}
/**
* @brief DIAG_GeneralHandler provides generic error handling, based on configuration.
*
* This function does all the handling based on the user defined configuration.
* According to its return value further treatment is left to the calling module itself.
* @param diag_ch_id: event ID of the event that has occurred
* @param event: event that occurred (OK, NOK, RESET)
* @param item_nr: item nr of event, to distinguish between different calling locations of the event
*
* @return DIAG_STATE_UNINITIALIZED if diag module still uninitialized,\n
* DIAG_HANDLER_RETURN_WRONG_ID if invalid diag id,\n
* DIAG_HANDLER_INVALID_TYPE if diag id doesn't correspond to diag type,\n
* DIAG_HANDLER_RETURN_OK if error/warning occurred but no threshold reached or event = DIAG_EVENT_OK/DIAG_EVENT_RESET,\n
* DIAG_HANDLER_RETURN_ERR_OCCURRED if error threshold reached,\n
* DIAG_HANDLER_RETURN_WARNING_OCCURRED if warning threshold reached,\n
*/
static DIAG_RETURNTYPE_e DIAG_GeneralHandler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr) {
uint32_t ret_val = DIAG_HANDLER_RETURN_UNKNOWN;
uint32_t *u32ptr_errCodemsk, *u32ptr_warnCodemsk;
uint16_t *u16ptr_threshcounter;
uint16_t cfg_threshold;
uint16_t err_enable_idx;
uint32_t err_enable_bitmask;
DIAG_TYPE_RECORDING_e recordingenabled;
if(diag.state == DIAG_STATE_UNINITIALIZED) {
return (DIAG_HANDLER_RETURN_NOT_READY);
}
if(diag_ch_id >= DIAG_ID_MAX) {
return (DIAG_HANDLER_RETURN_WRONG_ID);
}
if((diag_ch_id == DIAG_CH_CONTACTOR_DAMAGED) || (diag_ch_id == DIAG_CH_CONTACTOR_OPENING) ||
(diag_ch_id == DIAG_CH_CONTACTOR_CLOSING)) {
return (DIAG_HANDLER_INVALID_TYPE);
}
err_enable_idx = diag_ch_id/32; // array index of diag.err_enableflag[..]
err_enable_bitmask = 1<<(diag_ch_id%32); // bit number (mask) of diag.err_enableflag[idx]
u32ptr_errCodemsk = &diag.errflag[err_enable_idx];
u32ptr_warnCodemsk = &diag.warnflag[err_enable_idx];
u16ptr_threshcounter = &diag.occurrence_cnt[diag_ch_id];
cfg_threshold = diag_devptr->ch_cfg[diag.id2ch[diag_ch_id]].thresholds;
recordingenabled = diag_devptr->ch_cfg[diag.id2ch[diag_ch_id]].enablerecording;
if(event == DIAG_EVENT_OK)
{
if(diag.err_enableflag[err_enable_idx] & err_enable_bitmask)
{
//if (((*u16ptr_threshcounter) == 0) && (*u32ptr_errCodemsk == 0))
if (((*u16ptr_threshcounter) == 0))
{
; // everything ok, nothing to be handled
}
else if ((*u16ptr_threshcounter) > 1 )
{
(*u16ptr_threshcounter)--; // Error did not occur, decrement Error-Counter
}
//else if ((*u16ptr_threshcounter) <= 1)
else if ((*u16ptr_threshcounter) == 1)
{ // Error did not occur, now decrement to zero and clear Error- or Warning-Flag and make recording if enabled
*u32ptr_errCodemsk &= ~err_enable_bitmask; // ERROR: clear corresponding bit in errflag[idx]
*u32ptr_warnCodemsk &= ~err_enable_bitmask; // WARNING: clear corresponding bit in warnflag[idx]
(*u16ptr_threshcounter) = 0;
//Make entry in error-memory (error disappeared)
if(recordingenabled == DIAG_RECORDING_ENABLED)
DIAG_EntryWrite(diag_ch_id, event, item_nr);
/* Call callback function and reset error */
diag_ch_cfg[diag.id2ch[diag_ch_id]].callbackfunc(diag_ch_id, DIAG_EVENT_RESET);
}
}
ret_val = DIAG_HANDLER_RETURN_OK; // Function does not return an error-message!
}
else if(event == DIAG_EVENT_NOK)
{
if( diag.err_enableflag[err_enable_idx] & err_enable_bitmask )
{
if ((*u16ptr_threshcounter) < cfg_threshold )
{
(*u16ptr_threshcounter)++; // error-threshold not exceeded yet, increment Error-Counter
ret_val = DIAG_HANDLER_RETURN_OK; // Function does not return an error-message!
}
else if ((*u16ptr_threshcounter) == cfg_threshold )
{
// Error occured AND error-threshold exceeded
(*u16ptr_threshcounter)++;
*u32ptr_errCodemsk |= err_enable_bitmask; // ERROR: set corresponding bit in errflag[idx]
*u32ptr_warnCodemsk &= ~err_enable_bitmask; // WARNING: clear corresponding bit in warnflag[idx]
//Make entry in error-memory (error occurred)
if(recordingenabled == DIAG_RECORDING_ENABLED)
DIAG_EntryWrite(diag_ch_id, event, item_nr);
/* Call callback function and set error */
diag_ch_cfg[diag.id2ch[diag_ch_id]].callbackfunc(diag_ch_id, DIAG_EVENT_NOK);
/* Function returns an error-message! */
ret_val = DIAG_HANDLER_RETURN_ERR_OCCURRED;
}
else if (((*u16ptr_threshcounter) > cfg_threshold))
{
; // error-threshold already exceeded, nothing to be handled
}
}
else
{
// Error occured BUT NOT enabled by mask
*u32ptr_errCodemsk &= ~err_enable_bitmask; // ERROR: clear corresponding bit in errflag[idx]
*u32ptr_warnCodemsk |= err_enable_bitmask; // WARNING: set corresponding bit in warnflag[idx]
ret_val = DIAG_HANDLER_RETURN_WARNING_OCCURRED; // Function returns an error-message!
}
}
else if(event == DIAG_EVENT_RESET)
{
if(diag.err_enableflag[err_enable_idx] & err_enable_bitmask)
{ //clear counter, Error-, Warning-Flag and make recording if enabled
*u32ptr_errCodemsk &= ~err_enable_bitmask; // ERROR: clear corresponding bit in errflag[idx]
*u32ptr_warnCodemsk &= ~err_enable_bitmask; // WARNING: clear corresponding bit in warnflag[idx]
(*u16ptr_threshcounter) = 0;
if(recordingenabled==DIAG_RECORDING_ENABLED)
DIAG_EntryWrite(diag_ch_id, event, item_nr); //Make entry in error-memory (error disappeared) if error was recorded before
}
ret_val = DIAG_HANDLER_RETURN_OK; // Function does not return an error-message!
}
return (ret_val);
}
/**
* @brief DIAG_ContHandler provides generic contactor switching handling, based on configuration.
*
* This function does all the handling based on the user defined configuration.
* It needs to get called in every occurrence where a contactor is either opened or closed.
* According to its return value further treatment is left to the calling module itself.
*
* @param eventID switching event that occurred
* @param cont_nr contactor that switches
* @param openingCur current flow during contactor opening
*
* @return DIAG_HANDLER_RETURN_ERR_OCCURRED if hard opening threshold is reached,\n
* DIAG_HANDLER_RETURN_OK if normal opening/closing of contactor occurred or threshold not reached,\n
* DIAG_HANDLER_INVALID_TYPE if called with wrong eventID,\n
* DIAG_HANDLER_INVALID_DATA if no opening current is passed in case of hard opening
*/
static DIAG_RETURNTYPE_e DIAG_ContHandler(DIAG_CH_ID_e eventID, uint32_t cont_nr, float* openingCur) {
DIAG_RETURNTYPE_e retVal = DIAG_HANDLER_RETURN_UNKNOWN;
uint8_t updateNVRAM = 0;
if(diag_locked)
return retVal; // only locked when clearing the diagnosis memory
DIAG_CONTACTOR_s diagContactor;
NVM_Get_contactorcnt(&diagContactor);
if(eventID == DIAG_CH_CONTACTOR_OPENING) {
diagContactor.cont_switch_opened[cont_nr]++;
retVal = DIAG_HANDLER_RETURN_OK;
}
else if(eventID == DIAG_CH_CONTACTOR_CLOSING) {
diagContactor.cont_switch_closed[cont_nr]++;
retVal = DIAG_HANDLER_RETURN_OK;
}
else if(eventID == DIAG_CH_CONTACTOR_DAMAGED) {
if (NULL_PTR == openingCur) {
retVal = DIAG_HANDLER_INVALID_DATA;
}
else {
RTC_Time_s currTime;
RTC_Date_s currDate;
uint8_t buf[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
updateNVRAM = 1;
diagContactor.cont_switch_opened_hard_at_current[cont_nr]++;
if(diagContactor.cont_switch_opened_hard_at_current[cont_nr] >= CONT_NUMBER_OF_BAD_COUNTINGS)
retVal = DIAG_HANDLER_RETURN_ERR_OCCURRED;
else
retVal = DIAG_HANDLER_RETURN_OK;
if( diagContactorError_entry_wrptr >= &diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH]) {
diagContactorError_entry_wrptr = &diagContactorErrorMemory[0];
}
/* Write error entry */
/* Get time and date */
RTC_getTime(&currTime);
RTC_getDate(&currDate);
/* Set time and date */
diagContactorError_entry_wrptr->YY = currDate.Year;
diagContactorError_entry_wrptr->MM = currDate.Month;
diagContactorError_entry_wrptr->DD = currDate.Date;
diagContactorError_entry_wrptr->hh = currTime.Hours;
diagContactorError_entry_wrptr->mm = currTime.Minutes;
diagContactorError_entry_wrptr->ss = currTime.Seconds;
diagContactorError_entry_wrptr->contactor = (uint8_t)cont_nr;
diagContactorError_entry_wrptr->openingCurrent = *openingCur;
diagContactorError_entry_wrptr++;
DEBUG_PRINTF((const uint8_t * )"new Contactor error entry! currently ");
uint8_t tmp = (uint8_t)diagContactor.errcntreported;
DEBUG_PRINTF(U8ToDecascii(buf, &tmp, 2));
DEBUG_PRINTF((const uint8_t * )" error entrys");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
}
else {
retVal = DIAG_HANDLER_INVALID_TYPE;
}
if ((DIAG_HANDLER_RETURN_ERR_OCCURRED == retVal) || (DIAG_HANDLER_RETURN_OK == retVal)) {
/* Write new value in nvram buffer */
NVM_Set_contactorcnt(&diagContactor);
if (updateNVRAM == 1) {
/* Update NVRAM only if contactor opened hard at curren */
NVRAM_setWriteRequest(NVRAM_BLOCK_ID_CONT_COUNTER);
}
}
return retVal;
}
/**
* @brief overall system monitoring
*
* checks notifications (state and timestamps) of all system-relevant tasks or functions
* all checks should be customized corresponding to its timing and state requirements
*/
void DIAG_SysMon(void) {
DIAG_SYSMON_MODULE_ID_e module_id;
uint32_t localTimer = OS_getOSSysTick();
if (diagsysmonTimestamp == localTimer) {
return;
}
diagsysmonTimestamp = localTimer;
/* check modules */
for (module_id = 0; module_id < DIAG_SYSMON_MODULE_ID_MAX; module_id++) {
if ((diag_sysmon_ch_cfg[module_id].type == DIAG_SYSMON_CYCLICTASK) &&
(diag_sysmon_ch_cfg[module_id].state == DIAG_ENABLED)) {
if(diag_sysmon[module_id].timestamp - diag_sysmon_last[module_id].timestamp < 1) {
// module not running
if(++diag_sysmon_cnt[module_id] >= diag_sysmon_ch_cfg[module_id].threshold) {
//@todo configurable timeouts !
if(diag_sysmon_ch_cfg[module_id].enablerecording == DIAG_RECORDING_ENABLED) {
DIAG_Handler(DIAG_CH_SYSTEMMONITORING_TIMEOUT,DIAG_EVENT_NOK,module_id, NULL);
}
if(diag_sysmon_ch_cfg[module_id].handlingtype == DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR) {
// system not working trustfully, switch off contactors!
CONT_SwitchAllContactorsOff();
}
diag_sysmon_cnt[module_id] = 0;
// @todo: call callback function if error occurred
diag_sysmon_ch_cfg[module_id].callbackfunc(module_id);
}
} else {
// module running
diag_sysmon_cnt[module_id] = 0;
if(diag_sysmon[module_id].state != 0) {
/* check state of module */
// @todo: do something now!
}
}
} else {
// if Sysmon type != cyclic task (not used at the moment)
}
diag_sysmon_last[module_id] = diag_sysmon[module_id]; /*save last values for next check*/
}
}
void DIAG_SysMonNotify(DIAG_SYSMON_MODULE_ID_e module_id, uint32_t state) {
if (module_id < DIAG_SYSMON_MODULE_ID_MAX) {
taskENTER_CRITICAL();
diag_sysmon[module_id].timestamp = OS_getOSSysTick();
diag_sysmon[module_id].state = state;
taskEXIT_CRITICAL();
}
}
void DIAG_configASSERT(void) {
#ifdef STM32F4
uint32_t lr_register;
uint32_t sp_register;
__ASM volatile ("mov %0, r14" : "=r" (lr_register) );
__ASM volatile ("mov %0, r13" : "=r" (sp_register) );
lr_register = lr_register & 0xFFFFFFFE; // mask out LSB as this only is indicates thumb instruction
diag_fc.Val0 = sp_register; // actual stack pointer
diag_fc.Val1 = lr_register; // report instruction address where this function has been called
diag_fc.Val2 = *(uint32_t*)(sp_register + 0x1C); // return address of callers context (one above caller)
DIAG_Handler(DIAG_CH_CONFIGASSERT,DIAG_EVENT_NOK,0, NULL);
#endif
while (1) {
;
}
}
diag.h (primary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag.h
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE
* @prefix DIAG
*
* @brief Diag driver header
*
*/
#ifndef DIAG_H_
#define DIAG_H_
/*================== Includes =============================================*/
#include "diag_cfg.h"
/*================== Macros and Definitions ===============================*/
//FIXME Why is there no 1 in following enum?
/** diagnosis handler return types */
typedef enum {
DIAG_HANDLER_RETURN_OK = 0, /*!< error not occured or occured but threshold not reached */
DIAG_HANDLER_RETURN_ERR_OCCURED = 2, /*!< error occured and enabled */
DIAG_HANDLER_RETURN_WARNING_OCCURRED = 3, /*!< warning occured (error occured but not enabled) */
DIAG_HANDLER_RETURN_ERR_OCCURRED = 4, /*!< error occured and enabled */
DIAG_HANDLER_RETURN_WRONG_ID = 5, /*!< wrong diagnosis id */
DIAG_HANDLER_RETURN_UNKNOWN = 6, /*!< unknown return type */
DIAG_HANDLER_INVALID_TYPE = 7, /*!< invalid diagnosis type, error in configuration */
DIAG_HANDLER_INVALID_DATA = 8, /*!< invalid data, dependent of the diagHandler */
DIAG_HANDLER_RETURN_NOT_READY = 0xFFFFFFFF, /*!< diagnosis handler not ready */
} DIAG_RETURNTYPE_e;
/**
* state of diagnosis module
*/
typedef enum {
DIAG_STATE_UNINITIALIZED = 0, /*!< diagnosis module not initialized */
DIAG_STATE_INITIALIZED = 1, /*!< diagnosis module initialized (ready for use) */
} DIAG_STATE_e;
/**
* Counters for error and warning thresholds
*/
typedef struct {
uint8_t GENERALerrcnt[32];
uint8_t CELLMONerrcnt[32];
uint8_t COMerrcnt[32];
uint8_t ADCerrcnt[32];
} DIAG_OCCURRENCE_COUNTERS_s;
/**
* structure of failure code entry record
*/
typedef struct {
uint8_t YY;
uint8_t MM;
uint8_t DD;
uint8_t hh;
uint8_t mm;
uint8_t ss;
DIAG_EVENT_e event;
DIAG_CH_ID_e event_id;
uint32_t item;
uint32_t dummy1;
uint32_t Val0;
uint32_t Val1;
uint32_t Val2;
uint32_t Val3;
} DIAG_ERROR_ENTRY_s;
// FIXME maybe short explanation why there is separate Error entry for contactor in a few words
/**
* structure of failure code entry record for contactor
*/
typedef struct {
uint8_t YY;
uint8_t MM;
uint8_t DD;
uint8_t hh;
uint8_t mm;
uint8_t ss;
// DIAG_EVENT_e event;
// DIAG_CH_ID_e event_id;
uint8_t contactor;
float openingCurrent;
} DIAG_CONTACTOR_ERROR_ENTRY_s;
/**
* structure contains number of switching actions for each contactor
*/
typedef struct {
uint16_t cont_switch_closed[BS_NR_OF_CONTACTORS];
uint16_t cont_switch_opened[BS_NR_OF_CONTACTORS];
uint16_t cont_switch_opened_hard_at_current[BS_NR_OF_CONTACTORS];
uint16_t errcntreported; /*!< number of hard switches occurred since last call of DIAG_PrintContactorInfo */
// sizeof(struct) - (memory of contactors) - errcntreported - chksum
uint8_t reserved[0x40 - (3*BS_NR_OF_CONTACTORS*2) - 2 - 4]; /*!< reserved for future use */
} DIAG_CONTACTOR_s;
// FIXME doxygen comment missing
typedef struct {
uint32_t Val0;
uint32_t Val1;
uint32_t Val2;
uint32_t Val3;
} DIAG_FAILURECODE_s;
// FIXME doxygen comment missing, maybe even with explanation of struct member or use ///< comments
typedef struct {
DIAG_STATE_e state; /*!< actual state of diagnosis module */
uint16_t errcnttotal; /*!< total counts of diagnosis entry records*/
uint16_t errcntreported; /*!< reported error counts to external tool*/
uint32_t entry_event[DIAG_ID_MAX]; /*!< last detected entry event*/
uint8_t entry_cnt[DIAG_ID_MAX]; /*!< reported event counter used for limitation */
uint16_t occurrence_cnt[DIAG_ID_MAX]; /*!< */
uint8_t id2ch[DIAG_ID_MAX]; /*!< diagnosis-id to configuration channel selector*/
uint8_t nr_of_ch; /*!< number of configured channels*/
uint32_t errflag[(DIAG_ID_MAX+31)/32]; /*!< detected error flags (bit_nr = diag_id ) */
uint32_t warnflag[(DIAG_ID_MAX+31)/32]; /*!< detected warning flags (bit_nr = diag_id ) */
uint32_t err_enableflag[(DIAG_ID_MAX+31)/32]; /*!< enabled error flags (bit_nr = diag_id ) */
} DIAG_s;
/*================== Constant and Variable Definitions ====================*/
// FIXME doxygen comment missing
extern DIAG_FAILURECODE_s diag_fc;
// FIXME doxygen comment missing
//extern DIAG_s diag;
/*================== Function Prototypes ==================================*/
/**
* @brief DIAG_Handler provides generic error handling, based on diagnosis group.
@ingroup API_DIAG
* This function calls the handler functions depending on the diagnosis group of call.
* It needs to get called in every function which wants to apply some kind of diagnosis handling.
* According to its return value further treatment is either left to the calling module itself, or
* can be done in the callback function defined in diag_cfg.c
*
*
* @param diag_ch_id: event ID of the event that has occurred
* @param event: event that occurred (OK, NOK, RESET)
* @param item_nr: item nr of event, to distinguish between different calling locations of the event
* @param data: pointer to data if DIAG_CONT_TYPE
*
* @return DIAG_HANDLER_RETURN_UNKNOWN if invalid DIAG_TYPE_e, otherwise return value of
* DIAG_GeneralHandler or DIAG_ContHandler
*/
extern DIAG_RETURNTYPE_e DIAG_Handler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr, void* data);
/**
* @brief DIAG_Init initializes all needed structures/buffers.
*
* This function provides initialization of the diagnose module.
* In case of miss behaviour it calls Reset and adds an entry into database
* to ensure data validity/report back malfunction
*
* @param diag_dev_pointer
*/
extern STD_RETURN_TYPE_e DIAG_Init(DIAG_DEV_s *diag_dev_pointer, STD_RETURN_TYPE_e bkpramValid);
/**
* @brief trap of configuration errors derived by FreeRTOS configASSERT
*/
extern void DIAG_configASSERT(void);
/**
* @brief overall system monitoring
*
* checks notifications (state and timestamps) of all system-relevant tasks or functions
* all checks should be customized corresponding to its timing and state requirements
*/
extern void DIAG_SysMon(void);
/**
* @brief DIAG_PrintErrors prints contents of the error buffer on user request.
*
* This function prints out complete error buffer using the UART interface.
*/
extern void DIAG_PrintErrors(void);
/**
* @brief DIAG_PrintContactorInfo prints contents of the contactor switching buffer on user request.
*
* This function prints out complete contactor information using the UART interface.
*/
extern void DIAG_PrintContactorInfo(void);
/**
* @brief DIAG_SysMonNotify has to be called in every function using the system monitoring.
*
* @param module_id: module id to notify system monitoring
* @param state: state of module
*/
extern void DIAG_SysMonNotify(DIAG_SYSMON_MODULE_ID_e module_id, uint32_t state);
/*================== Function Implementations =============================*/
#endif /* DIAG_H_ */
diag.c (secondary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag.c
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE
* @prefix DIAG
*
* @brief Diag driver implementation
*
* This diagnose module is responsible for error handling and reporting.
* Reported errors are logged into the global database and can be reviewed
* on user request.
*/
/*================== Includes =============================================*/
#include "diag.h"
#include "com.h"
#include "misc.h"
#include "os.h"
#include "rtc.h"
/*================== Macros and Definitions ===============================*/
/*================== Constant and Variable Definitions ====================*/
static DIAG_s diag;
static DIAG_DEV_s *diag_devptr;
static uint32_t diagsysmonTimestamp = 0;
static uint8_t diag_locked = 0;
// FIXME unused
// FIXME do you really want to have global variables?
DIAG_CODE_s diag_err;
DIAG_CODE_s diag_warn;
DIAG_OCCURRENCE_COUNTERS_s diag_occurrence_counters;
//uint32_t diag_error;
DIAG_SYSMON_NOTIFICATION_s diag_sysmon[DIAG_SYSMON_MODULE_ID_MAX];
DIAG_SYSMON_NOTIFICATION_s diag_sysmon_last[DIAG_SYSMON_MODULE_ID_MAX];
uint32_t diag_sysmon_cnt[DIAG_SYSMON_MODULE_ID_MAX];
DIAG_ERROR_ENTRY_s MEM_BKP_SRAM diag_memory[DIAG_FAIL_ENTRY_LENGTH];
DIAG_ERROR_ENTRY_s MEM_BKP_SRAM *diag_entry_wrptr;
DIAG_ERROR_ENTRY_s MEM_BKP_SRAM *diag_entry_rdptr;
DIAG_CONTACTOR_ERROR_ENTRY_s MEM_BKP_SRAM diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH];
DIAG_CONTACTOR_ERROR_ENTRY_s MEM_BKP_SRAM *diagContactorError_entry_wrptr;
DIAG_CONTACTOR_ERROR_ENTRY_s MEM_BKP_SRAM *diagContactorError_entry_rdptr;
DIAG_FAILURECODE_s diag_fc;
/*================== Function Prototypes ==================================*/
static void DIAG_Reset(void);
static uint8_t DIAG_EntryWrite(uint8_t eventID, DIAG_EVENT_e event, uint32_t item_nr);
static DIAG_RETURNTYPE_e DIAG_GeneralHandler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr);
/*================== Function Implementations =============================*/
/**
* @brief DIAG_Reset resets/initalizes all needed strcutures/buffers.
*
* This function gets called during initialization of the diagnose module.
* It clears memory and counters used by diag later on.
*/
static void DIAG_Reset(void)
{
uint32_t i;
uint32_t *u32ptr = (uint32_t*)(&diag_memory[0]);
diag_locked = 1;
/* Delete memory */
for(i = 0; i < (sizeof(diag_memory))/4; i++)
*u32ptr++ = 0;
/* Reset counter */
for(i = 0; i < sizeof(diag.entry_cnt); i++)
diag.entry_cnt[i] = 0;
/* Set pointer to beginning of buffer */
diag_entry_wrptr = diag_entry_rdptr = &diag_memory[0];
diag.errcnttotal = 0;
/* Set pointer to beginning of buffer */
u32ptr = (uint32_t*)(&diagContactorErrorMemory[0]);
/* Delete memory */
for(i = 0; i < (sizeof(diagContactorErrorMemory))/4; i++)
*u32ptr++ = 0;
/* Set pointer to beginning of buffer */
diagContactorError_entry_wrptr = diagContactorError_entry_rdptr = &diagContactorErrorMemory[0];
diag_locked=0;
}
STD_RETURN_TYPE_e DIAG_Init(DIAG_DEV_s *diag_dev_pointer, STD_RETURN_TYPE_e bkpramValid) {
STD_RETURN_TYPE_e retval = E_OK;
uint8_t c = 0;
uint8_t id_nr = DIAG_ID_MAX;
uint32_t tmperr_Check[(DIAG_ID_MAX+31)/32];
diag_devptr = diag_dev_pointer;
diag.state = DIAG_STATE_UNINITIALIZED;
uint16_t checkfail = 0;
if( (diag_entry_rdptr<&diag_memory[0]) || (diag_entry_rdptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH]))
checkfail |= 0x01;
if( (diag_entry_wrptr<&diag_memory[0]) || (diag_entry_wrptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH]))
checkfail |= 0x02;
if(bkpramValid == E_NOT_OK)
checkfail |= 0x04;
if( (diagContactorError_entry_rdptr < &diagContactorErrorMemory[0]) ||
(diagContactorError_entry_rdptr >= &diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH]) )
checkfail |= 0x08;
if( (diagContactorError_entry_wrptr < &diagContactorErrorMemory[0]) ||
(diagContactorError_entry_wrptr >= &diagContactorErrorMemory[DIAG_FAIL_ENTRY_CONTACTOR_LENGTH]))
checkfail |= 0x10;
if(checkfail) {
DIAG_Reset();
}
/* Fill lookup table id2ch */
for(c = 0; c < diag_dev_pointer->nr_of_ch; c++) {
id_nr = diag_dev_pointer->ch_cfg[c].id;
if(id_nr < DIAG_ID_MAX) {
diag.id2ch[id_nr] = c; // e.g. diag.id2ch[DIAG_ID_90] = configured channel index
} else {
/* Configuration error -> set retval to E_NOT_OK */
checkfail |= 0x20;
retval = E_NOT_OK;
}
}
for(int i = 0; i < (DIAG_ID_MAX+31)/32; i++)
tmperr_Check[i] = 0;
/* Fill enable array err_enableflag */
for(int i = 0; i < diag_dev_pointer->nr_of_ch; i++) {
if(diag_dev_pointer->ch_cfg[i].state == DIAG_DISABLED) {
/* Disable diagnosis entry */
tmperr_Check[diag_dev_pointer->ch_cfg[i].id/32] |= 1 << (diag_dev_pointer->ch_cfg[i].id % 32);
}
}
/* take over configured error enable masks*/
for(c = 0; c < (DIAG_ID_MAX+31)/32; c++) {
diag.err_enableflag[c] = ~tmperr_Check[c];
}
diag.state = DIAG_STATE_INITIALIZED;
if(checkfail) {
/* make first entry after DIAG_Reset() */
(void)(DIAG_Handler(DIAG_CH_BKPDIAG_FAILURE, DIAG_EVENT_NOK, checkfail, NULL));
}
return retval;
}
void DIAG_PrintErrors(void) {
/* FIXME if read once, rdptr is on writeptr, therefore in the next call the errors aren't
* printed again. Maybe tmp save rdptr and set again at end of function. But when is the
* diag memory cleared then? */
uint8_t buf[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
if(diag_entry_rdptr == diag_entry_wrptr)
{
DEBUG_PRINTF((const uint8_t * )"no new entries in DIAG");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
else
{
DEBUG_PRINTF((const uint8_t * )"DIAG error entries:");
DEBUG_PRINTF((const uint8_t * )"\r\n");
DEBUG_PRINTF((const uint8_t * )"Date and Time: Error Code/Item Status Description");
DEBUG_PRINTF((const uint8_t * )"\r\n");
}
uint8_t c = 0;
while(diag_entry_rdptr != diag_entry_wrptr && c < 7)
{
if( diag_entry_rdptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH]) {
diag_entry_rdptr = &diag_memory[0];
}
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->DD, 2));
DEBUG_PRINTF((const uint8_t * )".");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->MM, 2));
DEBUG_PRINTF((const uint8_t * )".");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->YY, 2));
DEBUG_PRINTF((const uint8_t * )" - ");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->hh, 2));
DEBUG_PRINTF((const uint8_t * )":");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->mm, 2));
DEBUG_PRINTF((const uint8_t * )":");
DEBUG_PRINTF(U8ToDecascii(buf, &diag_entry_rdptr->ss, 2));
DEBUG_PRINTF((const uint8_t * )" ");
DEBUG_PRINTF(U8ToDecascii(buf, (uint8_t*)(&diag_entry_rdptr->event_id), 2));
DEBUG_PRINTF((const uint8_t * )" / 0x");
DEBUG_PRINTF(U32ToHexascii(buf, &diag_entry_rdptr->item));
DEBUG_PRINTF((const uint8_t * )" ");
if(diag_entry_rdptr->event == DIAG_EVENT_OK)
DEBUG_PRINTF((const uint8_t * )"cleared ");
else if(diag_entry_rdptr->event == DIAG_EVENT_NOK)
DEBUG_PRINTF((const uint8_t * )"occurred ");
else
DEBUG_PRINTF((const uint8_t * )"reset ");
for(uint8_t i = 0; i < 24; i++)
buf[i] = diag_devptr->ch_cfg[diag.id2ch[diag_entry_rdptr->event_id]].description[i];
DEBUG_PRINTF((const uint8_t *)buf);
DEBUG_PRINTF((const uint8_t * )"\r\n");
diag_entry_rdptr++;
c++;
}
// More entries in diag buffer
if(diag_entry_rdptr != diag_entry_wrptr)
DEBUG_PRINTF((const uint8_t * )"Please repeat command. Additional error entries in DIAG buffer available!\r\n");
}
/**
* @brief DIAG_EntryWrite adds an error entry.
*
* This function adds an entry to the error buffer.
* It provides some functionality to prevent duplicates from being logged.
* Multiple occurring error doesn't get logged anymore after they reached a
* pre-defined error count.
*
* @param eventID: ID of entry
* @param event: OK, NOK or RESET
* @param item_nr: item number of event
*
* @return 0xFF if event is logged, otherwise 0
*/
static uint8_t DIAG_EntryWrite(uint8_t eventID, DIAG_EVENT_e event, uint32_t item_nr) {
uint8_t ret_val = 0;
uint8_t c;
RTC_Time_s currTime;
RTC_Date_s currDate;
uint8_t buf[25] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // max. description length = 24 + 1 to identify end of array
if(diag_locked)
return ret_val; // only locked when clearing the diagnosis memory
if(diag.entry_event[eventID] == event)
return ret_val; // same event of same error type already recorded before -> ignore until event toggles
if((diag.entry_event[eventID] == DIAG_EVENT_OK) && (event == DIAG_EVENT_RESET))
return ret_val; // do record DIAG_EVENT_RESET-event only if last event was an error (re-initialization)
// meaning: DIAG_EVENT_RESET-event at first time call or after DIAG_EVENT_OK-event will not be recorded
if(++diag.entry_cnt[eventID] > DIAG_MAX_ENTRIES_OF_ERROR){
diag.entry_cnt[eventID] = DIAG_MAX_ENTRIES_OF_ERROR;
return ret_val; // this type of error has been recorded too many times -> ignore to avoid filling buffer with same failurecodes
}
if( diag_entry_wrptr >= &diag_memory[DIAG_FAIL_ENTRY_LENGTH] ) {
diag_entry_wrptr = &diag_memory[0];
}
// now record failurecode
ret_val=0xFF;
RTC_getTime(&currTime);
RTC_getDate(&currDate);
diag_entry_wrptr->YY = currDate.Year;
diag_entry_wrptr->MM = currDate.Month;
diag_entry_wrptr->DD = currDate.Date;
diag_entry_wrptr->hh = currTime.Hours;
diag_entry_wrptr->mm = currTime.Minutes;
diag_entry_wrptr->ss = currTime.Seconds;
diag_entry_wrptr->event_id = eventID; // Error Code 0... 4x32-1
diag_entry_wrptr->item = item_nr; //
diag_entry_wrptr->event = (uint8_t)event; // DIAG_EVENT_OK, DIAG_EVENT_NOK, DIAG_EVENT_RESET
diag_entry_wrptr->Val0 = diag_fc.Val0;
diag_entry_wrptr->Val1 = diag_fc.Val1;
diag_entry_wrptr->Val2 = diag_fc.Val2;
diag_entry_wrptr->Val3 = diag_fc.Val3;
++diag_entry_wrptr;
++diag.errcntreported; // counts of (new) diagnosis entry records which is still not been read by external Tool
// which will reset this value to 0 after having read all new entries which means <acknowledged by user>
++diag.errcnttotal; // total counts of diagnosis entry records
diag.entry_event[eventID] = event;
DEBUG_PRINTF((const uint8_t * )"New Error entry! (");
c = (uint8_t) diag.errcntreported;
DEBUG_PRINTF(U8ToDecascii(buf, &c,3));
DEBUG_PRINTF((const uint8_t * )"): Error Code/Item ");
DEBUG_PRINTF(U8ToDecascii(buf, &eventID, 3));
DEBUG_PRINTF((const uint8_t * )"/0x");
DEBUG_PRINTF(U32ToHexascii(buf, &item_nr));
DEBUG_PRINTF((const uint8_t * )" ");
// Copy error description in buffer, maximum description length = 24 characters
for(uint8_t i = 0; i < 24; i++)
buf[i] = diag_devptr->ch_cfg[diag.id2ch[eventID]].description[i];
DEBUG_PRINTF((const uint8_t *)buf);
if(event==DIAG_EVENT_OK)
DEBUG_PRINTF((const uint8_t * )" cleared");
else if (event==DIAG_EVENT_NOK)
DEBUG_PRINTF((const uint8_t * )" occurred");
else // DIAG_EVENT_RESET
DEBUG_PRINTF((const uint8_t * )" reset");
DEBUG_PRINTF((const uint8_t * )"\r\n");
return ret_val;
}
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr, void* data) {
DIAG_RETURNTYPE_e retVal = DIAG_HANDLER_RETURN_UNKNOWN;
/* Get diagnosis type */
DIAG_TYPE_e diagType = diag_dev.ch_cfg[diag.id2ch[diag_ch_id]].type;
switch(diagType) {
/* Call handler function depending on diagnosis type */
case DIAG_GENERAL_TYPE:
retVal = DIAG_GeneralHandler(diag_ch_id, event, item_nr);
break;
case DIAG_CELLMON_TYPE:
break;
case DIAG_COM_TYPE:
break;
case DIAG_ADC_TYPE:
break;
case DIAG_CONT_TYPE:
break;
default:
break;
}
return retVal;
}
/**
* @brief DIAG_GeneralHandler provides generic error handling, based on configuration.
*
* This function does all the handling based on the user defined configuration.
* According to its return value further treatment is left to the calling module itself.
* @param diag_ch_id: event ID of the event that has occurred
* @param event: event that occurred (OK, NOK, RESET)
* @param item_nr: item nr of event, to distinguish between different calling locations of the event
*
* @return DIAG_STATE_UNINITIALIZED if diag module still uninitialized,\n
* DIAG_HANDLER_RETURN_WRONG_ID if invalid diag id,\n
* DIAG_HANDLER_INVALID_TYPE if diag id doesn't correspond to diag type,\n
* DIAG_HANDLER_RETURN_OK if error/warning occurred but no threshold reached or event = DIAG_EVENT_OK/DIAG_EVENT_RESET,\n
* DIAG_HANDLER_RETURN_ERR_OCCURRED if error threshold reached,\n
* DIAG_HANDLER_RETURN_WARNING_OCCURRED if warning threshold reached,\n
*/
static DIAG_RETURNTYPE_e DIAG_GeneralHandler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr) {
uint32_t ret_val = DIAG_HANDLER_RETURN_UNKNOWN;
uint32_t *u32ptr_errCodemsk, *u32ptr_warnCodemsk;
uint16_t *u16ptr_threshcounter;
uint16_t cfg_threshold;
uint16_t err_enable_idx;
uint32_t err_enable_bitmask;
DIAG_TYPE_RECORDING_e recordingenabled;
if(diag.state == DIAG_STATE_UNINITIALIZED) {
return (DIAG_HANDLER_RETURN_NOT_READY);
}
if(diag_ch_id >= DIAG_ID_MAX) {
return (DIAG_HANDLER_RETURN_WRONG_ID);
}
if((diag_ch_id == DIAG_CH_CONTACTOR_DAMAGED) || (diag_ch_id == DIAG_CH_CONTACTOR_OPENING) ||
(diag_ch_id == DIAG_CH_CONTACTOR_CLOSING)) {
return (DIAG_HANDLER_INVALID_TYPE);
}
err_enable_idx = diag_ch_id/32; // array index of diag.err_enableflag[..]
err_enable_bitmask = 1<<(diag_ch_id%32); // bit number (mask) of diag.err_enableflag[idx]
u32ptr_errCodemsk = &diag.errflag[err_enable_idx];
u32ptr_warnCodemsk = &diag.warnflag[err_enable_idx];
u16ptr_threshcounter = &diag.occurrence_cnt[diag_ch_id];
cfg_threshold = diag_devptr->ch_cfg[diag.id2ch[diag_ch_id]].thresholds;
recordingenabled = diag_devptr->ch_cfg[diag.id2ch[diag_ch_id]].enablerecording;
if(event == DIAG_EVENT_OK)
{
if(diag.err_enableflag[err_enable_idx] & err_enable_bitmask)
{
//if (((*u16ptr_threshcounter) == 0) && (*u32ptr_errCodemsk == 0))
if (((*u16ptr_threshcounter) == 0))
{
; // everything ok, nothing to be handled
}
else if ((*u16ptr_threshcounter) > 1 )
{
(*u16ptr_threshcounter)--; // Error did not occur, decrement Error-Counter
}
//else if ((*u16ptr_threshcounter) <= 1)
else if ((*u16ptr_threshcounter) == 1)
{ // Error did not occur, now decrement to zero and clear Error- or Warning-Flag and make recording if enabled
*u32ptr_errCodemsk &= ~err_enable_bitmask; // ERROR: clear corresponding bit in errflag[idx]
*u32ptr_warnCodemsk &= ~err_enable_bitmask; // WARNING: clear corresponding bit in warnflag[idx]
(*u16ptr_threshcounter) = 0;
//Make entry in error-memory (error disappeared)
if(recordingenabled == DIAG_RECORDING_ENABLED)
DIAG_EntryWrite(diag_ch_id, event, item_nr);
/* Call callback function and reset error */
diag_ch_cfg[diag.id2ch[diag_ch_id]].callbackfunc(diag_ch_id, DIAG_EVENT_RESET);
}
}
ret_val = DIAG_HANDLER_RETURN_OK; // Function does not return an error-message!
}
else if(event == DIAG_EVENT_NOK)
{
if( diag.err_enableflag[err_enable_idx] & err_enable_bitmask )
{
if ((*u16ptr_threshcounter) < cfg_threshold )
{
(*u16ptr_threshcounter)++; // error-threshold not exceeded yet, increment Error-Counter
ret_val = DIAG_HANDLER_RETURN_OK; // Function does not return an error-message!
}
else if ((*u16ptr_threshcounter) == cfg_threshold )
{
// Error occured AND error-threshold exceeded
(*u16ptr_threshcounter)++;
*u32ptr_errCodemsk |= err_enable_bitmask; // ERROR: set corresponding bit in errflag[idx]
*u32ptr_warnCodemsk &= ~err_enable_bitmask; // WARNING: clear corresponding bit in warnflag[idx]
//Make entry in error-memory (error occurred)
if(recordingenabled == DIAG_RECORDING_ENABLED)
DIAG_EntryWrite(diag_ch_id, event, item_nr);
/* Call callback function and set error */
diag_ch_cfg[diag.id2ch[diag_ch_id]].callbackfunc(diag_ch_id, DIAG_EVENT_NOK);
/* Function returns an error-message! */
ret_val = DIAG_HANDLER_RETURN_ERR_OCCURRED;
}
else if (((*u16ptr_threshcounter) > cfg_threshold))
{
; // error-threshold already exceeded, nothing to be handled
}
}
else
{
// Error occured BUT NOT enabled by mask
*u32ptr_errCodemsk &= ~err_enable_bitmask; // ERROR: clear corresponding bit in errflag[idx]
*u32ptr_warnCodemsk |= err_enable_bitmask; // WARNING: set corresponding bit in warnflag[idx]
ret_val = DIAG_HANDLER_RETURN_WARNING_OCCURRED; // Function returns an error-message!
}
}
else if(event == DIAG_EVENT_RESET)
{
if(diag.err_enableflag[err_enable_idx] & err_enable_bitmask)
{ //clear counter, Error-, Warning-Flag and make recording if enabled
*u32ptr_errCodemsk &= ~err_enable_bitmask; // ERROR: clear corresponding bit in errflag[idx]
*u32ptr_warnCodemsk &= ~err_enable_bitmask; // WARNING: clear corresponding bit in warnflag[idx]
(*u16ptr_threshcounter) = 0;
if(recordingenabled==DIAG_RECORDING_ENABLED)
DIAG_EntryWrite(diag_ch_id, event, item_nr); //Make entry in error-memory (error disappeared) if error was recorded before
}
ret_val = DIAG_HANDLER_RETURN_OK; // Function does not return an error-message!
}
return (ret_val);
}
/**
* @brief overall system monitoring
*
* checks notifications (state and timestamps) of all system-relevant tasks or functions
* all checks should be customized corresponding to its timing and state requirements
*/
void DIAG_SysMon(void) {
DIAG_SYSMON_MODULE_ID_e module_id;
uint32_t localTimer = OS_getOSSysTick();
if (diagsysmonTimestamp == localTimer) {
return;
}
diagsysmonTimestamp = localTimer;
/* check modules */
for (module_id = 0; module_id < DIAG_SYSMON_MODULE_ID_MAX; module_id++) {
if ((diag_sysmon_ch_cfg[module_id].type == DIAG_SYSMON_CYCLICTASK) &&
(diag_sysmon_ch_cfg[module_id].state == DIAG_ENABLED)) {
if(diag_sysmon[module_id].timestamp - diag_sysmon_last[module_id].timestamp < 1) {
// module not running
if(++diag_sysmon_cnt[module_id] >= diag_sysmon_ch_cfg[module_id].threshold) {
//@todo configurable timeouts !
if(diag_sysmon_ch_cfg[module_id].enablerecording == DIAG_RECORDING_ENABLED) {
DIAG_Handler(DIAG_CH_SYSTEMMONITORING_TIMEOUT,DIAG_EVENT_NOK,module_id, NULL);
}
if(diag_sysmon_ch_cfg[module_id].handlingtype == DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR) {
// system not working trustfully, switch off contactors!
//BMS_SetStateRequest(BMS_STATE_ERROR_REQUEST);
//CONT_SwitchAllContactorsOff();
}
diag_sysmon_cnt[module_id] = 0;
// @todo: call callback function if error occurred
diag_sysmon_ch_cfg[module_id].callbackfunc(module_id);
}
} else {
// module running
diag_sysmon_cnt[module_id] = 0;
if(diag_sysmon[module_id].state != 0) {
/* check state of module */
// @todo: do something now!
}
}
} else {
// if Sysmon type != cyclic task (not used at the moment)
}
diag_sysmon_last[module_id] = diag_sysmon[module_id]; /*save last values for next check*/
}
}
void DIAG_SysMonNotify(DIAG_SYSMON_MODULE_ID_e module_id, uint32_t state) {
if (module_id < DIAG_SYSMON_MODULE_ID_MAX) {
taskENTER_CRITICAL();
diag_sysmon[module_id].timestamp = OS_getOSSysTick();
diag_sysmon[module_id].state = state;
taskEXIT_CRITICAL();
}
}
void DIAG_configASSERT(void) {
#ifdef STM32F4
uint32_t lr_register;
uint32_t sp_register;
__ASM volatile ("mov %0, r14" : "=r" (lr_register) );
__ASM volatile ("mov %0, r13" : "=r" (sp_register) );
lr_register = lr_register & 0xFFFFFFFE; // mask out LSB as this only is indicates thumb instruction
diag_fc.Val0 = sp_register; // actual stack pointer
diag_fc.Val1 = lr_register; // report instruction address where this function has been called
diag_fc.Val2 = *(uint32_t*)(sp_register + 0x1C); // return address of callers context (one above caller)
DIAG_Handler(DIAG_CH_CONFIGASSERT,DIAG_EVENT_NOK,0, NULL);
#endif
while (1) {
;
}
}
diag.h (secondary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag.h
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE
* @prefix DIAG
*
* @brief Diag driver header
*
*/
#ifndef DIAG_H_
#define DIAG_H_
/*================== Includes =============================================*/
#include "diag_cfg.h"
/*================== Macros and Definitions ===============================*/
//FIXME Why is there no 1 in following enum?
/** diagnosis handler return types */
typedef enum {
DIAG_HANDLER_RETURN_OK = 0, /*!< error not occured or occured but threshold not reached */
DIAG_HANDLER_RETURN_ERR_OCCURED = 2, /*!< error occured and enabled */
DIAG_HANDLER_RETURN_WARNING_OCCURRED = 3, /*!< warning occured (error occured but not enabled) */
DIAG_HANDLER_RETURN_ERR_OCCURRED = 4, /*!< error occured and enabled */
DIAG_HANDLER_RETURN_WRONG_ID = 5, /*!< wrong diagnosis id */
DIAG_HANDLER_RETURN_UNKNOWN = 6, /*!< unknown return type */
DIAG_HANDLER_INVALID_TYPE = 7, /*!< invalid diagnosis type, error in configuration */
DIAG_HANDLER_INVALID_DATA = 8, /*!< invalid data, dependent of the diagHandler */
DIAG_HANDLER_RETURN_NOT_READY = 0xFFFFFFFF, /*!< diagnosis handler not ready */
} DIAG_RETURNTYPE_e;
/**
* state of diagnosis module
*/
typedef enum {
DIAG_STATE_UNINITIALIZED = 0, /*!< diagnosis module not initialized */
DIAG_STATE_INITIALIZED = 1, /*!< diagnosis module initialized (ready for use) */
} DIAG_STATE_e;
/**
* Counters for error and warning thresholds
*/
typedef struct {
uint8_t GENERALerrcnt[32];
uint8_t CELLMONerrcnt[32];
uint8_t COMerrcnt[32];
uint8_t ADCerrcnt[32];
} DIAG_OCCURRENCE_COUNTERS_s;
/**
* structure of failure code entry record
*/
typedef struct {
uint8_t YY;
uint8_t MM;
uint8_t DD;
uint8_t hh;
uint8_t mm;
uint8_t ss;
DIAG_EVENT_e event;
DIAG_CH_ID_e event_id;
uint32_t item;
uint32_t dummy1;
uint32_t Val0;
uint32_t Val1;
uint32_t Val2;
uint32_t Val3;
} DIAG_ERROR_ENTRY_s;
// FIXME maybe short explanation why there is separate Error entry for contactor in a few words
/**
* structure of failure code entry record for contactor
*/
typedef struct {
uint8_t YY;
uint8_t MM;
uint8_t DD;
uint8_t hh;
uint8_t mm;
uint8_t ss;
// DIAG_EVENT_e event;
// DIAG_CH_ID_e event_id;
uint8_t contactor;
float openingCurrent;
} DIAG_CONTACTOR_ERROR_ENTRY_s;
/**
* structure contains number of switching actions for each contactor
*/
typedef struct {
uint16_t cont_switch_closed[BS_NR_OF_CONTACTORS];
uint16_t cont_switch_opened[BS_NR_OF_CONTACTORS];
uint16_t cont_switch_opened_hard_at_current[BS_NR_OF_CONTACTORS];
uint16_t errcntreported; /*!< number of hard switches occurred since last call of DIAG_PrintContactorInfo */
uint16_t reserved[11]; /*!< reserved for future use */
} DIAG_CONTACTOR_s;
// FIXME doxygen comment missing
typedef struct {
uint32_t Val0;
uint32_t Val1;
uint32_t Val2;
uint32_t Val3;
} DIAG_FAILURECODE_s;
// FIXME doxygen comment missing, maybe even with explanation of struct member or use ///< comments
typedef struct {
DIAG_STATE_e state; /*!< actual state of diagnosis module */
uint16_t errcnttotal; /*!< total counts of diagnosis entry records*/
uint16_t errcntreported; /*!< reported error counts to external tool*/
uint32_t entry_event[DIAG_ID_MAX]; /*!< last detected entry event*/
uint8_t entry_cnt[DIAG_ID_MAX]; /*!< reported event counter used for limitation */
uint16_t occurrence_cnt[DIAG_ID_MAX]; /*!< */
uint8_t id2ch[DIAG_ID_MAX]; /*!< diagnosis-id to configuration channel selector*/
uint8_t nr_of_ch; /*!< number of configured channels*/
uint32_t errflag[(DIAG_ID_MAX+31)/32]; /*!< detected error flags (bit_nr = diag_id ) */
uint32_t warnflag[(DIAG_ID_MAX+31)/32]; /*!< detected warning flags (bit_nr = diag_id ) */
uint32_t err_enableflag[(DIAG_ID_MAX+31)/32]; /*!< enabled error flags (bit_nr = diag_id ) */
} DIAG_s;
/*================== Constant and Variable Definitions ====================*/
// FIXME doxygen comment missing
extern DIAG_FAILURECODE_s diag_fc;
// FIXME doxygen comment missing
//extern DIAG_s diag;
/*================== Function Prototypes ==================================*/
/**
* @brief DIAG_Handler provides generic error handling, based on diagnosis group.
@ingroup API_DIAG
* This function calls the handler functions depending on the diagnosis group of call.
* It needs to get called in every function which wants to apply some kind of diagnosis handling.
* According to its return value further treatment is either left to the calling module itself, or
* can be done in the callback function defined in diag_cfg.c
*
*
* @param diag_ch_id: event ID of the event that has occurred
* @param event: event that occurred (OK, NOK, RESET)
* @param item_nr: item nr of event, to distinguish between different calling locations of the event
* @param data: pointer to data if DIAG_CONT_TYPE
*
* @return DIAG_HANDLER_RETURN_UNKNOWN if invalid DIAG_TYPE_e, otherwise return value of
* DIAG_GeneralHandler or DIAG_ContHandler
*/
extern DIAG_RETURNTYPE_e DIAG_Handler(DIAG_CH_ID_e diag_ch_id, DIAG_EVENT_e event, uint32_t item_nr, void* data);
/**
* @brief DIAG_Init initializes all needed structures/buffers.
*
* This function provides initialization of the diagnose module.
* In case of miss behaviour it calls Reset and adds an entry into database
* to ensure data validity/report back malfunction
*
* @param diag_dev_pointer
*/
extern STD_RETURN_TYPE_e DIAG_Init(DIAG_DEV_s *diag_dev_pointer, STD_RETURN_TYPE_e bkpramValid);
/**
* @brief trap of configuration errors derived by FreeRTOS configASSERT
*/
extern void DIAG_configASSERT(void);
/**
* @brief overall system monitoring
*
* checks notifications (state and timestamps) of all system-relevant tasks or functions
* all checks should be customized corresponding to its timing and state requirements
*/
extern void DIAG_SysMon(void);
/**
* @brief DIAG_PrintErrors prints contents of the error buffer on user request.
*
* This function prints out complete error buffer using the UART interface.
*/
extern void DIAG_PrintErrors(void);
/**
* @brief DIAG_SysMonNotify has to be called in every function using the system monitoring.
*
* @param module_id: module id to notify system monitoring
* @param state: state of module
*/
extern void DIAG_SysMonNotify(DIAG_SYSMON_MODULE_ID_e module_id, uint32_t state);
/*================== Function Implementations =============================*/
#endif /* DIAG_H_ */
diag_cfg.c (primary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag_cfg.c
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix DIAG
*
* @brief Diagnostic module configuration
*
* The configuration of the different diagnosis events defined in diag_cfg.h is set in the array
* diag_ch_cfg[], e.g. initialization errors or runtime errors.
*
* Every entry of the diag_ch_cfg[] array consists of
* - name of the diagnosis event (defined in diag_cfg.h)
* - type of diagnosis event
* - diagnosis sensitivity (after how many occurrences event is counted as error)
* - enabling of the recording for diagnosis event
* - enabling of the diagnosis event
* - callback function for diagnosis event if wished, otherwise dummyfu
*
* The system monitoring configuration defined in diag_cfg.h is set in the array
* diag_sysmon_ch_cfg[]. The system monitoring is at the moment only used for
* supervising the cyclic/periodic tasks.
*
* Every entry of the diag_sysmon_ch_cfg[] consists of
* - enum of monitored object
* - type of monitored object (at the moment only DIAG_SYSMON_CYCLICTASK is supported)
* - maximum delay in [ms] in which the object needs to call the DIAG_SysMonNotify function defined in diag.c
* - enabling of the recording for system monitoring
* - enabling of the system monitoring for the monitored object
* - callback function if system monitoring notices an error if wished, otherwise dummyfu2
*/
/*================== Includes =============================================*/
#include "diag_cfg.h"
#include "database.h"
/*================== Macros and Definitions ===============================*/
/*================== Constant and Variable Definitions ====================*/
/**
* Enable and Disable of Error Checks for Testing Purposes
*
* Each Bit enables or disables the diagnosis (checking of) the corresponding failure code
* FIXME struct isn't used anywhere in the code at the moment.
* FIXME delete if not needed
*/
DIAG_CODE_s diag_mask = {
.GENERALmsk=0xFFFFFFFF,
.CELLMONmsk=0xFFFFFFFF,
.COMmsk=0xFFFFFFFF,
.ADCmsk=0xFFFFFFFF,
};
/**
* Callback function of diagnosis error events
*
*/
static void dummyfu(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_RSL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MOL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_cantiming(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_cantiming_cc(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_cancurrentsensor(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_ltcpec(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_ltcmux(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_ltcspi(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactormainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactormainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorchargemainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorchargemainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorchargeprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_interlock(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void dummyfu2(DIAG_SYSMON_MODULE_ID_e ch_id);
void dummyfu(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
;
}
void DIAG_MSL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_voltage = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_RSL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.over_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.over_voltage = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.over_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.over_voltage = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_MSL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.under_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.under_voltage = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_RSL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.under_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.under_voltage = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.under_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.under_voltage = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_MSL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_temperature_charge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_RSL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.over_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.over_temperature_charge = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.over_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.over_temperature_charge = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_MSL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_temperature_discharge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_RSL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.over_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.over_temperature_discharge = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.over_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.over_temperature_discharge = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_MSL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.under_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.under_temperature_charge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_RSL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.under_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.under_temperature_charge = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.under_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.under_temperature_charge = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_MSL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.under_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.under_temperature_discharge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_RSL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.under_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.under_temperature_discharge = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.under_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.under_temperature_discharge = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_MSL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_current_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_current_charge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_RSL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.over_current_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.over_current_charge = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.over_current_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.over_current_charge = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_MSL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_current_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_current_discharge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_RSL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_RSL_FLAG_s rsl_flags;
DB_ReadBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
if (event == DIAG_EVENT_RESET) {
rsl_flags.over_current_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
rsl_flags.over_current_discharge = 1;
}
DB_WriteBlock(&rsl_flags, DATA_BLOCK_ID_RSL);
}
void DIAG_MOL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MOL_FLAG_s mol_flags;
DB_ReadBlock(&mol_flags, DATA_BLOCK_ID_MOL);
if (event == DIAG_EVENT_RESET) {
mol_flags.over_current_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
mol_flags.over_current_discharge = 1;
}
DB_WriteBlock(&mol_flags, DATA_BLOCK_ID_MOL);
}
void DIAG_error_cantiming(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.can_timing = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.can_timing = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_cantiming_cc(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.can_timing_cc = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.can_timing_cc = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_cancurrentsensor(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.currentsensorresponding = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.currentsensorresponding = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_ltcpec(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.crc_error = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.crc_error = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_ltcmux(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.mux_error = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.mux_error = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_ltcspi(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.spi_error = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.spi_error = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactormainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.main_plus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.main_plus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactormainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.main_minus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.main_minus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.precharge = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.precharge = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorchargemainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.charge_main_plus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.charge_main_plus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorchargemainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.charge_main_minus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.charge_main_minus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorchargeprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.charge_precharge = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.charge_precharge = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_interlock(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.interlock = 0;
}
if (event==DIAG_EVENT_NOK) {
error_flags.interlock = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
/**
* Callback function of system monitoring error events
*
*/
void dummyfu2(DIAG_SYSMON_MODULE_ID_e ch_id) {
;
}
DIAG_CH_CFG_s diag_ch_cfg[] = {
/* OS-Framework and startup events */
{DIAG_CH_FLASHCHECKSUM, "FLASHCHECKSUM", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_BKPDIAG_FAILURE, "BKPDIAG", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_WATCHDOGRESET_FAILURE, "WATCHDOGRESET", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_POSTOSINIT_FAILURE, "POSTOSINIT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CALIB_EEPR_FAILURE, "CALIB_EEPR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CAN_INIT_FAILURE, "CAN_INIT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_VIC_INIT_FAILURE, "VIC_INIT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* HW-/SW-Runtime events */
{DIAG_CH_DIV_BY_ZERO_FAILURE, "DIV_BY_ZERO", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_UNDEF_INSTRUCTION_FAILURE, "UNDEF_INSTRUCTION", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_DATA_BUS_FAILURE, "DATA_BUS_FAILURE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_INSTRUCTION_BUS_FAILURE, "INSTRUCTION_BUS", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_HARDFAULT_NOTHANDLED, "HARDFAULT_NOTHANDLED", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CONFIGASSERT, "CONFIGASSERT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SYSTEMMONITORING_TIMEOUT, "SYSTEMMONITORING_TIMEOUT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* Measurement events */
{DIAG_CH_CANS_MAX_VALUE_VIOLATE, "CANS_MAX_VALUE_VIOLATE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CANS_MIN_VALUE_VIOLATE, "CANS_MIN_VALUE_VIOLATE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CANS_CAN_MOD_FAILURE, "CANS_CAN_MOD_FAILURE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_TIM_ERROR, "ISOMETER_TIM_ERROR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_MID, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_GROUNDERROR, "ISOMETER_GROUNDERROR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_ERROR, "ISOMETER_ERROR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_MID, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_MEAS_INVALID, "ISOMETER_MEAS_INVALID", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* Under and over temperature, voltage and current at cell level */
{DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_MSL, "CELLVOLT_OVERVOLT_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overvoltage},
{DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_RSL, "CELLVOLT_OVERVOLT_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_RSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_overvoltage},
{DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_MOL, "CELLVOLT_OVERVOLT_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_MOL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_overvoltage},
{DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_MSL, "CELLVOLT_UNDERVOLT_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_undervoltage},
{DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_RSL, "CELLVOLT_UNDERVOLT_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_RSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_undervoltage},
{DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_MOL, "CELLVOLT_UNDERVOLT_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_MOL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_undervoltage},
{DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_MSL, "OVERTEMP_CHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overtemperaturecharge},
{DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_RSL, "OVERTEMP_CHARGE_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_RSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_overtemperaturecharge},
{DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_MOL, "OVERTEMP_CHARGE_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MOL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_overtemperaturecharge},
{DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_MSL, "OVERTEMP_DISCHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overtemperaturedischarge},
{DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_RSL, "OVERTEMP_DISCHARGE_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_overtemperaturedischarge},
{DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_MOL, "OVERTEMP_DISCHARGE_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_overtemperaturedischarge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_MSL, "UNDERTEMP_CHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_undertemperaturecharge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_RSL, "UNDERTEMP_CHARGE_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_undertemperaturecharge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_MOL, "UNDERTEMP_CHARGE_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_undertemperaturecharge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_MSL, "UNDERTEMP_DISCHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_undertemperaturedischarge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_RSL, "UNDERTEMP_DISCHARGE_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_undertemperaturedischarge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_MOL, "UNDERTEMP_DISCHARGE_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_undertemperaturedischarge},
{DIAG_CH_OVERCURRENT_CHARGE_MSL, "OVERCUR_CHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overcurrentcharge},
{DIAG_CH_OVERCURRENT_CHARGE_RSL, "OVERCUR_CHARGE_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_overcurrentcharge},
{DIAG_CH_OVERCURRENT_CHARGE_MOL, "OVERCUR_CHARGE_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_overcurrentcharge},
{DIAG_CH_OVERCURRENT_DISCHARGE_MSL, "OVERCUR_DISCHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overcurrentdischarge},
{DIAG_CH_OVERCURRENT_DISCHARGE_RSL, "OVERCUR_DISCHARGE_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_RSL_overcurrentdischarge},
{DIAG_CH_OVERCURRENT_DISCHARGE_MOL, "OVERCUR_DISCHARGE_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MOL_overcurrentdischarge},
{DIAG_CH_LTC_SPI, "LTC_SPI", DIAG_GENERAL_TYPE, DIAG_ERROR_LTC_SPI_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_ltcspi},
{DIAG_CH_LTC_PEC, "LTC_PEC", DIAG_GENERAL_TYPE, DIAG_ERROR_LTC_PEC_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_ltcpec},
{DIAG_CH_LTC_MUX, "LTC_MUX", DIAG_GENERAL_TYPE, DIAG_ERROR_LTC_MUX_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_ltcmux},
/* Communication events */
{DIAG_CH_CAN_TIMING, "CAN_TIMING", DIAG_GENERAL_TYPE, DIAG_ERROR_CAN_TIMING_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_CAN_TIMING, DIAG_error_cantiming},
{DIAG_CH_CAN_CC_RESPONDING, "CAN_CC_RESPONDING", DIAG_GENERAL_TYPE, DIAG_ERROR_CAN_TIMING_CC_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_CAN_SENSOR_PRESENT, DIAG_error_cantiming_cc},
{DIAG_CH_CURRENT_SENSOR_RESPONDING, "CURRENT_SENSOR_RESPONDING", DIAG_GENERAL_TYPE, DIAG_ERROR_CAN_SENSOR_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_CAN_SENSOR_PRESENT, DIAG_error_cancurrentsensor},
/* Contactor Damage Error */
{DIAG_CH_CONTACTOR_DAMAGED, "CONTACTOR_DAMAGED", DIAG_CONT_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CONTACTOR_OPENING, "CONTACTOR_OPENING", DIAG_CONT_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CONTACTOR_CLOSING, "CONTACTOR_CLOSING", DIAG_CONT_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* Contactor Feedback Error */
{DIAG_CH_CONTACTOR_MAIN_PLUS_FEEDBACK, "CONT_MAIN_PLUS_FEED", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_PLUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactormainplus},
{DIAG_CH_CONTACTOR_MAIN_MINUS_FEEDBACK, "CONT_MAIN_MINUS_FEED", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_MINUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactormainminus},
{DIAG_CH_CONTACTOR_PRECHARGE_FEEDBACK, "CONT_PRECHARGE_FEED", DIAG_GENERAL_TYPE, DIAG_ERROR_PRECHARGE_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorprecharge},
{DIAG_CH_CONTACTOR_CHARGE_MAIN_PLUS_FEEDBACK, "CONT_CHRGE_MAIN_PLUS_FEED", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_PLUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorchargemainplus},
{DIAG_CH_CONTACTOR_CHARGE_MAIN_MINUS_FEEDBACK, "CONT_CHRGE_MAIN_MINUS_FEED", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_MINUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorchargemainminus},
{DIAG_CH_CONTACTOR_CHARGE_PRECHARGE_FEEDBACK, "CONT_CHRGE_PRECHARGE_FEED", DIAG_GENERAL_TYPE, DIAG_ERROR_PRECHARGE_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorchargeprecharge},
/* Interlock Feedback Error */
{DIAG_CH_INTERLOCK_FEEDBACK, "INTERLOCK_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_INTERLOCK_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_interlock},
/* Slave PCB temperature errors for under and over temperature */
{DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_MSL, "SLAVE_PCB_UNDERTEMP_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_RSL, "SLAVE_PCB_UNDERTEMP_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_RSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_MOL, "SLAVE_PCB_UNDERTEMP_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MOL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_MSL, "SLAVE_PCB_OVERTEMP_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_RSL, "SLAVE_PCB_OVERTEMP_RSL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_RSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_MOL, "SLAVE_PCB_OVERTEMP_MOL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MOL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
};
DIAG_SYSMON_CH_CFG_s diag_sysmon_ch_cfg[] = {
{DIAG_SYSMON_DATABASE_ID, DIAG_SYSMON_CYCLICTASK, 10, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_SYS_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_BMS_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_CONT_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_ILCK_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_LTC_ID, DIAG_SYSMON_CYCLICTASK, 5, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_ISOGUARD_ID, DIAG_SYSMON_CYCLICTASK, 400, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_CANS_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_APPL_CYCLIC_1ms, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_APPL_CYCLIC_10ms, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_APPL_CYCLIC_100ms, DIAG_SYSMON_CYCLICTASK, 200, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
};
DIAG_DEV_s diag_dev = {
.nr_of_ch = sizeof(diag_ch_cfg)/sizeof(DIAG_CH_CFG_s),
.ch_cfg = &diag_ch_cfg[0],
};
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
diag_cfg.h (primary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag_cfg.h
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix DIAG
*
* @brief Diagnostic module configuration header
*
* In this header filer are the different diagnosis channel
* defines assigned to different diagnosis IDs.
*
* Furthermore are the diagnosis error log settings be configured here..
*/
#ifndef DIAG_CFG_H_
#define DIAG_CFG_H_
/*================== Includes =============================================*/
#include "general.h"
#include "batterysystem_cfg.h"
#include "diag_id_cfg.h"
/*================== Macros and Definitions ===============================*/
#define DIAG_ERROR_SENSITIVITY_HIGH (0) // logging at first event
#define DIAG_ERROR_SENSITIVITY_MID (5) // logging at fifth event
#define DIAG_ERROR_SENSITIVITY_LOW (10) // logging at tenth event
#define DIAG_ERROR_VOLTAGE_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if over/under voltage event */
#define DIAG_ERROR_VOLTAGE_SENSITIVITY_RSL (500) /*!< RSL level for event occurrence if over/under voltage event */
#define DIAG_ERROR_VOLTAGE_SENSITIVITY_MOL (500) /*!< MOL level for event occurrence if over/under voltage event */
#define DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if over/under temperature event */
#define DIAG_ERROR_TEMPERATURE_SENSITIVITY_RSL (500) /*!< RSL level for event occurrence if over/under temperature event */
#define DIAG_ERROR_TEMPERATURE_SENSITIVITY_MOL (500) /*!< MOL level for event occurrence if over/under temperature event */
#define DIAG_ERROR_CURRENT_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if over/under current event */
#define DIAG_ERROR_CURRENT_SENSITIVITY_RSL (500) /*!< RSL level for event occurrence if over/under current event */
#define DIAG_ERROR_CURRENT_SENSITIVITY_MOL (500) /*!< MOL level for event occurrence if over/under current event */
#define DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if slave PCB temperature event */
#define DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_RSL (500) /*!< RSL level for event occurrence if slave PCB temperature event */
#define DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MOL (500) /*!< MOL level for event occurrence if slave PCB temperature event */
#define DIAG_ERROR_LTC_PEC_SENSITIVITY (5)
#define DIAG_ERROR_LTC_MUX_SENSITIVITY (5)
#define DIAG_ERROR_LTC_SPI_SENSITIVITY (5)
#define DIAG_ERROR_CAN_TIMING_SENSITIVITY (100)
#define DIAG_ERROR_CAN_TIMING_CC_SENSITIVITY (100)
#define DIAG_ERROR_CAN_SENSOR_SENSITIVITY (100)
#define DIAG_ERROR_MAIN_PLUS_SENSITIVITY (500)
#define DIAG_ERROR_MAIN_MINUS_SENSITIVITY (500)
#define DIAG_ERROR_PRECHARGE_SENSITIVITY (500)
#define DIAG_ERROR_INTERLOCK_SENSITIVITY (10)
/**
* Number of errors that can be logged
*/
#define DIAG_FAIL_ENTRY_LENGTH (50)
/**
* Maximum number of the same error that are logged
*/
#define DIAG_MAX_ENTRIES_OF_ERROR (5)
/**
* Number of contactor errors that are logged
*/
#define DIAG_FAIL_ENTRY_CONTACTOR_LENGTH (50)
// FIXME simple doxygen comment for each define?
/* Initialization and startup events: 0-15 */
#define DIAG_CH_FLASHCHECKSUM DIAG_ID_5 //
#define DIAG_CH_BKPDIAG_FAILURE DIAG_ID_6 //
#define DIAG_CH_WATCHDOGRESET_FAILURE DIAG_ID_7 //
#define DIAG_CH_POSTOSINIT_FAILURE DIAG_ID_8 //
#define DIAG_CH_CALIB_EEPR_FAILURE DIAG_ID_9 //
#define DIAG_CH_CAN_INIT_FAILURE DIAG_ID_10 //
#define DIAG_CH_VIC_INIT_FAILURE DIAG_ID_11
/* HW-/SW-Runtime events: 16-31 */
#define DIAG_CH_DIV_BY_ZERO_FAILURE DIAG_ID_16 //
#define DIAG_CH_UNDEF_INSTRUCTION_FAILURE DIAG_ID_17 //
#define DIAG_CH_DATA_BUS_FAILURE DIAG_ID_18 //
#define DIAG_CH_INSTRUCTION_BUS_FAILURE DIAG_ID_19 //
#define DIAG_CH_HARDFAULT_NOTHANDLED DIAG_ID_20 //
#define DIAG_CH_RUNTIME_ERROR_RESERVED_1 DIAG_ID_21 // reserved for future needs
#define DIAG_CH_RUNTIME_ERROR_RESERVED_2 DIAG_ID_22 // reserved for future needs
#define DIAG_CH_RUNTIME_ERROR_RESERVED_3 DIAG_ID_23 // reserved for future needs
#define DIAG_CH_CONFIGASSERT DIAG_ID_24 //
#define DIAG_CH_SYSTEMMONITORING_TIMEOUT DIAG_ID_25 //
/* Measurement events: 32-47 */
#define DIAG_CH_CANS_MAX_VALUE_VIOLATE DIAG_ID_32
#define DIAG_CH_CANS_MIN_VALUE_VIOLATE DIAG_ID_33
#define DIAG_CH_CANS_CAN_MOD_FAILURE DIAG_ID_34
/**
* Measured frequency too low or no new value captured during last cycle
*/
#define DIAG_CH_ISOMETER_TIM_ERROR DIAG_ID_35
/**
* Ground error detected
*/
#define DIAG_CH_ISOMETER_GROUNDERROR DIAG_ID_36
/**
* Device error, invalid measurement result
*/
#define DIAG_CH_ISOMETER_ERROR DIAG_ID_37
/**
* Measurement trustworthy or not, hysteresis to ground error flag
*/
#define DIAG_CH_ISOMETER_MEAS_INVALID DIAG_ID_38
/**
* Cell voltage limits violated
*/
#define DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_MSL DIAG_ID_39
#define DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_RSL DIAG_ID_40
#define DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_MOL DIAG_ID_41
#define DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_MSL DIAG_ID_42
#define DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_RSL DIAG_ID_43
#define DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_MOL DIAG_ID_44
/**
* Temperature limits violated
*/
#define DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_MSL DIAG_ID_45
#define DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_RSL DIAG_ID_46
#define DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_MOL DIAG_ID_47
#define DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_MSL DIAG_ID_48
#define DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_RSL DIAG_ID_49
#define DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_MOL DIAG_ID_50
#define DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_MSL DIAG_ID_51
#define DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_RSL DIAG_ID_52
#define DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_MOL DIAG_ID_53
#define DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_MSL DIAG_ID_54
#define DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_RSL DIAG_ID_55
#define DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_MOL DIAG_ID_56
/**
* Overcurrent
*/
#define DIAG_CH_OVERCURRENT_CHARGE_MSL DIAG_ID_57
#define DIAG_CH_OVERCURRENT_CHARGE_RSL DIAG_ID_58
#define DIAG_CH_OVERCURRENT_CHARGE_MOL DIAG_ID_59
#define DIAG_CH_OVERCURRENT_DISCHARGE_MSL DIAG_ID_60
#define DIAG_CH_OVERCURRENT_DISCHARGE_RSL DIAG_ID_61
#define DIAG_CH_OVERCURRENT_DISCHARGE_MOL DIAG_ID_62
/**
* LTC
*/
#define DIAG_CH_LTC_SPI DIAG_ID_63
#define DIAG_CH_LTC_PEC DIAG_ID_64
#define DIAG_CH_LTC_MUX DIAG_ID_65
/* Communication events: 50-63*/
/**
* CAN timing not coming
*/
#define DIAG_CH_CAN_TIMING DIAG_ID_66
/**
* CAN C-C not coming
*/
#define DIAG_CH_CAN_CC_RESPONDING DIAG_ID_67
/**
* Current sensor not responding anymore
*/
#define DIAG_CH_CURRENT_SENSOR_RESPONDING DIAG_ID_68
/* Contactor events: 64-79*/
/**
* @brief Opening contactor at over current
*/
#define DIAG_CH_CONTACTOR_DAMAGED DIAG_ID_69
/**
* @brief counter for contactor opening
*/
#define DIAG_CH_CONTACTOR_OPENING DIAG_ID_70
/**
* @brief counter for contactor closing
*/
#define DIAG_CH_CONTACTOR_CLOSING DIAG_ID_71
/**
* @brief Contactor feedback error
*/
#define DIAG_CH_CONTACTOR_MAIN_PLUS_FEEDBACK DIAG_ID_72
#define DIAG_CH_CONTACTOR_MAIN_MINUS_FEEDBACK DIAG_ID_73
#define DIAG_CH_CONTACTOR_PRECHARGE_FEEDBACK DIAG_ID_74
#define DIAG_CH_CONTACTOR_CHARGE_MAIN_PLUS_FEEDBACK DIAG_ID_75
#define DIAG_CH_CONTACTOR_CHARGE_MAIN_MINUS_FEEDBACK DIAG_ID_76
#define DIAG_CH_CONTACTOR_CHARGE_PRECHARGE_FEEDBACK DIAG_ID_77
/**
* @brief Interlock feedback error
*/
#define DIAG_CH_INTERLOCK_FEEDBACK DIAG_ID_78
#define DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_MSL DIAG_ID_79
#define DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_RSL DIAG_ID_80
#define DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_MOL DIAG_ID_81
#define DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_MSL DIAG_ID_82
#define DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_RSL DIAG_ID_83
#define DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_MOL DIAG_ID_84
/**
* enable state of diagnosis entry
*/
typedef enum {
DIAG_ENABLED = 0,
DIAG_DISABLED = 1,
} DIAG_ENABLE_STATE_e;
#if CHECK_CAN_TIMING == TRUE
#define DIAG_CAN_TIMING DIAG_ENABLED
#else
#define DIAG_CAN_TIMING DIAG_DISABLED
#endif
#if CURRENT_SENSOR_PRESENT == TRUE
#define DIAG_CAN_SENSOR_PRESENT DIAG_ENABLED
#else
#define DIAG_CAN_SENSOR_PRESENT DIAG_DISABLED
#endif
// FIXME is it better to name it DIAG_GROUP_xxx instead of DIAG_xxx_TYPE and
/**
* diagnosis groups
* failure codes FC
*/
typedef enum {
DIAG_GENERAL_TYPE = 0x00, /*!< FC 0x00 - 0x1F */
DIAG_CELLMON_TYPE = 0x01, /*!< FC 0x20 - 0x3F */
DIAG_COM_TYPE = 0x02, /*!< FC 0x40 - 0x5F */
DIAG_ADC_TYPE = 0x04, /*!< FC 0x60 - 0x7F */
// FIXME which failure codes for following group?
DIAG_CONT_TYPE = 0x08 /*!< FC */
} DIAG_TYPE_e;
/**
* diagnosis recording activation
*/
typedef enum {
DIAG_RECORDING_ENABLED = 0x00, /*!< enable diagnosis event recording */
DIAG_RECORDING_DISABLED = 0x01, /*!< disable diagnosis event recording */
} DIAG_TYPE_RECORDING_e;
// FIXME duplicate comment with enum DIAG_TYPE_e
// FIXME some enums are typedefed with DIAG...TYPE_e, some with DIAG_TYPE..._e! Reconsider this
/**
* diagnosis types for system monitoring
*/
typedef enum {
DIAG_SYSMON_CYCLICTASK = 0x00, /*!< */
DIAG_SYSMON_RESERVED = 0x01 /*!< */
} DIAG_SYSMON_TYPE_e;
/**
* diagnosis handling type for system monitoring
*/
typedef enum {
DIAG_SYSMON_HANDLING_DONOTHING = 0x00, /*!< */
DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR = 0x01 /*!< */
} DIAG_SYSMON_HANDLING_TYPE_e;
/**
* @brief symbolic names for diagnosis
*/
typedef enum {
DIAG_OK = 0, /*!< diagnosis event ok */
DIAG_NOT_OK = 1, /*!< diagnosis event not ok */
DIAG_BUSY = 2 /*!< diagnosis event busy */
} Diag_ReturnType;
/**
* @brief listing of system-relevant tasks or functions which are checked by system monitoring
*
* diag_sysmon_ch_cfg[]=
*/
typedef enum {
DIAG_SYSMON_DATABASE_ID = 0, /*!< diag entry for database */
DIAG_SYSMON_SYS_ID = 1, /*!< diag entry for sys */
DIAG_SYSMON_BMS_ID = 2, /*!< diag entry for bms */
DIAG_SYSMON_CONT_ID = 3, /*!< diag entry for contactors */
DIAG_SYSMON_ILCK_ID = 4, /*!< diag entry for contactors */
DIAG_SYSMON_LTC_ID = 5, /*!< diag entry for ltc */
DIAG_SYSMON_ISOGUARD_ID = 6, /*!< diag entry for ioguard */
DIAG_SYSMON_CANS_ID = 7, /*!< diag entry for can */
DIAG_SYSMON_APPL_CYCLIC_1ms = 8, /*!< diag entry for application 10ms task */
DIAG_SYSMON_APPL_CYCLIC_10ms = 9, /*!< diag entry for application 10ms task */
DIAG_SYSMON_APPL_CYCLIC_100ms = 10, /*!< diag entry for application 100ms task */
DIAG_SYSMON_MODULE_ID_MAX = 11 /*!< end marker do not delete */
} DIAG_SYSMON_MODULE_ID_e;
// FIXME doxygen comment
// FIXME is DIAG_CODE_s an appropriate name for this?
typedef struct {
uint32_t GENERALmsk;
uint32_t CELLMONmsk;
uint32_t COMmsk;
uint32_t ADCmsk;
} DIAG_CODE_s;
/**
* Channel configuration of one diag channel
*/
typedef struct {
DIAG_CH_ID_e id; /*!< diagnosis event id diag_id */
uint8_t description[40];
DIAG_TYPE_e type; /*!< diagnosis group of diag event */
uint16_t thresholds; /*!< threshold for number of events which will be tolerated before generating a notification in both direction (OK or NOT OK)
* threshold=0: reports the value at first occurence, threshold=1:reports the value at second occurence*/
DIAG_TYPE_RECORDING_e enablerecording; /*!< if enabled recording in diag_memory will be activated */
DIAG_ENABLE_STATE_e state; /*!< if enabled diagnosis event will be evaluated */
void (*callbackfunc)(DIAG_CH_ID_e, DIAG_EVENT_e); /*!< will be called if number of events exceeds threshold (in both direction) with parameter DIAG_EVENT_e */
} DIAG_CH_CFG_s;
/**
* struct for device Configuration of diag module
*/
typedef struct {
uint8_t nr_of_ch; /*!< number of entries in DIAG_CH_CFG_s */
DIAG_CH_CFG_s *ch_cfg; /*!< pointer to diag channel config struct */
} DIAG_DEV_s;
/**
* state (in summary) used for task or function notification
*/
typedef struct {
uint32_t state; /*!< state */
uint32_t timestamp; /*!< timestamp of state */
} DIAG_SYSMON_NOTIFICATION_s;
/**
* Channel configuration of one system monitoring channel
*/
typedef struct {
DIAG_SYSMON_MODULE_ID_e id; /*!< the diag type by its symbolic name */
DIAG_SYSMON_TYPE_e type; /*!< system monitoring types: cyclic or special */
uint16_t threshold; /*!< max. delay time in ms */
DIAG_TYPE_RECORDING_e enablerecording; /*!< enabled if set to DIAG_RECORDING_ENABLED */
DIAG_SYSMON_HANDLING_TYPE_e handlingtype; /*!< type of handling of system monitoring errors */
DIAG_ENABLE_STATE_e state; /*!< enable or disable system monitoring */
void (*callbackfunc)(DIAG_SYSMON_MODULE_ID_e); /*!< */
} DIAG_SYSMON_CH_CFG_s;
/*================== Constant and Variable Definitions ====================*/
/**
* diag device configuration struct
*/
extern DIAG_DEV_s diag_dev;
/**
* diag system monitoring struct
*/
extern DIAG_SYSMON_CH_CFG_s diag_sysmon_ch_cfg[];
extern DIAG_CH_CFG_s diag_ch_cfg[];
// FIXME why is it in header at all? and why is it in code at all? not used
extern DIAG_CODE_s diag_mask;
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
#endif /* DIAG_CFG_H_ */
diag_id_cfg.h (primary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag_id_cfg.h
* @author foxBMS Team
* @date 13.11.2015 (date of creation)
* @ingroup ENGINE
* @prefix DIAG
*
* @brief This file contains basic definitions in order to use an abstracted diagnosis
*/
#ifndef DIAG_ID_CFG_H_
#define DIAG_ID_CFG_H_
/*================== Includes =============================================*/
/*================== Macros and Definitions ===============================*/
/**
* diagnosis check result (event)
*/
typedef enum {
DIAG_EVENT_OK = 0x00, /*!< diag channel event OK */
DIAG_EVENT_NOK = 0x01, /*!< diag channel event NOK */
DIAG_EVENT_RESET = 0x02, /*!< reset diag channel eventcounter to 0 */
} DIAG_EVENT_e;
/**
* symbolic IDs for possible diagnosis entries
*/
typedef enum {
DIAG_ID_0 = 0,
DIAG_ID_1 = 1,
DIAG_ID_2 = 2,
DIAG_ID_3 = 3,
DIAG_ID_4 = 4,
DIAG_ID_5 = 5,
DIAG_ID_6 = 6,
DIAG_ID_7 = 7,
DIAG_ID_8 = 8,
DIAG_ID_9 = 9,
DIAG_ID_10 = 10,
DIAG_ID_11 = 11,
DIAG_ID_12 = 12,
DIAG_ID_13 = 13,
DIAG_ID_14 = 14,
DIAG_ID_15 = 15,
DIAG_ID_16 = 16,
DIAG_ID_17 = 17,
DIAG_ID_18 = 18,
DIAG_ID_19 = 19,
DIAG_ID_20 = 20,
DIAG_ID_21 = 21,
DIAG_ID_22 = 22,
DIAG_ID_23 = 23,
DIAG_ID_24 = 24,
DIAG_ID_25 = 25,
DIAG_ID_26 = 26,
DIAG_ID_27 = 27,
DIAG_ID_28 = 28,
DIAG_ID_29 = 29,
DIAG_ID_30 = 30,
DIAG_ID_31 = 31,
DIAG_ID_32 = 32,
DIAG_ID_33 = 33,
DIAG_ID_34 = 34,
DIAG_ID_35 = 35,
DIAG_ID_36 = 36,
DIAG_ID_37 = 37,
DIAG_ID_38 = 38,
DIAG_ID_39 = 39,
DIAG_ID_40 = 40,
DIAG_ID_41 = 41,
DIAG_ID_42 = 42,
DIAG_ID_43 = 43,
DIAG_ID_44 = 44,
DIAG_ID_45 = 45,
DIAG_ID_46 = 46,
DIAG_ID_47 = 47,
DIAG_ID_48 = 48,
DIAG_ID_49 = 49,
DIAG_ID_50 = 50,
DIAG_ID_51 = 51,
DIAG_ID_52 = 52,
DIAG_ID_53 = 53,
DIAG_ID_54 = 54,
DIAG_ID_55 = 55,
DIAG_ID_56 = 56,
DIAG_ID_57 = 57,
DIAG_ID_58 = 58,
DIAG_ID_59 = 59,
DIAG_ID_60 = 60,
DIAG_ID_61 = 61,
DIAG_ID_62 = 62,
DIAG_ID_63 = 63,
DIAG_ID_64 = 64,
DIAG_ID_65 = 65,
DIAG_ID_66 = 66,
DIAG_ID_67 = 67,
DIAG_ID_68 = 68,
DIAG_ID_69 = 69,
DIAG_ID_70 = 70,
DIAG_ID_71 = 71,
DIAG_ID_72 = 72,
DIAG_ID_73 = 73,
DIAG_ID_74 = 74,
DIAG_ID_75 = 75,
DIAG_ID_76 = 76,
DIAG_ID_77 = 77,
DIAG_ID_78 = 78,
DIAG_ID_79 = 79,
DIAG_ID_80 = 80,
DIAG_ID_81 = 81,
DIAG_ID_82 = 82,
DIAG_ID_83 = 83,
DIAG_ID_84 = 84,
DIAG_ID_85 = 85,
DIAG_ID_86 = 86,
DIAG_ID_87 = 87,
DIAG_ID_88 = 88,
DIAG_ID_89 = 89,
DIAG_ID_90 = 90,
DIAG_ID_91 = 91,
DIAG_ID_92 = 92,
DIAG_ID_93 = 93,
DIAG_ID_94 = 94,
DIAG_ID_95 = 95,
DIAG_ID_96 = 96,
DIAG_ID_97 = 97,
DIAG_ID_98 = 98,
DIAG_ID_99 = 99,
DIAG_ID_100 = 100,
DIAG_ID_101 = 101,
DIAG_ID_102 = 102,
DIAG_ID_103 = 103,
DIAG_ID_104 = 104,
DIAG_ID_105 = 105,
DIAG_ID_106 = 106,
DIAG_ID_107 = 107,
DIAG_ID_108 = 108,
DIAG_ID_109 = 109,
DIAG_ID_110 = 110,
DIAG_ID_111 = 111,
DIAG_ID_MAX = 112,
} DIAG_CH_ID_e;
/*================== Constant and Variable Definitions ====================*/
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
#endif /* DIAG_ID_CFG_H_ */
diag_cfg.c (secondary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag_cfg.c
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix DIAG
*
* @brief Diagnostic module configuration
*
* The configuration of the different diagnosis events defined in diag_cfg.h is set in the array
* diag_ch_cfg[], e.g. initialization errors or runtime errors.
*
* Every entry of the diag_ch_cfg[] array consists of
* - name of the diagnosis event (defined in diag_cfg.h)
* - type of diagnosis event
* - diagnosis sensitivity (after how many occurrences event is counted as error)
* - enabling of the recording for diagnosis event
* - enabling of the diagnosis event
* - callback function for diagnosis event if wished, otherwise dummyfu
*
* The system monitoring configuration defined in diag_cfg.h is set in the array
* diag_sysmon_ch_cfg[]. The system monitoring is at the moment only used for
* supervising the cyclic/periodic tasks.
*
* Every entry of the diag_sysmon_ch_cfg[] consists of
* - enum of monitored object
* - type of monitored object (at the moment only DIAG_SYSMON_CYCLICTASK is supported)
* - maximum delay in [ms] in which the object needs to call the DIAG_SysMonNotify function defined in diag.c
* - enabling of the recording for system monitoring
* - enabling of the system monitoring for the monitored object
* - callback function if system monitoring notices an error if wished, otherwise dummyfu2
*/
/*================== Includes =============================================*/
#include "diag_cfg.h"
#include "database.h"
/*================== Macros and Definitions ===============================*/
/*================== Constant and Variable Definitions ====================*/
/**
* Enable and Disable of Error Checks for Testing Purposes
*
* Each Bit enables or disables the diagnosis (checking of) the corresponding failure code
* FIXME struct isn't used anywhere in the code at the moment.
* FIXME delete if not needed
*/
DIAG_CODE_s diag_mask = {
.GENERALmsk=0xFFFFFFFF,
.CELLMONmsk=0xFFFFFFFF,
.COMmsk=0xFFFFFFFF,
.ADCmsk=0xFFFFFFFF,
};
/**
* Callback function of diagnosis error events
*
*/
static void dummyfu(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_MSL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_cantiming(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_cantiming_cc(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_cancurrentsensor(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_ltcpec(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_ltcmux(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_ltcspi(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactormainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactormainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorchargemainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorchargemainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_contactorchargeprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void DIAG_error_interlock(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event);
static void dummyfu2(DIAG_SYSMON_MODULE_ID_e ch_id);
void dummyfu(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
;
}
void DIAG_MSL_overvoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_voltage = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_MSL_undervoltage(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.under_voltage = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.under_voltage = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_MSL_overtemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_temperature_charge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_MSL_overtemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_temperature_discharge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_MSL_undertemperaturecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.under_temperature_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.under_temperature_charge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_MSL_undertemperaturedischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.under_temperature_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.under_temperature_discharge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_MSL_overcurrentcharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_current_charge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_current_charge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_MSL_overcurrentdischarge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_MSL_FLAG_s msl_flags;
DB_ReadBlock(&msl_flags, DATA_BLOCK_ID_MSL);
if (event == DIAG_EVENT_RESET) {
msl_flags.over_current_discharge = 0;
}
if (event == DIAG_EVENT_NOK) {
msl_flags.over_current_discharge = 1;
}
DB_WriteBlock(&msl_flags, DATA_BLOCK_ID_MSL);
}
void DIAG_error_cantiming(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.can_timing = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.can_timing = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_cantiming_cc(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.can_timing_cc = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.can_timing_cc = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_cancurrentsensor(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.currentsensorresponding = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.currentsensorresponding = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_ltcpec(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.crc_error = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.crc_error = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_ltcmux(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.mux_error = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.mux_error = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_ltcspi(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.spi_error = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.spi_error = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactormainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.main_plus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.main_plus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactormainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.main_minus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.main_minus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.precharge = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.precharge = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorchargemainplus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.charge_main_plus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.charge_main_plus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorchargemainminus(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.charge_main_minus = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.charge_main_minus = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_contactorchargeprecharge(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.charge_precharge = 0;
}
if (event == DIAG_EVENT_NOK) {
error_flags.charge_precharge = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
void DIAG_error_interlock(DIAG_CH_ID_e ch_id, DIAG_EVENT_e event) {
DATA_BLOCK_ERRORSTATE_s error_flags;
DB_ReadBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
if (event == DIAG_EVENT_RESET) {
error_flags.interlock = 0;
}
if (event==DIAG_EVENT_NOK) {
error_flags.interlock = 1;
}
DB_WriteBlock(&error_flags, DATA_BLOCK_ID_ERRORSTATE);
}
/**
* Callback function of system monitoring error events
*
*/
void dummyfu2(DIAG_SYSMON_MODULE_ID_e ch_id) {
;
}
DIAG_CH_CFG_s diag_ch_cfg[] = {
/* OS-Framework and startup events */
{DIAG_CH_FLASHCHECKSUM, "FLASHCHECKSUM", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_BKPDIAG_FAILURE, "BKPDIAG", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_WATCHDOGRESET_FAILURE, "WATCHDOGRESET", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_POSTOSINIT_FAILURE, "POSTOSINIT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CALIB_EEPR_FAILURE, "CALIB_EEPR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CAN_INIT_FAILURE, "CAN_INIT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_VIC_INIT_FAILURE, "VIC_INIT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* HW-/SW-Runtime events */
{DIAG_CH_DIV_BY_ZERO_FAILURE, "DIV_BY_ZERO", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_UNDEF_INSTRUCTION_FAILURE, "UNDEF_INSTRUCTION", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_DATA_BUS_FAILURE, "DATA_BUS_FAILURE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_INSTRUCTION_BUS_FAILURE, "INSTRUCTION_BUS", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_HARDFAULT_NOTHANDLED, "HARDFAULT_NOTHANDLED", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CONFIGASSERT, "CONFIGASSERT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SYSTEMMONITORING_TIMEOUT, "SYSTEMMONITORING_TIMEOUT", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* Measurement events */
{DIAG_CH_CANS_MAX_VALUE_VIOLATE, "CANS_MAX_VALUE_VIOLATE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CANS_MIN_VALUE_VIOLATE, "CANS_MIN_VALUE_VIOLATE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CANS_CAN_MOD_FAILURE, "CANS_CAN_MOD_FAILURE", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_TIM_ERROR, "ISOMETER_TIM_ERROR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_MID, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_GROUNDERROR, "ISOMETER_GROUNDERROR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_ERROR, "ISOMETER_ERROR", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_MID, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_ISOMETER_MEAS_INVALID, "ISOMETER_MEAS_INVALID", DIAG_GENERAL_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* Under and over temperature, voltage and current at cell level */
{DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_MSL, "CELLVOLTAGE_OVERVOLTAGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overvoltage},
{DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_MSL, "CELLVOLTAGE_UNDERVOLTAGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_VOLTAGE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_undervoltage},
{DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_MSL, "OVERTEMPERATURE_CHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overtemperaturecharge},
{DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_MSL, "OVERTEMPERATURE_DISCHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overtemperaturedischarge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_MSL, "UNDERTEMPERATURE_CHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_undertemperaturecharge},
{DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_MSL, "UNDERTEMPERATURE_DISCHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_undertemperaturedischarge},
{DIAG_CH_OVERCURRENT_CHARGE_MSL, "OVERCURRENT_CHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overcurrentcharge},
{DIAG_CH_OVERCURRENT_DISCHARGE_MSL, "OVERCURRENT_DISCHARGE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_CURRENT_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_MSL_overcurrentdischarge},
{DIAG_CH_LTC_SPI, "LTC_SPI", DIAG_GENERAL_TYPE, DIAG_ERROR_LTC_SPI_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_ltcspi},
{DIAG_CH_LTC_PEC, "LTC_PEC", DIAG_GENERAL_TYPE, DIAG_ERROR_LTC_PEC_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_ltcpec},
{DIAG_CH_LTC_MUX, "LTC_MUX", DIAG_GENERAL_TYPE, DIAG_ERROR_LTC_MUX_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_ltcmux},
/* Communication events */
{DIAG_CH_CAN_TIMING, "CAN_TIMING", DIAG_GENERAL_TYPE, DIAG_ERROR_CAN_TIMING_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_CAN_TIMING, DIAG_error_cantiming},
{DIAG_CH_CAN_CC_RESPONDING, "CAN_CC_RESPONDING", DIAG_GENERAL_TYPE, DIAG_ERROR_CAN_TIMING_CC_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_CAN_SENSOR_PRESENT, DIAG_error_cantiming_cc},
{DIAG_CH_CURRENT_SENSOR_RESPONDING, "CURRENT_SENSOR_RESPONDING", DIAG_GENERAL_TYPE, DIAG_ERROR_CAN_SENSOR_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_CAN_SENSOR_PRESENT, DIAG_error_cancurrentsensor},
/* Contactor Damage Error */
{DIAG_CH_CONTACTOR_DAMAGED, "CONTACTOR_DAMAGED", DIAG_CONT_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CONTACTOR_OPENING, "CONTACTOR_OPENING", DIAG_CONT_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_CONTACTOR_CLOSING, "CONTACTOR_CLOSING", DIAG_CONT_TYPE, DIAG_ERROR_SENSITIVITY_HIGH, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
/* Contactor Feedback Error */
{DIAG_CH_CONTACTOR_MAIN_PLUS_FEEDBACK, "CONTACTOR_MAIN_PLUS_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_PLUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactormainplus},
{DIAG_CH_CONTACTOR_MAIN_MINUS_FEEDBACK, "CONTACTOR_MAIN_MINUS_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_MINUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactormainminus},
{DIAG_CH_CONTACTOR_PRECHARGE_FEEDBACK, "CONTACTOR_PRECHARGE_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_PRECHARGE_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorprecharge},
{DIAG_CH_CONTACTOR_CHARGE_MAIN_PLUS_FEEDBACK, "CONTACTOR_CHARGE_MAIN_PLUS_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_PLUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorchargemainplus},
{DIAG_CH_CONTACTOR_CHARGE_MAIN_MINUS_FEEDBACK, "CONTACTOR_CHARGE_MAIN_MINUS_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_MAIN_MINUS_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorchargemainminus},
{DIAG_CH_CONTACTOR_CHARGE_PRECHARGE_FEEDBACK, "CONTACTOR_CHARGE_PRECHARGE_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_PRECHARGE_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_contactorchargeprecharge},
/* Interlock Feedback Error */
{DIAG_CH_INTERLOCK_FEEDBACK, "INTERLOCK_FEEDBACK", DIAG_GENERAL_TYPE, DIAG_ERROR_INTERLOCK_SENSITIVITY, DIAG_RECORDING_ENABLED, DIAG_ENABLED, DIAG_error_interlock},
/* Slave PCB temperature errors for under and over temperature */
{DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_MSL, "SLAVE_PCB_UNDERTEMPERATURE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
{DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_MSL, "SLAVE_PCB_OVERTEMPERATURE_MSL", DIAG_GENERAL_TYPE, DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MSL, DIAG_RECORDING_ENABLED, DIAG_ENABLED, dummyfu},
};
DIAG_SYSMON_CH_CFG_s diag_sysmon_ch_cfg[]=
{
{DIAG_SYSMON_DATABASE_ID, DIAG_SYSMON_CYCLICTASK, 10, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_SYS_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_BMS_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_ILCK_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_LTC_ID, DIAG_SYSMON_CYCLICTASK, 5, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_ISOGUARD_ID, DIAG_SYSMON_CYCLICTASK, 400, DIAG_RECORDING_DISABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_DISABLED, dummyfu2},
{DIAG_SYSMON_CANS_ID, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_DISABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_DISABLED, dummyfu2},
{DIAG_SYSMON_APPL_CYCLIC_1ms, DIAG_SYSMON_CYCLICTASK, 2, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_APPL_CYCLIC_10ms, DIAG_SYSMON_CYCLICTASK, 20, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
{DIAG_SYSMON_APPL_CYCLIC_100ms, DIAG_SYSMON_CYCLICTASK, 200, DIAG_RECORDING_ENABLED, DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR, DIAG_ENABLED, dummyfu2},
};
DIAG_DEV_s diag_dev = {
.nr_of_ch = sizeof(diag_ch_cfg)/sizeof(DIAG_CH_CFG_s),
.ch_cfg = &diag_ch_cfg[0],
};
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
diag_cfg.h (secondary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag_cfg.h
* @author foxBMS Team
* @date 09.11.2015 (date of creation)
* @ingroup ENGINE_CONF
* @prefix DIAG
*
* @brief Diagnostic module configuration header
*
* In this header filer are the different diagnosis channel
* defines assigned to different diagnosis IDs.
*
* Furthermore are the diagnosis error log settings be configured here..
*/
#ifndef DIAG_CFG_H_
#define DIAG_CFG_H_
/*================== Includes =============================================*/
#include "general.h"
#include "batterysystem_cfg.h"
#include "diag_id_cfg.h"
/*================== Macros and Definitions ===============================*/
#define DIAG_ERROR_SENSITIVITY_HIGH (0) // logging at first event
#define DIAG_ERROR_SENSITIVITY_MID (5) // logging at fifth event
#define DIAG_ERROR_SENSITIVITY_LOW (10) // logging at tenth event
#define DIAG_ERROR_VOLTAGE_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if over/under voltage event */
#define DIAG_ERROR_TEMPERATURE_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if over/under temperature event */
#define DIAG_ERROR_CURRENT_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if over/under current event */
#define DIAG_ERROR_SLAVE_TEMP_SENSITIVITY_MSL (500) /*!< MSL level for event occurrence if slave PCB temperature event */
#define DIAG_ERROR_LTC_PEC_SENSITIVITY (5)
#define DIAG_ERROR_LTC_MUX_SENSITIVITY (5)
#define DIAG_ERROR_LTC_SPI_SENSITIVITY (5)
#define DIAG_ERROR_CAN_TIMING_SENSITIVITY (100)
#define DIAG_ERROR_CAN_TIMING_CC_SENSITIVITY (100)
#define DIAG_ERROR_CAN_SENSOR_SENSITIVITY (100)
#define DIAG_ERROR_MAIN_PLUS_SENSITIVITY (500)
#define DIAG_ERROR_MAIN_MINUS_SENSITIVITY (500)
#define DIAG_ERROR_PRECHARGE_SENSITIVITY (500)
#define DIAG_ERROR_INTERLOCK_SENSITIVITY (0)
/**
* Number of errors that can be logged
*/
#define DIAG_FAIL_ENTRY_LENGTH (50)
/**
* Maximum number of the same error that are logged
*/
#define DIAG_MAX_ENTRIES_OF_ERROR (5)
/**
* Number of contactor errors that are logged
*/
#define DIAG_FAIL_ENTRY_CONTACTOR_LENGTH (50)
// FIXME simple doxygen comment for each define?
/* Initialization and startup events: 0-15 */
#define DIAG_CH_FLASHCHECKSUM DIAG_ID_5 //
#define DIAG_CH_BKPDIAG_FAILURE DIAG_ID_6 //
#define DIAG_CH_WATCHDOGRESET_FAILURE DIAG_ID_7 //
#define DIAG_CH_POSTOSINIT_FAILURE DIAG_ID_8 //
#define DIAG_CH_CALIB_EEPR_FAILURE DIAG_ID_9 //
#define DIAG_CH_CAN_INIT_FAILURE DIAG_ID_10 //
#define DIAG_CH_VIC_INIT_FAILURE DIAG_ID_11
/* HW-/SW-Runtime events: 16-31 */
#define DIAG_CH_DIV_BY_ZERO_FAILURE DIAG_ID_16 //
#define DIAG_CH_UNDEF_INSTRUCTION_FAILURE DIAG_ID_17 //
#define DIAG_CH_DATA_BUS_FAILURE DIAG_ID_18 //
#define DIAG_CH_INSTRUCTION_BUS_FAILURE DIAG_ID_19 //
#define DIAG_CH_HARDFAULT_NOTHANDLED DIAG_ID_20 //
#define DIAG_CH_RUNTIME_ERROR_RESERVED_1 DIAG_ID_21 // reserved for future needs
#define DIAG_CH_RUNTIME_ERROR_RESERVED_2 DIAG_ID_22 // reserved for future needs
#define DIAG_CH_RUNTIME_ERROR_RESERVED_3 DIAG_ID_23 // reserved for future needs
#define DIAG_CH_CONFIGASSERT DIAG_ID_24 //
#define DIAG_CH_SYSTEMMONITORING_TIMEOUT DIAG_ID_25 //
/* Measurement events: 32-47 */
#define DIAG_CH_CANS_MAX_VALUE_VIOLATE DIAG_ID_32
#define DIAG_CH_CANS_MIN_VALUE_VIOLATE DIAG_ID_33
#define DIAG_CH_CANS_CAN_MOD_FAILURE DIAG_ID_34
/**
* Measured frequency too low or no new value captured during last cycle
*/
#define DIAG_CH_ISOMETER_TIM_ERROR DIAG_ID_35
/**
* Ground error detected
*/
#define DIAG_CH_ISOMETER_GROUNDERROR DIAG_ID_36
/**
* Device error, invalid measurement result
*/
#define DIAG_CH_ISOMETER_ERROR DIAG_ID_37
/**
* Measurement trustworthy or not, hysteresis to ground error flag
*/
#define DIAG_CH_ISOMETER_MEAS_INVALID DIAG_ID_38
/**
* Cell voltage limits violated
*/
#define DIAG_CH_CELLVOLTAGE_OVERVOLTAGE_MSL DIAG_ID_39
#define DIAG_CH_CELLVOLTAGE_UNDERVOLTAGE_MSL DIAG_ID_42
/**
* Temperature limits violated
*/
#define DIAG_CH_TEMP_OVERTEMPERATURE_CHARGE_MSL DIAG_ID_45
#define DIAG_CH_TEMP_OVERTEMPERATURE_DISCHARGE_MSL DIAG_ID_48
#define DIAG_CH_TEMP_UNDERTEMPERATURE_CHARGE_MSL DIAG_ID_51
#define DIAG_CH_TEMP_UNDERTEMPERATURE_DISCHARGE_MSL DIAG_ID_54
/**
* Overcurrent
*/
#define DIAG_CH_OVERCURRENT_CHARGE_MSL DIAG_ID_57
#define DIAG_CH_OVERCURRENT_DISCHARGE_MSL DIAG_ID_60
/**
* LTC
*/
#define DIAG_CH_LTC_SPI DIAG_ID_63
#define DIAG_CH_LTC_PEC DIAG_ID_64
#define DIAG_CH_LTC_MUX DIAG_ID_65
/* Communication events: 50-63*/
/**
* CAN timing not coming
*/
#define DIAG_CH_CAN_TIMING DIAG_ID_66
/**
* CAN C-C not coming
*/
#define DIAG_CH_CAN_CC_RESPONDING DIAG_ID_67
/**
* Current sensor not responding anymore
*/
#define DIAG_CH_CURRENT_SENSOR_RESPONDING DIAG_ID_68
/* Contactor events: 64-79*/
/**
* @brief Opening contactor at over current
*/
#define DIAG_CH_CONTACTOR_DAMAGED DIAG_ID_69
/**
* @brief counter for contactor opening
*/
#define DIAG_CH_CONTACTOR_OPENING DIAG_ID_70
/**
* @brief counter for contactor closing
*/
#define DIAG_CH_CONTACTOR_CLOSING DIAG_ID_71
/**
* @brief Contactor feedback error
*/
#define DIAG_CH_CONTACTOR_MAIN_PLUS_FEEDBACK DIAG_ID_72
#define DIAG_CH_CONTACTOR_MAIN_MINUS_FEEDBACK DIAG_ID_73
#define DIAG_CH_CONTACTOR_PRECHARGE_FEEDBACK DIAG_ID_74
#define DIAG_CH_CONTACTOR_CHARGE_MAIN_PLUS_FEEDBACK DIAG_ID_75
#define DIAG_CH_CONTACTOR_CHARGE_MAIN_MINUS_FEEDBACK DIAG_ID_76
#define DIAG_CH_CONTACTOR_CHARGE_PRECHARGE_FEEDBACK DIAG_ID_77
/**
* @brief Interlock feedback error
*/
#define DIAG_CH_INTERLOCK_FEEDBACK DIAG_ID_78
#define DIAG_CH_SLAVE_PCB_UNDERTEMPERATURE_MSL DIAG_ID_79
#define DIAG_CH_SLAVE_PCB_OVERTEMPERATURE_MSL DIAG_ID_82
/**
* enable state of diagnosis entry
*/
typedef enum {
DIAG_ENABLED = 0,
DIAG_DISABLED = 1,
} DIAG_ENABLE_STATE_e;
#if CHECK_CAN_TIMING == TRUE
#define DIAG_CAN_TIMING DIAG_ENABLED
#else
#define DIAG_CAN_TIMING DIAG_DISABLED
#endif
#if CURRENT_SENSOR_PRESENT == TRUE
#define DIAG_CAN_SENSOR_PRESENT DIAG_ENABLED
#else
#define DIAG_CAN_SENSOR_PRESENT DIAG_DISABLED
#endif
// FIXME is it better to name it DIAG_GROUP_xxx instead of DIAG_xxx_TYPE and
/**
* diagnosis groups
* failure codes FC
*/
typedef enum {
DIAG_GENERAL_TYPE = 0x00, /*!< FC 0x00 - 0x1F */
DIAG_CELLMON_TYPE = 0x01, /*!< FC 0x20 - 0x3F */
DIAG_COM_TYPE = 0x02, /*!< FC 0x40 - 0x5F */
DIAG_ADC_TYPE = 0x04, /*!< FC 0x60 - 0x7F */
// FIXME which failure codes for following group?
DIAG_CONT_TYPE = 0x08 /*!< FC */
} DIAG_TYPE_e;
/**
* diagnosis recording activation
*/
typedef enum {
DIAG_RECORDING_ENABLED = 0x00, /*!< enable diagnosis event recording */
DIAG_RECORDING_DISABLED = 0x01, /*!< disable diagnosis event recording */
} DIAG_TYPE_RECORDING_e;
// FIXME duplicate comment with enum DIAG_TYPE_e
// FIXME some enums are typedefed with DIAG...TYPE_e, some with DIAG_TYPE..._e! Reconsider this
/**
* diagnosis types for system monitoring
*/
typedef enum {
DIAG_SYSMON_CYCLICTASK = 0x00, /*!< */
DIAG_SYSMON_RESERVED = 0x01 /*!< */
} DIAG_SYSMON_TYPE_e;
/**
* diagnosis handling type for system monitoring
*/
typedef enum {
DIAG_SYSMON_HANDLING_DONOTHING = 0x00, /*!< */
DIAG_SYSMON_HANDLING_SWITCHOFFCONTACTOR = 0x01 /*!< */
} DIAG_SYSMON_HANDLING_TYPE_e;
/**
* @brief symbolic names for diagnosis
*/
typedef enum {
DIAG_OK = 0, /*!< diagnosis event ok */
DIAG_NOT_OK = 1, /*!< diagnosis event not ok */
DIAG_BUSY = 2 /*!< diagnosis event busy */
} Diag_ReturnType;
/**
* @brief listing of system-relevant tasks or functions which are checked by system monitoring
*
* diag_sysmon_ch_cfg[]=
*/
typedef enum {
DIAG_SYSMON_DATABASE_ID = 0, /*!< diag entry for database */
DIAG_SYSMON_SYS_ID = 1, /*!< diag entry for sys */
DIAG_SYSMON_BMS_ID = 2, /*!< diag entry for bms */
DIAG_SYSMON_ILCK_ID = 2, /*!< diag entry for bms */
DIAG_SYSMON_LTC_ID = 3, /*!< diag entry for ltc */
DIAG_SYSMON_ISOGUARD_ID = 4, /*!< diag entry for ioguard */
DIAG_SYSMON_CANS_ID = 5, /*!< diag entry for can */
DIAG_SYSMON_APPL_CYCLIC_1ms = 6, /*!< diag entry for application 10ms task */
DIAG_SYSMON_APPL_CYCLIC_10ms = 7, /*!< diag entry for application 10ms task */
DIAG_SYSMON_APPL_CYCLIC_100ms = 8, /*!< diag entry for application 100ms task */
DIAG_SYSMON_MODULE_ID_MAX = 9 /*!< end marker do not delete */
} DIAG_SYSMON_MODULE_ID_e;
// FIXME doxygen comment
// FIXME is DIAG_CODE_s an appropriate name for this?
typedef struct {
uint32_t GENERALmsk;
uint32_t CELLMONmsk;
uint32_t COMmsk;
uint32_t ADCmsk;
} DIAG_CODE_s;
/**
* Channel configuration of one diag channel
*/
typedef struct {
DIAG_CH_ID_e id; /*!< diagnosis event id diag_id */
uint8_t description[40];
DIAG_TYPE_e type; /*!< diagnosis group of diag event */
uint16_t thresholds; /*!< threshold for number of events which will be tolerated before generating a notification in both direction (OK or NOT OK)
* threshold=0: reports the value at first occurence, threshold=1:reports the value at second occurence*/
DIAG_TYPE_RECORDING_e enablerecording; /*!< if enabled recording in diag_memory will be activated */
DIAG_ENABLE_STATE_e state; /*!< if enabled diagnosis event will be evaluated */
void (*callbackfunc)(DIAG_CH_ID_e, DIAG_EVENT_e); /*!< will be called if number of events exceeds threshold (in both direction) with parameter DIAG_EVENT_e */
} DIAG_CH_CFG_s;
/**
* struct for device Configuration of diag module
*/
typedef struct {
uint8_t nr_of_ch; /*!< number of entries in DIAG_CH_CFG_s */
DIAG_CH_CFG_s *ch_cfg; /*!< pointer to diag channel config struct */
} DIAG_DEV_s;
/**
* state (in summary) used for task or function notification
*/
typedef struct {
uint32_t state; /*!< state */
uint32_t timestamp; /*!< timestamp of state */
} DIAG_SYSMON_NOTIFICATION_s;
/**
* Channel configuration of one system monitoring channel
*/
typedef struct {
DIAG_SYSMON_MODULE_ID_e id; /*!< the diag type by its symbolic name */
DIAG_SYSMON_TYPE_e type; /*!< system monitoring types: cyclic or special */
uint16_t threshold; /*!< max. delay time in ms */
DIAG_TYPE_RECORDING_e enablerecording; /*!< enabled if set to DIAG_RECORDING_ENABLED */
DIAG_SYSMON_HANDLING_TYPE_e handlingtype; /*!< type of handling of system monitoring errors */
DIAG_ENABLE_STATE_e state; /*!< enable or disable system monitoring */
void (*callbackfunc)(DIAG_SYSMON_MODULE_ID_e); /*!< */
} DIAG_SYSMON_CH_CFG_s;
/*================== Constant and Variable Definitions ====================*/
/**
* diag device configuration struct
*/
extern DIAG_DEV_s diag_dev;
/**
* diag system monitoring struct
*/
extern DIAG_SYSMON_CH_CFG_s diag_sysmon_ch_cfg[];
extern DIAG_CH_CFG_s diag_ch_cfg[];
// FIXME why is it in header at all? and why is it in code at all? not used
extern DIAG_CODE_s diag_mask;
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
#endif /* DIAG_CFG_H_ */
diag_id_cfg.h (secondary)¶
/**
*
* @copyright © 2010 - 2018, Fraunhofer-Gesellschaft zur Foerderung der
* angewandten Forschung e.V. All rights reserved.
*
* BSD 3-Clause License
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* We kindly request you to use one or more of the following phrases to refer
* to foxBMS in your hardware, software, documentation or advertising
* materials:
*
* ″This product uses parts of foxBMS®″
*
* ″This product includes parts of foxBMS®″
*
* ″This product is derived from foxBMS®″
*
*/
/**
* @file diag_id_cfg.h
* @author foxBMS Team
* @date 13.11.2015 (date of creation)
* @ingroup ENGINE
* @prefix DIAG
*
* @brief This file contains basic definitions in order to use an abstracted diagnosis
*/
#ifndef DIAG_ID_CFG_H_
#define DIAG_ID_CFG_H_
/*================== Includes =============================================*/
/*================== Macros and Definitions ===============================*/
/**
* diagnosis check result (event)
*/
typedef enum {
DIAG_EVENT_OK = 0x00, /*!< diag channel event OK */
DIAG_EVENT_NOK = 0x01, /*!< diag channel event NOK */
DIAG_EVENT_RESET = 0x02, /*!< reset diag channel eventcounter to 0 */
} DIAG_EVENT_e;
/**
* symbolic IDs for possible diagnosis entries
*/
typedef enum {
DIAG_ID_0 = 0,
DIAG_ID_1 = 1,
DIAG_ID_2 = 2,
DIAG_ID_3 = 3,
DIAG_ID_4 = 4,
DIAG_ID_5 = 5,
DIAG_ID_6 = 6,
DIAG_ID_7 = 7,
DIAG_ID_8 = 8,
DIAG_ID_9 = 9,
DIAG_ID_10 = 10,
DIAG_ID_11 = 11,
DIAG_ID_12 = 12,
DIAG_ID_13 = 13,
DIAG_ID_14 = 14,
DIAG_ID_15 = 15,
DIAG_ID_16 = 16,
DIAG_ID_17 = 17,
DIAG_ID_18 = 18,
DIAG_ID_19 = 19,
DIAG_ID_20 = 20,
DIAG_ID_21 = 21,
DIAG_ID_22 = 22,
DIAG_ID_23 = 23,
DIAG_ID_24 = 24,
DIAG_ID_25 = 25,
DIAG_ID_26 = 26,
DIAG_ID_27 = 27,
DIAG_ID_28 = 28,
DIAG_ID_29 = 29,
DIAG_ID_30 = 30,
DIAG_ID_31 = 31,
DIAG_ID_32 = 32,
DIAG_ID_33 = 33,
DIAG_ID_34 = 34,
DIAG_ID_35 = 35,
DIAG_ID_36 = 36,
DIAG_ID_37 = 37,
DIAG_ID_38 = 38,
DIAG_ID_39 = 39,
DIAG_ID_40 = 40,
DIAG_ID_41 = 41,
DIAG_ID_42 = 42,
DIAG_ID_43 = 43,
DIAG_ID_44 = 44,
DIAG_ID_45 = 45,
DIAG_ID_46 = 46,
DIAG_ID_47 = 47,
DIAG_ID_48 = 48,
DIAG_ID_49 = 49,
DIAG_ID_50 = 50,
DIAG_ID_51 = 51,
DIAG_ID_52 = 52,
DIAG_ID_53 = 53,
DIAG_ID_54 = 54,
DIAG_ID_55 = 55,
DIAG_ID_56 = 56,
DIAG_ID_57 = 57,
DIAG_ID_58 = 58,
DIAG_ID_59 = 59,
DIAG_ID_60 = 60,
DIAG_ID_61 = 61,
DIAG_ID_62 = 62,
DIAG_ID_63 = 63,
DIAG_ID_64 = 64,
DIAG_ID_65 = 65,
DIAG_ID_66 = 66,
DIAG_ID_67 = 67,
DIAG_ID_68 = 68,
DIAG_ID_69 = 69,
DIAG_ID_70 = 70,
DIAG_ID_71 = 71,
DIAG_ID_72 = 72,
DIAG_ID_73 = 73,
DIAG_ID_74 = 74,
DIAG_ID_75 = 75,
DIAG_ID_76 = 76,
DIAG_ID_77 = 77,
DIAG_ID_78 = 78,
DIAG_ID_79 = 79,
DIAG_ID_80 = 80,
DIAG_ID_81 = 81,
DIAG_ID_82 = 82,
DIAG_ID_83 = 83,
DIAG_ID_84 = 84,
DIAG_ID_85 = 85,
DIAG_ID_86 = 86,
DIAG_ID_87 = 87,
DIAG_ID_88 = 88,
DIAG_ID_89 = 89,
DIAG_ID_90 = 90,
DIAG_ID_91 = 91,
DIAG_ID_92 = 92,
DIAG_ID_93 = 93,
DIAG_ID_94 = 94,
DIAG_ID_95 = 95,
DIAG_ID_96 = 96,
DIAG_ID_97 = 97,
DIAG_ID_98 = 98,
DIAG_ID_99 = 99,
DIAG_ID_100 = 100,
DIAG_ID_101 = 101,
DIAG_ID_102 = 102,
DIAG_ID_103 = 103,
DIAG_ID_104 = 104,
DIAG_ID_105 = 105,
DIAG_ID_106 = 106,
DIAG_ID_107 = 107,
DIAG_ID_108 = 108,
DIAG_ID_109 = 109,
DIAG_ID_110 = 110,
DIAG_ID_111 = 111,
DIAG_ID_MAX = 112,
} DIAG_CH_ID_e;
/*================== Constant and Variable Definitions ====================*/
/*================== Function Prototypes ==================================*/
/*================== Function Implementations =============================*/
#endif /* DIAG_ID_CFG_H_ */