database.c (common)

/**
 *
 * @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    database.c
 * @author  foxBMS Team
 * @date    18.08.2015 (date of creation)
 * @ingroup ENGINE
 * @prefix  DATA
 *
 * @brief   Database module implementation
 *
 * Implementation of database module
 */

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

#include "diag.h"
#include <string.h>

/*================== Macros and Definitions ===============================*/
/**
 * Maximum queue timeout time in milliseconds
 */
#define DATA_QUEUE_TIMEOUT_MS   10

/*================== Constant and Variable Definitions ====================*/
// FIXME Some uninitialized variables
static DATA_BLOCK_ACCESS_s data_block_access[DATA_MAX_BLOCK_NR];
static SemaphoreHandle_t data_base_mutex[DATA_MAX_BLOCK_NR];
QueueHandle_t data_queue;

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

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

/*================== Public functions =====================================*/
void DATA_Init(void) {
    if(sizeof(data_base_dev) == 0) {
        // todo fatal error!

        while (1) {
            ;
        }
    }

    // FIXME What is mymessage structures?
    /* Create a queue capable of containing 10 pointers to mymessage structures.
//    These should be passed by pointer as they contain a lot of data. */
//    data_queueID = xQueueCreate( devptr->nr_of_blockheader, sizeof( DATA_QUEUE_MESSAGE_s) );    // FIXME number of queues=1 should be enough
//
//    if(data_queueID  ==  NULL_PTR) {
//        // Failed to create the queue
//        ;            // @ TODO Error Handling
//    }

    /* Iterate over database and set respective read/write pointer for each database entry */
    for(uint16_t i = 0; i < data_base_dev.nr_of_blockheader; i++) {

        /* Set write pointer to database entry */
        data_block_access[i].WRptr = (void*)*(uint32_t*)(data_base_dev.blockheaderptr + i);

        /* Set read pointer */
        if((data_base_dev.blockheaderptr + i)->buffertype  ==  DOUBLE_BUFFERING) {

            /* If database entry is double buffered -> set read pointer to
             * second section. After writing first database entry, pointer are
             * swapped and read pointer then points to written entry. */
            data_block_access[i].RDptr = (void*)((uint32_t)data_block_access[i].WRptr + (data_base_dev.blockheaderptr + i)->datalength);

        } else {
            /* Single buffering -> read = write pointer */
            data_block_access[i].RDptr = data_block_access[i].WRptr;
        }
        /* Create a mutex for each database entry */
        data_base_mutex[i] = xSemaphoreCreateMutex();
    }

    /* Create queue to transfer data to/from database */

    /* Create a queue capable of containing a pointer of type DATA_QUEUE_MESSAGE_s
    Data of Messages are passed by pointer as they contain a lot of data. */
    data_queue = xQueueCreate( 1, sizeof( DATA_QUEUE_MESSAGE_s) );

    if (data_queue == NULL_PTR) {
        // Failed to create the queue
        // @ TODO Error Handling
        while (1) {
            ;
        }
    }
}


void DB_WriteBlock(void *dataptrfromSender, DATA_BLOCK_ID_TYPE_e  blockID) {

    // dataptrfromSender is a pointer to data of caller function
    // dataptr_toptr_fromSender is a pointer to this pointer
    // this is used for passing message variable by reference
    // note: xQueueSend() always takes message variable by value
    DATA_QUEUE_MESSAGE_s data_send_msg;
    TickType_t queuetimeout;

    if( vPortCheckCriticalSection() ) {
        configASSERT(0);
    }

    queuetimeout = DATA_QUEUE_TIMEOUT_MS / portTICK_RATE_MS;
    if (queuetimeout == 0) {
        queuetimeout = 1;
    }

    // prepare send message with attributes of data block
    data_send_msg.blockID = blockID;
    data_send_msg.value.voidptr = dataptrfromSender;
    data_send_msg.accesstype = WRITE_ACCESS;
    // Send a pointer to a message object and
    // maximum block time: queuetimeout
    xQueueSend( data_queue, (void *) &data_send_msg, queuetimeout);
 }


void DATA_Task(void) {
    DATA_QUEUE_MESSAGE_s receive_msg;
    void *srcdataptr;
    void *dstdataptr;
    DATA_BLOCK_ID_TYPE_e blockID;
    DATA_BLOCK_ACCESS_TYPE_e    accesstype; /* read or write access type */
    uint16_t datalength;
    DATA_BLOCK_BUFFER_TYPE_e buffertype;

    if(data_queue != NULL_PTR) {

        if( xQueueReceive(data_queue,(&receive_msg),(TickType_t ) 1) ) {  // scan queue and wait for a message up to a maximum amount of 1ms (block time)

            // ptrrcvmessage now points to message of sender which contains data pointer and data block ID
            blockID = receive_msg.blockID;
            srcdataptr = receive_msg.value.voidptr;
            accesstype = receive_msg.accesstype;
            if((blockID < DATA_MAX_BLOCK_NR) && (srcdataptr != NULL_PTR)) {   // plausibility check
                // get entries of blockheader and write pointer
                if(accesstype == WRITE_ACCESS) {
                    // write access to data blocks
                    datalength = (data_base_dev.blockheaderptr + blockID)->datalength;
                    buffertype = (data_base_dev.blockheaderptr + blockID)->buffertype;
                    dstdataptr=data_block_access[blockID].WRptr;

                    /* Check if there any read accesses taking place (in tasks with lower priorities)*/
                    if(xSemaphoreTake(data_base_mutex[blockID], 0)  ==  TRUE) {
                        uint32_t *previousTimestampptr = NULL_PTR;
                        uint32_t *timestampptr = NULL_PTR;

                        /* Set timestamp pointer */
                        timestampptr = (uint32_t *)srcdataptr;
                        /* Set previous timestampptr */
                        previousTimestampptr = (uint32_t *)srcdataptr;
                        previousTimestampptr++;

                        /* Write previous timestamp */
                        *previousTimestampptr = *timestampptr;
                        /* Write timestamp */
                        *(uint32_t *)srcdataptr = OS_getOSSysTick();

                        memcpy(dstdataptr, srcdataptr, datalength);
                        xSemaphoreGive(data_base_mutex[blockID]);
                        if(buffertype  ==  DOUBLE_BUFFERING) {
                            /* swap the WR and RD pointers:
                               WRptr always points to buffer to be written next time and changed afterwards
                               RDptr always points to buffer to be read next time */
                            data_block_access[blockID].WRptr=data_block_access[blockID].RDptr;
                            data_block_access[blockID].RDptr=dstdataptr;
                        }
                    } else {
                        dstdataptr=data_block_access[blockID].WRptr;
                    }
                } else if(accesstype == READ_ACCESS) {
                    // Read access to data blocks
                    datalength = (data_base_dev.blockheaderptr + blockID)->datalength;
                    buffertype = (data_base_dev.blockheaderptr + blockID)->buffertype;
                    dstdataptr = srcdataptr;

                    if(buffertype  ==  DOUBLE_BUFFERING) {

                        if(xSemaphoreTake(data_base_mutex[blockID], 0)  ==  TRUE) {

                            srcdataptr = data_block_access[blockID].RDptr;
                            if(srcdataptr != NULL_PTR) {

                                memcpy(dstdataptr, srcdataptr, datalength);
                                xSemaphoreGive(data_base_mutex[blockID]);
                            }
                        }
                    } else if(buffertype  ==  SINGLE_BUFFERING) {
                            srcdataptr = data_block_access[blockID].RDptr;
                            if(srcdataptr != NULL_PTR) {
                                memcpy(dstdataptr, srcdataptr, datalength);
                            }
                    }
                } else {
                    ;
                }
            }
        }
        DIAG_SysMonNotify(DIAG_SYSMON_DATABASE_ID, 0);        // task is running, state = ok
    }
}


STD_RETURN_TYPE_e DB_ReadBlock(void *dataptrtoReceiver, DATA_BLOCK_ID_TYPE_e  blockID) {

    DATA_QUEUE_MESSAGE_s data_send_msg;
    TickType_t queuetimeout;

    if(vPortCheckCriticalSection()) {
        configASSERT(0);
    }

    queuetimeout = DATA_QUEUE_TIMEOUT_MS / portTICK_RATE_MS;
    if (queuetimeout  ==  0) {
        queuetimeout = 1;
    }

    // prepare send message with attributes of data block
    data_send_msg.blockID = blockID;
    data_send_msg.value.voidptr = dataptrtoReceiver;
    data_send_msg.accesstype = READ_ACCESS;

    // Send a pointer to a message object and
    // maximum block time: queuetimeout
    xQueueSend( data_queue, (void *) &data_send_msg, queuetimeout);

    return E_OK;
}

