ISOGUARD Module Sources


isoguard.c

/**
 *
 * @copyright © 2010 - 2020, 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    isoguard.c
 * @author  foxBMS Team
 * @date    12.10.2015 (date of creation)
 * @ingroup DRIVERS
 * @prefix  ISO
 *
 * @brief   Driver for the isolation monitoring.
 *
 * main file for insulation measurement
 *
 */



/*================== Includes =============================================*/
#include "isoguard.h"

#include "database.h"
#include "diag.h"
#include "ir155.h"

#if BUILD_MODULE_ENABLE_ISOGUARD == 1
/*================== Macros and Definitions ===============================*/

/*================== Constant and Variable Definitions ====================*/

/**
 * Dutycycle - resistance table
 * for Bender IR155-3204 (Art. No. B91068139)
 *
 *  dc | resistance/kOhm  |  description           |
 *  ---|------------------|------------------------|
 *  100| -63,16           |  not valid             |
 *  98 | -38,71           |  invalid               |
 *  95 | =0,00            |  invalid               |
 *  95 | >0,00            |  shortcut              |
 *  90 | 70,59            |  very low resistance   |
 *  80 | 240,00           |  low resistance        |
 *  70 | 461,54           |  low resistance        |
 *  60 | 763,64           |  lowmid resistance     |
 *  50 | 1200,00          |  highmid resistance    |
 *  40 | 1885,71          |  highmid resistance    |
 *  30 | 3120,00          |  high resistance       |
 *  20 | 6000,00          |  high resistance       |
 *  10 | 20400,00         |  very high resistance  |
 *  5  | oo               |  very high resistance  |
 *  3  |-55200,00         |  invalid               |
 *  0  |-22800,00         |  invalid               |
 *
 */

static ISO_INIT_STATE_e iso_state = ISO_STATE_UNINITIALIZED;
/*================== Function Prototypes ==================================*/


/*================== Function Implementations =============================*/

void ISO_Init(void) {
#ifdef ISO_ISOGUARD_ENABLE
    /* Initialize Software-Module */
    IR155_Init(ISO_CYCLE_TIME);

    /* Enable Hardware-Bender-Module */
    IR155_ENABLE_BENDER_HW();

    iso_state = ISO_STATE_INITIALIZED;
#endif
}


void ISO_ReInit(void) {
#ifdef ISO_ISOGUARD_ENABLE

    iso_state = ISO_STATE_UNINITIALIZED;

    /* Disable Hardware-Bender-Modul */
    IR155_DISABLE_BENDER_HW();

    /* DeInit Software-Modul */
    IR155_DeInit();

    /* DeInit Timer-Modul */
    HAL_TIM_IC_DeInit(&IR155_BENDER_IC_HANDLE);

    /* Wait 1ms */
    OS_taskDelay(1);

    /* Init and enable timer module and Isometer*/
    ISO_Init();
#endif
}


void ISO_MeasureInsulation(void) {
    /* Call sysmon notify function */
    DIAG_SysMonNotify(DIAG_SYSMON_ISOGUARD_ID, 0);        /* task is running, state = ok */

    #ifdef ISO_ISOGUARD_ENABLE
    /* Do not continue if ISOGUARD module is still uninitialized */
    if (iso_state == ISO_STATE_UNINITIALIZED) {
        return;
    }

    STD_RETURN_TYPE_e retVal = E_NOT_OK;
    IO_PIN_STATE_e ohksState = IO_PIN_RESET;    /* high -> no error, low -> error */
    uint32_t resistance = 0;
    IR155_STATE_e state = IR155_STATE_UNDEFINED;
    static DATA_BLOCK_ISOMETER_s ISO_measData = {  /* database structure */
            .valid = 1,
            .state = 1,
            .resistance_kOhm = 0,
            .timestamp = 0,
            .previous_timestamp = 0,
    };

    retVal = IR155_MeasureResistance(&state, &resistance, &ohksState);

    /* Get resistance */
    ISO_measData.resistance_kOhm = resistance;

    if (state == IR155_MEAS_NOT_VALID) {
        /* Measurement result is not valid */
        ISO_measData.valid = 1;
    } else {
        ISO_measData.valid = 0;
    }

    /* Set state valid/invalid based on resistance threshold */
    if (retVal == E_OK && resistance > ISO_RESISTANCE_THRESHOLD_kOhm &&
            (state == IR155_RESIST_MEAS_GOOD || state == IR155_RESIST_ESTIM_GOOD)) {
        ISO_measData.state = 0;     /* Good resistance measured */
    } else {
        ISO_measData.state = 1;     /* Invalid resistance measured or error occured; */
    }

    /* Set measurement result invalid if Pin OHKS detects an error */
    if (ohksState == IO_PIN_RESET ||
            (ISO_measData.valid == 0 && ISO_measData.state == 1)) {
        /* Error if PIN set or invalid insulation detected */
        DIAG_Handler(DIAG_CH_INSULATION_ERROR, DIAG_EVENT_NOK, 0);
    } else if (ISO_measData.valid == 0 && ISO_measData.state == 0) {
        /* Measurement okay */
        DIAG_Handler(DIAG_CH_INSULATION_ERROR, DIAG_EVENT_OK, 0);
    } else {
        /* Do nothing, Pin == okay, but measurement invalid */
    }

    ISO_measData.previous_timestamp = ISO_measData.timestamp;
    ISO_measData.timestamp = OS_getOSSysTick();

    /* Store data in database */
    DB_WriteBlock(&ISO_measData, DATA_BLOCK_ID_ISOGUARD);
#endif
}
#endif

