nvramhandler.c

/**
 *
 * @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    nvramhandler.c
 * @author  foxBMS Team
 * @date    17.09.2018 (date of creation)
 * @ingroup ENGINE
 * @prefix  NVRAM
 *
 * @brief   datahandler implementation to update nvram
 *
 */

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

#include "os.h"

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

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

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

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

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

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

void NVRAM_dataHandlerInit(void) {

    /* Reset last update time */
    for (uint8_t i = 0; i < nvram_number_of_blocks; i++) {
        nvram_dataHandlerBlocks[i].lastUpdate = 0;
    }
}


void NVRAM_dataHandler(void) {

    static float timestamp = 0;
    STD_RETURN_TYPE_e retval = E_NOT_OK;

    /* Get new OS timestamp */
    timestamp = (float) OS_getOSSysTick();

    for (uint8_t i = 0; i < nvram_number_of_blocks; i++) {

        /* Check if cyclic nvram block needs to be updated */
        if (nvram_dataHandlerBlocks[i].mode == NVRAM_Cyclic) {
            /* If passed time > update cycle time: -> update channel OR additional asynchronous request has been made */
            if ((timestamp - (nvram_dataHandlerBlocks[i].lastUpdate + nvram_dataHandlerBlocks[i].phase_ms)) >
            nvram_dataHandlerBlocks[i].updateCycleTime_ms ||
            nvram_dataHandlerBlocks[i].state == NVRAM_write) {
                /* Update nvram block */

                if (nvram_dataHandlerBlocks[i].funcWR != NULL_PTR) {
                    retval = nvram_dataHandlerBlocks[i].funcWR();

                    if (retval == E_OK) {
                        /* Write request successful: set to wait state again */
                        nvram_dataHandlerBlocks[i].lastUpdate = timestamp;
                        nvram_dataHandlerBlocks[i].state = NVRAM_wait;
                    } else {
                        /* Try again next NVRAM_dataHandler() call */
                        ;
                    }
                } else {
                    /* Invalid pointer access -> do nothing */
                    nvram_dataHandlerBlocks[i].state = NVRAM_wait;
                }
            }
        } else if (nvram_dataHandlerBlocks[i].mode == NVRAM_Triggered) {
            /* Check if triggered nvram block needs to be updated */
            if (nvram_dataHandlerBlocks[i].state == NVRAM_write) {

                /* Update nvram block */
                if (nvram_dataHandlerBlocks[i].funcWR != NULL_PTR) {
                    retval = nvram_dataHandlerBlocks[i].funcWR();
                    if (retval == E_OK) {
                        /* Write request successful: set to wait state again */
                        nvram_dataHandlerBlocks[i].lastUpdate = timestamp;
                        nvram_dataHandlerBlocks[i].state = NVRAM_wait;
                    } else {
                        /* Try again next NVRAM_dataHandler() call */
                        ;
                    }
                } else {
                    /* Invalid pointer access -> do nothing */
                    nvram_dataHandlerBlocks[i].state = NVRAM_wait;
                }
            }
        }
        else if (nvram_dataHandlerBlocks[i].state == NVRAM_read) {
            /* Check if read is requested */

            /* Read nvram block */
            if (nvram_dataHandlerBlocks[i].funcRD != NULL_PTR) {
                retval = nvram_dataHandlerBlocks[i].funcRD();
                if (retval == E_OK) {
                    /* Read request successful: set to wait state again */
                    nvram_dataHandlerBlocks[i].state = NVRAM_wait;
                } else {
                    /* Try again next NVRAM_dataHandler() call */
                    ;
                }
            } else {
                /* Invalid pointer access -> do nothing */
                nvram_dataHandlerBlocks[i].state = NVRAM_wait;
            }
        }
    }
}


void NVRAM_setWriteRequest(NVRAM_BLOCK_ID_TYPE_e blockID) {
    if (blockID < nvram_number_of_blocks) {
        nvram_dataHandlerBlocks[blockID].state = NVRAM_write;
    }
}

void NVRAM_setReadRequest(NVRAM_BLOCK_ID_TYPE_e blockID) {
    if (blockID < nvram_number_of_blocks) {
        nvram_dataHandlerBlocks[blockID].state = NVRAM_read;
    }
}

nvramhandler.h