// FIXME not used  currently - delete?
void * DATA_GetTablePtrBeginCritical(DATA_BLOCK_ID_TYPE_e  blockID) {
    //FIXME block with semaphore
    return data_block_access[blockID].RDptr;
}

/*================== Static functions =====================================*/

database.h (common)

/**
 *
 * @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    database.h
 * @author  foxBMS Team
 * @date    18.08.2015 (date of creation)
 * @ingroup ENGINE
 * @prefix  DATA
 *
 * @brief   Database module header
 *
 * Provides interfaces to database module
 *
 */

#ifndef DATABASE_H_
#define DATABASE_H_

/*================== Includes =============================================*/
#include "database_cfg.h"
#include "os.h"


/*================== Macros and Definitions ===============================*/
// FIXME doxygen comments
typedef struct {
    // FIXME what is the intention of this union? isn't it dangerous if someone expects a pointer to and accesses via .u32ptr, but there is a value stored in value?
    union {
        uint32_t                u32value;    /*  reference by uint32_t value   */
        uint32_t                *u32ptr;    /*  reference by uint32_t pointer */
        void                    *voidptr;    /*  reference by general pointer */
    } value;
    DATA_BLOCK_ID_TYPE_e        blockID;    /* definition of used message data type */
    DATA_BLOCK_ACCESS_TYPE_e    accesstype; /* read or write access type */
} DATA_QUEUE_MESSAGE_s;


typedef struct {
    void                           *RDptr;
    void                           *WRptr;
    DATA_BLOCK_BUFFER_TYPE_e  nr_of_buffer;    // todo really needed?
} DATA_BLOCK_ACCESS_s;

/*================== Constant and Variable Definitions ====================*/
extern QueueHandle_t data_queue;


/*================== Function Prototypes ==================================*/
/**
 * @brief   Initialization of database manager
 */
extern void DATA_Init(void);

/**
 * @brief   Stores a datablock in database
 * @param   blockID (type: DATA_BLOCK_ID_TYPE_e)
 * @param   dataptrfromSender (type: void *)
 */
extern void DB_WriteBlock(void *dataptrfromSender, DATA_BLOCK_ID_TYPE_e  blockID);

/**
 * @brief   Reads a datablock in database by value
 * @param   blockID (type: DATA_BLOCK_ID_TYPE_e)
 * @param   dataptrtoReceiver (type: void *)
 * @return  STD_RETURN_TYPE_e
 */
extern STD_RETURN_TYPE_e DB_ReadBlock(void *dataptrtoReceiver, DATA_BLOCK_ID_TYPE_e  blockID);

 /**
 * @brief   Gets a pointer to datablock in database ()
 * @param   blockID (type: DATA_BLOCK_ID_TYPE_e)
 * @return  void* RDptr
  */
extern void * DATA_GetTablePtrBeginCritical(DATA_BLOCK_ID_TYPE_e  blockID);

 /**
  * @brief   trigger of database manager
  */
 extern void DATA_Task(void);

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


#endif /* DATABASE_H_ */

database_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    database_cfg.c
 * @author  foxBMS Team
 * @date    18.08.2015 (date of creation)
 * @ingroup ENGINE_CONF
 * @prefix  DATA
 *
 * @brief   Database configuration
 *
 * Configuration of database module
 *
 */

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

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

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

/**
 * data block: cell voltage
 */
DATA_BLOCK_CELLVOLTAGE_s data_block_cellvoltage[DOUBLE_BUFFERING];

/**
 * data block: cell temperature
 */
DATA_BLOCK_CELLTEMPERATURE_s data_block_celltemperature[DOUBLE_BUFFERING];

/**
 * data block: sox
 */
DATA_BLOCK_SOX_s data_block_sox[SINGLE_BUFFERING];

/**
 * data block: sof
 */
DATA_BLOCK_SOF_s data_block_sof[SINGLE_BUFFERING];

/**
 * data block: balancing control
 */
DATA_BLOCK_BALANCING_CONTROL_s data_block_control_balancing[DOUBLE_BUFFERING];

/**
 * data block: balancing feedback
 */
DATA_BLOCK_BALANCING_FEEDBACK_s data_block_feedback_balancing[DOUBLE_BUFFERING];

/**
 * data block: current measurement
 */
DATA_BLOCK_CURRENT_SENSOR_s data_block_curr_sensor[DOUBLE_BUFFERING];

/**
 * data block: ADC
 */
DATA_BLOCK_HW_INFO_s data_block_adc[SINGLE_BUFFERING];

/**
 * data block: can state request
 */
DATA_BLOCK_STATEREQUEST_s data_block_staterequest[SINGLE_BUFFERING];

/**
 * data block: LTC minimum and maximum values
 */
DATA_BLOCK_MINMAX_s data_block_minmax[DOUBLE_BUFFERING];

/**
 * data block: isometer measurement
 */
DATA_BLOCK_ISOMETER_s data_block_isometer[SINGLE_BUFFERING];

/**
 * data block: error flags
 */
DATA_BLOCK_ERRORSTATE_s data_block_errors[DOUBLE_BUFFERING];

/**
 * data block: maximum safety limit violations
 */
DATA_BLOCK_MSL_FLAG_s data_block_MSL[SINGLE_BUFFERING];

/**
 * data block: recommended safety limit violations
 */
DATA_BLOCK_RSL_FLAG_s data_block_RSL[SINGLE_BUFFERING];

/**
 * data block: maximum operating limit violations
 */
DATA_BLOCK_MOL_FLAG_s data_block_MOL[SINGLE_BUFFERING];

/**
 * data block: moving mean current and power
 */
DATA_BLOCK_MOVING_AVERAGE_s data_block_mov_average[DOUBLE_BUFFERING];

/**
 * data block: contactor feedback
 */
DATA_BLOCK_CONTFEEDBACK_s data_block_contfeedback[SINGLE_BUFFERING];

/**
 * data block: interlock feedback
 */
DATA_BLOCK_ILCKFEEDBACK_s data_block_ilckfeedback[SINGLE_BUFFERING];

/**
 * data block: slave control
 */
DATA_BLOCK_SLAVE_CONTROL_s data_block_slave_control[SINGLE_BUFFERING];

/**
 * data block: system state
 */
DATA_BLOCK_SYSTEMSTATE_s data_block_systemstate[SINGLE_BUFFERING];

/**
 * data block: open wire check
 */
DATA_BLOCK_OPENWIRE_s data_block_open_wire[DOUBLE_BUFFERING];

/**
 * data block: LTC diagnosis values
 */
DATA_BLOCK_LTC_DEVICE_PARAMETER_s data_block_ltc_diagnosis[SINGLE_BUFFERING];


/**
 * data block: LTC ADC accuracy verification
 */
DATA_BLOCK_LTC_ADC_ACCURACY_s data_block_ltc_adc_accuracy[SINGLE_BUFFERING];

/**
 * data block: LTC ADC accuracy verification
 */
DATA_BLOCK_ALLGPIOVOLTAGE_s data_block_ltc_allgpiovoltages[DOUBLE_BUFFERING];

/**
 * @brief channel configuration of database (data blocks)
 *
 * all data block managed by database are listed here (address,size,consistency type)
 *
 */