isoguard.h

/**
 *
 * @copyright © 2010 - 2020, 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    isoguard.h
 * @author  foxBMS Team
 * @date    12.10.2015 (date of creation)
 * @ingroup DRIVERS
 * @prefix  ISO
 *
 * @brief   Headers for the driver for the isolation monitoring.
 *
 * Header file for insulation measurement
 */

#ifndef ISOGUARD_H_
#define ISOGUARD_H_

/*================== Includes =============================================*/
#include "isoguard_cfg.h"

/*================== Macros and Definitions ===============================*/

/*================== Constant and Variable Definitions ====================*/

/*================== Function Prototypes ==================================*/
/**
 * @brief Initializes SW-Isoguard modul and Enables HW-Bender-Modul
 */
extern void ISO_Init(void);

/**
 * @brief Resets isometer and timer modul as well as HW-Bender-Modul
 */
extern void ISO_ReInit(void);

/**
 * @brief Interface function which delivers the actual signal measurement (dutycyle) and writes the result in the database
 */
extern void ISO_MeasureInsulation(void);

/*================== Function Implementations =============================*/

#endif /* ISOGUARD_H_ */

ir155.c

/**
 *
 * @copyright © 2010 - 2020, 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    ir155.c
 * @author  foxBMS Team
 * @date    11.02.2014 (date of creation)
 * @ingroup DRIVERS
 * @prefix  IR155
 *
 * @brief   Driver for the isolation monitoring
 *
 * main file of bender isometer IR155 driver
 *
 */


/*================== Includes =============================================*/
#include "ir155.h"

#include "diag.h"

#if BUILD_MODULE_ENABLE_ISOGUARD == 1
/*================== Macros and Definitions ===============================*/
/* Defines for diagnosis handling */
#define DIAG_TIMER_OVERFLOW     0
#define DIAG_TIMER_NO_VALUE     1
#define DIAG_ERR_MEAS_CORRUPT   2
#define DIAG_ERR_DEVICE_ERROR   3
#define DIAG_ERR_SHORT_KL_15    4
#define DIAG_ERR_SHORT_KL_31    5
#define DIAG_ERR_UNDERVOLTAGE   6
#define DIAG_ERR_UNDEFINED      7


/*================== Constant and Variable Definitions ====================*/

/**
 *
 */
uint8_t MEM_BKP_SRAM isobender_grounderror = 0;

static TIM_DutyCycleType_s sig_ir155_dutycycle = {
        .ActiveTime = 0,
        .PeriodTime = 0,
};
static uint8_t measCycleTime = 0xFF;
static uint16_t hysteresisCounter = 0;

IR155_MEASUREMENT_s ir155_DC = {
        .sigICU.ActiveTime = 0,
        .sigICU.PeriodTime = 0,
        .resistance        = 0,
        .dutycycle         = 0,
        .OKHS_state        = 0,
        .mode              = IR155_UNKNOWN,
        .state             = IR155_UNINITIALIZED,
};

#ifdef IR155_HISTORYENABLE
unsigned char isoIR_his_idx = 0;
IR155_MEASUREMENT_HISTORY_s isoIR_his[IR155_HISTORY_LENGTH];  /* Initialization of array in ISOIR_Init() */
#endif

/*================== Function Prototypes ==================================*/
static IR155_SIGMODE_e IR155_GetMode(uint32_t signalperiod);

/*================== Function Implementations =============================*/

void IR155_Init(uint8_t cycleTime) {
#ifdef IR155_HISTORYENABLE
    for (int i = 0; i < IR155_HISTORY_LENGTH; i++) {
        isoIR_his[i].ir155_dc_Meas.sigICU.PeriodTime = 0;
        isoIR_his[i].ir155_dc_Meas.mode = IR155_UNKNOWN;
    }
#endif

    /* Timer peripheral initialization if not already done. */
    IR155_START_PWM_MEASUREMENT(&IR155_BENDER_IC_HANDLE);

    /* Check grounderror flag */
    if (isobender_grounderror != 0) {
        /* GROUNDERROR occured before shutting down */
        hysteresisCounter = IR155_WAIT_TIME_AFTER_GNDERROR;
    } else {
        /* Normal startup delay -> wait 2.2s until first measurement is trustworthy */
        hysteresisCounter = 2200;
    }

    measCycleTime = cycleTime;

    /* Set diagnosis message that measurement is not trustworthy */
    DIAG_Handler(DIAG_CH_ISOMETER_MEAS_INVALID, DIAG_EVENT_NOK, 0);
}



void IR155_DeInit(void) {
    /* Reset cycle time */
    measCycleTime = 0;

    /* IR155_MeasureResistance now always returns state IR155_MEAS_NOT_VALID
     * until IR155_Init() function is called again */
    hysteresisCounter = 1;

    /* Reset timer duty cycle struct */
    sig_ir155_dutycycle.ActiveTime = 0;
    sig_ir155_dutycycle.PeriodTime = 0;

    /* Set diagnosis message that measurement is not trustworthy */
    DIAG_Handler(DIAG_CH_ISOMETER_MEAS_INVALID, DIAG_EVENT_NOK, 0);
}