/**
 *
 * @copyright &copy; 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:
 *
 * &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    datahandler.h
 * @author  foxBMS Team
 * @date    17.09.2018 (date of creation)
 * @ingroup ENGINE
 * @prefix  DH_
 *
 * @brief   header file for data handler
 *
 */

#ifndef NVRAMHANDLER_H_
#define NVRAMHANDLER_H_

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

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

/*================== Extern Constant and Variable Declarations ==============*/

/*================== Extern Function Prototypes =============================*/
extern void NVRAM_dataHandlerInit(void);
extern void NVRAM_dataHandler(void);
extern void NVRAM_setWriteRequest(NVRAM_BLOCK_ID_TYPE_e blockID);
extern void NVRAM_setReadRequest(NVRAM_BLOCK_ID_TYPE_e blockID);

#endif /* NVRAMHANDLER_H_ */

nvramhandler_cfg.c (primary)

/**
 *
 * @copyright &copy; 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:
 *
 * &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    nvramhandler_cfg.c
 * @author  foxBMS Team
 * @date    17.09.2018 (date of creation)
 * @ingroup ENGINE_CONF
 * @prefix  NVRAM
 *
 * @brief   Datahandler configuration
 *
 * Configuration of datahandler module
 *
 */

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

#include "eepr.h"
#include "mcu.h"
#include "rtc.h"


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


/*================== Constant and Variable Definitions ====================*/
#ifdef BKP_SRAM_ENABLE
NVRAM_CH_NVSOC_s MEM_BKP_SRAM bkpsram_nvsoc;
NVRRAM_CH_CONT_COUNT_s MEM_BKP_SRAM bkpsram_contactors_count;
NVRAM_CH_OP_HOURS_s MEM_BKP_SRAM bkpsram_operating_hours;
NVRAM_OPERATING_HOURS_s MEM_BKP_SRAM bkpsram_op_hours;
#else
NVRAM_CH_NVSOC_s bkpsram_nvsoc;
NVRRAM_CH_CONT_COUNT_s bkpsram_contactors_count;
NVRAM_CH_OP_HOURS_s bkpsram_operating_hours;
NVRAM_OPERATING_HOURS_s bkpsram_op_hours;
#endif

NVRAM_BLOCK_s nvram_dataHandlerBlocks[] = {
        { NVRAM_wait, 0, NVRAM_Cyclic, 30000, 100, &NVM_operatingHoursUpdateRAM, &NVM_operatingHoursUpdateNVRAM },
        { NVRAM_wait, 0, NVRAM_Cyclic, 60000, 1000, &NVM_socUpdateRAM, &NVM_socUpdateNVRAM },
        { NVRAM_wait, 0, NVRAM_Triggered, 0, 0, &NVM_contactorcountUpdateRAM, &NVM_contactorcountUpdateNVRAM },
};

const uint16_t nvram_number_of_blocks = sizeof(nvram_dataHandlerBlocks)/sizeof(nvram_dataHandlerBlocks[0]);

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

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

STD_RETURN_TYPE_e NVM_setSOC(SOX_SOC_s* ptr) {

    STD_RETURN_TYPE_e retval = E_OK;

    if (ptr != NULL_PTR) {
        uint32_t interrupt_status = 0;

        /* Disable interrupts */
        interrupt_status = MCU_DisableINT();

        bkpsram_nvsoc.data = *ptr;
        bkpsram_nvsoc.previous_timestamp = bkpsram_nvsoc.timestamp;
        bkpsram_nvsoc.timestamp = RTC_getUnixTime();
        /* calculate checksum*/
        bkpsram_nvsoc.checksum = EEPR_CalcChecksum((uint8_t*)&bkpsram_nvsoc, sizeof(bkpsram_nvsoc) - 4);

        /* Enable interrupts */
        MCU_RestoreINT(interrupt_status);
    } else {
        retval = E_NOT_OK;
    }

    return retval;
}


STD_RETURN_TYPE_e NVM_getSOC(SOX_SOC_s *dest_ptr) {
    STD_RETURN_TYPE_e ret_val;

    if(EEPR_CalcChecksum((uint8_t*)&bkpsram_nvsoc, sizeof(bkpsram_nvsoc)-4) == bkpsram_nvsoc.checksum){
        //data valid
        *dest_ptr = bkpsram_nvsoc.data;
        ret_val = E_OK;
    } else {
        ret_val = E_NOT_OK;
    }
    return ret_val;
}