DATA_BASE_HEADER_s  data_base_header[] = {
    {
            (void*)(&data_block_cellvoltage[0]),
            sizeof(DATA_BLOCK_CELLVOLTAGE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_celltemperature[0]),
            sizeof(DATA_BLOCK_CELLTEMPERATURE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_sox[0]),
            sizeof(DATA_BLOCK_SOX_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_control_balancing[0]),
            sizeof(DATA_BLOCK_BALANCING_CONTROL_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_feedback_balancing[0]),
            sizeof(DATA_BLOCK_BALANCING_FEEDBACK_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_curr_sensor[0]),
            sizeof(DATA_BLOCK_CURRENT_SENSOR_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_adc[0]),
            sizeof(DATA_BLOCK_HW_INFO_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_staterequest[0]),
            sizeof(DATA_BLOCK_STATEREQUEST_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_minmax[0]),
            sizeof(DATA_BLOCK_MINMAX_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_isometer[0]),
            sizeof(DATA_BLOCK_ISOMETER_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_slave_control[0]),
            sizeof(DATA_BLOCK_SLAVE_CONTROL_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_open_wire[0]),
            sizeof(DATA_BLOCK_OPENWIRE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_ltc_diagnosis[0]),
            sizeof(DATA_BLOCK_LTC_DEVICE_PARAMETER_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_ltc_adc_accuracy[0]),
            sizeof(DATA_BLOCK_LTC_ADC_ACCURACY_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_errors[0]),
            sizeof(DATA_BLOCK_ERRORSTATE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_MSL[0]),
            sizeof(DATA_BLOCK_MSL_FLAG_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_RSL[0]),
            sizeof(DATA_BLOCK_RSL_FLAG_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_MOL[0]),
            sizeof(DATA_BLOCK_MOL_FLAG_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_mov_average[0]),
            sizeof(DATA_BLOCK_MOVING_AVERAGE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_contfeedback[0]),
            sizeof(DATA_BLOCK_CONTFEEDBACK_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_ilckfeedback[0]),
            sizeof(DATA_BLOCK_ILCKFEEDBACK_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_systemstate[0]),
            sizeof(DATA_BLOCK_SYSTEMSTATE_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_sof[0]),
            sizeof(DATA_BLOCK_SOF_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_ltc_allgpiovoltages[0]),
            sizeof(DATA_BLOCK_ALLGPIOVOLTAGE_s),
            DOUBLE_BUFFERING,
    },
};

/**
 * @brief device configuration of database
 *
 * all attributes of device configuration are listed here (pointer to channel list, number of channels)
 */
const DATA_BASE_HEADER_DEV_s data_base_dev = {
    .nr_of_blockheader  = sizeof(data_base_header)/sizeof(DATA_BASE_HEADER_s),    // number of blocks (and block headers)
    .blockheaderptr     = &data_base_header[0],
};

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

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

database_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    database_cfg.h
 * @author  foxBMS Team
 * @date    18.08.2015 (date of creation)
 * @ingroup ENGINE_CONF
 * @prefix  DATA
 *
 * @brief   Database configuration header
 *
 * Provides interfaces to database configuration
 *
 */

#ifndef DATABASE_CFG_H_
#define DATABASE_CFG_H_

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

#include "batterysystem_cfg.h"

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

/**
 * @brief maximum amount of data block
 *
 * this value is extendible but limitation is done due to RAM consumption and performance
 */
#define DATA_MAX_BLOCK_NR                24        /* max 24 Blocks currently supported*/

/**
 * @brief data block identification number
 */
typedef enum {
    DATA_BLOCK_00       =  0,
    DATA_BLOCK_01       =  1,
    DATA_BLOCK_02       =  2,
    DATA_BLOCK_03       =  3,
    DATA_BLOCK_04       =  4,
    DATA_BLOCK_05       =  5,
    DATA_BLOCK_06       =  6,
    DATA_BLOCK_07       =  7,
    DATA_BLOCK_08       =  8,
    DATA_BLOCK_09       =  9,
    DATA_BLOCK_10       = 10,
    DATA_BLOCK_11       = 11,
    DATA_BLOCK_12       = 12,
    DATA_BLOCK_13       = 13,
    DATA_BLOCK_14       = 14,
    DATA_BLOCK_15       = 15,
    DATA_BLOCK_16       = 16,
    DATA_BLOCK_17       = 17,
    DATA_BLOCK_18       = 18,
    DATA_BLOCK_19       = 19,
    DATA_BLOCK_20       = 20,
    DATA_BLOCK_21       = 21,
    DATA_BLOCK_22       = 22,
    DATA_BLOCK_23       = 23,
    DATA_BLOCK_MAX      = DATA_MAX_BLOCK_NR,
} DATA_BLOCK_ID_TYPE_e;


/**
 * @brief data block access types
 *
 * read or write access types
 */
typedef enum {
    WRITE_ACCESS    = 0,    /*!< write access to data block   */
    READ_ACCESS     = 1,    /*!< read access to data block   */
} DATA_BLOCK_ACCESS_TYPE_e;

/**
 * @brief data block consistency types
 *
 * recommendation: use single buffer for small data (e.g.,one variable) and less concurrent read and write accesses
 */
typedef enum {
    // Init-Sequence
    SINGLE_BUFFERING    = 1,    /*!< single buffering   */
    DOUBLE_BUFFERING    = 2,    /*!< double buffering   */
    // TRIPLEBUFFERING     = 3,    /* actually not supported*/
} DATA_BLOCK_BUFFER_TYPE_e;

/**
 * configuration struct of database channel (data block)
 */
typedef struct {
    void *blockptr;
    uint16_t datalength;
    DATA_BLOCK_BUFFER_TYPE_e buffertype;
} DATA_BASE_HEADER_s;

/**
 * configuration struct of database device
 */
typedef struct {
    uint8_t nr_of_blockheader;
    DATA_BASE_HEADER_s *blockheaderptr;
} DATA_BASE_HEADER_DEV_s;


/*================== Macros and Definitions [USER CONFIGURATION] =============*/
// FIXME comments doxygen, is comment necessary?
/*Macros and Definitions for User Configuration*/
#define     DATA_BLOCK_ID_CELLVOLTAGE                   DATA_BLOCK_00
#define     DATA_BLOCK_ID_CELLTEMPERATURE               DATA_BLOCK_01
#define     DATA_BLOCK_ID_SOX                           DATA_BLOCK_02
#define     DATA_BLOCK_ID_BALANCING_CONTROL_VALUES      DATA_BLOCK_03
#define     DATA_BLOCK_ID_BALANCING_FEEDBACK_VALUES     DATA_BLOCK_04
#define     DATA_BLOCK_ID_CURRENT_SENSOR                DATA_BLOCK_05
#define     DATA_BLOCK_ID_HW_INFO                       DATA_BLOCK_06
#define     DATA_BLOCK_ID_STATEREQUEST                  DATA_BLOCK_07
#define     DATA_BLOCK_ID_MINMAX                        DATA_BLOCK_08
#define     DATA_BLOCK_ID_ISOGUARD                      DATA_BLOCK_09
#define     DATA_BLOCK_ID_SLAVE_CONTROL                 DATA_BLOCK_10
#define     DATA_BLOCK_ID_OPEN_WIRE_CHECK               DATA_BLOCK_11
#define     DATA_BLOCK_ID_LTC_DEVICE_PARAMETER          DATA_BLOCK_12
#define     DATA_BLOCK_ID_LTC_ACCURACY                  DATA_BLOCK_13
#define     DATA_BLOCK_ID_ERRORSTATE                    DATA_BLOCK_14
#define     DATA_BLOCK_ID_MSL                           DATA_BLOCK_15
#define     DATA_BLOCK_ID_RSL                           DATA_BLOCK_16
#define     DATA_BLOCK_ID_MOL                           DATA_BLOCK_17
#define     DATA_BLOCK_ID_MOV_AVERAGE                   DATA_BLOCK_18
#define     DATA_BLOCK_ID_CONTFEEDBACK                  DATA_BLOCK_19
#define     DATA_BLOCK_ID_ILCKFEEDBACK                  DATA_BLOCK_20
#define     DATA_BLOCK_ID_SYSTEMSTATE                   DATA_BLOCK_21
#define     DATA_BLOCK_ID_SOF                           DATA_BLOCK_22
#define     DATA_BLOCK_ID_ALLGPIOVOLTAGE                DATA_BLOCK_23

/**
 * data block struct of cell voltage
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t voltage[BS_NR_OF_BAT_CELLS];       /*!< unit: mV                                   */
    uint32_t valid_voltPECs[BS_NR_OF_MODULES];  /*!< bitmask if PEC was okay. 0->ok, 1->error   */
    uint32_t sumOfCells[BS_NR_OF_MODULES];      /*!< unit: mV                                   */
    uint8_t valid_socPECs[BS_NR_OF_MODULES];   /*!< 0 -> if PEC okay; 1 -> PEC error           */
    uint8_t state;                              /*!< for future use                             */
} DATA_BLOCK_CELLVOLTAGE_s;

/**
 * data block struct of cell voltage
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t openwire[BS_NR_OF_BAT_CELLS];   /*!< 1 -> open wire, 0 -> everything ok */
    uint8_t state;                          /*!< for future use                       */
} DATA_BLOCK_OPENWIRE_s;