/**
 * Determines frequency-dependent operating state.
 * Use of intervals because of measuring and signal inaccuracy
 *
 * @param       signalperiod   period of captured signal in [1/75 ms], type uint32_t
 *
 * @return      ISO_SIGMODE_enum        bender operating state
 */
static IR155_SIGMODE_e IR155_GetMode(uint32_t signalperiod) {
    IR155_SIGMODE_e ret_val = IR155_UNKNOWN;

    if ((signalperiod >= IR155_NORMALCONDITION_PERIODE_MIN) && (signalperiod < IR155_NORMALCONDITION_PERIODE_MAX))
        ret_val = IR155_NORMAL_MODE;
    else if ((signalperiod >= IR155_UNDERVOLATGE_PERIODE_MIN) && (signalperiod < IR155_UNDERVOLATGE_PERIODE_MAX))
        ret_val = IR155_UNDERVOLATGE_MODE;        /* should not be detected as default threshold 0V, EOL Bender configurable! */
    else if ((signalperiod >= IR155_SPEEDSTART_PERIODE_MIN) && (signalperiod < IR155_SPEEDSTART_PERIODE_MAX))
        ret_val = IR155_SPEEDSTART_MODE;
    else if ((signalperiod >= IR155_IMDERROR_PERIODE_MIN) && (signalperiod < IR155_IMDERROR_PERIODE_MAX))
        ret_val = IR155_IMDERROR_MODE;
    else if ((signalperiod >= IR155_GROUNDERROR_PERIODE_MIN) && (signalperiod < IR155_GROUNDERROR_PERIODE_MAX))
        ret_val = IR155_GROUNDERROR_MODE;
    else  if (signalperiod < IR155_GROUNDERROR_PERIODE_MIN)
        ret_val = IR155_UNDEFINED_FRQMAX;
    else  if (signalperiod >= IR155_PERIODE_MAX) {
        if (IR155_GET_MHS()) {
            ret_val = IR155_SHORT_KL15;        /* level at port: high */
        } else {
            ret_val = IR155_SHORT_KL31;     /* level at port: low */
        }
    }
    return ret_val;
}