STD_RETURN_TYPE_e NVM_Set_contactorcnt(DIAG_CONTACTOR_s *ptr) {

    STD_RETURN_TYPE_e retval = E_OK;

    if (ptr != NULL_PTR) {
        uint32_t interrupt_status = 0;

        /* Disable interrupts */
        interrupt_status = MCU_DisableINT();

        /* update bkpsram values */
        //@FIXME: check pointer (nullpointer)
        bkpsram_contactors_count.data = *ptr;

        bkpsram_contactors_count.previous_timestamp = bkpsram_contactors_count.timestamp;
        bkpsram_contactors_count.timestamp = RTC_getUnixTime();
        /* calculate checksum*/
        bkpsram_contactors_count.checksum = EEPR_CalcChecksum((uint8_t*)&bkpsram_contactors_count, sizeof(bkpsram_contactors_count)-4);

        /* Enable interrupts */
        MCU_RestoreINT(interrupt_status);
    } else {
        retval = E_NOT_OK;
    }

    return retval;
}


STD_RETURN_TYPE_e NVM_Get_contactorcnt(DIAG_CONTACTOR_s *dest_ptr) {
    STD_RETURN_TYPE_e retval;

    if(EEPR_CalcChecksum((uint8_t*)&bkpsram_contactors_count, sizeof(bkpsram_contactors_count)-4) == bkpsram_contactors_count.checksum){
        //data valid
        //@FIXME: check pointer (nullpointer)
        *dest_ptr = bkpsram_contactors_count.data;
        retval = E_OK;
    } else {
        //data invalid
        retval = E_NOT_OK;
    }
    return retval;

}

STD_RETURN_TYPE_e NVM_setOperatingHours(NVRAM_OPERATING_HOURS_s *timer) {

    STD_RETURN_TYPE_e retval = E_OK;

    if (timer != NULL_PTR) {
        if(++timer->Timer_1ms > 9 ) {
            // 10ms
            timer->Timer_1ms = 0;

            if(++timer->Timer_10ms > 9) {
            // 100ms
                timer->Timer_10ms = 0;

                if(++timer->Timer_100ms > 9) {
                // 1s
                    timer->Timer_100ms = 0;

                    if(++timer->Timer_sec > 59) {
                    // 1min
                        timer->Timer_sec = 0;

                        if(++timer->Timer_min > 59) {
                        // 1h
                            timer->Timer_min=0;

                            if(++timer->Timer_h > 23) {
                            // 1d
                                timer->Timer_h=0;
                                ++timer->Timer_d;
                            }
                        }
                    }
                }
            }
        }
    } else {
        retval = E_NOT_OK;
    }
    return retval;
}


STD_RETURN_TYPE_e NVM_getOperatingHours(NVRAM_OPERATING_HOURS_s *dest_ptr) {
    STD_RETURN_TYPE_e ret_val;

    if(EEPR_CalcChecksum((uint8_t*)&bkpsram_operating_hours, sizeof(bkpsram_operating_hours)-4) == bkpsram_operating_hours.checksum){
        //data valid
        //@FIXME: check pointer (nullpointer)
        *dest_ptr = bkpsram_operating_hours.data;
        ret_val = E_OK;
    } else {
        //data invalid
        ret_val = E_NOT_OK;
    }
    return ret_val;
}


STD_RETURN_TYPE_e NVM_operatingHoursUpdateNVRAM(void) {

    STD_RETURN_TYPE_e retval = E_OK;

    uint32_t interrupt_status = 0;

    /* timestamp calculation done here because trigger function is called
     * in engine 1ms task. To reduce cpuload only calculate timestamps and
     * checksum before writing to NVRAM
     */
    /* Disable interrupts */
    interrupt_status = MCU_DisableINT();

    /* Set data value */
    bkpsram_operating_hours.data = bkpsram_op_hours;

    /* Set timestamp bkpsram values */
    bkpsram_operating_hours.previous_timestamp = bkpsram_operating_hours.timestamp;
    bkpsram_operating_hours.timestamp = RTC_getUnixTime();

    /* calculate checksum*/
    bkpsram_operating_hours.checksum = EEPR_CalcChecksum((uint8_t *)(&bkpsram_operating_hours),sizeof(bkpsram_operating_hours) - 4);

    /* Enable interrupts */
    MCU_RestoreINT(interrupt_status);

    EEPR_SetChDirtyFlag(EEPR_CH_OPERATING_HOURS);

    return retval;
}