/**
 * data block struct of cell temperatures
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    int16_t temperature[BS_NR_OF_TEMP_SENSORS];             /*!< unit: degree Celsius                       */
    uint16_t valid_temperaturePECs[BS_NR_OF_MODULES];  /*!< bitmask if PEC was okay. 0->ok, 1->error   */
    uint8_t state;                                          /*!< for future use                             */
} DATA_BLOCK_CELLTEMPERATURE_s;

/**
 * data block struct of sox
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                 /*!< timestamp of database entry                */
    uint32_t previous_timestamp;        /*!< timestamp of last database entry           */
    float soc_mean;                     /*!< 0.0 <= soc_mean <= 100.0           */
    float soc_min;                      /*!< 0.0 <= soc_min <= 100.0            */
    float soc_max;                      /*!< 0.0 <= soc_max <= 100.0            */
    uint8_t state;                      /*!<                                    */
} DATA_BLOCK_SOX_s;


/**
 * data block struct of sof limits
 */
typedef struct {
    uint32_t timestamp;                     /*!< timestamp of database entry                        */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry                   */
    float recommended_continuous_charge;    /*!< recommended continuous operating charge current    */
    float recommended_continuous_discharge; /*!< recommended continuous operating discharge current */
    float recommended_peak_charge;          /*!< recommended peak operating charge current          */
    float recommended_peak_discharge;       /*!< recommended peak operating discharge current       */
    float continuous_charge_MOL;            /*!< charge current maximum operating level             */
    float continuous_discharge_MOL;         /*!< discharge current maximum operating level          */
    float continuous_charge_RSL;            /*!< charge current recommended safety level            */
    float continuous_discharge_RSL;         /*!< discharge current recommended safety level         */
    float continuous_charge_MSL;            /*!< charge current maximum safety level                */
    float continuous_discharge_MSL;         /*!< discharge current maximum safety level             */
} DATA_BLOCK_SOF_s;


/*  data structure declaration of DATA_BLOCK_BALANCING_CONTROL */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t balancing_state[BS_NR_OF_BAT_CELLS];    /*!< 0 means balancing is active, 0 means balancing is inactive*/
    uint32_t delta_charge[BS_NR_OF_BAT_CELLS];    /*!< Difference in Depth-of-Discharge in mAs*/
    uint8_t enable_balancing;           /*!< Switch for enabling/disabling balancing    */
    uint8_t threshold;                  /*!< balancing threshold in mV                  */
    uint8_t request;                     /*!< balancing request per CAN                 */
    uint8_t state;                      /*!< for future use                             */
} DATA_BLOCK_BALANCING_CONTROL_s;

/*  data structure declaration of DATA_BLOCK_USER_IO_CONTROL */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t io_value_out[BS_NR_OF_MODULES];   /*!< data to be written to the port expander    */
    uint8_t io_value_in[BS_NR_OF_MODULES];    /*!< data read from to the port expander        */
    uint8_t eeprom_value_write[BS_NR_OF_MODULES];   /*!< data to be written to the slave EEPROM    */
    uint8_t eeprom_value_read[BS_NR_OF_MODULES];    /*!< data read from to the slave EEPROM        */
    uint8_t external_sensor_temperature[BS_NR_OF_MODULES];    /*!< temperature from the external sensor on slave   */
    uint32_t eeprom_read_address_to_use;                 /*!< address to read from for  slave EEPROM        */
    uint32_t eeprom_read_address_last_used;                 /*!< last address used to read fromfor slave EEPROM        */
    uint32_t eeprom_write_address_to_use;                 /*!< address to write to for slave EEPROM        */
    uint32_t eeprom_write_address_last_used;                 /*!< last address used to write to for slave EEPROM        */
    uint8_t state;                      /*!< for future use                             */
} DATA_BLOCK_SLAVE_CONTROL_s;

/**
 * data block struct of cell balancing feedback
 */

typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t value[BS_NR_OF_MODULES];    /*!< unit: mV (opto-coupler output)     */
    uint8_t state;                      /*!< for future use                     */
} DATA_BLOCK_BALANCING_FEEDBACK_s;


/**
 * data block struct of user multiplexer values
 */

typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t value[8*2*BS_NR_OF_MODULES];              /*!< unit: mV (mux voltage input)       */
    uint8_t state;                                  /*!< for future use                     */
} DATA_BLOCK_USER_MUX_s;

/**
 * data block struct of current measurement
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    float current;                                         /*!< unit: mA                */
    float voltage[BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR];  /*!< unit: mV                */
    float temperature;                                     /*!< unit: 0.1&deg;C             */
    float power;                                           /*!< unit: W                */
    float current_counter;                                 /*!< unit: A.s                */
    float energy_counter;                                  /*!< unit: W.h                */
    uint8_t state_current;
    uint8_t state_voltage;
    uint8_t state_temperature;
    uint8_t state_power;
    uint8_t state_cc;
    uint8_t state_ec;
    uint8_t newCurrent;
    uint8_t newPower;
    uint32_t previous_timestamp_cur;                       /*!< timestamp of current database entry   */
    uint32_t timestamp_cur;                                /*!< timestamp of current database entry   */
    uint32_t previous_timestamp_cc;                        /*!< timestamp of C-C database entry   */
    uint32_t timestamp_cc;                                 /*!< timestamp of C-C database entry   */
} DATA_BLOCK_CURRENT_SENSOR_s;


/**
 * data block struct of hardware info
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry           */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry      */
    float vbat;                                 /*!< unit: mV                              */
    float temperature;                          /*!< unit: degree Celsius                  */
    uint8_t state_vbat;                         /*!<                                       */
    uint8_t state_temperature;                  /*!<                                       */
} DATA_BLOCK_HW_INFO_s;


/**
 * data block struct of can state request
 */

typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t state_request;
    uint8_t previous_state_request;
    uint8_t state_request_pending;
    uint8_t state;
} DATA_BLOCK_STATEREQUEST_s;

/**
 * data block struct of LTC minimum and maximum values
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint32_t voltage_mean;
    uint16_t voltage_min;
    uint16_t voltage_module_number_min;
    uint16_t voltage_cell_number_min;
    uint16_t previous_voltage_min;
    uint16_t voltage_max;
    uint16_t voltage_module_number_max;
    uint16_t voltage_cell_number_max;
    uint16_t previous_voltage_max;
    float temperature_mean;
    int16_t temperature_min;
    uint16_t temperature_module_number_min;
    uint16_t temperature_sensor_number_min;
    int16_t temperature_max;
    uint16_t temperature_module_number_max;
    uint16_t temperature_sensor_number_max;
    uint8_t state;
} DATA_BLOCK_MINMAX_s;


/**
 * data block struct of isometer measurement
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;             /*!< timestamp of database entry                */
    uint32_t previous_timestamp;    /*!< timestamp of last database entry           */
    uint8_t valid;                  /*!< 0 -> valid, 1 -> resistance unreliable                             */
    uint8_t state;                  /*!< 0 -> resistance/measurement OK , 1 -> resistance too low or error  */
    uint32_t resistance_kOhm;       /*!< insulation resistance measured in kOhm                             */
} DATA_BLOCK_ISOMETER_s;


/**
 * data block struct of ltc device parameter
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint32_t sumOfCells[BS_NR_OF_MODULES];
    uint8_t valid_sumOfCells[BS_NR_OF_MODULES];         /*!< 0 -> valid, 1 -> unreliable                                        */
    uint16_t dieTemperature[BS_NR_OF_MODULES];          /* die temperature in degree celsius                                    */
    uint8_t valid_dieTemperature[BS_NR_OF_MODULES];     /*!< 0 -> valid, 1 -> unreliable                                        */
    uint32_t analogSupplyVolt[BS_NR_OF_MODULES];        /* voltage in [uV]                                                      */
    uint8_t valid_analogSupplyVolt[BS_NR_OF_MODULES];   /*!< 0 -> valid, 1 -> unreliable                                        */
    uint32_t digitalSupplyVolt[BS_NR_OF_MODULES];       /* voltage in [uV]                                                      */
    uint8_t valid_digitalSupplyVolt[BS_NR_OF_MODULES];  /*!< 0 -> valid, 1 -> unreliable                                        */
    uint32_t valid_cellvoltages[BS_NR_OF_MODULES];      /*!< 0 -> valid, 1 -> invalid, bit0 -> cell 0, bit1 -> cell 1 ...       */
    uint8_t valid_GPIOs[BS_NR_OF_MODULES];              /*!< 0 -> valid, 1 -> invalid, bit0 -> GPIO0, bit1 -> GPIO1 ...         */
    uint8_t valid_LTC[BS_NR_OF_MODULES];                /*!< 0 -> LTC working, 1 -> LTC defect                                  */
} DATA_BLOCK_LTC_DEVICE_PARAMETER_s;