STD_RETURN_TYPE_e IR155_MeasureResistance(IR155_STATE_e* state, uint32_t* resistance, IO_PIN_STATE_e* ohks_state) {
#ifdef IR155_HISTORYENABLE
    static IR155_INSULATION_s ir155_insulation_loc = {
            .state = IR155_UNINITIALIZED,
            .resistance = 0,
            .OKHS_state = 0,
            .state_old = IR155_UNINITIALIZED,
            .resistance_old = 0,
            .OKHS_State_old = 0,
    };
#endif

    /* Check parameters against null */
    if (state == NULL || resistance == NULL) {
        return E_NOT_OK;
    }

    TIM_RETURNTYPE_e retValTim = DIAG_TIM_ERROR;
    uint8_t retDiag = DIAG_HANDLER_RETURN_OK;
    STD_RETURN_TYPE_e retVal = E_OK;

    /* read value of IsoGuard Insulation_Good digital input */
    ir155_DC.OKHS_state = IR155_GET_OKHS();

    /* get actual active-time (t_ON)) and period from ICU */
    retValTim = IR155_GET_DUTYCYCLE(&sig_ir155_dutycycle);

    sig_ir155_dutycycle.ActiveTime *= TIM9_CLOCK_TICK_DURATION_IN_US * 75; /* in units of  (1/75) us */
    sig_ir155_dutycycle.PeriodTime *= TIM9_CLOCK_TICK_DURATION_IN_US * 75; /* in units of  (1/75) us */

    if (retValTim == DIAG_TIM_OK) {
        ir155_DC.sigICU.ActiveTime = sig_ir155_dutycycle.ActiveTime;            /* in units of  (1/75) us */
        ir155_DC.sigICU.PeriodTime = (sig_ir155_dutycycle.PeriodTime+500)/1000; /* in units of  (1/75) ms */

        DIAG_Handler(DIAG_CH_ISOMETER_TIM_ERROR, DIAG_EVENT_OK, DIAG_TIMER_NO_VALUE);
    } else {
        /* Error in call of ISOIR_GET_DUTYCYCLE or invalid values measured */
        if (retValTim == DIAG_TIM_OVERFLOW) {
            retDiag = DIAG_Handler(DIAG_CH_ISOMETER_TIM_ERROR, DIAG_EVENT_NOK, DIAG_TIMER_OVERFLOW);
        } else {
            retDiag = DIAG_Handler(DIAG_CH_ISOMETER_TIM_ERROR, DIAG_EVENT_NOK, DIAG_TIMER_NO_VALUE);
        }
        ir155_DC.sigICU.ActiveTime = 0;
        ir155_DC.sigICU.PeriodTime = 0;

        if (retDiag != 0)
            retVal = E_NOT_OK;
    }


    /* calculate actual duty cycle and frequency (which identifies mode)  */
    if (sig_ir155_dutycycle.ActiveTime < sig_ir155_dutycycle.PeriodTime) {
        /* both edges (high and low) have been detected within call time of this function */
        ir155_DC.dutycycle = ((ir155_DC .sigICU.ActiveTime)/ir155_DC .sigICU.PeriodTime + 5)/10;    /*  in units of % with rounding */
        ir155_DC.mode      = IR155_GetMode(ir155_DC .sigICU.PeriodTime);
    } else {
        /* this branch should never be entered if duty cycle-measurement works fine */
        if (sig_ir155_dutycycle.PeriodTime != 0) {
           /* implausible, SW-system error,Spikes...? */
            ir155_DC.mode      = IR155_DCM_CORRUPT;
        } else {
            /* no signal edges detected, */
            /* HW-system error? -> sensor wire break (pullup) */
            /* SW-system error? -> ICU not working */
            ir155_DC.mode      = IR155_DCM_NOSIGNAL;
        }
        /* Nevertheless, use pin level for low (0%) and high (100%) differentiation */
        if (IR155_GET_MHS())
            ir155_DC.dutycycle = 100;   /* max in units of % */
        else
            ir155_DC.dutycycle = 0;     /* min in units of % */

        retDiag = DIAG_Handler(DIAG_CH_ISOMETER_ERROR, DIAG_EVENT_NOK, DIAG_ERR_MEAS_CORRUPT);

        if (retDiag != 0)
            retVal = E_NOT_OK;
    }


    /* calculate resistance if possible which depends on mode of measurement output signal of isometer */
    /* (identified by frequency) */
    if (ir155_DC.mode == IR155_NORMAL_MODE) {
        /* 5%..10%*: because of measuring inaccuracy it is used [3%..12%]*/
        if ((ir155_DC.dutycycle) >= 3 && (ir155_DC.dutycycle <= 12)) {
            /* insulation good, sensor working good */
            ir155_DC.state = IR155_RESIST_MEAS_GOOD;

            if (ir155_DC.dutycycle <= 5) {
                ir155_DC.resistance = 106800;        /* max 106.8 MOhm */
            } else {
                ir155_DC.resistance = (90*1200)/(ir155_DC.dutycycle-5)-1200;
            }

        } else if (ir155_DC.dutycycle < 3) {
            /* insulation unknown, sensor working bad */
            ir155_DC.state = IR155_RESIST_MEAS_UNKNOWN; /* sensor error dc < 3% */
            ir155_DC.resistance = 0;                    /* resistance not readable */
        } else if (ir155_DC .dutycycle > 12 && ir155_DC.dutycycle <= 90) {
          /* 10%..90%*: because of measuring inaccuracy it is used ]12%..90%]*/

            /* insulation getting worse, sensor working good */
            /* sensor dc < 10%..90% */
            ir155_DC.resistance = (90*1200)/(ir155_DC.dutycycle-5)-1200; /* resistance  20MOhm...70kOhm */
            if (ir155_DC.resistance > IR155_RESISTANCE_RESPONSE_VALUE)
                ir155_DC.state = IR155_RESIST_MEAS_GOOD;
            else
                ir155_DC.state = IR155_RESIST_MEAS_BAD;
        } else if (ir155_DC.dutycycle > 90 && ir155_DC.dutycycle <= 97) {
            /* 90%..95%*: because of measuring inaccuracy it is used ]90%..97%]*/

            /* insulation bad, sensor working good */
            /* sensor dc < 90%..95% */
            if (ir155_DC .dutycycle >= 95) {
                ir155_DC.state = IR155_RESIST_MEAS_BAD;
                ir155_DC.resistance = 1;                /* 0kOhm will be interpreted as "not readable", so use 1kOhm */
            } else {
                ir155_DC.state = IR155_RESIST_MEAS_BAD;
                ir155_DC.resistance = (90*1200)/(ir155_DC.dutycycle-5)-1200;    /* resistance  70kOhm..0kOhm */
            }
        } else if (ir155_DC.dutycycle > 97 && ir155_DC.dutycycle <= 100) {  /* ]97%..100%] */
            /* insulation unknown, sensor working bad */
            ir155_DC.state = IR155_RESIST_MEAS_UNKNOWN;    /* sensor error dc > 95% */
            ir155_DC.resistance = 0;                        /* resistance not readable */
        }
    } else if (ir155_DC.mode == IR155_SPEEDSTART_MODE) {
         /* SSD Mode (SPEED STARTUP) will be entered first after startup (within 2sec.) for resistance estimation */
        /* as NORMAL MODE (Normal Condition measurement) could take maximum time of 17.5sec. */

        /* 5%..10%*: because of measuring inaccuracy it is used [3%..12%]*/
        if (ir155_DC.dutycycle >= 3 && ir155_DC.dutycycle <= 12) {
            /* insulation good estimation, sensor working good */
            ir155_DC.state = IR155_RESIST_ESTIM_GOOD;    /* sensor error dc = 5..10% */
            ir155_DC.resistance = 200;                      /* R >= 200kOhm */
        } else if (ir155_DC.dutycycle >= 88 && ir155_DC.dutycycle <= 97) {
            /* 90%..95%*: because of measuring inaccuracy it is used [88%..97%]*/
            /* insulation bad, sensor working good */
            ir155_DC.state = IR155_RESIST_ESTIM_BAD;    /* sensor error dc = 90..95% */
            ir155_DC.resistance = 50;           /* R <= 50kOhm */
        } else {
            /* insulation unknown, sensor working good, dc measurement corrupt */
            ir155_DC.state = IR155_RESIST_ESTIM_UNKNOWN;    /* sensor error dc = 0..5%, dc = 10..90% or dc > 95% */
            ir155_DC.resistance = 0;                    /* resistance not readable */
        }
    } else if (ir155_DC.mode == IR155_GROUNDERROR_MODE) {
        /* Condition "KL31 fault"  is identified by base frequency 50Hz */
        /* and duty cycle  47.5% ... 52.5% */

        /* 47.5%..52.5%*: because of measuring inaccuracy it is used ]40%..60%]  */
        if (ir155_DC.dutycycle > 40 && ir155_DC.dutycycle <= 60) {
            /* insulation unknown, sensor working bad */
            ir155_DC.state = IR155_GROUND_ERROR;

            if (DIAG_HANDLER_RETURN_OK != DIAG_Handler(DIAG_CH_ISOMETER_GROUNDERROR, DIAG_EVENT_NOK, 0)) {
                /* Set grounderror flag */
                isobender_grounderror = 1;
            }
        } else {
            /* insulation unknown, sensor working good, DC measurement corrupt */
            ir155_DC.state = IR155_STATE_UNDEFINED;
        }
        ir155_DC.resistance = 0;          /* resistance unknown */

    } else if (ir155_DC.mode == IR155_IMDERROR_MODE) {
        /* Condition "device error" is identified by base frequency 40Hz */
        /* with dutycycle  47.5% ... 52.5% */

        /* 47.5%..52.5%*: because of measuring inaccuracy it is used ]40%..60%]  */
        if (ir155_DC.dutycycle > 40 && ir155_DC.dutycycle <= 60) {
           /* insulation unknown, sensor working bad */
            ir155_DC.state = IR155_IMD_ERROR;
        } else {
            /* insulation unknown, sensor working unknown, DC measurement corrupt */
            ir155_DC.state = IR155_STATE_UNDEFINED;
        }
        ir155_DC.resistance = 0;          /* resistance unknown */
        retDiag = DIAG_Handler(DIAG_CH_ISOMETER_ERROR, DIAG_EVENT_NOK, DIAG_ERR_DEVICE_ERROR);
    } else if (ir155_DC.mode == IR155_SHORT_KL15) {
        ir155_DC.state = IR155_SIGNALSHORT_KL15;
        ir155_DC.resistance = 0;
        retDiag = DIAG_Handler(DIAG_CH_ISOMETER_ERROR, DIAG_EVENT_NOK, DIAG_ERR_SHORT_KL_15);
    } else if (ir155_DC.mode == IR155_SHORT_KL31) {
        ir155_DC.state = IR155_SIGNALSHORT_KL31;
        ir155_DC.resistance = 0;
        retDiag = DIAG_Handler(DIAG_CH_ISOMETER_ERROR, DIAG_EVENT_NOK, DIAG_ERR_SHORT_KL_31);
    } else if (ir155_DC.mode == IR155_UNDERVOLATGE_MODE ||
             ir155_DC.mode == IR155_UNDEFINED_FRQMAX  ||
             ir155_DC.mode == IR155_UNKNOWN           ||
             ir155_DC.mode == IR155_DCM_CORRUPT       ||
             ir155_DC.mode == IR155_DCM_NOSIGNAL
) {
        /* insulation unknown, sensor working unknown, DC measurement corrupt */
        if (ir155_DC.mode == IR155_UNDERVOLATGE_MODE) {
            retDiag = DIAG_Handler(DIAG_CH_ISOMETER_ERROR, DIAG_EVENT_NOK, DIAG_ERR_UNDERVOLTAGE);
        } else {
            retDiag = DIAG_Handler(DIAG_CH_ISOMETER_ERROR, DIAG_EVENT_NOK, DIAG_ERR_UNDEFINED);
        }
        ir155_DC.state = IR155_STATE_UNDEFINED;
        ir155_DC.resistance = 0;
    }

    if (retDiag != 0)
        retVal = E_NOT_OK;

    /* Measurement is not valid, either because of startup delay
       or detected ground error before startup */
    if (hysteresisCounter > 0) {
        if (hysteresisCounter >= measCycleTime) {
            hysteresisCounter -= measCycleTime;
            ir155_DC.state = IR155_MEAS_NOT_VALID;
        } else {
            /* 0 < hysteresisCounter < measCycleTime
             * Measurement is valid from that moment on */
            hysteresisCounter = 0;
        }

        if (hysteresisCounter == 0) {
            /* If hysteresis is over, reset diag flag and reset grounderror flag */
            DIAG_Handler(DIAG_CH_ISOMETER_GROUNDERROR, DIAG_EVENT_OK, 0);
            DIAG_Handler(DIAG_CH_ISOMETER_MEAS_INVALID, DIAG_EVENT_OK, 0);

            isobender_grounderror = 0;
        }
    }

    /* Write measurement result into insulation_meas pointer */
    *resistance = ir155_DC.resistance;
    *state = ir155_DC.state;
    *ohks_state = ir155_DC.OKHS_state;


    /* Reduce diag-counter if no error occurred */
    if ((retDiag == DIAG_HANDLER_RETURN_OK) ||
            ((retDiag != DIAG_HANDLER_RETURN_OK) && (ir155_DC .mode == IR155_GROUNDERROR_MODE))) {
        DIAG_Handler(DIAG_CH_ISOMETER_ERROR, DIAG_EVENT_OK, 0);
    }

#ifdef IR155_HISTORYENABLE
    ir155_insulation_loc.state = ir155_DC.state;
    ir155_insulation_loc.OKHS_state = ir155_DC.OKHS_state;
    ir155_insulation_loc.resistance = ir155_DC.resistance;
    if (ir155_insulation_loc.state != ir155_insulation_loc.state_old ||
            ir155_insulation_loc.resistance != ir155_insulation_loc.resistance_old ||
            ir155_insulation_loc.OKHS_state != ir155_insulation_loc.OKHS_State_old) {
        isoIR_his[isoIR_his_idx].ir155_dc_Meas = ir155_DC;
        isoIR_his[isoIR_his_idx].ir155_dc_Meas.state = ir155_insulation_loc.state;
        isoIR_his[isoIR_his_idx].ir155_dc_Meas.OKHS_state = ir155_insulation_loc.OKHS_state;
        isoIR_his[isoIR_his_idx++].timestamp_ms = OS_getOSSysTick();

        if (isoIR_his_idx >= IR155_HISTORY_LENGTH)
            isoIR_his_idx = 0;

        ir155_insulation_loc.state_old = ir155_insulation_loc.state;
        ir155_insulation_loc.resistance_old = ir155_insulation_loc.resistance;
        ir155_insulation_loc.OKHS_State_old = ir155_insulation_loc.OKHS_state;
    }
#endif

    return retVal;
}
#endif

