#ifndef __COMMON_INCLUDE_H__
#define __COMMON_INCLUDE_H__

/**
 *****************************************************************************
 ** \defgroup PDLMacroGroup General PDL macros
 ** \brief This section describes the interface for the PDL General macros
 **
 ** Provided functions of General PDL macros:
 **
 ** - PDL_WRITE_REG_SYNC()
 ** - PDL_SAFELY_DISABLE_INTERRUPT()
 ** 
 ** For more detail, see PDL_WRITE_REG_SYNC(), PDL_SAFELY_DISABLE_INTERRUPT()
 ** sections.
 *****************************************************************************/
/*@{ */

/**
 *****************************************************************************
 ** Including mechanism to synchronously write the register,
 ** including all latency time of bus bridges.
 ** This is ensured by reading back the register which will force the CPU to
 ** wait until the write/read-back operation is completed. Reading an address
 ** on the same bus as written before, will stall the CPU until all pending
 ** write operations in CPU write buffer to strictly ordered memory areas like
 ** I/O registers are completed.
 **
 ** This macro should be used to ensure a safe clearing of interrupt flags
 ** before returning from the ISR, to prevent ISR double execution in case of
 ** not-yet-cleared interrupt flags in a peripheral.
 **
 ** Typically the appropriate clear register is used to clear the
 ** interrupt status flag of a peripheral.
 **
 ** See Cortex-R5 TRM Appendix-D D.1 Memory ordering
 **
 *****************************************************************************/
#define PDL_WRITE_REG_SYNC(Register, val)   \
        {                                   \
            Register = val;                 \
            Register;                       \
            DMB();                          \
        }

/**
 *****************************************************************************
 ** Macro for synchronously disabling an interrupt of a peripheral
 ** including all latency time of bus bridges, interrupt status
 ** signal to the Interrupt Controller and interrupt priority evaluation.
 ** This macro should be used to ensure a safe, interrupt protected
 ** code execution after execution of this macro.
 **
 ** Typically the appropriate clear register is used to clear the
 ** interrupt enable flag of a peripheral.
 *****************************************************************************/
#define PDL_SAFELY_DISABLE_INTERRUPT(Register, val)     \
        {                                               \
            Register = val;                             \
            Register;                                   \
            NOP(); NOP(); NOP(); NOP(); NOP(); NOP();   \
        }




/**
 *****************************************************************************
 ** Macro for writing one ore more bits in a register by one register
 ** write operation. It is recommended to use this macro to initialize
 ** full registers with constant bit settings and to use this macro to set
 ** and clear bits located in a dedicated set/clear register.
 **
 ** Using this macro prevents RMW operations on registers thus providing
 ** better performance and preventing lost update problems when using concurrent
 ** accesses on such registers.
 ** 
 ** \param name         name of register, lowercase (e.g. usartn_sscr)
 ** \param unRegister   register variable which should be set (must be of union type)
 ** \param ...          one or more bit assignment(s) in PDL_WRITE_BIT_REG_ACC#unRegister
 **                       (format: ".u1BIT1 = 1, .u1BIT2 = 1")
 ** 
 ** \note The macro will write the full PDL_WRITE_BIT_REG_ACC#unRegister with the given bit mask.
 **       All remaining bits in PDL_WRITE_BIT_REG_ACC#unRegister which are not given will
 **       be written to '0'!
 **
 ** Usage example:
 **   
 **   // Set ADCn_CSC1:INTC and ADCn_CSC1:PAUSC to clear ADCn_CS1:INT and ADCn_CS1:PAUS bits
 **   PDL_WRITE_BIT_REG_ACC(adcn_csc1, ADC0.unCSC1, .u1INTC = 1, .u1PAUSC = 1);
 ** 
 *****************************************************************************/