/**
 * data block struct of ltc adc accuracy measurement
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    int adc1_deviation[BS_NR_OF_MODULES];       /* ADC1 deviation from 2nd reference */
    int adc2_deviation[BS_NR_OF_MODULES];       /* ADC2 deviation from 2nd reference */
} DATA_BLOCK_LTC_ADC_ACCURACY_s;

/**
 * data block struct of error flags
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                              /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                     /*!< timestamp of last database entry           */
    uint8_t general_error;                           /*!< 0 -> no error, 1 -> error         */
    uint8_t currentsensorresponding;                 /*!< 0 -> no error, 1 -> error         */
    uint8_t main_plus;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t main_minus;                              /*!< 0 -> no error, 1 -> error         */
    uint8_t precharge;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t charge_main_plus;                        /*!< 0 -> no error, 1 -> error         */
    uint8_t charge_main_minus;                       /*!< 0 -> no error, 1 -> error         */
    uint8_t charge_precharge;                        /*!< 0 -> no error, 1 -> error         */
    uint8_t interlock;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t crc_error;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t mux_error;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t spi_error;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t can_timing;                              /*!< 0 -> no error, 1 -> error         */
    uint8_t can_timing_cc;                           /*!< 0 -> no error, 1 -> error         */
    uint8_t can_cc_used;                             /*!< 0 -> not present, 1 -> present    */
} DATA_BLOCK_ERRORSTATE_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock  */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t general_MSL;                    /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_voltage;                   /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t under_voltage;                  /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_temperature_charge;        /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_temperature_discharge;     /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t under_temperature_charge;       /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t under_temperature_discharge;    /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_current_charge;            /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_current_discharge;         /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t pcb_over_temperature;           /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t pcb_under_temperature;          /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
} DATA_BLOCK_MSL_FLAG_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock  */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t general_RSL;                    /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_voltage;                   /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t under_voltage;                  /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_temperature_charge;        /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_temperature_discharge;     /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t under_temperature_charge;       /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t under_temperature_discharge;    /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_current_charge;            /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_current_discharge;         /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t pcb_over_temperature;           /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t pcb_under_temperature;          /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
} DATA_BLOCK_RSL_FLAG_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t general_MOL;                    /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_voltage;                   /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t under_voltage;                  /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_temperature_charge;        /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_temperature_discharge;     /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t under_temperature_charge;       /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t under_temperature_discharge;    /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_current_charge;            /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_current_discharge;         /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t pcb_over_temperature;           /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t pcb_under_temperature;          /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
} DATA_BLOCK_MOL_FLAG_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;               /*!< timestamp of database entry                */
    uint32_t previous_timestamp;      /*!< timestamp of last database entry           */
    float movAverage_current_1s;      /*!< current moving average over the last 1s               */
    float movAverage_current_5s;      /*!< current moving average over the last 5s               */
    float movAverage_current_10s;     /*!< current moving average over the last 10s              */
    float movAverage_current_30s;     /*!< current moving average over the last 30s              */
    float movAverage_current_60s;     /*!< current moving average over the last 60s              */
    float movAverage_current_config;  /*!< current moving average over the last configured time  */
    float movAverage_power_1s;        /*!< power moving average over the last 1s                 */
    float movAverage_power_5s;        /*!< power moving average over the last 5s                 */
    float movAverage_power_10s;       /*!< power moving average over the last 10s                */
    float movAverage_power_30s;       /*!< power moving average over the last 30s                */
    float movAverage_power_60s;       /*!< power moving average over the last 60s                */
    float movAverage_power_config;    /*!< power moving average over the last configured time    */
} DATA_BLOCK_MOVING_AVERAGE_s;

/**
 * data block struct of contactor feedback
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t contactor_feedback;                /*!< feedback of contactors, without interlock */
} DATA_BLOCK_CONTFEEDBACK_s;

/**
 * data block struct of interlock feedback
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t interlock_feedback;                 /*!< feedback of interlock, without contactors */
} DATA_BLOCK_ILCKFEEDBACK_s;

/**
 * data block struct of system state
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t bms_state;                          /*!< system state (e.g., standby, normal) */
} DATA_BLOCK_SYSTEMSTATE_s;

/**
 * data block struct of cell voltage
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                                                       /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                                              /*!< timestamp of last database entry           */
    uint16_t gpiovoltage[BS_NR_OF_MODULES * BS_NR_OF_GPIOS_PER_MODULE];       /*!< unit: mV                                   */
    uint8_t state;                                                            /*!< for future use                             */
} DATA_BLOCK_ALLGPIOVOLTAGE_s;

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

/**
 * @brief device configuration of database
 *
 * all attributes of device configuration are listed here (pointer to channel list, number of channels)
 */
extern const DATA_BASE_HEADER_DEV_s data_base_dev;

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

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

#endif /* DATABASE_CFG_H_ */

database_cfg.c (secondary)

/**
 *
 * @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    database_cfg.c
 * @author  foxBMS Team
 * @date    18.08.2015 (date of creation)
 * @ingroup ENGINE_CONF
 * @prefix  DATA
 *
 * @brief   Database configuration
 *
 * Configuration of database module
 *
 */

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

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

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

/**
 * data block: cell voltage
 */
DATA_BLOCK_CELLVOLTAGE_s data_block_cellvoltage[DOUBLE_BUFFERING];

/**
 * data block: cell temperature
 */
DATA_BLOCK_CELLTEMPERATURE_s data_block_celltemperature[DOUBLE_BUFFERING];

/**
 * data block: sox
 */
DATA_BLOCK_SOX_s data_block_sox[SINGLE_BUFFERING];

/**
 * data block: sof
 */
DATA_BLOCK_SOF_s data_block_sof[SINGLE_BUFFERING];

/**
 * data block: balancing control
 */
DATA_BLOCK_BALANCING_CONTROL_s data_block_control_balancing[DOUBLE_BUFFERING];

/**
 * data block: balancing feedback
 */
DATA_BLOCK_BALANCING_FEEDBACK_s data_block_feedback_balancing[DOUBLE_BUFFERING];

/**
 * data block: current measurement
 */
DATA_BLOCK_CURRENT_SENSOR_s data_block_curr_sensor[DOUBLE_BUFFERING];

/**
 * data block: ADC
 */
DATA_BLOCK_HW_INFO_s data_block_adc[SINGLE_BUFFERING];

/**
 * data block: can state request
 */
DATA_BLOCK_STATEREQUEST_s data_block_staterequest[SINGLE_BUFFERING];

/**
 * data block: LTC minimum and maximum values
 */
DATA_BLOCK_MINMAX_s data_block_minmax[DOUBLE_BUFFERING];

/**
 * data block: isometer measurement
 */
DATA_BLOCK_ISOMETER_s data_block_isometer[SINGLE_BUFFERING];

/**
 * data block: error flags
 */
DATA_BLOCK_ERRORSTATE_s data_block_errors[DOUBLE_BUFFERING];

/**
 * data block: maximum safety limit violations
 */
DATA_BLOCK_MSL_FLAG_s data_block_MSL[SINGLE_BUFFERING];

/**
 * data block: recommended safety limit violations
 */
DATA_BLOCK_RSL_FLAG_s data_block_RSL[SINGLE_BUFFERING];

/**
 * data block: maximum operating limit violations
 */
DATA_BLOCK_MOL_FLAG_s data_block_MOL[SINGLE_BUFFERING];

/**
 * data block: moving mean current and power
 */
DATA_BLOCK_MOVING_AVERAGE_s data_block_mov_average[DOUBLE_BUFFERING];

/**
 * data block: contactor feedback
 */
DATA_BLOCK_CONTFEEDBACK_s data_block_contfeedback[SINGLE_BUFFERING];

/**
 * data block: interlock feedback
 */
DATA_BLOCK_ILCKFEEDBACK_s data_block_ilckfeedback[SINGLE_BUFFERING];

/**
 * data block: slave control
 */
DATA_BLOCK_SLAVE_CONTROL_s data_block_slave_control[SINGLE_BUFFERING];

/**
 * data block: system state
 */