ir155.h

/**
 *
 * @copyright &copy; 2010 - 2020, 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:
 *
 * &Prime;This product uses parts of foxBMS&reg;&Prime;
 *
 * &Prime;This product includes parts of foxBMS&reg;&Prime;
 *
 * &Prime;This product is derived from foxBMS&reg;&Prime;
 *
 */

/**
 * @file    ir155.h
 * @author  foxBMS Team
 * @date    27.02.2013 (date of creation)
 * @ingroup DRIVERS
 * @prefix  IR155
 *
 * @brief   Headers for the driver for the isolation monitoring
 *
 * Module header for insulation measurements. Sets up the interface to the
 * IO and TIM module. Also sets up Bender Isometer specific settings.
 *
 */

#ifndef IR155_H_
#define IR155_H_

/*================== Includes =============================================*/
#include "general.h"

#include "io.h"
#include "timer.h"

/*================== Macros and Definitions ===============================*/
#define IR155_BENDER_IC_HANDLE   (htim9)

/**
 * @ingroup CONFIG_IR155
 * enable Bender history, designed for debugging purposes only
 * \par Type:
 * toggle
 * \par Default:
 * False
*/
/* #define IR155_HISTORYENABLE */



/**
 * @ingroup CONFIG_IR155
 * history depth, if history is enabled by IR155_KEY_HISTORYENABLE
 * \par Type:
 * int
 * \par Range:
 * x > 0
 * \par Default:
 * 5
*/
#define IR155_HISTORY_LENGTH            5