#define PDL_WRITE_BIT_REG_ACC(name, unRegister, ...)   \
        { \
            unRegister.stcField = (stc_##name##_field_t) { __VA_ARGS__ }; \
        }

/**
 *****************************************************************************
 ** Same macro as PDL_WRITE_BIT_REG_ACC() but including a typecast
 ** for unRegister to type un_{name}_t.
 *****************************************************************************/
#define PDL_WRITE_BIT_REG_ACC_TC(name, unRegister, ...)   \
        { \
            (*((un_##name##_t*)&unRegister))##.stcField = (stc_##name##_field_t) { __VA_ARGS__ }; \
        } 
             
/**
 *****************************************************************************
 ** Same macro as PDL_WRITE_BIT_REG_ACC() but accessing only one sub-byte within
 ** the given register. The additional parameter #byte will address the
 ** sub-byte in the given register.
 **
 ** The macro should be used for byte accesses to registers which contain
 ** clear/set bits as well as configuration bits which must not be overwritten.
 ** 
 ** \param byte         sub-byte in PDL_WRITE_BIT_BYTE_ACC#unRegister (0, 1, ...)
 ** 
 ** \note The macro will write only the given byte of PDL_WRITE_BIT_BYTE_ACC#unRegister
 **       with the given bit mask. All remaining bits in that register
 **       byte which are not given will be written to '0'!
 **
 ** Usage example:
 **   
 **   // Set SGn_CR0:AMICLR to clear SGn_CR1:AMINT
 **   // (only byte0 of SGn_CR0 is written to preserve settings in byte1)
 **   PDL_WRITE_BIT_BYTE_ACC(sgn_cr0, SG0.unCR0, .u1AMICLR = 1);
 ** 
 *****************************************************************************/
#define PDL_WRITE_BIT_BYTE_ACC(name, unRegister, byte, ...)      \
        { \
            (*( un_##name##_t *)&( unRegister )).stcFieldBytes.stcByte##byte## = \
                          ( stc_##name##_field_byte##byte##_t ) { __VA_ARGS__ }; \
        }
   
/**
 *****************************************************************************
 ** Same macro as PDL_WRITE_BIT_REG_ACC() but including mechanism to
 ** synchronously write the register, including all latency time of bus bridges.
 ** This is ensured by reading back the register which will force the CPU to
 ** wait until the write/read-back operation is completed. Reading an address
 ** on the same bus as written before, will stall the CPU until all pending
 ** write operations in CPU write buffer to strictly ordered memory areas like
 ** I/O registers are completed.
 **
 ** This macro should be used to ensure a safe clearing of interrupt flags
 ** before returning from the ISR, to prevent ISR double execution in case of
 ** not-yet-cleared interrupt flags in a peripheral.
 **
 ** Typically the appropriate clear register is used to clear the
 ** interrupt status flag of a peripheral.
 *****************************************************************************/
#define PDL_WRITE_BIT_REG_ACC_SYNC(name, unRegister, ...)   \
        { \
            PDL_WRITE_BIT_REG_ACC(name, unRegister, __VA_ARGS__); \
            unRegister##; \
        }

/**
 *****************************************************************************
 ** Same macro as PDL_WRITE_BIT_REG_ACC_SYNC() but including a typecast
 ** for unRegister to type un_{name}_t.
 *****************************************************************************/
#define PDL_WRITE_BIT_REG_ACC_SYNC_TC(name, unRegister, ...)   \
        { \
            PDL_WRITE_BIT_REG_ACC_TC(name, unRegister, __VA_ARGS__); \
            unRegister##; \
        }
/**
 *****************************************************************************
 ** Same macro as PDL_WRITE_BIT_REG_ACC_SYNC() but accessing only one sub-byte within
 ** the given register. The additional parameter #byte will address the
 ** sub-byte in the given register - similar to PDL_WRITE_BIT_BYTE_ACC().
 *****************************************************************************/
#define PDL_WRITE_BIT_BYTE_ACC_SYNC(name, unRegister, byte, ...)   \
        { \
            PDL_WRITE_BIT_BYTE_ACC(name, unRegister, byte, __VA_ARGS__); \
            unRegister##; \
        }
             
/**
 *****************************************************************************
 ** Macro for synchronously disabling an interrupt of a peripheral
 ** including all latency time of bus bridges, interrupt status
 ** signal to the Interrupt Controller and interrupt priority evaluation.
 ** This macro should be used to ensure a safe, interrupt protected
 ** code execution after execution of this macro.
 **
 ** Typically the appropriate clear register is used to clear the
 ** interrupt enable flag of a peripheral (e.g. set bit TIEC of 
 ** Serial Status Clear Register USARTN_SSCR to clear the 
 ** Transmission Interrupt Enable (TIE) bit in the Serial Status
 ** Register USARTN_SSR).
 ** 
 ** \param name         name of register, lowercase (e.g. usartn_sscr)
 ** \param unRegister   register variable which should be set (must be of union type)
 ** \param ...          one or more bit assignment(s) in 
 **                      PDL_SAFELY_DISABLE_INTERRUPT#unRegister (format: ".u1BIT1 = 1, .u1BIT2 = 1")
 ** 
 ** \note The macro will write the full PDL_SAFELY_DISABLE_INTERRUPT#unRegister 
 **       with the given bit mask.
 **       All remaining bits in PDL_SAFELY_DISABLE_INTERRUPT#unRegister 
 **       which are not given will be written to '0'! That's why it is 
 **       recommended to use the appropriate clear register.
 **
 ** Usage example:
 **   
 **   // Set USARTN_SSCR:TIEC to clear USARTN_SSR:TIE
 **   PDL_SAFELY_DISABLE_INTERRUPT(usartn_sscr, USART0.unSSCR, .u1TIEC = 1);
 ** 
 *****************************************************************************/
#define PDL_SAFELY_DISABLE_INTERRUPT_SPEU(name, unRegister, ...)     \
                        { \
                          PDL_WRITE_BIT_REG_ACC(name, unRegister, __VA_ARGS__); \
                          unRegister##; \
                          NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); \
                        }
/**
 *****************************************************************************
 ** Same macro as PDL_SAFELY_DISABLE_INTERRUPT() but including a typecast
 ** for unRegister to type un_{name}_t.
 *****************************************************************************/
#define PDL_SAFELY_DISABLE_INTERRUPT_TC_SPEU(name, unRegister, ...)     \
                        { \
                          PDL_WRITE_BIT_REG_ACC(name, (*((un_##name##_t*)&unRegister)), __VA_ARGS__); \
                          unRegister##; \
                          NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); \
                        }
 
    /**
    *****************************************************************************
    ** \brief Write protected register of PPC
    **
    ** \note This macro contains IRQ mask processing for protected sequence.
    **
    ** \param [in]  reg                Register access symbol.
    ** \param [in]  data               Write data.
    *****************************************************************************/
#define WPREG_PPC(reg, data)                   \
    {                                                   \
        un_ppc_keycdr_t wk;                             \
        uint32_t adr = (uint32_t)&reg;                  \
        uint8_t size_key;                               \
        wk.au16Halfword[0] = adr & 0x7FFF;              \
        size_key = (sizeof(reg) >> 1) << 4;             \
        IRQ_DISABLE_LOCAL();                            \
        wk.au8Byte[3] = size_key | (0 << 6);            \
        PPC_KEYCDR = wk.u32Register;                    \
        wk.au8Byte[3] = size_key | (1 << 6);            \
        PPC_KEYCDR = wk.u32Register;                    \
        wk.au8Byte[3] = size_key | (2 << 6);            \
        PPC_KEYCDR = wk.u32Register;                    \
        wk.au8Byte[3] = size_key | (3 << 6);            \
        PPC_KEYCDR = wk.u32Register;                    \
        reg = data;                                     \
        IRQ_RESTORE();                                  \
    }
    
    /**
    *****************************************************************************
    ** \brief Write protected register of GPIO
    **
    ** \note This macro contains IRQ mask processing for protected sequence.
    **
    ** \param [in]  reg                Register access symbol.
    ** \param [in]  data               Write data.
    *****************************************************************************/
#define WPREG_GPIO(reg, data)                  \
    {                                                   \
        un_gpio_keycdr_t wk;                            \
        uint32_t adr = (uint32_t)&reg;                  \
        uint8_t size_key;                               \
        wk.au16Halfword[0] = adr & 0x7FFF;              \
        size_key = (sizeof(reg) >> 1) << 4;             \
        IRQ_DISABLE_LOCAL();                            \
        wk.au8Byte[3] = size_key | (0 << 6);            \
        GPIO_KEYCDR = wk.u32Register;                   \
        wk.au8Byte[3] = size_key | (1 << 6);            \
        GPIO_KEYCDR = wk.u32Register;                   \
        wk.au8Byte[3] = size_key | (2 << 6);            \
        GPIO_KEYCDR = wk.u32Register;                   \
        wk.au8Byte[3] = size_key | (3 << 6);            \
        GPIO_KEYCDR = wk.u32Register;                   \
        reg = data;                                     \
        IRQ_RESTORE();                                  \
    }
    
    /**
    *****************************************************************************
    ** \brief Write protected register of RIC
    **
    ** \note This macro contains IRQ mask processing for protected sequence.
    **
    ** \param [in]  reg                Register access symbol.
    ** \param [in]  data               Write data.
    *****************************************************************************/
#define WPREG_RIC(reg, data)                   \
    {                                                   \
        un_ric_keycdr_t wk;                             \
        uint32_t adr = (uint32_t)&reg;                  \
        uint8_t size_key;                               \
        wk.au16Halfword[0] = adr & 0x7FFF;              \
        size_key = (sizeof(reg) >> 1) << 4;             \
        IRQ_DISABLE_LOCAL();                            \
        wk.au8Byte[3] = size_key | (0 << 6);            \
        RIC_KEYCDR = wk.u32Register;                    \
        wk.au8Byte[3] = size_key | (1 << 6);            \
        RIC_KEYCDR = wk.u32Register;                    \
        wk.au8Byte[3] = size_key | (2 << 6);            \
        RIC_KEYCDR = wk.u32Register;                    \
        wk.au8Byte[3] = size_key | (3 << 6);            \
        RIC_KEYCDR = wk.u32Register;                    \
        reg = data;                                     \
        IRQ_RESTORE();                                  \
    }
    
    /**
    *****************************************************************************
    ** \brief Write protected register of ADC
    **
    ** \note This macro contains IRQ mask processing for protected sequence.
    **
    ** \param [in]  reg                Register access symbol.
    ** \param [in]  data               Write data.
    *****************************************************************************/
#define WPREG_ADC(reg, data)                   \
    {                                                   \
        un_ader_2_keycdr_t wk;                          \
        uint32_t adr = (uint32_t)&reg;                  \
        uint8_t size_key;                               \
        wk.au16Halfword[0] = adr & 0x7FFF;              \
        size_key = (sizeof(reg) >> 1) << 4;             \
        IRQ_DISABLE_LOCAL();                            \
        wk.au8Byte[3] = size_key | (0 << 6);            \
        ADER_KEYCDR = wk.u32Register;                   \
        wk.au8Byte[3] = size_key | (1 << 6);            \
        ADER_KEYCDR = wk.u32Register;                   \
        wk.au8Byte[3] = size_key | (2 << 6);            \
        ADER_KEYCDR = wk.u32Register;                   \
        wk.au8Byte[3] = size_key | (3 << 6);            \
        ADER_KEYCDR = wk.u32Register;                   \
        reg = data;                                     \
        IRQ_RESTORE();                                  \
    }

#define     WRITE(r,v) r=v
/*****************************************************************************/
/* Include files                                                             */
/*****************************************************************************/
#include <math.h>
#include <string.h>

#include "base_types.h"
#include "mcu_settings.h"
#include "start.h"
#include "abstract.h"
#include "interrupts.h"
#include <arm_itm.h>
#include "cpu.h"
#include "tcflash.h"
#include "bsp_eeprom.h"

#include "UDS_Service.h" 
#include "UDS_Common.h"
#include "UDS_Parameter.h"
#include "DTC.h"
//#include "TP_Layer.h"

/*****************************************************************************/
/* system driver                                                             */
/*****************************************************************************/
#include "bsp_eic.h"
//#include "bsp_adc.h"
#include "canfd_320.h"
#include "canfd_320_driver.h"
#include "adc12b.h"
#include "bsp_dma.h"
#include "bsp_port.h"
#include "bsp_rtc.h"
#include "bsp_mfs_uart.h"
#include "bsp_bt_rlt.h"
#include "bsp_motor.h"
#include "bsp_sysctrl.h"
#include "sound.h"
#include "LCD_BUS_Interface.h"
#include "LCD_C035QAN02.h"
#include "bsp_system.h"
#include "i2s.h"
#include "bsp_bd8379.h"
#include "bsp_button.h"
#include "workflash.h"

/*****************************************************************************/
/* api include                                                             */
/*****************************************************************************/
#include "ProjectConfig.h"
#include "GlobalExternVar.h"

#include "main.h"
#include "CanRecvLib.h"
#include "io_config.h"
#include "api_adc.h"


#include "can.h"
#if (CAN_2ND)
#include "C_CAN_struct_2nd.h"
#include "M_CAN_struct_2nd.h"
#include "api_can_2nd.h"
#endif
#if (CAN_3RD)
#include "C_CAN_struct_3rd.h"
#include "M_CAN_struct_3rd.h"
#include "api_can_3rd.h"
#endif

#include "api_timer.h"
#include "api_tft.h"
#include "api_capture.h"
#include "MM_Can_TP.h"
#include "app_tft.h"
#include "api_workflash.h"
#include "WorkFlashPro.h"
#include "WorkFlashInterFace.h"
#include "EncryptDecrypt.h"

#include "NM_includes.h" 
#include "bsp_Presskey.h"
#include "ScanQrCodeConfig.h"
#include "api_RS485.h"
#include "R485_Communication_Matrix.h"
#include "BenchTpCommon.h"
/*****************************************************************************/
/* Global pre-processor symbols/macros ('#define')                           */
/*****************************************************************************/

/*****************************************************************************/
/* Global type definitions ('typedef')                                       */
/*****************************************************************************/

/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source)           */
/*****************************************************************************/

/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source)             */
/*****************************************************************************/

#endif