DATA_BLOCK_SYSTEMSTATE_s data_block_systemstate[SINGLE_BUFFERING];

/**
 * data block: open wire check
 */
DATA_BLOCK_OPENWIRE_s data_block_open_wire[DOUBLE_BUFFERING];

/**
 * data block: LTC diagnosis values
 */
DATA_BLOCK_LTC_DEVICE_PARAMETER_s data_block_ltc_diagnosis[SINGLE_BUFFERING];


/**
 * data block: LTC ADC accuracy verification
 */
DATA_BLOCK_LTC_ADC_ACCURACY_s data_block_ltc_adc_accuracy[SINGLE_BUFFERING];

/**
 * data block: LTC ADC accuracy verification
 */
DATA_BLOCK_ALLGPIOVOLTAGE_s data_block_ltc_allgpiovoltages[DOUBLE_BUFFERING];

/**
 * @brief channel configuration of database (data blocks)
 *
 * all data block managed by database are listed here (address,size,consistency type)
 *
 */
DATA_BASE_HEADER_s  data_base_header[] = {
    {
            (void*)(&data_block_cellvoltage[0]),
            sizeof(DATA_BLOCK_CELLVOLTAGE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_celltemperature[0]),
            sizeof(DATA_BLOCK_CELLTEMPERATURE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_sox[0]),
            sizeof(DATA_BLOCK_SOX_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_control_balancing[0]),
            sizeof(DATA_BLOCK_BALANCING_CONTROL_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_feedback_balancing[0]),
            sizeof(DATA_BLOCK_BALANCING_FEEDBACK_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_curr_sensor[0]),
            sizeof(DATA_BLOCK_CURRENT_SENSOR_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_adc[0]),
            sizeof(DATA_BLOCK_HW_INFO_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_staterequest[0]),
            sizeof(DATA_BLOCK_STATEREQUEST_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_minmax[0]),
            sizeof(DATA_BLOCK_MINMAX_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_isometer[0]),
            sizeof(DATA_BLOCK_ISOMETER_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_slave_control[0]),
            sizeof(DATA_BLOCK_SLAVE_CONTROL_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_open_wire[0]),
            sizeof(DATA_BLOCK_OPENWIRE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_ltc_diagnosis[0]),
            sizeof(DATA_BLOCK_LTC_DEVICE_PARAMETER_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_ltc_adc_accuracy[0]),
            sizeof(DATA_BLOCK_LTC_ADC_ACCURACY_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_errors[0]),
            sizeof(DATA_BLOCK_ERRORSTATE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_MSL[0]),
            sizeof(DATA_BLOCK_MSL_FLAG_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_RSL[0]),
            sizeof(DATA_BLOCK_RSL_FLAG_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_MOL[0]),
            sizeof(DATA_BLOCK_MOL_FLAG_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_mov_average[0]),
            sizeof(DATA_BLOCK_MOVING_AVERAGE_s),
            DOUBLE_BUFFERING,
    },
    {
            (void*)(&data_block_contfeedback[0]),
            sizeof(DATA_BLOCK_CONTFEEDBACK_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_ilckfeedback[0]),
            sizeof(DATA_BLOCK_ILCKFEEDBACK_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_systemstate[0]),
            sizeof(DATA_BLOCK_SYSTEMSTATE_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_sof[0]),
            sizeof(DATA_BLOCK_SOF_s),
            SINGLE_BUFFERING,
    },
    {
            (void*)(&data_block_ltc_allgpiovoltages[0]),
            sizeof(DATA_BLOCK_ALLGPIOVOLTAGE_s),
            DOUBLE_BUFFERING,
    },
};

/**
 * @brief device configuration of database
 *
 * all attributes of device configuration are listed here (pointer to channel list, number of channels)
 */
const DATA_BASE_HEADER_DEV_s data_base_dev = {
    .nr_of_blockheader  = sizeof(data_base_header)/sizeof(DATA_BASE_HEADER_s),    // number of blocks (and block headers)
    .blockheaderptr     = &data_base_header[0],
};

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

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

database_cfg.h (secondary)

/**
 *
 * @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    database_cfg.h
 * @author  foxBMS Team
 * @date    18.08.2015 (date of creation)
 * @ingroup ENGINE_CONF
 * @prefix  DATA
 *
 * @brief   Database configuration header
 *
 * Provides interfaces to database configuration
 *
 */

#ifndef DATABASE_CFG_H_
#define DATABASE_CFG_H_

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

#include "batterysystem_cfg.h"

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

/**
 * @brief maximum amount of data block
 *
 * this value is extendible but limitation is done due to RAM consumption and performance
 */
#define DATA_MAX_BLOCK_NR                24        /* max 24 Blocks currently supported*/

/**
 * @brief data block identification number
 */
typedef enum {
    DATA_BLOCK_00       =  0,
    DATA_BLOCK_01       =  1,
    DATA_BLOCK_02       =  2,
    DATA_BLOCK_03       =  3,
    DATA_BLOCK_04       =  4,
    DATA_BLOCK_05       =  5,
    DATA_BLOCK_06       =  6,
    DATA_BLOCK_07       =  7,
    DATA_BLOCK_08       =  8,
    DATA_BLOCK_09       =  9,
    DATA_BLOCK_10       = 10,
    DATA_BLOCK_11       = 11,
    DATA_BLOCK_12       = 12,
    DATA_BLOCK_13       = 13,
    DATA_BLOCK_14       = 14,
    DATA_BLOCK_15       = 15,
    DATA_BLOCK_16       = 16,
    DATA_BLOCK_17       = 17,
    DATA_BLOCK_18       = 18,
    DATA_BLOCK_19       = 19,
    DATA_BLOCK_20       = 20,
    DATA_BLOCK_21       = 21,
    DATA_BLOCK_22       = 22,
    DATA_BLOCK_23       = 23,
    DATA_BLOCK_MAX      = DATA_MAX_BLOCK_NR,
} DATA_BLOCK_ID_TYPE_e;


/**
 * @brief data block access types
 *
 * read or write access types
 */
typedef enum {
    WRITE_ACCESS    = 0,    /*!< write access to data block   */
    READ_ACCESS     = 1,    /*!< read access to data block   */
} DATA_BLOCK_ACCESS_TYPE_e;

/**
 * @brief data block consistency types
 *
 * recommendation: use single buffer for small data (e.g.,one variable) and less concurrent read and write accesses
 */
typedef enum {
    // Init-Sequence
    SINGLE_BUFFERING    = 1,    /*!< single buffering   */
    DOUBLE_BUFFERING    = 2,    /*!< double buffering   */
    // TRIPLEBUFFERING     = 3,    /* actually not supported*/
} DATA_BLOCK_BUFFER_TYPE_e;

/**
 * configuration struct of database channel (data block)
 */
typedef struct {
    void *blockptr;
    uint16_t datalength;
    DATA_BLOCK_BUFFER_TYPE_e buffertype;
} DATA_BASE_HEADER_s;

/**
 * configuration struct of database device
 */
typedef struct {
    uint8_t nr_of_blockheader;
    DATA_BASE_HEADER_s *blockheaderptr;
} DATA_BASE_HEADER_DEV_s;


/*================== Macros and Definitions [USER CONFIGURATION] =============*/
// FIXME comments doxygen, is comment necessary?
/*Macros and Definitions for User Configuration*/
#define     DATA_BLOCK_ID_CELLVOLTAGE                   DATA_BLOCK_00
#define     DATA_BLOCK_ID_CELLTEMPERATURE               DATA_BLOCK_01
#define     DATA_BLOCK_ID_SOX                           DATA_BLOCK_02
#define     DATA_BLOCK_ID_BALANCING_CONTROL_VALUES      DATA_BLOCK_03
#define     DATA_BLOCK_ID_BALANCING_FEEDBACK_VALUES     DATA_BLOCK_04
#define     DATA_BLOCK_ID_CURRENT_SENSOR                DATA_BLOCK_05
#define     DATA_BLOCK_ID_HW_INFO                       DATA_BLOCK_06
#define     DATA_BLOCK_ID_STATEREQUEST                  DATA_BLOCK_07
#define     DATA_BLOCK_ID_MINMAX                        DATA_BLOCK_08
#define     DATA_BLOCK_ID_ISOGUARD                      DATA_BLOCK_09
#define     DATA_BLOCK_ID_SLAVE_CONTROL                 DATA_BLOCK_10
#define     DATA_BLOCK_ID_OPEN_WIRE_CHECK               DATA_BLOCK_11
#define     DATA_BLOCK_ID_LTC_DEVICE_PARAMETER          DATA_BLOCK_12
#define     DATA_BLOCK_ID_LTC_ACCURACY                  DATA_BLOCK_13
#define     DATA_BLOCK_ID_ERRORSTATE                    DATA_BLOCK_14
#define     DATA_BLOCK_ID_MSL                           DATA_BLOCK_15
#define     DATA_BLOCK_ID_RSL                           DATA_BLOCK_16
#define     DATA_BLOCK_ID_MOL                           DATA_BLOCK_17
#define     DATA_BLOCK_ID_MOV_AVERAGE                   DATA_BLOCK_18
#define     DATA_BLOCK_ID_CONTFEEDBACK                  DATA_BLOCK_19
#define     DATA_BLOCK_ID_ILCKFEEDBACK                  DATA_BLOCK_20
#define     DATA_BLOCK_ID_SYSTEMSTATE                   DATA_BLOCK_21
#define     DATA_BLOCK_ID_SOF                           DATA_BLOCK_22
#define     DATA_BLOCK_ID_ALLGPIOVOLTAGE                DATA_BLOCK_23