/**
 * @ingroup CONFIG_IR155
 * IR155_PERIODE_RESOLUTION
 * \par Type:
 * int
 * \par Range:
 * x > 0
 * \par Default:
 * 75
*/
#define IR155_PERIODE_RESOLUTION        75

/**
 * @ingroup CONFIG_IR155
 * IR155_WAIT_TIME_AFTER_GNDERROR % IR155_CYCLE_TIME == 0 !!!!
 * During this time, the results of Bender Isometer aren't to be trusted
 * wait time in [ms] <= 65535;
 * IR155_WAIT_TIME_AFTER_GNDERROR
 * \par Type:
 * int
 * \par Range:
 * 0 < x <=65535
 * \par Unit:
 * ms
 * \par Default:
 * 25000
*/
#define IR155_WAIT_TIME_AFTER_GNDERROR  25000


/**
 * @ingroup CONFIG_IR155
 * Response value for Bender IR155-3204 with Article No. B91068139V4
 * \par Type:
 * int
 * \par Range:
 * x > 0
 * \par Default:
 * 100
*/
#define IR155_RESISTANCE_RESPONSE_VALUE 100

/* Enable/Disable Bender Hardware */
#define IR155_ENABLE_BENDER_HW()        IO_WritePin(IO_PIN_BENDER_SUPPLY_ENABLE, IO_PIN_SET)
#define IR155_DISABLE_BENDER_HW()       IO_WritePin(IO_PIN_BENDER_SUPPLY_ENABLE, IO_PIN_RESET)

/* Timer-modul interface functions */
#define IR155_START_PWM_MEASUREMENT(x)  TIM_Start_PWM_IC_Measurement(x)
#define IR155_GET_DUTYCYCLE(x)          TIM_GetDutycycle(&IR155_BENDER_IC_HANDLE, x)

/* Read pin state of MHS and OKHS Pin */
#define IR155_GET_MHS()                 IO_ReadPin(IO_PIN_BENDER_PWM)
#define IR155_GET_OKHS()                IO_ReadPin(IO_PIN_BENDER_OK)

/* Clear TIM update flag */
#define IR155_RESET_TIM()               __HAL_TIM_CLEAR_FLAG(&IR155_BENDER_IC_HANDLE, TIM_FLAG_UPDATE)

/**
 * symbolic names for the different possible periods of Bender Isometer.
 * Min and max values are defined for tolerance purposes of the measurement.
 * @ingroup ISO
 */