STD_RETURN_TYPE_e NVM_operatingHoursUpdateRAM(void) {
    STD_RETURN_TYPE_e retval = E_OK;
    EEPR_SetChReadReqFlag(EEPR_CH_OPERATING_HOURS);
    return retval;
}


STD_RETURN_TYPE_e NVM_socUpdateNVRAM(void) {
    STD_RETURN_TYPE_e retval = E_OK;
    EEPR_SetChDirtyFlag(EEPR_CH_NVSOC);
    return retval;
}


STD_RETURN_TYPE_e NVM_socUpdateRAM(void) {
    STD_RETURN_TYPE_e retval = E_OK;
    EEPR_SetChReadReqFlag(EEPR_CH_NVSOC);
    return retval;
}


STD_RETURN_TYPE_e NVM_contactorcountUpdateNVRAM(void) {
    STD_RETURN_TYPE_e retval = E_OK;
    EEPR_SetChDirtyFlag(EEPR_CH_CONTACTOR);
    return retval;
}


STD_RETURN_TYPE_e NVM_contactorcountUpdateRAM(void) {
    STD_RETURN_TYPE_e retval = E_OK;
    EEPR_SetChReadReqFlag(EEPR_CH_CONTACTOR);
    return retval;
}

nvramhandler_cfg.h (primary)

/**
 *
 * @copyright &copy; 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:
 *
 * &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    nvramhandler_cfg.h
 * @author  foxBMS Team
 * @date    17.09.2018 (date of creation)
 * @ingroup ENGINE_CONF
 * @prefix  NVRAM
 *
 * @brief   Datahandler configuration header
 *
 * Provides interfaces to datahandler configuration
 *
 */

#ifndef NVRAMHANDLER_CFG_H_
#define NVRAMHANDLER_CFG_H_

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

#include "nvram_cfg.h"

/*================== Macros and Definitions ===============================*/
typedef enum NVRAM_UpdateType {
    NVRAM_Cyclic,
    NVRAM_Triggered,
} NVRAM_UpdateType_e;

typedef enum NVRAM_state {
    NVRAM_wait    = 0,
    NVRAM_write   = 1,
    NVRAM_read    = 2,
} NVRAM_state_e;

typedef struct NVRAM_BLOCK {
    NVRAM_state_e state;                /*!< state of datahandler block          */
    uint32_t lastUpdate;                /*!< time of last nvram update           */
    NVRAM_UpdateType_e mode;            /*!< update mode (cyclic or triggered)   */
    uint32_t updateCycleTime_ms;        /*!< cycle time of algorithm             */
    uint32_t phase_ms;                  /*!< start time when executing algorithm */
    STD_RETURN_TYPE_e (*funcRD)(void);  /*!< read callback function              */
    STD_RETURN_TYPE_e (*funcWR)(void);  /*!< write callback function             */
} NVRAM_BLOCK_s;

/**
 * @brief data block identification number
 */
typedef enum {
    NVRAM_BLOCK_00 =  0,
    NVRAM_BLOCK_01 =  1,
    NVRAM_BLOCK_02 =  2,
    NVRAM_BLOCK_03 =  3,
    NVRAM_BLOCK_04 =  4,
    NVRAM_BLOCK_05 =  5,
    NVRAM_BLOCK_06 =  6,
    NVRAM_BLOCK_07 =  7,
    NVRAM_BLOCK_08 =  8,
    NVRAM_BLOCK_09 =  9,
    NVRAM_BLOCK_10 = 10,
    NVRAM_BLOCK_11 = 11,
    NVRAM_BLOCK_12 = 12,
    NVRAM_BLOCK_13 = 13,
    NVRAM_BLOCK_14 = 14,
    NVRAM_BLOCK_15 = 15,
    NVRAM_BLOCK_16 = 16,
} NVRAM_BLOCK_ID_TYPE_e;