/**
 * data block struct of cell voltage
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t voltage[BS_NR_OF_BAT_CELLS];       /*!< unit: mV                                   */
    uint32_t valid_voltPECs[BS_NR_OF_MODULES];  /*!< bitmask if PEC was okay. 0->ok, 1->error   */
    uint32_t sumOfCells[BS_NR_OF_MODULES];      /*!< unit: mV                                   */
    uint8_t valid_socPECs[BS_NR_OF_MODULES];   /*!< 0 -> if PEC okay; 1 -> PEC error           */
    uint8_t state;                              /*!< for future use                             */
} DATA_BLOCK_CELLVOLTAGE_s;

/**
 * data block struct of cell voltage
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t openwire[BS_NR_OF_BAT_CELLS];   /*!< 1 -> open wire, 0 -> everything ok */
    uint8_t state;                          /*!< for future use                       */
} DATA_BLOCK_OPENWIRE_s;

/**
 * data block struct of cell temperatures
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    int16_t temperature[BS_NR_OF_TEMP_SENSORS];             /*!< unit: degree Celsius                       */
    uint16_t valid_temperaturePECs[BS_NR_OF_MODULES];  /*!< bitmask if PEC was okay. 0->ok, 1->error   */
    uint8_t state;                                          /*!< for future use                             */
} DATA_BLOCK_CELLTEMPERATURE_s;

/**
 * data block struct of sox
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                 /*!< timestamp of database entry                */
    uint32_t previous_timestamp;        /*!< timestamp of last database entry           */
    float soc_mean;                     /*!< 0.0 <= soc_mean <= 100.0           */
    float soc_min;                      /*!< 0.0 <= soc_min <= 100.0            */
    float soc_max;                      /*!< 0.0 <= soc_max <= 100.0            */
    uint8_t state;                      /*!<                                    */
} DATA_BLOCK_SOX_s;


/**
 * data block struct of sof limits
 */
typedef struct {
    uint32_t timestamp;                     /*!< timestamp of database entry                        */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry                   */
    float recommended_continuous_charge;    /*!< recommended continuous operating charge current    */
    float recommended_continuous_discharge; /*!< recommended continuous operating discharge current */
    float recommended_peak_charge;          /*!< recommended peak operating charge current          */
    float recommended_peak_discharge;       /*!< recommended peak operating discharge current       */
    float continuous_charge_MOL;            /*!< charge current maximum operating level             */
    float continuous_discharge_MOL;         /*!< discharge current maximum operating level          */
    float continuous_charge_RSL;            /*!< charge current recommended safety level            */
    float continuous_discharge_RSL;         /*!< discharge current recommended safety level         */
    float continuous_charge_MSL;            /*!< charge current maximum safety level                */
    float continuous_discharge_MSL;         /*!< discharge current maximum safety level             */
} DATA_BLOCK_SOF_s;


/*  data structure declaration of DATA_BLOCK_BALANCING_CONTROL */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t balancing_state[BS_NR_OF_BAT_CELLS];    /*!< 0 means balancing is active, 0 means balancing is inactive*/
    uint32_t delta_charge[BS_NR_OF_BAT_CELLS];    /*!< Difference in Depth-of-Discharge in mAs*/
    uint8_t enable_balancing;           /*!< Switch for enabling/disabling balancing    */
    uint8_t threshold;                  /*!< balancing threshold in mV                  */
    uint8_t request;                     /*!< balancing request per CAN                 */
    uint8_t state;                      /*!< for future use                             */
} DATA_BLOCK_BALANCING_CONTROL_s;

/*  data structure declaration of DATA_BLOCK_USER_IO_CONTROL */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t io_value_out[BS_NR_OF_MODULES];   /*!< data to be written to the port expander    */
    uint8_t io_value_in[BS_NR_OF_MODULES];    /*!< data read from to the port expander        */
    uint8_t eeprom_value_write[BS_NR_OF_MODULES];   /*!< data to be written to the slave EEPROM    */
    uint8_t eeprom_value_read[BS_NR_OF_MODULES];    /*!< data read from to the slave EEPROM        */
    uint8_t external_sensor_temperature[BS_NR_OF_MODULES];    /*!< temperature from the external sensor on slave   */
    uint32_t eeprom_read_address_to_use;                 /*!< address to read from for  slave EEPROM        */
    uint32_t eeprom_read_address_last_used;                 /*!< last address used to read fromfor slave EEPROM        */
    uint32_t eeprom_write_address_to_use;                 /*!< address to write to for slave EEPROM        */
    uint32_t eeprom_write_address_last_used;                 /*!< last address used to write to for slave EEPROM        */
    uint8_t state;                      /*!< for future use                             */
} DATA_BLOCK_SLAVE_CONTROL_s;

/**
 * data block struct of cell balancing feedback
 */

typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t value[BS_NR_OF_MODULES];    /*!< unit: mV (opto-coupler output)     */
    uint8_t state;                      /*!< for future use                     */
} DATA_BLOCK_BALANCING_FEEDBACK_s;


/**
 * data block struct of user multiplexer values
 */

typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t value[8*2*BS_NR_OF_MODULES];              /*!< unit: mV (mux voltage input)       */
    uint8_t state;                                  /*!< for future use                     */
} DATA_BLOCK_USER_MUX_s;

/**
 * data block struct of current measurement
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    float current;                                         /*!< unit: mA                */
    float voltage[BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR];  /*!< unit: mV                */
    float temperature;                                     /*!< unit: 0.1&deg;C             */
    float power;                                           /*!< unit: W                */
    float current_counter;                                 /*!< unit: A.s                */
    float energy_counter;                                  /*!< unit: W.h                */
    uint8_t state_current;
    uint8_t state_voltage;
    uint8_t state_temperature;
    uint8_t state_power;
    uint8_t state_cc;
    uint8_t state_ec;
    uint8_t newCurrent;
    uint8_t newPower;
    uint32_t previous_timestamp_cur;                       /*!< timestamp of current database entry   */
    uint32_t timestamp_cur;                                /*!< timestamp of current database entry   */
    uint32_t previous_timestamp_cc;                        /*!< timestamp of C-C database entry   */
    uint32_t timestamp_cc;                                 /*!< timestamp of C-C database entry   */
} DATA_BLOCK_CURRENT_SENSOR_s;


/**
 * data block struct of ADC
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    float vbat;  // unit: to be defined
    uint32_t vbat_previous_timestamp;           /*!< timestamp of last database entry of vbat           */
    uint32_t vbat_timestamp;                    /*!< timestamp of database entry of vbat                */
    float temperature;                          /*!<                                                    */
    uint32_t temperature_previous_timestamp;    /*!< timestamp of last database entry of temperature    */
    uint32_t temperature_timestamp;             /*!< timestamp of database entry of temperature         */
    uint8_t state_vbat;                         /*!<                                                    */
    uint8_t state_temperature;                  /*!<                                                    */
} DATA_BLOCK_HW_INFO_s;


/**
 * data block struct of can state request
 */

typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t state_request;
    uint8_t previous_state_request;
    uint8_t state_request_pending;
    uint8_t state;
} DATA_BLOCK_STATEREQUEST_s;