typedef enum {
    /*Periodes in units of in units of  (1/75) ms*/
    IR155_PERIODE_MAX                   = 200*IR155_PERIODE_RESOLUTION,     /* 5    Hz*/

    IR155_NORMALCONDITION_PERIODE_MAX   = 120*IR155_PERIODE_RESOLUTION,     /* 8,3  Hz*/
    IR155_NORMALCONDITION_PERIODE       = 100*IR155_PERIODE_RESOLUTION,     /* 10   Hz*/
    IR155_NORMALCONDITION_PERIODE_MIN   = 80*IR155_PERIODE_RESOLUTION,      /* 12,5 Hz*/

    IR155_UNDERVOLATGE_PERIODE_MAX      = 60*IR155_PERIODE_RESOLUTION,      /* 16,7  Hz*/
    IR155_UNDERVOLATGE_PERIODE          = 50*IR155_PERIODE_RESOLUTION,      /* 20    Hz*/
    IR155_UNDERVOLATGE_PERIODE_MIN      = 40*IR155_PERIODE_RESOLUTION,      /* 25    Hz*/

    IR155_SPEEDSTART_PERIODE_MAX        = 37*IR155_PERIODE_RESOLUTION,      /* 27    Hz*/
    IR155_SPEEDSTART_PERIODE            = 33*IR155_PERIODE_RESOLUTION,      /* 30    Hz*/
    IR155_SPEEDSTART_PERIODE_MIN        = 29*IR155_PERIODE_RESOLUTION,      /* 34,5  Hz*/

    IR155_IMDERROR_PERIODE_MAX          = 28*IR155_PERIODE_RESOLUTION,      /* 35,7  Hz*/
    IR155_IMDERROR_PERIODE              = 25*IR155_PERIODE_RESOLUTION,      /* 40    Hz*/
    IR155_IMDERROR_PERIODE_MIN          = 23*IR155_PERIODE_RESOLUTION,      /* 43,5  Hz*/

    IR155_GROUNDERROR_PERIODE_MAX       = 22*IR155_PERIODE_RESOLUTION,      /* 45,5  Hz*/
    IR155_GROUNDERROR_PERIODE           = 20*IR155_PERIODE_RESOLUTION,      /* 50    Hz*/
    IR155_GROUNDERROR_PERIODE_MIN       = 17*IR155_PERIODE_RESOLUTION,      /* 58,8  Hz*/
} IR155_SIGPERIODE_e;


/**
 * symbolic names for the different operating modes Bender Isometer.
 * Defined through the frequency of the measurement signal.
 * @ingroup ISO
 */
typedef enum {
    IR155_NORMAL_MODE       = 0,        /* */
    IR155_SPEEDSTART_MODE   = 1,        /* */
    IR155_UNDERVOLATGE_MODE = 2,        /* */
    IR155_IMDERROR_MODE     = 3,        /* */
    IR155_GROUNDERROR_MODE  = 4,        /* */
    IR155_SHORT_KL31        = 5,        /* */
    IR155_SHORT_KL15        = 6,        /* */
    IR155_UNDEFINED_FRQMAX  = 7,        /* illegal frequency detected*/
    IR155_DCM_CORRUPT       = 8,        /* corrupt signal measurement (e.g. T_on > T_periode,)*/
    IR155_DCM_NOSIGNAL      = 9,        /* no signal (e.g. if 100% -> wire break, if 0% -> shortcut to GND */
    IR155_UNKNOWN           = 15,       /* */
}IR155_SIGMODE_e;


/**
 * symbolic names for the different operating states Bender Isometer.
 * Defined through the duty cycle of the measurement signal.
 * @ingroup ISO
 */
typedef enum {
    IR155_RESIST_MEAS_GOOD      = 0,        /* valid normal measurement available and ok*/
    IR155_RESIST_ESTIM_GOOD     = 1,        /* SPEEDSTART estimation ok */
    IR155_RESIST_MEAS_BAD       = 2,        /* valid normal measurement available and nok*/
    IR155_RESIST_ESTIM_BAD      = 3,        /* SPEEDSTART estimation nok */
    IR155_RESIST_ESTIM_UNKNOWN  = 4,        /* SPEEDSTART estimation unknown */
    IR155_RESIST_MEAS_UNKNOWN   = 5,        /* valid normal measurement available but unknown */
    IR155_GROUND_ERROR          = 6,        /* */
    IR155_IMD_ERROR             = 7,        /* */
    IR155_STATE_UNDEFINED       = 8,        /* */
    IR155_SIGNALSHORT_KL15      = 9,        /* */
    IR155_SIGNALSHORT_KL31      = 10,       /* */
    IR155_MEAS_NOT_VALID        = 11,       /* Measurement results are not valid*/
    IR155_TODO_2                = 12,       /* */
    IR155_TODO_3                = 13,       /* */
    IR155_TODO_4                = 14,       /* */
    IR155_UNINITIALIZED         = 15,       /* */
}IR155_STATE_e;

/**
 * type definition for structure of insulation measurement
 *  Active and period timer ticks of duty cycle signal,
 *  resistance in [kOhm],
 *  duty cycle in [percentage],
 *  pinstate of OKHS pin,
 *  operating mode,
 *  operating state
 * @ingroup ISO
 */
typedef struct {
    TIM_DutyCycleType_s sigICU;
    uint32_t resistance;
    uint8_t dutycycle;
    IO_PIN_STATE_e OKHS_state;
    IR155_SIGMODE_e mode : 4;
    IR155_STATE_e state  : 4;
} IR155_MEASUREMENT_s;

/**
 * type definition for structure when debugging
 * insulation measurement values,
 * timestamp in [ms]
 * @ingroup ISO
 */