/*================== Macros and Definitions [USER CONFIGURATION] =============*/
#define NVRAM_BLOCK_ID_OPERATING_HOURS         NVRAM_BLOCK_00
#define NVRAM_BLOCK_ID_CELLTEMPERATURE         NVRAM_BLOCK_01
#define NVRAM_BLOCK_ID_CONT_COUNTER            NVRAM_BLOCK_02

/*================== Constant and Variable Definitions ====================*/
/*
 * Array with pointer to the different algorithms
 */
extern NVRAM_BLOCK_s nvram_dataHandlerBlocks[];

/**
 * number of nvram datablocks
 */
extern const uint16_t nvram_number_of_blocks;

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

/** Interface functions writing to/ reading from non-volatile memory (NVRAM) */

/**
 * @brief   saves operating hours data into the non-volatile memory (NVM)
 *
 * @return  E_OK if successful, otherwise E_NOT_OK
 */
extern STD_RETURN_TYPE_e NVM_operatingHoursUpdateNVRAM(void);

/**
 * @brief   reads operating hours data from the non-volatile and writes to the volatile memory (RAM)
 *
 * @return  E_OK if successful, otherwise E_NOT_OK
 */
extern STD_RETURN_TYPE_e NVM_operatingHoursUpdateRAM(void);

/**
 * @brief   saves SOC data into the non-volatile memory (NVM)
 *
 * @return  E_OK if successful, otherwise E_NOT_OK
 */
extern STD_RETURN_TYPE_e NVM_socUpdateNVRAM(void);

/**
 * @brief   reads SOC data from the non-volatile and writes to the volatile memory (RAM)
 *
 * @return  E_OK if successful, otherwise E_NOT_OK
 */
extern STD_RETURN_TYPE_e NVM_socUpdateRAM(void);

/**
 * @brief   saves contactor counting data into the non-volatile memory (NVM)
 *
 * @return  E_OK if successful, otherwise E_NOT_OK
 */
extern STD_RETURN_TYPE_e NVM_contactorcountUpdateNVRAM(void);

/**
 * @brief   reads contactor counting data from the non-volatile and writes to the volatile memory (RAM)
 *
 * @return  E_OK if successful, otherwise E_NOT_OK
 */
extern STD_RETURN_TYPE_e NVM_contactorcountUpdateRAM(void);


/** Interface functions writting to/ reading from volatile memory (RAM/BKPSRAM) */

/**
 * @brief  Gets the operating hours from the volatile memory (RAM)
 *
 * @param  ptr pointer to destination buffer where the stored operating hours are copied
 * @return STD_RETURN_TYPE_e
*/
extern STD_RETURN_TYPE_e NVM_getOperatingHours(NVRAM_OPERATING_HOURS_s *dest_ptr);

/**
 * @brief  Increments the volatile memory (RAM)
 *
*/
extern STD_RETURN_TYPE_e NVM_setOperatingHours(NVRAM_OPERATING_HOURS_s *timer);

/**
 * @brief  Gets the number of opening/closing events of the contactors saved in the non-volatile RAM
 *
 * @param  ptr pointer where the contactor event data should be stored to
 *
 * @return E_OK if successful, otherwise E_NOT_OK
*/
extern STD_RETURN_TYPE_e NVM_Get_contactorcnt(DIAG_CONTACTOR_s *ptr);

/**
 * @brief  Sets the number of opening/closing events of the contactors saved in the non-volatile RAM
 *
 * @param  ptr pointer where the contactor events are stored
 *
 * @return E_OK if successful, otherwise E_NOT_OK
*/
extern STD_RETURN_TYPE_e NVM_Set_contactorcnt(DIAG_CONTACTOR_s *ptr);

/**
 * @brief  Gets the SOC data saved in the non-volatile RAM
 *
 * @return E_OK if successful, otherwise E_NOT_OK
*/
extern STD_RETURN_TYPE_e NVM_getSOC(SOX_SOC_s *dest_ptr);

/**
 * @brief  Sets the SOC data saved in the non-volatile RAM
 *
 * @param  ptr pointer where the soc data is stored
 *
 * @return E_OK if successful, otherwise E_NOT_OK
*/
extern STD_RETURN_TYPE_e NVM_setSOC(SOX_SOC_s* ptr);

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

#endif /* NVRAMHANDLER_CFG_H_ */