/**
 * data block struct of LTC minimum and maximum values
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint32_t voltage_mean;
    uint16_t voltage_min;
    uint16_t voltage_module_number_min;
    uint16_t voltage_cell_number_min;
    uint16_t previous_voltage_min;
    uint16_t voltage_max;
    uint16_t voltage_module_number_max;
    uint16_t voltage_cell_number_max;
    uint16_t previous_voltage_max;
    float temperature_mean;
    int16_t temperature_min;
    uint16_t temperature_module_number_min;
    uint16_t temperature_sensor_number_min;
    int16_t temperature_max;
    uint16_t temperature_module_number_max;
    uint16_t temperature_sensor_number_max;
    uint8_t state;
} DATA_BLOCK_MINMAX_s;


/**
 * data block struct of isometer measurement
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;             /*!< timestamp of database entry                */
    uint32_t previous_timestamp;    /*!< timestamp of last database entry           */
    uint8_t valid;                  /*!< 0 -> valid, 1 -> resistance unreliable                             */
    uint8_t state;                  /*!< 0 -> resistance/measurement OK , 1 -> resistance too low or error  */
    uint32_t resistance_kOhm;       /*!< insulation resistance measured in kOhm                             */
} DATA_BLOCK_ISOMETER_s;


/**
 * data block struct of ltc device parameter
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint32_t sumOfCells[BS_NR_OF_MODULES];
    uint8_t valid_sumOfCells[BS_NR_OF_MODULES];         /*!< 0 -> valid, 1 -> unreliable                                        */
    uint16_t dieTemperature[BS_NR_OF_MODULES];          /* die temperature in degree celsius                                    */
    uint8_t valid_dieTemperature[BS_NR_OF_MODULES];     /*!< 0 -> valid, 1 -> unreliable                                        */
    uint32_t analogSupplyVolt[BS_NR_OF_MODULES];        /* voltage in [uV]                                                      */
    uint8_t valid_analogSupplyVolt[BS_NR_OF_MODULES];   /*!< 0 -> valid, 1 -> unreliable                                        */
    uint32_t digitalSupplyVolt[BS_NR_OF_MODULES];       /* voltage in [uV]                                                      */
    uint8_t valid_digitalSupplyVolt[BS_NR_OF_MODULES];  /*!< 0 -> valid, 1 -> unreliable                                        */
    uint32_t valid_cellvoltages[BS_NR_OF_MODULES];      /*!< 0 -> valid, 1 -> invalid, bit0 -> cell 0, bit1 -> cell 1 ...       */
    uint8_t valid_GPIOs[BS_NR_OF_MODULES];              /*!< 0 -> valid, 1 -> invalid, bit0 -> GPIO0, bit1 -> GPIO1 ...         */
    uint8_t valid_LTC[BS_NR_OF_MODULES];                /*!< 0 -> LTC working, 1 -> LTC defect                                  */
} DATA_BLOCK_LTC_DEVICE_PARAMETER_s;


/**
 * data block struct of ltc adc accuracy measurement
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    int adc1_deviation[BS_NR_OF_MODULES];       /* ADC1 deviation from 2nd reference */
    int adc2_deviation[BS_NR_OF_MODULES];       /* ADC2 deviation from 2nd reference */
} DATA_BLOCK_LTC_ADC_ACCURACY_s;

/**
 * data block struct of error flags
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                              /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                     /*!< timestamp of last database entry           */
    uint8_t general_error;                           /*!< 0 -> no error, 1 -> error         */
    uint8_t currentsensorresponding;                 /*!< 0 -> no error, 1 -> error         */
    uint8_t main_plus;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t main_minus;                              /*!< 0 -> no error, 1 -> error         */
    uint8_t precharge;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t charge_main_plus;                        /*!< 0 -> no error, 1 -> error         */
    uint8_t charge_main_minus;                       /*!< 0 -> no error, 1 -> error         */
    uint8_t charge_precharge;                        /*!< 0 -> no error, 1 -> error         */
    uint8_t interlock;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t crc_error;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t mux_error;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t spi_error;                               /*!< 0 -> no error, 1 -> error         */
    uint8_t can_timing;                              /*!< 0 -> no error, 1 -> error         */
    uint8_t can_timing_cc;                           /*!< 0 -> no error, 1 -> error         */
    uint8_t can_cc_used;                             /*!< 0 -> not present, 1 -> present    */
} DATA_BLOCK_ERRORSTATE_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock  */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t general_MSL;                    /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_voltage;                   /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t under_voltage;                  /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_temperature_charge;        /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_temperature_discharge;     /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t under_temperature_charge;       /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t under_temperature_discharge;    /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_current_charge;            /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t over_current_discharge;         /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t pcb_over_temperature;           /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
    uint8_t pcb_under_temperature;          /*!< 0 -> MSL NOT violated, 1 -> MSL violated   */
} DATA_BLOCK_MSL_FLAG_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock  */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t general_RSL;                    /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_voltage;                   /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t under_voltage;                  /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_temperature_charge;        /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_temperature_discharge;     /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t under_temperature_charge;       /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t under_temperature_discharge;    /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_current_charge;            /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t over_current_discharge;         /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t pcb_over_temperature;           /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
    uint8_t pcb_under_temperature;          /*!< 0 -> RSL NOT violated, 1 -> RSL violated   */
} DATA_BLOCK_RSL_FLAG_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                     /*!< timestamp of database entry                */
    uint32_t previous_timestamp;            /*!< timestamp of last database entry           */
    uint8_t general_MOL;                    /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_voltage;                   /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t under_voltage;                  /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_temperature_charge;        /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_temperature_discharge;     /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t under_temperature_charge;       /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t under_temperature_discharge;    /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_current_charge;            /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t over_current_discharge;         /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t pcb_over_temperature;           /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
    uint8_t pcb_under_temperature;          /*!< 0 -> MOL NOT violated, 1 -> MOL violated    */
} DATA_BLOCK_MOL_FLAG_s;


typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;               /*!< timestamp of database entry                */
    uint32_t previous_timestamp;      /*!< timestamp of last database entry           */
    float movAverage_current_1s;      /*!< current moving average over the last 1s               */
    float movAverage_current_5s;      /*!< current moving average over the last 5s               */
    float movAverage_current_10s;     /*!< current moving average over the last 10s              */
    float movAverage_current_30s;     /*!< current moving average over the last 30s              */
    float movAverage_current_60s;     /*!< current moving average over the last 60s              */
    float movAverage_current_config;  /*!< current moving average over the last configured time  */
    float movAverage_power_1s;        /*!< power moving average over the last 1s                 */
    float movAverage_power_5s;        /*!< power moving average over the last 5s                 */
    float movAverage_power_10s;       /*!< power moving average over the last 10s                */
    float movAverage_power_30s;       /*!< power moving average over the last 30s                */
    float movAverage_power_60s;       /*!< power moving average over the last 60s                */
    float movAverage_power_config;    /*!< power moving average over the last configured time    */
} DATA_BLOCK_MOVING_AVERAGE_s;

/**
 * data block struct of contactor feedback
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint16_t contactor_feedback;                /*!< feedback of contactors, without interlock */
} DATA_BLOCK_CONTFEEDBACK_s;

/**
 * data block struct of interlock feedback
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t interlock_feedback;                 /*!< feedback of interlock, without contactors */
} DATA_BLOCK_ILCKFEEDBACK_s;

/**
 * data block struct of system state
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                         /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                /*!< timestamp of last database entry           */
    uint8_t bms_state;                          /*!< system state (e.g., standby, normal) */
} DATA_BLOCK_SYSTEMSTATE_s;

/**
 * data block struct of cell voltage
 */
typedef struct {
    /* Timestamp info needs to be at the beginning. Automatically written on DB_WriteBlock */
    uint32_t timestamp;                                                       /*!< timestamp of database entry                */
    uint32_t previous_timestamp;                                              /*!< timestamp of last database entry           */
    uint16_t gpiovoltage[BS_NR_OF_MODULES * BS_NR_OF_GPIOS_PER_MODULE];       /*!< unit: mV                                   */
    uint8_t state;                                                            /*!< for future use                             */
} DATA_BLOCK_ALLGPIOVOLTAGE_s;

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

/**
 * @brief device configuration of database
 *
 * all attributes of device configuration are listed here (pointer to channel list, number of channels)
 */
extern const DATA_BASE_HEADER_DEV_s data_base_dev;

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

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

#endif /* DATABASE_CFG_H_ */