typedef struct {
    IR155_MEASUREMENT_s ir155_dc_Meas;
    uint32_t timestamp_ms;
} IR155_MEASUREMENT_HISTORY_s;

/**
 * type definition for structure when debugging
 * operating state,
 * measured insulation resistance,
 * pinstate of OKHS pin,
 * previous operating state,
 * previous measured insulation resistance,
 * previous pinstate of OKHS pin
 * @ingroup ISO
 */
typedef struct {
    IR155_STATE_e   state : 4;
    uint16_t        resistance : 3;
    uint16_t        OKHS_state : 1;
    IR155_STATE_e   state_old : 4;
    uint16_t        resistance_old : 3;
    uint16_t        OKHS_State_old : 1;
} IR155_INSULATION_s;


/*================== Constant and Variable Definitions ====================*/


/*================== Function Prototypes ==================================*/
/**
 * @brief Software initialization of Timer-modul
 * @param cycleTime     cyclic call time of IR155_MeasureResistance function
 */
extern void IR155_Init(uint8_t cycleTime);

/**
 * @brief Software DeInitalization of Timer-modul
 */
extern void IR155_DeInit(void);

/**
 * @brief Interface function which delivers the actual signal measurement (duty cyle) and evaluation.
 *        Use of intervals because of measuring and signal inaccuracy. The evaluated results are
 *        finally written in the database.
 * @param state             pointer to write measurement state into
 * @param resistance        pointer to write measured resistance into
 * @param ohks_state        pointer to write OHKS pin state into
 *
 * @return E_OK if no error occurred, otherwise E_NOT_OK
 */
extern STD_RETURN_TYPE_e IR155_MeasureResistance(IR155_STATE_e* state, uint32_t* resistance, IO_PIN_STATE_e* ohks_state);

/*================== Function Implementations =============================*/

#endif /* IR155_H_ */

isoguard_cfg.c

/**
 *
 * @copyright &copy; 2010 - 2020, 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:
 *
 * &Prime;This product uses parts of foxBMS&reg;&Prime;
 *
 * &Prime;This product includes parts of foxBMS&reg;&Prime;
 *
 * &Prime;This product is derived from foxBMS&reg;&Prime;
 *
 */

/**
 * @file    isoguard_cfg.c
 * @author  foxBMS Team
 * @date    08.12.2015 (date of creation)
 * @ingroup DRIVERS_CONF
 * @prefix  ISO
 *
 * @brief   Configuration for the isolation monitoring.
 *
 * Configuration source file of isoguard module
 */

/*================== Includes =============================================*/
#include "isoguard_cfg.h"

/*================== Macros and Definitions ===============================*/

/*================== Constant and Variable Definitions ====================*/

/*================== Function Prototypes ==================================*/

/*================== Function Implementations =============================*/

isoguard_cfg.h

/**
 *
 * @copyright &copy; 2010 - 2020, 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:
 *
 * &Prime;This product uses parts of foxBMS&reg;&Prime;
 *
 * &Prime;This product includes parts of foxBMS&reg;&Prime;
 *
 * &Prime;This product is derived from foxBMS&reg;&Prime;
 *
 */

/**
 * @file    isoguard_cfg.h
 * @author  foxBMS Team
 * @date    08.12.2015 (date of creation)
 * @ingroup DRIVERS_CONF
 * @prefix  ISO
 *
 * @brief   Headers for the configuration for the isolation monitoring.
 *
 * Configuration header file for isguard module
 */

#ifndef ISOGUARD_CFG_H_
#define ISOGUARD_CFG_H_

/*================== Includes =============================================*/
#include "general.h"

/*================== Macros and Definitions ===============================*/

/**
 * @ingroup CONFIG_ISOGUARD
 * Enable/Disable switch for the isoguard module
 * \par Type:
 * toggle
 * \par Default:
 * True
*/

/**
 * Enable/Disable switch for the isoguard module
 */
#define ISO_ISOGUARD_ENABLE

/**
 * @ingroup CONFIG_ISOGUARD
 * Periodic calling time of isoguard measurement. Specifies the hysteresis
 * for valid measurement values after startup or reset
 * \par Type:
 * int
 * \par Unit:
 * ms
 * \par Range:
 * 100 < x
 * \par Default:
 * 200
*/

/**
 * isoguard call cycle time
 */
#define ISO_CYCLE_TIME              200

/**
 * @ingroup CONFIG_ISOGUARD
 * Resistance threshold in kOhm to differentiate of ISOIR_RESIST_MEAS_GOOD and
 * ISOIR_RESIST_MEAS_BAD in NORMAL_MODE within duty cycle of 10%..90%
 * \par Type:
 * int
 * \par Unit:
 * kOhm
 * \par Range:
 * 100 < x
 * \par Default:
 * 400
*/

/**
 * Resistance threshold in kOhm to differentiate of ISOIR_RESIST_MEAS_GOOD and
 * ISOIR_RESIST_MEAS_BAD in NORMAL_MODE within duty cycle of 10%..90%
 */
#define ISO_RESISTANCE_THRESHOLD_kOhm    400

/*================== Constant and Variable Definitions ====================*/
typedef enum {
    ISO_STATE_UNINITIALIZED = 0,
    ISO_STATE_INITIALIZED   = 1,
} ISO_INIT_STATE_e;

/*================== Function Prototypes ==================================*/

/*================== Function Implementations =============================*/

#endif /* ISOGUARD_CFG_H_ */